diff options
859 files changed, 14729 insertions, 8283 deletions
| @@ -3101,7 +3101,7 @@ S: Minto, NSW, 2566 | |||
| 3101 | S: Australia | 3101 | S: Australia |
| 3102 | 3102 | ||
| 3103 | N: Stephen Smalley | 3103 | N: Stephen Smalley |
| 3104 | E: sds@epoch.ncsc.mil | 3104 | E: sds@tycho.nsa.gov |
| 3105 | D: portions of the Linux Security Module (LSM) framework and security modules | 3105 | D: portions of the Linux Security Module (LSM) framework and security modules |
| 3106 | 3106 | ||
| 3107 | N: Chris Smith | 3107 | N: Chris Smith |
diff --git a/Documentation/cputopology.txt b/Documentation/cputopology.txt new file mode 100644 index 000000000000..ff280e2e1613 --- /dev/null +++ b/Documentation/cputopology.txt | |||
| @@ -0,0 +1,41 @@ | |||
| 1 | |||
| 2 | Export cpu topology info by sysfs. Items (attributes) are similar | ||
| 3 | to /proc/cpuinfo. | ||
| 4 | |||
| 5 | 1) /sys/devices/system/cpu/cpuX/topology/physical_package_id: | ||
| 6 | represent the physical package id of cpu X; | ||
| 7 | 2) /sys/devices/system/cpu/cpuX/topology/core_id: | ||
| 8 | represent the cpu core id to cpu X; | ||
| 9 | 3) /sys/devices/system/cpu/cpuX/topology/thread_siblings: | ||
| 10 | represent the thread siblings to cpu X in the same core; | ||
| 11 | 4) /sys/devices/system/cpu/cpuX/topology/core_siblings: | ||
| 12 | represent the thread siblings to cpu X in the same physical package; | ||
| 13 | |||
| 14 | To implement it in an architecture-neutral way, a new source file, | ||
| 15 | driver/base/topology.c, is to export the 5 attributes. | ||
| 16 | |||
| 17 | If one architecture wants to support this feature, it just needs to | ||
| 18 | implement 4 defines, typically in file include/asm-XXX/topology.h. | ||
| 19 | The 4 defines are: | ||
| 20 | #define topology_physical_package_id(cpu) | ||
| 21 | #define topology_core_id(cpu) | ||
| 22 | #define topology_thread_siblings(cpu) | ||
| 23 | #define topology_core_siblings(cpu) | ||
| 24 | |||
| 25 | The type of **_id is int. | ||
| 26 | The type of siblings is cpumask_t. | ||
| 27 | |||
| 28 | To be consistent on all architectures, the 4 attributes should have | ||
| 29 | deafult values if their values are unavailable. Below is the rule. | ||
| 30 | 1) physical_package_id: If cpu has no physical package id, -1 is the | ||
| 31 | default value. | ||
| 32 | 2) core_id: If cpu doesn't support multi-core, its core id is 0. | ||
| 33 | 3) thread_siblings: Just include itself, if the cpu doesn't support | ||
| 34 | HT/multi-thread. | ||
| 35 | 4) core_siblings: Just include itself, if the cpu doesn't support | ||
| 36 | multi-core and HT/Multi-thread. | ||
| 37 | |||
| 38 | So be careful when declaring the 4 defines in include/asm-XXX/topology.h. | ||
| 39 | |||
| 40 | If an attribute isn't defined on an architecture, it won't be exported. | ||
| 41 | |||
diff --git a/Documentation/driver-model/overview.txt b/Documentation/driver-model/overview.txt index 44662735cf81..ac4a7a737e43 100644 --- a/Documentation/driver-model/overview.txt +++ b/Documentation/driver-model/overview.txt | |||
| @@ -1,50 +1,43 @@ | |||
| 1 | The Linux Kernel Device Model | 1 | The Linux Kernel Device Model |
| 2 | 2 | ||
| 3 | Patrick Mochel <mochel@osdl.org> | 3 | Patrick Mochel <mochel@digitalimplant.org> |
| 4 | 4 | ||
| 5 | 26 August 2002 | 5 | Drafted 26 August 2002 |
| 6 | Updated 31 January 2006 | ||
| 6 | 7 | ||
| 7 | 8 | ||
| 8 | Overview | 9 | Overview |
| 9 | ~~~~~~~~ | 10 | ~~~~~~~~ |
| 10 | 11 | ||
| 11 | This driver model is a unification of all the current, disparate driver models | 12 | The Linux Kernel Driver Model is a unification of all the disparate driver |
| 12 | that are currently in the kernel. It is intended to augment the | 13 | models that were previously used in the kernel. It is intended to augment the |
| 13 | bus-specific drivers for bridges and devices by consolidating a set of data | 14 | bus-specific drivers for bridges and devices by consolidating a set of data |
| 14 | and operations into globally accessible data structures. | 15 | and operations into globally accessible data structures. |
| 15 | 16 | ||
| 16 | Current driver models implement some sort of tree-like structure (sometimes | 17 | Traditional driver models implemented some sort of tree-like structure |
| 17 | just a list) for the devices they control. But, there is no linkage between | 18 | (sometimes just a list) for the devices they control. There wasn't any |
| 18 | the different bus types. | 19 | uniformity across the different bus types. |
| 19 | 20 | ||
| 20 | A common data structure can provide this linkage with little overhead: when a | 21 | The current driver model provides a comon, uniform data model for describing |
| 21 | bus driver discovers a particular device, it can insert it into the global | 22 | a bus and the devices that can appear under the bus. The unified bus |
| 22 | tree as well as its local tree. In fact, the local tree becomes just a subset | 23 | model includes a set of common attributes which all busses carry, and a set |
| 23 | of the global tree. | 24 | of common callbacks, such as device discovery during bus probing, bus |
| 24 | 25 | shutdown, bus power management, etc. | |
| 25 | Common data fields can also be moved out of the local bus models into the | ||
| 26 | global model. Some of the manipulations of these fields can also be | ||
| 27 | consolidated. Most likely, manipulation functions will become a set | ||
| 28 | of helper functions, which the bus drivers wrap around to include any | ||
| 29 | bus-specific items. | ||
| 30 | |||
| 31 | The common device and bridge interface currently reflects the goals of the | ||
| 32 | modern PC: namely the ability to do seamless Plug and Play, power management, | ||
| 33 | and hot plug. (The model dictated by Intel and Microsoft (read: ACPI) ensures | ||
| 34 | us that any device in the system may fit any of these criteria.) | ||
| 35 | |||
| 36 | In reality, not every bus will be able to support such operations. But, most | ||
| 37 | buses will support a majority of those operations, and all future buses will. | ||
| 38 | In other words, a bus that doesn't support an operation is the exception, | ||
| 39 | instead of the other way around. | ||
| 40 | 26 | ||
| 27 | The common device and bridge interface reflects the goals of the modern | ||
| 28 | computer: namely the ability to do seamless device "plug and play", power | ||
| 29 | management, and hot plug. In particular, the model dictated by Intel and | ||
| 30 | Microsoft (namely ACPI) ensures that almost every device on almost any bus | ||
| 31 | on an x86-compatible system can work within this paradigm. Of course, | ||
| 32 | not every bus is able to support all such operations, although most | ||
| 33 | buses support a most of those operations. | ||
| 41 | 34 | ||
| 42 | 35 | ||
| 43 | Downstream Access | 36 | Downstream Access |
| 44 | ~~~~~~~~~~~~~~~~~ | 37 | ~~~~~~~~~~~~~~~~~ |
| 45 | 38 | ||
| 46 | Common data fields have been moved out of individual bus layers into a common | 39 | Common data fields have been moved out of individual bus layers into a common |
| 47 | data structure. But, these fields must still be accessed by the bus layers, | 40 | data structure. These fields must still be accessed by the bus layers, |
| 48 | and sometimes by the device-specific drivers. | 41 | and sometimes by the device-specific drivers. |
| 49 | 42 | ||
| 50 | Other bus layers are encouraged to do what has been done for the PCI layer. | 43 | Other bus layers are encouraged to do what has been done for the PCI layer. |
| @@ -53,7 +46,7 @@ struct pci_dev now looks like this: | |||
| 53 | struct pci_dev { | 46 | struct pci_dev { |
| 54 | ... | 47 | ... |
| 55 | 48 | ||
| 56 | struct device device; | 49 | struct device dev; |
| 57 | }; | 50 | }; |
| 58 | 51 | ||
| 59 | Note first that it is statically allocated. This means only one allocation on | 52 | Note first that it is statically allocated. This means only one allocation on |
| @@ -64,9 +57,9 @@ the two. | |||
| 64 | 57 | ||
| 65 | The PCI bus layer freely accesses the fields of struct device. It knows about | 58 | The PCI bus layer freely accesses the fields of struct device. It knows about |
| 66 | the structure of struct pci_dev, and it should know the structure of struct | 59 | the structure of struct pci_dev, and it should know the structure of struct |
| 67 | device. PCI devices that have been converted generally do not touch the fields | 60 | device. Individual PCI device drivers that have been converted the the current |
| 68 | of struct device. More precisely, device-specific drivers should not touch | 61 | driver model generally do not and should not touch the fields of struct device, |
| 69 | fields of struct device unless there is a strong compelling reason to do so. | 62 | unless there is a strong compelling reason to do so. |
| 70 | 63 | ||
| 71 | This abstraction is prevention of unnecessary pain during transitional phases. | 64 | This abstraction is prevention of unnecessary pain during transitional phases. |
| 72 | If the name of the field changes or is removed, then every downstream driver | 65 | If the name of the field changes or is removed, then every downstream driver |
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 4d4897c8ef96..b730d765b525 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
| @@ -162,3 +162,12 @@ What: pci_module_init(driver) | |||
| 162 | When: January 2007 | 162 | When: January 2007 |
| 163 | Why: Is replaced by pci_register_driver(pci_driver). | 163 | Why: Is replaced by pci_register_driver(pci_driver). |
| 164 | Who: Richard Knutsson <ricknu-0@student.ltu.se> and Greg Kroah-Hartman <gregkh@suse.de> | 164 | Who: Richard Knutsson <ricknu-0@student.ltu.se> and Greg Kroah-Hartman <gregkh@suse.de> |
| 165 | |||
| 166 | --------------------------- | ||
| 167 | |||
| 168 | What: I2C interface of the it87 driver | ||
| 169 | When: January 2007 | ||
| 170 | Why: The ISA interface is faster and should be always available. The I2C | ||
| 171 | probing is also known to cause trouble in at least one case (see | ||
| 172 | bug #5889.) | ||
| 173 | Who: Jean Delvare <khali@linux-fr.org> | ||
diff --git a/Documentation/filesystems/configfs/configfs_example.c b/Documentation/filesystems/configfs/configfs_example.c index f3c6e4946f98..3d4713a6c207 100644 --- a/Documentation/filesystems/configfs/configfs_example.c +++ b/Documentation/filesystems/configfs/configfs_example.c | |||
| @@ -320,6 +320,7 @@ static struct config_item_type simple_children_type = { | |||
| 320 | .ct_item_ops = &simple_children_item_ops, | 320 | .ct_item_ops = &simple_children_item_ops, |
| 321 | .ct_group_ops = &simple_children_group_ops, | 321 | .ct_group_ops = &simple_children_group_ops, |
| 322 | .ct_attrs = simple_children_attrs, | 322 | .ct_attrs = simple_children_attrs, |
| 323 | .ct_owner = THIS_MODULE, | ||
| 323 | }; | 324 | }; |
| 324 | 325 | ||
| 325 | static struct configfs_subsystem simple_children_subsys = { | 326 | static struct configfs_subsystem simple_children_subsys = { |
| @@ -403,6 +404,7 @@ static struct config_item_type group_children_type = { | |||
| 403 | .ct_item_ops = &group_children_item_ops, | 404 | .ct_item_ops = &group_children_item_ops, |
| 404 | .ct_group_ops = &group_children_group_ops, | 405 | .ct_group_ops = &group_children_group_ops, |
| 405 | .ct_attrs = group_children_attrs, | 406 | .ct_attrs = group_children_attrs, |
| 407 | .ct_owner = THIS_MODULE, | ||
| 406 | }; | 408 | }; |
| 407 | 409 | ||
| 408 | static struct configfs_subsystem group_children_subsys = { | 410 | static struct configfs_subsystem group_children_subsys = { |
diff --git a/Documentation/filesystems/ocfs2.txt b/Documentation/filesystems/ocfs2.txt index f2595caf052e..4389c684a80a 100644 --- a/Documentation/filesystems/ocfs2.txt +++ b/Documentation/filesystems/ocfs2.txt | |||
| @@ -35,6 +35,7 @@ Features which OCFS2 does not support yet: | |||
| 35 | be cluster coherent. | 35 | be cluster coherent. |
| 36 | - quotas | 36 | - quotas |
| 37 | - cluster aware flock | 37 | - cluster aware flock |
| 38 | - cluster aware lockf | ||
| 38 | - Directory change notification (F_NOTIFY) | 39 | - Directory change notification (F_NOTIFY) |
| 39 | - Distributed Caching (F_SETLEASE/F_GETLEASE/break_lease) | 40 | - Distributed Caching (F_SETLEASE/F_GETLEASE/break_lease) |
| 40 | - POSIX ACLs | 41 | - POSIX ACLs |
diff --git a/Documentation/hwmon/f71805f b/Documentation/hwmon/f71805f new file mode 100644 index 000000000000..28c5b7d1eb90 --- /dev/null +++ b/Documentation/hwmon/f71805f | |||
| @@ -0,0 +1,105 @@ | |||
| 1 | Kernel driver f71805f | ||
| 2 | ===================== | ||
| 3 | |||
| 4 | Supported chips: | ||
| 5 | * Fintek F71805F/FG | ||
| 6 | Prefix: 'f71805f' | ||
| 7 | Addresses scanned: none, address read from Super I/O config space | ||
| 8 | Datasheet: Provided by Fintek on request | ||
| 9 | |||
| 10 | Author: Jean Delvare <khali@linux-fr.org> | ||
| 11 | |||
| 12 | Thanks to Denis Kieft from Barracuda Networks for the donation of a | ||
| 13 | test system (custom Jetway K8M8MS motherboard, with CPU and RAM) and | ||
| 14 | for providing initial documentation. | ||
| 15 | |||
| 16 | Thanks to Kris Chen from Fintek for answering technical questions and | ||
| 17 | providing additional documentation. | ||
| 18 | |||
| 19 | Thanks to Chris Lin from Jetway for providing wiring schematics and | ||
| 20 | anwsering technical questions. | ||
| 21 | |||
| 22 | |||
| 23 | Description | ||
| 24 | ----------- | ||
| 25 | |||
| 26 | The Fintek F71805F/FG Super I/O chip includes complete hardware monitoring | ||
| 27 | capabilities. It can monitor up to 9 voltages (counting its own power | ||
| 28 | source), 3 fans and 3 temperature sensors. | ||
| 29 | |||
| 30 | This chip also has fan controlling features, using either DC or PWM, in | ||
| 31 | three different modes (one manual, two automatic). The driver doesn't | ||
| 32 | support these features yet. | ||
| 33 | |||
| 34 | The driver assumes that no more than one chip is present, which seems | ||
| 35 | reasonable. | ||
| 36 | |||
| 37 | |||
| 38 | Voltage Monitoring | ||
| 39 | ------------------ | ||
| 40 | |||
| 41 | Voltages are sampled by an 8-bit ADC with a LSB of 8 mV. The supported | ||
| 42 | range is thus from 0 to 2.040 V. Voltage values outside of this range | ||
| 43 | need external resistors. An exception is in0, which is used to monitor | ||
| 44 | the chip's own power source (+3.3V), and is divided internally by a | ||
| 45 | factor 2. | ||
| 46 | |||
| 47 | The two LSB of the voltage limit registers are not used (always 0), so | ||
| 48 | you can only set the limits in steps of 32 mV (before scaling). | ||
| 49 | |||
| 50 | The wirings and resistor values suggested by Fintek are as follow: | ||
| 51 | |||
| 52 | pin expected | ||
| 53 | name use R1 R2 divider raw val. | ||
| 54 | |||
| 55 | in0 VCC VCC3.3V int. int. 2.00 1.65 V | ||
| 56 | in1 VIN1 VTT1.2V 10K - 1.00 1.20 V | ||
| 57 | in2 VIN2 VRAM 100K 100K 2.00 ~1.25 V (1) | ||
| 58 | in3 VIN3 VCHIPSET 47K 100K 1.47 2.24 V (2) | ||
| 59 | in4 VIN4 VCC5V 200K 47K 5.25 0.95 V | ||
| 60 | in5 VIN5 +12V 200K 20K 11.00 1.05 V | ||
| 61 | in6 VIN6 VCC1.5V 10K - 1.00 1.50 V | ||
| 62 | in7 VIN7 VCORE 10K - 1.00 ~1.40 V (1) | ||
| 63 | in8 VIN8 VSB5V 200K 47K 1.00 0.95 V | ||
| 64 | |||
| 65 | (1) Depends on your hardware setup. | ||
| 66 | (2) Obviously not correct, swapping R1 and R2 would make more sense. | ||
| 67 | |||
| 68 | These values can be used as hints at best, as motherboard manufacturers | ||
| 69 | are free to use a completely different setup. As a matter of fact, the | ||
| 70 | Jetway K8M8MS uses a significantly different setup. You will have to | ||
| 71 | find out documentation about your own motherboard, and edit sensors.conf | ||
| 72 | accordingly. | ||
| 73 | |||
| 74 | Each voltage measured has associated low and high limits, each of which | ||
| 75 | triggers an alarm when crossed. | ||
| 76 | |||
| 77 | |||
| 78 | Fan Monitoring | ||
| 79 | -------------- | ||
| 80 | |||
| 81 | Fan rotation speeds are reported as 12-bit values from a gated clock | ||
| 82 | signal. Speeds down to 366 RPM can be measured. There is no theoretical | ||
| 83 | high limit, but values over 6000 RPM seem to cause problem. The effective | ||
| 84 | resolution is much lower than you would expect, the step between different | ||
| 85 | register values being 10 rather than 1. | ||
| 86 | |||
| 87 | The chip assumes 2 pulse-per-revolution fans. | ||
| 88 | |||
| 89 | An alarm is triggered if the rotation speed drops below a programmable | ||
| 90 | limit or is too low to be measured. | ||
| 91 | |||
| 92 | |||
| 93 | Temperature Monitoring | ||
| 94 | ---------------------- | ||
| 95 | |||
| 96 | Temperatures are reported in degrees Celsius. Each temperature measured | ||
| 97 | has a high limit, those crossing triggers an alarm. There is an associated | ||
| 98 | hysteresis value, below which the temperature has to drop before the | ||
| 99 | alarm is cleared. | ||
| 100 | |||
| 101 | All temperature channels are external, there is no embedded temperature | ||
| 102 | sensor. Each channel can be used for connecting either a thermal diode | ||
| 103 | or a thermistor. The driver reports the currently selected mode, but | ||
| 104 | doesn't allow changing it. In theory, the BIOS should have configured | ||
| 105 | everything properly. | ||
diff --git a/Documentation/hwmon/it87 b/Documentation/hwmon/it87 index 7f42e441c645..9555be1ed999 100644 --- a/Documentation/hwmon/it87 +++ b/Documentation/hwmon/it87 | |||
| @@ -9,7 +9,7 @@ Supported chips: | |||
| 9 | http://www.ite.com.tw/ | 9 | http://www.ite.com.tw/ |
| 10 | * IT8712F | 10 | * IT8712F |
| 11 | Prefix: 'it8712' | 11 | Prefix: 'it8712' |
| 12 | Addresses scanned: I2C 0x28 - 0x2f | 12 | Addresses scanned: I2C 0x2d |
| 13 | from Super I/O config space (8 I/O ports) | 13 | from Super I/O config space (8 I/O ports) |
| 14 | Datasheet: Publicly available at the ITE website | 14 | Datasheet: Publicly available at the ITE website |
| 15 | http://www.ite.com.tw/ | 15 | http://www.ite.com.tw/ |
diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface index 764cdc5480e7..a0d0ab24288e 100644 --- a/Documentation/hwmon/sysfs-interface +++ b/Documentation/hwmon/sysfs-interface | |||
| @@ -179,11 +179,12 @@ temp[1-*]_auto_point[1-*]_temp_hyst | |||
| 179 | **************** | 179 | **************** |
| 180 | 180 | ||
| 181 | temp[1-3]_type Sensor type selection. | 181 | temp[1-3]_type Sensor type selection. |
| 182 | Integers 1, 2, 3 or thermistor Beta value (3435) | 182 | Integers 1 to 4 or thermistor Beta value (typically 3435) |
| 183 | Read/Write. | 183 | Read/Write. |
| 184 | 1: PII/Celeron Diode | 184 | 1: PII/Celeron Diode |
| 185 | 2: 3904 transistor | 185 | 2: 3904 transistor |
| 186 | 3: thermal diode | 186 | 3: thermal diode |
| 187 | 4: thermistor (default/unknown Beta) | ||
| 187 | Not all types are supported by all chips | 188 | Not all types are supported by all chips |
| 188 | 189 | ||
| 189 | temp[1-4]_max Temperature max value. | 190 | temp[1-4]_max Temperature max value. |
| @@ -261,6 +262,21 @@ alarms Alarm bitmask. | |||
| 261 | of individual bits. | 262 | of individual bits. |
| 262 | Bits are defined in kernel/include/sensors.h. | 263 | Bits are defined in kernel/include/sensors.h. |
| 263 | 264 | ||
| 265 | alarms_in Alarm bitmask relative to in (voltage) channels | ||
| 266 | Read only | ||
| 267 | A '1' bit means an alarm, LSB corresponds to in0 and so on | ||
| 268 | Prefered to 'alarms' for newer chips | ||
| 269 | |||
| 270 | alarms_fan Alarm bitmask relative to fan channels | ||
| 271 | Read only | ||
| 272 | A '1' bit means an alarm, LSB corresponds to fan1 and so on | ||
| 273 | Prefered to 'alarms' for newer chips | ||
| 274 | |||
| 275 | alarms_temp Alarm bitmask relative to temp (temperature) channels | ||
| 276 | Read only | ||
| 277 | A '1' bit means an alarm, LSB corresponds to temp1 and so on | ||
| 278 | Prefered to 'alarms' for newer chips | ||
| 279 | |||
| 264 | beep_enable Beep/interrupt enable | 280 | beep_enable Beep/interrupt enable |
| 265 | 0 to disable. | 281 | 0 to disable. |
| 266 | 1 to enable. | 282 | 1 to enable. |
diff --git a/Documentation/i2c/busses/i2c-sis69x b/Documentation/i2c/busses/i2c-sis96x index b88953dfd580..00a009b977e9 100644 --- a/Documentation/i2c/busses/i2c-sis69x +++ b/Documentation/i2c/busses/i2c-sis96x | |||
| @@ -7,7 +7,7 @@ Supported adapters: | |||
| 7 | Any combination of these host bridges: | 7 | Any combination of these host bridges: |
| 8 | 645, 645DX (aka 646), 648, 650, 651, 655, 735, 745, 746 | 8 | 645, 645DX (aka 646), 648, 650, 651, 655, 735, 745, 746 |
| 9 | and these south bridges: | 9 | and these south bridges: |
| 10 | 961, 962, 963(L) | 10 | 961, 962, 963(L) |
| 11 | 11 | ||
| 12 | Author: Mark M. Hoffman <mhoffman@lightlink.com> | 12 | Author: Mark M. Hoffman <mhoffman@lightlink.com> |
| 13 | 13 | ||
| @@ -29,7 +29,7 @@ The command "lspci" as root should produce something like these lines: | |||
| 29 | 29 | ||
| 30 | or perhaps this... | 30 | or perhaps this... |
| 31 | 31 | ||
| 32 | 00:00.0 Host bridge: Silicon Integrated Systems [SiS]: Unknown device 0645 | 32 | 00:00.0 Host bridge: Silicon Integrated Systems [SiS]: Unknown device 0645 |
| 33 | 00:02.0 ISA bridge: Silicon Integrated Systems [SiS]: Unknown device 0961 | 33 | 00:02.0 ISA bridge: Silicon Integrated Systems [SiS]: Unknown device 0961 |
| 34 | 00:02.1 SMBus: Silicon Integrated Systems [SiS]: Unknown device 0016 | 34 | 00:02.1 SMBus: Silicon Integrated Systems [SiS]: Unknown device 0016 |
| 35 | 35 | ||
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 2b7cf19a06ad..26364d06ae92 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt | |||
| @@ -427,6 +427,23 @@ icmp_ignore_bogus_error_responses - BOOLEAN | |||
| 427 | will avoid log file clutter. | 427 | will avoid log file clutter. |
| 428 | Default: FALSE | 428 | Default: FALSE |
| 429 | 429 | ||
| 430 | icmp_errors_use_inbound_ifaddr - BOOLEAN | ||
| 431 | |||
| 432 | If zero, icmp error messages are sent with the primary address of | ||
| 433 | the exiting interface. | ||
| 434 | |||
| 435 | If non-zero, the message will be sent with the primary address of | ||
| 436 | the interface that received the packet that caused the icmp error. | ||
| 437 | This is the behaviour network many administrators will expect from | ||
| 438 | a router. And it can make debugging complicated network layouts | ||
| 439 | much easier. | ||
| 440 | |||
| 441 | Note that if no primary address exists for the interface selected, | ||
| 442 | then the primary address of the first non-loopback interface that | ||
| 443 | has one will be used regarldess of this setting. | ||
| 444 | |||
| 445 | Default: 0 | ||
| 446 | |||
| 430 | igmp_max_memberships - INTEGER | 447 | igmp_max_memberships - INTEGER |
| 431 | Change the maximum number of multicast groups we can subscribe to. | 448 | Change the maximum number of multicast groups we can subscribe to. |
| 432 | Default: 20 | 449 | Default: 20 |
diff --git a/Documentation/parport-lowlevel.txt b/Documentation/parport-lowlevel.txt index 1d40008a1926..8f2302415eff 100644 --- a/Documentation/parport-lowlevel.txt +++ b/Documentation/parport-lowlevel.txt | |||
| @@ -1068,7 +1068,7 @@ SYNOPSIS | |||
| 1068 | 1068 | ||
| 1069 | struct parport_operations { | 1069 | struct parport_operations { |
| 1070 | ... | 1070 | ... |
| 1071 | void (*write_status) (struct parport *port, unsigned char s); | 1071 | void (*write_control) (struct parport *port, unsigned char s); |
| 1072 | ... | 1072 | ... |
| 1073 | }; | 1073 | }; |
| 1074 | 1074 | ||
| @@ -1097,9 +1097,9 @@ SYNOPSIS | |||
| 1097 | 1097 | ||
| 1098 | struct parport_operations { | 1098 | struct parport_operations { |
| 1099 | ... | 1099 | ... |
| 1100 | void (*frob_control) (struct parport *port, | 1100 | unsigned char (*frob_control) (struct parport *port, |
| 1101 | unsigned char mask, | 1101 | unsigned char mask, |
| 1102 | unsigned char val); | 1102 | unsigned char val); |
| 1103 | ... | 1103 | ... |
| 1104 | }; | 1104 | }; |
| 1105 | 1105 | ||
diff --git a/Documentation/pci-error-recovery.txt b/Documentation/pci-error-recovery.txt index d089967e4948..634d3e5b5756 100644 --- a/Documentation/pci-error-recovery.txt +++ b/Documentation/pci-error-recovery.txt | |||
| @@ -1,246 +1,396 @@ | |||
| 1 | 1 | ||
| 2 | PCI Error Recovery | 2 | PCI Error Recovery |
| 3 | ------------------ | 3 | ------------------ |
| 4 | May 31, 2005 | 4 | February 2, 2006 |
| 5 | 5 | ||
| 6 | Current document maintainer: | 6 | Current document maintainer: |
| 7 | Linas Vepstas <linas@austin.ibm.com> | 7 | Linas Vepstas <linas@austin.ibm.com> |
| 8 | 8 | ||
| 9 | 9 | ||
| 10 | Some PCI bus controllers are able to detect certain "hard" PCI errors | 10 | Many PCI bus controllers are able to detect a variety of hardware |
| 11 | on the bus, such as parity errors on the data and address busses, as | 11 | PCI errors on the bus, such as parity errors on the data and address |
| 12 | well as SERR and PERR errors. These chipsets are then able to disable | 12 | busses, as well as SERR and PERR errors. Some of the more advanced |
| 13 | I/O to/from the affected device, so that, for example, a bad DMA | 13 | chipsets are able to deal with these errors; these include PCI-E chipsets, |
| 14 | address doesn't end up corrupting system memory. These same chipsets | 14 | and the PCI-host bridges found on IBM Power4 and Power5-based pSeries |
| 15 | are also able to reset the affected PCI device, and return it to | 15 | boxes. A typical action taken is to disconnect the affected device, |
| 16 | working condition. This document describes a generic API form | 16 | halting all I/O to it. The goal of a disconnection is to avoid system |
| 17 | performing error recovery. | 17 | corruption; for example, to halt system memory corruption due to DMA's |
| 18 | 18 | to "wild" addresses. Typically, a reconnection mechanism is also | |
| 19 | The core idea is that after a PCI error has been detected, there must | 19 | offered, so that the affected PCI device(s) are reset and put back |
| 20 | be a way for the kernel to coordinate with all affected device drivers | 20 | into working condition. The reset phase requires coordination |
| 21 | so that the pci card can be made operational again, possibly after | 21 | between the affected device drivers and the PCI controller chip. |
| 22 | performing a full electrical #RST of the PCI card. The API below | 22 | This document describes a generic API for notifying device drivers |
| 23 | provides a generic API for device drivers to be notified of PCI | 23 | of a bus disconnection, and then performing error recovery. |
| 24 | errors, and to be notified of, and respond to, a reset sequence. | 24 | This API is currently implemented in the 2.6.16 and later kernels. |
| 25 | 25 | ||
| 26 | Preliminary sketch of API, cut-n-pasted-n-modified email from | 26 | Reporting and recovery is performed in several steps. First, when |
| 27 | Ben Herrenschmidt, circa 5 april 2005 | 27 | a PCI hardware error has resulted in a bus disconnect, that event |
| 28 | is reported as soon as possible to all affected device drivers, | ||
| 29 | including multiple instances of a device driver on multi-function | ||
| 30 | cards. This allows device drivers to avoid deadlocking in spinloops, | ||
| 31 | waiting for some i/o-space register to change, when it never will. | ||
| 32 | It also gives the drivers a chance to defer incoming I/O as | ||
| 33 | needed. | ||
| 34 | |||
| 35 | Next, recovery is performed in several stages. Most of the complexity | ||
| 36 | is forced by the need to handle multi-function devices, that is, | ||
| 37 | devices that have multiple device drivers associated with them. | ||
| 38 | In the first stage, each driver is allowed to indicate what type | ||
| 39 | of reset it desires, the choices being a simple re-enabling of I/O | ||
| 40 | or requesting a hard reset (a full electrical #RST of the PCI card). | ||
| 41 | If any driver requests a full reset, that is what will be done. | ||
| 42 | |||
| 43 | After a full reset and/or a re-enabling of I/O, all drivers are | ||
| 44 | again notified, so that they may then perform any device setup/config | ||
| 45 | that may be required. After these have all completed, a final | ||
| 46 | "resume normal operations" event is sent out. | ||
| 47 | |||
| 48 | The biggest reason for choosing a kernel-based implementation rather | ||
| 49 | than a user-space implementation was the need to deal with bus | ||
| 50 | disconnects of PCI devices attached to storage media, and, in particular, | ||
| 51 | disconnects from devices holding the root file system. If the root | ||
| 52 | file system is disconnected, a user-space mechanism would have to go | ||
| 53 | through a large number of contortions to complete recovery. Almost all | ||
| 54 | of the current Linux file systems are not tolerant of disconnection | ||
| 55 | from/reconnection to their underlying block device. By contrast, | ||
| 56 | bus errors are easy to manage in the device driver. Indeed, most | ||
| 57 | device drivers already handle very similar recovery procedures; | ||
| 58 | for example, the SCSI-generic layer already provides significant | ||
| 59 | mechanisms for dealing with SCSI bus errors and SCSI bus resets. | ||
| 60 | |||
| 61 | |||
| 62 | Detailed Design | ||
| 63 | --------------- | ||
| 64 | Design and implementation details below, based on a chain of | ||
| 65 | public email discussions with Ben Herrenschmidt, circa 5 April 2005. | ||
| 28 | 66 | ||
| 29 | The error recovery API support is exposed to the driver in the form of | 67 | The error recovery API support is exposed to the driver in the form of |
| 30 | a structure of function pointers pointed to by a new field in struct | 68 | a structure of function pointers pointed to by a new field in struct |
| 31 | pci_driver. The absence of this pointer in pci_driver denotes an | 69 | pci_driver. A driver that fails to provide the structure is "non-aware", |
| 32 | "non-aware" driver, behaviour on these is platform dependant. | 70 | and the actual recovery steps taken are platform dependent. The |
| 33 | Platforms like ppc64 can try to simulate pci hotplug remove/add. | 71 | arch/powerpc implementation will simulate a PCI hotplug remove/add. |
| 34 | |||
| 35 | The definition of "pci_error_token" is not covered here. It is based on | ||
| 36 | Seto's work on the synchronous error detection. We still need to define | ||
| 37 | functions for extracting infos out of an opaque error token. This is | ||
| 38 | separate from this API. | ||
| 39 | 72 | ||
| 40 | This structure has the form: | 73 | This structure has the form: |
| 41 | |||
| 42 | struct pci_error_handlers | 74 | struct pci_error_handlers |
| 43 | { | 75 | { |
| 44 | int (*error_detected)(struct pci_dev *dev, pci_error_token error); | 76 | int (*error_detected)(struct pci_dev *dev, enum pci_channel_state); |
| 45 | int (*mmio_enabled)(struct pci_dev *dev); | 77 | int (*mmio_enabled)(struct pci_dev *dev); |
| 46 | int (*resume)(struct pci_dev *dev); | ||
| 47 | int (*link_reset)(struct pci_dev *dev); | 78 | int (*link_reset)(struct pci_dev *dev); |
| 48 | int (*slot_reset)(struct pci_dev *dev); | 79 | int (*slot_reset)(struct pci_dev *dev); |
| 80 | void (*resume)(struct pci_dev *dev); | ||
| 49 | }; | 81 | }; |
| 50 | 82 | ||
| 51 | A driver doesn't have to implement all of these callbacks. The | 83 | The possible channel states are: |
| 52 | only mandatory one is error_detected(). If a callback is not | 84 | enum pci_channel_state { |
| 53 | implemented, the corresponding feature is considered unsupported. | 85 | pci_channel_io_normal, /* I/O channel is in normal state */ |
| 54 | For example, if mmio_enabled() and resume() aren't there, then the | 86 | pci_channel_io_frozen, /* I/O to channel is blocked */ |
| 55 | driver is assumed as not doing any direct recovery and requires | 87 | pci_channel_io_perm_failure, /* PCI card is dead */ |
| 88 | }; | ||
| 89 | |||
| 90 | Possible return values are: | ||
| 91 | enum pci_ers_result { | ||
| 92 | PCI_ERS_RESULT_NONE, /* no result/none/not supported in device driver */ | ||
| 93 | PCI_ERS_RESULT_CAN_RECOVER, /* Device driver can recover without slot reset */ | ||
| 94 | PCI_ERS_RESULT_NEED_RESET, /* Device driver wants slot to be reset. */ | ||
| 95 | PCI_ERS_RESULT_DISCONNECT, /* Device has completely failed, is unrecoverable */ | ||
| 96 | PCI_ERS_RESULT_RECOVERED, /* Device driver is fully recovered and operational */ | ||
| 97 | }; | ||
| 98 | |||
| 99 | A driver does not have to implement all of these callbacks; however, | ||
| 100 | if it implements any, it must implement error_detected(). If a callback | ||
| 101 | is not implemented, the corresponding feature is considered unsupported. | ||
| 102 | For example, if mmio_enabled() and resume() aren't there, then it | ||
| 103 | is assumed that the driver is not doing any direct recovery and requires | ||
| 56 | a reset. If link_reset() is not implemented, the card is assumed as | 104 | a reset. If link_reset() is not implemented, the card is assumed as |
| 57 | not caring about link resets, in which case, if recover is supported, | 105 | not care about link resets. Typically a driver will want to know about |
| 58 | the core can try recover (but not slot_reset() unless it really did | 106 | a slot_reset(). |
| 59 | reset the slot). If slot_reset() is not supported, link_reset() can | 107 | |
| 60 | be called instead on a slot reset. | 108 | The actual steps taken by a platform to recover from a PCI error |
| 61 | 109 | event will be platform-dependent, but will follow the general | |
| 62 | At first, the call will always be : | 110 | sequence described below. |
| 63 | 111 | ||
| 64 | 1) error_detected() | 112 | STEP 0: Error Event |
| 65 | 113 | ------------------- | |
| 66 | Error detected. This is sent once after an error has been detected. At | 114 | PCI bus error is detect by the PCI hardware. On powerpc, the slot |
| 67 | this point, the device might not be accessible anymore depending on the | 115 | is isolated, in that all I/O is blocked: all reads return 0xffffffff, |
| 68 | platform (the slot will be isolated on ppc64). The driver may already | 116 | all writes are ignored. |
| 69 | have "noticed" the error because of a failing IO, but this is the proper | 117 | |
| 70 | "synchronisation point", that is, it gives a chance to the driver to | 118 | |
| 71 | cleanup, waiting for pending stuff (timers, whatever, etc...) to | 119 | STEP 1: Notification |
| 72 | complete; it can take semaphores, schedule, etc... everything but touch | 120 | -------------------- |
| 73 | the device. Within this function and after it returns, the driver | 121 | Platform calls the error_detected() callback on every instance of |
| 122 | every driver affected by the error. | ||
| 123 | |||
| 124 | At this point, the device might not be accessible anymore, depending on | ||
| 125 | the platform (the slot will be isolated on powerpc). The driver may | ||
| 126 | already have "noticed" the error because of a failing I/O, but this | ||
| 127 | is the proper "synchronization point", that is, it gives the driver | ||
| 128 | a chance to cleanup, waiting for pending stuff (timers, whatever, etc...) | ||
| 129 | to complete; it can take semaphores, schedule, etc... everything but | ||
| 130 | touch the device. Within this function and after it returns, the driver | ||
| 74 | shouldn't do any new IOs. Called in task context. This is sort of a | 131 | shouldn't do any new IOs. Called in task context. This is sort of a |
| 75 | "quiesce" point. See note about interrupts at the end of this doc. | 132 | "quiesce" point. See note about interrupts at the end of this doc. |
| 76 | 133 | ||
| 77 | Result codes: | 134 | All drivers participating in this system must implement this call. |
| 78 | - PCIERR_RESULT_CAN_RECOVER: | 135 | The driver must return one of the following result codes: |
| 79 | Driever returns this if it thinks it might be able to recover | 136 | - PCI_ERS_RESULT_CAN_RECOVER: |
| 137 | Driver returns this if it thinks it might be able to recover | ||
| 80 | the HW by just banging IOs or if it wants to be given | 138 | the HW by just banging IOs or if it wants to be given |
| 81 | a chance to extract some diagnostic informations (see | 139 | a chance to extract some diagnostic information (see |
| 82 | below). | 140 | mmio_enable, below). |
| 83 | - PCIERR_RESULT_NEED_RESET: | 141 | - PCI_ERS_RESULT_NEED_RESET: |
| 84 | Driver returns this if it thinks it can't recover unless the | 142 | Driver returns this if it can't recover without a hard |
| 85 | slot is reset. | 143 | slot reset. |
| 86 | - PCIERR_RESULT_DISCONNECT: | 144 | - PCI_ERS_RESULT_DISCONNECT: |
| 87 | Return this if driver thinks it won't recover at all, | 145 | Driver returns this if it doesn't want to recover at all. |
| 88 | (this will detach the driver ? or just leave it | 146 | |
| 89 | dangling ? to be decided) | 147 | The next step taken will depend on the result codes returned by the |
| 90 | 148 | drivers. | |
| 91 | So at this point, we have called error_detected() for all drivers | 149 | |
| 92 | on the segment that had the error. On ppc64, the slot is isolated. What | 150 | If all drivers on the segment/slot return PCI_ERS_RESULT_CAN_RECOVER, |
| 93 | happens now typically depends on the result from the drivers. If all | 151 | then the platform should re-enable IOs on the slot (or do nothing in |
| 94 | drivers on the segment/slot return PCIERR_RESULT_CAN_RECOVER, we would | 152 | particular, if the platform doesn't isolate slots), and recovery |
| 95 | re-enable IOs on the slot (or do nothing special if the platform doesn't | 153 | proceeds to STEP 2 (MMIO Enable). |
| 96 | isolate slots) and call 2). If not and we can reset slots, we go to 4), | 154 | |
| 97 | if neither, we have a dead slot. If it's an hotplug slot, we might | 155 | If any driver requested a slot reset (by returning PCI_ERS_RESULT_NEED_RESET), |
| 98 | "simulate" reset by triggering HW unplug/replug though. | 156 | then recovery proceeds to STEP 4 (Slot Reset). |
| 99 | 157 | ||
| 100 | >>> Current ppc64 implementation assumes that a device driver will | 158 | If the platform is unable to recover the slot, the next step |
| 101 | >>> *not* schedule or semaphore in this routine; the current ppc64 | 159 | is STEP 6 (Permanent Failure). |
| 160 | |||
| 161 | >>> The current powerpc implementation assumes that a device driver will | ||
| 162 | >>> *not* schedule or semaphore in this routine; the current powerpc | ||
| 102 | >>> implementation uses one kernel thread to notify all devices; | 163 | >>> implementation uses one kernel thread to notify all devices; |
| 103 | >>> thus, of one device sleeps/schedules, all devices are affected. | 164 | >>> thus, if one device sleeps/schedules, all devices are affected. |
| 104 | >>> Doing better requires complex multi-threaded logic in the error | 165 | >>> Doing better requires complex multi-threaded logic in the error |
| 105 | >>> recovery implementation (e.g. waiting for all notification threads | 166 | >>> recovery implementation (e.g. waiting for all notification threads |
| 106 | >>> to "join" before proceeding with recovery.) This seems excessively | 167 | >>> to "join" before proceeding with recovery.) This seems excessively |
| 107 | >>> complex and not worth implementing. | 168 | >>> complex and not worth implementing. |
| 108 | 169 | ||
| 109 | >>> The current ppc64 implementation doesn't much care if the device | 170 | >>> The current powerpc implementation doesn't much care if the device |
| 110 | >>> attempts i/o at this point, or not. I/O's will fail, returning | 171 | >>> attempts I/O at this point, or not. I/O's will fail, returning |
| 111 | >>> a value of 0xff on read, and writes will be dropped. If the device | 172 | >>> a value of 0xff on read, and writes will be dropped. If the device |
| 112 | >>> driver attempts more than 10K I/O's to a frozen adapter, it will | 173 | >>> driver attempts more than 10K I/O's to a frozen adapter, it will |
| 113 | >>> assume that the device driver has gone into an infinite loop, and | 174 | >>> assume that the device driver has gone into an infinite loop, and |
| 114 | >>> it will panic the the kernel. | 175 | >>> it will panic the the kernel. There doesn't seem to be any other |
| 176 | >>> way of stopping a device driver that insists on spinning on I/O. | ||
| 115 | 177 | ||
| 116 | 2) mmio_enabled() | 178 | STEP 2: MMIO Enabled |
| 179 | ------------------- | ||
| 180 | The platform re-enables MMIO to the device (but typically not the | ||
| 181 | DMA), and then calls the mmio_enabled() callback on all affected | ||
| 182 | device drivers. | ||
| 117 | 183 | ||
| 118 | This is the "early recovery" call. IOs are allowed again, but DMA is | 184 | This is the "early recovery" call. IOs are allowed again, but DMA is |
| 119 | not (hrm... to be discussed, I prefer not), with some restrictions. This | 185 | not (hrm... to be discussed, I prefer not), with some restrictions. This |
| 120 | is NOT a callback for the driver to start operations again, only to | 186 | is NOT a callback for the driver to start operations again, only to |
| 121 | peek/poke at the device, extract diagnostic information, if any, and | 187 | peek/poke at the device, extract diagnostic information, if any, and |
| 122 | eventually do things like trigger a device local reset or some such, | 188 | eventually do things like trigger a device local reset or some such, |
| 123 | but not restart operations. This is sent if all drivers on a segment | 189 | but not restart operations. This is callback is made if all drivers on |
| 124 | agree that they can try to recover and no automatic link reset was | 190 | a segment agree that they can try to recover and if no automatic link reset |
| 125 | performed by the HW. If the platform can't just re-enable IOs without | 191 | was performed by the HW. If the platform can't just re-enable IOs without |
| 126 | a slot reset or a link reset, it doesn't call this callback and goes | 192 | a slot reset or a link reset, it wont call this callback, and instead |
| 127 | directly to 3) or 4). All IOs should be done _synchronously_ from | 193 | will have gone directly to STEP 3 (Link Reset) or STEP 4 (Slot Reset) |
| 128 | within this callback, errors triggered by them will be returned via | 194 | |
| 129 | the normal pci_check_whatever() api, no new error_detected() callback | 195 | >>> The following is proposed; no platform implements this yet: |
| 130 | will be issued due to an error happening here. However, such an error | 196 | >>> Proposal: All I/O's should be done _synchronously_ from within |
| 131 | might cause IOs to be re-blocked for the whole segment, and thus | 197 | >>> this callback, errors triggered by them will be returned via |
| 132 | invalidate the recovery that other devices on the same segment might | 198 | >>> the normal pci_check_whatever() API, no new error_detected() |
| 133 | have done, forcing the whole segment into one of the next states, | 199 | >>> callback will be issued due to an error happening here. However, |
| 134 | that is link reset or slot reset. | 200 | >>> such an error might cause IOs to be re-blocked for the whole |
| 135 | 201 | >>> segment, and thus invalidate the recovery that other devices | |
| 136 | Result codes: | 202 | >>> on the same segment might have done, forcing the whole segment |
| 137 | - PCIERR_RESULT_RECOVERED | 203 | >>> into one of the next states, that is, link reset or slot reset. |
| 204 | |||
| 205 | The driver should return one of the following result codes: | ||
| 206 | - PCI_ERS_RESULT_RECOVERED | ||
| 138 | Driver returns this if it thinks the device is fully | 207 | Driver returns this if it thinks the device is fully |
| 139 | functionnal and thinks it is ready to start | 208 | functional and thinks it is ready to start |
| 140 | normal driver operations again. There is no | 209 | normal driver operations again. There is no |
| 141 | guarantee that the driver will actually be | 210 | guarantee that the driver will actually be |
| 142 | allowed to proceed, as another driver on the | 211 | allowed to proceed, as another driver on the |
| 143 | same segment might have failed and thus triggered a | 212 | same segment might have failed and thus triggered a |
| 144 | slot reset on platforms that support it. | 213 | slot reset on platforms that support it. |
| 145 | 214 | ||
| 146 | - PCIERR_RESULT_NEED_RESET | 215 | - PCI_ERS_RESULT_NEED_RESET |
| 147 | Driver returns this if it thinks the device is not | 216 | Driver returns this if it thinks the device is not |
| 148 | recoverable in it's current state and it needs a slot | 217 | recoverable in it's current state and it needs a slot |
| 149 | reset to proceed. | 218 | reset to proceed. |
| 150 | 219 | ||
| 151 | - PCIERR_RESULT_DISCONNECT | 220 | - PCI_ERS_RESULT_DISCONNECT |
| 152 | Same as above. Total failure, no recovery even after | 221 | Same as above. Total failure, no recovery even after |
| 153 | reset driver dead. (To be defined more precisely) | 222 | reset driver dead. (To be defined more precisely) |
| 154 | 223 | ||
| 155 | >>> The current ppc64 implementation does not implement this callback. | 224 | The next step taken depends on the results returned by the drivers. |
| 225 | If all drivers returned PCI_ERS_RESULT_RECOVERED, then the platform | ||
| 226 | proceeds to either STEP3 (Link Reset) or to STEP 5 (Resume Operations). | ||
| 227 | |||
| 228 | If any driver returned PCI_ERS_RESULT_NEED_RESET, then the platform | ||
| 229 | proceeds to STEP 4 (Slot Reset) | ||
| 156 | 230 | ||
| 157 | 3) link_reset() | 231 | >>> The current powerpc implementation does not implement this callback. |
| 158 | 232 | ||
| 159 | This is called after the link has been reset. This is typically | 233 | |
| 160 | a PCI Express specific state at this point and is done whenever a | 234 | STEP 3: Link Reset |
| 161 | non-fatal error has been detected that can be "solved" by resetting | 235 | ------------------ |
| 162 | the link. This call informs the driver of the reset and the driver | 236 | The platform resets the link, and then calls the link_reset() callback |
| 163 | should check if the device appears to be in working condition. | 237 | on all affected device drivers. This is a PCI-Express specific state |
| 164 | This function acts a bit like 2) mmio_enabled(), in that the driver | 238 | and is done whenever a non-fatal error has been detected that can be |
| 165 | is not supposed to restart normal driver I/O operations right away. | 239 | "solved" by resetting the link. This call informs the driver of the |
| 166 | Instead, it should just "probe" the device to check it's recoverability | 240 | reset and the driver should check to see if the device appears to be |
| 167 | status. If all is right, then the core will call resume() once all | 241 | in working condition. |
| 168 | drivers have ack'd link_reset(). | 242 | |
| 243 | The driver is not supposed to restart normal driver I/O operations | ||
| 244 | at this point. It should limit itself to "probing" the device to | ||
| 245 | check it's recoverability status. If all is right, then the platform | ||
| 246 | will call resume() once all drivers have ack'd link_reset(). | ||
| 169 | 247 | ||
| 170 | Result codes: | 248 | Result codes: |
| 171 | (identical to mmio_enabled) | 249 | (identical to STEP 3 (MMIO Enabled) |
| 250 | |||
| 251 | The platform then proceeds to either STEP 4 (Slot Reset) or STEP 5 | ||
| 252 | (Resume Operations). | ||
| 253 | |||
| 254 | >>> The current powerpc implementation does not implement this callback. | ||
| 255 | |||
| 256 | |||
| 257 | STEP 4: Slot Reset | ||
| 258 | ------------------ | ||
| 259 | The platform performs a soft or hard reset of the device, and then | ||
| 260 | calls the slot_reset() callback. | ||
| 261 | |||
| 262 | A soft reset consists of asserting the adapter #RST line and then | ||
| 263 | restoring the PCI BAR's and PCI configuration header to a state | ||
| 264 | that is equivalent to what it would be after a fresh system | ||
| 265 | power-on followed by power-on BIOS/system firmware initialization. | ||
| 266 | If the platform supports PCI hotplug, then the reset might be | ||
| 267 | performed by toggling the slot electrical power off/on. | ||
| 172 | 268 | ||
| 173 | >>> The current ppc64 implementation does not implement this callback. | 269 | It is important for the platform to restore the PCI config space |
| 270 | to the "fresh poweron" state, rather than the "last state". After | ||
| 271 | a slot reset, the device driver will almost always use its standard | ||
| 272 | device initialization routines, and an unusual config space setup | ||
| 273 | may result in hung devices, kernel panics, or silent data corruption. | ||
| 174 | 274 | ||
| 175 | 4) slot_reset() | 275 | This call gives drivers the chance to re-initialize the hardware |
| 276 | (re-download firmware, etc.). At this point, the driver may assume | ||
| 277 | that he card is in a fresh state and is fully functional. In | ||
| 278 | particular, interrupt generation should work normally. | ||
| 176 | 279 | ||
| 177 | This is called after the slot has been soft or hard reset by the | 280 | Drivers should not yet restart normal I/O processing operations |
| 178 | platform. A soft reset consists of asserting the adapter #RST line | 281 | at this point. If all device drivers report success on this |
| 179 | and then restoring the PCI BARs and PCI configuration header. If the | 282 | callback, the platform will call resume() to complete the sequence, |
| 180 | platform supports PCI hotplug, then it might instead perform a hard | 283 | and let the driver restart normal I/O processing. |
| 181 | reset by toggling power on the slot off/on. This call gives drivers | ||
| 182 | the chance to re-initialize the hardware (re-download firmware, etc.), | ||
| 183 | but drivers shouldn't restart normal I/O processing operations at | ||
| 184 | this point. (See note about interrupts; interrupts aren't guaranteed | ||
| 185 | to be delivered until the resume() callback has been called). If all | ||
| 186 | device drivers report success on this callback, the patform will call | ||
| 187 | resume() to complete the error handling and let the driver restart | ||
| 188 | normal I/O processing. | ||
| 189 | 284 | ||
| 190 | A driver can still return a critical failure for this function if | 285 | A driver can still return a critical failure for this function if |
| 191 | it can't get the device operational after reset. If the platform | 286 | it can't get the device operational after reset. If the platform |
| 192 | previously tried a soft reset, it migh now try a hard reset (power | 287 | previously tried a soft reset, it might now try a hard reset (power |
| 193 | cycle) and then call slot_reset() again. It the device still can't | 288 | cycle) and then call slot_reset() again. It the device still can't |
| 194 | be recovered, there is nothing more that can be done; the platform | 289 | be recovered, there is nothing more that can be done; the platform |
| 195 | will typically report a "permanent failure" in such a case. The | 290 | will typically report a "permanent failure" in such a case. The |
| 196 | device will be considered "dead" in this case. | 291 | device will be considered "dead" in this case. |
| 197 | 292 | ||
| 198 | Result codes: | 293 | Drivers for multi-function cards will need to coordinate among |
| 199 | - PCIERR_RESULT_DISCONNECT | 294 | themselves as to which driver instance will perform any "one-shot" |
| 200 | Same as above. | 295 | or global device initialization. For example, the Symbios sym53cxx2 |
| 296 | driver performs device init only from PCI function 0: | ||
| 201 | 297 | ||
| 202 | >>> The current ppc64 implementation does not try a power-cycle reset | 298 | + if (PCI_FUNC(pdev->devfn) == 0) |
| 203 | >>> if the driver returned PCIERR_RESULT_DISCONNECT. However, it should. | 299 | + sym_reset_scsi_bus(np, 0); |
| 204 | 300 | ||
| 205 | 5) resume() | 301 | Result codes: |
| 206 | 302 | - PCI_ERS_RESULT_DISCONNECT | |
| 207 | This is called if all drivers on the segment have returned | 303 | Same as above. |
| 208 | PCIERR_RESULT_RECOVERED from one of the 3 prevous callbacks. | ||
| 209 | That basically tells the driver to restart activity, tht everything | ||
| 210 | is back and running. No result code is taken into account here. If | ||
| 211 | a new error happens, it will restart a new error handling process. | ||
| 212 | 304 | ||
| 213 | That's it. I think this covers all the possibilities. The way those | 305 | Platform proceeds either to STEP 5 (Resume Operations) or STEP 6 (Permanent |
| 214 | callbacks are called is platform policy. A platform with no slot reset | 306 | Failure). |
| 215 | capability for example may want to just "ignore" drivers that can't | 307 | |
| 308 | >>> The current powerpc implementation does not currently try a | ||
| 309 | >>> power-cycle reset if the driver returned PCI_ERS_RESULT_DISCONNECT. | ||
| 310 | >>> However, it probably should. | ||
| 311 | |||
| 312 | |||
| 313 | STEP 5: Resume Operations | ||
| 314 | ------------------------- | ||
| 315 | The platform will call the resume() callback on all affected device | ||
| 316 | drivers if all drivers on the segment have returned | ||
| 317 | PCI_ERS_RESULT_RECOVERED from one of the 3 previous callbacks. | ||
| 318 | The goal of this callback is to tell the driver to restart activity, | ||
| 319 | that everything is back and running. This callback does not return | ||
| 320 | a result code. | ||
| 321 | |||
| 322 | At this point, if a new error happens, the platform will restart | ||
| 323 | a new error recovery sequence. | ||
| 324 | |||
| 325 | STEP 6: Permanent Failure | ||
| 326 | ------------------------- | ||
| 327 | A "permanent failure" has occurred, and the platform cannot recover | ||
| 328 | the device. The platform will call error_detected() with a | ||
| 329 | pci_channel_state value of pci_channel_io_perm_failure. | ||
| 330 | |||
| 331 | The device driver should, at this point, assume the worst. It should | ||
| 332 | cancel all pending I/O, refuse all new I/O, returning -EIO to | ||
| 333 | higher layers. The device driver should then clean up all of its | ||
| 334 | memory and remove itself from kernel operations, much as it would | ||
| 335 | during system shutdown. | ||
| 336 | |||
| 337 | The platform will typically notify the system operator of the | ||
| 338 | permanent failure in some way. If the device is hotplug-capable, | ||
| 339 | the operator will probably want to remove and replace the device. | ||
| 340 | Note, however, not all failures are truly "permanent". Some are | ||
| 341 | caused by over-heating, some by a poorly seated card. Many | ||
| 342 | PCI error events are caused by software bugs, e.g. DMA's to | ||
| 343 | wild addresses or bogus split transactions due to programming | ||
| 344 | errors. See the discussion in powerpc/eeh-pci-error-recovery.txt | ||
| 345 | for additional detail on real-life experience of the causes of | ||
| 346 | software errors. | ||
| 347 | |||
| 348 | |||
| 349 | Conclusion; General Remarks | ||
| 350 | --------------------------- | ||
| 351 | The way those callbacks are called is platform policy. A platform with | ||
| 352 | no slot reset capability may want to just "ignore" drivers that can't | ||
| 216 | recover (disconnect them) and try to let other cards on the same segment | 353 | recover (disconnect them) and try to let other cards on the same segment |
| 217 | recover. Keep in mind that in most real life cases, though, there will | 354 | recover. Keep in mind that in most real life cases, though, there will |
| 218 | be only one driver per segment. | 355 | be only one driver per segment. |
| 219 | 356 | ||
| 220 | Now, there is a note about interrupts. If you get an interrupt and your | 357 | Now, a note about interrupts. If you get an interrupt and your |
| 221 | device is dead or has been isolated, there is a problem :) | 358 | device is dead or has been isolated, there is a problem :) |
| 222 | 359 | The current policy is to turn this into a platform policy. | |
| 223 | After much thinking, I decided to leave that to the platform. That is, | 360 | That is, the recovery API only requires that: |
| 224 | the recovery API only precies that: | ||
| 225 | 361 | ||
| 226 | - There is no guarantee that interrupt delivery can proceed from any | 362 | - There is no guarantee that interrupt delivery can proceed from any |
| 227 | device on the segment starting from the error detection and until the | 363 | device on the segment starting from the error detection and until the |
| 228 | restart callback is sent, at which point interrupts are expected to be | 364 | resume callback is sent, at which point interrupts are expected to be |
| 229 | fully operational. | 365 | fully operational. |
| 230 | 366 | ||
| 231 | - There is no guarantee that interrupt delivery is stopped, that is, ad | 367 | - There is no guarantee that interrupt delivery is stopped, that is, |
| 232 | river that gets an interrupts after detecting an error, or that detects | 368 | a driver that gets an interrupt after detecting an error, or that detects |
| 233 | and error within the interrupt handler such that it prevents proper | 369 | an error within the interrupt handler such that it prevents proper |
| 234 | ack'ing of the interrupt (and thus removal of the source) should just | 370 | ack'ing of the interrupt (and thus removal of the source) should just |
| 235 | return IRQ_NOTHANDLED. It's up to the platform to deal with taht | 371 | return IRQ_NOTHANDLED. It's up to the platform to deal with that |
| 236 | condition, typically by masking the irq source during the duration of | 372 | condition, typically by masking the IRQ source during the duration of |
| 237 | the error handling. It is expected that the platform "knows" which | 373 | the error handling. It is expected that the platform "knows" which |
| 238 | interrupts are routed to error-management capable slots and can deal | 374 | interrupts are routed to error-management capable slots and can deal |
| 239 | with temporarily disabling that irq number during error processing (this | 375 | with temporarily disabling that IRQ number during error processing (this |
| 240 | isn't terribly complex). That means some IRQ latency for other devices | 376 | isn't terribly complex). That means some IRQ latency for other devices |
| 241 | sharing the interrupt, but there is simply no other way. High end | 377 | sharing the interrupt, but there is simply no other way. High end |
| 242 | platforms aren't supposed to share interrupts between many devices | 378 | platforms aren't supposed to share interrupts between many devices |
| 243 | anyway :) | 379 | anyway :) |
| 244 | 380 | ||
| 245 | 381 | >>> Implementation details for the powerpc platform are discussed in | |
| 246 | Revised: 31 May 2005 Linas Vepstas <linas@austin.ibm.com> | 382 | >>> the file Documentation/powerpc/eeh-pci-error-recovery.txt |
| 383 | |||
| 384 | >>> As of this writing, there are six device drivers with patches | ||
| 385 | >>> implementing error recovery. Not all of these patches are in | ||
| 386 | >>> mainline yet. These may be used as "examples": | ||
| 387 | >>> | ||
| 388 | >>> drivers/scsi/ipr.c | ||
| 389 | >>> drivers/scsi/sym53cxx_2 | ||
| 390 | >>> drivers/next/e100.c | ||
| 391 | >>> drivers/net/e1000 | ||
| 392 | >>> drivers/net/ixgb | ||
| 393 | >>> drivers/net/s2io.c | ||
| 394 | |||
| 395 | The End | ||
| 396 | ------- | ||
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt index 1284498e847c..54e5f9b1536d 100644 --- a/Documentation/powerpc/booting-without-of.txt +++ b/Documentation/powerpc/booting-without-of.txt | |||
| @@ -880,6 +880,10 @@ address which can extend beyond that limit. | |||
| 880 | - device_type : Should be "soc" | 880 | - device_type : Should be "soc" |
| 881 | - ranges : Should be defined as specified in 1) to describe the | 881 | - ranges : Should be defined as specified in 1) to describe the |
| 882 | translation of SOC addresses for memory mapped SOC registers. | 882 | translation of SOC addresses for memory mapped SOC registers. |
| 883 | - bus-frequency: Contains the bus frequency for the SOC node. | ||
| 884 | Typically, the value of this field is filled in by the boot | ||
| 885 | loader. | ||
| 886 | |||
| 883 | 887 | ||
| 884 | Recommended properties: | 888 | Recommended properties: |
| 885 | 889 | ||
| @@ -919,6 +923,7 @@ SOC. | |||
| 919 | device_type = "soc"; | 923 | device_type = "soc"; |
| 920 | ranges = <00000000 e0000000 00100000> | 924 | ranges = <00000000 e0000000 00100000> |
| 921 | reg = <e0000000 00003000>; | 925 | reg = <e0000000 00003000>; |
| 926 | bus-frequency = <0>; | ||
| 922 | } | 927 | } |
| 923 | 928 | ||
| 924 | 929 | ||
| @@ -1170,6 +1175,8 @@ platforms are moved over to use the flattened-device-tree model. | |||
| 1170 | 1175 | ||
| 1171 | mdio@24520 { | 1176 | mdio@24520 { |
| 1172 | reg = <24520 20>; | 1177 | reg = <24520 20>; |
| 1178 | device_type = "mdio"; | ||
| 1179 | compatible = "gianfar"; | ||
| 1173 | 1180 | ||
| 1174 | ethernet-phy@0 { | 1181 | ethernet-phy@0 { |
| 1175 | ...... | 1182 | ...... |
| @@ -1317,6 +1324,7 @@ not necessary as they are usually the same as the root node. | |||
| 1317 | device_type = "soc"; | 1324 | device_type = "soc"; |
| 1318 | ranges = <00000000 e0000000 00100000> | 1325 | ranges = <00000000 e0000000 00100000> |
| 1319 | reg = <e0000000 00003000>; | 1326 | reg = <e0000000 00003000>; |
| 1327 | bus-frequency = <0>; | ||
| 1320 | 1328 | ||
| 1321 | mdio@24520 { | 1329 | mdio@24520 { |
| 1322 | reg = <24520 20>; | 1330 | reg = <24520 20>; |
diff --git a/Documentation/spi/butterfly b/Documentation/spi/butterfly index a2e8c8d90e35..9927af7a629c 100644 --- a/Documentation/spi/butterfly +++ b/Documentation/spi/butterfly | |||
| @@ -12,13 +12,20 @@ You can make this adapter from an old printer cable and solder things | |||
| 12 | directly to the Butterfly. Or (if you have the parts and skills) you | 12 | directly to the Butterfly. Or (if you have the parts and skills) you |
| 13 | can come up with something fancier, providing ciruit protection to the | 13 | can come up with something fancier, providing ciruit protection to the |
| 14 | Butterfly and the printer port, or with a better power supply than two | 14 | Butterfly and the printer port, or with a better power supply than two |
| 15 | signal pins from the printer port. | 15 | signal pins from the printer port. Or for that matter, you can use |
| 16 | similar cables to talk to many AVR boards, even a breadboard. | ||
| 17 | |||
| 18 | This is more powerful than "ISP programming" cables since it lets kernel | ||
| 19 | SPI protocol drivers interact with the AVR, and could even let the AVR | ||
| 20 | issue interrupts to them. Later, your protocol driver should work | ||
| 21 | easily with a "real SPI controller", instead of this bitbanger. | ||
| 16 | 22 | ||
| 17 | 23 | ||
| 18 | The first cable connections will hook Linux up to one SPI bus, with the | 24 | The first cable connections will hook Linux up to one SPI bus, with the |
| 19 | AVR and a DataFlash chip; and to the AVR reset line. This is all you | 25 | AVR and a DataFlash chip; and to the AVR reset line. This is all you |
| 20 | need to reflash the firmware, and the pins are the standard Atmel "ISP" | 26 | need to reflash the firmware, and the pins are the standard Atmel "ISP" |
| 21 | connector pins (used also on non-Butterfly AVR boards). | 27 | connector pins (used also on non-Butterfly AVR boards). On the parport |
| 28 | side this is like "sp12" programming cables. | ||
| 22 | 29 | ||
| 23 | Signal Butterfly Parport (DB-25) | 30 | Signal Butterfly Parport (DB-25) |
| 24 | ------ --------- --------------- | 31 | ------ --------- --------------- |
| @@ -40,10 +47,14 @@ by clearing PORTB.[0-3]); (b) configure the mtd_dataflash driver; and | |||
| 40 | SELECT = J400.PB0/nSS = pin 17/C3,nSELECT | 47 | SELECT = J400.PB0/nSS = pin 17/C3,nSELECT |
| 41 | GND = J400.GND = pin 24/GND | 48 | GND = J400.GND = pin 24/GND |
| 42 | 49 | ||
| 43 | The "USI" controller, using J405, can be used for a second SPI bus. That | 50 | Or you could flash firmware making the AVR into an SPI slave (keeping the |
| 44 | would let you talk to the AVR over SPI, running firmware that makes it act | 51 | DataFlash in reset) and tweak the spi_butterfly driver to make it bind to |
| 45 | as an SPI slave, while letting either Linux or the AVR use the DataFlash. | 52 | the driver for your custom SPI-based protocol. |
| 46 | There are plenty of spare parport pins to wire this one up, such as: | 53 | |
| 54 | The "USI" controller, using J405, can also be used for a second SPI bus. | ||
| 55 | That would let you talk to the AVR using custom SPI-with-USI firmware, | ||
| 56 | while letting either Linux or the AVR use the DataFlash. There are plenty | ||
| 57 | of spare parport pins to wire this one up, such as: | ||
| 47 | 58 | ||
| 48 | Signal Butterfly Parport (DB-25) | 59 | Signal Butterfly Parport (DB-25) |
| 49 | ------ --------- --------------- | 60 | ------ --------- --------------- |
diff --git a/Documentation/unshare.txt b/Documentation/unshare.txt new file mode 100644 index 000000000000..90a5e9e5bef1 --- /dev/null +++ b/Documentation/unshare.txt | |||
| @@ -0,0 +1,295 @@ | |||
| 1 | |||
| 2 | unshare system call: | ||
| 3 | -------------------- | ||
| 4 | This document describes the new system call, unshare. The document | ||
| 5 | provides an overview of the feature, why it is needed, how it can | ||
| 6 | be used, its interface specification, design, implementation and | ||
| 7 | how it can be tested. | ||
| 8 | |||
| 9 | Change Log: | ||
| 10 | ----------- | ||
| 11 | version 0.1 Initial document, Janak Desai (janak@us.ibm.com), Jan 11, 2006 | ||
| 12 | |||
| 13 | Contents: | ||
| 14 | --------- | ||
| 15 | 1) Overview | ||
| 16 | 2) Benefits | ||
| 17 | 3) Cost | ||
| 18 | 4) Requirements | ||
| 19 | 5) Functional Specification | ||
| 20 | 6) High Level Design | ||
| 21 | 7) Low Level Design | ||
| 22 | 8) Test Specification | ||
| 23 | 9) Future Work | ||
| 24 | |||
| 25 | 1) Overview | ||
| 26 | ----------- | ||
| 27 | Most legacy operating system kernels support an abstraction of threads | ||
| 28 | as multiple execution contexts within a process. These kernels provide | ||
| 29 | special resources and mechanisms to maintain these "threads". The Linux | ||
| 30 | kernel, in a clever and simple manner, does not make distinction | ||
| 31 | between processes and "threads". The kernel allows processes to share | ||
| 32 | resources and thus they can achieve legacy "threads" behavior without | ||
| 33 | requiring additional data structures and mechanisms in the kernel. The | ||
| 34 | power of implementing threads in this manner comes not only from | ||
| 35 | its simplicity but also from allowing application programmers to work | ||
| 36 | outside the confinement of all-or-nothing shared resources of legacy | ||
| 37 | threads. On Linux, at the time of thread creation using the clone system | ||
| 38 | call, applications can selectively choose which resources to share | ||
| 39 | between threads. | ||
| 40 | |||
| 41 | unshare system call adds a primitive to the Linux thread model that | ||
| 42 | allows threads to selectively 'unshare' any resources that were being | ||
| 43 | shared at the time of their creation. unshare was conceptualized by | ||
| 44 | Al Viro in the August of 2000, on the Linux-Kernel mailing list, as part | ||
| 45 | of the discussion on POSIX threads on Linux. unshare augments the | ||
| 46 | usefulness of Linux threads for applications that would like to control | ||
| 47 | shared resources without creating a new process. unshare is a natural | ||
| 48 | addition to the set of available primitives on Linux that implement | ||
| 49 | the concept of process/thread as a virtual machine. | ||
| 50 | |||
| 51 | 2) Benefits | ||
| 52 | ----------- | ||
| 53 | unshare would be useful to large application frameworks such as PAM | ||
| 54 | where creating a new process to control sharing/unsharing of process | ||
| 55 | resources is not possible. Since namespaces are shared by default | ||
| 56 | when creating a new process using fork or clone, unshare can benefit | ||
| 57 | even non-threaded applications if they have a need to disassociate | ||
| 58 | from default shared namespace. The following lists two use-cases | ||
| 59 | where unshare can be used. | ||
| 60 | |||
| 61 | 2.1 Per-security context namespaces | ||
| 62 | ----------------------------------- | ||
| 63 | unshare can be used to implement polyinstantiated directories using | ||
| 64 | the kernel's per-process namespace mechanism. Polyinstantiated directories, | ||
| 65 | such as per-user and/or per-security context instance of /tmp, /var/tmp or | ||
| 66 | per-security context instance of a user's home directory, isolate user | ||
| 67 | processes when working with these directories. Using unshare, a PAM | ||
| 68 | module can easily setup a private namespace for a user at login. | ||
| 69 | Polyinstantiated directories are required for Common Criteria certification | ||
| 70 | with Labeled System Protection Profile, however, with the availability | ||
| 71 | of shared-tree feature in the Linux kernel, even regular Linux systems | ||
| 72 | can benefit from setting up private namespaces at login and | ||
| 73 | polyinstantiating /tmp, /var/tmp and other directories deemed | ||
| 74 | appropriate by system administrators. | ||
| 75 | |||
| 76 | 2.2 unsharing of virtual memory and/or open files | ||
| 77 | ------------------------------------------------- | ||
| 78 | Consider a client/server application where the server is processing | ||
| 79 | client requests by creating processes that share resources such as | ||
| 80 | virtual memory and open files. Without unshare, the server has to | ||
| 81 | decide what needs to be shared at the time of creating the process | ||
| 82 | which services the request. unshare allows the server an ability to | ||
| 83 | disassociate parts of the context during the servicing of the | ||
| 84 | request. For large and complex middleware application frameworks, this | ||
| 85 | ability to unshare after the process was created can be very | ||
| 86 | useful. | ||
| 87 | |||
| 88 | 3) Cost | ||
| 89 | ------- | ||
| 90 | In order to not duplicate code and to handle the fact that unshare | ||
| 91 | works on an active task (as opposed to clone/fork working on a newly | ||
| 92 | allocated inactive task) unshare had to make minor reorganizational | ||
| 93 | changes to copy_* functions utilized by clone/fork system call. | ||
| 94 | There is a cost associated with altering existing, well tested and | ||
| 95 | stable code to implement a new feature that may not get exercised | ||
| 96 | extensively in the beginning. However, with proper design and code | ||
| 97 | review of the changes and creation of an unshare test for the LTP | ||
| 98 | the benefits of this new feature can exceed its cost. | ||
| 99 | |||
| 100 | 4) Requirements | ||
| 101 | --------------- | ||
| 102 | unshare reverses sharing that was done using clone(2) system call, | ||
| 103 | so unshare should have a similar interface as clone(2). That is, | ||
| 104 | since flags in clone(int flags, void *stack) specifies what should | ||
| 105 | be shared, similar flags in unshare(int flags) should specify | ||
| 106 | what should be unshared. Unfortunately, this may appear to invert | ||
| 107 | the meaning of the flags from the way they are used in clone(2). | ||
| 108 | However, there was no easy solution that was less confusing and that | ||
| 109 | allowed incremental context unsharing in future without an ABI change. | ||
| 110 | |||
| 111 | unshare interface should accommodate possible future addition of | ||
| 112 | new context flags without requiring a rebuild of old applications. | ||
| 113 | If and when new context flags are added, unshare design should allow | ||
| 114 | incremental unsharing of those resources on an as needed basis. | ||
| 115 | |||
| 116 | 5) Functional Specification | ||
| 117 | --------------------------- | ||
| 118 | NAME | ||
| 119 | unshare - disassociate parts of the process execution context | ||
| 120 | |||
| 121 | SYNOPSIS | ||
| 122 | #include <sched.h> | ||
| 123 | |||
| 124 | int unshare(int flags); | ||
| 125 | |||
| 126 | DESCRIPTION | ||
| 127 | unshare allows a process to disassociate parts of its execution | ||
| 128 | context that are currently being shared with other processes. Part | ||
| 129 | of execution context, such as the namespace, is shared by default | ||
| 130 | when a new process is created using fork(2), while other parts, | ||
| 131 | such as the virtual memory, open file descriptors, etc, may be | ||
| 132 | shared by explicit request to share them when creating a process | ||
| 133 | using clone(2). | ||
| 134 | |||
| 135 | The main use of unshare is to allow a process to control its | ||
| 136 | shared execution context without creating a new process. | ||
| 137 | |||
| 138 | The flags argument specifies one or bitwise-or'ed of several of | ||
| 139 | the following constants. | ||
| 140 | |||
| 141 | CLONE_FS | ||
| 142 | If CLONE_FS is set, file system information of the caller | ||
| 143 | is disassociated from the shared file system information. | ||
| 144 | |||
| 145 | CLONE_FILES | ||
| 146 | If CLONE_FILES is set, the file descriptor table of the | ||
| 147 | caller is disassociated from the shared file descriptor | ||
| 148 | table. | ||
| 149 | |||
| 150 | CLONE_NEWNS | ||
| 151 | If CLONE_NEWNS is set, the namespace of the caller is | ||
| 152 | disassociated from the shared namespace. | ||
| 153 | |||
| 154 | CLONE_VM | ||
| 155 | If CLONE_VM is set, the virtual memory of the caller is | ||
| 156 | disassociated from the shared virtual memory. | ||
| 157 | |||
| 158 | RETURN VALUE | ||
| 159 | On success, zero returned. On failure, -1 is returned and errno is | ||
| 160 | |||
| 161 | ERRORS | ||
| 162 | EPERM CLONE_NEWNS was specified by a non-root process (process | ||
| 163 | without CAP_SYS_ADMIN). | ||
| 164 | |||
| 165 | ENOMEM Cannot allocate sufficient memory to copy parts of caller's | ||
| 166 | context that need to be unshared. | ||
| 167 | |||
| 168 | EINVAL Invalid flag was specified as an argument. | ||
| 169 | |||
| 170 | CONFORMING TO | ||
| 171 | The unshare() call is Linux-specific and should not be used | ||
| 172 | in programs intended to be portable. | ||
| 173 | |||
| 174 | SEE ALSO | ||
| 175 | clone(2), fork(2) | ||
| 176 | |||
| 177 | 6) High Level Design | ||
| 178 | -------------------- | ||
| 179 | Depending on the flags argument, the unshare system call allocates | ||
| 180 | appropriate process context structures, populates it with values from | ||
| 181 | the current shared version, associates newly duplicated structures | ||
| 182 | with the current task structure and releases corresponding shared | ||
| 183 | versions. Helper functions of clone (copy_*) could not be used | ||
| 184 | directly by unshare because of the following two reasons. | ||
| 185 | 1) clone operates on a newly allocated not-yet-active task | ||
| 186 | structure, where as unshare operates on the current active | ||
| 187 | task. Therefore unshare has to take appropriate task_lock() | ||
| 188 | before associating newly duplicated context structures | ||
| 189 | 2) unshare has to allocate and duplicate all context structures | ||
| 190 | that are being unshared, before associating them with the | ||
| 191 | current task and releasing older shared structures. Failure | ||
| 192 | do so will create race conditions and/or oops when trying | ||
| 193 | to backout due to an error. Consider the case of unsharing | ||
| 194 | both virtual memory and namespace. After successfully unsharing | ||
| 195 | vm, if the system call encounters an error while allocating | ||
| 196 | new namespace structure, the error return code will have to | ||
| 197 | reverse the unsharing of vm. As part of the reversal the | ||
| 198 | system call will have to go back to older, shared, vm | ||
| 199 | structure, which may not exist anymore. | ||
| 200 | |||
| 201 | Therefore code from copy_* functions that allocated and duplicated | ||
| 202 | current context structure was moved into new dup_* functions. Now, | ||
| 203 | copy_* functions call dup_* functions to allocate and duplicate | ||
| 204 | appropriate context structures and then associate them with the | ||
| 205 | task structure that is being constructed. unshare system call on | ||
| 206 | the other hand performs the following: | ||
| 207 | 1) Check flags to force missing, but implied, flags | ||
| 208 | 2) For each context structure, call the corresponding unshare | ||
| 209 | helper function to allocate and duplicate a new context | ||
| 210 | structure, if the appropriate bit is set in the flags argument. | ||
| 211 | 3) If there is no error in allocation and duplication and there | ||
| 212 | are new context structures then lock the current task structure, | ||
| 213 | associate new context structures with the current task structure, | ||
| 214 | and release the lock on the current task structure. | ||
| 215 | 4) Appropriately release older, shared, context structures. | ||
| 216 | |||
| 217 | 7) Low Level Design | ||
| 218 | ------------------- | ||
| 219 | Implementation of unshare can be grouped in the following 4 different | ||
| 220 | items: | ||
| 221 | a) Reorganization of existing copy_* functions | ||
| 222 | b) unshare system call service function | ||
| 223 | c) unshare helper functions for each different process context | ||
| 224 | d) Registration of system call number for different architectures | ||
| 225 | |||
| 226 | 7.1) Reorganization of copy_* functions | ||
| 227 | Each copy function such as copy_mm, copy_namespace, copy_files, | ||
| 228 | etc, had roughly two components. The first component allocated | ||
| 229 | and duplicated the appropriate structure and the second component | ||
| 230 | linked it to the task structure passed in as an argument to the copy | ||
| 231 | function. The first component was split into its own function. | ||
| 232 | These dup_* functions allocated and duplicated the appropriate | ||
| 233 | context structure. The reorganized copy_* functions invoked | ||
| 234 | their corresponding dup_* functions and then linked the newly | ||
| 235 | duplicated structures to the task structure with which the | ||
| 236 | copy function was called. | ||
| 237 | |||
| 238 | 7.2) unshare system call service function | ||
| 239 | * Check flags | ||
| 240 | Force implied flags. If CLONE_THREAD is set force CLONE_VM. | ||
| 241 | If CLONE_VM is set, force CLONE_SIGHAND. If CLONE_SIGHAND is | ||
| 242 | set and signals are also being shared, force CLONE_THREAD. If | ||
| 243 | CLONE_NEWNS is set, force CLONE_FS. | ||
| 244 | * For each context flag, invoke the corresponding unshare_* | ||
| 245 | helper routine with flags passed into the system call and a | ||
| 246 | reference to pointer pointing the new unshared structure | ||
| 247 | * If any new structures are created by unshare_* helper | ||
| 248 | functions, take the task_lock() on the current task, | ||
| 249 | modify appropriate context pointers, and release the | ||
| 250 | task lock. | ||
| 251 | * For all newly unshared structures, release the corresponding | ||
| 252 | older, shared, structures. | ||
| 253 | |||
| 254 | 7.3) unshare_* helper functions | ||
| 255 | For unshare_* helpers corresponding to CLONE_SYSVSEM, CLONE_SIGHAND, | ||
| 256 | and CLONE_THREAD, return -EINVAL since they are not implemented yet. | ||
| 257 | For others, check the flag value to see if the unsharing is | ||
| 258 | required for that structure. If it is, invoke the corresponding | ||
| 259 | dup_* function to allocate and duplicate the structure and return | ||
| 260 | a pointer to it. | ||
| 261 | |||
| 262 | 7.4) Appropriately modify architecture specific code to register the | ||
| 263 | the new system call. | ||
| 264 | |||
| 265 | 8) Test Specification | ||
| 266 | --------------------- | ||
| 267 | The test for unshare should test the following: | ||
| 268 | 1) Valid flags: Test to check that clone flags for signal and | ||
| 269 | signal handlers, for which unsharing is not implemented | ||
| 270 | yet, return -EINVAL. | ||
| 271 | 2) Missing/implied flags: Test to make sure that if unsharing | ||
| 272 | namespace without specifying unsharing of filesystem, correctly | ||
| 273 | unshares both namespace and filesystem information. | ||
| 274 | 3) For each of the four (namespace, filesystem, files and vm) | ||
| 275 | supported unsharing, verify that the system call correctly | ||
| 276 | unshares the appropriate structure. Verify that unsharing | ||
| 277 | them individually as well as in combination with each | ||
| 278 | other works as expected. | ||
| 279 | 4) Concurrent execution: Use shared memory segments and futex on | ||
| 280 | an address in the shm segment to synchronize execution of | ||
| 281 | about 10 threads. Have a couple of threads execute execve, | ||
| 282 | a couple _exit and the rest unshare with different combination | ||
| 283 | of flags. Verify that unsharing is performed as expected and | ||
| 284 | that there are no oops or hangs. | ||
| 285 | |||
| 286 | 9) Future Work | ||
| 287 | -------------- | ||
| 288 | The current implementation of unshare does not allow unsharing of | ||
| 289 | signals and signal handlers. Signals are complex to begin with and | ||
| 290 | to unshare signals and/or signal handlers of a currently running | ||
| 291 | process is even more complex. If in the future there is a specific | ||
| 292 | need to allow unsharing of signals and/or signal handlers, it can | ||
| 293 | be incrementally added to unshare without affecting legacy | ||
| 294 | applications using unshare. | ||
| 295 | |||
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88 index 56e194f1a0b0..8bea3fbd0548 100644 --- a/Documentation/video4linux/CARDLIST.cx88 +++ b/Documentation/video4linux/CARDLIST.cx88 | |||
| @@ -42,4 +42,4 @@ | |||
| 42 | 41 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile) [0070:9800,0070:9802] | 42 | 41 -> Hauppauge WinTV-HVR1100 DVB-T/Hybrid (Low Profile) [0070:9800,0070:9802] |
| 43 | 42 -> digitalnow DNTV Live! DVB-T Pro [1822:0025] | 43 | 42 -> digitalnow DNTV Live! DVB-T Pro [1822:0025] |
| 44 | 43 -> KWorld/VStream XPert DVB-T with cx22702 [17de:08a1] | 44 | 43 -> KWorld/VStream XPert DVB-T with cx22702 [17de:08a1] |
| 45 | 44 -> DViCO FusionHDTV DVB-T Dual Digital [18ac:db50] | 45 | 44 -> DViCO FusionHDTV DVB-T Dual Digital [18ac:db50,18ac:db54] |
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index cb3a59bbeb17..8a352597830f 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | 0 -> UNKNOWN/GENERIC | 1 | 0 -> UNKNOWN/GENERIC |
| 2 | 1 -> Proteus Pro [philips reference design] [1131:2001,1131:2001] | 2 | 1 -> Proteus Pro [philips reference design] [1131:2001,1131:2001] |
| 3 | 2 -> LifeView FlyVIDEO3000 [5168:0138,4e42:0138] | 3 | 2 -> LifeView FlyVIDEO3000 [5168:0138,4e42:0138] |
| 4 | 3 -> LifeView FlyVIDEO2000 [5168:0138] | 4 | 3 -> LifeView/Typhoon FlyVIDEO2000 [5168:0138,4e42:0138] |
| 5 | 4 -> EMPRESS [1131:6752] | 5 | 4 -> EMPRESS [1131:6752] |
| 6 | 5 -> SKNet Monster TV [1131:4e85] | 6 | 5 -> SKNet Monster TV [1131:4e85] |
| 7 | 6 -> Tevion MD 9717 | 7 | 6 -> Tevion MD 9717 |
| @@ -53,12 +53,12 @@ | |||
| 53 | 52 -> AverMedia AverTV/305 [1461:2108] | 53 | 52 -> AverMedia AverTV/305 [1461:2108] |
| 54 | 53 -> ASUS TV-FM 7135 [1043:4845] | 54 | 53 -> ASUS TV-FM 7135 [1043:4845] |
| 55 | 54 -> LifeView FlyTV Platinum FM [5168:0214,1489:0214] | 55 | 54 -> LifeView FlyTV Platinum FM [5168:0214,1489:0214] |
| 56 | 55 -> LifeView FlyDVB-T DUO [5168:0502,5168:0306] | 56 | 55 -> LifeView FlyDVB-T DUO [5168:0306] |
| 57 | 56 -> Avermedia AVerTV 307 [1461:a70a] | 57 | 56 -> Avermedia AVerTV 307 [1461:a70a] |
| 58 | 57 -> Avermedia AVerTV GO 007 FM [1461:f31f] | 58 | 57 -> Avermedia AVerTV GO 007 FM [1461:f31f] |
| 59 | 58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0351,1421:0370,1421:1370] | 59 | 58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0351,1421:0370,1421:1370] |
| 60 | 59 -> Kworld/Tevion V-Stream Xpert TV PVR7134 | 60 | 59 -> Kworld/Tevion V-Stream Xpert TV PVR7134 |
| 61 | 60 -> Typhoon DVB-T Duo Digital/Analog Cardbus [4e42:0502] | 61 | 60 -> LifeView/Typhoon FlyDVB-T Duo Cardbus [5168:0502,4e42:0502] |
| 62 | 61 -> Philips TOUGH DVB-T reference design [1131:2004] | 62 | 61 -> Philips TOUGH DVB-T reference design [1131:2004] |
| 63 | 62 -> Compro VideoMate TV Gold+II | 63 | 62 -> Compro VideoMate TV Gold+II |
| 64 | 63 -> Kworld Xpert TV PVR7134 | 64 | 63 -> Kworld Xpert TV PVR7134 |
diff --git a/Documentation/x86_64/boot-options.txt b/Documentation/x86_64/boot-options.txt index 9c5fc15d03d1..153740f460a6 100644 --- a/Documentation/x86_64/boot-options.txt +++ b/Documentation/x86_64/boot-options.txt | |||
| @@ -40,6 +40,18 @@ APICs | |||
| 40 | no_timer_check Don't check the IO-APIC timer. This can work around | 40 | no_timer_check Don't check the IO-APIC timer. This can work around |
| 41 | problems with incorrect timer initialization on some boards. | 41 | problems with incorrect timer initialization on some boards. |
| 42 | 42 | ||
| 43 | apicmaintimer Run time keeping from the local APIC timer instead | ||
| 44 | of using the PIT/HPET interrupt for this. This is useful | ||
| 45 | when the PIT/HPET interrupts are unreliable. | ||
| 46 | |||
| 47 | noapicmaintimer Don't do time keeping using the APIC timer. | ||
| 48 | Useful when this option was auto selected, but doesn't work. | ||
| 49 | |||
| 50 | apicpmtimer | ||
| 51 | Do APIC timer calibration using the pmtimer. Implies | ||
| 52 | apicmaintimer. Useful when your PIT timer is totally | ||
| 53 | broken. | ||
| 54 | |||
| 43 | Early Console | 55 | Early Console |
| 44 | 56 | ||
| 45 | syntax: earlyprintk=vga | 57 | syntax: earlyprintk=vga |
diff --git a/MAINTAINERS b/MAINTAINERS index 42955fe1ffa0..b22db521cec1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -540,7 +540,8 @@ S: Supported | |||
| 540 | 540 | ||
| 541 | BTTV VIDEO4LINUX DRIVER | 541 | BTTV VIDEO4LINUX DRIVER |
| 542 | P: Mauro Carvalho Chehab | 542 | P: Mauro Carvalho Chehab |
| 543 | M: mchehab@brturbo.com.br | 543 | M: mchehab@infradead.org |
| 544 | M: v4l-dvb-maintainer@linuxtv.org | ||
| 544 | L: video4linux-list@redhat.com | 545 | L: video4linux-list@redhat.com |
| 545 | W: http://linuxtv.org | 546 | W: http://linuxtv.org |
| 546 | T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git | 547 | T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git |
| @@ -557,7 +558,8 @@ S: Supported | |||
| 557 | 558 | ||
| 558 | CONFIGFS | 559 | CONFIGFS |
| 559 | P: Joel Becker | 560 | P: Joel Becker |
| 560 | M: Joel Becker <joel.becker@oracle.com> | 561 | M: joel.becker@oracle.com |
| 562 | L: linux-kernel@vger.kernel.org | ||
| 561 | S: Supported | 563 | S: Supported |
| 562 | 564 | ||
| 563 | CIRRUS LOGIC GENERIC FBDEV DRIVER | 565 | CIRRUS LOGIC GENERIC FBDEV DRIVER |
| @@ -836,11 +838,12 @@ S: Maintained | |||
| 836 | 838 | ||
| 837 | DVB SUBSYSTEM AND DRIVERS | 839 | DVB SUBSYSTEM AND DRIVERS |
| 838 | P: LinuxTV.org Project | 840 | P: LinuxTV.org Project |
| 839 | M: linux-dvb-maintainer@linuxtv.org | 841 | M: mchehab@infradead.org |
| 842 | M: v4l-dvb-maintainer@linuxtv.org | ||
| 840 | L: linux-dvb@linuxtv.org (subscription required) | 843 | L: linux-dvb@linuxtv.org (subscription required) |
| 841 | W: http://linuxtv.org/ | 844 | W: http://linuxtv.org/ |
| 842 | T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git | 845 | T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git |
| 843 | S: Supported | 846 | S: Maintained |
| 844 | 847 | ||
| 845 | EATA-DMA SCSI DRIVER | 848 | EATA-DMA SCSI DRIVER |
| 846 | P: Michael Neuffer | 849 | P: Michael Neuffer |
| @@ -928,6 +931,12 @@ M: sct@redhat.com, akpm@osdl.org, adilger@clusterfs.com | |||
| 928 | L: ext3-users@redhat.com | 931 | L: ext3-users@redhat.com |
| 929 | S: Maintained | 932 | S: Maintained |
| 930 | 933 | ||
| 934 | F71805F HARDWARE MONITORING DRIVER | ||
| 935 | P: Jean Delvare | ||
| 936 | M: khali@linux-fr.org | ||
| 937 | L: lm-sensors@lm-sensors.org | ||
| 938 | S: Maintained | ||
| 939 | |||
| 931 | FARSYNC SYNCHRONOUS DRIVER | 940 | FARSYNC SYNCHRONOUS DRIVER |
| 932 | P: Kevin Curtis | 941 | P: Kevin Curtis |
| 933 | M: kevin.curtis@farsite.co.uk | 942 | M: kevin.curtis@farsite.co.uk |
| @@ -1984,7 +1993,6 @@ M: philb@gnu.org | |||
| 1984 | P: Tim Waugh | 1993 | P: Tim Waugh |
| 1985 | M: tim@cyberelk.net | 1994 | M: tim@cyberelk.net |
| 1986 | P: David Campbell | 1995 | P: David Campbell |
| 1987 | M: campbell@torque.net | ||
| 1988 | P: Andrea Arcangeli | 1996 | P: Andrea Arcangeli |
| 1989 | M: andrea@suse.de | 1997 | M: andrea@suse.de |
| 1990 | L: linux-parport@lists.infradead.org | 1998 | L: linux-parport@lists.infradead.org |
| @@ -2298,7 +2306,7 @@ S: Supported | |||
| 2298 | 2306 | ||
| 2299 | SELINUX SECURITY MODULE | 2307 | SELINUX SECURITY MODULE |
| 2300 | P: Stephen Smalley | 2308 | P: Stephen Smalley |
| 2301 | M: sds@epoch.ncsc.mil | 2309 | M: sds@tycho.nsa.gov |
| 2302 | P: James Morris | 2310 | P: James Morris |
| 2303 | M: jmorris@namei.org | 2311 | M: jmorris@namei.org |
| 2304 | L: linux-kernel@vger.kernel.org (kernel issues) | 2312 | L: linux-kernel@vger.kernel.org (kernel issues) |
| @@ -2956,7 +2964,8 @@ S: Maintained | |||
| 2956 | 2964 | ||
| 2957 | VIDEO FOR LINUX | 2965 | VIDEO FOR LINUX |
| 2958 | P: Mauro Carvalho Chehab | 2966 | P: Mauro Carvalho Chehab |
| 2959 | M: mchehab@brturbo.com.br | 2967 | M: mchehab@infradead.org |
| 2968 | M: v4l-dvb-maintainer@linuxtv.org | ||
| 2960 | L: video4linux-list@redhat.com | 2969 | L: video4linux-list@redhat.com |
| 2961 | W: http://linuxtv.org | 2970 | W: http://linuxtv.org |
| 2962 | T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git | 2971 | T: git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git |
| @@ -1,7 +1,7 @@ | |||
| 1 | VERSION = 2 | 1 | VERSION = 2 |
| 2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
| 3 | SUBLEVEL = 16 | 3 | SUBLEVEL = 16 |
| 4 | EXTRAVERSION =-rc1 | 4 | EXTRAVERSION =-rc2 |
| 5 | NAME=Sliding Snow Leopard | 5 | NAME=Sliding Snow Leopard |
| 6 | 6 | ||
| 7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
| @@ -442,7 +442,7 @@ export KBUILD_DEFCONFIG | |||
| 442 | config %config: scripts_basic outputmakefile FORCE | 442 | config %config: scripts_basic outputmakefile FORCE |
| 443 | $(Q)mkdir -p include/linux | 443 | $(Q)mkdir -p include/linux |
| 444 | $(Q)$(MAKE) $(build)=scripts/kconfig $@ | 444 | $(Q)$(MAKE) $(build)=scripts/kconfig $@ |
| 445 | $(Q)$(MAKE) .kernelrelease | 445 | $(Q)$(MAKE) -C $(srctree) KBUILD_SRC= .kernelrelease |
| 446 | 446 | ||
| 447 | else | 447 | else |
| 448 | # =========================================================================== | 448 | # =========================================================================== |
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 4b873527ce1c..02c2db08114a 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c | |||
| @@ -73,9 +73,6 @@ cpumask_t cpu_online_map; | |||
| 73 | 73 | ||
| 74 | EXPORT_SYMBOL(cpu_online_map); | 74 | EXPORT_SYMBOL(cpu_online_map); |
| 75 | 75 | ||
| 76 | /* cpus reported in the hwrpb */ | ||
| 77 | static unsigned long hwrpb_cpu_present_mask __initdata = 0; | ||
| 78 | |||
| 79 | int smp_num_probed; /* Internal processor count */ | 76 | int smp_num_probed; /* Internal processor count */ |
| 80 | int smp_num_cpus = 1; /* Number that came online. */ | 77 | int smp_num_cpus = 1; /* Number that came online. */ |
| 81 | 78 | ||
| @@ -442,7 +439,7 @@ setup_smp(void) | |||
| 442 | if ((cpu->flags & 0x1cc) == 0x1cc) { | 439 | if ((cpu->flags & 0x1cc) == 0x1cc) { |
| 443 | smp_num_probed++; | 440 | smp_num_probed++; |
| 444 | /* Assume here that "whami" == index */ | 441 | /* Assume here that "whami" == index */ |
| 445 | hwrpb_cpu_present_mask |= (1UL << i); | 442 | cpu_set(i, cpu_possible_map); |
| 446 | cpu->pal_revision = boot_cpu_palrev; | 443 | cpu->pal_revision = boot_cpu_palrev; |
| 447 | } | 444 | } |
| 448 | 445 | ||
| @@ -453,12 +450,12 @@ setup_smp(void) | |||
| 453 | } | 450 | } |
| 454 | } else { | 451 | } else { |
| 455 | smp_num_probed = 1; | 452 | smp_num_probed = 1; |
| 456 | hwrpb_cpu_present_mask = (1UL << boot_cpuid); | 453 | cpu_set(boot_cpuid, cpu_possible_map); |
| 457 | } | 454 | } |
| 458 | cpu_present_mask = cpumask_of_cpu(boot_cpuid); | 455 | cpu_present_mask = cpumask_of_cpu(boot_cpuid); |
| 459 | 456 | ||
| 460 | printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n", | 457 | printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n", |
| 461 | smp_num_probed, hwrpb_cpu_present_mask); | 458 | smp_num_probed, cpu_possible_map.bits[0]); |
| 462 | } | 459 | } |
| 463 | 460 | ||
| 464 | /* | 461 | /* |
| @@ -467,8 +464,6 @@ setup_smp(void) | |||
| 467 | void __init | 464 | void __init |
| 468 | smp_prepare_cpus(unsigned int max_cpus) | 465 | smp_prepare_cpus(unsigned int max_cpus) |
| 469 | { | 466 | { |
| 470 | int cpu_count, i; | ||
| 471 | |||
| 472 | /* Take care of some initial bookkeeping. */ | 467 | /* Take care of some initial bookkeeping. */ |
| 473 | memset(ipi_data, 0, sizeof(ipi_data)); | 468 | memset(ipi_data, 0, sizeof(ipi_data)); |
| 474 | 469 | ||
| @@ -486,19 +481,7 @@ smp_prepare_cpus(unsigned int max_cpus) | |||
| 486 | 481 | ||
| 487 | printk(KERN_INFO "SMP starting up secondaries.\n"); | 482 | printk(KERN_INFO "SMP starting up secondaries.\n"); |
| 488 | 483 | ||
| 489 | cpu_count = 1; | 484 | smp_num_cpus = smp_num_probed; |
| 490 | for (i = 0; (i < NR_CPUS) && (cpu_count < max_cpus); i++) { | ||
| 491 | if (i == boot_cpuid) | ||
| 492 | continue; | ||
| 493 | |||
| 494 | if (((hwrpb_cpu_present_mask >> i) & 1) == 0) | ||
| 495 | continue; | ||
| 496 | |||
| 497 | cpu_set(i, cpu_possible_map); | ||
| 498 | cpu_count++; | ||
| 499 | } | ||
| 500 | |||
| 501 | smp_num_cpus = cpu_count; | ||
| 502 | } | 485 | } |
| 503 | 486 | ||
| 504 | void __devinit | 487 | void __devinit |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5959e36c3b4c..15dc1a0dffbb 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
| @@ -10,9 +10,9 @@ config ARM | |||
| 10 | default y | 10 | default y |
| 11 | help | 11 | help |
| 12 | The ARM series is a line of low-power-consumption RISC chip designs | 12 | The ARM series is a line of low-power-consumption RISC chip designs |
| 13 | licensed by ARM ltd and targeted at embedded applications and | 13 | licensed by ARM Ltd and targeted at embedded applications and |
| 14 | handhelds such as the Compaq IPAQ. ARM-based PCs are no longer | 14 | handhelds such as the Compaq IPAQ. ARM-based PCs are no longer |
| 15 | manufactured, but legacy ARM-based PC hardware remains popular in | 15 | manufactured, but legacy ARM-based PC hardware remains popular in |
| 16 | Europe. There is an ARM Linux project with a web page at | 16 | Europe. There is an ARM Linux project with a web page at |
| 17 | <http://www.arm.linux.org.uk/>. | 17 | <http://www.arm.linux.org.uk/>. |
| 18 | 18 | ||
| @@ -69,6 +69,9 @@ config GENERIC_ISA_DMA | |||
| 69 | config FIQ | 69 | config FIQ |
| 70 | bool | 70 | bool |
| 71 | 71 | ||
| 72 | config ARCH_MTD_XIP | ||
| 73 | bool | ||
| 74 | |||
| 72 | source "init/Kconfig" | 75 | source "init/Kconfig" |
| 73 | 76 | ||
| 74 | menu "System Type" | 77 | menu "System Type" |
| @@ -81,45 +84,62 @@ config ARCH_CLPS7500 | |||
| 81 | bool "Cirrus-CL-PS7500FE" | 84 | bool "Cirrus-CL-PS7500FE" |
| 82 | select TIMER_ACORN | 85 | select TIMER_ACORN |
| 83 | select ISA | 86 | select ISA |
| 87 | help | ||
| 88 | Support for the Cirrus Logic PS7500FE system-on-a-chip. | ||
| 84 | 89 | ||
| 85 | config ARCH_CLPS711X | 90 | config ARCH_CLPS711X |
| 86 | bool "CLPS711x/EP721x-based" | 91 | bool "CLPS711x/EP721x-based" |
| 92 | help | ||
| 93 | Support for Cirrus Logic 711x/721x based boards. | ||
| 87 | 94 | ||
| 88 | config ARCH_CO285 | 95 | config ARCH_CO285 |
| 89 | bool "Co-EBSA285" | 96 | bool "Co-EBSA285" |
| 90 | select FOOTBRIDGE | 97 | select FOOTBRIDGE |
| 91 | select FOOTBRIDGE_ADDIN | 98 | select FOOTBRIDGE_ADDIN |
| 99 | help | ||
| 100 | Support for Intel's EBSA285 companion chip. | ||
| 92 | 101 | ||
| 93 | config ARCH_EBSA110 | 102 | config ARCH_EBSA110 |
| 94 | bool "EBSA-110" | 103 | bool "EBSA-110" |
| 95 | select ISA | 104 | select ISA |
| 96 | help | 105 | help |
| 97 | This is an evaluation board for the StrongARM processor available | 106 | This is an evaluation board for the StrongARM processor available |
| 98 | from Digital. It has limited hardware on-board, including an onboard | 107 | from Digital. It has limited hardware on-board, including an |
| 99 | Ethernet interface, two PCMCIA sockets, two serial ports and a | 108 | Ethernet interface, two PCMCIA sockets, two serial ports and a |
| 100 | parallel port. | 109 | parallel port. |
| 101 | 110 | ||
| 102 | config ARCH_FOOTBRIDGE | 111 | config ARCH_FOOTBRIDGE |
| 103 | bool "FootBridge" | 112 | bool "FootBridge" |
| 104 | select FOOTBRIDGE | 113 | select FOOTBRIDGE |
| 114 | help | ||
| 115 | Support for systems based on the DC21285 companion chip | ||
| 116 | ("FootBridge"), such as the Simtec CATS and the Rebel NetWinder. | ||
| 105 | 117 | ||
| 106 | config ARCH_INTEGRATOR | 118 | config ARCH_INTEGRATOR |
| 107 | bool "Integrator" | 119 | bool "Integrator" |
| 108 | select ARM_AMBA | 120 | select ARM_AMBA |
| 109 | select ICST525 | 121 | select ICST525 |
| 122 | help | ||
| 123 | Support for ARM's Integrator platform. | ||
| 110 | 124 | ||
| 111 | config ARCH_IOP3XX | 125 | config ARCH_IOP3XX |
| 112 | bool "IOP3xx-based" | 126 | bool "IOP3xx-based" |
| 113 | select PCI | 127 | select PCI |
| 128 | help | ||
| 129 | Support for Intel's IOP3XX (XScale) family of processors. | ||
| 114 | 130 | ||
| 115 | config ARCH_IXP4XX | 131 | config ARCH_IXP4XX |
| 116 | bool "IXP4xx-based" | 132 | bool "IXP4xx-based" |
| 117 | select DMABOUNCE | 133 | select DMABOUNCE |
| 118 | select PCI | 134 | select PCI |
| 135 | help | ||
| 136 | Support for Intel's IXP4XX (XScale) family of processors. | ||
| 119 | 137 | ||
| 120 | config ARCH_IXP2000 | 138 | config ARCH_IXP2000 |
| 121 | bool "IXP2400/2800-based" | 139 | bool "IXP2400/2800-based" |
| 122 | select PCI | 140 | select PCI |
| 141 | help | ||
| 142 | Support for Intel's IXP2400/2800 (XScale) family of processors. | ||
| 123 | 143 | ||
| 124 | config ARCH_L7200 | 144 | config ARCH_L7200 |
| 125 | bool "LinkUp-L7200" | 145 | bool "LinkUp-L7200" |
| @@ -136,6 +156,9 @@ config ARCH_L7200 | |||
| 136 | 156 | ||
| 137 | config ARCH_PXA | 157 | config ARCH_PXA |
| 138 | bool "PXA2xx-based" | 158 | bool "PXA2xx-based" |
| 159 | select ARCH_MTD_XIP | ||
| 160 | help | ||
| 161 | Support for Intel's PXA2XX processor line. | ||
| 139 | 162 | ||
| 140 | config ARCH_RPC | 163 | config ARCH_RPC |
| 141 | bool "RiscPC" | 164 | bool "RiscPC" |
| @@ -152,19 +175,25 @@ config ARCH_SA1100 | |||
| 152 | bool "SA1100-based" | 175 | bool "SA1100-based" |
| 153 | select ISA | 176 | select ISA |
| 154 | select ARCH_DISCONTIGMEM_ENABLE | 177 | select ARCH_DISCONTIGMEM_ENABLE |
| 178 | select ARCH_MTD_XIP | ||
| 179 | help | ||
| 180 | Support for StrongARM 11x0 based boards. | ||
| 155 | 181 | ||
| 156 | config ARCH_S3C2410 | 182 | config ARCH_S3C2410 |
| 157 | bool "Samsung S3C2410" | 183 | bool "Samsung S3C2410" |
| 158 | help | 184 | help |
| 159 | Samsung S3C2410X CPU based systems, such as the Simtec Electronics | 185 | Samsung S3C2410X CPU based systems, such as the Simtec Electronics |
| 160 | BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or | 186 | BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or |
| 161 | the Samsung SMDK2410 development board (and derviatives). | 187 | the Samsung SMDK2410 development board (and derivatives). |
| 162 | 188 | ||
| 163 | config ARCH_SHARK | 189 | config ARCH_SHARK |
| 164 | bool "Shark" | 190 | bool "Shark" |
| 165 | select ISA | 191 | select ISA |
| 166 | select ISA_DMA | 192 | select ISA_DMA |
| 167 | select PCI | 193 | select PCI |
| 194 | help | ||
| 195 | Support for the StrongARM based Digital DNARD machine, also known | ||
| 196 | as "Shark" (<http://www.shark-linux.de/shark.html>). | ||
| 168 | 197 | ||
| 169 | config ARCH_LH7A40X | 198 | config ARCH_LH7A40X |
| 170 | bool "Sharp LH7A40X" | 199 | bool "Sharp LH7A40X" |
| @@ -176,6 +205,8 @@ config ARCH_LH7A40X | |||
| 176 | 205 | ||
| 177 | config ARCH_OMAP | 206 | config ARCH_OMAP |
| 178 | bool "TI OMAP" | 207 | bool "TI OMAP" |
| 208 | help | ||
| 209 | Support for TI's OMAP platform (OMAP1 and OMAP2). | ||
| 179 | 210 | ||
| 180 | config ARCH_VERSATILE | 211 | config ARCH_VERSATILE |
| 181 | bool "Versatile" | 212 | bool "Versatile" |
| @@ -194,6 +225,8 @@ config ARCH_REALVIEW | |||
| 194 | 225 | ||
| 195 | config ARCH_IMX | 226 | config ARCH_IMX |
| 196 | bool "IMX" | 227 | bool "IMX" |
| 228 | help | ||
| 229 | Support for Motorola's i.MX family of processors (MX1, MXL). | ||
| 197 | 230 | ||
| 198 | config ARCH_H720X | 231 | config ARCH_H720X |
| 199 | bool "Hynix-HMS720x-based" | 232 | bool "Hynix-HMS720x-based" |
| @@ -210,8 +243,8 @@ config ARCH_AAEC2000 | |||
| 210 | config ARCH_AT91RM9200 | 243 | config ARCH_AT91RM9200 |
| 211 | bool "AT91RM9200" | 244 | bool "AT91RM9200" |
| 212 | help | 245 | help |
| 213 | Say Y here if you intend to run this kernel on an AT91RM9200-based | 246 | Say Y here if you intend to run this kernel on an Atmel |
| 214 | board. | 247 | AT91RM9200-based board. |
| 215 | 248 | ||
| 216 | endchoice | 249 | endchoice |
| 217 | 250 | ||
| @@ -417,8 +450,8 @@ config AEABI | |||
| 417 | To use this you need GCC version 4.0.0 or later. | 450 | To use this you need GCC version 4.0.0 or later. |
| 418 | 451 | ||
| 419 | config OABI_COMPAT | 452 | config OABI_COMPAT |
| 420 | bool "Allow old ABI binaries to run with this kernel" | 453 | bool "Allow old ABI binaries to run with this kernel (EXPERIMENTAL)" |
| 421 | depends on AEABI | 454 | depends on AEABI && EXPERIMENTAL |
| 422 | default y | 455 | default y |
| 423 | help | 456 | help |
| 424 | This option preserves the old syscall interface along with the | 457 | This option preserves the old syscall interface along with the |
diff --git a/arch/arm/configs/at91rm9200dk_defconfig b/arch/arm/configs/at91rm9200dk_defconfig index 5cdd13acf8ff..1fe73d198888 100644 --- a/arch/arm/configs/at91rm9200dk_defconfig +++ b/arch/arm/configs/at91rm9200dk_defconfig | |||
| @@ -85,7 +85,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" | |||
| 85 | # CONFIG_ARCH_CLPS711X is not set | 85 | # CONFIG_ARCH_CLPS711X is not set |
| 86 | # CONFIG_ARCH_CO285 is not set | 86 | # CONFIG_ARCH_CO285 is not set |
| 87 | # CONFIG_ARCH_EBSA110 is not set | 87 | # CONFIG_ARCH_EBSA110 is not set |
| 88 | # CONFIG_ARCH_CAMELOT is not set | ||
| 89 | # CONFIG_ARCH_FOOTBRIDGE is not set | 88 | # CONFIG_ARCH_FOOTBRIDGE is not set |
| 90 | # CONFIG_ARCH_INTEGRATOR is not set | 89 | # CONFIG_ARCH_INTEGRATOR is not set |
| 91 | # CONFIG_ARCH_IOP3XX is not set | 90 | # CONFIG_ARCH_IOP3XX is not set |
diff --git a/arch/arm/configs/at91rm9200ek_defconfig b/arch/arm/configs/at91rm9200ek_defconfig index 20838ccf1da7..b7d934cdb1b7 100644 --- a/arch/arm/configs/at91rm9200ek_defconfig +++ b/arch/arm/configs/at91rm9200ek_defconfig | |||
| @@ -85,7 +85,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" | |||
| 85 | # CONFIG_ARCH_CLPS711X is not set | 85 | # CONFIG_ARCH_CLPS711X is not set |
| 86 | # CONFIG_ARCH_CO285 is not set | 86 | # CONFIG_ARCH_CO285 is not set |
| 87 | # CONFIG_ARCH_EBSA110 is not set | 87 | # CONFIG_ARCH_EBSA110 is not set |
| 88 | # CONFIG_ARCH_CAMELOT is not set | ||
| 89 | # CONFIG_ARCH_FOOTBRIDGE is not set | 88 | # CONFIG_ARCH_FOOTBRIDGE is not set |
| 90 | # CONFIG_ARCH_INTEGRATOR is not set | 89 | # CONFIG_ARCH_INTEGRATOR is not set |
| 91 | # CONFIG_ARCH_IOP3XX is not set | 90 | # CONFIG_ARCH_IOP3XX is not set |
diff --git a/arch/arm/configs/csb337_defconfig b/arch/arm/configs/csb337_defconfig index 885a3184830a..94bd9932a402 100644 --- a/arch/arm/configs/csb337_defconfig +++ b/arch/arm/configs/csb337_defconfig | |||
| @@ -85,7 +85,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" | |||
| 85 | # CONFIG_ARCH_CLPS711X is not set | 85 | # CONFIG_ARCH_CLPS711X is not set |
| 86 | # CONFIG_ARCH_CO285 is not set | 86 | # CONFIG_ARCH_CO285 is not set |
| 87 | # CONFIG_ARCH_EBSA110 is not set | 87 | # CONFIG_ARCH_EBSA110 is not set |
| 88 | # CONFIG_ARCH_CAMELOT is not set | ||
| 89 | # CONFIG_ARCH_FOOTBRIDGE is not set | 88 | # CONFIG_ARCH_FOOTBRIDGE is not set |
| 90 | # CONFIG_ARCH_INTEGRATOR is not set | 89 | # CONFIG_ARCH_INTEGRATOR is not set |
| 91 | # CONFIG_ARCH_IOP3XX is not set | 90 | # CONFIG_ARCH_IOP3XX is not set |
diff --git a/arch/arm/configs/csb637_defconfig b/arch/arm/configs/csb637_defconfig index 95a96a5462a0..1519124c5501 100644 --- a/arch/arm/configs/csb637_defconfig +++ b/arch/arm/configs/csb637_defconfig | |||
| @@ -85,7 +85,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" | |||
| 85 | # CONFIG_ARCH_CLPS711X is not set | 85 | # CONFIG_ARCH_CLPS711X is not set |
| 86 | # CONFIG_ARCH_CO285 is not set | 86 | # CONFIG_ARCH_CO285 is not set |
| 87 | # CONFIG_ARCH_EBSA110 is not set | 87 | # CONFIG_ARCH_EBSA110 is not set |
| 88 | # CONFIG_ARCH_CAMELOT is not set | ||
| 89 | # CONFIG_ARCH_FOOTBRIDGE is not set | 88 | # CONFIG_ARCH_FOOTBRIDGE is not set |
| 90 | # CONFIG_ARCH_INTEGRATOR is not set | 89 | # CONFIG_ARCH_INTEGRATOR is not set |
| 91 | # CONFIG_ARCH_IOP3XX is not set | 90 | # CONFIG_ARCH_IOP3XX is not set |
diff --git a/arch/arm/configs/enp2611_defconfig b/arch/arm/configs/enp2611_defconfig index 9592e3925c79..5fdaf3ce9d56 100644 --- a/arch/arm/configs/enp2611_defconfig +++ b/arch/arm/configs/enp2611_defconfig | |||
| @@ -171,7 +171,7 @@ CONFIG_ALIGNMENT_TRAP=y | |||
| 171 | # | 171 | # |
| 172 | CONFIG_ZBOOT_ROM_TEXT=0x0 | 172 | CONFIG_ZBOOT_ROM_TEXT=0x0 |
| 173 | CONFIG_ZBOOT_ROM_BSS=0x0 | 173 | CONFIG_ZBOOT_ROM_BSS=0x0 |
| 174 | CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware" | 174 | CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0" |
| 175 | # CONFIG_XIP_KERNEL is not set | 175 | # CONFIG_XIP_KERNEL is not set |
| 176 | 176 | ||
| 177 | # | 177 | # |
diff --git a/arch/arm/configs/ixdp2400_defconfig b/arch/arm/configs/ixdp2400_defconfig index d9d6bb86a6fa..c67fc449a11f 100644 --- a/arch/arm/configs/ixdp2400_defconfig +++ b/arch/arm/configs/ixdp2400_defconfig | |||
| @@ -172,7 +172,7 @@ CONFIG_ALIGNMENT_TRAP=y | |||
| 172 | # | 172 | # |
| 173 | CONFIG_ZBOOT_ROM_TEXT=0x0 | 173 | CONFIG_ZBOOT_ROM_TEXT=0x0 |
| 174 | CONFIG_ZBOOT_ROM_BSS=0x0 | 174 | CONFIG_ZBOOT_ROM_BSS=0x0 |
| 175 | CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware" | 175 | CONFIG_CMDLINE="console=ttyS0,57600 root=/dev/nfs ip=bootp mem=64M@0x0" |
| 176 | # CONFIG_XIP_KERNEL is not set | 176 | # CONFIG_XIP_KERNEL is not set |
| 177 | 177 | ||
| 178 | # | 178 | # |
diff --git a/arch/arm/configs/ixdp2401_defconfig b/arch/arm/configs/ixdp2401_defconfig index 2dc9d499c7d7..60d66e82c51f 100644 --- a/arch/arm/configs/ixdp2401_defconfig +++ b/arch/arm/configs/ixdp2401_defconfig | |||
| @@ -172,7 +172,7 @@ CONFIG_ALIGNMENT_TRAP=y | |||
| 172 | # | 172 | # |
| 173 | CONFIG_ZBOOT_ROM_TEXT=0x0 | 173 | CONFIG_ZBOOT_ROM_TEXT=0x0 |
| 174 | CONFIG_ZBOOT_ROM_BSS=0x0 | 174 | CONFIG_ZBOOT_ROM_BSS=0x0 |
| 175 | CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware" | 175 | CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0" |
| 176 | # CONFIG_XIP_KERNEL is not set | 176 | # CONFIG_XIP_KERNEL is not set |
| 177 | 177 | ||
| 178 | # | 178 | # |
diff --git a/arch/arm/configs/ixdp2801_defconfig b/arch/arm/configs/ixdp2801_defconfig index ea8f4b478fa3..f54f3dcc5b33 100644 --- a/arch/arm/configs/ixdp2801_defconfig +++ b/arch/arm/configs/ixdp2801_defconfig | |||
| @@ -172,7 +172,7 @@ CONFIG_ALIGNMENT_TRAP=y | |||
| 172 | # | 172 | # |
| 173 | CONFIG_ZBOOT_ROM_TEXT=0x0 | 173 | CONFIG_ZBOOT_ROM_TEXT=0x0 |
| 174 | CONFIG_ZBOOT_ROM_BSS=0x0 | 174 | CONFIG_ZBOOT_ROM_BSS=0x0 |
| 175 | CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0 pci=firmware ixdp2x01_clock=50000000" | 175 | CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp mem=64M@0x0" |
| 176 | # CONFIG_XIP_KERNEL is not set | 176 | # CONFIG_XIP_KERNEL is not set |
| 177 | 177 | ||
| 178 | # | 178 | # |
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index 1964ccd8a71f..6695b07cf1ba 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig | |||
| @@ -1,11 +1,10 @@ | |||
| 1 | # | 1 | # |
| 2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
| 3 | # Linux kernel version: 2.6.15-rc1 | 3 | # Linux kernel version: 2.6.16-rc2 |
| 4 | # Sun Nov 13 17:41:24 2005 | 4 | # Mon Feb 6 11:17:23 2006 |
| 5 | # | 5 | # |
| 6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
| 7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
| 8 | CONFIG_UID16=y | ||
| 9 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
| 10 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 9 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
| 11 | 10 | ||
| @@ -28,27 +27,31 @@ CONFIG_SYSVIPC=y | |||
| 28 | # CONFIG_BSD_PROCESS_ACCT is not set | 27 | # CONFIG_BSD_PROCESS_ACCT is not set |
| 29 | CONFIG_SYSCTL=y | 28 | CONFIG_SYSCTL=y |
| 30 | # CONFIG_AUDIT is not set | 29 | # CONFIG_AUDIT is not set |
| 31 | # CONFIG_HOTPLUG is not set | ||
| 32 | CONFIG_KOBJECT_UEVENT=y | ||
| 33 | # CONFIG_IKCONFIG is not set | 30 | # CONFIG_IKCONFIG is not set |
| 34 | CONFIG_INITRAMFS_SOURCE="" | 31 | CONFIG_INITRAMFS_SOURCE="" |
| 32 | CONFIG_UID16=y | ||
| 33 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
| 35 | # CONFIG_EMBEDDED is not set | 34 | # CONFIG_EMBEDDED is not set |
| 36 | CONFIG_KALLSYMS=y | 35 | CONFIG_KALLSYMS=y |
| 37 | # CONFIG_KALLSYMS_ALL is not set | 36 | # CONFIG_KALLSYMS_ALL is not set |
| 38 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 37 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
| 38 | CONFIG_HOTPLUG=y | ||
| 39 | CONFIG_PRINTK=y | 39 | CONFIG_PRINTK=y |
| 40 | CONFIG_BUG=y | 40 | CONFIG_BUG=y |
| 41 | CONFIG_ELF_CORE=y | ||
| 41 | CONFIG_BASE_FULL=y | 42 | CONFIG_BASE_FULL=y |
| 42 | CONFIG_FUTEX=y | 43 | CONFIG_FUTEX=y |
| 43 | CONFIG_EPOLL=y | 44 | CONFIG_EPOLL=y |
| 44 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
| 45 | CONFIG_SHMEM=y | 45 | CONFIG_SHMEM=y |
| 46 | CONFIG_CC_ALIGN_FUNCTIONS=0 | 46 | CONFIG_CC_ALIGN_FUNCTIONS=0 |
| 47 | CONFIG_CC_ALIGN_LABELS=0 | 47 | CONFIG_CC_ALIGN_LABELS=0 |
| 48 | CONFIG_CC_ALIGN_LOOPS=0 | 48 | CONFIG_CC_ALIGN_LOOPS=0 |
| 49 | CONFIG_CC_ALIGN_JUMPS=0 | 49 | CONFIG_CC_ALIGN_JUMPS=0 |
| 50 | CONFIG_SLAB=y | ||
| 50 | # CONFIG_TINY_SHMEM is not set | 51 | # CONFIG_TINY_SHMEM is not set |
| 51 | CONFIG_BASE_SMALL=0 | 52 | CONFIG_BASE_SMALL=0 |
| 53 | # CONFIG_SLOB is not set | ||
| 54 | CONFIG_OBSOLETE_INTERMODULE=y | ||
| 52 | 55 | ||
| 53 | # | 56 | # |
| 54 | # Loadable module support | 57 | # Loadable module support |
| @@ -102,6 +105,7 @@ CONFIG_ARCH_S3C2410=y | |||
| 102 | # CONFIG_ARCH_IMX is not set | 105 | # CONFIG_ARCH_IMX is not set |
| 103 | # CONFIG_ARCH_H720X is not set | 106 | # CONFIG_ARCH_H720X is not set |
| 104 | # CONFIG_ARCH_AAEC2000 is not set | 107 | # CONFIG_ARCH_AAEC2000 is not set |
| 108 | # CONFIG_ARCH_AT91RM9200 is not set | ||
| 105 | 109 | ||
| 106 | # | 110 | # |
| 107 | # S3C24XX Implementations | 111 | # S3C24XX Implementations |
| @@ -160,7 +164,6 @@ CONFIG_CPU_TLB_V4WBI=y | |||
| 160 | # Bus support | 164 | # Bus support |
| 161 | # | 165 | # |
| 162 | CONFIG_ISA=y | 166 | CONFIG_ISA=y |
| 163 | CONFIG_ISA_DMA_API=y | ||
| 164 | 167 | ||
| 165 | # | 168 | # |
| 166 | # PCCARD (PCMCIA/CardBus) support | 169 | # PCCARD (PCMCIA/CardBus) support |
| @@ -172,6 +175,7 @@ CONFIG_ISA_DMA_API=y | |||
| 172 | # | 175 | # |
| 173 | # CONFIG_PREEMPT is not set | 176 | # CONFIG_PREEMPT is not set |
| 174 | # CONFIG_NO_IDLE_HZ is not set | 177 | # CONFIG_NO_IDLE_HZ is not set |
| 178 | # CONFIG_AEABI is not set | ||
| 175 | # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set | 179 | # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set |
| 176 | CONFIG_SELECT_MEMORY_MODEL=y | 180 | CONFIG_SELECT_MEMORY_MODEL=y |
| 177 | CONFIG_FLATMEM_MANUAL=y | 181 | CONFIG_FLATMEM_MANUAL=y |
| @@ -214,6 +218,8 @@ CONFIG_BINFMT_AOUT=y | |||
| 214 | # Power management options | 218 | # Power management options |
| 215 | # | 219 | # |
| 216 | CONFIG_PM=y | 220 | CONFIG_PM=y |
| 221 | CONFIG_PM_LEGACY=y | ||
| 222 | # CONFIG_PM_DEBUG is not set | ||
| 217 | CONFIG_APM=y | 223 | CONFIG_APM=y |
| 218 | 224 | ||
| 219 | # | 225 | # |
| @@ -259,6 +265,11 @@ CONFIG_TCP_CONG_BIC=y | |||
| 259 | # SCTP Configuration (EXPERIMENTAL) | 265 | # SCTP Configuration (EXPERIMENTAL) |
| 260 | # | 266 | # |
| 261 | # CONFIG_IP_SCTP is not set | 267 | # CONFIG_IP_SCTP is not set |
| 268 | |||
| 269 | # | ||
| 270 | # TIPC Configuration (EXPERIMENTAL) | ||
| 271 | # | ||
| 272 | # CONFIG_TIPC is not set | ||
| 262 | # CONFIG_ATM is not set | 273 | # CONFIG_ATM is not set |
| 263 | # CONFIG_BRIDGE is not set | 274 | # CONFIG_BRIDGE is not set |
| 264 | # CONFIG_VLAN_8021Q is not set | 275 | # CONFIG_VLAN_8021Q is not set |
| @@ -276,7 +287,6 @@ CONFIG_TCP_CONG_BIC=y | |||
| 276 | # QoS and/or fair queueing | 287 | # QoS and/or fair queueing |
| 277 | # | 288 | # |
| 278 | # CONFIG_NET_SCHED is not set | 289 | # CONFIG_NET_SCHED is not set |
| 279 | # CONFIG_NET_CLS_ROUTE is not set | ||
| 280 | 290 | ||
| 281 | # | 291 | # |
| 282 | # Network testing | 292 | # Network testing |
| @@ -300,6 +310,11 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y | |||
| 300 | # CONFIG_DEBUG_DRIVER is not set | 310 | # CONFIG_DEBUG_DRIVER is not set |
| 301 | 311 | ||
| 302 | # | 312 | # |
| 313 | # Connector - unified userspace <-> kernelspace linker | ||
| 314 | # | ||
| 315 | # CONFIG_CONNECTOR is not set | ||
| 316 | |||
| 317 | # | ||
| 303 | # Memory Technology Devices (MTD) | 318 | # Memory Technology Devices (MTD) |
| 304 | # | 319 | # |
| 305 | CONFIG_MTD=y | 320 | CONFIG_MTD=y |
| @@ -412,8 +427,6 @@ CONFIG_PARPORT_1284=y | |||
| 412 | # | 427 | # |
| 413 | # Block devices | 428 | # Block devices |
| 414 | # | 429 | # |
| 415 | # CONFIG_BLK_DEV_XD is not set | ||
| 416 | # CONFIG_PARIDE is not set | ||
| 417 | # CONFIG_BLK_DEV_COW_COMMON is not set | 430 | # CONFIG_BLK_DEV_COW_COMMON is not set |
| 418 | CONFIG_BLK_DEV_LOOP=y | 431 | CONFIG_BLK_DEV_LOOP=y |
| 419 | # CONFIG_BLK_DEV_CRYPTOLOOP is not set | 432 | # CONFIG_BLK_DEV_CRYPTOLOOP is not set |
| @@ -502,7 +515,6 @@ CONFIG_NETDEVICES=y | |||
| 502 | CONFIG_NET_ETHERNET=y | 515 | CONFIG_NET_ETHERNET=y |
| 503 | CONFIG_MII=y | 516 | CONFIG_MII=y |
| 504 | # CONFIG_NET_VENDOR_3COM is not set | 517 | # CONFIG_NET_VENDOR_3COM is not set |
| 505 | # CONFIG_LANCE is not set | ||
| 506 | # CONFIG_NET_VENDOR_SMC is not set | 518 | # CONFIG_NET_VENDOR_SMC is not set |
| 507 | # CONFIG_SMC91X is not set | 519 | # CONFIG_SMC91X is not set |
| 508 | CONFIG_DM9000=y | 520 | CONFIG_DM9000=y |
| @@ -607,11 +619,11 @@ CONFIG_SERIAL_NONSTANDARD=y | |||
| 607 | # CONFIG_ROCKETPORT is not set | 619 | # CONFIG_ROCKETPORT is not set |
| 608 | # CONFIG_CYCLADES is not set | 620 | # CONFIG_CYCLADES is not set |
| 609 | # CONFIG_DIGIEPCA is not set | 621 | # CONFIG_DIGIEPCA is not set |
| 610 | # CONFIG_ESPSERIAL is not set | ||
| 611 | # CONFIG_MOXA_INTELLIO is not set | 622 | # CONFIG_MOXA_INTELLIO is not set |
| 612 | # CONFIG_MOXA_SMARTIO is not set | 623 | # CONFIG_MOXA_SMARTIO is not set |
| 613 | # CONFIG_ISI is not set | 624 | # CONFIG_ISI is not set |
| 614 | # CONFIG_SYNCLINKMP is not set | 625 | # CONFIG_SYNCLINKMP is not set |
| 626 | # CONFIG_SYNCLINK_GT is not set | ||
| 615 | # CONFIG_N_HDLC is not set | 627 | # CONFIG_N_HDLC is not set |
| 616 | # CONFIG_RISCOM8 is not set | 628 | # CONFIG_RISCOM8 is not set |
| 617 | # CONFIG_SPECIALIX is not set | 629 | # CONFIG_SPECIALIX is not set |
| @@ -625,6 +637,7 @@ CONFIG_SERIAL_NONSTANDARD=y | |||
| 625 | CONFIG_SERIAL_8250=y | 637 | CONFIG_SERIAL_8250=y |
| 626 | CONFIG_SERIAL_8250_CONSOLE=y | 638 | CONFIG_SERIAL_8250_CONSOLE=y |
| 627 | CONFIG_SERIAL_8250_NR_UARTS=8 | 639 | CONFIG_SERIAL_8250_NR_UARTS=8 |
| 640 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 | ||
| 628 | CONFIG_SERIAL_8250_EXTENDED=y | 641 | CONFIG_SERIAL_8250_EXTENDED=y |
| 629 | CONFIG_SERIAL_8250_MANY_PORTS=y | 642 | CONFIG_SERIAL_8250_MANY_PORTS=y |
| 630 | CONFIG_SERIAL_8250_SHARE_IRQ=y | 643 | CONFIG_SERIAL_8250_SHARE_IRQ=y |
| @@ -687,6 +700,7 @@ CONFIG_S3C2410_RTC=y | |||
| 687 | # | 700 | # |
| 688 | # TPM devices | 701 | # TPM devices |
| 689 | # | 702 | # |
| 703 | # CONFIG_TCG_TPM is not set | ||
| 690 | # CONFIG_TELCLOCK is not set | 704 | # CONFIG_TELCLOCK is not set |
| 691 | 705 | ||
| 692 | # | 706 | # |
| @@ -731,6 +745,12 @@ CONFIG_SENSORS_EEPROM=m | |||
| 731 | # CONFIG_I2C_DEBUG_CHIP is not set | 745 | # CONFIG_I2C_DEBUG_CHIP is not set |
| 732 | 746 | ||
| 733 | # | 747 | # |
| 748 | # SPI support | ||
| 749 | # | ||
| 750 | # CONFIG_SPI is not set | ||
| 751 | # CONFIG_SPI_MASTER is not set | ||
| 752 | |||
| 753 | # | ||
| 734 | # Hardware Monitoring support | 754 | # Hardware Monitoring support |
| 735 | # | 755 | # |
| 736 | CONFIG_HWMON=y | 756 | CONFIG_HWMON=y |
| @@ -863,6 +883,7 @@ CONFIG_FS_MBCACHE=y | |||
| 863 | # CONFIG_JFS_FS is not set | 883 | # CONFIG_JFS_FS is not set |
| 864 | # CONFIG_FS_POSIX_ACL is not set | 884 | # CONFIG_FS_POSIX_ACL is not set |
| 865 | # CONFIG_XFS_FS is not set | 885 | # CONFIG_XFS_FS is not set |
| 886 | # CONFIG_OCFS2_FS is not set | ||
| 866 | # CONFIG_MINIX_FS is not set | 887 | # CONFIG_MINIX_FS is not set |
| 867 | CONFIG_ROMFS_FS=y | 888 | CONFIG_ROMFS_FS=y |
| 868 | CONFIG_INOTIFY=y | 889 | CONFIG_INOTIFY=y |
| @@ -897,6 +918,7 @@ CONFIG_SYSFS=y | |||
| 897 | # CONFIG_HUGETLB_PAGE is not set | 918 | # CONFIG_HUGETLB_PAGE is not set |
| 898 | CONFIG_RAMFS=y | 919 | CONFIG_RAMFS=y |
| 899 | # CONFIG_RELAYFS_FS is not set | 920 | # CONFIG_RELAYFS_FS is not set |
| 921 | # CONFIG_CONFIGFS_FS is not set | ||
| 900 | 922 | ||
| 901 | # | 923 | # |
| 902 | # Miscellaneous filesystems | 924 | # Miscellaneous filesystems |
| @@ -965,6 +987,7 @@ CONFIG_SOLARIS_X86_PARTITION=y | |||
| 965 | # CONFIG_SGI_PARTITION is not set | 987 | # CONFIG_SGI_PARTITION is not set |
| 966 | # CONFIG_ULTRIX_PARTITION is not set | 988 | # CONFIG_ULTRIX_PARTITION is not set |
| 967 | # CONFIG_SUN_PARTITION is not set | 989 | # CONFIG_SUN_PARTITION is not set |
| 990 | # CONFIG_KARMA_PARTITION is not set | ||
| 968 | # CONFIG_EFI_PARTITION is not set | 991 | # CONFIG_EFI_PARTITION is not set |
| 969 | 992 | ||
| 970 | # | 993 | # |
| @@ -1020,12 +1043,13 @@ CONFIG_NLS_DEFAULT="iso8859-1" | |||
| 1020 | # Kernel hacking | 1043 | # Kernel hacking |
| 1021 | # | 1044 | # |
| 1022 | # CONFIG_PRINTK_TIME is not set | 1045 | # CONFIG_PRINTK_TIME is not set |
| 1023 | CONFIG_DEBUG_KERNEL=y | ||
| 1024 | CONFIG_MAGIC_SYSRQ=y | 1046 | CONFIG_MAGIC_SYSRQ=y |
| 1047 | CONFIG_DEBUG_KERNEL=y | ||
| 1025 | CONFIG_LOG_BUF_SHIFT=16 | 1048 | CONFIG_LOG_BUF_SHIFT=16 |
| 1026 | CONFIG_DETECT_SOFTLOCKUP=y | 1049 | CONFIG_DETECT_SOFTLOCKUP=y |
| 1027 | # CONFIG_SCHEDSTATS is not set | 1050 | # CONFIG_SCHEDSTATS is not set |
| 1028 | # CONFIG_DEBUG_SLAB is not set | 1051 | # CONFIG_DEBUG_SLAB is not set |
| 1052 | CONFIG_DEBUG_MUTEXES=y | ||
| 1029 | # CONFIG_DEBUG_SPINLOCK is not set | 1053 | # CONFIG_DEBUG_SPINLOCK is not set |
| 1030 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | 1054 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set |
| 1031 | # CONFIG_DEBUG_KOBJECT is not set | 1055 | # CONFIG_DEBUG_KOBJECT is not set |
| @@ -1034,6 +1058,7 @@ CONFIG_DEBUG_INFO=y | |||
| 1034 | # CONFIG_DEBUG_FS is not set | 1058 | # CONFIG_DEBUG_FS is not set |
| 1035 | # CONFIG_DEBUG_VM is not set | 1059 | # CONFIG_DEBUG_VM is not set |
| 1036 | CONFIG_FRAME_POINTER=y | 1060 | CONFIG_FRAME_POINTER=y |
| 1061 | CONFIG_FORCED_INLINING=y | ||
| 1037 | # CONFIG_RCU_TORTURE_TEST is not set | 1062 | # CONFIG_RCU_TORTURE_TEST is not set |
| 1038 | CONFIG_DEBUG_USER=y | 1063 | CONFIG_DEBUG_USER=y |
| 1039 | # CONFIG_DEBUG_WAITQ is not set | 1064 | # CONFIG_DEBUG_WAITQ is not set |
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index d058e7c12568..8c3035d5ffc9 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S | |||
| @@ -291,21 +291,21 @@ | |||
| 291 | CALL(sys_mq_getsetattr) | 291 | CALL(sys_mq_getsetattr) |
| 292 | /* 280 */ CALL(sys_waitid) | 292 | /* 280 */ CALL(sys_waitid) |
| 293 | CALL(sys_socket) | 293 | CALL(sys_socket) |
| 294 | CALL(sys_bind) | 294 | CALL(ABI(sys_bind, sys_oabi_bind)) |
| 295 | CALL(sys_connect) | 295 | CALL(ABI(sys_connect, sys_oabi_connect)) |
| 296 | CALL(sys_listen) | 296 | CALL(sys_listen) |
| 297 | /* 285 */ CALL(sys_accept) | 297 | /* 285 */ CALL(sys_accept) |
| 298 | CALL(sys_getsockname) | 298 | CALL(sys_getsockname) |
| 299 | CALL(sys_getpeername) | 299 | CALL(sys_getpeername) |
| 300 | CALL(sys_socketpair) | 300 | CALL(sys_socketpair) |
| 301 | CALL(sys_send) | 301 | CALL(sys_send) |
| 302 | /* 290 */ CALL(sys_sendto) | 302 | /* 290 */ CALL(ABI(sys_sendto, sys_oabi_sendto)) |
| 303 | CALL(sys_recv) | 303 | CALL(sys_recv) |
| 304 | CALL(sys_recvfrom) | 304 | CALL(sys_recvfrom) |
| 305 | CALL(sys_shutdown) | 305 | CALL(sys_shutdown) |
| 306 | CALL(sys_setsockopt) | 306 | CALL(sys_setsockopt) |
| 307 | /* 295 */ CALL(sys_getsockopt) | 307 | /* 295 */ CALL(sys_getsockopt) |
| 308 | CALL(sys_sendmsg) | 308 | CALL(ABI(sys_sendmsg, sys_oabi_sendmsg)) |
| 309 | CALL(sys_recvmsg) | 309 | CALL(sys_recvmsg) |
| 310 | CALL(ABI(sys_semop, sys_oabi_semop)) | 310 | CALL(ABI(sys_semop, sys_oabi_semop)) |
| 311 | CALL(sys_semget) | 311 | CALL(sys_semget) |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index d401d908c463..964cd717506b 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
| @@ -333,10 +333,14 @@ __pabt_svc: | |||
| 333 | @ from the exception stack | 333 | @ from the exception stack |
| 334 | 334 | ||
| 335 | #if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) | 335 | #if __LINUX_ARM_ARCH__ < 6 && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) |
| 336 | #ifndef CONFIG_MMU | ||
| 337 | #warning "NPTL on non MMU needs fixing" | ||
| 338 | #else | ||
| 336 | @ make sure our user space atomic helper is aborted | 339 | @ make sure our user space atomic helper is aborted |
| 337 | cmp r2, #TASK_SIZE | 340 | cmp r2, #TASK_SIZE |
| 338 | bichs r3, r3, #PSR_Z_BIT | 341 | bichs r3, r3, #PSR_Z_BIT |
| 339 | #endif | 342 | #endif |
| 343 | #endif | ||
| 340 | 344 | ||
| 341 | @ | 345 | @ |
| 342 | @ We are now ready to fill in the remaining blanks on the stack: | 346 | @ We are now ready to fill in the remaining blanks on the stack: |
| @@ -705,7 +709,12 @@ __kuser_memory_barrier: @ 0xffff0fa0 | |||
| 705 | * The C flag is also set if *ptr was changed to allow for assembly | 709 | * The C flag is also set if *ptr was changed to allow for assembly |
| 706 | * optimization in the calling code. | 710 | * optimization in the calling code. |
| 707 | * | 711 | * |
| 708 | * Note: this routine already includes memory barriers as needed. | 712 | * Notes: |
| 713 | * | ||
| 714 | * - This routine already includes memory barriers as needed. | ||
| 715 | * | ||
| 716 | * - A failure might be transient, i.e. it is possible, although unlikely, | ||
| 717 | * that "failure" be returned even if *ptr == oldval. | ||
| 709 | * | 718 | * |
| 710 | * For example, a user space atomic_add implementation could look like this: | 719 | * For example, a user space atomic_add implementation could look like this: |
| 711 | * | 720 | * |
| @@ -756,12 +765,18 @@ __kuser_cmpxchg: @ 0xffff0fc0 | |||
| 756 | * exception happening just after the str instruction which would | 765 | * exception happening just after the str instruction which would |
| 757 | * clear the Z flag although the exchange was done. | 766 | * clear the Z flag although the exchange was done. |
| 758 | */ | 767 | */ |
| 768 | #ifdef CONFIG_MMU | ||
| 759 | teq ip, ip @ set Z flag | 769 | teq ip, ip @ set Z flag |
| 760 | ldr ip, [r2] @ load current val | 770 | ldr ip, [r2] @ load current val |
| 761 | add r3, r2, #1 @ prepare store ptr | 771 | add r3, r2, #1 @ prepare store ptr |
| 762 | teqeq ip, r0 @ compare with oldval if still allowed | 772 | teqeq ip, r0 @ compare with oldval if still allowed |
| 763 | streq r1, [r3, #-1]! @ store newval if still allowed | 773 | streq r1, [r3, #-1]! @ store newval if still allowed |
| 764 | subs r0, r2, r3 @ if r2 == r3 the str occured | 774 | subs r0, r2, r3 @ if r2 == r3 the str occured |
| 775 | #else | ||
| 776 | #warning "NPTL on non MMU needs fixing" | ||
| 777 | mov r0, #-1 | ||
| 778 | adds r0, r0, #0 | ||
| 779 | #endif | ||
| 765 | mov pc, lr | 780 | mov pc, lr |
| 766 | 781 | ||
| 767 | #else | 782 | #else |
diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c index eafa8e5284af..9d4b76409c64 100644 --- a/arch/arm/kernel/sys_oabi-compat.c +++ b/arch/arm/kernel/sys_oabi-compat.c | |||
| @@ -59,6 +59,16 @@ | |||
| 59 | * struct sembuf loses its padding with EABI. Since arrays of them are | 59 | * struct sembuf loses its padding with EABI. Since arrays of them are |
| 60 | * used they have to be copyed to remove the padding. Compatibility wrappers | 60 | * used they have to be copyed to remove the padding. Compatibility wrappers |
| 61 | * provided below. | 61 | * provided below. |
| 62 | * | ||
| 63 | * sys_bind: | ||
| 64 | * sys_connect: | ||
| 65 | * sys_sendmsg: | ||
| 66 | * sys_sendto: | ||
| 67 | * | ||
| 68 | * struct sockaddr_un loses its padding with EABI. Since the size of the | ||
| 69 | * structure is used as a validation test in unix_mkname(), we need to | ||
| 70 | * change the length argument to 110 whenever it is 112. Compatibility | ||
| 71 | * wrappers provided below. | ||
| 62 | */ | 72 | */ |
| 63 | 73 | ||
| 64 | #include <linux/syscalls.h> | 74 | #include <linux/syscalls.h> |
| @@ -67,6 +77,7 @@ | |||
| 67 | #include <linux/fcntl.h> | 77 | #include <linux/fcntl.h> |
| 68 | #include <linux/eventpoll.h> | 78 | #include <linux/eventpoll.h> |
| 69 | #include <linux/sem.h> | 79 | #include <linux/sem.h> |
| 80 | #include <linux/socket.h> | ||
| 70 | #include <asm/ipc.h> | 81 | #include <asm/ipc.h> |
| 71 | #include <asm/uaccess.h> | 82 | #include <asm/uaccess.h> |
| 72 | 83 | ||
| @@ -337,3 +348,63 @@ asmlinkage int sys_oabi_ipc(uint call, int first, int second, int third, | |||
| 337 | return sys_ipc(call, first, second, third, ptr, fifth); | 348 | return sys_ipc(call, first, second, third, ptr, fifth); |
| 338 | } | 349 | } |
| 339 | } | 350 | } |
| 351 | |||
| 352 | asmlinkage long sys_oabi_bind(int fd, struct sockaddr __user *addr, int addrlen) | ||
| 353 | { | ||
| 354 | sa_family_t sa_family; | ||
| 355 | if (addrlen == 112 && | ||
| 356 | get_user(sa_family, &addr->sa_family) == 0 && | ||
| 357 | sa_family == AF_UNIX) | ||
| 358 | addrlen = 110; | ||
| 359 | return sys_bind(fd, addr, addrlen); | ||
| 360 | } | ||
| 361 | |||
| 362 | asmlinkage long sys_oabi_connect(int fd, struct sockaddr __user *addr, int addrlen) | ||
| 363 | { | ||
| 364 | sa_family_t sa_family; | ||
| 365 | if (addrlen == 112 && | ||
| 366 | get_user(sa_family, &addr->sa_family) == 0 && | ||
| 367 | sa_family == AF_UNIX) | ||
| 368 | addrlen = 110; | ||
| 369 | return sys_connect(fd, addr, addrlen); | ||
| 370 | } | ||
| 371 | |||
| 372 | asmlinkage long sys_oabi_sendto(int fd, void __user *buff, | ||
| 373 | size_t len, unsigned flags, | ||
| 374 | struct sockaddr __user *addr, | ||
| 375 | int addrlen) | ||
| 376 | { | ||
| 377 | sa_family_t sa_family; | ||
| 378 | if (addrlen == 112 && | ||
| 379 | get_user(sa_family, &addr->sa_family) == 0 && | ||
| 380 | sa_family == AF_UNIX) | ||
| 381 | addrlen = 110; | ||
| 382 | return sys_sendto(fd, buff, len, flags, addr, addrlen); | ||
| 383 | } | ||
| 384 | |||
| 385 | asmlinkage long sys_oabi_sendmsg(int fd, struct msghdr __user *msg, unsigned flags) | ||
| 386 | { | ||
| 387 | struct sockaddr __user *addr; | ||
| 388 | int msg_namelen; | ||
| 389 | sa_family_t sa_family; | ||
| 390 | if (msg && | ||
| 391 | get_user(msg_namelen, &msg->msg_namelen) == 0 && | ||
| 392 | msg_namelen == 112 && | ||
| 393 | get_user(addr, &msg->msg_name) == 0 && | ||
| 394 | get_user(sa_family, &addr->sa_family) == 0 && | ||
| 395 | sa_family == AF_UNIX) | ||
| 396 | { | ||
| 397 | /* | ||
| 398 | * HACK ALERT: there is a limit to how much backward bending | ||
| 399 | * we should do for what is actually a transitional | ||
| 400 | * compatibility layer. This already has known flaws with | ||
| 401 | * a few ioctls that we don't intend to fix. Therefore | ||
| 402 | * consider this blatent hack as another one... and take care | ||
| 403 | * to run for cover. In most cases it will "just work fine". | ||
| 404 | * If it doesn't, well, tough. | ||
| 405 | */ | ||
| 406 | put_user(110, &msg->msg_namelen); | ||
| 407 | } | ||
| 408 | return sys_sendmsg(fd, msg, flags); | ||
| 409 | } | ||
| 410 | |||
diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig index 0793dcf54f2e..0e2b641268ad 100644 --- a/arch/arm/mach-clps711x/Kconfig +++ b/arch/arm/mach-clps711x/Kconfig | |||
| @@ -24,6 +24,8 @@ config ARCH_CEIVA | |||
| 24 | 24 | ||
| 25 | config ARCH_CLEP7312 | 25 | config ARCH_CLEP7312 |
| 26 | bool "CLEP7312" | 26 | bool "CLEP7312" |
| 27 | help | ||
| 28 | Boards based on the Cirrus Logic 7212/7312 chips. | ||
| 27 | 29 | ||
| 28 | config ARCH_EDB7211 | 30 | config ARCH_EDB7211 |
| 29 | bool "EDB7211" | 31 | bool "EDB7211" |
diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c index dc31e3fd6c57..8ab1b040288c 100644 --- a/arch/arm/mach-imx/mx1ads.c +++ b/arch/arm/mach-imx/mx1ads.c | |||
| @@ -27,7 +27,6 @@ | |||
| 27 | #include <asm/mach/arch.h> | 27 | #include <asm/mach/arch.h> |
| 28 | #include <linux/interrupt.h> | 28 | #include <linux/interrupt.h> |
| 29 | #include "generic.h" | 29 | #include "generic.h" |
| 30 | #include <asm/serial.h> | ||
| 31 | 30 | ||
| 32 | static struct resource cs89x0_resources[] = { | 31 | static struct resource cs89x0_resources[] = { |
| 33 | [0] = { | 32 | [0] = { |
diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c index 9e5a13bb39d0..52fac89e95b5 100644 --- a/arch/arm/mach-ixp2000/enp2611.c +++ b/arch/arm/mach-ixp2000/enp2611.c | |||
| @@ -106,6 +106,7 @@ static void __init enp2611_pci_preinit(void) | |||
| 106 | { | 106 | { |
| 107 | ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00100000); | 107 | ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00100000); |
| 108 | ixp2000_pci_preinit(); | 108 | ixp2000_pci_preinit(); |
| 109 | pcibios_setup("firmware"); | ||
| 109 | } | 110 | } |
| 110 | 111 | ||
| 111 | static inline int enp2611_pci_valid_device(struct pci_bus *bus, | 112 | static inline int enp2611_pci_valid_device(struct pci_bus *bus, |
diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c index 7c782403042a..09101271298e 100644 --- a/arch/arm/mach-ixp2000/ixdp2400.c +++ b/arch/arm/mach-ixp2000/ixdp2400.c | |||
| @@ -68,6 +68,7 @@ void __init ixdp2400_pci_preinit(void) | |||
| 68 | { | 68 | { |
| 69 | ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00100000); | 69 | ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00100000); |
| 70 | ixp2000_pci_preinit(); | 70 | ixp2000_pci_preinit(); |
| 71 | pcibios_setup("firmware"); | ||
| 71 | } | 72 | } |
| 72 | 73 | ||
| 73 | int ixdp2400_pci_setup(int nr, struct pci_sys_data *sys) | 74 | int ixdp2400_pci_setup(int nr, struct pci_sys_data *sys) |
diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c index 10f06606d460..150519fb38ec 100644 --- a/arch/arm/mach-ixp2000/ixdp2x01.c +++ b/arch/arm/mach-ixp2000/ixdp2x01.c | |||
| @@ -212,6 +212,7 @@ void __init ixdp2x01_pci_preinit(void) | |||
| 212 | { | 212 | { |
| 213 | ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00000000); | 213 | ixp2000_reg_write(IXP2000_PCI_ADDR_EXT, 0x00000000); |
| 214 | ixp2000_pci_preinit(); | 214 | ixp2000_pci_preinit(); |
| 215 | pcibios_setup("firmware"); | ||
| 215 | } | 216 | } |
| 216 | 217 | ||
| 217 | #define DEVPIN(dev, pin) ((pin) | ((dev) << 3)) | 218 | #define DEVPIN(dev, pin) ((pin) | ((dev) << 3)) |
| @@ -299,7 +300,9 @@ struct hw_pci ixdp2x01_pci __initdata = { | |||
| 299 | 300 | ||
| 300 | int __init ixdp2x01_pci_init(void) | 301 | int __init ixdp2x01_pci_init(void) |
| 301 | { | 302 | { |
| 302 | pci_common_init(&ixdp2x01_pci); | 303 | if (machine_is_ixdp2401() || machine_is_ixdp2801()) |
| 304 | pci_common_init(&ixdp2x01_pci); | ||
| 305 | |||
| 303 | return 0; | 306 | return 0; |
| 304 | } | 307 | } |
| 305 | 308 | ||
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c index bdc20b51b076..a177e78b2b87 100644 --- a/arch/arm/mach-omap1/board-generic.c +++ b/arch/arm/mach-omap1/board-generic.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | 30 | ||
| 31 | static void __init omap_generic_init_irq(void) | 31 | static void __init omap_generic_init_irq(void) |
| 32 | { | 32 | { |
| 33 | omap1_init_common_hw(); | ||
| 33 | omap_init_irq(); | 34 | omap_init_irq(); |
| 34 | } | 35 | } |
| 35 | 36 | ||
| @@ -104,7 +105,7 @@ static void __init omap_generic_init(void) | |||
| 104 | 105 | ||
| 105 | static void __init omap_generic_map_io(void) | 106 | static void __init omap_generic_map_io(void) |
| 106 | { | 107 | { |
| 107 | omap_map_common_io(); | 108 | omap1_map_common_io(); |
| 108 | } | 109 | } |
| 109 | 110 | ||
| 110 | MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710") | 111 | MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710") |
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index 9533c36a92df..89f0cc74a519 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c | |||
| @@ -128,6 +128,7 @@ static void __init h2_init_smc91x(void) | |||
| 128 | 128 | ||
| 129 | static void __init h2_init_irq(void) | 129 | static void __init h2_init_irq(void) |
| 130 | { | 130 | { |
| 131 | omap1_init_common_hw(); | ||
| 131 | omap_init_irq(); | 132 | omap_init_irq(); |
| 132 | omap_gpio_init(); | 133 | omap_gpio_init(); |
| 133 | h2_init_smc91x(); | 134 | h2_init_smc91x(); |
| @@ -194,7 +195,7 @@ static void __init h2_init(void) | |||
| 194 | 195 | ||
| 195 | static void __init h2_map_io(void) | 196 | static void __init h2_map_io(void) |
| 196 | { | 197 | { |
| 197 | omap_map_common_io(); | 198 | omap1_map_common_io(); |
| 198 | } | 199 | } |
| 199 | 200 | ||
| 200 | MACHINE_START(OMAP_H2, "TI-H2") | 201 | MACHINE_START(OMAP_H2, "TI-H2") |
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c index d665efc1c344..d9f386265996 100644 --- a/arch/arm/mach-omap1/board-h3.c +++ b/arch/arm/mach-omap1/board-h3.c | |||
| @@ -203,6 +203,7 @@ static void __init h3_init_smc91x(void) | |||
| 203 | 203 | ||
| 204 | void h3_init_irq(void) | 204 | void h3_init_irq(void) |
| 205 | { | 205 | { |
| 206 | omap1_init_common_hw(); | ||
| 206 | omap_init_irq(); | 207 | omap_init_irq(); |
| 207 | omap_gpio_init(); | 208 | omap_gpio_init(); |
| 208 | h3_init_smc91x(); | 209 | h3_init_smc91x(); |
| @@ -210,7 +211,7 @@ void h3_init_irq(void) | |||
| 210 | 211 | ||
| 211 | static void __init h3_map_io(void) | 212 | static void __init h3_map_io(void) |
| 212 | { | 213 | { |
| 213 | omap_map_common_io(); | 214 | omap1_map_common_io(); |
| 214 | } | 215 | } |
| 215 | 216 | ||
| 216 | MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board") | 217 | MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board") |
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c index 652f37c7f906..a04e4332915e 100644 --- a/arch/arm/mach-omap1/board-innovator.c +++ b/arch/arm/mach-omap1/board-innovator.c | |||
| @@ -181,6 +181,7 @@ static void __init innovator_init_smc91x(void) | |||
| 181 | 181 | ||
| 182 | void innovator_init_irq(void) | 182 | void innovator_init_irq(void) |
| 183 | { | 183 | { |
| 184 | omap1_init_common_hw(); | ||
| 184 | omap_init_irq(); | 185 | omap_init_irq(); |
| 185 | omap_gpio_init(); | 186 | omap_gpio_init(); |
| 186 | #ifdef CONFIG_ARCH_OMAP15XX | 187 | #ifdef CONFIG_ARCH_OMAP15XX |
| @@ -285,7 +286,7 @@ static void __init innovator_init(void) | |||
| 285 | 286 | ||
| 286 | static void __init innovator_map_io(void) | 287 | static void __init innovator_map_io(void) |
| 287 | { | 288 | { |
| 288 | omap_map_common_io(); | 289 | omap1_map_common_io(); |
| 289 | 290 | ||
| 290 | #ifdef CONFIG_ARCH_OMAP15XX | 291 | #ifdef CONFIG_ARCH_OMAP15XX |
| 291 | if (cpu_is_omap1510()) { | 292 | if (cpu_is_omap1510()) { |
diff --git a/arch/arm/mach-omap1/board-netstar.c b/arch/arm/mach-omap1/board-netstar.c index 58f783930d45..60d5f8a3339c 100644 --- a/arch/arm/mach-omap1/board-netstar.c +++ b/arch/arm/mach-omap1/board-netstar.c | |||
| @@ -65,6 +65,7 @@ static struct omap_board_config_kernel netstar_config[] = { | |||
| 65 | 65 | ||
| 66 | static void __init netstar_init_irq(void) | 66 | static void __init netstar_init_irq(void) |
| 67 | { | 67 | { |
| 68 | omap1_init_common_hw(); | ||
| 68 | omap_init_irq(); | 69 | omap_init_irq(); |
| 69 | omap_gpio_init(); | 70 | omap_gpio_init(); |
| 70 | } | 71 | } |
| @@ -108,7 +109,7 @@ static void __init netstar_init(void) | |||
| 108 | 109 | ||
| 109 | static void __init netstar_map_io(void) | 110 | static void __init netstar_map_io(void) |
| 110 | { | 111 | { |
| 111 | omap_map_common_io(); | 112 | omap1_map_common_io(); |
| 112 | } | 113 | } |
| 113 | 114 | ||
| 114 | #define MACHINE_PANICED 1 | 115 | #define MACHINE_PANICED 1 |
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c index e5d126e8f276..543fa136106d 100644 --- a/arch/arm/mach-omap1/board-osk.c +++ b/arch/arm/mach-omap1/board-osk.c | |||
| @@ -169,6 +169,7 @@ static void __init osk_init_cf(void) | |||
| 169 | 169 | ||
| 170 | static void __init osk_init_irq(void) | 170 | static void __init osk_init_irq(void) |
| 171 | { | 171 | { |
| 172 | omap1_init_common_hw(); | ||
| 172 | omap_init_irq(); | 173 | omap_init_irq(); |
| 173 | omap_gpio_init(); | 174 | omap_gpio_init(); |
| 174 | osk_init_smc91x(); | 175 | osk_init_smc91x(); |
| @@ -269,7 +270,7 @@ static void __init osk_init(void) | |||
| 269 | 270 | ||
| 270 | static void __init osk_map_io(void) | 271 | static void __init osk_map_io(void) |
| 271 | { | 272 | { |
| 272 | omap_map_common_io(); | 273 | omap1_map_common_io(); |
| 273 | } | 274 | } |
| 274 | 275 | ||
| 275 | MACHINE_START(OMAP_OSK, "TI-OSK") | 276 | MACHINE_START(OMAP_OSK, "TI-OSK") |
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c index 67fada207622..e488f7236775 100644 --- a/arch/arm/mach-omap1/board-palmte.c +++ b/arch/arm/mach-omap1/board-palmte.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | static void __init omap_generic_init_irq(void) | 35 | static void __init omap_generic_init_irq(void) |
| 36 | { | 36 | { |
| 37 | omap1_init_common_hw(); | ||
| 37 | omap_init_irq(); | 38 | omap_init_irq(); |
| 38 | } | 39 | } |
| 39 | 40 | ||
| @@ -72,7 +73,7 @@ static void __init omap_generic_init(void) | |||
| 72 | 73 | ||
| 73 | static void __init omap_generic_map_io(void) | 74 | static void __init omap_generic_map_io(void) |
| 74 | { | 75 | { |
| 75 | omap_map_common_io(); | 76 | omap1_map_common_io(); |
| 76 | } | 77 | } |
| 77 | 78 | ||
| 78 | MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E") | 79 | MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E") |
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c index 88708a0c52a2..3913a3cc0ce6 100644 --- a/arch/arm/mach-omap1/board-perseus2.c +++ b/arch/arm/mach-omap1/board-perseus2.c | |||
| @@ -144,6 +144,7 @@ static void __init perseus2_init_smc91x(void) | |||
| 144 | 144 | ||
| 145 | void omap_perseus2_init_irq(void) | 145 | void omap_perseus2_init_irq(void) |
| 146 | { | 146 | { |
| 147 | omap1_init_common_hw(); | ||
| 147 | omap_init_irq(); | 148 | omap_init_irq(); |
| 148 | omap_gpio_init(); | 149 | omap_gpio_init(); |
| 149 | perseus2_init_smc91x(); | 150 | perseus2_init_smc91x(); |
| @@ -160,7 +161,7 @@ static struct map_desc omap_perseus2_io_desc[] __initdata = { | |||
| 160 | 161 | ||
| 161 | static void __init omap_perseus2_map_io(void) | 162 | static void __init omap_perseus2_map_io(void) |
| 162 | { | 163 | { |
| 163 | omap_map_common_io(); | 164 | omap1_map_common_io(); |
| 164 | iotable_init(omap_perseus2_io_desc, | 165 | iotable_init(omap_perseus2_io_desc, |
| 165 | ARRAY_SIZE(omap_perseus2_io_desc)); | 166 | ARRAY_SIZE(omap_perseus2_io_desc)); |
| 166 | 167 | ||
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c index 959b4b847c87..bfd5fdd1a875 100644 --- a/arch/arm/mach-omap1/board-voiceblue.c +++ b/arch/arm/mach-omap1/board-voiceblue.c | |||
| @@ -162,6 +162,7 @@ static struct omap_board_config_kernel voiceblue_config[] = { | |||
| 162 | 162 | ||
| 163 | static void __init voiceblue_init_irq(void) | 163 | static void __init voiceblue_init_irq(void) |
| 164 | { | 164 | { |
| 165 | omap1_init_common_hw(); | ||
| 165 | omap_init_irq(); | 166 | omap_init_irq(); |
| 166 | omap_gpio_init(); | 167 | omap_gpio_init(); |
| 167 | } | 168 | } |
| @@ -206,7 +207,7 @@ static void __init voiceblue_init(void) | |||
| 206 | 207 | ||
| 207 | static void __init voiceblue_map_io(void) | 208 | static void __init voiceblue_map_io(void) |
| 208 | { | 209 | { |
| 209 | omap_map_common_io(); | 210 | omap1_map_common_io(); |
| 210 | } | 211 | } |
| 211 | 212 | ||
| 212 | #define MACHINE_PANICED 1 | 213 | #define MACHINE_PANICED 1 |
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c index a7a19f75b9e1..82d556be79c5 100644 --- a/arch/arm/mach-omap1/io.c +++ b/arch/arm/mach-omap1/io.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| 14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
| 15 | 15 | ||
| 16 | #include <asm/tlb.h> | ||
| 16 | #include <asm/mach/map.h> | 17 | #include <asm/mach/map.h> |
| 17 | #include <asm/io.h> | 18 | #include <asm/io.h> |
| 18 | #include <asm/arch/mux.h> | 19 | #include <asm/arch/mux.h> |
| @@ -83,15 +84,24 @@ static struct map_desc omap16xx_io_desc[] __initdata = { | |||
| 83 | }; | 84 | }; |
| 84 | #endif | 85 | #endif |
| 85 | 86 | ||
| 86 | static int initialized = 0; | 87 | /* |
| 87 | 88 | * Maps common IO regions for omap1. This should only get called from | |
| 88 | static void __init _omap_map_io(void) | 89 | * board specific init. |
| 90 | */ | ||
| 91 | void __init omap1_map_common_io(void) | ||
| 89 | { | 92 | { |
| 90 | initialized = 1; | ||
| 91 | |||
| 92 | /* We have to initialize the IO space mapping before we can run | ||
| 93 | * cpu_is_omapxxx() macros. */ | ||
| 94 | iotable_init(omap_io_desc, ARRAY_SIZE(omap_io_desc)); | 93 | iotable_init(omap_io_desc, ARRAY_SIZE(omap_io_desc)); |
| 94 | |||
| 95 | /* Normally devicemaps_init() would flush caches and tlb after | ||
| 96 | * mdesc->map_io(), but we must also do it here because of the CPU | ||
| 97 | * revision check below. | ||
| 98 | */ | ||
| 99 | local_flush_tlb_all(); | ||
| 100 | flush_cache_all(); | ||
| 101 | |||
| 102 | /* We want to check CPU revision early for cpu_is_omapxxxx() macros. | ||
| 103 | * IO space mapping must be initialized before we can do that. | ||
| 104 | */ | ||
| 95 | omap_check_revision(); | 105 | omap_check_revision(); |
| 96 | 106 | ||
| 97 | #ifdef CONFIG_ARCH_OMAP730 | 107 | #ifdef CONFIG_ARCH_OMAP730 |
| @@ -111,7 +121,14 @@ static void __init _omap_map_io(void) | |||
| 111 | #endif | 121 | #endif |
| 112 | 122 | ||
| 113 | omap_sram_init(); | 123 | omap_sram_init(); |
| 124 | } | ||
| 114 | 125 | ||
| 126 | /* | ||
| 127 | * Common low-level hardware init for omap1. This should only get called from | ||
| 128 | * board specific init. | ||
| 129 | */ | ||
| 130 | void __init omap1_init_common_hw() | ||
| 131 | { | ||
| 115 | /* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort | 132 | /* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort |
| 116 | * on a Posted Write in the TIPB Bridge". | 133 | * on a Posted Write in the TIPB Bridge". |
| 117 | */ | 134 | */ |
| @@ -121,16 +138,7 @@ static void __init _omap_map_io(void) | |||
| 121 | /* Must init clocks early to assure that timer interrupt works | 138 | /* Must init clocks early to assure that timer interrupt works |
| 122 | */ | 139 | */ |
| 123 | omap1_clk_init(); | 140 | omap1_clk_init(); |
| 124 | } | ||
| 125 | 141 | ||
| 126 | /* | 142 | omap1_mux_init(); |
| 127 | * This should only get called from board specific init | ||
| 128 | */ | ||
| 129 | void __init omap_map_common_io(void) | ||
| 130 | { | ||
| 131 | if (!initialized) { | ||
| 132 | _omap_map_io(); | ||
| 133 | omap1_mux_init(); | ||
| 134 | } | ||
| 135 | } | 143 | } |
| 136 | 144 | ||
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index b937123e5c65..eaecbf422d8c 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | 33 | ||
| 34 | static void __init omap_generic_init_irq(void) | 34 | static void __init omap_generic_init_irq(void) |
| 35 | { | 35 | { |
| 36 | omap2_init_common_hw(); | ||
| 36 | omap_init_irq(); | 37 | omap_init_irq(); |
| 37 | } | 38 | } |
| 38 | 39 | ||
| @@ -64,7 +65,7 @@ static void __init omap_generic_init(void) | |||
| 64 | 65 | ||
| 65 | static void __init omap_generic_map_io(void) | 66 | static void __init omap_generic_map_io(void) |
| 66 | { | 67 | { |
| 67 | omap_map_common_io(); | 68 | omap2_map_common_io(); |
| 68 | } | 69 | } |
| 69 | 70 | ||
| 70 | MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx") | 71 | MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx") |
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index c3c35d40378a..a300d634d8a5 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c | |||
| @@ -136,6 +136,7 @@ static inline void __init h4_init_smc91x(void) | |||
| 136 | 136 | ||
| 137 | static void __init omap_h4_init_irq(void) | 137 | static void __init omap_h4_init_irq(void) |
| 138 | { | 138 | { |
| 139 | omap2_init_common_hw(); | ||
| 139 | omap_init_irq(); | 140 | omap_init_irq(); |
| 140 | omap_gpio_init(); | 141 | omap_gpio_init(); |
| 141 | h4_init_smc91x(); | 142 | h4_init_smc91x(); |
| @@ -181,7 +182,7 @@ static void __init omap_h4_init(void) | |||
| 181 | 182 | ||
| 182 | static void __init omap_h4_map_io(void) | 183 | static void __init omap_h4_map_io(void) |
| 183 | { | 184 | { |
| 184 | omap_map_common_io(); | 185 | omap2_map_common_io(); |
| 185 | } | 186 | } |
| 186 | 187 | ||
| 187 | MACHINE_START(OMAP_H4, "OMAP2420 H4 board") | 188 | MACHINE_START(OMAP_H4, "OMAP2420 H4 board") |
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index b41b1efaa2cf..3baa70819f24 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c | |||
| @@ -44,7 +44,7 @@ unsigned int get_clk_frequency_khz( int info) | |||
| 44 | 44 | ||
| 45 | /* Read clkcfg register: it has turbo, b, half-turbo (and f) */ | 45 | /* Read clkcfg register: it has turbo, b, half-turbo (and f) */ |
| 46 | asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) ); | 46 | asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) ); |
| 47 | t = clkcfg & (1 << 1); | 47 | t = clkcfg & (1 << 0); |
| 48 | ht = clkcfg & (1 << 2); | 48 | ht = clkcfg & (1 << 2); |
| 49 | b = clkcfg & (1 << 3); | 49 | b = clkcfg & (1 << 3); |
| 50 | 50 | ||
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 4a222f59f2cf..4303d988c4bf 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c | |||
| @@ -182,7 +182,7 @@ static const struct icst307_params realview_oscvco_params = { | |||
| 182 | static void realview_oscvco_set(struct clk *clk, struct icst307_vco vco) | 182 | static void realview_oscvco_set(struct clk *clk, struct icst307_vco vco) |
| 183 | { | 183 | { |
| 184 | void __iomem *sys_lock = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LOCK_OFFSET; | 184 | void __iomem *sys_lock = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LOCK_OFFSET; |
| 185 | void __iomem *sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC1_OFFSET; | 185 | void __iomem *sys_osc = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_OSC4_OFFSET; |
| 186 | u32 val; | 186 | u32 val; |
| 187 | 187 | ||
| 188 | val = readl(sys_osc) & ~0x7ffff; | 188 | val = readl(sys_osc) & ~0x7ffff; |
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile index b4f1e051c768..1217bf00309c 100644 --- a/arch/arm/mach-s3c2410/Makefile +++ b/arch/arm/mach-s3c2410/Makefile | |||
| @@ -10,9 +10,13 @@ obj-m := | |||
| 10 | obj-n := | 10 | obj-n := |
| 11 | obj- := | 11 | obj- := |
| 12 | 12 | ||
| 13 | # S3C2400 support files | ||
| 14 | obj-$(CONFIG_CPU_S3C2400) += s3c2400-gpio.o | ||
| 15 | |||
| 13 | # S3C2410 support files | 16 | # S3C2410 support files |
| 14 | 17 | ||
| 15 | obj-$(CONFIG_CPU_S3C2410) += s3c2410.o | 18 | obj-$(CONFIG_CPU_S3C2410) += s3c2410.o |
| 19 | obj-$(CONFIG_CPU_S3C2410) += s3c2410-gpio.o | ||
| 16 | obj-$(CONFIG_S3C2410_DMA) += dma.o | 20 | obj-$(CONFIG_S3C2410_DMA) += dma.o |
| 17 | 21 | ||
| 18 | # Power Management support | 22 | # Power Management support |
| @@ -25,6 +29,7 @@ obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o | |||
| 25 | obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o | 29 | obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o |
| 26 | obj-$(CONFIG_CPU_S3C2440) += s3c2440-irq.o | 30 | obj-$(CONFIG_CPU_S3C2440) += s3c2440-irq.o |
| 27 | obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o | 31 | obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o |
| 32 | obj-$(CONFIG_CPU_S3C2440) += s3c2410-gpio.o | ||
| 28 | 33 | ||
| 29 | # bast extras | 34 | # bast extras |
| 30 | 35 | ||
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c index af2f3d52b61b..08489efdaf06 100644 --- a/arch/arm/mach-s3c2410/clock.c +++ b/arch/arm/mach-s3c2410/clock.c | |||
| @@ -40,7 +40,6 @@ | |||
| 40 | #include <linux/mutex.h> | 40 | #include <linux/mutex.h> |
| 41 | 41 | ||
| 42 | #include <asm/hardware.h> | 42 | #include <asm/hardware.h> |
| 43 | #include <asm/atomic.h> | ||
| 44 | #include <asm/irq.h> | 43 | #include <asm/irq.h> |
| 45 | #include <asm/io.h> | 44 | #include <asm/io.h> |
| 46 | 45 | ||
| @@ -59,22 +58,18 @@ static DEFINE_MUTEX(clocks_mutex); | |||
| 59 | void inline s3c24xx_clk_enable(unsigned int clocks, unsigned int enable) | 58 | void inline s3c24xx_clk_enable(unsigned int clocks, unsigned int enable) |
| 60 | { | 59 | { |
| 61 | unsigned long clkcon; | 60 | unsigned long clkcon; |
| 62 | unsigned long flags; | ||
| 63 | |||
| 64 | local_irq_save(flags); | ||
| 65 | 61 | ||
| 66 | clkcon = __raw_readl(S3C2410_CLKCON); | 62 | clkcon = __raw_readl(S3C2410_CLKCON); |
| 67 | clkcon &= ~clocks; | ||
| 68 | 63 | ||
| 69 | if (enable) | 64 | if (enable) |
| 70 | clkcon |= clocks; | 65 | clkcon |= clocks; |
| 66 | else | ||
| 67 | clkcon &= ~clocks; | ||
| 71 | 68 | ||
| 72 | /* ensure none of the special function bits set */ | 69 | /* ensure none of the special function bits set */ |
| 73 | clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER); | 70 | clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER); |
| 74 | 71 | ||
| 75 | __raw_writel(clkcon, S3C2410_CLKCON); | 72 | __raw_writel(clkcon, S3C2410_CLKCON); |
| 76 | |||
| 77 | local_irq_restore(flags); | ||
| 78 | } | 73 | } |
| 79 | 74 | ||
| 80 | /* enable and disable calls for use with the clk struct */ | 75 | /* enable and disable calls for use with the clk struct */ |
| @@ -138,16 +133,32 @@ void clk_put(struct clk *clk) | |||
| 138 | 133 | ||
| 139 | int clk_enable(struct clk *clk) | 134 | int clk_enable(struct clk *clk) |
| 140 | { | 135 | { |
| 141 | if (IS_ERR(clk)) | 136 | if (IS_ERR(clk) || clk == NULL) |
| 142 | return -EINVAL; | 137 | return -EINVAL; |
| 143 | 138 | ||
| 144 | return (clk->enable)(clk, 1); | 139 | clk_enable(clk->parent); |
| 140 | |||
| 141 | mutex_lock(&clocks_mutex); | ||
| 142 | |||
| 143 | if ((clk->usage++) == 0) | ||
| 144 | (clk->enable)(clk, 1); | ||
| 145 | |||
| 146 | mutex_unlock(&clocks_mutex); | ||
| 147 | return 0; | ||
| 145 | } | 148 | } |
| 146 | 149 | ||
| 147 | void clk_disable(struct clk *clk) | 150 | void clk_disable(struct clk *clk) |
| 148 | { | 151 | { |
| 149 | if (!IS_ERR(clk)) | 152 | if (IS_ERR(clk) || clk == NULL) |
| 153 | return; | ||
| 154 | |||
| 155 | mutex_lock(&clocks_mutex); | ||
| 156 | |||
| 157 | if ((--clk->usage) == 0) | ||
| 150 | (clk->enable)(clk, 0); | 158 | (clk->enable)(clk, 0); |
| 159 | |||
| 160 | mutex_unlock(&clocks_mutex); | ||
| 161 | clk_disable(clk->parent); | ||
| 151 | } | 162 | } |
| 152 | 163 | ||
| 153 | 164 | ||
| @@ -361,6 +372,14 @@ int s3c24xx_register_clock(struct clk *clk) | |||
| 361 | if (clk->enable == NULL) | 372 | if (clk->enable == NULL) |
| 362 | clk->enable = clk_null_enable; | 373 | clk->enable = clk_null_enable; |
| 363 | 374 | ||
| 375 | /* if this is a standard clock, set the usage state */ | ||
| 376 | |||
| 377 | if (clk->ctrlbit) { | ||
| 378 | unsigned long clkcon = __raw_readl(S3C2410_CLKCON); | ||
| 379 | |||
| 380 | clk->usage = (clkcon & clk->ctrlbit) ? 1 : 0; | ||
| 381 | } | ||
| 382 | |||
| 364 | /* add to the list of available clocks */ | 383 | /* add to the list of available clocks */ |
| 365 | 384 | ||
| 366 | mutex_lock(&clocks_mutex); | 385 | mutex_lock(&clocks_mutex); |
| @@ -402,6 +421,8 @@ int __init s3c24xx_setup_clocks(unsigned long xtal, | |||
| 402 | * the LCD clock if it is not needed. | 421 | * the LCD clock if it is not needed. |
| 403 | */ | 422 | */ |
| 404 | 423 | ||
| 424 | mutex_lock(&clocks_mutex); | ||
| 425 | |||
| 405 | s3c24xx_clk_enable(S3C2410_CLKCON_NAND, 0); | 426 | s3c24xx_clk_enable(S3C2410_CLKCON_NAND, 0); |
| 406 | s3c24xx_clk_enable(S3C2410_CLKCON_USBH, 0); | 427 | s3c24xx_clk_enable(S3C2410_CLKCON_USBH, 0); |
| 407 | s3c24xx_clk_enable(S3C2410_CLKCON_USBD, 0); | 428 | s3c24xx_clk_enable(S3C2410_CLKCON_USBD, 0); |
| @@ -409,6 +430,8 @@ int __init s3c24xx_setup_clocks(unsigned long xtal, | |||
| 409 | s3c24xx_clk_enable(S3C2410_CLKCON_IIC, 0); | 430 | s3c24xx_clk_enable(S3C2410_CLKCON_IIC, 0); |
| 410 | s3c24xx_clk_enable(S3C2410_CLKCON_SPI, 0); | 431 | s3c24xx_clk_enable(S3C2410_CLKCON_SPI, 0); |
| 411 | 432 | ||
| 433 | mutex_unlock(&clocks_mutex); | ||
| 434 | |||
| 412 | /* assume uart clocks are correctly setup */ | 435 | /* assume uart clocks are correctly setup */ |
| 413 | 436 | ||
| 414 | /* register our clocks */ | 437 | /* register our clocks */ |
diff --git a/arch/arm/mach-s3c2410/clock.h b/arch/arm/mach-s3c2410/clock.h index 177d5c8decf7..eb5c95d1e7f2 100644 --- a/arch/arm/mach-s3c2410/clock.h +++ b/arch/arm/mach-s3c2410/clock.h | |||
| @@ -16,6 +16,7 @@ struct clk { | |||
| 16 | struct clk *parent; | 16 | struct clk *parent; |
| 17 | const char *name; | 17 | const char *name; |
| 18 | int id; | 18 | int id; |
| 19 | int usage; | ||
| 19 | unsigned long rate; | 20 | unsigned long rate; |
| 20 | unsigned long ctrlbit; | 21 | unsigned long ctrlbit; |
| 21 | int (*enable)(struct clk *, int enable); | 22 | int (*enable)(struct clk *, int enable); |
diff --git a/arch/arm/mach-s3c2410/cpu.c b/arch/arm/mach-s3c2410/cpu.c index 687fe371369d..00a379334b60 100644 --- a/arch/arm/mach-s3c2410/cpu.c +++ b/arch/arm/mach-s3c2410/cpu.c | |||
| @@ -40,6 +40,7 @@ | |||
| 40 | 40 | ||
| 41 | #include "cpu.h" | 41 | #include "cpu.h" |
| 42 | #include "clock.h" | 42 | #include "clock.h" |
| 43 | #include "s3c2400.h" | ||
| 43 | #include "s3c2410.h" | 44 | #include "s3c2410.h" |
| 44 | #include "s3c2440.h" | 45 | #include "s3c2440.h" |
| 45 | 46 | ||
| @@ -55,6 +56,7 @@ struct cpu_table { | |||
| 55 | 56 | ||
| 56 | /* table of supported CPUs */ | 57 | /* table of supported CPUs */ |
| 57 | 58 | ||
| 59 | static const char name_s3c2400[] = "S3C2400"; | ||
| 58 | static const char name_s3c2410[] = "S3C2410"; | 60 | static const char name_s3c2410[] = "S3C2410"; |
| 59 | static const char name_s3c2440[] = "S3C2440"; | 61 | static const char name_s3c2440[] = "S3C2440"; |
| 60 | static const char name_s3c2410a[] = "S3C2410A"; | 62 | static const char name_s3c2410a[] = "S3C2410A"; |
| @@ -96,7 +98,16 @@ static struct cpu_table cpu_ids[] __initdata = { | |||
| 96 | .init_uarts = s3c2440_init_uarts, | 98 | .init_uarts = s3c2440_init_uarts, |
| 97 | .init = s3c2440_init, | 99 | .init = s3c2440_init, |
| 98 | .name = name_s3c2440a | 100 | .name = name_s3c2440a |
| 99 | } | 101 | }, |
| 102 | { | ||
| 103 | .idcode = 0x0, /* S3C2400 doesn't have an idcode */ | ||
| 104 | .idmask = 0xffffffff, | ||
| 105 | .map_io = s3c2400_map_io, | ||
| 106 | .init_clocks = s3c2400_init_clocks, | ||
| 107 | .init_uarts = s3c2400_init_uarts, | ||
| 108 | .init = s3c2400_init, | ||
| 109 | .name = name_s3c2400 | ||
| 110 | }, | ||
| 100 | }; | 111 | }; |
| 101 | 112 | ||
| 102 | /* minimal IO mapping */ | 113 | /* minimal IO mapping */ |
| @@ -148,12 +159,15 @@ static struct cpu_table *cpu; | |||
| 148 | 159 | ||
| 149 | void __init s3c24xx_init_io(struct map_desc *mach_desc, int size) | 160 | void __init s3c24xx_init_io(struct map_desc *mach_desc, int size) |
| 150 | { | 161 | { |
| 151 | unsigned long idcode; | 162 | unsigned long idcode = 0x0; |
| 152 | 163 | ||
| 153 | /* initialise the io descriptors we need for initialisation */ | 164 | /* initialise the io descriptors we need for initialisation */ |
| 154 | iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc)); | 165 | iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc)); |
| 155 | 166 | ||
| 167 | #ifndef CONFIG_CPU_S3C2400 | ||
| 156 | idcode = __raw_readl(S3C2410_GSTATUS1); | 168 | idcode = __raw_readl(S3C2410_GSTATUS1); |
| 169 | #endif | ||
| 170 | |||
| 157 | cpu = s3c_lookup_cpu(idcode); | 171 | cpu = s3c_lookup_cpu(idcode); |
| 158 | 172 | ||
| 159 | if (cpu == NULL) { | 173 | if (cpu == NULL) { |
diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c index b8d994a24d1c..0a47d38789a5 100644 --- a/arch/arm/mach-s3c2410/devs.c +++ b/arch/arm/mach-s3c2410/devs.c | |||
| @@ -275,6 +275,11 @@ static struct resource s3c_adc_resource[] = { | |||
| 275 | }, | 275 | }, |
| 276 | [1] = { | 276 | [1] = { |
| 277 | .start = IRQ_TC, | 277 | .start = IRQ_TC, |
| 278 | .end = IRQ_TC, | ||
| 279 | .flags = IORESOURCE_IRQ, | ||
| 280 | }, | ||
| 281 | [2] = { | ||
| 282 | .start = IRQ_ADC, | ||
| 278 | .end = IRQ_ADC, | 283 | .end = IRQ_ADC, |
| 279 | .flags = IORESOURCE_IRQ, | 284 | .flags = IORESOURCE_IRQ, |
| 280 | } | 285 | } |
diff --git a/arch/arm/mach-s3c2410/gpio.c b/arch/arm/mach-s3c2410/gpio.c index 23ea3d5fa09c..cd39e8684584 100644 --- a/arch/arm/mach-s3c2410/gpio.c +++ b/arch/arm/mach-s3c2410/gpio.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | * 05-Nov-2004 BJD EXPORT_SYMBOL() added for all code | 31 | * 05-Nov-2004 BJD EXPORT_SYMBOL() added for all code |
| 32 | * 13-Mar-2005 BJD Updates for __iomem | 32 | * 13-Mar-2005 BJD Updates for __iomem |
| 33 | * 26-Oct-2005 BJD Added generic configuration types | 33 | * 26-Oct-2005 BJD Added generic configuration types |
| 34 | * 15-Jan-2006 LCVR Added support for the S3C2400 | ||
| 34 | */ | 35 | */ |
| 35 | 36 | ||
| 36 | 37 | ||
| @@ -48,7 +49,7 @@ | |||
| 48 | 49 | ||
| 49 | void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function) | 50 | void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function) |
| 50 | { | 51 | { |
| 51 | void __iomem *base = S3C2410_GPIO_BASE(pin); | 52 | void __iomem *base = S3C24XX_GPIO_BASE(pin); |
| 52 | unsigned long mask; | 53 | unsigned long mask; |
| 53 | unsigned long con; | 54 | unsigned long con; |
| 54 | unsigned long flags; | 55 | unsigned long flags; |
| @@ -95,7 +96,7 @@ EXPORT_SYMBOL(s3c2410_gpio_cfgpin); | |||
| 95 | 96 | ||
| 96 | unsigned int s3c2410_gpio_getcfg(unsigned int pin) | 97 | unsigned int s3c2410_gpio_getcfg(unsigned int pin) |
| 97 | { | 98 | { |
| 98 | void __iomem *base = S3C2410_GPIO_BASE(pin); | 99 | void __iomem *base = S3C24XX_GPIO_BASE(pin); |
| 99 | unsigned long mask; | 100 | unsigned long mask; |
| 100 | 101 | ||
| 101 | if (pin < S3C2410_GPIO_BANKB) { | 102 | if (pin < S3C2410_GPIO_BANKB) { |
| @@ -111,7 +112,7 @@ EXPORT_SYMBOL(s3c2410_gpio_getcfg); | |||
| 111 | 112 | ||
| 112 | void s3c2410_gpio_pullup(unsigned int pin, unsigned int to) | 113 | void s3c2410_gpio_pullup(unsigned int pin, unsigned int to) |
| 113 | { | 114 | { |
| 114 | void __iomem *base = S3C2410_GPIO_BASE(pin); | 115 | void __iomem *base = S3C24XX_GPIO_BASE(pin); |
| 115 | unsigned long offs = S3C2410_GPIO_OFFSET(pin); | 116 | unsigned long offs = S3C2410_GPIO_OFFSET(pin); |
| 116 | unsigned long flags; | 117 | unsigned long flags; |
| 117 | unsigned long up; | 118 | unsigned long up; |
| @@ -133,7 +134,7 @@ EXPORT_SYMBOL(s3c2410_gpio_pullup); | |||
| 133 | 134 | ||
| 134 | void s3c2410_gpio_setpin(unsigned int pin, unsigned int to) | 135 | void s3c2410_gpio_setpin(unsigned int pin, unsigned int to) |
| 135 | { | 136 | { |
| 136 | void __iomem *base = S3C2410_GPIO_BASE(pin); | 137 | void __iomem *base = S3C24XX_GPIO_BASE(pin); |
| 137 | unsigned long offs = S3C2410_GPIO_OFFSET(pin); | 138 | unsigned long offs = S3C2410_GPIO_OFFSET(pin); |
| 138 | unsigned long flags; | 139 | unsigned long flags; |
| 139 | unsigned long dat; | 140 | unsigned long dat; |
| @@ -152,7 +153,7 @@ EXPORT_SYMBOL(s3c2410_gpio_setpin); | |||
| 152 | 153 | ||
| 153 | unsigned int s3c2410_gpio_getpin(unsigned int pin) | 154 | unsigned int s3c2410_gpio_getpin(unsigned int pin) |
| 154 | { | 155 | { |
| 155 | void __iomem *base = S3C2410_GPIO_BASE(pin); | 156 | void __iomem *base = S3C24XX_GPIO_BASE(pin); |
| 156 | unsigned long offs = S3C2410_GPIO_OFFSET(pin); | 157 | unsigned long offs = S3C2410_GPIO_OFFSET(pin); |
| 157 | 158 | ||
| 158 | return __raw_readl(base + 0x04) & (1<< offs); | 159 | return __raw_readl(base + 0x04) & (1<< offs); |
| @@ -166,70 +167,13 @@ unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change) | |||
| 166 | unsigned long misccr; | 167 | unsigned long misccr; |
| 167 | 168 | ||
| 168 | local_irq_save(flags); | 169 | local_irq_save(flags); |
| 169 | misccr = __raw_readl(S3C2410_MISCCR); | 170 | misccr = __raw_readl(S3C24XX_MISCCR); |
| 170 | misccr &= ~clear; | 171 | misccr &= ~clear; |
| 171 | misccr ^= change; | 172 | misccr ^= change; |
| 172 | __raw_writel(misccr, S3C2410_MISCCR); | 173 | __raw_writel(misccr, S3C24XX_MISCCR); |
| 173 | local_irq_restore(flags); | 174 | local_irq_restore(flags); |
| 174 | 175 | ||
| 175 | return misccr; | 176 | return misccr; |
| 176 | } | 177 | } |
| 177 | 178 | ||
| 178 | EXPORT_SYMBOL(s3c2410_modify_misccr); | 179 | EXPORT_SYMBOL(s3c2410_modify_misccr); |
| 179 | |||
| 180 | int s3c2410_gpio_getirq(unsigned int pin) | ||
| 181 | { | ||
| 182 | if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15_EINT23) | ||
| 183 | return -1; /* not valid interrupts */ | ||
| 184 | |||
| 185 | if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7) | ||
| 186 | return -1; /* not valid pin */ | ||
| 187 | |||
| 188 | if (pin < S3C2410_GPF4) | ||
| 189 | return (pin - S3C2410_GPF0) + IRQ_EINT0; | ||
| 190 | |||
| 191 | if (pin < S3C2410_GPG0) | ||
| 192 | return (pin - S3C2410_GPF4) + IRQ_EINT4; | ||
| 193 | |||
| 194 | return (pin - S3C2410_GPG0) + IRQ_EINT8; | ||
| 195 | } | ||
| 196 | |||
| 197 | EXPORT_SYMBOL(s3c2410_gpio_getirq); | ||
| 198 | |||
| 199 | int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on, | ||
| 200 | unsigned int config) | ||
| 201 | { | ||
| 202 | void __iomem *reg = S3C2410_EINFLT0; | ||
| 203 | unsigned long flags; | ||
| 204 | unsigned long val; | ||
| 205 | |||
| 206 | if (pin < S3C2410_GPG8 || pin > S3C2410_GPG15) | ||
| 207 | return -1; | ||
| 208 | |||
| 209 | config &= 0xff; | ||
| 210 | |||
| 211 | pin -= S3C2410_GPG8_EINT16; | ||
| 212 | reg += pin & ~3; | ||
| 213 | |||
| 214 | local_irq_save(flags); | ||
| 215 | |||
| 216 | /* update filter width and clock source */ | ||
| 217 | |||
| 218 | val = __raw_readl(reg); | ||
| 219 | val &= ~(0xff << ((pin & 3) * 8)); | ||
| 220 | val |= config << ((pin & 3) * 8); | ||
| 221 | __raw_writel(val, reg); | ||
| 222 | |||
| 223 | /* update filter enable */ | ||
| 224 | |||
| 225 | val = __raw_readl(S3C2410_EXTINT2); | ||
| 226 | val &= ~(1 << ((pin * 4) + 3)); | ||
| 227 | val |= on << ((pin * 4) + 3); | ||
| 228 | __raw_writel(val, S3C2410_EXTINT2); | ||
| 229 | |||
| 230 | local_irq_restore(flags); | ||
| 231 | |||
| 232 | return 0; | ||
| 233 | } | ||
| 234 | |||
| 235 | EXPORT_SYMBOL(s3c2410_gpio_irqfilter); | ||
diff --git a/arch/arm/mach-s3c2410/s3c2400-gpio.c b/arch/arm/mach-s3c2410/s3c2400-gpio.c new file mode 100644 index 000000000000..5127f39fa9bf --- /dev/null +++ b/arch/arm/mach-s3c2410/s3c2400-gpio.c | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | /* linux/arch/arm/mach-s3c2410/gpio.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2006 Lucas Correia Villa Real <lucasvr@gobolinux.org> | ||
| 4 | * | ||
| 5 | * S3C2400 GPIO support | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify | ||
| 8 | * it under the terms of the GNU General Public License as published by | ||
| 9 | * the Free Software Foundation; either version 2 of the License, or | ||
| 10 | * (at your option) any later version. | ||
| 11 | * | ||
| 12 | * This program is distributed in the hope that it will be useful, | ||
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | * GNU General Public License for more details. | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 20 | * | ||
| 21 | * Changelog | ||
| 22 | * 15-Jan-2006 LCVR Splitted from gpio.c, adding support for the S3C2400 | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include <linux/kernel.h> | ||
| 26 | #include <linux/init.h> | ||
| 27 | #include <linux/module.h> | ||
| 28 | #include <linux/interrupt.h> | ||
| 29 | #include <linux/ioport.h> | ||
| 30 | |||
| 31 | #include <asm/hardware.h> | ||
| 32 | #include <asm/irq.h> | ||
| 33 | #include <asm/io.h> | ||
| 34 | |||
| 35 | #include <asm/arch/regs-gpio.h> | ||
| 36 | |||
| 37 | int s3c2400_gpio_getirq(unsigned int pin) | ||
| 38 | { | ||
| 39 | if (pin < S3C2410_GPE0 || pin > S3C2400_GPE7_EINT7) | ||
| 40 | return -1; /* not valid interrupts */ | ||
| 41 | |||
| 42 | return (pin - S3C2410_GPE0) + IRQ_EINT0; | ||
| 43 | } | ||
| 44 | |||
| 45 | EXPORT_SYMBOL(s3c2400_gpio_getirq); | ||
diff --git a/arch/arm/mach-s3c2410/s3c2410-gpio.c b/arch/arm/mach-s3c2410/s3c2410-gpio.c new file mode 100644 index 000000000000..d5e1caea1d23 --- /dev/null +++ b/arch/arm/mach-s3c2410/s3c2410-gpio.c | |||
| @@ -0,0 +1,93 @@ | |||
| 1 | /* linux/arch/arm/mach-s3c2410/gpio.c | ||
| 2 | * | ||
| 3 | * Copyright (c) 2004-2006 Simtec Electronics | ||
| 4 | * Ben Dooks <ben@simtec.co.uk> | ||
| 5 | * | ||
| 6 | * S3C2410 GPIO support | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | * | ||
| 22 | * Changelog | ||
| 23 | * 15-Jan-2006 LCVR Splitted from gpio.c | ||
| 24 | */ | ||
| 25 | |||
| 26 | #include <linux/kernel.h> | ||
| 27 | #include <linux/init.h> | ||
| 28 | #include <linux/module.h> | ||
| 29 | #include <linux/interrupt.h> | ||
| 30 | #include <linux/ioport.h> | ||
| 31 | |||
| 32 | #include <asm/hardware.h> | ||
| 33 | #include <asm/irq.h> | ||
| 34 | #include <asm/io.h> | ||
| 35 | |||
| 36 | #include <asm/arch/regs-gpio.h> | ||
| 37 | |||
| 38 | int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on, | ||
| 39 | unsigned int config) | ||
| 40 | { | ||
| 41 | void __iomem *reg = S3C2410_EINFLT0; | ||
| 42 | unsigned long flags; | ||
| 43 | unsigned long val; | ||
| 44 | |||
| 45 | if (pin < S3C2410_GPG8 || pin > S3C2410_GPG15) | ||
| 46 | return -1; | ||
| 47 | |||
| 48 | config &= 0xff; | ||
| 49 | |||
| 50 | pin -= S3C2410_GPG8_EINT16; | ||
| 51 | reg += pin & ~3; | ||
| 52 | |||
| 53 | local_irq_save(flags); | ||
| 54 | |||
| 55 | /* update filter width and clock source */ | ||
| 56 | |||
| 57 | val = __raw_readl(reg); | ||
| 58 | val &= ~(0xff << ((pin & 3) * 8)); | ||
| 59 | val |= config << ((pin & 3) * 8); | ||
| 60 | __raw_writel(val, reg); | ||
| 61 | |||
| 62 | /* update filter enable */ | ||
| 63 | |||
| 64 | val = __raw_readl(S3C2410_EXTINT2); | ||
| 65 | val &= ~(1 << ((pin * 4) + 3)); | ||
| 66 | val |= on << ((pin * 4) + 3); | ||
| 67 | __raw_writel(val, S3C2410_EXTINT2); | ||
| 68 | |||
| 69 | local_irq_restore(flags); | ||
| 70 | |||
| 71 | return 0; | ||
| 72 | } | ||
| 73 | |||
| 74 | EXPORT_SYMBOL(s3c2410_gpio_irqfilter); | ||
| 75 | |||
| 76 | int s3c2410_gpio_getirq(unsigned int pin) | ||
| 77 | { | ||
| 78 | if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15_EINT23) | ||
| 79 | return -1; /* not valid interrupts */ | ||
| 80 | |||
| 81 | if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7) | ||
| 82 | return -1; /* not valid pin */ | ||
| 83 | |||
| 84 | if (pin < S3C2410_GPF4) | ||
| 85 | return (pin - S3C2410_GPF0) + IRQ_EINT0; | ||
| 86 | |||
| 87 | if (pin < S3C2410_GPG0) | ||
| 88 | return (pin - S3C2410_GPF4) + IRQ_EINT4; | ||
| 89 | |||
| 90 | return (pin - S3C2410_GPG0) + IRQ_EINT8; | ||
| 91 | } | ||
| 92 | |||
| 93 | EXPORT_SYMBOL(s3c2410_gpio_getirq); | ||
diff --git a/arch/arm/mach-s3c2410/sleep.S b/arch/arm/mach-s3c2410/sleep.S index e9a055b779b7..832fb86a03b4 100644 --- a/arch/arm/mach-s3c2410/sleep.S +++ b/arch/arm/mach-s3c2410/sleep.S | |||
| @@ -72,7 +72,7 @@ ENTRY(s3c2410_cpu_suspend) | |||
| 72 | @@ prepare cpu to sleep | 72 | @@ prepare cpu to sleep |
| 73 | 73 | ||
| 74 | ldr r4, =S3C2410_REFRESH | 74 | ldr r4, =S3C2410_REFRESH |
| 75 | ldr r5, =S3C2410_MISCCR | 75 | ldr r5, =S3C24XX_MISCCR |
| 76 | ldr r6, =S3C2410_CLKCON | 76 | ldr r6, =S3C2410_CLKCON |
| 77 | ldr r7, [ r4 ] @ get REFRESH (and ensure in TLB) | 77 | ldr r7, [ r4 ] @ get REFRESH (and ensure in TLB) |
| 78 | ldr r8, [ r5 ] @ get MISCCR (and ensure in TLB) | 78 | ldr r8, [ r5 ] @ get MISCCR (and ensure in TLB) |
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S index 72966d90e956..d921c1024ae0 100644 --- a/arch/arm/mm/cache-v6.S +++ b/arch/arm/mm/cache-v6.S | |||
| @@ -92,22 +92,16 @@ ENTRY(v6_coherent_kern_range) | |||
| 92 | * - the Icache does not read data from the write buffer | 92 | * - the Icache does not read data from the write buffer |
| 93 | */ | 93 | */ |
| 94 | ENTRY(v6_coherent_user_range) | 94 | ENTRY(v6_coherent_user_range) |
| 95 | bic r0, r0, #CACHE_LINE_SIZE - 1 | 95 | |
| 96 | 1: | ||
| 97 | #ifdef HARVARD_CACHE | 96 | #ifdef HARVARD_CACHE |
| 98 | mcr p15, 0, r0, c7, c10, 1 @ clean D line | 97 | bic r0, r0, #CACHE_LINE_SIZE - 1 |
| 98 | 1: mcr p15, 0, r0, c7, c10, 1 @ clean D line | ||
| 99 | mcr p15, 0, r0, c7, c5, 1 @ invalidate I line | 99 | mcr p15, 0, r0, c7, c5, 1 @ invalidate I line |
| 100 | #endif | 100 | add r0, r0, #CACHE_LINE_SIZE |
| 101 | mcr p15, 0, r0, c7, c5, 7 @ invalidate BTB entry | ||
| 102 | add r0, r0, #BTB_FLUSH_SIZE | ||
| 103 | mcr p15, 0, r0, c7, c5, 7 @ invalidate BTB entry | ||
| 104 | add r0, r0, #BTB_FLUSH_SIZE | ||
| 105 | mcr p15, 0, r0, c7, c5, 7 @ invalidate BTB entry | ||
| 106 | add r0, r0, #BTB_FLUSH_SIZE | ||
| 107 | mcr p15, 0, r0, c7, c5, 7 @ invalidate BTB entry | ||
| 108 | add r0, r0, #BTB_FLUSH_SIZE | ||
| 109 | cmp r0, r1 | 101 | cmp r0, r1 |
| 110 | blo 1b | 102 | blo 1b |
| 103 | #endif | ||
| 104 | mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB | ||
| 111 | #ifdef HARVARD_CACHE | 105 | #ifdef HARVARD_CACHE |
| 112 | mov r0, #0 | 106 | mov r0, #0 |
| 113 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer | 107 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer |
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S index 861b35947280..2d3823ec3153 100644 --- a/arch/arm/mm/proc-xscale.S +++ b/arch/arm/mm/proc-xscale.S | |||
| @@ -241,7 +241,15 @@ ENTRY(xscale_flush_user_cache_range) | |||
| 241 | * it also trashes the mini I-cache used by JTAG debuggers. | 241 | * it also trashes the mini I-cache used by JTAG debuggers. |
| 242 | */ | 242 | */ |
| 243 | ENTRY(xscale_coherent_kern_range) | 243 | ENTRY(xscale_coherent_kern_range) |
| 244 | /* FALLTHROUGH */ | 244 | bic r0, r0, #CACHELINESIZE - 1 |
| 245 | 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry | ||
| 246 | add r0, r0, #CACHELINESIZE | ||
| 247 | cmp r0, r1 | ||
| 248 | blo 1b | ||
| 249 | mov r0, #0 | ||
| 250 | mcr p15, 0, r0, c7, c5, 0 @ Invalidate I cache & BTB | ||
| 251 | mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer | ||
| 252 | mov pc, lr | ||
| 245 | 253 | ||
| 246 | /* | 254 | /* |
| 247 | * coherent_user_range(start, end) | 255 | * coherent_user_range(start, end) |
| @@ -252,18 +260,16 @@ ENTRY(xscale_coherent_kern_range) | |||
| 252 | * | 260 | * |
| 253 | * - start - virtual start address | 261 | * - start - virtual start address |
| 254 | * - end - virtual end address | 262 | * - end - virtual end address |
| 255 | * | ||
| 256 | * Note: single I-cache line invalidation isn't used here since | ||
| 257 | * it also trashes the mini I-cache used by JTAG debuggers. | ||
| 258 | */ | 263 | */ |
| 259 | ENTRY(xscale_coherent_user_range) | 264 | ENTRY(xscale_coherent_user_range) |
| 260 | bic r0, r0, #CACHELINESIZE - 1 | 265 | bic r0, r0, #CACHELINESIZE - 1 |
| 261 | 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry | 266 | 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry |
| 267 | mcr p15, 0, r0, c7, c5, 1 @ Invalidate I cache entry | ||
| 262 | add r0, r0, #CACHELINESIZE | 268 | add r0, r0, #CACHELINESIZE |
| 263 | cmp r0, r1 | 269 | cmp r0, r1 |
| 264 | blo 1b | 270 | blo 1b |
| 265 | mov r0, #0 | 271 | mov r0, #0 |
| 266 | mcr p15, 0, r0, c7, c5, 0 @ Invalidate I cache & BTB | 272 | mcr p15, 0, r0, c7, c5, 6 @ Invalidate BTB |
| 267 | mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer | 273 | mcr p15, 0, r0, c7, c10, 4 @ Drain Write (& Fill) Buffer |
| 268 | mov pc, lr | 274 | mov pc, lr |
| 269 | 275 | ||
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c index 1415930ceee1..6f8bc1f0e6a1 100644 --- a/arch/arm/oprofile/common.c +++ b/arch/arm/oprofile/common.c | |||
| @@ -137,8 +137,9 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
| 137 | if (spec) { | 137 | if (spec) { |
| 138 | init_MUTEX(&op_arm_sem); | 138 | init_MUTEX(&op_arm_sem); |
| 139 | 139 | ||
| 140 | if (spec->init() < 0) | 140 | ret = spec->init(); |
| 141 | return -ENODEV; | 141 | if (ret < 0) |
| 142 | return ret; | ||
| 142 | 143 | ||
| 143 | op_arm_model = spec; | 144 | op_arm_model = spec; |
| 144 | init_driverfs(); | 145 | init_driverfs(); |
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 792f66375830..ee82763b02b8 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
| 18 | 18 | ||
| 19 | #include <asm/mach/map.h> | 19 | #include <asm/mach/map.h> |
| 20 | #include <asm/tlb.h> | ||
| 20 | #include <asm/io.h> | 21 | #include <asm/io.h> |
| 21 | #include <asm/cacheflush.h> | 22 | #include <asm/cacheflush.h> |
| 22 | 23 | ||
| @@ -96,6 +97,14 @@ void __init omap_map_sram(void) | |||
| 96 | omap_sram_io_desc[0].length); | 97 | omap_sram_io_desc[0].length); |
| 97 | 98 | ||
| 98 | /* | 99 | /* |
| 100 | * Normally devicemaps_init() would flush caches and tlb after | ||
| 101 | * mdesc->map_io(), but since we're called from map_io(), we | ||
| 102 | * must do it here. | ||
| 103 | */ | ||
| 104 | local_flush_tlb_all(); | ||
| 105 | flush_cache_all(); | ||
| 106 | |||
| 107 | /* | ||
| 99 | * Looks like we need to preserve some bootloader code at the | 108 | * Looks like we need to preserve some bootloader code at the |
| 100 | * beginning of SRAM for jumping to flash for reboot to work... | 109 | * beginning of SRAM for jumping to flash for reboot to work... |
| 101 | */ | 110 | */ |
diff --git a/arch/cris/Makefile b/arch/cris/Makefile index ea65d585cf5e..ee114699ef8e 100644 --- a/arch/cris/Makefile +++ b/arch/cris/Makefile | |||
| @@ -119,7 +119,7 @@ $(SRC_ARCH)/.links: | |||
| 119 | @ln -sfn $(SRC_ARCH)/$(SARCH)/lib $(SRC_ARCH)/lib | 119 | @ln -sfn $(SRC_ARCH)/$(SARCH)/lib $(SRC_ARCH)/lib |
| 120 | @ln -sfn $(SRC_ARCH)/$(SARCH) $(SRC_ARCH)/arch | 120 | @ln -sfn $(SRC_ARCH)/$(SARCH) $(SRC_ARCH)/arch |
| 121 | @ln -sfn $(SRC_ARCH)/$(SARCH)/vmlinux.lds.S $(SRC_ARCH)/kernel/vmlinux.lds.S | 121 | @ln -sfn $(SRC_ARCH)/$(SARCH)/vmlinux.lds.S $(SRC_ARCH)/kernel/vmlinux.lds.S |
| 122 | @ln -sfn $(SRC_ARCH)/$(SARCH)/asm-offsets.c $(SRC_ARCH)/kernel/asm-offsets.c | 122 | @ln -sfn $(SRC_ARCH)/$(SARCH)/kernel/asm-offsets.c $(SRC_ARCH)/kernel/asm-offsets.c |
| 123 | @touch $@ | 123 | @touch $@ |
| 124 | 124 | ||
| 125 | # Create link to sub arch includes | 125 | # Create link to sub arch includes |
diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c index f214f74f264e..961c0d58ded4 100644 --- a/arch/cris/arch-v10/kernel/ptrace.c +++ b/arch/cris/arch-v10/kernel/ptrace.c | |||
| @@ -202,18 +202,18 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
| 202 | int i; | 202 | int i; |
| 203 | unsigned long tmp; | 203 | unsigned long tmp; |
| 204 | 204 | ||
| 205 | ret = 0; | ||
| 205 | for (i = 0; i <= PT_MAX; i++) { | 206 | for (i = 0; i <= PT_MAX; i++) { |
| 206 | tmp = get_reg(child, i); | 207 | tmp = get_reg(child, i); |
| 207 | 208 | ||
| 208 | if (put_user(tmp, datap)) { | 209 | if (put_user(tmp, datap)) { |
| 209 | ret = -EFAULT; | 210 | ret = -EFAULT; |
| 210 | goto out_tsk; | 211 | break; |
| 211 | } | 212 | } |
| 212 | 213 | ||
| 213 | data += sizeof(long); | 214 | data += sizeof(long); |
| 214 | } | 215 | } |
| 215 | 216 | ||
| 216 | ret = 0; | ||
| 217 | break; | 217 | break; |
| 218 | } | 218 | } |
| 219 | 219 | ||
| @@ -222,10 +222,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
| 222 | int i; | 222 | int i; |
| 223 | unsigned long tmp; | 223 | unsigned long tmp; |
| 224 | 224 | ||
| 225 | ret = 0; | ||
| 225 | for (i = 0; i <= PT_MAX; i++) { | 226 | for (i = 0; i <= PT_MAX; i++) { |
| 226 | if (get_user(tmp, datap)) { | 227 | if (get_user(tmp, datap)) { |
| 227 | ret = -EFAULT; | 228 | ret = -EFAULT; |
| 228 | goto out_tsk; | 229 | break; |
| 229 | } | 230 | } |
| 230 | 231 | ||
| 231 | if (i == PT_DCCR) { | 232 | if (i == PT_DCCR) { |
| @@ -237,7 +238,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
| 237 | data += sizeof(long); | 238 | data += sizeof(long); |
| 238 | } | 239 | } |
| 239 | 240 | ||
| 240 | ret = 0; | ||
| 241 | break; | 241 | break; |
| 242 | } | 242 | } |
| 243 | 243 | ||
diff --git a/arch/cris/kernel/setup.c b/arch/cris/kernel/setup.c index d11206e467ab..1ba57efff60d 100644 --- a/arch/cris/kernel/setup.c +++ b/arch/cris/kernel/setup.c | |||
| @@ -24,7 +24,6 @@ | |||
| 24 | /* | 24 | /* |
| 25 | * Setup options | 25 | * Setup options |
| 26 | */ | 26 | */ |
| 27 | struct drive_info_struct { char dummy[32]; } drive_info; | ||
| 28 | struct screen_info screen_info; | 27 | struct screen_info screen_info; |
| 29 | 28 | ||
| 30 | extern int root_mountflags; | 29 | extern int root_mountflags; |
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index d86c865a7cd2..0afec8566e7b 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig | |||
| @@ -442,6 +442,7 @@ config HIGHMEM4G | |||
| 442 | 442 | ||
| 443 | config HIGHMEM64G | 443 | config HIGHMEM64G |
| 444 | bool "64GB" | 444 | bool "64GB" |
| 445 | depends on X86_CMPXCHG64 | ||
| 445 | help | 446 | help |
| 446 | Select this if you have a 32-bit processor and more than 4 | 447 | Select this if you have a 32-bit processor and more than 4 |
| 447 | gigabytes of physical RAM. | 448 | gigabytes of physical RAM. |
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index f21fa0d4482f..79577f0ace98 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
| @@ -248,10 +248,17 @@ acpi_parse_lapic(acpi_table_entry_header * header, const unsigned long end) | |||
| 248 | 248 | ||
| 249 | acpi_table_print_madt_entry(header); | 249 | acpi_table_print_madt_entry(header); |
| 250 | 250 | ||
| 251 | /* Register even disabled CPUs for cpu hotplug */ | 251 | /* Record local apic id only when enabled */ |
| 252 | 252 | if (processor->flags.enabled) | |
| 253 | x86_acpiid_to_apicid[processor->acpi_id] = processor->id; | 253 | x86_acpiid_to_apicid[processor->acpi_id] = processor->id; |
| 254 | 254 | ||
| 255 | /* | ||
| 256 | * We need to register disabled CPU as well to permit | ||
| 257 | * counting disabled CPUs. This allows us to size | ||
| 258 | * cpus_possible_map more accurately, to permit | ||
| 259 | * to not preallocating memory for all NR_CPUS | ||
| 260 | * when we use CPU hotplug. | ||
| 261 | */ | ||
| 255 | mp_register_lapic(processor->id, /* APIC ID */ | 262 | mp_register_lapic(processor->id, /* APIC ID */ |
| 256 | processor->flags.enabled); /* Enabled? */ | 263 | processor->flags.enabled); /* Enabled? */ |
| 257 | 264 | ||
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index acd3f1e34ca6..f39e09ef64ec 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c | |||
| @@ -75,8 +75,10 @@ void ack_bad_irq(unsigned int irq) | |||
| 75 | * holds up an irq slot - in excessive cases (when multiple | 75 | * holds up an irq slot - in excessive cases (when multiple |
| 76 | * unexpected vectors occur) that might lock up the APIC | 76 | * unexpected vectors occur) that might lock up the APIC |
| 77 | * completely. | 77 | * completely. |
| 78 | * But only ack when the APIC is enabled -AK | ||
| 78 | */ | 79 | */ |
| 79 | ack_APIC_irq(); | 80 | if (cpu_has_apic) |
| 81 | ack_APIC_irq(); | ||
| 80 | } | 82 | } |
| 81 | 83 | ||
| 82 | void __init apic_intr_init(void) | 84 | void __init apic_intr_init(void) |
| @@ -1303,6 +1305,7 @@ int __init APIC_init_uniprocessor (void) | |||
| 1303 | if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { | 1305 | if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) { |
| 1304 | printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n", | 1306 | printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n", |
| 1305 | boot_cpu_physical_apicid); | 1307 | boot_cpu_physical_apicid); |
| 1308 | clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability); | ||
| 1306 | return -1; | 1309 | return -1; |
| 1307 | } | 1310 | } |
| 1308 | 1311 | ||
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c index 333578a4e91a..0810f81f2a05 100644 --- a/arch/i386/kernel/cpu/amd.c +++ b/arch/i386/kernel/cpu/amd.c | |||
| @@ -282,3 +282,11 @@ int __init amd_init_cpu(void) | |||
| 282 | } | 282 | } |
| 283 | 283 | ||
| 284 | //early_arch_initcall(amd_init_cpu); | 284 | //early_arch_initcall(amd_init_cpu); |
| 285 | |||
| 286 | static int __init amd_exit_cpu(void) | ||
| 287 | { | ||
| 288 | cpu_devs[X86_VENDOR_AMD] = NULL; | ||
| 289 | return 0; | ||
| 290 | } | ||
| 291 | |||
| 292 | late_initcall(amd_exit_cpu); | ||
diff --git a/arch/i386/kernel/cpu/centaur.c b/arch/i386/kernel/cpu/centaur.c index 0dd92a23d622..f52669ecb93f 100644 --- a/arch/i386/kernel/cpu/centaur.c +++ b/arch/i386/kernel/cpu/centaur.c | |||
| @@ -470,3 +470,11 @@ int __init centaur_init_cpu(void) | |||
| 470 | } | 470 | } |
| 471 | 471 | ||
| 472 | //early_arch_initcall(centaur_init_cpu); | 472 | //early_arch_initcall(centaur_init_cpu); |
| 473 | |||
| 474 | static int __init centaur_exit_cpu(void) | ||
| 475 | { | ||
| 476 | cpu_devs[X86_VENDOR_CENTAUR] = NULL; | ||
| 477 | return 0; | ||
| 478 | } | ||
| 479 | |||
| 480 | late_initcall(centaur_exit_cpu); | ||
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 15aee26ec2b6..7eb9213734a3 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c | |||
| @@ -44,6 +44,7 @@ static void default_init(struct cpuinfo_x86 * c) | |||
| 44 | 44 | ||
| 45 | static struct cpu_dev default_cpu = { | 45 | static struct cpu_dev default_cpu = { |
| 46 | .c_init = default_init, | 46 | .c_init = default_init, |
| 47 | .c_vendor = "Unknown", | ||
| 47 | }; | 48 | }; |
| 48 | static struct cpu_dev * this_cpu = &default_cpu; | 49 | static struct cpu_dev * this_cpu = &default_cpu; |
| 49 | 50 | ||
| @@ -150,6 +151,7 @@ static void __devinit get_cpu_vendor(struct cpuinfo_x86 *c, int early) | |||
| 150 | { | 151 | { |
| 151 | char *v = c->x86_vendor_id; | 152 | char *v = c->x86_vendor_id; |
| 152 | int i; | 153 | int i; |
| 154 | static int printed; | ||
| 153 | 155 | ||
| 154 | for (i = 0; i < X86_VENDOR_NUM; i++) { | 156 | for (i = 0; i < X86_VENDOR_NUM; i++) { |
| 155 | if (cpu_devs[i]) { | 157 | if (cpu_devs[i]) { |
| @@ -159,10 +161,17 @@ static void __devinit get_cpu_vendor(struct cpuinfo_x86 *c, int early) | |||
| 159 | c->x86_vendor = i; | 161 | c->x86_vendor = i; |
| 160 | if (!early) | 162 | if (!early) |
| 161 | this_cpu = cpu_devs[i]; | 163 | this_cpu = cpu_devs[i]; |
| 162 | break; | 164 | return; |
| 163 | } | 165 | } |
| 164 | } | 166 | } |
| 165 | } | 167 | } |
| 168 | if (!printed) { | ||
| 169 | printed++; | ||
| 170 | printk(KERN_ERR "CPU: Vendor unknown, using generic init.\n"); | ||
| 171 | printk(KERN_ERR "CPU: Your system may be unstable.\n"); | ||
| 172 | } | ||
| 173 | c->x86_vendor = X86_VENDOR_UNKNOWN; | ||
| 174 | this_cpu = &default_cpu; | ||
| 166 | } | 175 | } |
| 167 | 176 | ||
| 168 | 177 | ||
diff --git a/arch/i386/kernel/cpu/cyrix.c b/arch/i386/kernel/cpu/cyrix.c index 75015975d038..00f2e058797c 100644 --- a/arch/i386/kernel/cpu/cyrix.c +++ b/arch/i386/kernel/cpu/cyrix.c | |||
| @@ -345,7 +345,7 @@ static void __init init_cyrix(struct cpuinfo_x86 *c) | |||
| 345 | /* | 345 | /* |
| 346 | * Handle National Semiconductor branded processors | 346 | * Handle National Semiconductor branded processors |
| 347 | */ | 347 | */ |
| 348 | static void __devinit init_nsc(struct cpuinfo_x86 *c) | 348 | static void __init init_nsc(struct cpuinfo_x86 *c) |
| 349 | { | 349 | { |
| 350 | /* There may be GX1 processors in the wild that are branded | 350 | /* There may be GX1 processors in the wild that are branded |
| 351 | * NSC and not Cyrix. | 351 | * NSC and not Cyrix. |
| @@ -444,6 +444,14 @@ int __init cyrix_init_cpu(void) | |||
| 444 | 444 | ||
| 445 | //early_arch_initcall(cyrix_init_cpu); | 445 | //early_arch_initcall(cyrix_init_cpu); |
| 446 | 446 | ||
| 447 | static int __init cyrix_exit_cpu(void) | ||
| 448 | { | ||
| 449 | cpu_devs[X86_VENDOR_CYRIX] = NULL; | ||
| 450 | return 0; | ||
| 451 | } | ||
| 452 | |||
| 453 | late_initcall(cyrix_exit_cpu); | ||
| 454 | |||
| 447 | static struct cpu_dev nsc_cpu_dev __initdata = { | 455 | static struct cpu_dev nsc_cpu_dev __initdata = { |
| 448 | .c_vendor = "NSC", | 456 | .c_vendor = "NSC", |
| 449 | .c_ident = { "Geode by NSC" }, | 457 | .c_ident = { "Geode by NSC" }, |
| @@ -458,3 +466,11 @@ int __init nsc_init_cpu(void) | |||
| 458 | } | 466 | } |
| 459 | 467 | ||
| 460 | //early_arch_initcall(nsc_init_cpu); | 468 | //early_arch_initcall(nsc_init_cpu); |
| 469 | |||
| 470 | static int __init nsc_exit_cpu(void) | ||
| 471 | { | ||
| 472 | cpu_devs[X86_VENDOR_NSC] = NULL; | ||
| 473 | return 0; | ||
| 474 | } | ||
| 475 | |||
| 476 | late_initcall(nsc_exit_cpu); | ||
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c index af591c73345f..ffe58cee0c48 100644 --- a/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/arch/i386/kernel/cpu/intel_cacheinfo.c | |||
| @@ -152,6 +152,7 @@ static int __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_le | |||
| 152 | return 0; | 152 | return 0; |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | /* will only be called once; __init is safe here */ | ||
| 155 | static int __init find_num_cache_leaves(void) | 156 | static int __init find_num_cache_leaves(void) |
| 156 | { | 157 | { |
| 157 | unsigned int eax, ebx, ecx, edx; | 158 | unsigned int eax, ebx, ecx, edx; |
diff --git a/arch/i386/kernel/cpu/nexgen.c b/arch/i386/kernel/cpu/nexgen.c index 30898a260a5c..ad87fa58058d 100644 --- a/arch/i386/kernel/cpu/nexgen.c +++ b/arch/i386/kernel/cpu/nexgen.c | |||
| @@ -61,3 +61,11 @@ int __init nexgen_init_cpu(void) | |||
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | //early_arch_initcall(nexgen_init_cpu); | 63 | //early_arch_initcall(nexgen_init_cpu); |
| 64 | |||
| 65 | static int __init nexgen_exit_cpu(void) | ||
| 66 | { | ||
| 67 | cpu_devs[X86_VENDOR_NEXGEN] = NULL; | ||
| 68 | return 0; | ||
| 69 | } | ||
| 70 | |||
| 71 | late_initcall(nexgen_exit_cpu); | ||
diff --git a/arch/i386/kernel/cpu/rise.c b/arch/i386/kernel/cpu/rise.c index 8602425628ca..d08d5a2811c8 100644 --- a/arch/i386/kernel/cpu/rise.c +++ b/arch/i386/kernel/cpu/rise.c | |||
| @@ -51,3 +51,11 @@ int __init rise_init_cpu(void) | |||
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | //early_arch_initcall(rise_init_cpu); | 53 | //early_arch_initcall(rise_init_cpu); |
| 54 | |||
| 55 | static int __init rise_exit_cpu(void) | ||
| 56 | { | ||
| 57 | cpu_devs[X86_VENDOR_RISE] = NULL; | ||
| 58 | return 0; | ||
| 59 | } | ||
| 60 | |||
| 61 | late_initcall(rise_exit_cpu); | ||
diff --git a/arch/i386/kernel/cpu/transmeta.c b/arch/i386/kernel/cpu/transmeta.c index fc426380366b..bdbeb77f4e22 100644 --- a/arch/i386/kernel/cpu/transmeta.c +++ b/arch/i386/kernel/cpu/transmeta.c | |||
| @@ -84,7 +84,7 @@ static void __init init_transmeta(struct cpuinfo_x86 *c) | |||
| 84 | #endif | 84 | #endif |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | static void transmeta_identify(struct cpuinfo_x86 * c) | 87 | static void __init transmeta_identify(struct cpuinfo_x86 * c) |
| 88 | { | 88 | { |
| 89 | u32 xlvl; | 89 | u32 xlvl; |
| 90 | generic_identify(c); | 90 | generic_identify(c); |
| @@ -111,3 +111,11 @@ int __init transmeta_init_cpu(void) | |||
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | //early_arch_initcall(transmeta_init_cpu); | 113 | //early_arch_initcall(transmeta_init_cpu); |
| 114 | |||
| 115 | static int __init transmeta_exit_cpu(void) | ||
| 116 | { | ||
| 117 | cpu_devs[X86_VENDOR_TRANSMETA] = NULL; | ||
| 118 | return 0; | ||
| 119 | } | ||
| 120 | |||
| 121 | late_initcall(transmeta_exit_cpu); | ||
diff --git a/arch/i386/kernel/cpu/umc.c b/arch/i386/kernel/cpu/umc.c index 264fcad559d5..2cd988f6dc55 100644 --- a/arch/i386/kernel/cpu/umc.c +++ b/arch/i386/kernel/cpu/umc.c | |||
| @@ -31,3 +31,11 @@ int __init umc_init_cpu(void) | |||
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | //early_arch_initcall(umc_init_cpu); | 33 | //early_arch_initcall(umc_init_cpu); |
| 34 | |||
| 35 | static int __init umc_exit_cpu(void) | ||
| 36 | { | ||
| 37 | cpu_devs[X86_VENDOR_UMC] = NULL; | ||
| 38 | return 0; | ||
| 39 | } | ||
| 40 | |||
| 41 | late_initcall(umc_exit_cpu); | ||
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index d661703ac1cb..63f39a7e2c96 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c | |||
| @@ -138,7 +138,7 @@ static int __init check_nmi_watchdog(void) | |||
| 138 | if (nmi_watchdog == NMI_LOCAL_APIC) | 138 | if (nmi_watchdog == NMI_LOCAL_APIC) |
| 139 | smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0); | 139 | smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0); |
| 140 | 140 | ||
| 141 | for (cpu = 0; cpu < NR_CPUS; cpu++) | 141 | for_each_cpu(cpu) |
| 142 | prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count; | 142 | prev_nmi_count[cpu] = per_cpu(irq_stat, cpu).__nmi_count; |
| 143 | local_irq_enable(); | 143 | local_irq_enable(); |
| 144 | mdelay((10*1000)/nmi_hz); // wait 10 ticks | 144 | mdelay((10*1000)/nmi_hz); // wait 10 ticks |
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 2185377fdde1..0480454ebffa 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c | |||
| @@ -297,8 +297,10 @@ void show_regs(struct pt_regs * regs) | |||
| 297 | 297 | ||
| 298 | if (user_mode(regs)) | 298 | if (user_mode(regs)) |
| 299 | printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp); | 299 | printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp); |
| 300 | printk(" EFLAGS: %08lx %s (%s)\n", | 300 | printk(" EFLAGS: %08lx %s (%s %.*s)\n", |
| 301 | regs->eflags, print_tainted(), system_utsname.release); | 301 | regs->eflags, print_tainted(), system_utsname.release, |
| 302 | (int)strcspn(system_utsname.version, " "), | ||
| 303 | system_utsname.version); | ||
| 302 | printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", | 304 | printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", |
| 303 | regs->eax,regs->ebx,regs->ecx,regs->edx); | 305 | regs->eax,regs->ebx,regs->ecx,regs->edx); |
| 304 | printk("ESI: %08lx EDI: %08lx EBP: %08lx", | 306 | printk("ESI: %08lx EDI: %08lx EBP: %08lx", |
diff --git a/arch/i386/kernel/syscall_table.S b/arch/i386/kernel/syscall_table.S index 1b665928336b..5a8b3fb6d27b 100644 --- a/arch/i386/kernel/syscall_table.S +++ b/arch/i386/kernel/syscall_table.S | |||
| @@ -309,3 +309,4 @@ ENTRY(sys_call_table) | |||
| 309 | .long sys_faccessat | 309 | .long sys_faccessat |
| 310 | .long sys_pselect6 | 310 | .long sys_pselect6 |
| 311 | .long sys_ppoll | 311 | .long sys_ppoll |
| 312 | .long sys_unshare /* 310 */ | ||
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 0aaebf3e1cfa..b814dbdcc91e 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
| @@ -166,7 +166,8 @@ static void show_trace_log_lvl(struct task_struct *task, | |||
| 166 | stack = (unsigned long*)context->previous_esp; | 166 | stack = (unsigned long*)context->previous_esp; |
| 167 | if (!stack) | 167 | if (!stack) |
| 168 | break; | 168 | break; |
| 169 | printk(KERN_EMERG " =======================\n"); | 169 | printk(log_lvl); |
| 170 | printk(" =======================\n"); | ||
| 170 | } | 171 | } |
| 171 | } | 172 | } |
| 172 | 173 | ||
| @@ -239,9 +240,11 @@ void show_registers(struct pt_regs *regs) | |||
| 239 | } | 240 | } |
| 240 | print_modules(); | 241 | print_modules(); |
| 241 | printk(KERN_EMERG "CPU: %d\nEIP: %04x:[<%08lx>] %s VLI\n" | 242 | printk(KERN_EMERG "CPU: %d\nEIP: %04x:[<%08lx>] %s VLI\n" |
| 242 | "EFLAGS: %08lx (%s) \n", | 243 | "EFLAGS: %08lx (%s %.*s) \n", |
| 243 | smp_processor_id(), 0xffff & regs->xcs, regs->eip, | 244 | smp_processor_id(), 0xffff & regs->xcs, regs->eip, |
| 244 | print_tainted(), regs->eflags, system_utsname.release); | 245 | print_tainted(), regs->eflags, system_utsname.release, |
| 246 | (int)strcspn(system_utsname.version, " "), | ||
| 247 | system_utsname.version); | ||
| 245 | print_symbol(KERN_EMERG "EIP is at %s\n", regs->eip); | 248 | print_symbol(KERN_EMERG "EIP is at %s\n", regs->eip); |
| 246 | printk(KERN_EMERG "eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", | 249 | printk(KERN_EMERG "eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", |
| 247 | regs->eax, regs->ebx, regs->ecx, regs->edx); | 250 | regs->eax, regs->ebx, regs->ecx, regs->edx); |
diff --git a/arch/i386/oprofile/backtrace.c b/arch/i386/oprofile/backtrace.c index 21654be3f73f..acc18138fb22 100644 --- a/arch/i386/oprofile/backtrace.c +++ b/arch/i386/oprofile/backtrace.c | |||
| @@ -49,7 +49,9 @@ dump_backtrace(struct frame_head * head) | |||
| 49 | * | stack | | 49 | * | stack | |
| 50 | * --------------- saved regs->ebp value if valid (frame_head address) | 50 | * --------------- saved regs->ebp value if valid (frame_head address) |
| 51 | * . . | 51 | * . . |
| 52 | * --------------- struct pt_regs stored on stack (struct pt_regs *) | 52 | * --------------- saved regs->rsp value if x86_64 |
| 53 | * | | | ||
| 54 | * --------------- struct pt_regs * stored on stack if 32-bit | ||
| 53 | * | | | 55 | * | | |
| 54 | * . . | 56 | * . . |
| 55 | * | | | 57 | * | | |
| @@ -57,13 +59,26 @@ dump_backtrace(struct frame_head * head) | |||
| 57 | * | | | 59 | * | | |
| 58 | * | | \/ Lower addresses | 60 | * | | \/ Lower addresses |
| 59 | * | 61 | * |
| 60 | * Thus, &pt_regs <-> stack base restricts the valid(ish) ebp values | 62 | * Thus, regs (or regs->rsp for x86_64) <-> stack base restricts the |
| 63 | * valid(ish) ebp values. Note: (1) for x86_64, NMI and several other | ||
| 64 | * exceptions use special stacks, maintained by the interrupt stack table | ||
| 65 | * (IST). These stacks are set up in trap_init() in | ||
| 66 | * arch/x86_64/kernel/traps.c. Thus, for x86_64, regs now does not point | ||
| 67 | * to the kernel stack; instead, it points to some location on the NMI | ||
| 68 | * stack. On the other hand, regs->rsp is the stack pointer saved when the | ||
| 69 | * NMI occurred. (2) For 32-bit, regs->esp is not valid because the | ||
| 70 | * processor does not save %esp on the kernel stack when interrupts occur | ||
| 71 | * in the kernel mode. | ||
| 61 | */ | 72 | */ |
| 62 | #ifdef CONFIG_FRAME_POINTER | 73 | #ifdef CONFIG_FRAME_POINTER |
| 63 | static int valid_kernel_stack(struct frame_head * head, struct pt_regs * regs) | 74 | static int valid_kernel_stack(struct frame_head * head, struct pt_regs * regs) |
| 64 | { | 75 | { |
| 65 | unsigned long headaddr = (unsigned long)head; | 76 | unsigned long headaddr = (unsigned long)head; |
| 77 | #ifdef CONFIG_X86_64 | ||
| 78 | unsigned long stack = (unsigned long)regs->rsp; | ||
| 79 | #else | ||
| 66 | unsigned long stack = (unsigned long)regs; | 80 | unsigned long stack = (unsigned long)regs; |
| 81 | #endif | ||
| 67 | unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE; | 82 | unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE; |
| 68 | 83 | ||
| 69 | return headaddr > stack && headaddr < stack_base; | 84 | return headaddr > stack && headaddr < stack_base; |
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 199eeaf0f4e3..845cd0902a50 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
| @@ -194,7 +194,6 @@ config IA64_L1_CACHE_SHIFT | |||
| 194 | default "7" if MCKINLEY | 194 | default "7" if MCKINLEY |
| 195 | default "6" if ITANIUM | 195 | default "6" if ITANIUM |
| 196 | 196 | ||
| 197 | # align cache-sensitive data to 64 bytes | ||
| 198 | config IA64_CYCLONE | 197 | config IA64_CYCLONE |
| 199 | bool "Cyclone (EXA) Time Source support" | 198 | bool "Cyclone (EXA) Time Source support" |
| 200 | help | 199 | help |
| @@ -374,6 +373,9 @@ config IA64_PALINFO | |||
| 374 | To use this option, you have to ensure that the "/proc file system | 373 | To use this option, you have to ensure that the "/proc file system |
| 375 | support" (CONFIG_PROC_FS) is enabled, too. | 374 | support" (CONFIG_PROC_FS) is enabled, too. |
| 376 | 375 | ||
| 376 | config SGI_SN | ||
| 377 | def_bool y if (IA64_SGI_SN2 || IA64_GENERIC) | ||
| 378 | |||
| 377 | source "drivers/firmware/Kconfig" | 379 | source "drivers/firmware/Kconfig" |
| 378 | 380 | ||
| 379 | source "fs/Kconfig.binfmt" | 381 | source "fs/Kconfig.binfmt" |
diff --git a/arch/ia64/dig/setup.c b/arch/ia64/dig/setup.c index d58003f1ad02..c9104bfff667 100644 --- a/arch/ia64/dig/setup.c +++ b/arch/ia64/dig/setup.c | |||
| @@ -25,16 +25,6 @@ | |||
| 25 | #include <asm/machvec.h> | 25 | #include <asm/machvec.h> |
| 26 | #include <asm/system.h> | 26 | #include <asm/system.h> |
| 27 | 27 | ||
| 28 | /* | ||
| 29 | * This is here so we can use the CMOS detection in ide-probe.c to | ||
| 30 | * determine what drives are present. In theory, we don't need this | ||
| 31 | * as the auto-detection could be done via ide-probe.c:do_probe() but | ||
| 32 | * in practice that would be much slower, which is painful when | ||
| 33 | * running in the simulator. Note that passing zeroes in DRIVE_INFO | ||
| 34 | * is sufficient (the IDE driver will autodetect the drive geometry). | ||
| 35 | */ | ||
| 36 | char drive_info[4*16]; | ||
| 37 | |||
| 38 | void __init | 28 | void __init |
| 39 | dig_setup (char **cmdline_p) | 29 | dig_setup (char **cmdline_p) |
| 40 | { | 30 | { |
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c index c485a3b32ba8..9990320b6f9a 100644 --- a/arch/ia64/kernel/efi.c +++ b/arch/ia64/kernel/efi.c | |||
| @@ -410,24 +410,16 @@ efi_init (void) | |||
| 410 | efi_config_table_t *config_tables; | 410 | efi_config_table_t *config_tables; |
| 411 | efi_char16_t *c16; | 411 | efi_char16_t *c16; |
| 412 | u64 efi_desc_size; | 412 | u64 efi_desc_size; |
| 413 | char *cp, *end, vendor[100] = "unknown"; | 413 | char *cp, vendor[100] = "unknown"; |
| 414 | extern char saved_command_line[]; | 414 | extern char saved_command_line[]; |
| 415 | int i; | 415 | int i; |
| 416 | 416 | ||
| 417 | /* it's too early to be able to use the standard kernel command line support... */ | 417 | /* it's too early to be able to use the standard kernel command line support... */ |
| 418 | for (cp = saved_command_line; *cp; ) { | 418 | for (cp = saved_command_line; *cp; ) { |
| 419 | if (memcmp(cp, "mem=", 4) == 0) { | 419 | if (memcmp(cp, "mem=", 4) == 0) { |
| 420 | cp += 4; | 420 | mem_limit = memparse(cp + 4, &cp); |
| 421 | mem_limit = memparse(cp, &end); | ||
| 422 | if (end != cp) | ||
| 423 | break; | ||
| 424 | cp = end; | ||
| 425 | } else if (memcmp(cp, "max_addr=", 9) == 0) { | 421 | } else if (memcmp(cp, "max_addr=", 9) == 0) { |
| 426 | cp += 9; | 422 | max_addr = GRANULEROUNDDOWN(memparse(cp + 9, &cp)); |
| 427 | max_addr = GRANULEROUNDDOWN(memparse(cp, &end)); | ||
| 428 | if (end != cp) | ||
| 429 | break; | ||
| 430 | cp = end; | ||
| 431 | } else { | 423 | } else { |
| 432 | while (*cp != ' ' && *cp) | 424 | while (*cp != ' ' && *cp) |
| 433 | ++cp; | 425 | ++cp; |
| @@ -458,7 +450,7 @@ efi_init (void) | |||
| 458 | /* Show what we know for posterity */ | 450 | /* Show what we know for posterity */ |
| 459 | c16 = __va(efi.systab->fw_vendor); | 451 | c16 = __va(efi.systab->fw_vendor); |
| 460 | if (c16) { | 452 | if (c16) { |
| 461 | for (i = 0;i < (int) sizeof(vendor) && *c16; ++i) | 453 | for (i = 0;i < (int) sizeof(vendor) - 1 && *c16; ++i) |
| 462 | vendor[i] = *c16++; | 454 | vendor[i] = *c16++; |
| 463 | vendor[i] = '\0'; | 455 | vendor[i] = '\0'; |
| 464 | } | 456 | } |
diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S index fbc7ea35dd57..f1778a84ea61 100644 --- a/arch/ia64/kernel/head.S +++ b/arch/ia64/kernel/head.S | |||
| @@ -352,6 +352,7 @@ start_ap: | |||
| 352 | mov ar.rsc=0 // place RSE in enforced lazy mode | 352 | mov ar.rsc=0 // place RSE in enforced lazy mode |
| 353 | ;; | 353 | ;; |
| 354 | loadrs // clear the dirty partition | 354 | loadrs // clear the dirty partition |
| 355 | mov IA64_KR(PER_CPU_DATA)=r0 // clear physical per-CPU base | ||
| 355 | ;; | 356 | ;; |
| 356 | mov ar.bspstore=r2 // establish the new RSE stack | 357 | mov ar.bspstore=r2 // establish the new RSE stack |
| 357 | ;; | 358 | ;; |
diff --git a/arch/ia64/kernel/sal.c b/arch/ia64/kernel/sal.c index acc0f132f86c..056f7a6eedc7 100644 --- a/arch/ia64/kernel/sal.c +++ b/arch/ia64/kernel/sal.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/spinlock.h> | 14 | #include <linux/spinlock.h> |
| 15 | #include <linux/string.h> | 15 | #include <linux/string.h> |
| 16 | 16 | ||
| 17 | #include <asm/delay.h> | ||
| 17 | #include <asm/page.h> | 18 | #include <asm/page.h> |
| 18 | #include <asm/sal.h> | 19 | #include <asm/sal.h> |
| 19 | #include <asm/pal.h> | 20 | #include <asm/pal.h> |
| @@ -214,6 +215,78 @@ chk_nointroute_opt(void) | |||
| 214 | static void __init sal_desc_ap_wakeup(void *p) { } | 215 | static void __init sal_desc_ap_wakeup(void *p) { } |
| 215 | #endif | 216 | #endif |
| 216 | 217 | ||
| 218 | /* | ||
| 219 | * HP rx5670 firmware polls for interrupts during SAL_CACHE_FLUSH by reading | ||
| 220 | * cr.ivr, but it never writes cr.eoi. This leaves any interrupt marked as | ||
| 221 | * "in-service" and masks other interrupts of equal or lower priority. | ||
| 222 | * | ||
| 223 | * HP internal defect reports: F1859, F2775, F3031. | ||
| 224 | */ | ||
| 225 | static int sal_cache_flush_drops_interrupts; | ||
| 226 | |||
| 227 | static void __init | ||
| 228 | check_sal_cache_flush (void) | ||
| 229 | { | ||
| 230 | unsigned long flags, itv; | ||
| 231 | int cpu; | ||
| 232 | u64 vector; | ||
| 233 | |||
| 234 | cpu = get_cpu(); | ||
| 235 | local_irq_save(flags); | ||
| 236 | |||
| 237 | /* | ||
| 238 | * Schedule a timer interrupt, wait until it's reported, and see if | ||
| 239 | * SAL_CACHE_FLUSH drops it. | ||
| 240 | */ | ||
| 241 | itv = ia64_get_itv(); | ||
| 242 | BUG_ON((itv & (1 << 16)) == 0); | ||
| 243 | |||
| 244 | ia64_set_itv(IA64_TIMER_VECTOR); | ||
| 245 | ia64_set_itm(ia64_get_itc() + 1000); | ||
| 246 | |||
| 247 | while (!ia64_get_irr(IA64_TIMER_VECTOR)) | ||
| 248 | cpu_relax(); | ||
| 249 | |||
| 250 | ia64_sal_cache_flush(3); | ||
| 251 | |||
| 252 | if (ia64_get_irr(IA64_TIMER_VECTOR)) { | ||
| 253 | vector = ia64_get_ivr(); | ||
| 254 | ia64_eoi(); | ||
| 255 | WARN_ON(vector != IA64_TIMER_VECTOR); | ||
| 256 | } else { | ||
| 257 | sal_cache_flush_drops_interrupts = 1; | ||
| 258 | printk(KERN_ERR "SAL: SAL_CACHE_FLUSH drops interrupts; " | ||
| 259 | "PAL_CACHE_FLUSH will be used instead\n"); | ||
| 260 | ia64_eoi(); | ||
| 261 | } | ||
| 262 | |||
| 263 | ia64_set_itv(itv); | ||
| 264 | local_irq_restore(flags); | ||
| 265 | put_cpu(); | ||
| 266 | } | ||
| 267 | |||
| 268 | s64 | ||
| 269 | ia64_sal_cache_flush (u64 cache_type) | ||
| 270 | { | ||
| 271 | struct ia64_sal_retval isrv; | ||
| 272 | |||
| 273 | if (sal_cache_flush_drops_interrupts) { | ||
| 274 | unsigned long flags; | ||
| 275 | u64 progress; | ||
| 276 | s64 rc; | ||
| 277 | |||
| 278 | progress = 0; | ||
| 279 | local_irq_save(flags); | ||
| 280 | rc = ia64_pal_cache_flush(cache_type, | ||
| 281 | PAL_CACHE_FLUSH_INVALIDATE, &progress, NULL); | ||
| 282 | local_irq_restore(flags); | ||
| 283 | return rc; | ||
| 284 | } | ||
| 285 | |||
| 286 | SAL_CALL(isrv, SAL_CACHE_FLUSH, cache_type, 0, 0, 0, 0, 0, 0); | ||
| 287 | return isrv.status; | ||
| 288 | } | ||
| 289 | |||
| 217 | void __init | 290 | void __init |
| 218 | ia64_sal_init (struct ia64_sal_systab *systab) | 291 | ia64_sal_init (struct ia64_sal_systab *systab) |
| 219 | { | 292 | { |
| @@ -262,6 +335,8 @@ ia64_sal_init (struct ia64_sal_systab *systab) | |||
| 262 | } | 335 | } |
| 263 | p += SAL_DESC_SIZE(*p); | 336 | p += SAL_DESC_SIZE(*p); |
| 264 | } | 337 | } |
| 338 | |||
| 339 | check_sal_cache_flush(); | ||
| 265 | } | 340 | } |
| 266 | 341 | ||
| 267 | int | 342 | int |
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index c0766575a3a2..35f7835294a3 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c | |||
| @@ -71,6 +71,8 @@ unsigned long __per_cpu_offset[NR_CPUS]; | |||
| 71 | EXPORT_SYMBOL(__per_cpu_offset); | 71 | EXPORT_SYMBOL(__per_cpu_offset); |
| 72 | #endif | 72 | #endif |
| 73 | 73 | ||
| 74 | extern void ia64_setup_printk_clock(void); | ||
| 75 | |||
| 74 | DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info); | 76 | DEFINE_PER_CPU(struct cpuinfo_ia64, cpu_info); |
| 75 | DEFINE_PER_CPU(unsigned long, local_per_cpu_offset); | 77 | DEFINE_PER_CPU(unsigned long, local_per_cpu_offset); |
| 76 | DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8); | 78 | DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8); |
| @@ -445,6 +447,8 @@ setup_arch (char **cmdline_p) | |||
| 445 | /* process SAL system table: */ | 447 | /* process SAL system table: */ |
| 446 | ia64_sal_init(efi.sal_systab); | 448 | ia64_sal_init(efi.sal_systab); |
| 447 | 449 | ||
| 450 | ia64_setup_printk_clock(); | ||
| 451 | |||
| 448 | #ifdef CONFIG_SMP | 452 | #ifdef CONFIG_SMP |
| 449 | cpu_physical_id(0) = hard_smp_processor_id(); | 453 | cpu_physical_id(0) = hard_smp_processor_id(); |
| 450 | 454 | ||
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index 028a2b95936c..a094ec49ccfa 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c | |||
| @@ -278,3 +278,30 @@ udelay (unsigned long usecs) | |||
| 278 | } | 278 | } |
| 279 | } | 279 | } |
| 280 | EXPORT_SYMBOL(udelay); | 280 | EXPORT_SYMBOL(udelay); |
| 281 | |||
| 282 | static unsigned long long ia64_itc_printk_clock(void) | ||
| 283 | { | ||
| 284 | if (ia64_get_kr(IA64_KR_PER_CPU_DATA)) | ||
| 285 | return sched_clock(); | ||
| 286 | return 0; | ||
| 287 | } | ||
| 288 | |||
| 289 | static unsigned long long ia64_default_printk_clock(void) | ||
| 290 | { | ||
| 291 | return (unsigned long long)(jiffies_64 - INITIAL_JIFFIES) * | ||
| 292 | (1000000000/HZ); | ||
| 293 | } | ||
| 294 | |||
| 295 | unsigned long long (*ia64_printk_clock)(void) = &ia64_default_printk_clock; | ||
| 296 | |||
| 297 | unsigned long long printk_clock(void) | ||
| 298 | { | ||
| 299 | return ia64_printk_clock(); | ||
| 300 | } | ||
| 301 | |||
| 302 | void __init | ||
| 303 | ia64_setup_printk_clock(void) | ||
| 304 | { | ||
| 305 | if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)) | ||
| 306 | ia64_printk_clock = ia64_itc_printk_clock; | ||
| 307 | } | ||
diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c index 706b7734e191..6e5eea19fa67 100644 --- a/arch/ia64/kernel/topology.c +++ b/arch/ia64/kernel/topology.c | |||
| @@ -71,31 +71,33 @@ static int __init topology_init(void) | |||
| 71 | int i, err = 0; | 71 | int i, err = 0; |
| 72 | 72 | ||
| 73 | #ifdef CONFIG_NUMA | 73 | #ifdef CONFIG_NUMA |
| 74 | sysfs_nodes = kmalloc(sizeof(struct node) * MAX_NUMNODES, GFP_KERNEL); | 74 | sysfs_nodes = kzalloc(sizeof(struct node) * MAX_NUMNODES, GFP_KERNEL); |
| 75 | if (!sysfs_nodes) { | 75 | if (!sysfs_nodes) { |
| 76 | err = -ENOMEM; | 76 | err = -ENOMEM; |
| 77 | goto out; | 77 | goto out; |
| 78 | } | 78 | } |
| 79 | memset(sysfs_nodes, 0, sizeof(struct node) * MAX_NUMNODES); | ||
| 80 | 79 | ||
| 81 | /* MCD - Do we want to register all ONLINE nodes, or all POSSIBLE nodes? */ | 80 | /* |
| 82 | for_each_online_node(i) | 81 | * MCD - Do we want to register all ONLINE nodes, or all POSSIBLE nodes? |
| 82 | */ | ||
| 83 | for_each_online_node(i) { | ||
| 83 | if ((err = register_node(&sysfs_nodes[i], i, 0))) | 84 | if ((err = register_node(&sysfs_nodes[i], i, 0))) |
| 84 | goto out; | 85 | goto out; |
| 86 | } | ||
| 85 | #endif | 87 | #endif |
| 86 | 88 | ||
| 87 | sysfs_cpus = kmalloc(sizeof(struct ia64_cpu) * NR_CPUS, GFP_KERNEL); | 89 | sysfs_cpus = kzalloc(sizeof(struct ia64_cpu) * NR_CPUS, GFP_KERNEL); |
| 88 | if (!sysfs_cpus) { | 90 | if (!sysfs_cpus) { |
| 89 | err = -ENOMEM; | 91 | err = -ENOMEM; |
| 90 | goto out; | 92 | goto out; |
| 91 | } | 93 | } |
| 92 | memset(sysfs_cpus, 0, sizeof(struct ia64_cpu) * NR_CPUS); | ||
| 93 | 94 | ||
| 94 | for_each_present_cpu(i) | 95 | for_each_present_cpu(i) { |
| 95 | if((err = arch_register_cpu(i))) | 96 | if((err = arch_register_cpu(i))) |
| 96 | goto out; | 97 | goto out; |
| 98 | } | ||
| 97 | out: | 99 | out: |
| 98 | return err; | 100 | return err; |
| 99 | } | 101 | } |
| 100 | 102 | ||
| 101 | __initcall(topology_init); | 103 | subsys_initcall(topology_init); |
diff --git a/arch/ia64/sn/Makefile b/arch/ia64/sn/Makefile index a269f6d84c29..79a7df02e812 100644 --- a/arch/ia64/sn/Makefile +++ b/arch/ia64/sn/Makefile | |||
| @@ -9,6 +9,4 @@ | |||
| 9 | # Makefile for the sn ia64 subplatform | 9 | # Makefile for the sn ia64 subplatform |
| 10 | # | 10 | # |
| 11 | 11 | ||
| 12 | CPPFLAGS += -I$(srctree)/arch/ia64/sn/include | ||
| 13 | |||
| 14 | obj-y += kernel/ pci/ | 12 | obj-y += kernel/ pci/ |
diff --git a/arch/ia64/sn/kernel/Makefile b/arch/ia64/sn/kernel/Makefile index 4351c4ff9845..3e9b4eea7418 100644 --- a/arch/ia64/sn/kernel/Makefile +++ b/arch/ia64/sn/kernel/Makefile | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | # Copyright (C) 1999,2001-2005 Silicon Graphics, Inc. All Rights Reserved. | 7 | # Copyright (C) 1999,2001-2005 Silicon Graphics, Inc. All Rights Reserved. |
| 8 | # | 8 | # |
| 9 | 9 | ||
| 10 | CPPFLAGS += -I$(srctree)/arch/ia64/sn/include | ||
| 11 | |||
| 10 | obj-y += setup.o bte.o bte_error.o irq.o mca.o idle.o \ | 12 | obj-y += setup.o bte.o bte_error.o irq.o mca.o idle.o \ |
| 11 | huberror.o io_init.o iomv.o klconflib.o sn2/ | 13 | huberror.o io_init.o iomv.o klconflib.o sn2/ |
| 12 | obj-$(CONFIG_IA64_GENERIC) += machvec.o | 14 | obj-$(CONFIG_IA64_GENERIC) += machvec.o |
diff --git a/arch/ia64/sn/kernel/bte.c b/arch/ia64/sn/kernel/bte.c index dd73c0cb754b..1f11db470d90 100644 --- a/arch/ia64/sn/kernel/bte.c +++ b/arch/ia64/sn/kernel/bte.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
| 4 | * for more details. | 4 | * for more details. |
| 5 | * | 5 | * |
| 6 | * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. | 6 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/config.h> | 9 | #include <linux/config.h> |
| @@ -186,18 +186,13 @@ retry_bteop: | |||
| 186 | 186 | ||
| 187 | /* Initialize the notification to a known value. */ | 187 | /* Initialize the notification to a known value. */ |
| 188 | *bte->most_rcnt_na = BTE_WORD_BUSY; | 188 | *bte->most_rcnt_na = BTE_WORD_BUSY; |
| 189 | notif_phys_addr = TO_PHYS(ia64_tpa((unsigned long)bte->most_rcnt_na)); | 189 | notif_phys_addr = (u64)bte->most_rcnt_na; |
| 190 | 190 | ||
| 191 | if (is_shub2()) { | ||
| 192 | src = SH2_TIO_PHYS_TO_DMA(src); | ||
| 193 | dest = SH2_TIO_PHYS_TO_DMA(dest); | ||
| 194 | notif_phys_addr = SH2_TIO_PHYS_TO_DMA(notif_phys_addr); | ||
| 195 | } | ||
| 196 | /* Set the source and destination registers */ | 191 | /* Set the source and destination registers */ |
| 197 | BTE_PRINTKV(("IBSA = 0x%lx)\n", (TO_PHYS(src)))); | 192 | BTE_PRINTKV(("IBSA = 0x%lx)\n", src)); |
| 198 | BTE_SRC_STORE(bte, TO_PHYS(src)); | 193 | BTE_SRC_STORE(bte, src); |
| 199 | BTE_PRINTKV(("IBDA = 0x%lx)\n", (TO_PHYS(dest)))); | 194 | BTE_PRINTKV(("IBDA = 0x%lx)\n", dest)); |
| 200 | BTE_DEST_STORE(bte, TO_PHYS(dest)); | 195 | BTE_DEST_STORE(bte, dest); |
| 201 | 196 | ||
| 202 | /* Set the notification register */ | 197 | /* Set the notification register */ |
| 203 | BTE_PRINTKV(("IBNA = 0x%lx)\n", notif_phys_addr)); | 198 | BTE_PRINTKV(("IBNA = 0x%lx)\n", notif_phys_addr)); |
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index a4c78152b336..d7e4d79e16a8 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c | |||
| @@ -208,7 +208,7 @@ static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device, | |||
| 208 | * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for | 208 | * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for |
| 209 | * each node in the system. | 209 | * each node in the system. |
| 210 | */ | 210 | */ |
| 211 | static void sn_fixup_ionodes(void) | 211 | static void __init sn_fixup_ionodes(void) |
| 212 | { | 212 | { |
| 213 | struct sn_flush_device_kernel *sn_flush_device_kernel; | 213 | struct sn_flush_device_kernel *sn_flush_device_kernel; |
| 214 | struct sn_flush_device_kernel *dev_entry; | 214 | struct sn_flush_device_kernel *dev_entry; |
| @@ -467,6 +467,13 @@ void sn_pci_fixup_slot(struct pci_dev *dev) | |||
| 467 | pcidev_info->pdi_sn_irq_info = NULL; | 467 | pcidev_info->pdi_sn_irq_info = NULL; |
| 468 | kfree(sn_irq_info); | 468 | kfree(sn_irq_info); |
| 469 | } | 469 | } |
| 470 | |||
| 471 | /* | ||
| 472 | * MSI currently not supported on altix. Remove this when | ||
| 473 | * the MSI abstraction patches are integrated into the kernel | ||
| 474 | * (sometime after 2.6.16 releases) | ||
| 475 | */ | ||
| 476 | dev->no_msi = 1; | ||
| 470 | } | 477 | } |
| 471 | 478 | ||
| 472 | /* | 479 | /* |
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c index ec37084bdc17..74d87d903d5d 100644 --- a/arch/ia64/sn/kernel/irq.c +++ b/arch/ia64/sn/kernel/irq.c | |||
| @@ -5,11 +5,12 @@ | |||
| 5 | * License. See the file "COPYING" in the main directory of this archive | 5 | * License. See the file "COPYING" in the main directory of this archive |
| 6 | * for more details. | 6 | * for more details. |
| 7 | * | 7 | * |
| 8 | * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. | 8 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. |
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <linux/irq.h> | 11 | #include <linux/irq.h> |
| 12 | #include <linux/spinlock.h> | 12 | #include <linux/spinlock.h> |
| 13 | #include <linux/init.h> | ||
| 13 | #include <asm/sn/addrs.h> | 14 | #include <asm/sn/addrs.h> |
| 14 | #include <asm/sn/arch.h> | 15 | #include <asm/sn/arch.h> |
| 15 | #include <asm/sn/intr.h> | 16 | #include <asm/sn/intr.h> |
| @@ -76,17 +77,15 @@ static void sn_enable_irq(unsigned int irq) | |||
| 76 | 77 | ||
| 77 | static void sn_ack_irq(unsigned int irq) | 78 | static void sn_ack_irq(unsigned int irq) |
| 78 | { | 79 | { |
| 79 | u64 event_occurred, mask = 0; | 80 | u64 event_occurred, mask; |
| 80 | 81 | ||
| 81 | irq = irq & 0xff; | 82 | irq = irq & 0xff; |
| 82 | event_occurred = | 83 | event_occurred = HUB_L((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED)); |
| 83 | HUB_L((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED)); | ||
| 84 | mask = event_occurred & SH_ALL_INT_MASK; | 84 | mask = event_occurred & SH_ALL_INT_MASK; |
| 85 | HUB_S((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS), | 85 | HUB_S((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS), mask); |
| 86 | mask); | ||
| 87 | __set_bit(irq, (volatile void *)pda->sn_in_service_ivecs); | 86 | __set_bit(irq, (volatile void *)pda->sn_in_service_ivecs); |
| 88 | 87 | ||
| 89 | move_irq(irq); | 88 | move_native_irq(irq); |
| 90 | } | 89 | } |
| 91 | 90 | ||
| 92 | static void sn_end_irq(unsigned int irq) | 91 | static void sn_end_irq(unsigned int irq) |
| @@ -219,9 +218,8 @@ static void register_intr_pda(struct sn_irq_info *sn_irq_info) | |||
| 219 | pdacpu(cpu)->sn_last_irq = irq; | 218 | pdacpu(cpu)->sn_last_irq = irq; |
| 220 | } | 219 | } |
| 221 | 220 | ||
| 222 | if (pdacpu(cpu)->sn_first_irq == 0 || pdacpu(cpu)->sn_first_irq > irq) { | 221 | if (pdacpu(cpu)->sn_first_irq == 0 || pdacpu(cpu)->sn_first_irq > irq) |
| 223 | pdacpu(cpu)->sn_first_irq = irq; | 222 | pdacpu(cpu)->sn_first_irq = irq; |
| 224 | } | ||
| 225 | } | 223 | } |
| 226 | 224 | ||
| 227 | static void unregister_intr_pda(struct sn_irq_info *sn_irq_info) | 225 | static void unregister_intr_pda(struct sn_irq_info *sn_irq_info) |
| @@ -289,7 +287,7 @@ void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info) | |||
| 289 | list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]); | 287 | list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]); |
| 290 | spin_unlock(&sn_irq_info_lock); | 288 | spin_unlock(&sn_irq_info_lock); |
| 291 | 289 | ||
| 292 | (void)register_intr_pda(sn_irq_info); | 290 | register_intr_pda(sn_irq_info); |
| 293 | } | 291 | } |
| 294 | 292 | ||
| 295 | void sn_irq_unfixup(struct pci_dev *pci_dev) | 293 | void sn_irq_unfixup(struct pci_dev *pci_dev) |
| @@ -419,7 +417,7 @@ void sn_lb_int_war_check(void) | |||
| 419 | rcu_read_unlock(); | 417 | rcu_read_unlock(); |
| 420 | } | 418 | } |
| 421 | 419 | ||
| 422 | void sn_irq_lh_init(void) | 420 | void __init sn_irq_lh_init(void) |
| 423 | { | 421 | { |
| 424 | int i; | 422 | int i; |
| 425 | 423 | ||
| @@ -434,5 +432,4 @@ void sn_irq_lh_init(void) | |||
| 434 | 432 | ||
| 435 | INIT_LIST_HEAD(sn_irq_lh[i]); | 433 | INIT_LIST_HEAD(sn_irq_lh[i]); |
| 436 | } | 434 | } |
| 437 | |||
| 438 | } | 435 | } |
diff --git a/arch/ia64/sn/kernel/klconflib.c b/arch/ia64/sn/kernel/klconflib.c index 0f11a3299cd2..87682b48ef83 100644 --- a/arch/ia64/sn/kernel/klconflib.c +++ b/arch/ia64/sn/kernel/klconflib.c | |||
| @@ -78,31 +78,30 @@ format_module_id(char *buffer, moduleid_t m, int fmt) | |||
| 78 | position = MODULE_GET_BPOS(m); | 78 | position = MODULE_GET_BPOS(m); |
| 79 | 79 | ||
| 80 | if ((fmt == MODULE_FORMAT_BRIEF) || (fmt == MODULE_FORMAT_LCD)) { | 80 | if ((fmt == MODULE_FORMAT_BRIEF) || (fmt == MODULE_FORMAT_LCD)) { |
| 81 | /* Brief module number format, eg. 002c15 */ | 81 | /* Brief module number format, eg. 002c15 */ |
| 82 | 82 | ||
| 83 | /* Decompress the rack number */ | 83 | /* Decompress the rack number */ |
| 84 | *buffer++ = '0' + RACK_GET_CLASS(rack); | 84 | *buffer++ = '0' + RACK_GET_CLASS(rack); |
| 85 | *buffer++ = '0' + RACK_GET_GROUP(rack); | 85 | *buffer++ = '0' + RACK_GET_GROUP(rack); |
| 86 | *buffer++ = '0' + RACK_GET_NUM(rack); | 86 | *buffer++ = '0' + RACK_GET_NUM(rack); |
| 87 | 87 | ||
| 88 | /* Add the brick type */ | 88 | /* Add the brick type */ |
| 89 | *buffer++ = brickchar; | 89 | *buffer++ = brickchar; |
| 90 | } | 90 | } |
| 91 | else if (fmt == MODULE_FORMAT_LONG) { | 91 | else if (fmt == MODULE_FORMAT_LONG) { |
| 92 | /* Fuller hwgraph format, eg. rack/002/bay/15 */ | 92 | /* Fuller hwgraph format, eg. rack/002/bay/15 */ |
| 93 | 93 | ||
| 94 | strcpy(buffer, "rack" "/"); buffer += strlen(buffer); | 94 | strcpy(buffer, "rack" "/"); buffer += strlen(buffer); |
| 95 | 95 | ||
| 96 | *buffer++ = '0' + RACK_GET_CLASS(rack); | 96 | *buffer++ = '0' + RACK_GET_CLASS(rack); |
| 97 | *buffer++ = '0' + RACK_GET_GROUP(rack); | 97 | *buffer++ = '0' + RACK_GET_GROUP(rack); |
| 98 | *buffer++ = '0' + RACK_GET_NUM(rack); | 98 | *buffer++ = '0' + RACK_GET_NUM(rack); |
| 99 | 99 | ||
| 100 | strcpy(buffer, "/" "bay" "/"); buffer += strlen(buffer); | 100 | strcpy(buffer, "/" "bay" "/"); buffer += strlen(buffer); |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | /* Add the bay position, using at least two digits */ | 103 | /* Add the bay position, using at least two digits */ |
| 104 | if (position < 10) | 104 | if (position < 10) |
| 105 | *buffer++ = '0'; | 105 | *buffer++ = '0'; |
| 106 | sprintf(buffer, "%d", position); | 106 | sprintf(buffer, "%d", position); |
| 107 | |||
| 108 | } | 107 | } |
diff --git a/arch/ia64/sn/kernel/mca.c b/arch/ia64/sn/kernel/mca.c index 9ab684d1bb55..3db62f24596c 100644 --- a/arch/ia64/sn/kernel/mca.c +++ b/arch/ia64/sn/kernel/mca.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
| 4 | * for more details. | 4 | * for more details. |
| 5 | * | 5 | * |
| 6 | * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. | 6 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/types.h> | 9 | #include <linux/types.h> |
| @@ -137,7 +137,8 @@ int sn_salinfo_platform_oemdata(const u8 *sect_header, u8 **oemdata, u64 *oemdat | |||
| 137 | 137 | ||
| 138 | static int __init sn_salinfo_init(void) | 138 | static int __init sn_salinfo_init(void) |
| 139 | { | 139 | { |
| 140 | salinfo_platform_oemdata = &sn_salinfo_platform_oemdata; | 140 | if (ia64_platform_is("sn2")) |
| 141 | salinfo_platform_oemdata = &sn_salinfo_platform_oemdata; | ||
| 141 | return 0; | 142 | return 0; |
| 142 | } | 143 | } |
| 143 | 144 | ||
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index e510dce9971f..48645ac120fc 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c | |||
| @@ -67,6 +67,7 @@ extern unsigned long last_time_offset; | |||
| 67 | extern void (*ia64_mark_idle) (int); | 67 | extern void (*ia64_mark_idle) (int); |
| 68 | extern void snidle(int); | 68 | extern void snidle(int); |
| 69 | extern unsigned char acpi_kbd_controller_present; | 69 | extern unsigned char acpi_kbd_controller_present; |
| 70 | extern unsigned long long (*ia64_printk_clock)(void); | ||
| 70 | 71 | ||
| 71 | unsigned long sn_rtc_cycles_per_second; | 72 | unsigned long sn_rtc_cycles_per_second; |
| 72 | EXPORT_SYMBOL(sn_rtc_cycles_per_second); | 73 | EXPORT_SYMBOL(sn_rtc_cycles_per_second); |
| @@ -125,20 +126,6 @@ struct screen_info sn_screen_info = { | |||
| 125 | }; | 126 | }; |
| 126 | 127 | ||
| 127 | /* | 128 | /* |
| 128 | * This is here so we can use the CMOS detection in ide-probe.c to | ||
| 129 | * determine what drives are present. In theory, we don't need this | ||
| 130 | * as the auto-detection could be done via ide-probe.c:do_probe() but | ||
| 131 | * in practice that would be much slower, which is painful when | ||
| 132 | * running in the simulator. Note that passing zeroes in DRIVE_INFO | ||
| 133 | * is sufficient (the IDE driver will autodetect the drive geometry). | ||
| 134 | */ | ||
| 135 | #ifdef CONFIG_IA64_GENERIC | ||
| 136 | extern char drive_info[4 * 16]; | ||
| 137 | #else | ||
| 138 | char drive_info[4 * 16]; | ||
| 139 | #endif | ||
| 140 | |||
| 141 | /* | ||
| 142 | * This routine can only be used during init, since | 129 | * This routine can only be used during init, since |
| 143 | * smp_boot_data is an init data structure. | 130 | * smp_boot_data is an init data structure. |
| 144 | * We have to use smp_boot_data.cpu_phys_id to find | 131 | * We have to use smp_boot_data.cpu_phys_id to find |
| @@ -209,7 +196,7 @@ void __init early_sn_setup(void) | |||
| 209 | } | 196 | } |
| 210 | 197 | ||
| 211 | extern int platform_intr_list[]; | 198 | extern int platform_intr_list[]; |
| 212 | static int __initdata shub_1_1_found = 0; | 199 | static int __initdata shub_1_1_found; |
| 213 | 200 | ||
| 214 | /* | 201 | /* |
| 215 | * sn_check_for_wars | 202 | * sn_check_for_wars |
| @@ -372,6 +359,16 @@ sn_scan_pcdp(void) | |||
| 372 | } | 359 | } |
| 373 | } | 360 | } |
| 374 | 361 | ||
| 362 | static unsigned long sn2_rtc_initial; | ||
| 363 | |||
| 364 | static unsigned long long ia64_sn2_printk_clock(void) | ||
| 365 | { | ||
| 366 | unsigned long rtc_now = rtc_time(); | ||
| 367 | |||
| 368 | return (rtc_now - sn2_rtc_initial) * | ||
| 369 | (1000000000 / sn_rtc_cycles_per_second); | ||
| 370 | } | ||
| 371 | |||
| 375 | /** | 372 | /** |
| 376 | * sn_setup - SN platform setup routine | 373 | * sn_setup - SN platform setup routine |
| 377 | * @cmdline_p: kernel command line | 374 | * @cmdline_p: kernel command line |
| @@ -386,6 +383,7 @@ void __init sn_setup(char **cmdline_p) | |||
| 386 | u32 version = sn_sal_rev(); | 383 | u32 version = sn_sal_rev(); |
| 387 | extern void sn_cpu_init(void); | 384 | extern void sn_cpu_init(void); |
| 388 | 385 | ||
| 386 | sn2_rtc_initial = rtc_time(); | ||
| 389 | ia64_sn_plat_set_error_handling_features(); // obsolete | 387 | ia64_sn_plat_set_error_handling_features(); // obsolete |
| 390 | ia64_sn_set_os_feature(OSF_MCA_SLV_TO_OS_INIT_SLV); | 388 | ia64_sn_set_os_feature(OSF_MCA_SLV_TO_OS_INIT_SLV); |
| 391 | ia64_sn_set_os_feature(OSF_FEAT_LOG_SBES); | 389 | ia64_sn_set_os_feature(OSF_FEAT_LOG_SBES); |
| @@ -437,19 +435,6 @@ void __init sn_setup(char **cmdline_p) | |||
| 437 | */ | 435 | */ |
| 438 | build_cnode_tables(); | 436 | build_cnode_tables(); |
| 439 | 437 | ||
| 440 | /* | ||
| 441 | * Old PROMs do not provide an ACPI FADT. Disable legacy keyboard | ||
| 442 | * support here so we don't have to listen to failed keyboard probe | ||
| 443 | * messages. | ||
| 444 | */ | ||
| 445 | if (version <= 0x0209 && acpi_kbd_controller_present) { | ||
| 446 | printk(KERN_INFO "Disabling legacy keyboard support as prom " | ||
| 447 | "is too old and doesn't provide FADT\n"); | ||
| 448 | acpi_kbd_controller_present = 0; | ||
| 449 | } | ||
| 450 | |||
| 451 | printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF); | ||
| 452 | |||
| 453 | status = | 438 | status = |
| 454 | ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec, | 439 | ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec, |
| 455 | &drift); | 440 | &drift); |
| @@ -463,6 +448,21 @@ void __init sn_setup(char **cmdline_p) | |||
| 463 | 448 | ||
| 464 | platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_CPE_VECTOR; | 449 | platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_CPE_VECTOR; |
| 465 | 450 | ||
| 451 | ia64_printk_clock = ia64_sn2_printk_clock; | ||
| 452 | |||
| 453 | /* | ||
| 454 | * Old PROMs do not provide an ACPI FADT. Disable legacy keyboard | ||
| 455 | * support here so we don't have to listen to failed keyboard probe | ||
| 456 | * messages. | ||
| 457 | */ | ||
| 458 | if (version <= 0x0209 && acpi_kbd_controller_present) { | ||
| 459 | printk(KERN_INFO "Disabling legacy keyboard support as prom " | ||
| 460 | "is too old and doesn't provide FADT\n"); | ||
| 461 | acpi_kbd_controller_present = 0; | ||
| 462 | } | ||
| 463 | |||
| 464 | printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF); | ||
| 465 | |||
| 466 | /* | 466 | /* |
| 467 | * we set the default root device to /dev/hda | 467 | * we set the default root device to /dev/hda |
| 468 | * to make simulation easy | 468 | * to make simulation easy |
| @@ -578,13 +578,17 @@ void __init sn_cpu_init(void) | |||
| 578 | sn_prom_type = 2; | 578 | sn_prom_type = 2; |
| 579 | else | 579 | else |
| 580 | sn_prom_type = 1; | 580 | sn_prom_type = 1; |
| 581 | printk("Running on medusa with %s PROM\n", (sn_prom_type == 1) ? "real" : "fake"); | 581 | printk(KERN_INFO "Running on medusa with %s PROM\n", |
| 582 | (sn_prom_type == 1) ? "real" : "fake"); | ||
| 582 | } | 583 | } |
| 583 | 584 | ||
| 584 | memset(pda, 0, sizeof(pda)); | 585 | memset(pda, 0, sizeof(pda)); |
| 585 | if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2, &sn_hub_info->nasid_bitmask, &sn_hub_info->nasid_shift, | 586 | if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2, |
| 586 | &sn_system_size, &sn_sharing_domain_size, &sn_partition_id, | 587 | &sn_hub_info->nasid_bitmask, |
| 587 | &sn_coherency_id, &sn_region_size)) | 588 | &sn_hub_info->nasid_shift, |
| 589 | &sn_system_size, &sn_sharing_domain_size, | ||
| 590 | &sn_partition_id, &sn_coherency_id, | ||
| 591 | &sn_region_size)) | ||
| 588 | BUG(); | 592 | BUG(); |
| 589 | sn_hub_info->as_shift = sn_hub_info->nasid_shift - 2; | 593 | sn_hub_info->as_shift = sn_hub_info->nasid_shift - 2; |
| 590 | 594 | ||
| @@ -716,7 +720,8 @@ void __init build_cnode_tables(void) | |||
| 716 | for_each_online_node(node) { | 720 | for_each_online_node(node) { |
| 717 | kl_config_hdr_t *klgraph_header; | 721 | kl_config_hdr_t *klgraph_header; |
| 718 | nasid = cnodeid_to_nasid(node); | 722 | nasid = cnodeid_to_nasid(node); |
| 719 | if ((klgraph_header = ia64_sn_get_klconfig_addr(nasid)) == NULL) | 723 | klgraph_header = ia64_sn_get_klconfig_addr(nasid); |
| 724 | if (klgraph_header == NULL) | ||
| 720 | BUG(); | 725 | BUG(); |
| 721 | brd = NODE_OFFSET_TO_LBOARD(nasid, klgraph_header->ch_board_info); | 726 | brd = NODE_OFFSET_TO_LBOARD(nasid, klgraph_header->ch_board_info); |
| 722 | while (brd) { | 727 | while (brd) { |
| @@ -734,7 +739,7 @@ nasid_slice_to_cpuid(int nasid, int slice) | |||
| 734 | { | 739 | { |
| 735 | long cpu; | 740 | long cpu; |
| 736 | 741 | ||
| 737 | for (cpu=0; cpu < NR_CPUS; cpu++) | 742 | for (cpu = 0; cpu < NR_CPUS; cpu++) |
| 738 | if (cpuid_to_nasid(cpu) == nasid && | 743 | if (cpuid_to_nasid(cpu) == nasid && |
| 739 | cpuid_to_slice(cpu) == slice) | 744 | cpuid_to_slice(cpu) == slice) |
| 740 | return cpu; | 745 | return cpu; |
diff --git a/arch/ia64/sn/kernel/sn2/Makefile b/arch/ia64/sn/kernel/sn2/Makefile index 170bde4549da..99e177693234 100644 --- a/arch/ia64/sn/kernel/sn2/Makefile +++ b/arch/ia64/sn/kernel/sn2/Makefile | |||
| @@ -9,5 +9,7 @@ | |||
| 9 | # sn2 specific kernel files | 9 | # sn2 specific kernel files |
| 10 | # | 10 | # |
| 11 | 11 | ||
| 12 | CPPFLAGS += -I$(srctree)/arch/ia64/sn/include | ||
| 13 | |||
| 12 | obj-y += cache.o io.o ptc_deadlock.o sn2_smp.o sn_proc_fs.o \ | 14 | obj-y += cache.o io.o ptc_deadlock.o sn2_smp.o sn_proc_fs.o \ |
| 13 | prominfo_proc.o timer.o timer_interrupt.o sn_hwperf.o | 15 | prominfo_proc.o timer.o timer_interrupt.o sn_hwperf.o |
diff --git a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c index 471bbaa65d1b..f153a4c35c70 100644 --- a/arch/ia64/sn/kernel/sn2/sn2_smp.c +++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * License. See the file "COPYING" in the main directory of this archive | 5 | * License. See the file "COPYING" in the main directory of this archive |
| 6 | * for more details. | 6 | * for more details. |
| 7 | * | 7 | * |
| 8 | * Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved. | 8 | * Copyright (C) 2000-2006 Silicon Graphics, Inc. All rights reserved. |
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
| @@ -46,104 +46,28 @@ DECLARE_PER_CPU(struct ptc_stats, ptcstats); | |||
| 46 | 46 | ||
| 47 | static __cacheline_aligned DEFINE_SPINLOCK(sn2_global_ptc_lock); | 47 | static __cacheline_aligned DEFINE_SPINLOCK(sn2_global_ptc_lock); |
| 48 | 48 | ||
| 49 | void sn2_ptc_deadlock_recovery(short *, short, int, volatile unsigned long *, unsigned long data0, | 49 | void sn2_ptc_deadlock_recovery(short *, short, short, int, volatile unsigned long *, unsigned long, |
| 50 | volatile unsigned long *, unsigned long data1); | 50 | volatile unsigned long *, unsigned long); |
| 51 | 51 | ||
| 52 | #ifdef DEBUG_PTC | ||
| 53 | /* | 52 | /* |
| 54 | * ptctest: | 53 | * Note: some is the following is captured here to make degugging easier |
| 55 | * | 54 | * (the macros make more sense if you see the debug patch - not posted) |
| 56 | * xyz - 3 digit hex number: | ||
| 57 | * x - Force PTC purges to use shub: | ||
| 58 | * 0 - no force | ||
| 59 | * 1 - force | ||
| 60 | * y - interupt enable | ||
| 61 | * 0 - disable interrupts | ||
| 62 | * 1 - leave interuupts enabled | ||
| 63 | * z - type of lock: | ||
| 64 | * 0 - global lock | ||
| 65 | * 1 - node local lock | ||
| 66 | * 2 - no lock | ||
| 67 | * | ||
| 68 | * Note: on shub1, only ptctest == 0 is supported. Don't try other values! | ||
| 69 | */ | 55 | */ |
| 70 | |||
| 71 | static unsigned int sn2_ptctest = 0; | ||
| 72 | |||
| 73 | static int __init ptc_test(char *str) | ||
| 74 | { | ||
| 75 | get_option(&str, &sn2_ptctest); | ||
| 76 | return 1; | ||
| 77 | } | ||
| 78 | __setup("ptctest=", ptc_test); | ||
| 79 | |||
| 80 | static inline int ptc_lock(unsigned long *flagp) | ||
| 81 | { | ||
| 82 | unsigned long opt = sn2_ptctest & 255; | ||
| 83 | |||
| 84 | switch (opt) { | ||
| 85 | case 0x00: | ||
| 86 | spin_lock_irqsave(&sn2_global_ptc_lock, *flagp); | ||
| 87 | break; | ||
| 88 | case 0x01: | ||
| 89 | spin_lock_irqsave(&sn_nodepda->ptc_lock, *flagp); | ||
| 90 | break; | ||
| 91 | case 0x02: | ||
| 92 | local_irq_save(*flagp); | ||
| 93 | break; | ||
| 94 | case 0x10: | ||
| 95 | spin_lock(&sn2_global_ptc_lock); | ||
| 96 | break; | ||
| 97 | case 0x11: | ||
| 98 | spin_lock(&sn_nodepda->ptc_lock); | ||
| 99 | break; | ||
| 100 | case 0x12: | ||
| 101 | break; | ||
| 102 | default: | ||
| 103 | BUG(); | ||
| 104 | } | ||
| 105 | return opt; | ||
| 106 | } | ||
| 107 | |||
| 108 | static inline void ptc_unlock(unsigned long flags, int opt) | ||
| 109 | { | ||
| 110 | switch (opt) { | ||
| 111 | case 0x00: | ||
| 112 | spin_unlock_irqrestore(&sn2_global_ptc_lock, flags); | ||
| 113 | break; | ||
| 114 | case 0x01: | ||
| 115 | spin_unlock_irqrestore(&sn_nodepda->ptc_lock, flags); | ||
| 116 | break; | ||
| 117 | case 0x02: | ||
| 118 | local_irq_restore(flags); | ||
| 119 | break; | ||
| 120 | case 0x10: | ||
| 121 | spin_unlock(&sn2_global_ptc_lock); | ||
| 122 | break; | ||
| 123 | case 0x11: | ||
| 124 | spin_unlock(&sn_nodepda->ptc_lock); | ||
| 125 | break; | ||
| 126 | case 0x12: | ||
| 127 | break; | ||
| 128 | default: | ||
| 129 | BUG(); | ||
| 130 | } | ||
| 131 | } | ||
| 132 | #else | ||
| 133 | |||
| 134 | #define sn2_ptctest 0 | 56 | #define sn2_ptctest 0 |
| 57 | #define local_node_uses_ptc_ga(sh1) ((sh1) ? 1 : 0) | ||
| 58 | #define max_active_pio(sh1) ((sh1) ? 32 : 7) | ||
| 59 | #define reset_max_active_on_deadlock() 1 | ||
| 60 | #define PTC_LOCK(sh1) ((sh1) ? &sn2_global_ptc_lock : &sn_nodepda->ptc_lock) | ||
| 135 | 61 | ||
| 136 | static inline int ptc_lock(unsigned long *flagp) | 62 | static inline void ptc_lock(int sh1, unsigned long *flagp) |
| 137 | { | 63 | { |
| 138 | spin_lock_irqsave(&sn2_global_ptc_lock, *flagp); | 64 | spin_lock_irqsave(PTC_LOCK(sh1), *flagp); |
| 139 | return 0; | ||
| 140 | } | 65 | } |
| 141 | 66 | ||
| 142 | static inline void ptc_unlock(unsigned long flags, int opt) | 67 | static inline void ptc_unlock(int sh1, unsigned long flags) |
| 143 | { | 68 | { |
| 144 | spin_unlock_irqrestore(&sn2_global_ptc_lock, flags); | 69 | spin_unlock_irqrestore(PTC_LOCK(sh1), flags); |
| 145 | } | 70 | } |
| 146 | #endif | ||
| 147 | 71 | ||
| 148 | struct ptc_stats { | 72 | struct ptc_stats { |
| 149 | unsigned long ptc_l; | 73 | unsigned long ptc_l; |
| @@ -151,27 +75,30 @@ struct ptc_stats { | |||
| 151 | unsigned long shub_ptc_flushes; | 75 | unsigned long shub_ptc_flushes; |
| 152 | unsigned long nodes_flushed; | 76 | unsigned long nodes_flushed; |
| 153 | unsigned long deadlocks; | 77 | unsigned long deadlocks; |
| 78 | unsigned long deadlocks2; | ||
| 154 | unsigned long lock_itc_clocks; | 79 | unsigned long lock_itc_clocks; |
| 155 | unsigned long shub_itc_clocks; | 80 | unsigned long shub_itc_clocks; |
| 156 | unsigned long shub_itc_clocks_max; | 81 | unsigned long shub_itc_clocks_max; |
| 82 | unsigned long shub_ptc_flushes_not_my_mm; | ||
| 157 | }; | 83 | }; |
| 158 | 84 | ||
| 159 | static inline unsigned long wait_piowc(void) | 85 | static inline unsigned long wait_piowc(void) |
| 160 | { | 86 | { |
| 161 | volatile unsigned long *piows, zeroval; | 87 | volatile unsigned long *piows; |
| 162 | unsigned long ws; | 88 | unsigned long zeroval, ws; |
| 163 | 89 | ||
| 164 | piows = pda->pio_write_status_addr; | 90 | piows = pda->pio_write_status_addr; |
| 165 | zeroval = pda->pio_write_status_val; | 91 | zeroval = pda->pio_write_status_val; |
| 166 | do { | 92 | do { |
| 167 | cpu_relax(); | 93 | cpu_relax(); |
| 168 | } while (((ws = *piows) & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK) != zeroval); | 94 | } while (((ws = *piows) & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK) != zeroval); |
| 169 | return ws; | 95 | return (ws & SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK) != 0; |
| 170 | } | 96 | } |
| 171 | 97 | ||
| 172 | void sn_tlb_migrate_finish(struct mm_struct *mm) | 98 | void sn_tlb_migrate_finish(struct mm_struct *mm) |
| 173 | { | 99 | { |
| 174 | if (mm == current->mm) | 100 | /* flush_tlb_mm is inefficient if more than 1 users of mm */ |
| 101 | if (mm == current->mm && mm && atomic_read(&mm->mm_users) == 1) | ||
| 175 | flush_tlb_mm(mm); | 102 | flush_tlb_mm(mm); |
| 176 | } | 103 | } |
| 177 | 104 | ||
| @@ -201,12 +128,14 @@ void | |||
| 201 | sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, | 128 | sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, |
| 202 | unsigned long end, unsigned long nbits) | 129 | unsigned long end, unsigned long nbits) |
| 203 | { | 130 | { |
| 204 | int i, opt, shub1, cnode, mynasid, cpu, lcpu = 0, nasid, flushed = 0; | 131 | int i, ibegin, shub1, cnode, mynasid, cpu, lcpu = 0, nasid; |
| 205 | int mymm = (mm == current->active_mm && current->mm); | 132 | int mymm = (mm == current->active_mm && mm == current->mm); |
| 133 | int use_cpu_ptcga; | ||
| 206 | volatile unsigned long *ptc0, *ptc1; | 134 | volatile unsigned long *ptc0, *ptc1; |
| 207 | unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value; | 135 | unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value, old_rr = 0; |
| 208 | short nasids[MAX_NUMNODES], nix; | 136 | short nasids[MAX_NUMNODES], nix; |
| 209 | nodemask_t nodes_flushed; | 137 | nodemask_t nodes_flushed; |
| 138 | int active, max_active, deadlock; | ||
| 210 | 139 | ||
| 211 | nodes_clear(nodes_flushed); | 140 | nodes_clear(nodes_flushed); |
| 212 | i = 0; | 141 | i = 0; |
| @@ -267,41 +196,56 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, | |||
| 267 | 196 | ||
| 268 | 197 | ||
| 269 | mynasid = get_nasid(); | 198 | mynasid = get_nasid(); |
| 199 | use_cpu_ptcga = local_node_uses_ptc_ga(shub1); | ||
| 200 | max_active = max_active_pio(shub1); | ||
| 270 | 201 | ||
| 271 | itc = ia64_get_itc(); | 202 | itc = ia64_get_itc(); |
| 272 | opt = ptc_lock(&flags); | 203 | ptc_lock(shub1, &flags); |
| 273 | itc2 = ia64_get_itc(); | 204 | itc2 = ia64_get_itc(); |
| 205 | |||
| 274 | __get_cpu_var(ptcstats).lock_itc_clocks += itc2 - itc; | 206 | __get_cpu_var(ptcstats).lock_itc_clocks += itc2 - itc; |
| 275 | __get_cpu_var(ptcstats).shub_ptc_flushes++; | 207 | __get_cpu_var(ptcstats).shub_ptc_flushes++; |
| 276 | __get_cpu_var(ptcstats).nodes_flushed += nix; | 208 | __get_cpu_var(ptcstats).nodes_flushed += nix; |
| 209 | if (!mymm) | ||
| 210 | __get_cpu_var(ptcstats).shub_ptc_flushes_not_my_mm++; | ||
| 277 | 211 | ||
| 212 | if (use_cpu_ptcga && !mymm) { | ||
| 213 | old_rr = ia64_get_rr(start); | ||
| 214 | ia64_set_rr(start, (old_rr & 0xff) | (rr_value << 8)); | ||
| 215 | ia64_srlz_d(); | ||
| 216 | } | ||
| 217 | |||
| 218 | wait_piowc(); | ||
| 278 | do { | 219 | do { |
| 279 | if (shub1) | 220 | if (shub1) |
| 280 | data1 = start | (1UL << SH1_PTC_1_START_SHFT); | 221 | data1 = start | (1UL << SH1_PTC_1_START_SHFT); |
| 281 | else | 222 | else |
| 282 | data0 = (data0 & ~SH2_PTC_ADDR_MASK) | (start & SH2_PTC_ADDR_MASK); | 223 | data0 = (data0 & ~SH2_PTC_ADDR_MASK) | (start & SH2_PTC_ADDR_MASK); |
| 283 | for (i = 0; i < nix; i++) { | 224 | deadlock = 0; |
| 225 | active = 0; | ||
| 226 | for (ibegin = 0, i = 0; i < nix; i++) { | ||
| 284 | nasid = nasids[i]; | 227 | nasid = nasids[i]; |
| 285 | if ((!(sn2_ptctest & 3)) && unlikely(nasid == mynasid && mymm)) { | 228 | if (use_cpu_ptcga && unlikely(nasid == mynasid)) { |
| 286 | ia64_ptcga(start, nbits << 2); | 229 | ia64_ptcga(start, nbits << 2); |
| 287 | ia64_srlz_i(); | 230 | ia64_srlz_i(); |
| 288 | } else { | 231 | } else { |
| 289 | ptc0 = CHANGE_NASID(nasid, ptc0); | 232 | ptc0 = CHANGE_NASID(nasid, ptc0); |
| 290 | if (ptc1) | 233 | if (ptc1) |
| 291 | ptc1 = CHANGE_NASID(nasid, ptc1); | 234 | ptc1 = CHANGE_NASID(nasid, ptc1); |
| 292 | pio_atomic_phys_write_mmrs(ptc0, data0, ptc1, | 235 | pio_atomic_phys_write_mmrs(ptc0, data0, ptc1, data1); |
| 293 | data1); | 236 | active++; |
| 294 | flushed = 1; | 237 | } |
| 238 | if (active >= max_active || i == (nix - 1)) { | ||
| 239 | if ((deadlock = wait_piowc())) { | ||
| 240 | sn2_ptc_deadlock_recovery(nasids, ibegin, i, mynasid, ptc0, data0, ptc1, data1); | ||
| 241 | if (reset_max_active_on_deadlock()) | ||
| 242 | max_active = 1; | ||
| 243 | } | ||
| 244 | active = 0; | ||
| 245 | ibegin = i + 1; | ||
| 295 | } | 246 | } |
| 296 | } | 247 | } |
| 297 | if (flushed | ||
| 298 | && (wait_piowc() & | ||
| 299 | (SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK))) { | ||
| 300 | sn2_ptc_deadlock_recovery(nasids, nix, mynasid, ptc0, data0, ptc1, data1); | ||
| 301 | } | ||
| 302 | |||
| 303 | start += (1UL << nbits); | 248 | start += (1UL << nbits); |
| 304 | |||
| 305 | } while (start < end); | 249 | } while (start < end); |
| 306 | 250 | ||
| 307 | itc2 = ia64_get_itc() - itc2; | 251 | itc2 = ia64_get_itc() - itc2; |
| @@ -309,7 +253,12 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, | |||
| 309 | if (itc2 > __get_cpu_var(ptcstats).shub_itc_clocks_max) | 253 | if (itc2 > __get_cpu_var(ptcstats).shub_itc_clocks_max) |
| 310 | __get_cpu_var(ptcstats).shub_itc_clocks_max = itc2; | 254 | __get_cpu_var(ptcstats).shub_itc_clocks_max = itc2; |
| 311 | 255 | ||
| 312 | ptc_unlock(flags, opt); | 256 | if (old_rr) { |
| 257 | ia64_set_rr(start, old_rr); | ||
| 258 | ia64_srlz_d(); | ||
| 259 | } | ||
| 260 | |||
| 261 | ptc_unlock(shub1, flags); | ||
| 313 | 262 | ||
| 314 | preempt_enable(); | 263 | preempt_enable(); |
| 315 | } | 264 | } |
| @@ -321,27 +270,30 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, | |||
| 321 | * TLB flush transaction. The recovery sequence is somewhat tricky & is | 270 | * TLB flush transaction. The recovery sequence is somewhat tricky & is |
| 322 | * coded in assembly language. | 271 | * coded in assembly language. |
| 323 | */ | 272 | */ |
| 324 | void sn2_ptc_deadlock_recovery(short *nasids, short nix, int mynasid, volatile unsigned long *ptc0, unsigned long data0, | 273 | void sn2_ptc_deadlock_recovery(short *nasids, short ib, short ie, int mynasid, volatile unsigned long *ptc0, unsigned long data0, |
| 325 | volatile unsigned long *ptc1, unsigned long data1) | 274 | volatile unsigned long *ptc1, unsigned long data1) |
| 326 | { | 275 | { |
| 327 | extern void sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long, | 276 | extern unsigned long sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long, |
| 328 | volatile unsigned long *, unsigned long, volatile unsigned long *, unsigned long); | 277 | volatile unsigned long *, unsigned long, volatile unsigned long *, unsigned long); |
| 329 | short nasid, i; | 278 | short nasid, i; |
| 330 | unsigned long *piows, zeroval; | 279 | unsigned long *piows, zeroval, n; |
| 331 | 280 | ||
| 332 | __get_cpu_var(ptcstats).deadlocks++; | 281 | __get_cpu_var(ptcstats).deadlocks++; |
| 333 | 282 | ||
| 334 | piows = (unsigned long *) pda->pio_write_status_addr; | 283 | piows = (unsigned long *) pda->pio_write_status_addr; |
| 335 | zeroval = pda->pio_write_status_val; | 284 | zeroval = pda->pio_write_status_val; |
| 336 | 285 | ||
| 337 | for (i=0; i < nix; i++) { | 286 | |
| 287 | for (i=ib; i <= ie; i++) { | ||
| 338 | nasid = nasids[i]; | 288 | nasid = nasids[i]; |
| 339 | if (!(sn2_ptctest & 3) && nasid == mynasid) | 289 | if (local_node_uses_ptc_ga(is_shub1()) && nasid == mynasid) |
| 340 | continue; | 290 | continue; |
| 341 | ptc0 = CHANGE_NASID(nasid, ptc0); | 291 | ptc0 = CHANGE_NASID(nasid, ptc0); |
| 342 | if (ptc1) | 292 | if (ptc1) |
| 343 | ptc1 = CHANGE_NASID(nasid, ptc1); | 293 | ptc1 = CHANGE_NASID(nasid, ptc1); |
| 344 | sn2_ptc_deadlock_recovery_core(ptc0, data0, ptc1, data1, piows, zeroval); | 294 | |
| 295 | n = sn2_ptc_deadlock_recovery_core(ptc0, data0, ptc1, data1, piows, zeroval); | ||
| 296 | __get_cpu_var(ptcstats).deadlocks2 += n; | ||
| 345 | } | 297 | } |
| 346 | 298 | ||
| 347 | } | 299 | } |
| @@ -452,20 +404,22 @@ static int sn2_ptc_seq_show(struct seq_file *file, void *data) | |||
| 452 | cpu = *(loff_t *) data; | 404 | cpu = *(loff_t *) data; |
| 453 | 405 | ||
| 454 | if (!cpu) { | 406 | if (!cpu) { |
| 455 | seq_printf(file, "# ptc_l change_rid shub_ptc_flushes shub_nodes_flushed deadlocks lock_nsec shub_nsec shub_nsec_max\n"); | 407 | seq_printf(file, |
| 408 | "# cpu ptc_l newrid ptc_flushes nodes_flushed deadlocks lock_nsec shub_nsec shub_nsec_max not_my_mm deadlock2\n"); | ||
| 456 | seq_printf(file, "# ptctest %d\n", sn2_ptctest); | 409 | seq_printf(file, "# ptctest %d\n", sn2_ptctest); |
| 457 | } | 410 | } |
| 458 | 411 | ||
| 459 | if (cpu < NR_CPUS && cpu_online(cpu)) { | 412 | if (cpu < NR_CPUS && cpu_online(cpu)) { |
| 460 | stat = &per_cpu(ptcstats, cpu); | 413 | stat = &per_cpu(ptcstats, cpu); |
| 461 | seq_printf(file, "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld\n", cpu, stat->ptc_l, | 414 | seq_printf(file, "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\n", cpu, stat->ptc_l, |
| 462 | stat->change_rid, stat->shub_ptc_flushes, stat->nodes_flushed, | 415 | stat->change_rid, stat->shub_ptc_flushes, stat->nodes_flushed, |
| 463 | stat->deadlocks, | 416 | stat->deadlocks, |
| 464 | 1000 * stat->lock_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec, | 417 | 1000 * stat->lock_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec, |
| 465 | 1000 * stat->shub_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec, | 418 | 1000 * stat->shub_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec, |
| 466 | 1000 * stat->shub_itc_clocks_max / per_cpu(cpu_info, cpu).cyc_per_usec); | 419 | 1000 * stat->shub_itc_clocks_max / per_cpu(cpu_info, cpu).cyc_per_usec, |
| 420 | stat->shub_ptc_flushes_not_my_mm, | ||
| 421 | stat->deadlocks2); | ||
| 467 | } | 422 | } |
| 468 | |||
| 469 | return 0; | 423 | return 0; |
| 470 | } | 424 | } |
| 471 | 425 | ||
| @@ -476,7 +430,7 @@ static struct seq_operations sn2_ptc_seq_ops = { | |||
| 476 | .show = sn2_ptc_seq_show | 430 | .show = sn2_ptc_seq_show |
| 477 | }; | 431 | }; |
| 478 | 432 | ||
| 479 | int sn2_ptc_proc_open(struct inode *inode, struct file *file) | 433 | static int sn2_ptc_proc_open(struct inode *inode, struct file *file) |
| 480 | { | 434 | { |
| 481 | return seq_open(file, &sn2_ptc_seq_ops); | 435 | return seq_open(file, &sn2_ptc_seq_ops); |
| 482 | } | 436 | } |
diff --git a/arch/ia64/sn/kernel/sn2/sn_hwperf.c b/arch/ia64/sn/kernel/sn2/sn_hwperf.c index 19b54fbcd7ea..70db21f3df21 100644 --- a/arch/ia64/sn/kernel/sn2/sn_hwperf.c +++ b/arch/ia64/sn/kernel/sn2/sn_hwperf.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
| 4 | * for more details. | 4 | * for more details. |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2004-2005 Silicon Graphics, Inc. All rights reserved. | 6 | * Copyright (C) 2004-2006 Silicon Graphics, Inc. All rights reserved. |
| 7 | * | 7 | * |
| 8 | * SGI Altix topology and hardware performance monitoring API. | 8 | * SGI Altix topology and hardware performance monitoring API. |
| 9 | * Mark Goodwin <markgw@sgi.com>. | 9 | * Mark Goodwin <markgw@sgi.com>. |
| @@ -973,6 +973,9 @@ static int __devinit sn_hwperf_misc_register_init(void) | |||
| 973 | { | 973 | { |
| 974 | int e; | 974 | int e; |
| 975 | 975 | ||
| 976 | if (!ia64_platform_is("sn2")) | ||
| 977 | return 0; | ||
| 978 | |||
| 976 | sn_hwperf_init(); | 979 | sn_hwperf_init(); |
| 977 | 980 | ||
| 978 | /* | 981 | /* |
diff --git a/arch/ia64/sn/kernel/xpc_main.c b/arch/ia64/sn/kernel/xpc_main.c index c75f8aeefc2b..9cd460dfe27e 100644 --- a/arch/ia64/sn/kernel/xpc_main.c +++ b/arch/ia64/sn/kernel/xpc_main.c | |||
| @@ -575,18 +575,21 @@ xpc_activate_partition(struct xpc_partition *part) | |||
| 575 | 575 | ||
| 576 | spin_lock_irqsave(&part->act_lock, irq_flags); | 576 | spin_lock_irqsave(&part->act_lock, irq_flags); |
| 577 | 577 | ||
| 578 | pid = kernel_thread(xpc_activating, (void *) ((u64) partid), 0); | ||
| 579 | |||
| 580 | DBUG_ON(part->act_state != XPC_P_INACTIVE); | 578 | DBUG_ON(part->act_state != XPC_P_INACTIVE); |
| 581 | 579 | ||
| 582 | if (pid > 0) { | 580 | part->act_state = XPC_P_ACTIVATION_REQ; |
| 583 | part->act_state = XPC_P_ACTIVATION_REQ; | 581 | XPC_SET_REASON(part, xpcCloneKThread, __LINE__); |
| 584 | XPC_SET_REASON(part, xpcCloneKThread, __LINE__); | ||
| 585 | } else { | ||
| 586 | XPC_SET_REASON(part, xpcCloneKThreadFailed, __LINE__); | ||
| 587 | } | ||
| 588 | 582 | ||
| 589 | spin_unlock_irqrestore(&part->act_lock, irq_flags); | 583 | spin_unlock_irqrestore(&part->act_lock, irq_flags); |
| 584 | |||
| 585 | pid = kernel_thread(xpc_activating, (void *) ((u64) partid), 0); | ||
| 586 | |||
| 587 | if (unlikely(pid <= 0)) { | ||
| 588 | spin_lock_irqsave(&part->act_lock, irq_flags); | ||
| 589 | part->act_state = XPC_P_INACTIVE; | ||
| 590 | XPC_SET_REASON(part, xpcCloneKThreadFailed, __LINE__); | ||
| 591 | spin_unlock_irqrestore(&part->act_lock, irq_flags); | ||
| 592 | } | ||
| 590 | } | 593 | } |
| 591 | 594 | ||
| 592 | 595 | ||
diff --git a/arch/ia64/sn/pci/Makefile b/arch/ia64/sn/pci/Makefile index 321576b1b425..c6946784a6a8 100644 --- a/arch/ia64/sn/pci/Makefile +++ b/arch/ia64/sn/pci/Makefile | |||
| @@ -7,4 +7,6 @@ | |||
| 7 | # | 7 | # |
| 8 | # Makefile for the sn pci general routines. | 8 | # Makefile for the sn pci general routines. |
| 9 | 9 | ||
| 10 | CPPFLAGS += -I$(srctree)/arch/ia64/sn/include | ||
| 11 | |||
| 10 | obj-y := pci_dma.o tioca_provider.o tioce_provider.o pcibr/ | 12 | obj-y := pci_dma.o tioca_provider.o tioce_provider.o pcibr/ |
diff --git a/arch/ia64/sn/pci/pcibr/Makefile b/arch/ia64/sn/pci/pcibr/Makefile index 1850c4a94c41..3b403ea456f9 100644 --- a/arch/ia64/sn/pci/pcibr/Makefile +++ b/arch/ia64/sn/pci/pcibr/Makefile | |||
| @@ -7,5 +7,7 @@ | |||
| 7 | # | 7 | # |
| 8 | # Makefile for the sn2 io routines. | 8 | # Makefile for the sn2 io routines. |
| 9 | 9 | ||
| 10 | CPPFLAGS += -I$(srctree)/arch/ia64/sn/include | ||
| 11 | |||
| 10 | obj-y += pcibr_dma.o pcibr_reg.o \ | 12 | obj-y += pcibr_dma.o pcibr_reg.o \ |
| 11 | pcibr_ate.o pcibr_provider.o | 13 | pcibr_ate.o pcibr_provider.o |
diff --git a/arch/m32r/kernel/m32r_ksyms.c b/arch/m32r/kernel/m32r_ksyms.c index dbc8a392105f..be8b711367ec 100644 --- a/arch/m32r/kernel/m32r_ksyms.c +++ b/arch/m32r/kernel/m32r_ksyms.c | |||
| @@ -18,11 +18,6 @@ | |||
| 18 | #include <asm/irq.h> | 18 | #include <asm/irq.h> |
| 19 | #include <asm/tlbflush.h> | 19 | #include <asm/tlbflush.h> |
| 20 | 20 | ||
| 21 | #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE) | ||
| 22 | extern struct drive_info_struct drive_info; | ||
| 23 | EXPORT_SYMBOL(drive_info); | ||
| 24 | #endif | ||
| 25 | |||
| 26 | /* platform dependent support */ | 21 | /* platform dependent support */ |
| 27 | EXPORT_SYMBOL(boot_cpu_data); | 22 | EXPORT_SYMBOL(boot_cpu_data); |
| 28 | EXPORT_SYMBOL(dump_fpu); | 23 | EXPORT_SYMBOL(dump_fpu); |
diff --git a/arch/m32r/kernel/setup.c b/arch/m32r/kernel/setup.c index c2e4dccf0112..d742037a7ccb 100644 --- a/arch/m32r/kernel/setup.c +++ b/arch/m32r/kernel/setup.c | |||
| @@ -37,12 +37,6 @@ | |||
| 37 | extern void init_mmu(void); | 37 | extern void init_mmu(void); |
| 38 | #endif | 38 | #endif |
| 39 | 39 | ||
| 40 | #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) \ | ||
| 41 | || defined(CONFIG_BLK_DEV_IDE_MODULE) \ | ||
| 42 | || defined(CONFIG_BLK_DEV_HD_MODULE) | ||
| 43 | struct drive_info_struct { char dummy[32]; } drive_info; | ||
| 44 | #endif | ||
| 45 | |||
| 46 | extern char _end[]; | 40 | extern char _end[]; |
| 47 | 41 | ||
| 48 | /* | 42 | /* |
diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c index 99bf43824795..63c117dae0c3 100644 --- a/arch/m68knommu/kernel/process.c +++ b/arch/m68knommu/kernel/process.c | |||
| @@ -39,6 +39,14 @@ | |||
| 39 | 39 | ||
| 40 | asmlinkage void ret_from_fork(void); | 40 | asmlinkage void ret_from_fork(void); |
| 41 | 41 | ||
| 42 | /* | ||
| 43 | * The following aren't currently used. | ||
| 44 | */ | ||
| 45 | void (*pm_idle)(void); | ||
| 46 | EXPORT_SYMBOL(pm_idle); | ||
| 47 | |||
| 48 | void (*pm_power_off)(void); | ||
| 49 | EXPORT_SYMBOL(pm_power_off); | ||
| 42 | 50 | ||
| 43 | /* | 51 | /* |
| 44 | * The idle loop on an m68knommu.. | 52 | * The idle loop on an m68knommu.. |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index c3e852e9953e..767de847b4ab 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
| @@ -595,6 +595,7 @@ config SGI_IP32 | |||
| 595 | select SYS_HAS_CPU_R5000 | 595 | select SYS_HAS_CPU_R5000 |
| 596 | select SYS_HAS_CPU_R10000 if BROKEN | 596 | select SYS_HAS_CPU_R10000 if BROKEN |
| 597 | select SYS_HAS_CPU_RM7000 | 597 | select SYS_HAS_CPU_RM7000 |
| 598 | select SYS_HAS_CPU_NEVADA | ||
| 598 | select SYS_SUPPORTS_64BIT_KERNEL | 599 | select SYS_SUPPORTS_64BIT_KERNEL |
| 599 | select SYS_SUPPORTS_BIG_ENDIAN | 600 | select SYS_SUPPORTS_BIG_ENDIAN |
| 600 | help | 601 | help |
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 2a9f2ef27b29..6a57407df1bc 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile | |||
| @@ -53,14 +53,17 @@ CROSS_COMPILE := $(tool-prefix) | |||
| 53 | endif | 53 | endif |
| 54 | 54 | ||
| 55 | CHECKFLAGS-y += -D__linux__ -D__mips__ \ | 55 | CHECKFLAGS-y += -D__linux__ -D__mips__ \ |
| 56 | -D_MIPS_SZINT=32 \ | ||
| 56 | -D_ABIO32=1 \ | 57 | -D_ABIO32=1 \ |
| 57 | -D_ABIN32=2 \ | 58 | -D_ABIN32=2 \ |
| 58 | -D_ABI64=3 | 59 | -D_ABI64=3 |
| 59 | CHECKFLAGS-$(CONFIG_32BIT) += -D_MIPS_SIM=_ABIO32 \ | 60 | CHECKFLAGS-$(CONFIG_32BIT) += -D_MIPS_SIM=_ABIO32 \ |
| 60 | -D_MIPS_SZLONG=32 \ | 61 | -D_MIPS_SZLONG=32 \ |
| 62 | -D_MIPS_SZPTR=32 \ | ||
| 61 | -D__PTRDIFF_TYPE__=int | 63 | -D__PTRDIFF_TYPE__=int |
| 62 | CHECKFLAGS-$(CONFIG_64BIT) += -m64 -D_MIPS_SIM=_ABI64 \ | 64 | CHECKFLAGS-$(CONFIG_64BIT) += -m64 -D_MIPS_SIM=_ABI64 \ |
| 63 | -D_MIPS_SZLONG=64 \ | 65 | -D_MIPS_SZLONG=64 \ |
| 66 | -D_MIPS_SZPTR=64 \ | ||
| 64 | -D__PTRDIFF_TYPE__="long int" | 67 | -D__PTRDIFF_TYPE__="long int" |
| 65 | CHECKFLAGS-$(CONFIG_CPU_BIG_ENDIAN) += -D__MIPSEB__ | 68 | CHECKFLAGS-$(CONFIG_CPU_BIG_ENDIAN) += -D__MIPSEB__ |
| 66 | CHECKFLAGS-$(CONFIG_CPU_LITTLE_ENDIAN) += -D__MIPSEL__ | 69 | CHECKFLAGS-$(CONFIG_CPU_LITTLE_ENDIAN) += -D__MIPSEL__ |
| @@ -166,79 +169,97 @@ echo $$gcc_abi $$gcc_opt$$gcc_cpu $$gcc_isa $$gas_abi $$gas_opt$$gas_cpu $$gas_i | |||
| 166 | # | 169 | # |
| 167 | cflags-$(CONFIG_CPU_R3000) += \ | 170 | cflags-$(CONFIG_CPU_R3000) += \ |
| 168 | $(call set_gccflags,r3000,mips1,r3000,mips1,mips1) | 171 | $(call set_gccflags,r3000,mips1,r3000,mips1,mips1) |
| 172 | CHECKFLAGS-$(CONFIG_CPU_R3000) += -D_MIPS_ISA=_MIPS_ISA_MIPS1 | ||
| 169 | 173 | ||
| 170 | cflags-$(CONFIG_CPU_TX39XX) += \ | 174 | cflags-$(CONFIG_CPU_TX39XX) += \ |
| 171 | $(call set_gccflags,r3900,mips1,r3000,mips1,mips1) | 175 | $(call set_gccflags,r3900,mips1,r3000,mips1,mips1) |
| 176 | CHECKFLAGS-$(CONFIG_CPU_TX39XX) += -D_MIPS_ISA=_MIPS_ISA_MIPS1 | ||
| 172 | 177 | ||
| 173 | cflags-$(CONFIG_CPU_R6000) += \ | 178 | cflags-$(CONFIG_CPU_R6000) += \ |
| 174 | $(call set_gccflags,r6000,mips2,r6000,mips2,mips2) \ | 179 | $(call set_gccflags,r6000,mips2,r6000,mips2,mips2) \ |
| 175 | -Wa,--trap | 180 | -Wa,--trap |
| 181 | CHECKFLAGS-$(CONFIG_CPU_R6000) += -D_MIPS_ISA=_MIPS_ISA_MIPS2 | ||
| 176 | 182 | ||
| 177 | cflags-$(CONFIG_CPU_R4300) += \ | 183 | cflags-$(CONFIG_CPU_R4300) += \ |
| 178 | $(call set_gccflags,r4300,mips3,r4300,mips3,mips2) \ | 184 | $(call set_gccflags,r4300,mips3,r4300,mips3,mips2) \ |
| 179 | -Wa,--trap | 185 | -Wa,--trap |
| 186 | CHECKFLAGS-$(CONFIG_CPU_R4300) += -D_MIPS_ISA=_MIPS_ISA_MIPS3 | ||
| 180 | 187 | ||
| 181 | cflags-$(CONFIG_CPU_VR41XX) += \ | 188 | cflags-$(CONFIG_CPU_VR41XX) += \ |
| 182 | $(call set_gccflags,r4100,mips3,r4600,mips3,mips2) \ | 189 | $(call set_gccflags,r4100,mips3,r4600,mips3,mips2) \ |
| 183 | -Wa,--trap | 190 | -Wa,--trap |
| 191 | CHECKFLAGS-$(CONFIG_CPU_VR41XX) += -D_MIPS_ISA=_MIPS_ISA_MIPS3 | ||
| 184 | 192 | ||
| 185 | cflags-$(CONFIG_CPU_R4X00) += \ | 193 | cflags-$(CONFIG_CPU_R4X00) += \ |
| 186 | $(call set_gccflags,r4600,mips3,r4600,mips3,mips2) \ | 194 | $(call set_gccflags,r4600,mips3,r4600,mips3,mips2) \ |
| 187 | -Wa,--trap | 195 | -Wa,--trap |
| 196 | CHECKFLAGS-$(CONFIG_CPU_R4X00) += -D_MIPS_ISA=_MIPS_ISA_MIPS3 | ||
| 188 | 197 | ||
| 189 | cflags-$(CONFIG_CPU_TX49XX) += \ | 198 | cflags-$(CONFIG_CPU_TX49XX) += \ |
| 190 | $(call set_gccflags,r4600,mips3,r4600,mips3,mips2) \ | 199 | $(call set_gccflags,r4600,mips3,r4600,mips3,mips2) \ |
| 191 | -Wa,--trap | 200 | -Wa,--trap |
| 201 | CHECKFLAGS-$(CONFIG_CPU_TX49XX) += -D_MIPS_ISA=_MIPS_ISA_MIPS3 | ||
| 192 | 202 | ||
| 193 | cflags-$(CONFIG_CPU_MIPS32_R1) += \ | 203 | cflags-$(CONFIG_CPU_MIPS32_R1) += \ |
| 194 | $(call set_gccflags,mips32,mips32,r4600,mips3,mips2) \ | 204 | $(call set_gccflags,mips32,mips32,r4600,mips3,mips2) \ |
| 195 | -Wa,--trap | 205 | -Wa,--trap |
| 206 | CHECKFLAGS-$(CONFIG_CPU_MIPS32_R1) += -D_MIPS_ISA=_MIPS_ISA_MIPS32 | ||
| 196 | 207 | ||
| 197 | cflags-$(CONFIG_CPU_MIPS32_R2) += \ | 208 | cflags-$(CONFIG_CPU_MIPS32_R2) += \ |
| 198 | $(call set_gccflags,mips32r2,mips32r2,r4600,mips3,mips2) \ | 209 | $(call set_gccflags,mips32r2,mips32r2,r4600,mips3,mips2) \ |
| 199 | -Wa,--trap | 210 | -Wa,--trap |
| 211 | CHECKFLAGS-$(CONFIG_CPU_MIPS32_R2) += -D_MIPS_ISA=_MIPS_ISA_MIPS32 | ||
| 200 | 212 | ||
| 201 | cflags-$(CONFIG_CPU_MIPS64_R1) += \ | 213 | cflags-$(CONFIG_CPU_MIPS64_R1) += \ |
| 202 | $(call set_gccflags,mips64,mips64,r4600,mips3,mips2) \ | 214 | $(call set_gccflags,mips64,mips64,r4600,mips3,mips2) \ |
| 203 | -Wa,--trap | 215 | -Wa,--trap |
| 216 | CHECKFLAGS-$(CONFIG_CPU_MIPS64_R1) += -D_MIPS_ISA=_MIPS_ISA_MIPS64 | ||
| 204 | 217 | ||
| 205 | cflags-$(CONFIG_CPU_MIPS64_R2) += \ | 218 | cflags-$(CONFIG_CPU_MIPS64_R2) += \ |
| 206 | $(call set_gccflags,mips64r2,mips64r2,r4600,mips3,mips2) \ | 219 | $(call set_gccflags,mips64r2,mips64r2,r4600,mips3,mips2) \ |
| 207 | -Wa,--trap | 220 | -Wa,--trap |
| 221 | CHECKFLAGS-$(CONFIG_CPU_MIPS64_R2) += -D_MIPS_ISA=_MIPS_ISA_MIPS64 | ||
| 208 | 222 | ||
| 209 | cflags-$(CONFIG_CPU_R5000) += \ | 223 | cflags-$(CONFIG_CPU_R5000) += \ |
| 210 | $(call set_gccflags,r5000,mips4,r5000,mips4,mips2) \ | 224 | $(call set_gccflags,r5000,mips4,r5000,mips4,mips2) \ |
| 211 | -Wa,--trap | 225 | -Wa,--trap |
| 226 | CHECKFLAGS-$(CONFIG_CPU_R5000) += -D_MIPS_ISA=_MIPS_ISA_MIPS4 | ||
| 212 | 227 | ||
| 213 | cflags-$(CONFIG_CPU_R5432) += \ | 228 | cflags-$(CONFIG_CPU_R5432) += \ |
| 214 | $(call set_gccflags,r5400,mips4,r5000,mips4,mips2) \ | 229 | $(call set_gccflags,r5400,mips4,r5000,mips4,mips2) \ |
| 215 | -Wa,--trap | 230 | -Wa,--trap |
| 231 | CHECKFLAGS-$(CONFIG_CPU_R5432) += -D_MIPS_ISA=_MIPS_ISA_MIPS4 | ||
| 216 | 232 | ||
| 217 | cflags-$(CONFIG_CPU_NEVADA) += \ | 233 | cflags-$(CONFIG_CPU_NEVADA) += \ |
| 218 | $(call set_gccflags,rm5200,mips4,r5000,mips4,mips2) \ | 234 | $(call set_gccflags,rm5200,mips4,r5000,mips4,mips2) \ |
| 219 | -Wa,--trap | 235 | -Wa,--trap |
| 220 | # $(call cc-option,-mmad) | 236 | CHECKFLAGS-$(CONFIG_CPU_NEVADA) += -D_MIPS_ISA=_MIPS_ISA_MIPS4 |
| 221 | 237 | ||
| 222 | cflags-$(CONFIG_CPU_RM7000) += \ | 238 | cflags-$(CONFIG_CPU_RM7000) += \ |
| 223 | $(call set_gccflags,rm7000,mips4,r5000,mips4,mips2) \ | 239 | $(call set_gccflags,rm7000,mips4,r5000,mips4,mips2) \ |
| 224 | -Wa,--trap | 240 | -Wa,--trap |
| 241 | CHECKFLAGS-$(CONFIG_CPU_RM7000) += -D_MIPS_ISA=_MIPS_ISA_MIPS4 | ||
| 225 | 242 | ||
| 226 | cflags-$(CONFIG_CPU_RM9000) += \ | 243 | cflags-$(CONFIG_CPU_RM9000) += \ |
| 227 | $(call set_gccflags,rm9000,mips4,r5000,mips4,mips2) \ | 244 | $(call set_gccflags,rm9000,mips4,r5000,mips4,mips2) \ |
| 228 | -Wa,--trap | 245 | -Wa,--trap |
| 246 | CHECKFLAGS-$(CONFIG_CPU_RM9000) += -D_MIPS_ISA=_MIPS_ISA_MIPS4 | ||
| 229 | 247 | ||
| 230 | 248 | ||
| 231 | cflags-$(CONFIG_CPU_SB1) += \ | 249 | cflags-$(CONFIG_CPU_SB1) += \ |
| 232 | $(call set_gccflags,sb1,mips64,r5000,mips4,mips2) \ | 250 | $(call set_gccflags,sb1,mips64,r5000,mips4,mips2) \ |
| 233 | -Wa,--trap | 251 | -Wa,--trap |
| 252 | CHECKFLAGS-$(CONFIG_CPU_SB1) += -D_MIPS_ISA=_MIPS_ISA_MIPS64 | ||
| 234 | 253 | ||
| 235 | cflags-$(CONFIG_CPU_R8000) += \ | 254 | cflags-$(CONFIG_CPU_R8000) += \ |
| 236 | $(call set_gccflags,r8000,mips4,r8000,mips4,mips2) \ | 255 | $(call set_gccflags,r8000,mips4,r8000,mips4,mips2) \ |
| 237 | -Wa,--trap | 256 | -Wa,--trap |
| 257 | CHECKFLAGS-$(CONFIG_CPU_R8000) += -D_MIPS_ISA=_MIPS_ISA_MIPS4 | ||
| 238 | 258 | ||
| 239 | cflags-$(CONFIG_CPU_R10000) += \ | 259 | cflags-$(CONFIG_CPU_R10000) += \ |
| 240 | $(call set_gccflags,r10000,mips4,r8000,mips4,mips2) \ | 260 | $(call set_gccflags,r10000,mips4,r8000,mips4,mips2) \ |
| 241 | -Wa,--trap | 261 | -Wa,--trap |
| 262 | CHECKFLAGS-$(CONFIG_CPU_R10000) += -D_MIPS_ISA=_MIPS_ISA_MIPS4 | ||
| 242 | 263 | ||
| 243 | ifdef CONFIG_CPU_SB1 | 264 | ifdef CONFIG_CPU_SB1 |
| 244 | ifdef CONFIG_SB1_PASS_1_WORKAROUNDS | 265 | ifdef CONFIG_SB1_PASS_1_WORKAROUNDS |
| @@ -369,7 +390,7 @@ load-$(CONFIG_MIPS_XXS1500) += 0xffffffff80100000 | |||
| 369 | # Cobalt Server | 390 | # Cobalt Server |
| 370 | # | 391 | # |
| 371 | core-$(CONFIG_MIPS_COBALT) += arch/mips/cobalt/ | 392 | core-$(CONFIG_MIPS_COBALT) += arch/mips/cobalt/ |
| 372 | cflags-$(CONFIG_MIPS_COBALT) += -Iinclude/asm-mips/cobalt | 393 | cflags-$(CONFIG_MIPS_COBALT) += -Iinclude/asm-mips/mach-cobalt |
| 373 | load-$(CONFIG_MIPS_COBALT) += 0xffffffff80080000 | 394 | load-$(CONFIG_MIPS_COBALT) += 0xffffffff80080000 |
| 374 | 395 | ||
| 375 | # | 396 | # |
diff --git a/arch/mips/au1000/common/reset.c b/arch/mips/au1000/common/reset.c index 65b84db800e4..4ffccedf5967 100644 --- a/arch/mips/au1000/common/reset.c +++ b/arch/mips/au1000/common/reset.c | |||
| @@ -151,7 +151,7 @@ void au1000_restart(char *command) | |||
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | set_c0_status(ST0_BEV | ST0_ERL); | 153 | set_c0_status(ST0_BEV | ST0_ERL); |
| 154 | set_c0_config(CONF_CM_UNCACHED); | 154 | change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED); |
| 155 | flush_cache_all(); | 155 | flush_cache_all(); |
| 156 | write_c0_wired(0); | 156 | write_c0_wired(0); |
| 157 | 157 | ||
diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c index 08c8c855cc9c..eb155c071aa6 100644 --- a/arch/mips/au1000/common/setup.c +++ b/arch/mips/au1000/common/setup.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <linux/delay.h> | 33 | #include <linux/delay.h> |
| 34 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
| 35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
| 36 | #include <linux/pm.h> | ||
| 36 | 37 | ||
| 37 | #include <asm/cpu.h> | 38 | #include <asm/cpu.h> |
| 38 | #include <asm/bootinfo.h> | 39 | #include <asm/bootinfo.h> |
| @@ -125,7 +126,7 @@ void __init plat_setup(void) | |||
| 125 | #endif | 126 | #endif |
| 126 | _machine_restart = au1000_restart; | 127 | _machine_restart = au1000_restart; |
| 127 | _machine_halt = au1000_halt; | 128 | _machine_halt = au1000_halt; |
| 128 | _machine_power_off = au1000_power_off; | 129 | pm_power_off = au1000_power_off; |
| 129 | board_time_init = au1xxx_time_init; | 130 | board_time_init = au1xxx_time_init; |
| 130 | board_timer_setup = au1xxx_timer_setup; | 131 | board_timer_setup = au1xxx_timer_setup; |
| 131 | 132 | ||
diff --git a/arch/mips/cobalt/int-handler.S b/arch/mips/cobalt/int-handler.S index f92608e8d84f..e75d5e3ca868 100644 --- a/arch/mips/cobalt/int-handler.S +++ b/arch/mips/cobalt/int-handler.S | |||
| @@ -8,7 +8,7 @@ | |||
| 8 | */ | 8 | */ |
| 9 | #include <asm/asm.h> | 9 | #include <asm/asm.h> |
| 10 | #include <asm/mipsregs.h> | 10 | #include <asm/mipsregs.h> |
| 11 | #include <asm/cobalt/cobalt.h> | 11 | #include <asm/mach-cobalt/cobalt.h> |
| 12 | #include <asm/regdef.h> | 12 | #include <asm/regdef.h> |
| 13 | #include <asm/stackframe.h> | 13 | #include <asm/stackframe.h> |
| 14 | 14 | ||
diff --git a/arch/mips/cobalt/irq.c b/arch/mips/cobalt/irq.c index 0d90851f925e..f9a108820d6e 100644 --- a/arch/mips/cobalt/irq.c +++ b/arch/mips/cobalt/irq.c | |||
| @@ -18,7 +18,7 @@ | |||
| 18 | #include <asm/gt64120.h> | 18 | #include <asm/gt64120.h> |
| 19 | #include <asm/ptrace.h> | 19 | #include <asm/ptrace.h> |
| 20 | 20 | ||
| 21 | #include <asm/cobalt/cobalt.h> | 21 | #include <asm/mach-cobalt/cobalt.h> |
| 22 | 22 | ||
| 23 | extern void cobalt_handle_int(void); | 23 | extern void cobalt_handle_int(void); |
| 24 | 24 | ||
diff --git a/arch/mips/cobalt/reset.c b/arch/mips/cobalt/reset.c index 805a0e88507b..753dfccae6fa 100644 --- a/arch/mips/cobalt/reset.c +++ b/arch/mips/cobalt/reset.c | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | #include <asm/reboot.h> | 16 | #include <asm/reboot.h> |
| 17 | #include <asm/system.h> | 17 | #include <asm/system.h> |
| 18 | #include <asm/mipsregs.h> | 18 | #include <asm/mipsregs.h> |
| 19 | #include <asm/cobalt/cobalt.h> | 19 | #include <asm/mach-cobalt/cobalt.h> |
| 20 | 20 | ||
| 21 | void cobalt_machine_halt(void) | 21 | void cobalt_machine_halt(void) |
| 22 | { | 22 | { |
diff --git a/arch/mips/cobalt/setup.c b/arch/mips/cobalt/setup.c index d358a118fa31..b9713a723053 100644 --- a/arch/mips/cobalt/setup.c +++ b/arch/mips/cobalt/setup.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * License. See the file "COPYING" in the main directory of this archive | 5 | * License. See the file "COPYING" in the main directory of this archive |
| 6 | * for more details. | 6 | * for more details. |
| 7 | * | 7 | * |
| 8 | * Copyright (C) 1996, 1997, 2004 by Ralf Baechle (ralf@linux-mips.org) | 8 | * Copyright (C) 1996, 1997, 2004, 05 by Ralf Baechle (ralf@linux-mips.org) |
| 9 | * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv) | 9 | * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv) |
| 10 | * | 10 | * |
| 11 | */ | 11 | */ |
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
| 14 | #include <linux/pci.h> | 14 | #include <linux/pci.h> |
| 15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
| 16 | #include <linux/pm.h> | ||
| 16 | #include <linux/serial.h> | 17 | #include <linux/serial.h> |
| 17 | #include <linux/serial_core.h> | 18 | #include <linux/serial_core.h> |
| 18 | 19 | ||
| @@ -25,7 +26,7 @@ | |||
| 25 | #include <asm/gt64120.h> | 26 | #include <asm/gt64120.h> |
| 26 | #include <asm/serial.h> | 27 | #include <asm/serial.h> |
| 27 | 28 | ||
| 28 | #include <asm/cobalt/cobalt.h> | 29 | #include <asm/mach-cobalt/cobalt.h> |
| 29 | 30 | ||
| 30 | extern void cobalt_machine_restart(char *command); | 31 | extern void cobalt_machine_restart(char *command); |
| 31 | extern void cobalt_machine_halt(void); | 32 | extern void cobalt_machine_halt(void); |
| @@ -99,7 +100,7 @@ void __init plat_setup(void) | |||
| 99 | 100 | ||
| 100 | _machine_restart = cobalt_machine_restart; | 101 | _machine_restart = cobalt_machine_restart; |
| 101 | _machine_halt = cobalt_machine_halt; | 102 | _machine_halt = cobalt_machine_halt; |
| 102 | _machine_power_off = cobalt_machine_power_off; | 103 | pm_power_off = cobalt_machine_power_off; |
| 103 | 104 | ||
| 104 | board_timer_setup = cobalt_timer_setup; | 105 | board_timer_setup = cobalt_timer_setup; |
| 105 | 106 | ||
| @@ -139,7 +140,7 @@ void __init plat_setup(void) | |||
| 139 | uart.type = PORT_UNKNOWN; | 140 | uart.type = PORT_UNKNOWN; |
| 140 | uart.uartclk = 18432000; | 141 | uart.uartclk = 18432000; |
| 141 | uart.irq = COBALT_SERIAL_IRQ; | 142 | uart.irq = COBALT_SERIAL_IRQ; |
| 142 | uart.flags = STD_COM_FLAGS; | 143 | uart.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
| 143 | uart.iobase = 0xc800000; | 144 | uart.iobase = 0xc800000; |
| 144 | uart.iotype = UPIO_PORT; | 145 | uart.iotype = UPIO_PORT; |
| 145 | 146 | ||
diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig index 967e7acd8e1f..a34db6e82b27 100644 --- a/arch/mips/configs/ip32_defconfig +++ b/arch/mips/configs/ip32_defconfig | |||
| @@ -102,6 +102,7 @@ CONFIG_CPU_R5000=y | |||
| 102 | # CONFIG_CPU_RM9000 is not set | 102 | # CONFIG_CPU_RM9000 is not set |
| 103 | # CONFIG_CPU_SB1 is not set | 103 | # CONFIG_CPU_SB1 is not set |
| 104 | CONFIG_SYS_HAS_CPU_R5000=y | 104 | CONFIG_SYS_HAS_CPU_R5000=y |
| 105 | CONFIG_SYS_HAS_CPU_NEVADA=y | ||
| 105 | CONFIG_SYS_HAS_CPU_RM7000=y | 106 | CONFIG_SYS_HAS_CPU_RM7000=y |
| 106 | CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y | 107 | CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y |
| 107 | CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y | 108 | CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y |
diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig index dee44606164c..c02becab850b 100644 --- a/arch/mips/configs/qemu_defconfig +++ b/arch/mips/configs/qemu_defconfig | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | # | 1 | # |
| 2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
| 3 | # Linux kernel version: 2.6.15-rc2 | 3 | # Linux kernel version: 2.6.16-rc2 |
| 4 | # Thu Nov 24 01:07:00 2005 | 4 | # Fri Feb 3 17:14:27 2006 |
| 5 | # | 5 | # |
| 6 | CONFIG_MIPS=y | 6 | CONFIG_MIPS=y |
| 7 | 7 | ||
| @@ -147,26 +147,27 @@ CONFIG_LOCALVERSION_AUTO=y | |||
| 147 | # CONFIG_BSD_PROCESS_ACCT is not set | 147 | # CONFIG_BSD_PROCESS_ACCT is not set |
| 148 | # CONFIG_SYSCTL is not set | 148 | # CONFIG_SYSCTL is not set |
| 149 | # CONFIG_AUDIT is not set | 149 | # CONFIG_AUDIT is not set |
| 150 | # CONFIG_HOTPLUG is not set | ||
| 151 | CONFIG_KOBJECT_UEVENT=y | ||
| 152 | # CONFIG_IKCONFIG is not set | 150 | # CONFIG_IKCONFIG is not set |
| 153 | CONFIG_INITRAMFS_SOURCE="" | 151 | CONFIG_INITRAMFS_SOURCE="" |
| 154 | CONFIG_EMBEDDED=y | 152 | CONFIG_EMBEDDED=y |
| 155 | CONFIG_KALLSYMS=y | 153 | CONFIG_KALLSYMS=y |
| 156 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 154 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
| 155 | # CONFIG_HOTPLUG is not set | ||
| 157 | CONFIG_PRINTK=y | 156 | CONFIG_PRINTK=y |
| 158 | # CONFIG_BUG is not set | 157 | # CONFIG_BUG is not set |
| 158 | CONFIG_ELF_CORE=y | ||
| 159 | # CONFIG_BASE_FULL is not set | 159 | # CONFIG_BASE_FULL is not set |
| 160 | # CONFIG_FUTEX is not set | 160 | # CONFIG_FUTEX is not set |
| 161 | # CONFIG_EPOLL is not set | 161 | # CONFIG_EPOLL is not set |
| 162 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
| 163 | # CONFIG_SHMEM is not set | 162 | # CONFIG_SHMEM is not set |
| 164 | CONFIG_CC_ALIGN_FUNCTIONS=0 | 163 | CONFIG_CC_ALIGN_FUNCTIONS=0 |
| 165 | CONFIG_CC_ALIGN_LABELS=0 | 164 | CONFIG_CC_ALIGN_LABELS=0 |
| 166 | CONFIG_CC_ALIGN_LOOPS=0 | 165 | CONFIG_CC_ALIGN_LOOPS=0 |
| 167 | CONFIG_CC_ALIGN_JUMPS=0 | 166 | CONFIG_CC_ALIGN_JUMPS=0 |
| 167 | CONFIG_SLAB=y | ||
| 168 | CONFIG_TINY_SHMEM=y | 168 | CONFIG_TINY_SHMEM=y |
| 169 | CONFIG_BASE_SMALL=1 | 169 | CONFIG_BASE_SMALL=1 |
| 170 | # CONFIG_SLOB is not set | ||
| 170 | 171 | ||
| 171 | # | 172 | # |
| 172 | # Loadable module support | 173 | # Loadable module support |
| @@ -266,11 +267,7 @@ CONFIG_TCP_CONG_BIC=y | |||
| 266 | # CONFIG_HAMRADIO is not set | 267 | # CONFIG_HAMRADIO is not set |
| 267 | # CONFIG_IRDA is not set | 268 | # CONFIG_IRDA is not set |
| 268 | # CONFIG_BT is not set | 269 | # CONFIG_BT is not set |
| 269 | CONFIG_IEEE80211=y | 270 | # CONFIG_IEEE80211 is not set |
| 270 | # CONFIG_IEEE80211_DEBUG is not set | ||
| 271 | CONFIG_IEEE80211_CRYPT_WEP=y | ||
| 272 | CONFIG_IEEE80211_CRYPT_CCMP=y | ||
| 273 | CONFIG_IEEE80211_CRYPT_TKIP=y | ||
| 274 | 271 | ||
| 275 | # | 272 | # |
| 276 | # Device Drivers | 273 | # Device Drivers |
| @@ -323,7 +320,7 @@ CONFIG_BLK_DEV_RAM_COUNT=16 | |||
| 323 | # | 320 | # |
| 324 | # SCSI device support | 321 | # SCSI device support |
| 325 | # | 322 | # |
| 326 | CONFIG_RAID_ATTRS=y | 323 | # CONFIG_RAID_ATTRS is not set |
| 327 | # CONFIG_SCSI is not set | 324 | # CONFIG_SCSI is not set |
| 328 | 325 | ||
| 329 | # | 326 | # |
| @@ -366,24 +363,16 @@ CONFIG_NETDEVICES=y | |||
| 366 | # | 363 | # |
| 367 | # PHY device support | 364 | # PHY device support |
| 368 | # | 365 | # |
| 369 | CONFIG_PHYLIB=y | 366 | # CONFIG_PHYLIB is not set |
| 370 | |||
| 371 | # | ||
| 372 | # MII PHY device drivers | ||
| 373 | # | ||
| 374 | CONFIG_MARVELL_PHY=y | ||
| 375 | CONFIG_DAVICOM_PHY=y | ||
| 376 | CONFIG_QSEMI_PHY=y | ||
| 377 | CONFIG_LXT_PHY=y | ||
| 378 | CONFIG_CICADA_PHY=y | ||
| 379 | 367 | ||
| 380 | # | 368 | # |
| 381 | # Ethernet (10 or 100Mbit) | 369 | # Ethernet (10 or 100Mbit) |
| 382 | # | 370 | # |
| 383 | CONFIG_NET_ETHERNET=y | 371 | CONFIG_NET_ETHERNET=y |
| 384 | CONFIG_MII=y | 372 | # CONFIG_MII is not set |
| 385 | # CONFIG_NET_VENDOR_3COM is not set | 373 | # CONFIG_NET_VENDOR_3COM is not set |
| 386 | # CONFIG_NET_VENDOR_SMC is not set | 374 | # CONFIG_NET_VENDOR_SMC is not set |
| 375 | # CONFIG_DM9000 is not set | ||
| 387 | # CONFIG_NET_VENDOR_RACAL is not set | 376 | # CONFIG_NET_VENDOR_RACAL is not set |
| 388 | # CONFIG_DEPCA is not set | 377 | # CONFIG_DEPCA is not set |
| 389 | # CONFIG_HP100 is not set | 378 | # CONFIG_HP100 is not set |
| @@ -479,6 +468,7 @@ CONFIG_HW_CONSOLE=y | |||
| 479 | CONFIG_SERIAL_8250=y | 468 | CONFIG_SERIAL_8250=y |
| 480 | CONFIG_SERIAL_8250_CONSOLE=y | 469 | CONFIG_SERIAL_8250_CONSOLE=y |
| 481 | CONFIG_SERIAL_8250_NR_UARTS=4 | 470 | CONFIG_SERIAL_8250_NR_UARTS=4 |
| 471 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 | ||
| 482 | # CONFIG_SERIAL_8250_EXTENDED is not set | 472 | # CONFIG_SERIAL_8250_EXTENDED is not set |
| 483 | 473 | ||
| 484 | # | 474 | # |
| @@ -518,6 +508,12 @@ CONFIG_SERIAL_CORE_CONSOLE=y | |||
| 518 | # CONFIG_I2C is not set | 508 | # CONFIG_I2C is not set |
| 519 | 509 | ||
| 520 | # | 510 | # |
| 511 | # SPI support | ||
| 512 | # | ||
| 513 | # CONFIG_SPI is not set | ||
| 514 | # CONFIG_SPI_MASTER is not set | ||
| 515 | |||
| 516 | # | ||
| 521 | # Dallas's 1-wire bus | 517 | # Dallas's 1-wire bus |
| 522 | # | 518 | # |
| 523 | # CONFIG_W1 is not set | 519 | # CONFIG_W1 is not set |
| @@ -592,11 +588,14 @@ CONFIG_DUMMY_CONSOLE=y | |||
| 592 | # | 588 | # |
| 593 | 589 | ||
| 594 | # | 590 | # |
| 591 | # EDAC - error detection and reporting (RAS) | ||
| 592 | # | ||
| 593 | |||
| 594 | # | ||
| 595 | # File systems | 595 | # File systems |
| 596 | # | 596 | # |
| 597 | # CONFIG_EXT2_FS is not set | 597 | # CONFIG_EXT2_FS is not set |
| 598 | # CONFIG_EXT3_FS is not set | 598 | # CONFIG_EXT3_FS is not set |
| 599 | # CONFIG_JBD is not set | ||
| 600 | # CONFIG_REISERFS_FS is not set | 599 | # CONFIG_REISERFS_FS is not set |
| 601 | # CONFIG_JFS_FS is not set | 600 | # CONFIG_JFS_FS is not set |
| 602 | # CONFIG_FS_POSIX_ACL is not set | 601 | # CONFIG_FS_POSIX_ACL is not set |
| @@ -677,6 +676,7 @@ CONFIG_MSDOS_PARTITION=y | |||
| 677 | # Kernel hacking | 676 | # Kernel hacking |
| 678 | # | 677 | # |
| 679 | # CONFIG_PRINTK_TIME is not set | 678 | # CONFIG_PRINTK_TIME is not set |
| 679 | # CONFIG_MAGIC_SYSRQ is not set | ||
| 680 | # CONFIG_DEBUG_KERNEL is not set | 680 | # CONFIG_DEBUG_KERNEL is not set |
| 681 | CONFIG_LOG_BUF_SHIFT=14 | 681 | CONFIG_LOG_BUF_SHIFT=14 |
| 682 | CONFIG_CROSSCOMPILE=y | 682 | CONFIG_CROSSCOMPILE=y |
| @@ -690,31 +690,7 @@ CONFIG_CMDLINE="console=ttyS0 debug ip=172.20.0.2:172.20.0.1::255.255.0.0" | |||
| 690 | # | 690 | # |
| 691 | # Cryptographic options | 691 | # Cryptographic options |
| 692 | # | 692 | # |
| 693 | CONFIG_CRYPTO=y | 693 | # CONFIG_CRYPTO is not set |
| 694 | CONFIG_CRYPTO_HMAC=y | ||
| 695 | CONFIG_CRYPTO_NULL=y | ||
| 696 | CONFIG_CRYPTO_MD4=y | ||
| 697 | CONFIG_CRYPTO_MD5=y | ||
| 698 | CONFIG_CRYPTO_SHA1=y | ||
| 699 | CONFIG_CRYPTO_SHA256=y | ||
| 700 | CONFIG_CRYPTO_SHA512=y | ||
| 701 | CONFIG_CRYPTO_WP512=y | ||
| 702 | CONFIG_CRYPTO_TGR192=y | ||
| 703 | CONFIG_CRYPTO_DES=y | ||
| 704 | CONFIG_CRYPTO_BLOWFISH=y | ||
| 705 | CONFIG_CRYPTO_TWOFISH=y | ||
| 706 | CONFIG_CRYPTO_SERPENT=y | ||
| 707 | CONFIG_CRYPTO_AES=y | ||
| 708 | CONFIG_CRYPTO_CAST5=y | ||
| 709 | CONFIG_CRYPTO_CAST6=y | ||
| 710 | CONFIG_CRYPTO_TEA=y | ||
| 711 | CONFIG_CRYPTO_ARC4=y | ||
| 712 | CONFIG_CRYPTO_KHAZAD=y | ||
| 713 | CONFIG_CRYPTO_ANUBIS=y | ||
| 714 | CONFIG_CRYPTO_DEFLATE=y | ||
| 715 | CONFIG_CRYPTO_MICHAEL_MIC=y | ||
| 716 | CONFIG_CRYPTO_CRC32C=y | ||
| 717 | # CONFIG_CRYPTO_TEST is not set | ||
| 718 | 694 | ||
| 719 | # | 695 | # |
| 720 | # Hardware crypto devices | 696 | # Hardware crypto devices |
| @@ -724,8 +700,6 @@ CONFIG_CRYPTO_CRC32C=y | |||
| 724 | # Library routines | 700 | # Library routines |
| 725 | # | 701 | # |
| 726 | # CONFIG_CRC_CCITT is not set | 702 | # CONFIG_CRC_CCITT is not set |
| 727 | CONFIG_CRC16=y | 703 | # CONFIG_CRC16 is not set |
| 728 | CONFIG_CRC32=y | 704 | CONFIG_CRC32=y |
| 729 | CONFIG_LIBCRC32C=y | 705 | # CONFIG_LIBCRC32C is not set |
| 730 | CONFIG_ZLIB_INFLATE=y | ||
| 731 | CONFIG_ZLIB_DEFLATE=y | ||
diff --git a/arch/mips/ddb5xxx/ddb5074/setup.c b/arch/mips/ddb5xxx/ddb5074/setup.c index 11535be265b9..91456b068c2e 100644 --- a/arch/mips/ddb5xxx/ddb5074/setup.c +++ b/arch/mips/ddb5xxx/ddb5074/setup.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/ide.h> | 14 | #include <linux/ide.h> |
| 15 | #include <linux/ioport.h> | 15 | #include <linux/ioport.h> |
| 16 | #include <linux/irq.h> | 16 | #include <linux/irq.h> |
| 17 | #include <linux/pm.h> | ||
| 17 | 18 | ||
| 18 | #include <asm/addrspace.h> | 19 | #include <asm/addrspace.h> |
| 19 | #include <asm/bcache.h> | 20 | #include <asm/bcache.h> |
| @@ -95,7 +96,7 @@ void __init plat_setup(void) | |||
| 95 | 96 | ||
| 96 | _machine_restart = ddb_machine_restart; | 97 | _machine_restart = ddb_machine_restart; |
| 97 | _machine_halt = ddb_machine_halt; | 98 | _machine_halt = ddb_machine_halt; |
| 98 | _machine_power_off = ddb_machine_power_off; | 99 | pm_power_off = ddb_machine_power_off; |
| 99 | 100 | ||
| 100 | ddb_out32(DDB_BAR0, 0); | 101 | ddb_out32(DDB_BAR0, 0); |
| 101 | 102 | ||
diff --git a/arch/mips/ddb5xxx/ddb5476/setup.c b/arch/mips/ddb5xxx/ddb5476/setup.c index f4e480a74edf..c902adef5942 100644 --- a/arch/mips/ddb5xxx/ddb5476/setup.c +++ b/arch/mips/ddb5xxx/ddb5476/setup.c | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
| 12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
| 13 | #include <linux/pci.h> | 13 | #include <linux/pci.h> |
| 14 | #include <linux/pm.h> | ||
| 14 | 15 | ||
| 15 | #include <asm/addrspace.h> | 16 | #include <asm/addrspace.h> |
| 16 | #include <asm/bcache.h> | 17 | #include <asm/bcache.h> |
| @@ -133,7 +134,7 @@ void __init plat_setup(void) | |||
| 133 | 134 | ||
| 134 | _machine_restart = ddb_machine_restart; | 135 | _machine_restart = ddb_machine_restart; |
| 135 | _machine_halt = ddb_machine_halt; | 136 | _machine_halt = ddb_machine_halt; |
| 136 | _machine_power_off = ddb_machine_power_off; | 137 | pm_power_off = ddb_machine_power_off; |
| 137 | 138 | ||
| 138 | /* request io port/mem resources */ | 139 | /* request io port/mem resources */ |
| 139 | if (request_resource(&ioport_resource, &ddb5476_ioport.dma1) || | 140 | if (request_resource(&ioport_resource, &ddb5476_ioport.dma1) || |
diff --git a/arch/mips/ddb5xxx/ddb5477/setup.c b/arch/mips/ddb5xxx/ddb5477/setup.c index 81163353c4a8..2f566034cc44 100644 --- a/arch/mips/ddb5xxx/ddb5477/setup.c +++ b/arch/mips/ddb5xxx/ddb5477/setup.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/major.h> | 26 | #include <linux/major.h> |
| 27 | #include <linux/kdev_t.h> | 27 | #include <linux/kdev_t.h> |
| 28 | #include <linux/root_dev.h> | 28 | #include <linux/root_dev.h> |
| 29 | #include <linux/pm.h> | ||
| 29 | 30 | ||
| 30 | #include <asm/cpu.h> | 31 | #include <asm/cpu.h> |
| 31 | #include <asm/bootinfo.h> | 32 | #include <asm/bootinfo.h> |
| @@ -182,7 +183,7 @@ void __init plat_setup(void) | |||
| 182 | 183 | ||
| 183 | _machine_restart = ddb_machine_restart; | 184 | _machine_restart = ddb_machine_restart; |
| 184 | _machine_halt = ddb_machine_halt; | 185 | _machine_halt = ddb_machine_halt; |
| 185 | _machine_power_off = ddb_machine_power_off; | 186 | pm_power_off = ddb_machine_power_off; |
| 186 | 187 | ||
| 187 | /* setup resource limits */ | 188 | /* setup resource limits */ |
| 188 | ioport_resource.end = DDB_PCI0_IO_SIZE + DDB_PCI1_IO_SIZE - 1; | 189 | ioport_resource.end = DDB_PCI0_IO_SIZE + DDB_PCI1_IO_SIZE - 1; |
diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c index 9ef54fe1feaa..7c1ca8f6330e 100644 --- a/arch/mips/dec/setup.c +++ b/arch/mips/dec/setup.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
| 18 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
| 19 | #include <linux/types.h> | 19 | #include <linux/types.h> |
| 20 | #include <linux/pm.h> | ||
| 20 | 21 | ||
| 21 | #include <asm/bootinfo.h> | 22 | #include <asm/bootinfo.h> |
| 22 | #include <asm/cpu.h> | 23 | #include <asm/cpu.h> |
| @@ -158,7 +159,7 @@ void __init plat_setup(void) | |||
| 158 | 159 | ||
| 159 | _machine_restart = dec_machine_restart; | 160 | _machine_restart = dec_machine_restart; |
| 160 | _machine_halt = dec_machine_halt; | 161 | _machine_halt = dec_machine_halt; |
| 161 | _machine_power_off = dec_machine_power_off; | 162 | pm_power_off = dec_machine_power_off; |
| 162 | 163 | ||
| 163 | ioport_resource.start = ~0UL; | 164 | ioport_resource.start = ~0UL; |
| 164 | ioport_resource.end = 0UL; | 165 | ioport_resource.end = 0UL; |
diff --git a/arch/mips/gt64120/ev64120/setup.c b/arch/mips/gt64120/ev64120/setup.c index 98b5a96cc039..6d859d1e7a2d 100644 --- a/arch/mips/gt64120/ev64120/setup.c +++ b/arch/mips/gt64120/ev64120/setup.c | |||
| @@ -34,6 +34,8 @@ | |||
| 34 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
| 35 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
| 36 | #include <linux/timex.h> | 36 | #include <linux/timex.h> |
| 37 | #include <linux/pm.h> | ||
| 38 | |||
| 37 | #include <asm/bootinfo.h> | 39 | #include <asm/bootinfo.h> |
| 38 | #include <asm/page.h> | 40 | #include <asm/page.h> |
| 39 | #include <asm/io.h> | 41 | #include <asm/io.h> |
| @@ -73,7 +75,7 @@ void __init plat_setup(void) | |||
| 73 | { | 75 | { |
| 74 | _machine_restart = galileo_machine_restart; | 76 | _machine_restart = galileo_machine_restart; |
| 75 | _machine_halt = galileo_machine_halt; | 77 | _machine_halt = galileo_machine_halt; |
| 76 | _machine_power_off = galileo_machine_power_off; | 78 | pm_power_off = galileo_machine_power_off; |
| 77 | 79 | ||
| 78 | board_time_init = gt64120_time_init; | 80 | board_time_init = gt64120_time_init; |
| 79 | set_io_port_base(KSEG1); | 81 | set_io_port_base(KSEG1); |
diff --git a/arch/mips/gt64120/momenco_ocelot/setup.c b/arch/mips/gt64120/momenco_ocelot/setup.c index 0d07c33112d0..20b65d3d2151 100644 --- a/arch/mips/gt64120/momenco_ocelot/setup.c +++ b/arch/mips/gt64120/momenco_ocelot/setup.c | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | * BRIEF MODULE DESCRIPTION | 4 | * BRIEF MODULE DESCRIPTION |
| 5 | * Momentum Computer Ocelot (CP7000) - board dependent boot routines | 5 | * Momentum Computer Ocelot (CP7000) - board dependent boot routines |
| 6 | * | 6 | * |
| 7 | * Copyright (C) 1996, 1997, 2001 Ralf Baechle | 7 | * Copyright (C) 1996, 1997, 2001, 06 Ralf Baechle (ralf@linux-mips.org) |
| 8 | * Copyright (C) 2000 RidgeRun, Inc. | 8 | * Copyright (C) 2000 RidgeRun, Inc. |
| 9 | * Copyright (C) 2001 Red Hat, Inc. | 9 | * Copyright (C) 2001 Red Hat, Inc. |
| 10 | * Copyright (C) 2002 Momentum Computer | 10 | * Copyright (C) 2002 Momentum Computer |
| @@ -47,6 +47,8 @@ | |||
| 47 | #include <linux/pci.h> | 47 | #include <linux/pci.h> |
| 48 | #include <linux/timex.h> | 48 | #include <linux/timex.h> |
| 49 | #include <linux/vmalloc.h> | 49 | #include <linux/vmalloc.h> |
| 50 | #include <linux/pm.h> | ||
| 51 | |||
| 50 | #include <asm/time.h> | 52 | #include <asm/time.h> |
| 51 | #include <asm/bootinfo.h> | 53 | #include <asm/bootinfo.h> |
| 52 | #include <asm/page.h> | 54 | #include <asm/page.h> |
| @@ -159,7 +161,7 @@ void __init plat_setup(void) | |||
| 159 | 161 | ||
| 160 | _machine_restart = momenco_ocelot_restart; | 162 | _machine_restart = momenco_ocelot_restart; |
| 161 | _machine_halt = momenco_ocelot_halt; | 163 | _machine_halt = momenco_ocelot_halt; |
| 162 | _machine_power_off = momenco_ocelot_power_off; | 164 | pm_power_off = momenco_ocelot_power_off; |
| 163 | 165 | ||
| 164 | /* | 166 | /* |
| 165 | * initrd_start = (ulong)ocelot_initrd_start; | 167 | * initrd_start = (ulong)ocelot_initrd_start; |
diff --git a/arch/mips/ite-boards/generic/it8172_setup.c b/arch/mips/ite-boards/generic/it8172_setup.c index 062429dd7ca0..fc73c8d69df7 100644 --- a/arch/mips/ite-boards/generic/it8172_setup.c +++ b/arch/mips/ite-boards/generic/it8172_setup.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/major.h> | 34 | #include <linux/major.h> |
| 35 | #include <linux/kdev_t.h> | 35 | #include <linux/kdev_t.h> |
| 36 | #include <linux/root_dev.h> | 36 | #include <linux/root_dev.h> |
| 37 | #include <linux/pm.h> | ||
| 37 | 38 | ||
| 38 | #include <asm/cpu.h> | 39 | #include <asm/cpu.h> |
| 39 | #include <asm/time.h> | 40 | #include <asm/time.h> |
| @@ -125,7 +126,7 @@ void __init plat_setup(void) | |||
| 125 | 126 | ||
| 126 | _machine_restart = it8172_restart; | 127 | _machine_restart = it8172_restart; |
| 127 | _machine_halt = it8172_halt; | 128 | _machine_halt = it8172_halt; |
| 128 | _machine_power_off = it8172_power_off; | 129 | pm_power_off = it8172_power_off; |
| 129 | 130 | ||
| 130 | /* | 131 | /* |
| 131 | * IO/MEM resources. | 132 | * IO/MEM resources. |
diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c index 044df9d4ab7c..4036dc434551 100644 --- a/arch/mips/jazz/setup.c +++ b/arch/mips/jazz/setup.c | |||
| @@ -19,6 +19,8 @@ | |||
| 19 | #include <linux/console.h> | 19 | #include <linux/console.h> |
| 20 | #include <linux/fb.h> | 20 | #include <linux/fb.h> |
| 21 | #include <linux/ide.h> | 21 | #include <linux/ide.h> |
| 22 | #include <linux/pm.h> | ||
| 23 | |||
| 22 | #include <asm/bootinfo.h> | 24 | #include <asm/bootinfo.h> |
| 23 | #include <asm/irq.h> | 25 | #include <asm/irq.h> |
| 24 | #include <asm/jazz.h> | 26 | #include <asm/jazz.h> |
| @@ -79,7 +81,7 @@ void __init plat_setup(void) | |||
| 79 | 81 | ||
| 80 | _machine_restart = jazz_machine_restart; | 82 | _machine_restart = jazz_machine_restart; |
| 81 | _machine_halt = jazz_machine_halt; | 83 | _machine_halt = jazz_machine_halt; |
| 82 | _machine_power_off = jazz_machine_power_off; | 84 | pm_power_off = jazz_machine_power_off; |
| 83 | 85 | ||
| 84 | #warning "Somebody should check if screen_info is ok for Jazz." | 86 | #warning "Somebody should check if screen_info is ok for Jazz." |
| 85 | 87 | ||
diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c index 4763957df8fc..9359cc413494 100644 --- a/arch/mips/jmr3927/rbhma3100/setup.c +++ b/arch/mips/jmr3927/rbhma3100/setup.c | |||
| @@ -44,6 +44,7 @@ | |||
| 44 | #include <linux/ioport.h> | 44 | #include <linux/ioport.h> |
| 45 | #include <linux/param.h> /* for HZ */ | 45 | #include <linux/param.h> /* for HZ */ |
| 46 | #include <linux/delay.h> | 46 | #include <linux/delay.h> |
| 47 | #include <linux/pm.h> | ||
| 47 | #ifdef CONFIG_SERIAL_TXX9 | 48 | #ifdef CONFIG_SERIAL_TXX9 |
| 48 | #include <linux/tty.h> | 49 | #include <linux/tty.h> |
| 49 | #include <linux/serial.h> | 50 | #include <linux/serial.h> |
| @@ -211,7 +212,7 @@ void __init plat_setup(void) | |||
| 211 | 212 | ||
| 212 | _machine_restart = jmr3927_machine_restart; | 213 | _machine_restart = jmr3927_machine_restart; |
| 213 | _machine_halt = jmr3927_machine_halt; | 214 | _machine_halt = jmr3927_machine_halt; |
| 214 | _machine_power_off = jmr3927_machine_power_off; | 215 | pm_power_off = jmr3927_machine_power_off; |
| 215 | 216 | ||
| 216 | /* | 217 | /* |
| 217 | * IO/MEM resources. | 218 | * IO/MEM resources. |
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index fac48ad27b34..292f8b243a5e 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
| @@ -2,8 +2,8 @@ | |||
| 2 | * Processor capabilities determination functions. | 2 | * Processor capabilities determination functions. |
| 3 | * | 3 | * |
| 4 | * Copyright (C) xxxx the Anonymous | 4 | * Copyright (C) xxxx the Anonymous |
| 5 | * Copyright (C) 1994 - 2006 Ralf Baechle | ||
| 5 | * Copyright (C) 2003, 2004 Maciej W. Rozycki | 6 | * Copyright (C) 2003, 2004 Maciej W. Rozycki |
| 6 | * Copyright (C) 1994 - 2003 Ralf Baechle | ||
| 7 | * Copyright (C) 2001, 2004 MIPS Inc. | 7 | * Copyright (C) 2001, 2004 MIPS Inc. |
| 8 | * | 8 | * |
| 9 | * This program is free software; you can redistribute it and/or | 9 | * This program is free software; you can redistribute it and/or |
| @@ -641,10 +641,9 @@ static inline void cpu_probe_sibyte(struct cpuinfo_mips *c) | |||
| 641 | switch (c->processor_id & 0xff00) { | 641 | switch (c->processor_id & 0xff00) { |
| 642 | case PRID_IMP_SB1: | 642 | case PRID_IMP_SB1: |
| 643 | c->cputype = CPU_SB1; | 643 | c->cputype = CPU_SB1; |
| 644 | #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS | ||
| 645 | /* FPU in pass1 is known to have issues. */ | 644 | /* FPU in pass1 is known to have issues. */ |
| 646 | c->options &= ~(MIPS_CPU_FPU | MIPS_CPU_32FPR); | 645 | if ((c->processor_id & 0xff) < 0x20) |
| 647 | #endif | 646 | c->options &= ~(MIPS_CPU_FPU | MIPS_CPU_32FPR); |
| 648 | break; | 647 | break; |
| 649 | case PRID_IMP_SB1A: | 648 | case PRID_IMP_SB1A: |
| 650 | c->cputype = CPU_SB1A; | 649 | c->cputype = CPU_SB1A; |
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index aa18a8b7b380..13f22d1d0e8b 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S | |||
| @@ -233,11 +233,11 @@ NESTED(except_vec_nmi, 0, sp) | |||
| 233 | NESTED(nmi_handler, PT_SIZE, sp) | 233 | NESTED(nmi_handler, PT_SIZE, sp) |
| 234 | .set push | 234 | .set push |
| 235 | .set noat | 235 | .set noat |
| 236 | .set mips3 | ||
| 237 | SAVE_ALL | 236 | SAVE_ALL |
| 238 | move a0, sp | 237 | move a0, sp |
| 239 | jal nmi_exception_handler | 238 | jal nmi_exception_handler |
| 240 | RESTORE_ALL | 239 | RESTORE_ALL |
| 240 | .set mips3 | ||
| 241 | eret | 241 | eret |
| 242 | .set pop | 242 | .set pop |
| 243 | END(nmi_handler) | 243 | END(nmi_handler) |
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index fa98f10d0132..5232fc752935 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | * for more details. | 4 | * for more details. |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 1994 - 1999, 2000 by Ralf Baechle and others. | 6 | * Copyright (C) 1994 - 1999, 2000 by Ralf Baechle and others. |
| 7 | * Copyright (C) 2005, 2006 by Ralf Baechle (ralf@linux-mips.org) | ||
| 7 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. | 8 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. |
| 8 | * Copyright (C) 2004 Thiemo Seufer | 9 | * Copyright (C) 2004 Thiemo Seufer |
| 9 | */ | 10 | */ |
| @@ -58,8 +59,8 @@ ATTRIB_NORET void cpu_idle(void) | |||
| 58 | } | 59 | } |
| 59 | } | 60 | } |
| 60 | 61 | ||
| 61 | extern int do_signal(sigset_t *oldset, struct pt_regs *regs); | 62 | extern void do_signal(struct pt_regs *regs); |
| 62 | extern int do_signal32(sigset_t *oldset, struct pt_regs *regs); | 63 | extern void do_signal32(struct pt_regs *regs); |
| 63 | 64 | ||
| 64 | /* | 65 | /* |
| 65 | * Native o32 and N64 ABI without DSP ASE | 66 | * Native o32 and N64 ABI without DSP ASE |
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c index 0c82b25d8c6d..0d5cf97af727 100644 --- a/arch/mips/kernel/ptrace32.c +++ b/arch/mips/kernel/ptrace32.c | |||
| @@ -88,7 +88,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) | |||
| 88 | ret = -EIO; | 88 | ret = -EIO; |
| 89 | if (copied != sizeof(tmp)) | 89 | if (copied != sizeof(tmp)) |
| 90 | break; | 90 | break; |
| 91 | ret = put_user(tmp, (unsigned int *) (unsigned long) data); | 91 | ret = put_user(tmp, (unsigned int __user *) (unsigned long) data); |
| 92 | break; | 92 | break; |
| 93 | } | 93 | } |
| 94 | 94 | ||
| @@ -174,8 +174,10 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) | |||
| 174 | case FPC_EIR: { /* implementation / version register */ | 174 | case FPC_EIR: { /* implementation / version register */ |
| 175 | unsigned int flags; | 175 | unsigned int flags; |
| 176 | 176 | ||
| 177 | if (!cpu_has_fpu) | 177 | if (!cpu_has_fpu) { |
| 178 | tmp = 0; | ||
| 178 | break; | 179 | break; |
| 180 | } | ||
| 179 | 181 | ||
| 180 | preempt_disable(); | 182 | preempt_disable(); |
| 181 | if (cpu_has_mipsmt) { | 183 | if (cpu_has_mipsmt) { |
| @@ -194,15 +196,18 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) | |||
| 194 | preempt_enable(); | 196 | preempt_enable(); |
| 195 | break; | 197 | break; |
| 196 | } | 198 | } |
| 197 | case DSP_BASE ... DSP_BASE + 5: | 199 | case DSP_BASE ... DSP_BASE + 5: { |
| 200 | dspreg_t *dregs; | ||
| 201 | |||
| 198 | if (!cpu_has_dsp) { | 202 | if (!cpu_has_dsp) { |
| 199 | tmp = 0; | 203 | tmp = 0; |
| 200 | ret = -EIO; | 204 | ret = -EIO; |
| 201 | goto out_tsk; | 205 | goto out_tsk; |
| 202 | } | 206 | } |
| 203 | dspreg_t *dregs = __get_dsp_regs(child); | 207 | dregs = __get_dsp_regs(child); |
| 204 | tmp = (unsigned long) (dregs[addr - DSP_BASE]); | 208 | tmp = (unsigned long) (dregs[addr - DSP_BASE]); |
| 205 | break; | 209 | break; |
| 210 | } | ||
| 206 | case DSP_CONTROL: | 211 | case DSP_CONTROL: |
| 207 | if (!cpu_has_dsp) { | 212 | if (!cpu_has_dsp) { |
| 208 | tmp = 0; | 213 | tmp = 0; |
| @@ -216,7 +221,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) | |||
| 216 | ret = -EIO; | 221 | ret = -EIO; |
| 217 | goto out_tsk; | 222 | goto out_tsk; |
| 218 | } | 223 | } |
| 219 | ret = put_user(tmp, (unsigned *) (unsigned long) data); | 224 | ret = put_user(tmp, (unsigned __user *) (unsigned long) data); |
| 220 | break; | 225 | break; |
| 221 | } | 226 | } |
| 222 | 227 | ||
| @@ -304,15 +309,18 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) | |||
| 304 | else | 309 | else |
| 305 | child->thread.fpu.soft.fcr31 = data; | 310 | child->thread.fpu.soft.fcr31 = data; |
| 306 | break; | 311 | break; |
| 307 | case DSP_BASE ... DSP_BASE + 5: | 312 | case DSP_BASE ... DSP_BASE + 5: { |
| 313 | dspreg_t *dregs; | ||
| 314 | |||
| 308 | if (!cpu_has_dsp) { | 315 | if (!cpu_has_dsp) { |
| 309 | ret = -EIO; | 316 | ret = -EIO; |
| 310 | break; | 317 | break; |
| 311 | } | 318 | } |
| 312 | 319 | ||
| 313 | dspreg_t *dregs = __get_dsp_regs(child); | 320 | dregs = __get_dsp_regs(child); |
| 314 | dregs[addr - DSP_BASE] = data; | 321 | dregs[addr - DSP_BASE] = data; |
| 315 | break; | 322 | break; |
| 323 | } | ||
| 316 | case DSP_CONTROL: | 324 | case DSP_CONTROL: |
| 317 | if (!cpu_has_dsp) { | 325 | if (!cpu_has_dsp) { |
| 318 | ret = -EIO; | 326 | ret = -EIO; |
diff --git a/arch/mips/kernel/reset.c b/arch/mips/kernel/reset.c index 5e37df3111ad..621037db2290 100644 --- a/arch/mips/kernel/reset.c +++ b/arch/mips/kernel/reset.c | |||
| @@ -3,17 +3,16 @@ | |||
| 3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
| 4 | * for more details. | 4 | * for more details. |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2001 by Ralf Baechle | 6 | * Copyright (C) 2001, 06 by Ralf Baechle (ralf@linux-mips.org) |
| 7 | * Copyright (C) 2001 MIPS Technologies, Inc. | 7 | * Copyright (C) 2001 MIPS Technologies, Inc. |
| 8 | */ | 8 | */ |
| 9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
| 10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
| 11 | #include <linux/pm.h> | ||
| 11 | #include <linux/types.h> | 12 | #include <linux/types.h> |
| 12 | #include <linux/reboot.h> | 13 | #include <linux/reboot.h> |
| 13 | #include <asm/reboot.h> | ||
| 14 | 14 | ||
| 15 | void (*pm_power_off)(void); | 15 | #include <asm/reboot.h> |
| 16 | EXPORT_SYMBOL(pm_power_off); | ||
| 17 | 16 | ||
| 18 | /* | 17 | /* |
| 19 | * Urgs ... Too many MIPS machines to handle this in a generic way. | 18 | * Urgs ... Too many MIPS machines to handle this in a generic way. |
| @@ -22,23 +21,22 @@ EXPORT_SYMBOL(pm_power_off); | |||
| 22 | */ | 21 | */ |
| 23 | void (*_machine_restart)(char *command); | 22 | void (*_machine_restart)(char *command); |
| 24 | void (*_machine_halt)(void); | 23 | void (*_machine_halt)(void); |
| 25 | void (*_machine_power_off)(void); | 24 | void (*pm_power_off)(void); |
| 26 | 25 | ||
| 27 | void machine_restart(char *command) | 26 | void machine_restart(char *command) |
| 28 | { | 27 | { |
| 29 | _machine_restart(command); | 28 | if (_machine_restart) |
| 29 | _machine_restart(command); | ||
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | void machine_halt(void) | 32 | void machine_halt(void) |
| 33 | { | 33 | { |
| 34 | _machine_halt(); | 34 | if (_machine_halt) |
| 35 | _machine_halt(); | ||
| 35 | } | 36 | } |
| 36 | 37 | ||
| 37 | void machine_power_off(void) | 38 | void machine_power_off(void) |
| 38 | { | 39 | { |
| 39 | if (pm_power_off) | 40 | if (pm_power_off) |
| 40 | pm_power_off(); | 41 | pm_power_off(); |
| 41 | |||
| 42 | _machine_power_off(); | ||
| 43 | } | 42 | } |
| 44 | |||
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index 1d855112bac2..986a9cf23067 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c | |||
| @@ -1,5 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved. | 2 | * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved. |
| 3 | * Copyright (C) 2005, 06 Ralf Baechle (ralf@linux-mips.org) | ||
| 3 | * | 4 | * |
| 4 | * This program is free software; you can distribute it and/or modify it | 5 | * This program is free software; you can distribute it and/or modify it |
| 5 | * under the terms of the GNU General Public License (Version 2) as | 6 | * under the terms of the GNU General Public License (Version 2) as |
| @@ -20,9 +21,12 @@ | |||
| 20 | #include <linux/module.h> | 21 | #include <linux/module.h> |
| 21 | #include <linux/fs.h> | 22 | #include <linux/fs.h> |
| 22 | #include <linux/init.h> | 23 | #include <linux/init.h> |
| 24 | #include <linux/interrupt.h> | ||
| 25 | #include <linux/irq.h> | ||
| 23 | #include <linux/poll.h> | 26 | #include <linux/poll.h> |
| 24 | #include <linux/sched.h> | 27 | #include <linux/sched.h> |
| 25 | #include <linux/wait.h> | 28 | #include <linux/wait.h> |
| 29 | |||
| 26 | #include <asm/mipsmtregs.h> | 30 | #include <asm/mipsmtregs.h> |
| 27 | #include <asm/bitops.h> | 31 | #include <asm/bitops.h> |
| 28 | #include <asm/cpu.h> | 32 | #include <asm/cpu.h> |
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index a42e0e8caa7b..d7c4a38ed5ae 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S | |||
| @@ -617,6 +617,23 @@ einval: li v0, -EINVAL | |||
| 617 | sys sys_inotify_init 0 | 617 | sys sys_inotify_init 0 |
| 618 | sys sys_inotify_add_watch 3 /* 4285 */ | 618 | sys sys_inotify_add_watch 3 /* 4285 */ |
| 619 | sys sys_inotify_rm_watch 2 | 619 | sys sys_inotify_rm_watch 2 |
| 620 | sys sys_migrate_pages 4 | ||
| 621 | sys sys_openat 4 | ||
| 622 | sys sys_mkdirat 3 | ||
| 623 | sys sys_mknodat 4 /* 4290 */ | ||
| 624 | sys sys_fchownat 5 | ||
| 625 | sys sys_futimesat 3 | ||
| 626 | sys sys_newfstatat 4 | ||
| 627 | sys sys_unlinkat 3 | ||
| 628 | sys sys_renameat 4 /* 4295 */ | ||
| 629 | sys sys_linkat 4 | ||
| 630 | sys sys_symlinkat 3 | ||
| 631 | sys sys_readlinkat 4 | ||
| 632 | sys sys_fchmodat 3 | ||
| 633 | sys sys_faccessat 3 /* 4300 */ | ||
| 634 | sys sys_pselect6 6 | ||
| 635 | sys sys_ppoll 5 | ||
| 636 | sys sys_unshare 1 | ||
| 620 | .endm | 637 | .endm |
| 621 | 638 | ||
| 622 | /* We pre-compute the number of _instruction_ bytes needed to | 639 | /* We pre-compute the number of _instruction_ bytes needed to |
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 47bfbd416709..98bf25df56f3 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S | |||
| @@ -443,3 +443,20 @@ sys_call_table: | |||
| 443 | PTR sys_inotify_init | 443 | PTR sys_inotify_init |
| 444 | PTR sys_inotify_add_watch | 444 | PTR sys_inotify_add_watch |
| 445 | PTR sys_inotify_rm_watch /* 5245 */ | 445 | PTR sys_inotify_rm_watch /* 5245 */ |
| 446 | PTR sys_migrate_pages | ||
| 447 | PTR sys_openat | ||
| 448 | PTR sys_mkdirat | ||
| 449 | PTR sys_mknodat | ||
| 450 | PTR sys_fchownat /* 5250 */ | ||
| 451 | PTR sys_futimesat | ||
| 452 | PTR sys_newfstatat | ||
| 453 | PTR sys_unlinkat | ||
| 454 | PTR sys_renameat | ||
| 455 | PTR sys_linkat /* 5255 */ | ||
| 456 | PTR sys_symlinkat | ||
| 457 | PTR sys_readlinkat | ||
| 458 | PTR sys_fchmodat | ||
| 459 | PTR sys_faccessat | ||
| 460 | PTR sys_pselect6 /* 5260 */ | ||
| 461 | PTR sys_ppoll | ||
| 462 | PTR sys_unshare | ||
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index b465ced1758f..bc4980cefc8b 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S | |||
| @@ -369,3 +369,20 @@ EXPORT(sysn32_call_table) | |||
| 369 | PTR sys_inotify_init | 369 | PTR sys_inotify_init |
| 370 | PTR sys_inotify_add_watch | 370 | PTR sys_inotify_add_watch |
| 371 | PTR sys_inotify_rm_watch | 371 | PTR sys_inotify_rm_watch |
| 372 | PTR sys_migrate_pages /* 6250 */ | ||
| 373 | PTR sys_openat | ||
| 374 | PTR sys_mkdirat | ||
| 375 | PTR sys_mknodat | ||
| 376 | PTR sys_fchownat | ||
| 377 | PTR sys_futimesat /* 6255 */ | ||
| 378 | PTR sys_newfstatat | ||
| 379 | PTR sys_unlinkat | ||
| 380 | PTR sys_renameat | ||
| 381 | PTR sys_linkat | ||
| 382 | PTR sys_symlinkat /* 6260 */ | ||
| 383 | PTR sys_readlinkat | ||
| 384 | PTR sys_fchmodat | ||
| 385 | PTR sys_faccessat | ||
| 386 | PTR sys_pselect6 | ||
| 387 | PTR sys_ppoll /* 6265 */ | ||
| 388 | PTR sys_unshare | ||
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 3d338ca7eeeb..5b0414018c9a 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S | |||
| @@ -491,4 +491,21 @@ sys_call_table: | |||
| 491 | PTR sys_inotify_init | 491 | PTR sys_inotify_init |
| 492 | PTR sys_inotify_add_watch /* 4285 */ | 492 | PTR sys_inotify_add_watch /* 4285 */ |
| 493 | PTR sys_inotify_rm_watch | 493 | PTR sys_inotify_rm_watch |
| 494 | PTR sys_migrate_pages | ||
| 495 | PTR compat_sys_openat | ||
| 496 | PTR sys_mkdirat | ||
| 497 | PTR sys_mknodat /* 4290 */ | ||
| 498 | PTR sys_fchownat | ||
| 499 | PTR compat_sys_futimesat | ||
| 500 | PTR compat_sys_newfstatat | ||
| 501 | PTR sys_unlinkat | ||
| 502 | PTR sys_renameat /* 4295 */ | ||
| 503 | PTR sys_linkat | ||
| 504 | PTR sys_symlinkat | ||
| 505 | PTR sys_readlinkat | ||
| 506 | PTR sys_fchmodat | ||
| 507 | PTR sys_faccessat /* 4300 */ | ||
| 508 | PTR sys_pselect6 | ||
| 509 | PTR sys_ppoll | ||
| 510 | PTR sys_unshare | ||
| 494 | .size sys_call_table,.-sys_call_table | 511 | .size sys_call_table,.-sys_call_table |
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h index 0f66ae5838b9..0fbc492d24b4 100644 --- a/arch/mips/kernel/signal-common.h +++ b/arch/mips/kernel/signal-common.h | |||
| @@ -11,7 +11,7 @@ | |||
| 11 | #include <linux/config.h> | 11 | #include <linux/config.h> |
| 12 | 12 | ||
| 13 | static inline int | 13 | static inline int |
| 14 | setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) | 14 | setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) |
| 15 | { | 15 | { |
| 16 | int err = 0; | 16 | int err = 0; |
| 17 | 17 | ||
| @@ -82,7 +82,7 @@ out: | |||
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | static inline int | 84 | static inline int |
| 85 | restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) | 85 | restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) |
| 86 | { | 86 | { |
| 87 | unsigned int used_math; | 87 | unsigned int used_math; |
| 88 | unsigned long treg; | 88 | unsigned long treg; |
| @@ -157,7 +157,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) | |||
| 157 | /* | 157 | /* |
| 158 | * Determine which stack to use.. | 158 | * Determine which stack to use.. |
| 159 | */ | 159 | */ |
| 160 | static inline void * | 160 | static inline void __user * |
| 161 | get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) | 161 | get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) |
| 162 | { | 162 | { |
| 163 | unsigned long sp; | 163 | unsigned long sp; |
| @@ -176,7 +176,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) | |||
| 176 | if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0)) | 176 | if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0)) |
| 177 | sp = current->sas_ss_sp + current->sas_ss_size; | 177 | sp = current->sas_ss_sp + current->sas_ss_size; |
| 178 | 178 | ||
| 179 | return (void *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? 32 : ALMASK)); | 179 | return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? 32 : ALMASK)); |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | static inline int install_sigtramp(unsigned int __user *tramp, | 182 | static inline int install_sigtramp(unsigned int __user *tramp, |
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 7d1800fe7038..c974cc9b30eb 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c | |||
| @@ -39,8 +39,6 @@ | |||
| 39 | 39 | ||
| 40 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | 40 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) |
| 41 | 41 | ||
| 42 | int do_signal(sigset_t *oldset, struct pt_regs *regs); | ||
| 43 | |||
| 44 | /* | 42 | /* |
| 45 | * Atomically swap in the new signal mask, and wait for a signal. | 43 | * Atomically swap in the new signal mask, and wait for a signal. |
| 46 | */ | 44 | */ |
| @@ -50,7 +48,7 @@ save_static_function(sys_sigsuspend); | |||
| 50 | __attribute_used__ noinline static int | 48 | __attribute_used__ noinline static int |
| 51 | _sys_sigsuspend(nabi_no_regargs struct pt_regs regs) | 49 | _sys_sigsuspend(nabi_no_regargs struct pt_regs regs) |
| 52 | { | 50 | { |
| 53 | sigset_t saveset, newset; | 51 | sigset_t newset; |
| 54 | sigset_t __user *uset; | 52 | sigset_t __user *uset; |
| 55 | 53 | ||
| 56 | uset = (sigset_t __user *) regs.regs[4]; | 54 | uset = (sigset_t __user *) regs.regs[4]; |
| @@ -59,19 +57,15 @@ _sys_sigsuspend(nabi_no_regargs struct pt_regs regs) | |||
| 59 | sigdelsetmask(&newset, ~_BLOCKABLE); | 57 | sigdelsetmask(&newset, ~_BLOCKABLE); |
| 60 | 58 | ||
| 61 | spin_lock_irq(¤t->sighand->siglock); | 59 | spin_lock_irq(¤t->sighand->siglock); |
| 62 | saveset = current->blocked; | 60 | current->saved_sigmask = current->blocked; |
| 63 | current->blocked = newset; | 61 | current->blocked = newset; |
| 64 | recalc_sigpending(); | 62 | recalc_sigpending(); |
| 65 | spin_unlock_irq(¤t->sighand->siglock); | 63 | spin_unlock_irq(¤t->sighand->siglock); |
| 66 | 64 | ||
| 67 | regs.regs[2] = EINTR; | 65 | current->state = TASK_INTERRUPTIBLE; |
| 68 | regs.regs[7] = 1; | 66 | schedule(); |
| 69 | while (1) { | 67 | set_thread_flag(TIF_RESTORE_SIGMASK); |
| 70 | current->state = TASK_INTERRUPTIBLE; | 68 | return -ERESTARTNOHAND; |
| 71 | schedule(); | ||
| 72 | if (do_signal(&saveset, ®s)) | ||
| 73 | return -EINTR; | ||
| 74 | } | ||
| 75 | } | 69 | } |
| 76 | #endif | 70 | #endif |
| 77 | 71 | ||
| @@ -79,7 +73,7 @@ save_static_function(sys_rt_sigsuspend); | |||
| 79 | __attribute_used__ noinline static int | 73 | __attribute_used__ noinline static int |
| 80 | _sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) | 74 | _sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) |
| 81 | { | 75 | { |
| 82 | sigset_t saveset, newset; | 76 | sigset_t newset; |
| 83 | sigset_t __user *unewset; | 77 | sigset_t __user *unewset; |
| 84 | size_t sigsetsize; | 78 | size_t sigsetsize; |
| 85 | 79 | ||
| @@ -94,19 +88,15 @@ _sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) | |||
| 94 | sigdelsetmask(&newset, ~_BLOCKABLE); | 88 | sigdelsetmask(&newset, ~_BLOCKABLE); |
| 95 | 89 | ||
| 96 | spin_lock_irq(¤t->sighand->siglock); | 90 | spin_lock_irq(¤t->sighand->siglock); |
| 97 | saveset = current->blocked; | 91 | current->saved_sigmask = current->blocked; |
| 98 | current->blocked = newset; | 92 | current->blocked = newset; |
| 99 | recalc_sigpending(); | 93 | recalc_sigpending(); |
| 100 | spin_unlock_irq(¤t->sighand->siglock); | 94 | spin_unlock_irq(¤t->sighand->siglock); |
| 101 | 95 | ||
| 102 | regs.regs[2] = EINTR; | 96 | current->state = TASK_INTERRUPTIBLE; |
| 103 | regs.regs[7] = 1; | 97 | schedule(); |
| 104 | while (1) { | 98 | set_thread_flag(TIF_RESTORE_SIGMASK); |
| 105 | current->state = TASK_INTERRUPTIBLE; | 99 | return -ERESTARTNOHAND; |
| 106 | schedule(); | ||
| 107 | if (do_signal(&saveset, ®s)) | ||
| 108 | return -EINTR; | ||
| 109 | } | ||
| 110 | } | 100 | } |
| 111 | 101 | ||
| 112 | #ifdef CONFIG_TRAD_SIGNALS | 102 | #ifdef CONFIG_TRAD_SIGNALS |
| @@ -199,10 +189,10 @@ save_static_function(sys_sigreturn); | |||
| 199 | __attribute_used__ noinline static void | 189 | __attribute_used__ noinline static void |
| 200 | _sys_sigreturn(nabi_no_regargs struct pt_regs regs) | 190 | _sys_sigreturn(nabi_no_regargs struct pt_regs regs) |
| 201 | { | 191 | { |
| 202 | struct sigframe *frame; | 192 | struct sigframe __user *frame; |
| 203 | sigset_t blocked; | 193 | sigset_t blocked; |
| 204 | 194 | ||
| 205 | frame = (struct sigframe *) regs.regs[29]; | 195 | frame = (struct sigframe __user *) regs.regs[29]; |
| 206 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | 196 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) |
| 207 | goto badframe; | 197 | goto badframe; |
| 208 | if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked))) | 198 | if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked))) |
| @@ -236,11 +226,11 @@ save_static_function(sys_rt_sigreturn); | |||
| 236 | __attribute_used__ noinline static void | 226 | __attribute_used__ noinline static void |
| 237 | _sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs) | 227 | _sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs) |
| 238 | { | 228 | { |
| 239 | struct rt_sigframe *frame; | 229 | struct rt_sigframe __user *frame; |
| 240 | sigset_t set; | 230 | sigset_t set; |
| 241 | stack_t st; | 231 | stack_t st; |
| 242 | 232 | ||
| 243 | frame = (struct rt_sigframe *) regs.regs[29]; | 233 | frame = (struct rt_sigframe __user *) regs.regs[29]; |
| 244 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | 234 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) |
| 245 | goto badframe; | 235 | goto badframe; |
| 246 | if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set))) | 236 | if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set))) |
| @@ -259,7 +249,7 @@ _sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs) | |||
| 259 | goto badframe; | 249 | goto badframe; |
| 260 | /* It is more difficult to avoid calling this function than to | 250 | /* It is more difficult to avoid calling this function than to |
| 261 | call it and ignore errors. */ | 251 | call it and ignore errors. */ |
| 262 | do_sigaltstack(&st, NULL, regs.regs[29]); | 252 | do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]); |
| 263 | 253 | ||
| 264 | /* | 254 | /* |
| 265 | * Don't let your children do this ... | 255 | * Don't let your children do this ... |
| @@ -279,7 +269,7 @@ badframe: | |||
| 279 | int setup_frame(struct k_sigaction * ka, struct pt_regs *regs, | 269 | int setup_frame(struct k_sigaction * ka, struct pt_regs *regs, |
| 280 | int signr, sigset_t *set) | 270 | int signr, sigset_t *set) |
| 281 | { | 271 | { |
| 282 | struct sigframe *frame; | 272 | struct sigframe __user *frame; |
| 283 | int err = 0; | 273 | int err = 0; |
| 284 | 274 | ||
| 285 | frame = get_sigframe(ka, regs, sizeof(*frame)); | 275 | frame = get_sigframe(ka, regs, sizeof(*frame)); |
| @@ -315,18 +305,18 @@ int setup_frame(struct k_sigaction * ka, struct pt_regs *regs, | |||
| 315 | current->comm, current->pid, | 305 | current->comm, current->pid, |
| 316 | frame, regs->cp0_epc, frame->regs[31]); | 306 | frame, regs->cp0_epc, frame->regs[31]); |
| 317 | #endif | 307 | #endif |
| 318 | return 1; | 308 | return 0; |
| 319 | 309 | ||
| 320 | give_sigsegv: | 310 | give_sigsegv: |
| 321 | force_sigsegv(signr, current); | 311 | force_sigsegv(signr, current); |
| 322 | return 0; | 312 | return -EFAULT; |
| 323 | } | 313 | } |
| 324 | #endif | 314 | #endif |
| 325 | 315 | ||
| 326 | int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, | 316 | int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, |
| 327 | int signr, sigset_t *set, siginfo_t *info) | 317 | int signr, sigset_t *set, siginfo_t *info) |
| 328 | { | 318 | { |
| 329 | struct rt_sigframe *frame; | 319 | struct rt_sigframe __user *frame; |
| 330 | int err = 0; | 320 | int err = 0; |
| 331 | 321 | ||
| 332 | frame = get_sigframe(ka, regs, sizeof(*frame)); | 322 | frame = get_sigframe(ka, regs, sizeof(*frame)); |
| @@ -340,7 +330,7 @@ int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, | |||
| 340 | 330 | ||
| 341 | /* Create the ucontext. */ | 331 | /* Create the ucontext. */ |
| 342 | err |= __put_user(0, &frame->rs_uc.uc_flags); | 332 | err |= __put_user(0, &frame->rs_uc.uc_flags); |
| 343 | err |= __put_user(0, &frame->rs_uc.uc_link); | 333 | err |= __put_user(NULL, &frame->rs_uc.uc_link); |
| 344 | err |= __put_user((void *)current->sas_ss_sp, | 334 | err |= __put_user((void *)current->sas_ss_sp, |
| 345 | &frame->rs_uc.uc_stack.ss_sp); | 335 | &frame->rs_uc.uc_stack.ss_sp); |
| 346 | err |= __put_user(sas_ss_flags(regs->regs[29]), | 336 | err |= __put_user(sas_ss_flags(regs->regs[29]), |
| @@ -375,11 +365,11 @@ int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs, | |||
| 375 | current->comm, current->pid, | 365 | current->comm, current->pid, |
| 376 | frame, regs->cp0_epc, regs->regs[31]); | 366 | frame, regs->cp0_epc, regs->regs[31]); |
| 377 | #endif | 367 | #endif |
| 378 | return 1; | 368 | return 0; |
| 379 | 369 | ||
| 380 | give_sigsegv: | 370 | give_sigsegv: |
| 381 | force_sigsegv(signr, current); | 371 | force_sigsegv(signr, current); |
| 382 | return 0; | 372 | return -EFAULT; |
| 383 | } | 373 | } |
| 384 | 374 | ||
| 385 | static inline int handle_signal(unsigned long sig, siginfo_t *info, | 375 | static inline int handle_signal(unsigned long sig, siginfo_t *info, |
| @@ -393,7 +383,7 @@ static inline int handle_signal(unsigned long sig, siginfo_t *info, | |||
| 393 | regs->regs[2] = EINTR; | 383 | regs->regs[2] = EINTR; |
| 394 | break; | 384 | break; |
| 395 | case ERESTARTSYS: | 385 | case ERESTARTSYS: |
| 396 | if(!(ka->sa.sa_flags & SA_RESTART)) { | 386 | if (!(ka->sa.sa_flags & SA_RESTART)) { |
| 397 | regs->regs[2] = EINTR; | 387 | regs->regs[2] = EINTR; |
| 398 | break; | 388 | break; |
| 399 | } | 389 | } |
| @@ -420,9 +410,10 @@ static inline int handle_signal(unsigned long sig, siginfo_t *info, | |||
| 420 | return ret; | 410 | return ret; |
| 421 | } | 411 | } |
| 422 | 412 | ||
| 423 | int do_signal(sigset_t *oldset, struct pt_regs *regs) | 413 | void do_signal(struct pt_regs *regs) |
| 424 | { | 414 | { |
| 425 | struct k_sigaction ka; | 415 | struct k_sigaction ka; |
| 416 | sigset_t *oldset; | ||
| 426 | siginfo_t info; | 417 | siginfo_t info; |
| 427 | int signr; | 418 | int signr; |
| 428 | 419 | ||
| @@ -432,17 +423,31 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) | |||
| 432 | * if so. | 423 | * if so. |
| 433 | */ | 424 | */ |
| 434 | if (!user_mode(regs)) | 425 | if (!user_mode(regs)) |
| 435 | return 1; | 426 | return; |
| 436 | 427 | ||
| 437 | if (try_to_freeze()) | 428 | if (try_to_freeze()) |
| 438 | goto no_signal; | 429 | goto no_signal; |
| 439 | 430 | ||
| 440 | if (!oldset) | 431 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
| 432 | oldset = ¤t->saved_sigmask; | ||
| 433 | else | ||
| 441 | oldset = ¤t->blocked; | 434 | oldset = ¤t->blocked; |
| 442 | 435 | ||
| 436 | |||
| 443 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 437 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
| 444 | if (signr > 0) | 438 | if (signr > 0) { |
| 445 | return handle_signal(signr, &info, &ka, oldset, regs); | 439 | /* Whee! Actually deliver the signal. */ |
| 440 | if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { | ||
| 441 | /* | ||
| 442 | * A signal was successfully delivered; the saved | ||
| 443 | * sigmask will have been stored in the signal frame, | ||
| 444 | * and will be restored by sigreturn, so we can simply | ||
| 445 | * clear the TIF_RESTORE_SIGMASK flag. | ||
| 446 | */ | ||
| 447 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) | ||
| 448 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
| 449 | } | ||
| 450 | } | ||
| 446 | 451 | ||
| 447 | no_signal: | 452 | no_signal: |
| 448 | /* | 453 | /* |
| @@ -463,18 +468,25 @@ no_signal: | |||
| 463 | regs->cp0_epc -= 4; | 468 | regs->cp0_epc -= 4; |
| 464 | } | 469 | } |
| 465 | } | 470 | } |
| 466 | return 0; | 471 | |
| 472 | /* | ||
| 473 | * If there's no signal to deliver, we just put the saved sigmask | ||
| 474 | * back | ||
| 475 | */ | ||
| 476 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) { | ||
| 477 | clear_thread_flag(TIF_RESTORE_SIGMASK); | ||
| 478 | sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); | ||
| 479 | } | ||
| 467 | } | 480 | } |
| 468 | 481 | ||
| 469 | /* | 482 | /* |
| 470 | * notification of userspace execution resumption | 483 | * notification of userspace execution resumption |
| 471 | * - triggered by current->work.notify_resume | 484 | * - triggered by the TIF_WORK_MASK flags |
| 472 | */ | 485 | */ |
| 473 | asmlinkage void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, | 486 | asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused, |
| 474 | __u32 thread_info_flags) | 487 | __u32 thread_info_flags) |
| 475 | { | 488 | { |
| 476 | /* deal with pending signal delivery */ | 489 | /* deal with pending signal delivery */ |
| 477 | if (thread_info_flags & _TIF_SIGPENDING) { | 490 | if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) |
| 478 | current->thread.abi->do_signal(oldset, regs); | 491 | current->thread.abi->do_signal(regs); |
| 479 | } | ||
| 480 | } | 492 | } |
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index 98b185bbc947..da3271e1fdac 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c | |||
| @@ -144,7 +144,7 @@ struct ucontext32 { | |||
| 144 | extern void __put_sigset_unknown_nsig(void); | 144 | extern void __put_sigset_unknown_nsig(void); |
| 145 | extern void __get_sigset_unknown_nsig(void); | 145 | extern void __get_sigset_unknown_nsig(void); |
| 146 | 146 | ||
| 147 | static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t *ubuf) | 147 | static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t __user *ubuf) |
| 148 | { | 148 | { |
| 149 | int err = 0; | 149 | int err = 0; |
| 150 | 150 | ||
| @@ -269,7 +269,7 @@ asmlinkage int sys32_sigaction(int sig, const struct sigaction32 *act, | |||
| 269 | if (!access_ok(VERIFY_READ, act, sizeof(*act))) | 269 | if (!access_ok(VERIFY_READ, act, sizeof(*act))) |
| 270 | return -EFAULT; | 270 | return -EFAULT; |
| 271 | err |= __get_user(handler, &act->sa_handler); | 271 | err |= __get_user(handler, &act->sa_handler); |
| 272 | new_ka.sa.sa_handler = (void*)(s64)handler; | 272 | new_ka.sa.sa_handler = (void __user *)(s64)handler; |
| 273 | err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); | 273 | err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); |
| 274 | err |= __get_user(mask, &act->sa_mask.sig[0]); | 274 | err |= __get_user(mask, &act->sa_mask.sig[0]); |
| 275 | if (err) | 275 | if (err) |
| @@ -299,8 +299,8 @@ asmlinkage int sys32_sigaction(int sig, const struct sigaction32 *act, | |||
| 299 | 299 | ||
| 300 | asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs) | 300 | asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs) |
| 301 | { | 301 | { |
| 302 | const stack32_t *uss = (const stack32_t *) regs.regs[4]; | 302 | const stack32_t __user *uss = (const stack32_t __user *) regs.regs[4]; |
| 303 | stack32_t *uoss = (stack32_t *) regs.regs[5]; | 303 | stack32_t __user *uoss = (stack32_t __user *) regs.regs[5]; |
| 304 | unsigned long usp = regs.regs[29]; | 304 | unsigned long usp = regs.regs[29]; |
| 305 | stack_t kss, koss; | 305 | stack_t kss, koss; |
| 306 | int ret, err = 0; | 306 | int ret, err = 0; |
| @@ -319,7 +319,8 @@ asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs) | |||
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | set_fs (KERNEL_DS); | 321 | set_fs (KERNEL_DS); |
| 322 | ret = do_sigaltstack(uss ? &kss : NULL , uoss ? &koss : NULL, usp); | 322 | ret = do_sigaltstack(uss ? (stack_t __user *)&kss : NULL, |
| 323 | uoss ? (stack_t __user *)&koss : NULL, usp); | ||
| 323 | set_fs (old_fs); | 324 | set_fs (old_fs); |
| 324 | 325 | ||
| 325 | if (!ret && uoss) { | 326 | if (!ret && uoss) { |
| @@ -335,7 +336,7 @@ asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs) | |||
| 335 | return ret; | 336 | return ret; |
| 336 | } | 337 | } |
| 337 | 338 | ||
| 338 | static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc) | 339 | static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 __user *sc) |
| 339 | { | 340 | { |
| 340 | u32 used_math; | 341 | u32 used_math; |
| 341 | int err = 0; | 342 | int err = 0; |
| @@ -420,7 +421,7 @@ struct rt_sigframe32 { | |||
| 420 | #endif | 421 | #endif |
| 421 | }; | 422 | }; |
| 422 | 423 | ||
| 423 | int copy_siginfo_to_user32(compat_siginfo_t *to, siginfo_t *from) | 424 | int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) |
| 424 | { | 425 | { |
| 425 | int err; | 426 | int err; |
| 426 | 427 | ||
| @@ -455,7 +456,7 @@ int copy_siginfo_to_user32(compat_siginfo_t *to, siginfo_t *from) | |||
| 455 | err |= __put_user(from->si_uid, &to->si_uid); | 456 | err |= __put_user(from->si_uid, &to->si_uid); |
| 456 | break; | 457 | break; |
| 457 | case __SI_FAULT >> 16: | 458 | case __SI_FAULT >> 16: |
| 458 | err |= __put_user((long)from->si_addr, &to->si_addr); | 459 | err |= __put_user((unsigned long)from->si_addr, &to->si_addr); |
| 459 | break; | 460 | break; |
| 460 | case __SI_POLL >> 16: | 461 | case __SI_POLL >> 16: |
| 461 | err |= __put_user(from->si_band, &to->si_band); | 462 | err |= __put_user(from->si_band, &to->si_band); |
| @@ -476,10 +477,10 @@ save_static_function(sys32_sigreturn); | |||
| 476 | __attribute_used__ noinline static void | 477 | __attribute_used__ noinline static void |
| 477 | _sys32_sigreturn(nabi_no_regargs struct pt_regs regs) | 478 | _sys32_sigreturn(nabi_no_regargs struct pt_regs regs) |
| 478 | { | 479 | { |
| 479 | struct sigframe *frame; | 480 | struct sigframe __user *frame; |
| 480 | sigset_t blocked; | 481 | sigset_t blocked; |
| 481 | 482 | ||
| 482 | frame = (struct sigframe *) regs.regs[29]; | 483 | frame = (struct sigframe __user *) regs.regs[29]; |
| 483 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | 484 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) |
| 484 | goto badframe; | 485 | goto badframe; |
| 485 | if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked))) | 486 | if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked))) |
| @@ -512,13 +513,13 @@ save_static_function(sys32_rt_sigreturn); | |||
| 512 | __attribute_used__ noinline static void | 513 | __attribute_used__ noinline static void |
| 513 | _sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) | 514 | _sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) |
| 514 | { | 515 | { |
| 515 | struct rt_sigframe32 *frame; | 516 | struct rt_sigframe32 __user *frame; |
| 516 | mm_segment_t old_fs; | 517 | mm_segment_t old_fs; |
| 517 | sigset_t set; | 518 | sigset_t set; |
| 518 | stack_t st; | 519 | stack_t st; |
| 519 | s32 sp; | 520 | s32 sp; |
| 520 | 521 | ||
| 521 | frame = (struct rt_sigframe32 *) regs.regs[29]; | 522 | frame = (struct rt_sigframe32 __user *) regs.regs[29]; |
| 522 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | 523 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) |
| 523 | goto badframe; | 524 | goto badframe; |
| 524 | if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set))) | 525 | if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set))) |
| @@ -546,7 +547,7 @@ _sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) | |||
| 546 | call it and ignore errors. */ | 547 | call it and ignore errors. */ |
| 547 | old_fs = get_fs(); | 548 | old_fs = get_fs(); |
| 548 | set_fs (KERNEL_DS); | 549 | set_fs (KERNEL_DS); |
| 549 | do_sigaltstack(&st, NULL, regs.regs[29]); | 550 | do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]); |
| 550 | set_fs (old_fs); | 551 | set_fs (old_fs); |
| 551 | 552 | ||
| 552 | /* | 553 | /* |
| @@ -564,7 +565,7 @@ badframe: | |||
| 564 | } | 565 | } |
| 565 | 566 | ||
| 566 | static inline int setup_sigcontext32(struct pt_regs *regs, | 567 | static inline int setup_sigcontext32(struct pt_regs *regs, |
| 567 | struct sigcontext32 *sc) | 568 | struct sigcontext32 __user *sc) |
| 568 | { | 569 | { |
| 569 | int err = 0; | 570 | int err = 0; |
| 570 | 571 | ||
| @@ -623,8 +624,9 @@ out: | |||
| 623 | /* | 624 | /* |
| 624 | * Determine which stack to use.. | 625 | * Determine which stack to use.. |
| 625 | */ | 626 | */ |
| 626 | static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, | 627 | static inline void __user *get_sigframe(struct k_sigaction *ka, |
| 627 | size_t frame_size) | 628 | struct pt_regs *regs, |
| 629 | size_t frame_size) | ||
| 628 | { | 630 | { |
| 629 | unsigned long sp; | 631 | unsigned long sp; |
| 630 | 632 | ||
| @@ -642,13 +644,13 @@ static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, | |||
| 642 | if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0)) | 644 | if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0)) |
| 643 | sp = current->sas_ss_sp + current->sas_ss_size; | 645 | sp = current->sas_ss_sp + current->sas_ss_size; |
| 644 | 646 | ||
| 645 | return (void *)((sp - frame_size) & ALMASK); | 647 | return (void __user *)((sp - frame_size) & ALMASK); |
| 646 | } | 648 | } |
| 647 | 649 | ||
| 648 | int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, | 650 | int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, |
| 649 | int signr, sigset_t *set) | 651 | int signr, sigset_t *set) |
| 650 | { | 652 | { |
| 651 | struct sigframe *frame; | 653 | struct sigframe __user *frame; |
| 652 | int err = 0; | 654 | int err = 0; |
| 653 | 655 | ||
| 654 | frame = get_sigframe(ka, regs, sizeof(*frame)); | 656 | frame = get_sigframe(ka, regs, sizeof(*frame)); |
| @@ -692,17 +694,17 @@ int setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, | |||
| 692 | current->comm, current->pid, | 694 | current->comm, current->pid, |
| 693 | frame, regs->cp0_epc, frame->sf_code); | 695 | frame, regs->cp0_epc, frame->sf_code); |
| 694 | #endif | 696 | #endif |
| 695 | return 1; | 697 | return 0; |
| 696 | 698 | ||
| 697 | give_sigsegv: | 699 | give_sigsegv: |
| 698 | force_sigsegv(signr, current); | 700 | force_sigsegv(signr, current); |
| 699 | return 0; | 701 | return -EFAULT; |
| 700 | } | 702 | } |
| 701 | 703 | ||
| 702 | int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, | 704 | int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, |
| 703 | int signr, sigset_t *set, siginfo_t *info) | 705 | int signr, sigset_t *set, siginfo_t *info) |
| 704 | { | 706 | { |
| 705 | struct rt_sigframe32 *frame; | 707 | struct rt_sigframe32 __user *frame; |
| 706 | int err = 0; | 708 | int err = 0; |
| 707 | s32 sp; | 709 | s32 sp; |
| 708 | 710 | ||
| @@ -763,11 +765,11 @@ int setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, | |||
| 763 | current->comm, current->pid, | 765 | current->comm, current->pid, |
| 764 | frame, regs->cp0_epc, frame->rs_code); | 766 | frame, regs->cp0_epc, frame->rs_code); |
| 765 | #endif | 767 | #endif |
| 766 | return 1; | 768 | return 0; |
| 767 | 769 | ||
| 768 | give_sigsegv: | 770 | give_sigsegv: |
| 769 | force_sigsegv(signr, current); | 771 | force_sigsegv(signr, current); |
| 770 | return 0; | 772 | return -EFAULT; |
| 771 | } | 773 | } |
| 772 | 774 | ||
| 773 | static inline int handle_signal(unsigned long sig, siginfo_t *info, | 775 | static inline int handle_signal(unsigned long sig, siginfo_t *info, |
| @@ -855,7 +857,7 @@ no_signal: | |||
| 855 | } | 857 | } |
| 856 | 858 | ||
| 857 | asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 *act, | 859 | asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 *act, |
| 858 | struct sigaction32 *oact, | 860 | struct sigaction32 __user *oact, |
| 859 | unsigned int sigsetsize) | 861 | unsigned int sigsetsize) |
| 860 | { | 862 | { |
| 861 | struct k_sigaction new_sa, old_sa; | 863 | struct k_sigaction new_sa, old_sa; |
| @@ -872,7 +874,7 @@ asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 *act, | |||
| 872 | if (!access_ok(VERIFY_READ, act, sizeof(*act))) | 874 | if (!access_ok(VERIFY_READ, act, sizeof(*act))) |
| 873 | return -EFAULT; | 875 | return -EFAULT; |
| 874 | err |= __get_user(handler, &act->sa_handler); | 876 | err |= __get_user(handler, &act->sa_handler); |
| 875 | new_sa.sa.sa_handler = (void*)(s64)handler; | 877 | new_sa.sa.sa_handler = (void __user *)(s64)handler; |
| 876 | err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags); | 878 | err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags); |
| 877 | err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask); | 879 | err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask); |
| 878 | if (err) | 880 | if (err) |
| @@ -899,7 +901,7 @@ out: | |||
| 899 | } | 901 | } |
| 900 | 902 | ||
| 901 | asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t *set, | 903 | asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t *set, |
| 902 | compat_sigset_t *oset, unsigned int sigsetsize) | 904 | compat_sigset_t __user *oset, unsigned int sigsetsize) |
| 903 | { | 905 | { |
| 904 | sigset_t old_set, new_set; | 906 | sigset_t old_set, new_set; |
| 905 | int ret; | 907 | int ret; |
| @@ -909,8 +911,9 @@ asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t *set, | |||
| 909 | return -EFAULT; | 911 | return -EFAULT; |
| 910 | 912 | ||
| 911 | set_fs (KERNEL_DS); | 913 | set_fs (KERNEL_DS); |
| 912 | ret = sys_rt_sigprocmask(how, set ? &new_set : NULL, | 914 | ret = sys_rt_sigprocmask(how, set ? (sigset_t __user *)&new_set : NULL, |
| 913 | oset ? &old_set : NULL, sigsetsize); | 915 | oset ? (sigset_t __user *)&old_set : NULL, |
| 916 | sigsetsize); | ||
| 914 | set_fs (old_fs); | 917 | set_fs (old_fs); |
| 915 | 918 | ||
| 916 | if (!ret && oset && put_sigset(&old_set, oset)) | 919 | if (!ret && oset && put_sigset(&old_set, oset)) |
| @@ -919,7 +922,7 @@ asmlinkage int sys32_rt_sigprocmask(int how, compat_sigset_t *set, | |||
| 919 | return ret; | 922 | return ret; |
| 920 | } | 923 | } |
| 921 | 924 | ||
| 922 | asmlinkage int sys32_rt_sigpending(compat_sigset_t *uset, | 925 | asmlinkage int sys32_rt_sigpending(compat_sigset_t __user *uset, |
| 923 | unsigned int sigsetsize) | 926 | unsigned int sigsetsize) |
| 924 | { | 927 | { |
| 925 | int ret; | 928 | int ret; |
| @@ -927,7 +930,7 @@ asmlinkage int sys32_rt_sigpending(compat_sigset_t *uset, | |||
| 927 | mm_segment_t old_fs = get_fs(); | 930 | mm_segment_t old_fs = get_fs(); |
| 928 | 931 | ||
| 929 | set_fs (KERNEL_DS); | 932 | set_fs (KERNEL_DS); |
| 930 | ret = sys_rt_sigpending(&set, sigsetsize); | 933 | ret = sys_rt_sigpending((sigset_t __user *)&set, sigsetsize); |
| 931 | set_fs (old_fs); | 934 | set_fs (old_fs); |
| 932 | 935 | ||
| 933 | if (!ret && put_sigset(&set, uset)) | 936 | if (!ret && put_sigset(&set, uset)) |
| @@ -936,7 +939,7 @@ asmlinkage int sys32_rt_sigpending(compat_sigset_t *uset, | |||
| 936 | return ret; | 939 | return ret; |
| 937 | } | 940 | } |
| 938 | 941 | ||
| 939 | asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t *uinfo) | 942 | asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo) |
| 940 | { | 943 | { |
| 941 | siginfo_t info; | 944 | siginfo_t info; |
| 942 | int ret; | 945 | int ret; |
| @@ -946,7 +949,7 @@ asmlinkage int sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t *uinfo) | |||
| 946 | copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE)) | 949 | copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE)) |
| 947 | return -EFAULT; | 950 | return -EFAULT; |
| 948 | set_fs (KERNEL_DS); | 951 | set_fs (KERNEL_DS); |
| 949 | ret = sys_rt_sigqueueinfo(pid, sig, &info); | 952 | ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info); |
| 950 | set_fs (old_fs); | 953 | set_fs (old_fs); |
| 951 | return ret; | 954 | return ret; |
| 952 | } | 955 | } |
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c index ec61b2670ba6..384fc4a639a4 100644 --- a/arch/mips/kernel/signal_n32.c +++ b/arch/mips/kernel/signal_n32.c | |||
| @@ -48,6 +48,8 @@ | |||
| 48 | #define __NR_N32_rt_sigreturn 6211 | 48 | #define __NR_N32_rt_sigreturn 6211 |
| 49 | #define __NR_N32_restart_syscall 6214 | 49 | #define __NR_N32_restart_syscall 6214 |
| 50 | 50 | ||
| 51 | #define DEBUG_SIG 0 | ||
| 52 | |||
| 51 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | 53 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) |
| 52 | 54 | ||
| 53 | /* IRIX compatible stack_t */ | 55 | /* IRIX compatible stack_t */ |
| @@ -83,12 +85,12 @@ save_static_function(sysn32_rt_sigreturn); | |||
| 83 | __attribute_used__ noinline static void | 85 | __attribute_used__ noinline static void |
| 84 | _sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) | 86 | _sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) |
| 85 | { | 87 | { |
| 86 | struct rt_sigframe_n32 *frame; | 88 | struct rt_sigframe_n32 __user *frame; |
| 87 | sigset_t set; | 89 | sigset_t set; |
| 88 | stack_t st; | 90 | stack_t st; |
| 89 | s32 sp; | 91 | s32 sp; |
| 90 | 92 | ||
| 91 | frame = (struct rt_sigframe_n32 *) regs.regs[29]; | 93 | frame = (struct rt_sigframe_n32 __user *) regs.regs[29]; |
| 92 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | 94 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) |
| 93 | goto badframe; | 95 | goto badframe; |
| 94 | if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set))) | 96 | if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set))) |
| @@ -114,7 +116,7 @@ _sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) | |||
| 114 | 116 | ||
| 115 | /* It is more difficult to avoid calling this function than to | 117 | /* It is more difficult to avoid calling this function than to |
| 116 | call it and ignore errors. */ | 118 | call it and ignore errors. */ |
| 117 | do_sigaltstack(&st, NULL, regs.regs[29]); | 119 | do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]); |
| 118 | 120 | ||
| 119 | /* | 121 | /* |
| 120 | * Don't let your children do this ... | 122 | * Don't let your children do this ... |
| @@ -133,7 +135,7 @@ badframe: | |||
| 133 | int setup_rt_frame_n32(struct k_sigaction * ka, | 135 | int setup_rt_frame_n32(struct k_sigaction * ka, |
| 134 | struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) | 136 | struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) |
| 135 | { | 137 | { |
| 136 | struct rt_sigframe_n32 *frame; | 138 | struct rt_sigframe_n32 __user *frame; |
| 137 | int err = 0; | 139 | int err = 0; |
| 138 | s32 sp; | 140 | s32 sp; |
| 139 | 141 | ||
| @@ -184,9 +186,9 @@ int setup_rt_frame_n32(struct k_sigaction * ka, | |||
| 184 | current->comm, current->pid, | 186 | current->comm, current->pid, |
| 185 | frame, regs->cp0_epc, regs->regs[31]); | 187 | frame, regs->cp0_epc, regs->regs[31]); |
| 186 | #endif | 188 | #endif |
| 187 | return 1; | 189 | return 0; |
| 188 | 190 | ||
| 189 | give_sigsegv: | 191 | give_sigsegv: |
| 190 | force_sigsegv(signr, current); | 192 | force_sigsegv(signr, current); |
| 191 | return 0; | 193 | return -EFAULT; |
| 192 | } | 194 | } |
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 332358430ff5..1da2eeb3ef9e 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c | |||
| @@ -212,12 +212,12 @@ asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs) | |||
| 212 | int error; | 212 | int error; |
| 213 | char * filename; | 213 | char * filename; |
| 214 | 214 | ||
| 215 | filename = getname((char *) (long)regs.regs[4]); | 215 | filename = getname((char __user *) (long)regs.regs[4]); |
| 216 | error = PTR_ERR(filename); | 216 | error = PTR_ERR(filename); |
| 217 | if (IS_ERR(filename)) | 217 | if (IS_ERR(filename)) |
| 218 | goto out; | 218 | goto out; |
| 219 | error = do_execve(filename, (char **) (long)regs.regs[5], | 219 | error = do_execve(filename, (char __user *__user *) (long)regs.regs[5], |
| 220 | (char **) (long)regs.regs[6], ®s); | 220 | (char __user *__user *) (long)regs.regs[6], ®s); |
| 221 | putname(filename); | 221 | putname(filename); |
| 222 | 222 | ||
| 223 | out: | 223 | out: |
| @@ -227,7 +227,7 @@ out: | |||
| 227 | /* | 227 | /* |
| 228 | * Compacrapability ... | 228 | * Compacrapability ... |
| 229 | */ | 229 | */ |
| 230 | asmlinkage int sys_uname(struct old_utsname * name) | 230 | asmlinkage int sys_uname(struct old_utsname __user * name) |
| 231 | { | 231 | { |
| 232 | if (name && !copy_to_user(name, &system_utsname, sizeof (*name))) | 232 | if (name && !copy_to_user(name, &system_utsname, sizeof (*name))) |
| 233 | return 0; | 233 | return 0; |
| @@ -237,7 +237,7 @@ asmlinkage int sys_uname(struct old_utsname * name) | |||
| 237 | /* | 237 | /* |
| 238 | * Compacrapability ... | 238 | * Compacrapability ... |
| 239 | */ | 239 | */ |
| 240 | asmlinkage int sys_olduname(struct oldold_utsname * name) | 240 | asmlinkage int sys_olduname(struct oldold_utsname __user * name) |
| 241 | { | 241 | { |
| 242 | int error; | 242 | int error; |
| 243 | 243 | ||
| @@ -274,7 +274,7 @@ void sys_set_thread_area(unsigned long addr) | |||
| 274 | asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3) | 274 | asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3) |
| 275 | { | 275 | { |
| 276 | int tmp, len; | 276 | int tmp, len; |
| 277 | char *name; | 277 | char __user *name; |
| 278 | 278 | ||
| 279 | switch(cmd) { | 279 | switch(cmd) { |
| 280 | case SETNAME: { | 280 | case SETNAME: { |
| @@ -283,7 +283,7 @@ asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3) | |||
| 283 | if (!capable(CAP_SYS_ADMIN)) | 283 | if (!capable(CAP_SYS_ADMIN)) |
| 284 | return -EPERM; | 284 | return -EPERM; |
| 285 | 285 | ||
| 286 | name = (char *) arg1; | 286 | name = (char __user *) arg1; |
| 287 | 287 | ||
| 288 | len = strncpy_from_user(nodename, name, __NEW_UTS_LEN); | 288 | len = strncpy_from_user(nodename, name, __NEW_UTS_LEN); |
| 289 | if (len < 0) | 289 | if (len < 0) |
| @@ -324,7 +324,7 @@ asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3) | |||
| 324 | * This is really horribly ugly. | 324 | * This is really horribly ugly. |
| 325 | */ | 325 | */ |
| 326 | asmlinkage int sys_ipc (uint call, int first, int second, | 326 | asmlinkage int sys_ipc (uint call, int first, int second, |
| 327 | unsigned long third, void *ptr, long fifth) | 327 | unsigned long third, void __user *ptr, long fifth) |
| 328 | { | 328 | { |
| 329 | int version, ret; | 329 | int version, ret; |
| 330 | 330 | ||
| @@ -333,24 +333,25 @@ asmlinkage int sys_ipc (uint call, int first, int second, | |||
| 333 | 333 | ||
| 334 | switch (call) { | 334 | switch (call) { |
| 335 | case SEMOP: | 335 | case SEMOP: |
| 336 | return sys_semtimedop (first, (struct sembuf *)ptr, second, | 336 | return sys_semtimedop (first, (struct sembuf __user *)ptr, |
| 337 | NULL); | 337 | second, NULL); |
| 338 | case SEMTIMEDOP: | 338 | case SEMTIMEDOP: |
| 339 | return sys_semtimedop (first, (struct sembuf *)ptr, second, | 339 | return sys_semtimedop (first, (struct sembuf __user *)ptr, |
| 340 | (const struct timespec __user *)fifth); | 340 | second, |
| 341 | (const struct timespec __user *)fifth); | ||
| 341 | case SEMGET: | 342 | case SEMGET: |
| 342 | return sys_semget (first, second, third); | 343 | return sys_semget (first, second, third); |
| 343 | case SEMCTL: { | 344 | case SEMCTL: { |
| 344 | union semun fourth; | 345 | union semun fourth; |
| 345 | if (!ptr) | 346 | if (!ptr) |
| 346 | return -EINVAL; | 347 | return -EINVAL; |
| 347 | if (get_user(fourth.__pad, (void **) ptr)) | 348 | if (get_user(fourth.__pad, (void *__user *) ptr)) |
| 348 | return -EFAULT; | 349 | return -EFAULT; |
| 349 | return sys_semctl (first, second, third, fourth); | 350 | return sys_semctl (first, second, third, fourth); |
| 350 | } | 351 | } |
| 351 | 352 | ||
| 352 | case MSGSND: | 353 | case MSGSND: |
| 353 | return sys_msgsnd (first, (struct msgbuf *) ptr, | 354 | return sys_msgsnd (first, (struct msgbuf __user *) ptr, |
| 354 | second, third); | 355 | second, third); |
| 355 | case MSGRCV: | 356 | case MSGRCV: |
| 356 | switch (version) { | 357 | switch (version) { |
| @@ -360,7 +361,7 @@ asmlinkage int sys_ipc (uint call, int first, int second, | |||
| 360 | return -EINVAL; | 361 | return -EINVAL; |
| 361 | 362 | ||
| 362 | if (copy_from_user(&tmp, | 363 | if (copy_from_user(&tmp, |
| 363 | (struct ipc_kludge *) ptr, | 364 | (struct ipc_kludge __user *) ptr, |
| 364 | sizeof (tmp))) | 365 | sizeof (tmp))) |
| 365 | return -EFAULT; | 366 | return -EFAULT; |
| 366 | return sys_msgrcv (first, tmp.msgp, second, | 367 | return sys_msgrcv (first, tmp.msgp, second, |
| @@ -368,35 +369,38 @@ asmlinkage int sys_ipc (uint call, int first, int second, | |||
| 368 | } | 369 | } |
| 369 | default: | 370 | default: |
| 370 | return sys_msgrcv (first, | 371 | return sys_msgrcv (first, |
| 371 | (struct msgbuf *) ptr, | 372 | (struct msgbuf __user *) ptr, |
| 372 | second, fifth, third); | 373 | second, fifth, third); |
| 373 | } | 374 | } |
| 374 | case MSGGET: | 375 | case MSGGET: |
| 375 | return sys_msgget ((key_t) first, second); | 376 | return sys_msgget ((key_t) first, second); |
| 376 | case MSGCTL: | 377 | case MSGCTL: |
| 377 | return sys_msgctl (first, second, (struct msqid_ds *) ptr); | 378 | return sys_msgctl (first, second, |
| 379 | (struct msqid_ds __user *) ptr); | ||
| 378 | 380 | ||
| 379 | case SHMAT: | 381 | case SHMAT: |
| 380 | switch (version) { | 382 | switch (version) { |
| 381 | default: { | 383 | default: { |
| 382 | ulong raddr; | 384 | ulong raddr; |
| 383 | ret = do_shmat (first, (char *) ptr, second, &raddr); | 385 | ret = do_shmat (first, (char __user *) ptr, second, |
| 386 | &raddr); | ||
| 384 | if (ret) | 387 | if (ret) |
| 385 | return ret; | 388 | return ret; |
| 386 | return put_user (raddr, (ulong *) third); | 389 | return put_user (raddr, (ulong __user *) third); |
| 387 | } | 390 | } |
| 388 | case 1: /* iBCS2 emulator entry point */ | 391 | case 1: /* iBCS2 emulator entry point */ |
| 389 | if (!segment_eq(get_fs(), get_ds())) | 392 | if (!segment_eq(get_fs(), get_ds())) |
| 390 | return -EINVAL; | 393 | return -EINVAL; |
| 391 | return do_shmat (first, (char *) ptr, second, (ulong *) third); | 394 | return do_shmat (first, (char __user *) ptr, second, |
| 395 | (ulong *) third); | ||
| 392 | } | 396 | } |
| 393 | case SHMDT: | 397 | case SHMDT: |
| 394 | return sys_shmdt ((char *)ptr); | 398 | return sys_shmdt ((char __user *)ptr); |
| 395 | case SHMGET: | 399 | case SHMGET: |
| 396 | return sys_shmget (first, second, third); | 400 | return sys_shmget (first, second, third); |
| 397 | case SHMCTL: | 401 | case SHMCTL: |
| 398 | return sys_shmctl (first, second, | 402 | return sys_shmctl (first, second, |
| 399 | (struct shmid_ds *) ptr); | 403 | (struct shmid_ds __user *) ptr); |
| 400 | default: | 404 | default: |
| 401 | return -ENOSYS; | 405 | return -ENOSYS; |
| 402 | } | 406 | } |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 59a187956de0..c9d2b5147ca3 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
| @@ -1168,7 +1168,7 @@ void __init per_cpu_trap_init(void) | |||
| 1168 | #endif | 1168 | #endif |
| 1169 | if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV) | 1169 | if (current_cpu_data.isa_level == MIPS_CPU_ISA_IV) |
| 1170 | status_set |= ST0_XX; | 1170 | status_set |= ST0_XX; |
| 1171 | change_c0_status(ST0_CU|ST0_MX|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX, | 1171 | change_c0_status(ST0_CU|ST0_MX|ST0_RE|ST0_FR|ST0_BEV|ST0_TS|ST0_KX|ST0_SX|ST0_UX, |
| 1172 | status_set); | 1172 | status_set); |
| 1173 | 1173 | ||
| 1174 | if (cpu_has_dsp) | 1174 | if (cpu_has_dsp) |
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 25cc856d8e7e..ff699dbb99f7 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | #include <linux/config.h> | 1 | #include <linux/config.h> |
| 2 | #include <asm/asm-offsets.h> | ||
| 2 | #include <asm-generic/vmlinux.lds.h> | 3 | #include <asm-generic/vmlinux.lds.h> |
| 3 | 4 | ||
| 4 | #undef mips /* CPP really sucks for this job */ | 5 | #undef mips /* CPP really sucks for this job */ |
| @@ -64,10 +65,10 @@ SECTIONS | |||
| 64 | we can shorten the on-disk segment size. */ | 65 | we can shorten the on-disk segment size. */ |
| 65 | .sdata : { *(.sdata) } | 66 | .sdata : { *(.sdata) } |
| 66 | 67 | ||
| 67 | . = ALIGN(4096); | 68 | . = ALIGN(_PAGE_SIZE); |
| 68 | __nosave_begin = .; | 69 | __nosave_begin = .; |
| 69 | .data_nosave : { *(.data.nosave) } | 70 | .data_nosave : { *(.data.nosave) } |
| 70 | . = ALIGN(4096); | 71 | . = ALIGN(_PAGE_SIZE); |
| 71 | __nosave_end = .; | 72 | __nosave_end = .; |
| 72 | 73 | ||
| 73 | . = ALIGN(32); | 74 | . = ALIGN(32); |
| @@ -76,7 +77,7 @@ SECTIONS | |||
| 76 | _edata = .; /* End of data section */ | 77 | _edata = .; /* End of data section */ |
| 77 | 78 | ||
| 78 | /* will be freed after init */ | 79 | /* will be freed after init */ |
| 79 | . = ALIGN(4096); /* Init code and data */ | 80 | . = ALIGN(_PAGE_SIZE); /* Init code and data */ |
| 80 | __init_begin = .; | 81 | __init_begin = .; |
| 81 | .init.text : { | 82 | .init.text : { |
| 82 | _sinittext = .; | 83 | _sinittext = .; |
| @@ -105,7 +106,7 @@ SECTIONS | |||
| 105 | .con_initcall.init : { *(.con_initcall.init) } | 106 | .con_initcall.init : { *(.con_initcall.init) } |
| 106 | __con_initcall_end = .; | 107 | __con_initcall_end = .; |
| 107 | SECURITY_INIT | 108 | SECURITY_INIT |
| 108 | . = ALIGN(4096); | 109 | . = ALIGN(_PAGE_SIZE); |
| 109 | __initramfs_start = .; | 110 | __initramfs_start = .; |
| 110 | .init.ramfs : { *(.init.ramfs) } | 111 | .init.ramfs : { *(.init.ramfs) } |
| 111 | __initramfs_end = .; | 112 | __initramfs_end = .; |
| @@ -113,7 +114,7 @@ SECTIONS | |||
| 113 | __per_cpu_start = .; | 114 | __per_cpu_start = .; |
| 114 | .data.percpu : { *(.data.percpu) } | 115 | .data.percpu : { *(.data.percpu) } |
| 115 | __per_cpu_end = .; | 116 | __per_cpu_end = .; |
| 116 | . = ALIGN(4096); | 117 | . = ALIGN(_PAGE_SIZE); |
| 117 | __init_end = .; | 118 | __init_end = .; |
| 118 | /* freed after init ends here */ | 119 | /* freed after init ends here */ |
| 119 | 120 | ||
diff --git a/arch/mips/lasat/reset.c b/arch/mips/lasat/reset.c index 8d7d7a454f9a..181bf68175fc 100644 --- a/arch/mips/lasat/reset.c +++ b/arch/mips/lasat/reset.c | |||
| @@ -19,9 +19,12 @@ | |||
| 19 | */ | 19 | */ |
| 20 | #include <linux/config.h> | 20 | #include <linux/config.h> |
| 21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
| 22 | #include <linux/pm.h> | ||
| 23 | |||
| 22 | #include <asm/reboot.h> | 24 | #include <asm/reboot.h> |
| 23 | #include <asm/system.h> | 25 | #include <asm/system.h> |
| 24 | #include <asm/lasat/lasat.h> | 26 | #include <asm/lasat/lasat.h> |
| 27 | |||
| 25 | #include "picvue.h" | 28 | #include "picvue.h" |
| 26 | #include "prom.h" | 29 | #include "prom.h" |
| 27 | 30 | ||
| @@ -63,5 +66,5 @@ void lasat_reboot_setup(void) | |||
| 63 | { | 66 | { |
| 64 | _machine_restart = lasat_machine_restart; | 67 | _machine_restart = lasat_machine_restart; |
| 65 | _machine_halt = lasat_machine_halt; | 68 | _machine_halt = lasat_machine_halt; |
| 66 | _machine_power_off = lasat_machine_halt; | 69 | pm_power_off = lasat_machine_halt; |
| 67 | } | 70 | } |
diff --git a/arch/mips/lasat/setup.c b/arch/mips/lasat/setup.c index dcd819d57dae..83eb08b7a072 100644 --- a/arch/mips/lasat/setup.c +++ b/arch/mips/lasat/setup.c | |||
| @@ -134,8 +134,8 @@ void __init serial_init(void) | |||
| 134 | 134 | ||
| 135 | memset(&s, 0, sizeof(s)); | 135 | memset(&s, 0, sizeof(s)); |
| 136 | 136 | ||
| 137 | s.flags = STD_COM_FLAGS; | 137 | s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
| 138 | s.iotype = SERIAL_IO_MEM; | 138 | s.iotype = UPIO_MEM; |
| 139 | 139 | ||
| 140 | if (mips_machtype == MACH_LASAT_100) { | 140 | if (mips_machtype == MACH_LASAT_100) { |
| 141 | s.uartclk = LASAT_BASE_BAUD_100 * 16; | 141 | s.uartclk = LASAT_BASE_BAUD_100 * 16; |
diff --git a/arch/mips/lib-32/dump_tlb.c b/arch/mips/lib-32/dump_tlb.c index 46519f4331eb..c49a925d0169 100644 --- a/arch/mips/lib-32/dump_tlb.c +++ b/arch/mips/lib-32/dump_tlb.c | |||
| @@ -158,29 +158,26 @@ void dump_list_process(struct task_struct *t, void *address) | |||
| 158 | printk("task->mm == %8p\n", t->mm); | 158 | printk("task->mm == %8p\n", t->mm); |
| 159 | //printk("tasks->mm.pgd == %08x\n", (unsigned int) t->mm->pgd); | 159 | //printk("tasks->mm.pgd == %08x\n", (unsigned int) t->mm->pgd); |
| 160 | 160 | ||
| 161 | if (addr > KSEG0) | 161 | if (addr > KSEG0) { |
| 162 | page_dir = pgd_offset_k(0); | 162 | page_dir = pgd_offset_k(0); |
| 163 | else if (t->mm) { | ||
| 164 | page_dir = pgd_offset(t->mm, 0); | ||
| 165 | printk("page_dir == %08x\n", (unsigned int) page_dir); | ||
| 166 | } else | ||
| 167 | printk("Current thread has no mm\n"); | ||
| 168 | |||
| 169 | if (addr > KSEG0) | ||
| 170 | pgd = pgd_offset_k(addr); | 163 | pgd = pgd_offset_k(addr); |
| 171 | else if (t->mm) { | 164 | } else if (t->mm) { |
| 165 | page_dir = pgd_offset(t->mm, 0); | ||
| 172 | pgd = pgd_offset(t->mm, addr); | 166 | pgd = pgd_offset(t->mm, addr); |
| 173 | printk("pgd == %08x, ", (unsigned int) pgd); | 167 | } else { |
| 174 | pud = pud_offset(pgd, addr); | 168 | printk("Current thread has no mm\n"); |
| 175 | printk("pud == %08x, ", (unsigned int) pud); | 169 | return; |
| 170 | } | ||
| 171 | printk("page_dir == %08x\n", (unsigned int) page_dir); | ||
| 172 | printk("pgd == %08x, ", (unsigned int) pgd); | ||
| 173 | pud = pud_offset(pgd, addr); | ||
| 174 | printk("pud == %08x, ", (unsigned int) pud); | ||
| 176 | 175 | ||
| 177 | pmd = pmd_offset(pud, addr); | 176 | pmd = pmd_offset(pud, addr); |
| 178 | printk("pmd == %08x, ", (unsigned int) pmd); | 177 | printk("pmd == %08x, ", (unsigned int) pmd); |
| 179 | 178 | ||
| 180 | pte = pte_offset(pmd, addr); | 179 | pte = pte_offset(pmd, addr); |
| 181 | printk("pte == %08x, ", (unsigned int) pte); | 180 | printk("pte == %08x, ", (unsigned int) pte); |
| 182 | } else | ||
| 183 | printk("Current thread has no mm\n"); | ||
| 184 | 181 | ||
| 185 | page = *pte; | 182 | page = *pte; |
| 186 | #ifdef CONFIG_64BIT_PHYS_ADDR | 183 | #ifdef CONFIG_64BIT_PHYS_ADDR |
diff --git a/arch/mips/math-emu/dp_simple.c b/arch/mips/math-emu/dp_simple.c index 495c1ac94298..1c555e6c6a9f 100644 --- a/arch/mips/math-emu/dp_simple.c +++ b/arch/mips/math-emu/dp_simple.c | |||
| @@ -48,16 +48,22 @@ ieee754dp ieee754dp_neg(ieee754dp x) | |||
| 48 | CLEARCX; | 48 | CLEARCX; |
| 49 | FLUSHXDP; | 49 | FLUSHXDP; |
| 50 | 50 | ||
| 51 | /* | ||
| 52 | * Invert the sign ALWAYS to prevent an endless recursion on | ||
| 53 | * pow() in libc. | ||
| 54 | */ | ||
| 55 | /* quick fix up */ | ||
| 56 | DPSIGN(x) ^= 1; | ||
| 57 | |||
| 51 | if (xc == IEEE754_CLASS_SNAN) { | 58 | if (xc == IEEE754_CLASS_SNAN) { |
| 59 | ieee754dp y = ieee754dp_indef(); | ||
| 52 | SETCX(IEEE754_INVALID_OPERATION); | 60 | SETCX(IEEE754_INVALID_OPERATION); |
| 53 | return ieee754dp_nanxcpt(ieee754dp_indef(), "neg"); | 61 | DPSIGN(y) = DPSIGN(x); |
| 62 | return ieee754dp_nanxcpt(y, "neg"); | ||
| 54 | } | 63 | } |
| 55 | 64 | ||
| 56 | if (ieee754dp_isnan(x)) /* but not infinity */ | 65 | if (ieee754dp_isnan(x)) /* but not infinity */ |
| 57 | return ieee754dp_nanxcpt(x, "neg", x); | 66 | return ieee754dp_nanxcpt(x, "neg", x); |
| 58 | |||
| 59 | /* quick fix up */ | ||
| 60 | DPSIGN(x) ^= 1; | ||
| 61 | return x; | 67 | return x; |
| 62 | } | 68 | } |
| 63 | 69 | ||
diff --git a/arch/mips/math-emu/sp_simple.c b/arch/mips/math-emu/sp_simple.c index c809830dffb4..770f0f4677cd 100644 --- a/arch/mips/math-emu/sp_simple.c +++ b/arch/mips/math-emu/sp_simple.c | |||
| @@ -48,16 +48,22 @@ ieee754sp ieee754sp_neg(ieee754sp x) | |||
| 48 | CLEARCX; | 48 | CLEARCX; |
| 49 | FLUSHXSP; | 49 | FLUSHXSP; |
| 50 | 50 | ||
| 51 | /* | ||
| 52 | * Invert the sign ALWAYS to prevent an endless recursion on | ||
| 53 | * pow() in libc. | ||
| 54 | */ | ||
| 55 | /* quick fix up */ | ||
| 56 | SPSIGN(x) ^= 1; | ||
| 57 | |||
| 51 | if (xc == IEEE754_CLASS_SNAN) { | 58 | if (xc == IEEE754_CLASS_SNAN) { |
| 59 | ieee754sp y = ieee754sp_indef(); | ||
| 52 | SETCX(IEEE754_INVALID_OPERATION); | 60 | SETCX(IEEE754_INVALID_OPERATION); |
| 53 | return ieee754sp_nanxcpt(ieee754sp_indef(), "neg"); | 61 | SPSIGN(y) = SPSIGN(x); |
| 62 | return ieee754sp_nanxcpt(y, "neg"); | ||
| 54 | } | 63 | } |
| 55 | 64 | ||
| 56 | if (ieee754sp_isnan(x)) /* but not infinity */ | 65 | if (ieee754sp_isnan(x)) /* but not infinity */ |
| 57 | return ieee754sp_nanxcpt(x, "neg", x); | 66 | return ieee754sp_nanxcpt(x, "neg", x); |
| 58 | |||
| 59 | /* quick fix up */ | ||
| 60 | SPSIGN(x) ^= 1; | ||
| 61 | return x; | 67 | return x; |
| 62 | } | 68 | } |
| 63 | 69 | ||
diff --git a/arch/mips/mips-boards/atlas/atlas_setup.c b/arch/mips/mips-boards/atlas/atlas_setup.c index 625843b30bed..873cf3141a31 100644 --- a/arch/mips/mips-boards/atlas/atlas_setup.c +++ b/arch/mips/mips-boards/atlas/atlas_setup.c | |||
| @@ -82,8 +82,8 @@ static void __init serial_init(void) | |||
| 82 | #endif | 82 | #endif |
| 83 | s.irq = ATLASINT_UART; | 83 | s.irq = ATLASINT_UART; |
| 84 | s.uartclk = ATLAS_BASE_BAUD * 16; | 84 | s.uartclk = ATLAS_BASE_BAUD * 16; |
| 85 | s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; | 85 | s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ; |
| 86 | s.iotype = SERIAL_IO_PORT; | 86 | s.iotype = UPIO_PORT; |
| 87 | s.regshift = 3; | 87 | s.regshift = 3; |
| 88 | 88 | ||
| 89 | if (early_serial_setup(&s) != 0) { | 89 | if (early_serial_setup(&s) != 0) { |
diff --git a/arch/mips/mips-boards/generic/reset.c b/arch/mips/mips-boards/generic/reset.c index 9fdec743bd95..7213c395fb6b 100644 --- a/arch/mips/mips-boards/generic/reset.c +++ b/arch/mips/mips-boards/generic/reset.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | * | 23 | * |
| 24 | */ | 24 | */ |
| 25 | #include <linux/config.h> | 25 | #include <linux/config.h> |
| 26 | #include <linux/pm.h> | ||
| 26 | 27 | ||
| 27 | #include <asm/io.h> | 28 | #include <asm/io.h> |
| 28 | #include <asm/reboot.h> | 29 | #include <asm/reboot.h> |
| @@ -65,9 +66,9 @@ void mips_reboot_setup(void) | |||
| 65 | _machine_restart = mips_machine_restart; | 66 | _machine_restart = mips_machine_restart; |
| 66 | _machine_halt = mips_machine_halt; | 67 | _machine_halt = mips_machine_halt; |
| 67 | #if defined(CONFIG_MIPS_ATLAS) | 68 | #if defined(CONFIG_MIPS_ATLAS) |
| 68 | _machine_power_off = atlas_machine_power_off; | 69 | pm_power_off = atlas_machine_power_off; |
| 69 | #endif | 70 | #endif |
| 70 | #if defined(CONFIG_MIPS_MALTA) || defined(CONFIG_MIPS_SEAD) | 71 | #if defined(CONFIG_MIPS_MALTA) || defined(CONFIG_MIPS_SEAD) |
| 71 | _machine_power_off = mips_machine_halt; | 72 | pm_power_off = mips_machine_halt; |
| 72 | #endif | 73 | #endif |
| 73 | } | 74 | } |
diff --git a/arch/mips/mips-boards/sead/sead_setup.c b/arch/mips/mips-boards/sead/sead_setup.c index f966bc161dfa..4266ce445174 100644 --- a/arch/mips/mips-boards/sead/sead_setup.c +++ b/arch/mips/mips-boards/sead/sead_setup.c | |||
| @@ -71,8 +71,8 @@ static void __init serial_init(void) | |||
| 71 | #endif | 71 | #endif |
| 72 | s.irq = MIPSCPU_INT_BASE + MIPSCPU_INT_UART0; | 72 | s.irq = MIPSCPU_INT_BASE + MIPSCPU_INT_UART0; |
| 73 | s.uartclk = SEAD_BASE_BAUD * 16; | 73 | s.uartclk = SEAD_BASE_BAUD * 16; |
| 74 | s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; | 74 | s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ; |
| 75 | s.iotype = 0; | 75 | s.iotype = UPIO_PORT; |
| 76 | s.regshift = 3; | 76 | s.regshift = 3; |
| 77 | 77 | ||
| 78 | if (early_serial_setup(&s) != 0) { | 78 | if (early_serial_setup(&s) != 0) { |
diff --git a/arch/mips/mips-boards/sim/sim_setup.c b/arch/mips/mips-boards/sim/sim_setup.c index 485d5a58d9cf..a2fd62997ca3 100644 --- a/arch/mips/mips-boards/sim/sim_setup.c +++ b/arch/mips/mips-boards/sim/sim_setup.c | |||
| @@ -88,8 +88,8 @@ static void __init serial_init(void) | |||
| 88 | but poll for now */ | 88 | but poll for now */ |
| 89 | s.irq = 0; | 89 | s.irq = 0; |
| 90 | s.uartclk = BASE_BAUD * 16; | 90 | s.uartclk = BASE_BAUD * 16; |
| 91 | s.flags = ASYNC_BOOT_AUTOCONF | UPF_SKIP_TEST; | 91 | s.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
| 92 | s.iotype = SERIAL_IO_PORT | ASYNC_SKIP_TEST; | 92 | s.iotype = UPIO_PORT; |
| 93 | s.regshift = 0; | 93 | s.regshift = 0; |
| 94 | s.timeout = 4; | 94 | s.timeout = 4; |
| 95 | 95 | ||
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 422b55fab07a..e51c38cef88e 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c | |||
| @@ -464,8 +464,8 @@ static void r4k_flush_data_cache_page(unsigned long addr) | |||
| 464 | } | 464 | } |
| 465 | 465 | ||
| 466 | struct flush_icache_range_args { | 466 | struct flush_icache_range_args { |
| 467 | unsigned long __user start; | 467 | unsigned long start; |
| 468 | unsigned long __user end; | 468 | unsigned long end; |
| 469 | }; | 469 | }; |
| 470 | 470 | ||
| 471 | static inline void local_r4k_flush_icache_range(void *args) | 471 | static inline void local_r4k_flush_icache_range(void *args) |
| @@ -528,8 +528,7 @@ static inline void local_r4k_flush_icache_range(void *args) | |||
| 528 | } | 528 | } |
| 529 | } | 529 | } |
| 530 | 530 | ||
| 531 | static void r4k_flush_icache_range(unsigned long __user start, | 531 | static void r4k_flush_icache_range(unsigned long start, unsigned long end) |
| 532 | unsigned long __user end) | ||
| 533 | { | 532 | { |
| 534 | struct flush_icache_range_args args; | 533 | struct flush_icache_range_args args; |
| 535 | 534 | ||
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index 314701a66b13..591c22b080e4 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c | |||
| @@ -25,8 +25,7 @@ void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start, | |||
| 25 | unsigned long end); | 25 | unsigned long end); |
| 26 | void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, | 26 | void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, |
| 27 | unsigned long pfn); | 27 | unsigned long pfn); |
| 28 | void (*flush_icache_range)(unsigned long __user start, | 28 | void (*flush_icache_range)(unsigned long start, unsigned long end); |
| 29 | unsigned long __user end); | ||
| 30 | void (*flush_icache_page)(struct vm_area_struct *vma, struct page *page); | 29 | void (*flush_icache_page)(struct vm_area_struct *vma, struct page *page); |
| 31 | 30 | ||
| 32 | /* MIPS specific cache operations */ | 31 | /* MIPS specific cache operations */ |
| @@ -53,7 +52,7 @@ EXPORT_SYMBOL(_dma_cache_inv); | |||
| 53 | * We could optimize the case where the cache argument is not BCACHE but | 52 | * We could optimize the case where the cache argument is not BCACHE but |
| 54 | * that seems very atypical use ... | 53 | * that seems very atypical use ... |
| 55 | */ | 54 | */ |
| 56 | asmlinkage int sys_cacheflush(unsigned long __user addr, | 55 | asmlinkage int sys_cacheflush(unsigned long addr, |
| 57 | unsigned long bytes, unsigned int cache) | 56 | unsigned long bytes, unsigned int cache) |
| 58 | { | 57 | { |
| 59 | if (bytes == 0) | 58 | if (bytes == 0) |
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 4ee91c9a556f..0ff9a348b843 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/bootmem.h> | 24 | #include <linux/bootmem.h> |
| 25 | #include <linux/highmem.h> | 25 | #include <linux/highmem.h> |
| 26 | #include <linux/swap.h> | 26 | #include <linux/swap.h> |
| 27 | #include <linux/proc_fs.h> | ||
| 27 | 28 | ||
| 28 | #include <asm/bootinfo.h> | 29 | #include <asm/bootinfo.h> |
| 29 | #include <asm/cachectl.h> | 30 | #include <asm/cachectl.h> |
| @@ -200,6 +201,11 @@ static inline int page_is_ram(unsigned long pagenr) | |||
| 200 | return 0; | 201 | return 0; |
| 201 | } | 202 | } |
| 202 | 203 | ||
| 204 | static struct kcore_list kcore_mem, kcore_vmalloc; | ||
| 205 | #ifdef CONFIG_64BIT | ||
| 206 | static struct kcore_list kcore_kseg0; | ||
| 207 | #endif | ||
| 208 | |||
| 203 | void __init mem_init(void) | 209 | void __init mem_init(void) |
| 204 | { | 210 | { |
| 205 | unsigned long codesize, reservedpages, datasize, initsize; | 211 | unsigned long codesize, reservedpages, datasize, initsize; |
| @@ -249,6 +255,16 @@ void __init mem_init(void) | |||
| 249 | datasize = (unsigned long) &_edata - (unsigned long) &_etext; | 255 | datasize = (unsigned long) &_edata - (unsigned long) &_etext; |
| 250 | initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; | 256 | initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; |
| 251 | 257 | ||
| 258 | #ifdef CONFIG_64BIT | ||
| 259 | if ((unsigned long) &_text > (unsigned long) CKSEG0) | ||
| 260 | /* The -4 is a hack so that user tools don't have to handle | ||
| 261 | the overflow. */ | ||
| 262 | kclist_add(&kcore_kseg0, (void *) CKSEG0, 0x80000000 - 4); | ||
| 263 | #endif | ||
| 264 | kclist_add(&kcore_mem, __va(0), max_low_pfn << PAGE_SHIFT); | ||
| 265 | kclist_add(&kcore_vmalloc, (void *)VMALLOC_START, | ||
| 266 | VMALLOC_END-VMALLOC_START); | ||
| 267 | |||
| 252 | printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, " | 268 | printk(KERN_INFO "Memory: %luk/%luk available (%ldk kernel code, " |
| 253 | "%ldk reserved, %ldk data, %ldk init, %ldk highmem)\n", | 269 | "%ldk reserved, %ldk data, %ldk init, %ldk highmem)\n", |
| 254 | (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), | 270 | (unsigned long) nr_free_pages() << (PAGE_SHIFT-10), |
diff --git a/arch/mips/momentum/jaguar_atx/ja-console.c b/arch/mips/momentum/jaguar_atx/ja-console.c index da6e1ed34db1..2292d0ec47fc 100644 --- a/arch/mips/momentum/jaguar_atx/ja-console.c +++ b/arch/mips/momentum/jaguar_atx/ja-console.c | |||
| @@ -93,7 +93,7 @@ static void inline ja_console_probe(void) | |||
| 93 | up.uartclk = JAGUAR_ATX_UART_CLK; | 93 | up.uartclk = JAGUAR_ATX_UART_CLK; |
| 94 | up.regshift = 2; | 94 | up.regshift = 2; |
| 95 | up.iotype = UPIO_MEM; | 95 | up.iotype = UPIO_MEM; |
| 96 | up.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; | 96 | up.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
| 97 | up.line = 0; | 97 | up.line = 0; |
| 98 | 98 | ||
| 99 | if (early_serial_setup(&up)) | 99 | if (early_serial_setup(&up)) |
diff --git a/arch/mips/momentum/jaguar_atx/setup.c b/arch/mips/momentum/jaguar_atx/setup.c index bab192ddc185..301d67226d72 100644 --- a/arch/mips/momentum/jaguar_atx/setup.c +++ b/arch/mips/momentum/jaguar_atx/setup.c | |||
| @@ -50,6 +50,7 @@ | |||
| 50 | #include <linux/pci.h> | 50 | #include <linux/pci.h> |
| 51 | #include <linux/swap.h> | 51 | #include <linux/swap.h> |
| 52 | #include <linux/ioport.h> | 52 | #include <linux/ioport.h> |
| 53 | #include <linux/pm.h> | ||
| 53 | #include <linux/sched.h> | 54 | #include <linux/sched.h> |
| 54 | #include <linux/interrupt.h> | 55 | #include <linux/interrupt.h> |
| 55 | #include <linux/timex.h> | 56 | #include <linux/timex.h> |
| @@ -365,7 +366,7 @@ void __init plat_setup(void) | |||
| 365 | 366 | ||
| 366 | _machine_restart = momenco_jaguar_restart; | 367 | _machine_restart = momenco_jaguar_restart; |
| 367 | _machine_halt = momenco_jaguar_halt; | 368 | _machine_halt = momenco_jaguar_halt; |
| 368 | _machine_power_off = momenco_jaguar_power_off; | 369 | pm_power_off = momenco_jaguar_power_off; |
| 369 | 370 | ||
| 370 | /* | 371 | /* |
| 371 | * initrd_start = (ulong)jaguar_initrd_start; | 372 | * initrd_start = (ulong)jaguar_initrd_start; |
diff --git a/arch/mips/momentum/ocelot_3/setup.c b/arch/mips/momentum/ocelot_3/setup.c index c9b7ff8148ec..f95677f4f06f 100644 --- a/arch/mips/momentum/ocelot_3/setup.c +++ b/arch/mips/momentum/ocelot_3/setup.c | |||
| @@ -57,6 +57,8 @@ | |||
| 57 | #include <linux/timex.h> | 57 | #include <linux/timex.h> |
| 58 | #include <linux/bootmem.h> | 58 | #include <linux/bootmem.h> |
| 59 | #include <linux/mv643xx.h> | 59 | #include <linux/mv643xx.h> |
| 60 | #include <linux/pm.h> | ||
| 61 | |||
| 60 | #include <asm/time.h> | 62 | #include <asm/time.h> |
| 61 | #include <asm/page.h> | 63 | #include <asm/page.h> |
| 62 | #include <asm/bootinfo.h> | 64 | #include <asm/bootinfo.h> |
| @@ -321,7 +323,7 @@ void __init plat_setup(void) | |||
| 321 | 323 | ||
| 322 | _machine_restart = momenco_ocelot_restart; | 324 | _machine_restart = momenco_ocelot_restart; |
| 323 | _machine_halt = momenco_ocelot_halt; | 325 | _machine_halt = momenco_ocelot_halt; |
| 324 | _machine_power_off = momenco_ocelot_power_off; | 326 | pm_power_off = momenco_ocelot_power_off; |
| 325 | 327 | ||
| 326 | /* Wired TLB entries */ | 328 | /* Wired TLB entries */ |
| 327 | setup_wired_tlb_entries(); | 329 | setup_wired_tlb_entries(); |
diff --git a/arch/mips/momentum/ocelot_c/setup.c b/arch/mips/momentum/ocelot_c/setup.c index 2755c1547473..15998d8a9341 100644 --- a/arch/mips/momentum/ocelot_c/setup.c +++ b/arch/mips/momentum/ocelot_c/setup.c | |||
| @@ -51,8 +51,10 @@ | |||
| 51 | #include <linux/sched.h> | 51 | #include <linux/sched.h> |
| 52 | #include <linux/interrupt.h> | 52 | #include <linux/interrupt.h> |
| 53 | #include <linux/pci.h> | 53 | #include <linux/pci.h> |
| 54 | #include <linux/pm.h> | ||
| 54 | #include <linux/timex.h> | 55 | #include <linux/timex.h> |
| 55 | #include <linux/vmalloc.h> | 56 | #include <linux/vmalloc.h> |
| 57 | |||
| 56 | #include <asm/time.h> | 58 | #include <asm/time.h> |
| 57 | #include <asm/bootinfo.h> | 59 | #include <asm/bootinfo.h> |
| 58 | #include <asm/page.h> | 60 | #include <asm/page.h> |
| @@ -236,7 +238,7 @@ void __init plat_setup(void) | |||
| 236 | 238 | ||
| 237 | _machine_restart = momenco_ocelot_restart; | 239 | _machine_restart = momenco_ocelot_restart; |
| 238 | _machine_halt = momenco_ocelot_halt; | 240 | _machine_halt = momenco_ocelot_halt; |
| 239 | _machine_power_off = momenco_ocelot_power_off; | 241 | pm_power_off = momenco_ocelot_power_off; |
| 240 | 242 | ||
| 241 | /* | 243 | /* |
| 242 | * initrd_start = (ulong)ocelot_initrd_start; | 244 | * initrd_start = (ulong)ocelot_initrd_start; |
diff --git a/arch/mips/momentum/ocelot_g/setup.c b/arch/mips/momentum/ocelot_g/setup.c index 6336751391c3..fed4e8eee116 100644 --- a/arch/mips/momentum/ocelot_g/setup.c +++ b/arch/mips/momentum/ocelot_g/setup.c | |||
| @@ -47,8 +47,10 @@ | |||
| 47 | #include <linux/sched.h> | 47 | #include <linux/sched.h> |
| 48 | #include <linux/interrupt.h> | 48 | #include <linux/interrupt.h> |
| 49 | #include <linux/pci.h> | 49 | #include <linux/pci.h> |
| 50 | #include <linux/pm.h> | ||
| 50 | #include <linux/timex.h> | 51 | #include <linux/timex.h> |
| 51 | #include <linux/vmalloc.h> | 52 | #include <linux/vmalloc.h> |
| 53 | |||
| 52 | #include <asm/time.h> | 54 | #include <asm/time.h> |
| 53 | #include <asm/bootinfo.h> | 55 | #include <asm/bootinfo.h> |
| 54 | #include <asm/page.h> | 56 | #include <asm/page.h> |
| @@ -169,7 +171,7 @@ void __init plat_setup(void) | |||
| 169 | 171 | ||
| 170 | _machine_restart = momenco_ocelot_restart; | 172 | _machine_restart = momenco_ocelot_restart; |
| 171 | _machine_halt = momenco_ocelot_halt; | 173 | _machine_halt = momenco_ocelot_halt; |
| 172 | _machine_power_off = momenco_ocelot_power_off; | 174 | pm_power_off = momenco_ocelot_power_off; |
| 173 | 175 | ||
| 174 | /* | 176 | /* |
| 175 | * initrd_start = (ulong)ocelot_initrd_start; | 177 | * initrd_start = (ulong)ocelot_initrd_start; |
diff --git a/arch/mips/oprofile/Makefile b/arch/mips/oprofile/Makefile index 354261d37d62..0a50aad5bbe4 100644 --- a/arch/mips/oprofile/Makefile +++ b/arch/mips/oprofile/Makefile | |||
| @@ -12,4 +12,5 @@ oprofile-y := $(DRIVER_OBJS) common.o | |||
| 12 | 12 | ||
| 13 | oprofile-$(CONFIG_CPU_MIPS32) += op_model_mipsxx.o | 13 | oprofile-$(CONFIG_CPU_MIPS32) += op_model_mipsxx.o |
| 14 | oprofile-$(CONFIG_CPU_MIPS64) += op_model_mipsxx.o | 14 | oprofile-$(CONFIG_CPU_MIPS64) += op_model_mipsxx.o |
| 15 | oprofile-$(CONFIG_CPU_SB1) += op_model_mipsxx.o | ||
| 15 | oprofile-$(CONFIG_CPU_RM9000) += op_model_rm9000.o | 16 | oprofile-$(CONFIG_CPU_RM9000) += op_model_rm9000.o |
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c index 53f9889b30ed..935dd851f480 100644 --- a/arch/mips/oprofile/common.c +++ b/arch/mips/oprofile/common.c | |||
| @@ -79,6 +79,9 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) | |||
| 79 | case CPU_20KC: | 79 | case CPU_20KC: |
| 80 | case CPU_24K: | 80 | case CPU_24K: |
| 81 | case CPU_25KF: | 81 | case CPU_25KF: |
| 82 | case CPU_34K: | ||
| 83 | case CPU_SB1: | ||
| 84 | case CPU_SB1A: | ||
| 82 | lmodel = &op_model_mipsxx; | 85 | lmodel = &op_model_mipsxx; |
| 83 | break; | 86 | break; |
| 84 | 87 | ||
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index 1d1eee407faf..95d488ca0754 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c | |||
| @@ -201,10 +201,21 @@ static int __init mipsxx_init(void) | |||
| 201 | op_model_mipsxx.cpu_type = "mips/25K"; | 201 | op_model_mipsxx.cpu_type = "mips/25K"; |
| 202 | break; | 202 | break; |
| 203 | 203 | ||
| 204 | #ifndef CONFIG_SMP | ||
| 205 | case CPU_34K: | ||
| 206 | op_model_mipsxx.cpu_type = "mips/34K"; | ||
| 207 | break; | ||
| 208 | #endif | ||
| 209 | |||
| 204 | case CPU_5KC: | 210 | case CPU_5KC: |
| 205 | op_model_mipsxx.cpu_type = "mips/5K"; | 211 | op_model_mipsxx.cpu_type = "mips/5K"; |
| 206 | break; | 212 | break; |
| 207 | 213 | ||
| 214 | case CPU_SB1: | ||
| 215 | case CPU_SB1A: | ||
| 216 | op_model_mipsxx.cpu_type = "mips/sb1"; | ||
| 217 | break; | ||
| 218 | |||
| 208 | default: | 219 | default: |
| 209 | printk(KERN_ERR "Profiling unsupported for this CPU\n"); | 220 | printk(KERN_ERR "Profiling unsupported for this CPU\n"); |
| 210 | 221 | ||
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index 741e67c9195a..16205b587338 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile | |||
| @@ -46,6 +46,7 @@ obj-$(CONFIG_PMC_YOSEMITE) += fixup-yosemite.o ops-titan.o ops-titan-ht.o \ | |||
| 46 | obj-$(CONFIG_SGI_IP27) += pci-ip27.o | 46 | obj-$(CONFIG_SGI_IP27) += pci-ip27.o |
| 47 | obj-$(CONFIG_SGI_IP32) += fixup-ip32.o ops-mace.o pci-ip32.o | 47 | obj-$(CONFIG_SGI_IP32) += fixup-ip32.o ops-mace.o pci-ip32.o |
| 48 | obj-$(CONFIG_SIBYTE_SB1250) += fixup-sb1250.o pci-sb1250.o | 48 | obj-$(CONFIG_SIBYTE_SB1250) += fixup-sb1250.o pci-sb1250.o |
| 49 | obj-$(CONFIG_SIBYTE_BCM112X) += fixup-sb1250.o pci-sb1250.o | ||
| 49 | obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o | 50 | obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o |
| 50 | obj-$(CONFIG_SNI_RM200_PCI) += fixup-sni.o ops-sni.o | 51 | obj-$(CONFIG_SNI_RM200_PCI) += fixup-sni.o ops-sni.o |
| 51 | obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o | 52 | obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o |
diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c index 909292f50d06..75a01e764898 100644 --- a/arch/mips/pci/fixup-cobalt.c +++ b/arch/mips/pci/fixup-cobalt.c | |||
| @@ -17,7 +17,7 @@ | |||
| 17 | #include <asm/io.h> | 17 | #include <asm/io.h> |
| 18 | #include <asm/gt64120.h> | 18 | #include <asm/gt64120.h> |
| 19 | 19 | ||
| 20 | #include <asm/cobalt/cobalt.h> | 20 | #include <asm/mach-cobalt/cobalt.h> |
| 21 | 21 | ||
| 22 | extern int cobalt_board_id; | 22 | extern int cobalt_board_id; |
| 23 | 23 | ||
| @@ -52,7 +52,7 @@ static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev) | |||
| 52 | pci_read_config_byte(dev, PCI_LATENCY_TIMER, <); | 52 | pci_read_config_byte(dev, PCI_LATENCY_TIMER, <); |
| 53 | if (lt < 64) | 53 | if (lt < 64) |
| 54 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); | 54 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); |
| 55 | pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 7); | 55 | pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8); |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, | 58 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, |
| @@ -69,7 +69,7 @@ static void qube_raq_galileo_fixup(struct pci_dev *dev) | |||
| 69 | * host bridge. | 69 | * host bridge. |
| 70 | */ | 70 | */ |
| 71 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); | 71 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); |
| 72 | pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 7); | 72 | pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8); |
| 73 | 73 | ||
| 74 | /* | 74 | /* |
| 75 | * The code described by the comment below has been removed | 75 | * The code described by the comment below has been removed |
diff --git a/arch/mips/pci/ops-gt64111.c b/arch/mips/pci/ops-gt64111.c index c1807934768d..13de45940b19 100644 --- a/arch/mips/pci/ops-gt64111.c +++ b/arch/mips/pci/ops-gt64111.c | |||
| @@ -15,7 +15,7 @@ | |||
| 15 | #include <asm/io.h> | 15 | #include <asm/io.h> |
| 16 | #include <asm/gt64120.h> | 16 | #include <asm/gt64120.h> |
| 17 | 17 | ||
| 18 | #include <asm/cobalt/cobalt.h> | 18 | #include <asm/mach-cobalt/cobalt.h> |
| 19 | 19 | ||
| 20 | /* | 20 | /* |
| 21 | * Device 31 on the GT64111 is used to generate PCI special | 21 | * Device 31 on the GT64111 is used to generate PCI special |
diff --git a/arch/mips/pci/pci-bcm1480.c b/arch/mips/pci/pci-bcm1480.c index f194b4e4f86a..ca975e7d32ff 100644 --- a/arch/mips/pci/pci-bcm1480.c +++ b/arch/mips/pci/pci-bcm1480.c | |||
| @@ -234,11 +234,9 @@ static int __init bcm1480_pcibios_init(void) | |||
| 234 | 234 | ||
| 235 | /* turn on ExpMemEn */ | 235 | /* turn on ExpMemEn */ |
| 236 | cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40)); | 236 | cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40)); |
| 237 | printk("PCIFeatureCtrl = %x\n", cmdreg); | ||
| 238 | WRITECFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40), | 237 | WRITECFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40), |
| 239 | cmdreg | 0x10); | 238 | cmdreg | 0x10); |
| 240 | cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40)); | 239 | cmdreg = READCFG32(CFGOFFSET(0, PCI_DEVFN(PCI_BRIDGE_DEVICE, 0), 0x40)); |
| 241 | printk("PCIFeatureCtrl = %x\n", cmdreg); | ||
| 242 | 240 | ||
| 243 | /* | 241 | /* |
| 244 | * Establish mappings in KSEG2 (kernel virtual) to PCI I/O | 242 | * Establish mappings in KSEG2 (kernel virtual) to PCI I/O |
diff --git a/arch/mips/philips/pnx8550/common/platform.c b/arch/mips/philips/pnx8550/common/platform.c index 8aa9bd65b45e..a592260fd673 100644 --- a/arch/mips/philips/pnx8550/common/platform.c +++ b/arch/mips/philips/pnx8550/common/platform.c | |||
| @@ -66,28 +66,28 @@ struct ip3106_port ip3106_ports[] = { | |||
| 66 | [0] = { | 66 | [0] = { |
| 67 | .port = { | 67 | .port = { |
| 68 | .type = PORT_IP3106, | 68 | .type = PORT_IP3106, |
| 69 | .iotype = SERIAL_IO_MEM, | 69 | .iotype = UPIO_MEM, |
| 70 | .membase = (void __iomem *)PNX8550_UART_PORT0, | 70 | .membase = (void __iomem *)PNX8550_UART_PORT0, |
| 71 | .mapbase = PNX8550_UART_PORT0, | 71 | .mapbase = PNX8550_UART_PORT0, |
| 72 | .irq = PNX8550_UART_INT(0), | 72 | .irq = PNX8550_UART_INT(0), |
| 73 | .uartclk = 3692300, | 73 | .uartclk = 3692300, |
| 74 | .fifosize = 16, | 74 | .fifosize = 16, |
| 75 | .ops = &ip3106_pops, | 75 | .ops = &ip3106_pops, |
| 76 | .flags = ASYNC_BOOT_AUTOCONF, | 76 | .flags = UPF_BOOT_AUTOCONF, |
| 77 | .line = 0, | 77 | .line = 0, |
| 78 | }, | 78 | }, |
| 79 | }, | 79 | }, |
| 80 | [1] = { | 80 | [1] = { |
| 81 | .port = { | 81 | .port = { |
| 82 | .type = PORT_IP3106, | 82 | .type = PORT_IP3106, |
| 83 | .iotype = SERIAL_IO_MEM, | 83 | .iotype = UPIO_MEM, |
| 84 | .membase = (void __iomem *)PNX8550_UART_PORT1, | 84 | .membase = (void __iomem *)PNX8550_UART_PORT1, |
| 85 | .mapbase = PNX8550_UART_PORT1, | 85 | .mapbase = PNX8550_UART_PORT1, |
| 86 | .irq = PNX8550_UART_INT(1), | 86 | .irq = PNX8550_UART_INT(1), |
| 87 | .uartclk = 3692300, | 87 | .uartclk = 3692300, |
| 88 | .fifosize = 16, | 88 | .fifosize = 16, |
| 89 | .ops = &ip3106_pops, | 89 | .ops = &ip3106_pops, |
| 90 | .flags = ASYNC_BOOT_AUTOCONF, | 90 | .flags = UPF_BOOT_AUTOCONF, |
| 91 | .line = 1, | 91 | .line = 1, |
| 92 | }, | 92 | }, |
| 93 | }, | 93 | }, |
diff --git a/arch/mips/philips/pnx8550/common/setup.c b/arch/mips/philips/pnx8550/common/setup.c index ee6bf72094f6..0d8a77619391 100644 --- a/arch/mips/philips/pnx8550/common/setup.c +++ b/arch/mips/philips/pnx8550/common/setup.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
| 26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
| 27 | #include <linux/serial_ip3106.h> | 27 | #include <linux/serial_ip3106.h> |
| 28 | #include <linux/pm.h> | ||
| 28 | 29 | ||
| 29 | #include <asm/cpu.h> | 30 | #include <asm/cpu.h> |
| 30 | #include <asm/bootinfo.h> | 31 | #include <asm/bootinfo.h> |
| @@ -90,7 +91,7 @@ void __init plat_setup(void) | |||
| 90 | 91 | ||
| 91 | _machine_restart = pnx8550_machine_restart; | 92 | _machine_restart = pnx8550_machine_restart; |
| 92 | _machine_halt = pnx8550_machine_halt; | 93 | _machine_halt = pnx8550_machine_halt; |
| 93 | _machine_power_off = pnx8550_machine_power_off; | 94 | pm_power_off = pnx8550_machine_power_off; |
| 94 | 95 | ||
| 95 | board_time_init = pnx8550_time_init; | 96 | board_time_init = pnx8550_time_init; |
| 96 | board_timer_setup = pnx8550_timer_setup; | 97 | board_timer_setup = pnx8550_timer_setup; |
diff --git a/arch/mips/pmc-sierra/yosemite/prom.c b/arch/mips/pmc-sierra/yosemite/prom.c index 555bfacf7647..165275c00cbb 100644 --- a/arch/mips/pmc-sierra/yosemite/prom.c +++ b/arch/mips/pmc-sierra/yosemite/prom.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
| 14 | #include <linux/mm.h> | 14 | #include <linux/mm.h> |
| 15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
| 16 | #include <linux/pm.h> | ||
| 16 | #include <linux/smp.h> | 17 | #include <linux/smp.h> |
| 17 | 18 | ||
| 18 | #include <asm/io.h> | 19 | #include <asm/io.h> |
| @@ -92,7 +93,7 @@ void __init prom_init(void) | |||
| 92 | /* Callbacks for halt, restart */ | 93 | /* Callbacks for halt, restart */ |
| 93 | _machine_restart = (void (*)(char *)) prom_exit; | 94 | _machine_restart = (void (*)(char *)) prom_exit; |
| 94 | _machine_halt = prom_halt; | 95 | _machine_halt = prom_halt; |
| 95 | _machine_power_off = prom_halt; | 96 | pm_power_off = prom_halt; |
| 96 | 97 | ||
| 97 | debug_vectors = cv; | 98 | debug_vectors = cv; |
| 98 | arcs_cmdline[0] = '\0'; | 99 | arcs_cmdline[0] = '\0'; |
diff --git a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c index 059755b5ed57..8bce711575de 100644 --- a/arch/mips/pmc-sierra/yosemite/setup.c +++ b/arch/mips/pmc-sierra/yosemite/setup.c | |||
| @@ -185,7 +185,7 @@ static void __init py_uart_setup(void) | |||
| 185 | up.uartclk = TITAN_UART_CLK; | 185 | up.uartclk = TITAN_UART_CLK; |
| 186 | up.regshift = 0; | 186 | up.regshift = 0; |
| 187 | up.iotype = UPIO_MEM; | 187 | up.iotype = UPIO_MEM; |
| 188 | up.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; | 188 | up.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
| 189 | up.line = 0; | 189 | up.line = 0; |
| 190 | 190 | ||
| 191 | if (early_serial_setup(&up)) | 191 | if (early_serial_setup(&up)) |
diff --git a/arch/mips/sgi-ip22/ip22-reset.c b/arch/mips/sgi-ip22/ip22-reset.c index 214ffd2e98a3..92a3b3c15ed3 100644 --- a/arch/mips/sgi-ip22/ip22-reset.c +++ b/arch/mips/sgi-ip22/ip22-reset.c | |||
| @@ -3,8 +3,9 @@ | |||
| 3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
| 4 | * for more details. | 4 | * for more details. |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 1997, 1998, 2001, 2003 by Ralf Baechle | 6 | * Copyright (C) 1997, 1998, 2001, 03, 05, 06 by Ralf Baechle |
| 7 | */ | 7 | */ |
| 8 | #include <linux/linkage.h> | ||
| 8 | #include <linux/init.h> | 9 | #include <linux/init.h> |
| 9 | #include <linux/ds1286.h> | 10 | #include <linux/ds1286.h> |
| 10 | #include <linux/module.h> | 11 | #include <linux/module.h> |
| @@ -12,6 +13,7 @@ | |||
| 12 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| 13 | #include <linux/sched.h> | 14 | #include <linux/sched.h> |
| 14 | #include <linux/notifier.h> | 15 | #include <linux/notifier.h> |
| 16 | #include <linux/pm.h> | ||
| 15 | #include <linux/timer.h> | 17 | #include <linux/timer.h> |
| 16 | 18 | ||
| 17 | #include <asm/io.h> | 19 | #include <asm/io.h> |
| @@ -41,28 +43,10 @@ static struct timer_list power_timer, blink_timer, debounce_timer, volume_timer; | |||
| 41 | 43 | ||
| 42 | #define MACHINE_PANICED 1 | 44 | #define MACHINE_PANICED 1 |
| 43 | #define MACHINE_SHUTTING_DOWN 2 | 45 | #define MACHINE_SHUTTING_DOWN 2 |
| 44 | static int machine_state = 0; | ||
| 45 | 46 | ||
| 46 | static void sgi_machine_restart(char *command) __attribute__((noreturn)); | 47 | static int machine_state; |
| 47 | static void sgi_machine_halt(void) __attribute__((noreturn)); | ||
| 48 | static void sgi_machine_power_off(void) __attribute__((noreturn)); | ||
| 49 | 48 | ||
| 50 | static void sgi_machine_restart(char *command) | 49 | static void ATTRIB_NORET sgi_machine_power_off(void) |
| 51 | { | ||
| 52 | if (machine_state & MACHINE_SHUTTING_DOWN) | ||
| 53 | sgi_machine_power_off(); | ||
| 54 | sgimc->cpuctrl0 |= SGIMC_CCTRL0_SYSINIT; | ||
| 55 | while (1); | ||
| 56 | } | ||
| 57 | |||
| 58 | static void sgi_machine_halt(void) | ||
| 59 | { | ||
| 60 | if (machine_state & MACHINE_SHUTTING_DOWN) | ||
| 61 | sgi_machine_power_off(); | ||
| 62 | ArcEnterInteractiveMode(); | ||
| 63 | } | ||
| 64 | |||
| 65 | static void sgi_machine_power_off(void) | ||
| 66 | { | 50 | { |
| 67 | unsigned int tmp; | 51 | unsigned int tmp; |
| 68 | 52 | ||
| @@ -84,6 +68,21 @@ static void sgi_machine_power_off(void) | |||
| 84 | } | 68 | } |
| 85 | } | 69 | } |
| 86 | 70 | ||
| 71 | static void ATTRIB_NORET sgi_machine_restart(char *command) | ||
| 72 | { | ||
| 73 | if (machine_state & MACHINE_SHUTTING_DOWN) | ||
| 74 | sgi_machine_power_off(); | ||
| 75 | sgimc->cpuctrl0 |= SGIMC_CCTRL0_SYSINIT; | ||
| 76 | while (1); | ||
| 77 | } | ||
| 78 | |||
| 79 | static void ATTRIB_NORET sgi_machine_halt(void) | ||
| 80 | { | ||
| 81 | if (machine_state & MACHINE_SHUTTING_DOWN) | ||
| 82 | sgi_machine_power_off(); | ||
| 83 | ArcEnterInteractiveMode(); | ||
| 84 | } | ||
| 85 | |||
| 87 | static void power_timeout(unsigned long data) | 86 | static void power_timeout(unsigned long data) |
| 88 | { | 87 | { |
| 89 | sgi_machine_power_off(); | 88 | sgi_machine_power_off(); |
| @@ -95,7 +94,7 @@ static void blink_timeout(unsigned long data) | |||
| 95 | sgi_ioc_reset ^= (SGIOC_RESET_LC0OFF|SGIOC_RESET_LC1OFF); | 94 | sgi_ioc_reset ^= (SGIOC_RESET_LC0OFF|SGIOC_RESET_LC1OFF); |
| 96 | sgioc->reset = sgi_ioc_reset; | 95 | sgioc->reset = sgi_ioc_reset; |
| 97 | 96 | ||
| 98 | mod_timer(&blink_timer, jiffies+data); | 97 | mod_timer(&blink_timer, jiffies + data); |
| 99 | } | 98 | } |
| 100 | 99 | ||
| 101 | static void debounce(unsigned long data) | 100 | static void debounce(unsigned long data) |
| @@ -103,7 +102,7 @@ static void debounce(unsigned long data) | |||
| 103 | del_timer(&debounce_timer); | 102 | del_timer(&debounce_timer); |
| 104 | if (sgint->istat1 & SGINT_ISTAT1_PWR) { | 103 | if (sgint->istat1 & SGINT_ISTAT1_PWR) { |
| 105 | /* Interrupt still being sent. */ | 104 | /* Interrupt still being sent. */ |
| 106 | debounce_timer.expires = jiffies + 5; /* 0.05s */ | 105 | debounce_timer.expires = jiffies + (HZ / 20); /* 0.05s */ |
| 107 | add_timer(&debounce_timer); | 106 | add_timer(&debounce_timer); |
| 108 | 107 | ||
| 109 | sgioc->panel = SGIOC_PANEL_POWERON | SGIOC_PANEL_POWERINTR | | 108 | sgioc->panel = SGIOC_PANEL_POWERON | SGIOC_PANEL_POWERINTR | |
| @@ -151,7 +150,7 @@ static inline void volume_up_button(unsigned long data) | |||
| 151 | indy_volume_button(1); | 150 | indy_volume_button(1); |
| 152 | 151 | ||
| 153 | if (sgint->istat1 & SGINT_ISTAT1_PWR) { | 152 | if (sgint->istat1 & SGINT_ISTAT1_PWR) { |
| 154 | volume_timer.expires = jiffies + 1; | 153 | volume_timer.expires = jiffies + (HZ / 100); |
| 155 | add_timer(&volume_timer); | 154 | add_timer(&volume_timer); |
| 156 | } | 155 | } |
| 157 | } | 156 | } |
| @@ -164,7 +163,7 @@ static inline void volume_down_button(unsigned long data) | |||
| 164 | indy_volume_button(-1); | 163 | indy_volume_button(-1); |
| 165 | 164 | ||
| 166 | if (sgint->istat1 & SGINT_ISTAT1_PWR) { | 165 | if (sgint->istat1 & SGINT_ISTAT1_PWR) { |
| 167 | volume_timer.expires = jiffies + 1; | 166 | volume_timer.expires = jiffies + (HZ / 100); |
| 168 | add_timer(&volume_timer); | 167 | add_timer(&volume_timer); |
| 169 | } | 168 | } |
| 170 | } | 169 | } |
| @@ -199,14 +198,14 @@ static irqreturn_t panel_int(int irq, void *dev_id, struct pt_regs *regs) | |||
| 199 | if (!(buttons & SGIOC_PANEL_VOLUPINTR)) { | 198 | if (!(buttons & SGIOC_PANEL_VOLUPINTR)) { |
| 200 | init_timer(&volume_timer); | 199 | init_timer(&volume_timer); |
| 201 | volume_timer.function = volume_up_button; | 200 | volume_timer.function = volume_up_button; |
| 202 | volume_timer.expires = jiffies + 1; | 201 | volume_timer.expires = jiffies + (HZ / 100); |
| 203 | add_timer(&volume_timer); | 202 | add_timer(&volume_timer); |
| 204 | } | 203 | } |
| 205 | /* Volume down button was pressed */ | 204 | /* Volume down button was pressed */ |
| 206 | if (!(buttons & SGIOC_PANEL_VOLDNINTR)) { | 205 | if (!(buttons & SGIOC_PANEL_VOLDNINTR)) { |
| 207 | init_timer(&volume_timer); | 206 | init_timer(&volume_timer); |
| 208 | volume_timer.function = volume_down_button; | 207 | volume_timer.function = volume_down_button; |
| 209 | volume_timer.expires = jiffies + 1; | 208 | volume_timer.expires = jiffies + (HZ / 100); |
| 210 | add_timer(&volume_timer); | 209 | add_timer(&volume_timer); |
| 211 | } | 210 | } |
| 212 | 211 | ||
| @@ -234,7 +233,7 @@ static int __init reboot_setup(void) | |||
| 234 | { | 233 | { |
| 235 | _machine_restart = sgi_machine_restart; | 234 | _machine_restart = sgi_machine_restart; |
| 236 | _machine_halt = sgi_machine_halt; | 235 | _machine_halt = sgi_machine_halt; |
| 237 | _machine_power_off = sgi_machine_power_off; | 236 | pm_power_off = sgi_machine_power_off; |
| 238 | 237 | ||
| 239 | request_irq(SGI_PANEL_IRQ, panel_int, 0, "Front Panel", NULL); | 238 | request_irq(SGI_PANEL_IRQ, panel_int, 0, "Front Panel", NULL); |
| 240 | init_timer(&blink_timer); | 239 | init_timer(&blink_timer); |
diff --git a/arch/mips/sgi-ip22/ip22-setup.c b/arch/mips/sgi-ip22/ip22-setup.c index 5e59b4c8876b..7018e1833e85 100644 --- a/arch/mips/sgi-ip22/ip22-setup.c +++ b/arch/mips/sgi-ip22/ip22-setup.c | |||
| @@ -56,6 +56,7 @@ extern void ip22_time_init(void) __init; | |||
| 56 | void __init plat_setup(void) | 56 | void __init plat_setup(void) |
| 57 | { | 57 | { |
| 58 | char *ctype; | 58 | char *ctype; |
| 59 | char *cserial; | ||
| 59 | 60 | ||
| 60 | board_be_init = ip22_be_init; | 61 | board_be_init = ip22_be_init; |
| 61 | ip22_time_init(); | 62 | ip22_time_init(); |
| @@ -81,9 +82,14 @@ void __init plat_setup(void) | |||
| 81 | /* ARCS console environment variable is set to "g?" for | 82 | /* ARCS console environment variable is set to "g?" for |
| 82 | * graphics console, it is set to "d" for the first serial | 83 | * graphics console, it is set to "d" for the first serial |
| 83 | * line and "d2" for the second serial line. | 84 | * line and "d2" for the second serial line. |
| 85 | * | ||
| 86 | * Need to check if the case is 'g' but no keyboard: | ||
| 87 | * (ConsoleIn/Out = serial) | ||
| 84 | */ | 88 | */ |
| 85 | ctype = ArcGetEnvironmentVariable("console"); | 89 | ctype = ArcGetEnvironmentVariable("console"); |
| 86 | if (ctype && *ctype == 'd') { | 90 | cserial = ArcGetEnvironmentVariable("ConsoleOut"); |
| 91 | |||
| 92 | if ((ctype && *ctype == 'd') || (cserial && *cserial == 's')) { | ||
| 87 | static char options[8]; | 93 | static char options[8]; |
| 88 | char *baud = ArcGetEnvironmentVariable("dbaud"); | 94 | char *baud = ArcGetEnvironmentVariable("dbaud"); |
| 89 | if (baud) | 95 | if (baud) |
| @@ -91,7 +97,7 @@ void __init plat_setup(void) | |||
| 91 | add_preferred_console("ttyS", *(ctype + 1) == '2' ? 1 : 0, | 97 | add_preferred_console("ttyS", *(ctype + 1) == '2' ? 1 : 0, |
| 92 | baud ? options : NULL); | 98 | baud ? options : NULL); |
| 93 | } else if (!ctype || *ctype != 'g') { | 99 | } else if (!ctype || *ctype != 'g') { |
| 94 | /* Use ARC if we don't want serial ('d') or Newport ('g'). */ | 100 | /* Use ARC if we don't want serial ('d') or graphics ('g'). */ |
| 95 | prom_flags |= PROM_FLAG_USE_AS_CONSOLE; | 101 | prom_flags |= PROM_FLAG_USE_AS_CONSOLE; |
| 96 | add_preferred_console("arc", 0, NULL); | 102 | add_preferred_console("arc", 0, NULL); |
| 97 | } | 103 | } |
diff --git a/arch/mips/sgi-ip27/ip27-reset.c b/arch/mips/sgi-ip27/ip27-reset.c index 2e16be94c78b..4322db57d3c1 100644 --- a/arch/mips/sgi-ip27/ip27-reset.c +++ b/arch/mips/sgi-ip27/ip27-reset.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * | 5 | * |
| 6 | * Reset an IP27. | 6 | * Reset an IP27. |
| 7 | * | 7 | * |
| 8 | * Copyright (C) 1997, 1998, 1999, 2000 by Ralf Baechle | 8 | * Copyright (C) 1997, 1998, 1999, 2000, 06 by Ralf Baechle |
| 9 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. | 9 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. |
| 10 | */ | 10 | */ |
| 11 | #include <linux/config.h> | 11 | #include <linux/config.h> |
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/smp.h> | 15 | #include <linux/smp.h> |
| 16 | #include <linux/mmzone.h> | 16 | #include <linux/mmzone.h> |
| 17 | #include <linux/nodemask.h> | 17 | #include <linux/nodemask.h> |
| 18 | #include <linux/pm.h> | ||
| 18 | 19 | ||
| 19 | #include <asm/io.h> | 20 | #include <asm/io.h> |
| 20 | #include <asm/irq.h> | 21 | #include <asm/irq.h> |
| @@ -77,5 +78,5 @@ void ip27_reboot_setup(void) | |||
| 77 | { | 78 | { |
| 78 | _machine_restart = ip27_machine_restart; | 79 | _machine_restart = ip27_machine_restart; |
| 79 | _machine_halt = ip27_machine_halt; | 80 | _machine_halt = ip27_machine_halt; |
| 80 | _machine_power_off = ip27_machine_power_off; | 81 | pm_power_off = ip27_machine_power_off; |
| 81 | } | 82 | } |
diff --git a/arch/mips/sgi-ip32/ip32-reset.c b/arch/mips/sgi-ip32/ip32-reset.c index 88e1f52059ff..0c948008b023 100644 --- a/arch/mips/sgi-ip32/ip32-reset.c +++ b/arch/mips/sgi-ip32/ip32-reset.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
| 16 | #include <linux/ds17287rtc.h> | 16 | #include <linux/ds17287rtc.h> |
| 17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
| 18 | #include <linux/pm.h> | ||
| 18 | 19 | ||
| 19 | #include <asm/addrspace.h> | 20 | #include <asm/addrspace.h> |
| 20 | #include <asm/irq.h> | 21 | #include <asm/irq.h> |
| @@ -188,7 +189,7 @@ static __init int ip32_reboot_setup(void) | |||
| 188 | 189 | ||
| 189 | _machine_restart = ip32_machine_restart; | 190 | _machine_restart = ip32_machine_restart; |
| 190 | _machine_halt = ip32_machine_halt; | 191 | _machine_halt = ip32_machine_halt; |
| 191 | _machine_power_off = ip32_machine_power_off; | 192 | pm_power_off = ip32_machine_power_off; |
| 192 | 193 | ||
| 193 | init_timer(&blink_timer); | 194 | init_timer(&blink_timer); |
| 194 | blink_timer.function = blink_timeout; | 195 | blink_timer.function = blink_timeout; |
diff --git a/arch/mips/sgi-ip32/ip32-setup.c b/arch/mips/sgi-ip32/ip32-setup.c index d10a269aeae1..2c38770b1e1b 100644 --- a/arch/mips/sgi-ip32/ip32-setup.c +++ b/arch/mips/sgi-ip32/ip32-setup.c | |||
| @@ -66,11 +66,6 @@ static inline void str2eaddr(unsigned char *ea, unsigned char *str) | |||
| 66 | #include <linux/tty.h> | 66 | #include <linux/tty.h> |
| 67 | #include <linux/serial.h> | 67 | #include <linux/serial.h> |
| 68 | #include <linux/serial_core.h> | 68 | #include <linux/serial_core.h> |
| 69 | extern int early_serial_setup(struct uart_port *port); | ||
| 70 | |||
| 71 | #define STD_COM_FLAGS (ASYNC_SKIP_TEST) | ||
| 72 | #define BASE_BAUD (1843200 / 16) | ||
| 73 | |||
| 74 | #endif /* CONFIG_SERIAL_8250 */ | 69 | #endif /* CONFIG_SERIAL_8250 */ |
| 75 | 70 | ||
| 76 | /* An arbitrary time; this can be decreased if reliability looks good */ | 71 | /* An arbitrary time; this can be decreased if reliability looks good */ |
| @@ -110,8 +105,8 @@ void __init plat_setup(void) | |||
| 110 | o2_serial[0].type = PORT_16550A; | 105 | o2_serial[0].type = PORT_16550A; |
| 111 | o2_serial[0].line = 0; | 106 | o2_serial[0].line = 0; |
| 112 | o2_serial[0].irq = MACEISA_SERIAL1_IRQ; | 107 | o2_serial[0].irq = MACEISA_SERIAL1_IRQ; |
| 113 | o2_serial[0].flags = STD_COM_FLAGS; | 108 | o2_serial[0].flags = UPF_SKIP_TEST; |
| 114 | o2_serial[0].uartclk = BASE_BAUD * 16; | 109 | o2_serial[0].uartclk = 1843200; |
| 115 | o2_serial[0].iotype = UPIO_MEM; | 110 | o2_serial[0].iotype = UPIO_MEM; |
| 116 | o2_serial[0].membase = (char *)&mace->isa.serial1; | 111 | o2_serial[0].membase = (char *)&mace->isa.serial1; |
| 117 | o2_serial[0].fifosize = 14; | 112 | o2_serial[0].fifosize = 14; |
| @@ -121,8 +116,8 @@ void __init plat_setup(void) | |||
| 121 | o2_serial[1].type = PORT_16550A; | 116 | o2_serial[1].type = PORT_16550A; |
| 122 | o2_serial[1].line = 1; | 117 | o2_serial[1].line = 1; |
| 123 | o2_serial[1].irq = MACEISA_SERIAL2_IRQ; | 118 | o2_serial[1].irq = MACEISA_SERIAL2_IRQ; |
| 124 | o2_serial[1].flags = STD_COM_FLAGS; | 119 | o2_serial[1].flags = UPF_SKIP_TEST; |
| 125 | o2_serial[1].uartclk = BASE_BAUD * 16; | 120 | o2_serial[1].uartclk = 1843200; |
| 126 | o2_serial[1].iotype = UPIO_MEM; | 121 | o2_serial[1].iotype = UPIO_MEM; |
| 127 | o2_serial[1].membase = (char *)&mace->isa.serial2; | 122 | o2_serial[1].membase = (char *)&mace->isa.serial2; |
| 128 | o2_serial[1].fifosize = 14; | 123 | o2_serial[1].fifosize = 14; |
diff --git a/arch/mips/sibyte/cfe/setup.c b/arch/mips/sibyte/cfe/setup.c index 7a2c7a8510d4..ea308029450e 100644 --- a/arch/mips/sibyte/cfe/setup.c +++ b/arch/mips/sibyte/cfe/setup.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
| 24 | #include <linux/blkdev.h> | 24 | #include <linux/blkdev.h> |
| 25 | #include <linux/bootmem.h> | 25 | #include <linux/bootmem.h> |
| 26 | #include <linux/pm.h> | ||
| 26 | #include <linux/smp.h> | 27 | #include <linux/smp.h> |
| 27 | 28 | ||
| 28 | #include <asm/bootinfo.h> | 29 | #include <asm/bootinfo.h> |
| @@ -248,7 +249,7 @@ void __init prom_init(void) | |||
| 248 | 249 | ||
| 249 | _machine_restart = cfe_linux_restart; | 250 | _machine_restart = cfe_linux_restart; |
| 250 | _machine_halt = cfe_linux_halt; | 251 | _machine_halt = cfe_linux_halt; |
| 251 | _machine_power_off = cfe_linux_halt; | 252 | pm_power_off = cfe_linux_halt; |
| 252 | 253 | ||
| 253 | /* | 254 | /* |
| 254 | * Check if a loader was used; if NOT, the 4 arguments are | 255 | * Check if a loader was used; if NOT, the 4 arguments are |
diff --git a/arch/mips/sibyte/sb1250/prom.c b/arch/mips/sibyte/sb1250/prom.c index de62ab0f55a2..742043f8d755 100644 --- a/arch/mips/sibyte/sb1250/prom.c +++ b/arch/mips/sibyte/sb1250/prom.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/bootmem.h> | 24 | #include <linux/bootmem.h> |
| 25 | #include <linux/smp.h> | 25 | #include <linux/smp.h> |
| 26 | #include <linux/initrd.h> | 26 | #include <linux/initrd.h> |
| 27 | #include <linux/pm.h> | ||
| 27 | 28 | ||
| 28 | #include <asm/bootinfo.h> | 29 | #include <asm/bootinfo.h> |
| 29 | #include <asm/reboot.h> | 30 | #include <asm/reboot.h> |
| @@ -79,7 +80,7 @@ void __init prom_init(void) | |||
| 79 | { | 80 | { |
| 80 | _machine_restart = (void (*)(char *))prom_linux_exit; | 81 | _machine_restart = (void (*)(char *))prom_linux_exit; |
| 81 | _machine_halt = prom_linux_exit; | 82 | _machine_halt = prom_linux_exit; |
| 82 | _machine_power_off = prom_linux_exit; | 83 | pm_power_off = prom_linux_exit; |
| 83 | 84 | ||
| 84 | strcpy(arcs_cmdline, "root=/dev/ram0 "); | 85 | strcpy(arcs_cmdline, "root=/dev/ram0 "); |
| 85 | 86 | ||
diff --git a/arch/mips/sibyte/sb1250/setup.c b/arch/mips/sibyte/sb1250/setup.c index df2e266c700c..fde4751c84fe 100644 --- a/arch/mips/sibyte/sb1250/setup.c +++ b/arch/mips/sibyte/sb1250/setup.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 17 | */ | 17 | */ |
| 18 | #include <linux/config.h> | 18 | #include <linux/config.h> |
| 19 | #include <linux/init.h> | ||
| 19 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
| 20 | #include <linux/reboot.h> | 21 | #include <linux/reboot.h> |
| 21 | #include <linux/string.h> | 22 | #include <linux/string.h> |
| @@ -42,7 +43,7 @@ static inline int setup_bcm112x(void); | |||
| 42 | 43 | ||
| 43 | /* Setup code likely to be common to all SiByte platforms */ | 44 | /* Setup code likely to be common to all SiByte platforms */ |
| 44 | 45 | ||
| 45 | static inline int sys_rev_decode(void) | 46 | static int __init sys_rev_decode(void) |
| 46 | { | 47 | { |
| 47 | int ret = 0; | 48 | int ret = 0; |
| 48 | 49 | ||
| @@ -74,7 +75,7 @@ static inline int sys_rev_decode(void) | |||
| 74 | return ret; | 75 | return ret; |
| 75 | } | 76 | } |
| 76 | 77 | ||
| 77 | static inline int setup_bcm1250(void) | 78 | static int __init setup_bcm1250(void) |
| 78 | { | 79 | { |
| 79 | int ret = 0; | 80 | int ret = 0; |
| 80 | 81 | ||
| @@ -120,7 +121,7 @@ static inline int setup_bcm1250(void) | |||
| 120 | return ret; | 121 | return ret; |
| 121 | } | 122 | } |
| 122 | 123 | ||
| 123 | static inline int setup_bcm112x(void) | 124 | static int __init setup_bcm112x(void) |
| 124 | { | 125 | { |
| 125 | int ret = 0; | 126 | int ret = 0; |
| 126 | 127 | ||
| @@ -146,7 +147,7 @@ static inline int setup_bcm112x(void) | |||
| 146 | return ret; | 147 | return ret; |
| 147 | } | 148 | } |
| 148 | 149 | ||
| 149 | void sb1250_setup(void) | 150 | void __init sb1250_setup(void) |
| 150 | { | 151 | { |
| 151 | uint64_t sys_rev; | 152 | uint64_t sys_rev; |
| 152 | int plldiv; | 153 | int plldiv; |
| @@ -169,31 +170,42 @@ void sb1250_setup(void) | |||
| 169 | soc_str, pass_str, zbbus_mhz * 2, sb1_pass); | 170 | soc_str, pass_str, zbbus_mhz * 2, sb1_pass); |
| 170 | prom_printf("Board type: %s\n", get_system_type()); | 171 | prom_printf("Board type: %s\n", get_system_type()); |
| 171 | 172 | ||
| 172 | switch(war_pass) { | 173 | switch (war_pass) { |
| 173 | case K_SYS_REVISION_BCM1250_PASS1: | 174 | case K_SYS_REVISION_BCM1250_PASS1: |
| 174 | #ifndef CONFIG_SB1_PASS_1_WORKAROUNDS | 175 | #ifndef CONFIG_SB1_PASS_1_WORKAROUNDS |
| 175 | prom_printf("@@@@ This is a BCM1250 A0-A2 (Pass 1) board, and the kernel doesn't have the proper workarounds compiled in. @@@@\n"); | 176 | prom_printf("@@@@ This is a BCM1250 A0-A2 (Pass 1) board, " |
| 177 | "and the kernel doesn't have the proper " | ||
| 178 | "workarounds compiled in. @@@@\n"); | ||
| 176 | bad_config = 1; | 179 | bad_config = 1; |
| 177 | #endif | 180 | #endif |
| 178 | break; | 181 | break; |
| 179 | case K_SYS_REVISION_BCM1250_PASS2: | 182 | case K_SYS_REVISION_BCM1250_PASS2: |
| 180 | /* Pass 2 - easiest as default for now - so many numbers */ | 183 | /* Pass 2 - easiest as default for now - so many numbers */ |
| 181 | #if !defined(CONFIG_SB1_PASS_2_WORKAROUNDS) || !defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS) | 184 | #if !defined(CONFIG_SB1_PASS_2_WORKAROUNDS) || \ |
| 182 | prom_printf("@@@@ This is a BCM1250 A3-A10 board, and the kernel doesn't have the proper workarounds compiled in. @@@@\n"); | 185 | !defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS) |
| 186 | prom_printf("@@@@ This is a BCM1250 A3-A10 board, and the " | ||
| 187 | "kernel doesn't have the proper workarounds " | ||
| 188 | "compiled in. @@@@\n"); | ||
| 183 | bad_config = 1; | 189 | bad_config = 1; |
| 184 | #endif | 190 | #endif |
| 185 | #ifdef CONFIG_CPU_HAS_PREFETCH | 191 | #ifdef CONFIG_CPU_HAS_PREFETCH |
| 186 | prom_printf("@@@@ Prefetches may be enabled in this kernel, but are buggy on this board. @@@@\n"); | 192 | prom_printf("@@@@ Prefetches may be enabled in this kernel, " |
| 193 | "but are buggy on this board. @@@@\n"); | ||
| 187 | bad_config = 1; | 194 | bad_config = 1; |
| 188 | #endif | 195 | #endif |
| 189 | break; | 196 | break; |
| 190 | case K_SYS_REVISION_BCM1250_PASS2_2: | 197 | case K_SYS_REVISION_BCM1250_PASS2_2: |
| 191 | #ifndef CONFIG_SB1_PASS_2_WORKAROUNDS | 198 | #ifndef CONFIG_SB1_PASS_2_WORKAROUNDS |
| 192 | prom_printf("@@@@ This is a BCM1250 B1/B2. board, and the kernel doesn't have the proper workarounds compiled in. @@@@\n"); | 199 | prom_printf("@@@@ This is a BCM1250 B1/B2. board, and the " |
| 200 | "kernel doesn't have the proper workarounds " | ||
| 201 | "compiled in. @@@@\n"); | ||
| 193 | bad_config = 1; | 202 | bad_config = 1; |
| 194 | #endif | 203 | #endif |
| 195 | #if defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS) || !defined(CONFIG_CPU_HAS_PREFETCH) | 204 | #if defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS) || \ |
| 196 | prom_printf("@@@@ This is a BCM1250 B1/B2, but the kernel is conservatively configured for an 'A' stepping. @@@@\n"); | 205 | !defined(CONFIG_CPU_HAS_PREFETCH) |
| 206 | prom_printf("@@@@ This is a BCM1250 B1/B2, but the kernel is " | ||
| 207 | "conservatively configured for an 'A' stepping. " | ||
| 208 | "@@@@\n"); | ||
| 197 | #endif | 209 | #endif |
| 198 | break; | 210 | break; |
| 199 | default: | 211 | default: |
diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c index 262c85680709..1141fcd13a59 100644 --- a/arch/mips/sni/setup.c +++ b/arch/mips/sni/setup.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * License. See the file "COPYING" in the main directory of this archive | 5 | * License. See the file "COPYING" in the main directory of this archive |
| 6 | * for more details. | 6 | * for more details. |
| 7 | * | 7 | * |
| 8 | * Copyright (C) 1996, 97, 98, 2000, 03, 04 Ralf Baechle (ralf@linux-mips.org) | 8 | * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org) |
| 9 | */ | 9 | */ |
| 10 | #include <linux/config.h> | 10 | #include <linux/config.h> |
| 11 | #include <linux/eisa.h> | 11 | #include <linux/eisa.h> |
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
| 16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
| 17 | #include <linux/mc146818rtc.h> | 17 | #include <linux/mc146818rtc.h> |
| 18 | #include <linux/pm.h> | ||
| 18 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
| 19 | #include <linux/console.h> | 20 | #include <linux/console.h> |
| 20 | #include <linux/fb.h> | 21 | #include <linux/fb.h> |
| @@ -189,7 +190,7 @@ void __init plat_setup(void) | |||
| 189 | 190 | ||
| 190 | _machine_restart = sni_machine_restart; | 191 | _machine_restart = sni_machine_restart; |
| 191 | _machine_halt = sni_machine_halt; | 192 | _machine_halt = sni_machine_halt; |
| 192 | _machine_power_off = sni_machine_power_off; | 193 | pm_power_off = sni_machine_power_off; |
| 193 | 194 | ||
| 194 | sni_display_setup(); | 195 | sni_display_setup(); |
| 195 | 196 | ||
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c index e4d095d3e192..e19e2be70f76 100644 --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_prom.c | |||
| @@ -60,7 +60,6 @@ void __init prom_init_cmdline(void) | |||
| 60 | 60 | ||
| 61 | void __init prom_init(void) | 61 | void __init prom_init(void) |
| 62 | { | 62 | { |
| 63 | const char* toshiba_name_list[] = GROUP_TOSHIBA_NAMES; | ||
| 64 | extern int tx4927_get_mem_size(void); | 63 | extern int tx4927_get_mem_size(void); |
| 65 | extern char* toshiba_name; | 64 | extern char* toshiba_name; |
| 66 | int msize; | 65 | int msize; |
| @@ -69,12 +68,13 @@ void __init prom_init(void) | |||
| 69 | 68 | ||
| 70 | mips_machgroup = MACH_GROUP_TOSHIBA; | 69 | mips_machgroup = MACH_GROUP_TOSHIBA; |
| 71 | 70 | ||
| 72 | if ((read_c0_prid() & 0xff) == PRID_REV_TX4927) | 71 | if ((read_c0_prid() & 0xff) == PRID_REV_TX4927) { |
| 73 | mips_machtype = MACH_TOSHIBA_RBTX4927; | 72 | mips_machtype = MACH_TOSHIBA_RBTX4927; |
| 74 | else | 73 | toshiba_name = "TX4927"; |
| 74 | } else { | ||
| 75 | mips_machtype = MACH_TOSHIBA_RBTX4937; | 75 | mips_machtype = MACH_TOSHIBA_RBTX4937; |
| 76 | 76 | toshiba_name = "TX4937"; | |
| 77 | toshiba_name = toshiba_name_list[mips_machtype]; | 77 | } |
| 78 | 78 | ||
| 79 | msize = tx4927_get_mem_size(); | 79 | msize = tx4927_get_mem_size(); |
| 80 | add_memory_region(0, msize << 20, BOOT_MEM_RAM); | 80 | add_memory_region(0, msize << 20, BOOT_MEM_RAM); |
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c index 990fcb294bab..2ad6401d2af4 100644 --- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c +++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c | |||
| @@ -53,6 +53,8 @@ | |||
| 53 | #include <linux/interrupt.h> | 53 | #include <linux/interrupt.h> |
| 54 | #include <linux/pci.h> | 54 | #include <linux/pci.h> |
| 55 | #include <linux/timex.h> | 55 | #include <linux/timex.h> |
| 56 | #include <linux/pm.h> | ||
| 57 | |||
| 56 | #include <asm/bootinfo.h> | 58 | #include <asm/bootinfo.h> |
| 57 | #include <asm/page.h> | 59 | #include <asm/page.h> |
| 58 | #include <asm/io.h> | 60 | #include <asm/io.h> |
| @@ -537,19 +539,10 @@ void tx4927_pci_setup(void) | |||
| 537 | TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, | 539 | TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, |
| 538 | "0x%08lx=mips_io_port_base", | 540 | "0x%08lx=mips_io_port_base", |
| 539 | mips_io_port_base); | 541 | mips_io_port_base); |
| 540 | |||
| 541 | TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, | ||
| 542 | "setup pci_io_resource to 0x%08lx 0x%08lx\n", | ||
| 543 | pci_io_resource.start, | ||
| 544 | pci_io_resource.end); | ||
| 545 | TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI2, | ||
| 546 | "setup pci_mem_resource to 0x%08lx 0x%08lx\n", | ||
| 547 | pci_mem_resource.start, | ||
| 548 | pci_mem_resource.end); | ||
| 549 | |||
| 550 | if (!called) { | 542 | if (!called) { |
| 551 | printk | 543 | printk |
| 552 | ("TX4927 PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n", | 544 | ("%s PCIC -- DID:%04x VID:%04x RID:%02x Arbiter:%s\n", |
| 545 | toshiba_name, | ||
| 553 | (unsigned short) (tx4927_pcicptr->pciid >> 16), | 546 | (unsigned short) (tx4927_pcicptr->pciid >> 16), |
| 554 | (unsigned short) (tx4927_pcicptr->pciid & 0xffff), | 547 | (unsigned short) (tx4927_pcicptr->pciid & 0xffff), |
| 555 | (unsigned short) (tx4927_pcicptr->pciccrev & 0xff), | 548 | (unsigned short) (tx4927_pcicptr->pciccrev & 0xff), |
| @@ -562,21 +555,52 @@ void tx4927_pci_setup(void) | |||
| 562 | (tx4927_ccfgptr->ccfg & TX4927_CCFG_PCI66) ? " PCI66" : ""); | 555 | (tx4927_ccfgptr->ccfg & TX4927_CCFG_PCI66) ? " PCI66" : ""); |
| 563 | if (tx4927_ccfgptr->pcfg & TX4927_PCFG_PCICLKEN_ALL) { | 556 | if (tx4927_ccfgptr->pcfg & TX4927_PCFG_PCICLKEN_ALL) { |
| 564 | int pciclk = 0; | 557 | int pciclk = 0; |
| 565 | switch ((unsigned long) tx4927_ccfgptr-> | 558 | if (mips_machtype == MACH_TOSHIBA_RBTX4937) |
| 566 | ccfg & TX4927_CCFG_PCIDIVMODE_MASK) { | 559 | switch ((unsigned long) tx4927_ccfgptr-> |
| 567 | case TX4927_CCFG_PCIDIVMODE_2_5: | 560 | ccfg & TX4937_CCFG_PCIDIVMODE_MASK) { |
| 568 | pciclk = tx4927_cpu_clock * 2 / 5; | 561 | case TX4937_CCFG_PCIDIVMODE_4: |
| 569 | break; | 562 | pciclk = tx4927_cpu_clock / 4; |
| 570 | case TX4927_CCFG_PCIDIVMODE_3: | 563 | break; |
| 571 | pciclk = tx4927_cpu_clock / 3; | 564 | case TX4937_CCFG_PCIDIVMODE_4_5: |
| 572 | break; | 565 | pciclk = tx4927_cpu_clock * 2 / 9; |
| 573 | case TX4927_CCFG_PCIDIVMODE_5: | 566 | break; |
| 574 | pciclk = tx4927_cpu_clock / 5; | 567 | case TX4937_CCFG_PCIDIVMODE_5: |
| 575 | break; | 568 | pciclk = tx4927_cpu_clock / 5; |
| 576 | case TX4927_CCFG_PCIDIVMODE_6: | 569 | break; |
| 577 | pciclk = tx4927_cpu_clock / 6; | 570 | case TX4937_CCFG_PCIDIVMODE_5_5: |
| 578 | break; | 571 | pciclk = tx4927_cpu_clock * 2 / 11; |
| 579 | } | 572 | break; |
| 573 | case TX4937_CCFG_PCIDIVMODE_8: | ||
| 574 | pciclk = tx4927_cpu_clock / 8; | ||
| 575 | break; | ||
| 576 | case TX4937_CCFG_PCIDIVMODE_9: | ||
| 577 | pciclk = tx4927_cpu_clock / 9; | ||
| 578 | break; | ||
| 579 | case TX4937_CCFG_PCIDIVMODE_10: | ||
| 580 | pciclk = tx4927_cpu_clock / 10; | ||
| 581 | break; | ||
| 582 | case TX4937_CCFG_PCIDIVMODE_11: | ||
| 583 | pciclk = tx4927_cpu_clock / 11; | ||
| 584 | break; | ||
| 585 | } | ||
| 586 | |||
| 587 | else | ||
| 588 | switch ((unsigned long) tx4927_ccfgptr-> | ||
| 589 | ccfg & TX4927_CCFG_PCIDIVMODE_MASK) { | ||
| 590 | case TX4927_CCFG_PCIDIVMODE_2_5: | ||
| 591 | pciclk = tx4927_cpu_clock * 2 / 5; | ||
| 592 | break; | ||
| 593 | case TX4927_CCFG_PCIDIVMODE_3: | ||
| 594 | pciclk = tx4927_cpu_clock / 3; | ||
| 595 | break; | ||
| 596 | case TX4927_CCFG_PCIDIVMODE_5: | ||
| 597 | pciclk = tx4927_cpu_clock / 5; | ||
| 598 | break; | ||
| 599 | case TX4927_CCFG_PCIDIVMODE_6: | ||
| 600 | pciclk = tx4927_cpu_clock / 6; | ||
| 601 | break; | ||
| 602 | } | ||
| 603 | |||
| 580 | printk("Internal(%dMHz)", pciclk / 1000000); | 604 | printk("Internal(%dMHz)", pciclk / 1000000); |
| 581 | } else { | 605 | } else { |
| 582 | int pciclk = 0; | 606 | int pciclk = 0; |
| @@ -814,24 +838,40 @@ void __init toshiba_rbtx4927_setup(void) | |||
| 814 | ":ResetRoutines\n"); | 838 | ":ResetRoutines\n"); |
| 815 | _machine_restart = toshiba_rbtx4927_restart; | 839 | _machine_restart = toshiba_rbtx4927_restart; |
| 816 | _machine_halt = toshiba_rbtx4927_halt; | 840 | _machine_halt = toshiba_rbtx4927_halt; |
| 817 | _machine_power_off = toshiba_rbtx4927_power_off; | 841 | pm_power_off = toshiba_rbtx4927_power_off; |
| 818 | 842 | ||
| 819 | #ifdef CONFIG_PCI | 843 | #ifdef CONFIG_PCI |
| 820 | 844 | ||
| 821 | /* PCIC */ | 845 | /* PCIC */ |
| 822 | /* | 846 | /* |
| 823 | * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz. | 847 | * ASSUMPTION: PCIDIVMODE is configured for PCI 33MHz or 66MHz. |
| 824 | * PCIDIVMODE[12:11]'s initial value are given by S9[4:3] (ON:0, OFF:1). | 848 | * |
| 849 | * For TX4927: | ||
| 850 | * PCIDIVMODE[12:11]'s initial value is given by S9[4:3] (ON:0, OFF:1). | ||
| 825 | * CPU 166MHz: PCI 66MHz : PCIDIVMODE: 00 (1/2.5) | 851 | * CPU 166MHz: PCI 66MHz : PCIDIVMODE: 00 (1/2.5) |
| 826 | * CPU 200MHz: PCI 66MHz : PCIDIVMODE: 01 (1/3) | 852 | * CPU 200MHz: PCI 66MHz : PCIDIVMODE: 01 (1/3) |
| 827 | * CPU 166MHz: PCI 33MHz : PCIDIVMODE: 10 (1/5) | 853 | * CPU 166MHz: PCI 33MHz : PCIDIVMODE: 10 (1/5) |
| 828 | * CPU 200MHz: PCI 33MHz : PCIDIVMODE: 11 (1/6) | 854 | * CPU 200MHz: PCI 33MHz : PCIDIVMODE: 11 (1/6) |
| 829 | * i.e. S9[3]: ON (83MHz), OFF (100MHz) | 855 | * i.e. S9[3]: ON (83MHz), OFF (100MHz) |
| 856 | * | ||
| 857 | * For TX4937: | ||
| 858 | * PCIDIVMODE[12:11]'s initial value is given by S1[5:4] (ON:0, OFF:1) | ||
| 859 | * PCIDIVMODE[10] is 0. | ||
| 860 | * CPU 266MHz: PCI 33MHz : PCIDIVMODE: 000 (1/8) | ||
| 861 | * CPU 266MHz: PCI 66MHz : PCIDIVMODE: 001 (1/4) | ||
| 862 | * CPU 300MHz: PCI 33MHz : PCIDIVMODE: 010 (1/9) | ||
| 863 | * CPU 300MHz: PCI 66MHz : PCIDIVMODE: 011 (1/4.5) | ||
| 864 | * CPU 333MHz: PCI 33MHz : PCIDIVMODE: 100 (1/10) | ||
| 865 | * CPU 333MHz: PCI 66MHz : PCIDIVMODE: 101 (1/5) | ||
| 866 | * | ||
| 830 | */ | 867 | */ |
| 831 | TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1, | 868 | TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1, |
| 832 | "ccfg is %lx, DIV is %x\n", | 869 | "ccfg is %lx, PCIDIVMODE is %x\n", |
| 833 | (unsigned long) tx4927_ccfgptr-> | 870 | (unsigned long) tx4927_ccfgptr->ccfg, |
| 834 | ccfg, TX4927_CCFG_PCIDIVMODE_MASK); | 871 | (unsigned long) tx4927_ccfgptr->ccfg & |
| 872 | (mips_machtype == MACH_TOSHIBA_RBTX4937 ? | ||
| 873 | TX4937_CCFG_PCIDIVMODE_MASK : | ||
| 874 | TX4927_CCFG_PCIDIVMODE_MASK)); | ||
| 835 | 875 | ||
| 836 | TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1, | 876 | TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1, |
| 837 | "PCI66 mode is %lx, PCI mode is %lx, pci arb is %lx\n", | 877 | "PCI66 mode is %lx, PCI mode is %lx, pci arb is %lx\n", |
| @@ -842,20 +882,30 @@ void __init toshiba_rbtx4927_setup(void) | |||
| 842 | (unsigned long) tx4927_ccfgptr-> | 882 | (unsigned long) tx4927_ccfgptr-> |
| 843 | ccfg & TX4927_CCFG_PCIXARB); | 883 | ccfg & TX4927_CCFG_PCIXARB); |
| 844 | 884 | ||
| 845 | TOSHIBA_RBTX4927_SETUP_DPRINTK(TOSHIBA_RBTX4927_SETUP_PCI1, | 885 | if (mips_machtype == MACH_TOSHIBA_RBTX4937) |
| 846 | "PCIDIVMODE is %lx\n", | 886 | switch ((unsigned long)tx4927_ccfgptr-> |
| 847 | (unsigned long) tx4927_ccfgptr-> | 887 | ccfg & TX4937_CCFG_PCIDIVMODE_MASK) { |
| 848 | ccfg & TX4927_CCFG_PCIDIVMODE_MASK); | 888 | case TX4937_CCFG_PCIDIVMODE_8: |
| 849 | 889 | case TX4937_CCFG_PCIDIVMODE_4: | |
| 850 | switch ((unsigned long) tx4927_ccfgptr-> | 890 | tx4927_cpu_clock = 266666666; /* 266MHz */ |
| 851 | ccfg & TX4927_CCFG_PCIDIVMODE_MASK) { | 891 | break; |
| 852 | case TX4927_CCFG_PCIDIVMODE_2_5: | 892 | case TX4937_CCFG_PCIDIVMODE_9: |
| 853 | case TX4927_CCFG_PCIDIVMODE_5: | 893 | case TX4937_CCFG_PCIDIVMODE_4_5: |
| 854 | tx4927_cpu_clock = 166000000; /* 166MHz */ | 894 | tx4927_cpu_clock = 300000000; /* 300MHz */ |
| 855 | break; | 895 | break; |
| 856 | default: | 896 | default: |
| 857 | tx4927_cpu_clock = 200000000; /* 200MHz */ | 897 | tx4927_cpu_clock = 333333333; /* 333MHz */ |
| 858 | } | 898 | } |
| 899 | else | ||
| 900 | switch ((unsigned long)tx4927_ccfgptr-> | ||
| 901 | ccfg & TX4927_CCFG_PCIDIVMODE_MASK) { | ||
| 902 | case TX4927_CCFG_PCIDIVMODE_2_5: | ||
| 903 | case TX4927_CCFG_PCIDIVMODE_5: | ||
| 904 | tx4927_cpu_clock = 166666666; /* 166MHz */ | ||
| 905 | break; | ||
| 906 | default: | ||
| 907 | tx4927_cpu_clock = 200000000; /* 200MHz */ | ||
| 908 | } | ||
| 859 | 909 | ||
| 860 | /* CCFG */ | 910 | /* CCFG */ |
| 861 | /* enable Timeout BusError */ | 911 | /* enable Timeout BusError */ |
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c index 9f1dcc8ca5a3..5c7ace982a49 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c +++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c | |||
| @@ -20,6 +20,8 @@ | |||
| 20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
| 21 | #include <linux/console.h> | 21 | #include <linux/console.h> |
| 22 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
| 23 | #include <linux/pm.h> | ||
| 24 | |||
| 23 | #include <asm/wbflush.h> | 25 | #include <asm/wbflush.h> |
| 24 | #include <asm/reboot.h> | 26 | #include <asm/reboot.h> |
| 25 | #include <asm/irq.h> | 27 | #include <asm/irq.h> |
| @@ -1003,7 +1005,7 @@ void __init toshiba_rbtx4938_setup(void) | |||
| 1003 | 1005 | ||
| 1004 | _machine_restart = rbtx4938_machine_restart; | 1006 | _machine_restart = rbtx4938_machine_restart; |
| 1005 | _machine_halt = rbtx4938_machine_halt; | 1007 | _machine_halt = rbtx4938_machine_halt; |
| 1006 | _machine_power_off = rbtx4938_machine_power_off; | 1008 | pm_power_off = rbtx4938_machine_power_off; |
| 1007 | 1009 | ||
| 1008 | *rbtx4938_led_ptr = 0xff; | 1010 | *rbtx4938_led_ptr = 0xff; |
| 1009 | printk("RBTX4938 --- FPGA(Rev %02x)", *rbtx4938_fpga_rev_ptr); | 1011 | printk("RBTX4938 --- FPGA(Rev %02x)", *rbtx4938_fpga_rev_ptr); |
diff --git a/arch/mips/vr41xx/common/pmu.c b/arch/mips/vr41xx/common/pmu.c index 02bf4f7d06ba..5e469796413f 100644 --- a/arch/mips/vr41xx/common/pmu.c +++ b/arch/mips/vr41xx/common/pmu.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
| 22 | #include <linux/ioport.h> | 22 | #include <linux/ioport.h> |
| 23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
| 24 | #include <linux/pm.h> | ||
| 24 | #include <linux/smp.h> | 25 | #include <linux/smp.h> |
| 25 | #include <linux/types.h> | 26 | #include <linux/types.h> |
| 26 | 27 | ||
| @@ -114,7 +115,7 @@ static int __init vr41xx_pmu_init(void) | |||
| 114 | 115 | ||
| 115 | _machine_restart = vr41xx_restart; | 116 | _machine_restart = vr41xx_restart; |
| 116 | _machine_halt = vr41xx_halt; | 117 | _machine_halt = vr41xx_halt; |
| 117 | _machine_power_off = vr41xx_power_off; | 118 | pm_power_off = vr41xx_power_off; |
| 118 | 119 | ||
| 119 | return 0; | 120 | return 0; |
| 120 | } | 121 | } |
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index e77a06e9621e..7c914a4c67c3 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig | |||
| @@ -149,14 +149,20 @@ config HOTPLUG_CPU | |||
| 149 | default y if SMP | 149 | default y if SMP |
| 150 | select HOTPLUG | 150 | select HOTPLUG |
| 151 | 151 | ||
| 152 | config ARCH_SELECT_MEMORY_MODEL | ||
| 153 | def_bool y | ||
| 154 | depends on 64BIT | ||
| 155 | |||
| 152 | config ARCH_DISCONTIGMEM_ENABLE | 156 | config ARCH_DISCONTIGMEM_ENABLE |
| 153 | bool "Discontiguous memory support (EXPERIMENTAL)" | 157 | def_bool y |
| 154 | depends on 64BIT && EXPERIMENTAL | 158 | depends on 64BIT |
| 155 | help | 159 | |
| 156 | Say Y to support efficient handling of discontiguous physical memory, | 160 | config ARCH_FLATMEM_ENABLE |
| 157 | for architectures which are either NUMA (Non-Uniform Memory Access) | 161 | def_bool y |
| 158 | or have huge holes in the physical address space for other reasons. | 162 | |
| 159 | See <file:Documentation/vm/numa> for more. | 163 | config ARCH_DISCONTIGMEM_DEFAULT |
| 164 | def_bool y | ||
| 165 | depends on ARCH_DISCONTIGMEM_ENABLE | ||
| 160 | 166 | ||
| 161 | source "kernel/Kconfig.hz" | 167 | source "kernel/Kconfig.hz" |
| 162 | source "mm/Kconfig" | 168 | source "mm/Kconfig" |
diff --git a/arch/parisc/Kconfig.debug b/arch/parisc/Kconfig.debug index 8caaed187a1f..9166bd117267 100644 --- a/arch/parisc/Kconfig.debug +++ b/arch/parisc/Kconfig.debug | |||
| @@ -11,4 +11,14 @@ config DEBUG_RWLOCK | |||
| 11 | too many attempts. If you suspect a rwlock problem or a kernel | 11 | too many attempts. If you suspect a rwlock problem or a kernel |
| 12 | hacker asks for this option then say Y. Otherwise say N. | 12 | hacker asks for this option then say Y. Otherwise say N. |
| 13 | 13 | ||
| 14 | config DEBUG_RODATA | ||
| 15 | bool "Write protect kernel read-only data structures" | ||
| 16 | depends on DEBUG_KERNEL | ||
| 17 | help | ||
| 18 | Mark the kernel read-only data as write-protected in the pagetables, | ||
| 19 | in order to catch accidental (and incorrect) writes to such const | ||
| 20 | data. This option may have a slight performance impact because a | ||
| 21 | portion of the kernel code won't be covered by a TLB anymore. | ||
| 22 | If in doubt, say "N". | ||
| 23 | |||
| 14 | endmenu | 24 | endmenu |
diff --git a/arch/parisc/configs/b180_defconfig b/arch/parisc/configs/b180_defconfig index 8819e7e6ae3f..37e98241ce4b 100644 --- a/arch/parisc/configs/b180_defconfig +++ b/arch/parisc/configs/b180_defconfig | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | # | 1 | # |
| 2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
| 3 | # Linux kernel version: 2.6.14-rc5-pa1 | 3 | # Linux kernel version: 2.6.16-rc1-pa0 |
| 4 | # Fri Oct 21 23:06:10 2005 | 4 | # Tue Jan 17 08:21:01 2006 |
| 5 | # | 5 | # |
| 6 | CONFIG_PARISC=y | 6 | CONFIG_PARISC=y |
| 7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
| @@ -29,8 +29,6 @@ CONFIG_SYSVIPC=y | |||
| 29 | # CONFIG_BSD_PROCESS_ACCT is not set | 29 | # CONFIG_BSD_PROCESS_ACCT is not set |
| 30 | CONFIG_SYSCTL=y | 30 | CONFIG_SYSCTL=y |
| 31 | # CONFIG_AUDIT is not set | 31 | # CONFIG_AUDIT is not set |
| 32 | # CONFIG_HOTPLUG is not set | ||
| 33 | CONFIG_KOBJECT_UEVENT=y | ||
| 34 | CONFIG_IKCONFIG=y | 32 | CONFIG_IKCONFIG=y |
| 35 | CONFIG_IKCONFIG_PROC=y | 33 | CONFIG_IKCONFIG_PROC=y |
| 36 | CONFIG_INITRAMFS_SOURCE="" | 34 | CONFIG_INITRAMFS_SOURCE="" |
| @@ -38,8 +36,10 @@ CONFIG_INITRAMFS_SOURCE="" | |||
| 38 | CONFIG_KALLSYMS=y | 36 | CONFIG_KALLSYMS=y |
| 39 | # CONFIG_KALLSYMS_ALL is not set | 37 | # CONFIG_KALLSYMS_ALL is not set |
| 40 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 38 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
| 39 | CONFIG_HOTPLUG=y | ||
| 41 | CONFIG_PRINTK=y | 40 | CONFIG_PRINTK=y |
| 42 | CONFIG_BUG=y | 41 | CONFIG_BUG=y |
| 42 | CONFIG_ELF_CORE=y | ||
| 43 | CONFIG_BASE_FULL=y | 43 | CONFIG_BASE_FULL=y |
| 44 | CONFIG_FUTEX=y | 44 | CONFIG_FUTEX=y |
| 45 | CONFIG_EPOLL=y | 45 | CONFIG_EPOLL=y |
| @@ -48,8 +48,10 @@ CONFIG_CC_ALIGN_FUNCTIONS=0 | |||
| 48 | CONFIG_CC_ALIGN_LABELS=0 | 48 | CONFIG_CC_ALIGN_LABELS=0 |
| 49 | CONFIG_CC_ALIGN_LOOPS=0 | 49 | CONFIG_CC_ALIGN_LOOPS=0 |
| 50 | CONFIG_CC_ALIGN_JUMPS=0 | 50 | CONFIG_CC_ALIGN_JUMPS=0 |
| 51 | CONFIG_SLAB=y | ||
| 51 | # CONFIG_TINY_SHMEM is not set | 52 | # CONFIG_TINY_SHMEM is not set |
| 52 | CONFIG_BASE_SMALL=0 | 53 | CONFIG_BASE_SMALL=0 |
| 54 | # CONFIG_SLOB is not set | ||
| 53 | 55 | ||
| 54 | # | 56 | # |
| 55 | # Loadable module support | 57 | # Loadable module support |
| @@ -57,10 +59,28 @@ CONFIG_BASE_SMALL=0 | |||
| 57 | CONFIG_MODULES=y | 59 | CONFIG_MODULES=y |
| 58 | # CONFIG_MODULE_UNLOAD is not set | 60 | # CONFIG_MODULE_UNLOAD is not set |
| 59 | CONFIG_OBSOLETE_MODPARM=y | 61 | CONFIG_OBSOLETE_MODPARM=y |
| 62 | CONFIG_MODVERSIONS=y | ||
| 60 | # CONFIG_MODULE_SRCVERSION_ALL is not set | 63 | # CONFIG_MODULE_SRCVERSION_ALL is not set |
| 61 | # CONFIG_KMOD is not set | 64 | # CONFIG_KMOD is not set |
| 62 | 65 | ||
| 63 | # | 66 | # |
| 67 | # Block layer | ||
| 68 | # | ||
| 69 | |||
| 70 | # | ||
| 71 | # IO Schedulers | ||
| 72 | # | ||
| 73 | CONFIG_IOSCHED_NOOP=y | ||
| 74 | CONFIG_IOSCHED_AS=y | ||
| 75 | CONFIG_IOSCHED_DEADLINE=y | ||
| 76 | CONFIG_IOSCHED_CFQ=y | ||
| 77 | # CONFIG_DEFAULT_AS is not set | ||
| 78 | # CONFIG_DEFAULT_DEADLINE is not set | ||
| 79 | CONFIG_DEFAULT_CFQ=y | ||
| 80 | # CONFIG_DEFAULT_NOOP is not set | ||
| 81 | CONFIG_DEFAULT_IOSCHED="cfq" | ||
| 82 | |||
| 83 | # | ||
| 64 | # Processor type and features | 84 | # Processor type and features |
| 65 | # | 85 | # |
| 66 | # CONFIG_PA7000 is not set | 86 | # CONFIG_PA7000 is not set |
| @@ -77,6 +97,7 @@ CONFIG_HZ=250 | |||
| 77 | CONFIG_FLATMEM=y | 97 | CONFIG_FLATMEM=y |
| 78 | CONFIG_FLAT_NODE_MEM_MAP=y | 98 | CONFIG_FLAT_NODE_MEM_MAP=y |
| 79 | # CONFIG_SPARSEMEM_STATIC is not set | 99 | # CONFIG_SPARSEMEM_STATIC is not set |
| 100 | CONFIG_SPLIT_PTLOCK_CPUS=4096 | ||
| 80 | # CONFIG_PREEMPT is not set | 101 | # CONFIG_PREEMPT is not set |
| 81 | # CONFIG_HPUX is not set | 102 | # CONFIG_HPUX is not set |
| 82 | 103 | ||
| @@ -84,8 +105,8 @@ CONFIG_FLAT_NODE_MEM_MAP=y | |||
| 84 | # Bus options (PCI, PCMCIA, EISA, GSC, ISA) | 105 | # Bus options (PCI, PCMCIA, EISA, GSC, ISA) |
| 85 | # | 106 | # |
| 86 | CONFIG_GSC=y | 107 | CONFIG_GSC=y |
| 87 | # CONFIG_HPPB is not set | 108 | CONFIG_HPPB=y |
| 88 | # CONFIG_IOMMU_CCIO is not set | 109 | CONFIG_IOMMU_CCIO=y |
| 89 | CONFIG_GSC_LASI=y | 110 | CONFIG_GSC_LASI=y |
| 90 | CONFIG_GSC_WAX=y | 111 | CONFIG_GSC_WAX=y |
| 91 | CONFIG_EISA=y | 112 | CONFIG_EISA=y |
| @@ -165,8 +186,11 @@ CONFIG_IPV6=y | |||
| 165 | # CONFIG_LLC2 is not set | 186 | # CONFIG_LLC2 is not set |
| 166 | # CONFIG_IPX is not set | 187 | # CONFIG_IPX is not set |
| 167 | # CONFIG_ATALK is not set | 188 | # CONFIG_ATALK is not set |
| 189 | |||
| 190 | # | ||
| 191 | # QoS and/or fair queueing | ||
| 192 | # | ||
| 168 | # CONFIG_NET_SCHED is not set | 193 | # CONFIG_NET_SCHED is not set |
| 169 | # CONFIG_NET_CLS_ROUTE is not set | ||
| 170 | 194 | ||
| 171 | # | 195 | # |
| 172 | # Network testing | 196 | # Network testing |
| @@ -205,6 +229,7 @@ CONFIG_STANDALONE=y | |||
| 205 | CONFIG_PARPORT=y | 229 | CONFIG_PARPORT=y |
| 206 | CONFIG_PARPORT_PC=y | 230 | CONFIG_PARPORT_PC=y |
| 207 | # CONFIG_PARPORT_SERIAL is not set | 231 | # CONFIG_PARPORT_SERIAL is not set |
| 232 | CONFIG_PARPORT_NOT_PC=y | ||
| 208 | CONFIG_PARPORT_GSC=y | 233 | CONFIG_PARPORT_GSC=y |
| 209 | # CONFIG_PARPORT_1284 is not set | 234 | # CONFIG_PARPORT_1284 is not set |
| 210 | 235 | ||
| @@ -230,14 +255,6 @@ CONFIG_BLK_DEV_RAM_COUNT=16 | |||
| 230 | CONFIG_CDROM_PKTCDVD=m | 255 | CONFIG_CDROM_PKTCDVD=m |
| 231 | CONFIG_CDROM_PKTCDVD_BUFFERS=8 | 256 | CONFIG_CDROM_PKTCDVD_BUFFERS=8 |
| 232 | # CONFIG_CDROM_PKTCDVD_WCACHE is not set | 257 | # CONFIG_CDROM_PKTCDVD_WCACHE is not set |
| 233 | |||
| 234 | # | ||
| 235 | # IO Schedulers | ||
| 236 | # | ||
| 237 | CONFIG_IOSCHED_NOOP=y | ||
| 238 | CONFIG_IOSCHED_AS=y | ||
| 239 | CONFIG_IOSCHED_DEADLINE=y | ||
| 240 | CONFIG_IOSCHED_CFQ=y | ||
| 241 | CONFIG_ATA_OVER_ETH=y | 258 | CONFIG_ATA_OVER_ETH=y |
| 242 | 259 | ||
| 243 | # | 260 | # |
| @@ -281,6 +298,7 @@ CONFIG_SCSI_SPI_ATTRS=y | |||
| 281 | # | 298 | # |
| 282 | # SCSI low-level drivers | 299 | # SCSI low-level drivers |
| 283 | # | 300 | # |
| 301 | # CONFIG_ISCSI_TCP is not set | ||
| 284 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set | 302 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set |
| 285 | # CONFIG_SCSI_3W_9XXX is not set | 303 | # CONFIG_SCSI_3W_9XXX is not set |
| 286 | # CONFIG_SCSI_ACARD is not set | 304 | # CONFIG_SCSI_ACARD is not set |
| @@ -313,21 +331,19 @@ CONFIG_SCSI_SYM53C8XX_2=y | |||
| 313 | CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 | 331 | CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 |
| 314 | CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 | 332 | CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 |
| 315 | CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 | 333 | CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 |
| 316 | # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set | 334 | CONFIG_SCSI_SYM53C8XX_MMIO=y |
| 317 | # CONFIG_SCSI_IPR is not set | 335 | # CONFIG_SCSI_IPR is not set |
| 318 | # CONFIG_SCSI_ZALON is not set | 336 | CONFIG_SCSI_ZALON=y |
| 337 | CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 | ||
| 338 | CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 | ||
| 339 | CONFIG_SCSI_NCR53C8XX_SYNC=40 | ||
| 340 | # CONFIG_SCSI_NCR53C8XX_PROFILE is not set | ||
| 319 | # CONFIG_SCSI_PAS16 is not set | 341 | # CONFIG_SCSI_PAS16 is not set |
| 320 | # CONFIG_SCSI_PSI240I is not set | 342 | # CONFIG_SCSI_PSI240I is not set |
| 321 | # CONFIG_SCSI_QLOGIC_FAS is not set | 343 | # CONFIG_SCSI_QLOGIC_FAS is not set |
| 322 | # CONFIG_SCSI_QLOGIC_FC is not set | 344 | # CONFIG_SCSI_QLOGIC_FC is not set |
| 323 | # CONFIG_SCSI_QLOGIC_1280 is not set | 345 | # CONFIG_SCSI_QLOGIC_1280 is not set |
| 324 | CONFIG_SCSI_QLA2XXX=y | 346 | # CONFIG_SCSI_QLA_FC is not set |
| 325 | # CONFIG_SCSI_QLA21XX is not set | ||
| 326 | # CONFIG_SCSI_QLA22XX is not set | ||
| 327 | # CONFIG_SCSI_QLA2300 is not set | ||
| 328 | # CONFIG_SCSI_QLA2322 is not set | ||
| 329 | # CONFIG_SCSI_QLA6312 is not set | ||
| 330 | # CONFIG_SCSI_QLA24XX is not set | ||
| 331 | # CONFIG_SCSI_LPFC is not set | 347 | # CONFIG_SCSI_LPFC is not set |
| 332 | # CONFIG_SCSI_SIM710 is not set | 348 | # CONFIG_SCSI_SIM710 is not set |
| 333 | # CONFIG_SCSI_SYM53C416 is not set | 349 | # CONFIG_SCSI_SYM53C416 is not set |
| @@ -397,7 +413,7 @@ CONFIG_NETDEVICES=y | |||
| 397 | # | 413 | # |
| 398 | CONFIG_NET_ETHERNET=y | 414 | CONFIG_NET_ETHERNET=y |
| 399 | # CONFIG_MII is not set | 415 | # CONFIG_MII is not set |
| 400 | # CONFIG_LASI_82596 is not set | 416 | CONFIG_LASI_82596=y |
| 401 | # CONFIG_HAPPYMEAL is not set | 417 | # CONFIG_HAPPYMEAL is not set |
| 402 | # CONFIG_SUNGEM is not set | 418 | # CONFIG_SUNGEM is not set |
| 403 | # CONFIG_CASSINI is not set | 419 | # CONFIG_CASSINI is not set |
| @@ -464,6 +480,7 @@ CONFIG_NET_RADIO=y | |||
| 464 | # Wireless 802.11b ISA/PCI cards support | 480 | # Wireless 802.11b ISA/PCI cards support |
| 465 | # | 481 | # |
| 466 | # CONFIG_HERMES is not set | 482 | # CONFIG_HERMES is not set |
| 483 | # CONFIG_ATMEL is not set | ||
| 467 | 484 | ||
| 468 | # | 485 | # |
| 469 | # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support | 486 | # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support |
| @@ -527,7 +544,7 @@ CONFIG_KEYBOARD_ATKBD_HP_KEYCODES=y | |||
| 527 | # CONFIG_KEYBOARD_XTKBD is not set | 544 | # CONFIG_KEYBOARD_XTKBD is not set |
| 528 | # CONFIG_KEYBOARD_NEWTON is not set | 545 | # CONFIG_KEYBOARD_NEWTON is not set |
| 529 | # CONFIG_KEYBOARD_HIL_OLD is not set | 546 | # CONFIG_KEYBOARD_HIL_OLD is not set |
| 530 | # CONFIG_KEYBOARD_HIL is not set | 547 | CONFIG_KEYBOARD_HIL=y |
| 531 | CONFIG_INPUT_MOUSE=y | 548 | CONFIG_INPUT_MOUSE=y |
| 532 | CONFIG_MOUSE_PS2=y | 549 | CONFIG_MOUSE_PS2=y |
| 533 | # CONFIG_MOUSE_SERIAL is not set | 550 | # CONFIG_MOUSE_SERIAL is not set |
| @@ -535,7 +552,7 @@ CONFIG_MOUSE_PS2=y | |||
| 535 | # CONFIG_MOUSE_LOGIBM is not set | 552 | # CONFIG_MOUSE_LOGIBM is not set |
| 536 | # CONFIG_MOUSE_PC110PAD is not set | 553 | # CONFIG_MOUSE_PC110PAD is not set |
| 537 | # CONFIG_MOUSE_VSXXXAA is not set | 554 | # CONFIG_MOUSE_VSXXXAA is not set |
| 538 | # CONFIG_MOUSE_HIL is not set | 555 | CONFIG_MOUSE_HIL=y |
| 539 | # CONFIG_INPUT_JOYSTICK is not set | 556 | # CONFIG_INPUT_JOYSTICK is not set |
| 540 | # CONFIG_INPUT_TOUCHSCREEN is not set | 557 | # CONFIG_INPUT_TOUCHSCREEN is not set |
| 541 | CONFIG_INPUT_MISC=y | 558 | CONFIG_INPUT_MISC=y |
| @@ -549,7 +566,8 @@ CONFIG_SERIO=y | |||
| 549 | # CONFIG_SERIO_SERPORT is not set | 566 | # CONFIG_SERIO_SERPORT is not set |
| 550 | # CONFIG_SERIO_PARKBD is not set | 567 | # CONFIG_SERIO_PARKBD is not set |
| 551 | CONFIG_SERIO_GSCPS2=y | 568 | CONFIG_SERIO_GSCPS2=y |
| 552 | # CONFIG_HP_SDC is not set | 569 | CONFIG_HP_SDC=y |
| 570 | CONFIG_HIL_MLC=y | ||
| 553 | # CONFIG_SERIO_PCIPS2 is not set | 571 | # CONFIG_SERIO_PCIPS2 is not set |
| 554 | CONFIG_SERIO_LIBPS2=y | 572 | CONFIG_SERIO_LIBPS2=y |
| 555 | # CONFIG_SERIO_RAW is not set | 573 | # CONFIG_SERIO_RAW is not set |
| @@ -569,6 +587,7 @@ CONFIG_HW_CONSOLE=y | |||
| 569 | CONFIG_SERIAL_8250=y | 587 | CONFIG_SERIAL_8250=y |
| 570 | CONFIG_SERIAL_8250_CONSOLE=y | 588 | CONFIG_SERIAL_8250_CONSOLE=y |
| 571 | CONFIG_SERIAL_8250_NR_UARTS=13 | 589 | CONFIG_SERIAL_8250_NR_UARTS=13 |
| 590 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 | ||
| 572 | CONFIG_SERIAL_8250_EXTENDED=y | 591 | CONFIG_SERIAL_8250_EXTENDED=y |
| 573 | CONFIG_SERIAL_8250_MANY_PORTS=y | 592 | CONFIG_SERIAL_8250_MANY_PORTS=y |
| 574 | CONFIG_SERIAL_8250_SHARE_IRQ=y | 593 | CONFIG_SERIAL_8250_SHARE_IRQ=y |
| @@ -582,11 +601,10 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y | |||
| 582 | # | 601 | # |
| 583 | # Non-8250 serial port support | 602 | # Non-8250 serial port support |
| 584 | # | 603 | # |
| 585 | # CONFIG_SERIAL_MUX is not set | 604 | CONFIG_SERIAL_MUX=y |
| 586 | # CONFIG_PDC_CONSOLE is not set | 605 | CONFIG_SERIAL_MUX_CONSOLE=y |
| 587 | CONFIG_SERIAL_CORE=y | 606 | CONFIG_SERIAL_CORE=y |
| 588 | CONFIG_SERIAL_CORE_CONSOLE=y | 607 | CONFIG_SERIAL_CORE_CONSOLE=y |
| 589 | # CONFIG_SERIAL_JSM is not set | ||
| 590 | CONFIG_UNIX98_PTYS=y | 608 | CONFIG_UNIX98_PTYS=y |
| 591 | CONFIG_LEGACY_PTYS=y | 609 | CONFIG_LEGACY_PTYS=y |
| 592 | CONFIG_LEGACY_PTY_COUNT=256 | 610 | CONFIG_LEGACY_PTY_COUNT=256 |
| @@ -626,6 +644,12 @@ CONFIG_GEN_RTC=y | |||
| 626 | # CONFIG_I2C is not set | 644 | # CONFIG_I2C is not set |
| 627 | 645 | ||
| 628 | # | 646 | # |
| 647 | # SPI support | ||
| 648 | # | ||
| 649 | # CONFIG_SPI is not set | ||
| 650 | # CONFIG_SPI_MASTER is not set | ||
| 651 | |||
| 652 | # | ||
| 629 | # Dallas's 1-wire bus | 653 | # Dallas's 1-wire bus |
| 630 | # | 654 | # |
| 631 | # CONFIG_W1 is not set | 655 | # CONFIG_W1 is not set |
| @@ -661,7 +685,6 @@ CONFIG_FB=y | |||
| 661 | CONFIG_FB_CFB_FILLRECT=y | 685 | CONFIG_FB_CFB_FILLRECT=y |
| 662 | CONFIG_FB_CFB_COPYAREA=y | 686 | CONFIG_FB_CFB_COPYAREA=y |
| 663 | CONFIG_FB_CFB_IMAGEBLIT=y | 687 | CONFIG_FB_CFB_IMAGEBLIT=y |
| 664 | CONFIG_FB_SOFT_CURSOR=y | ||
| 665 | # CONFIG_FB_MACMODES is not set | 688 | # CONFIG_FB_MACMODES is not set |
| 666 | # CONFIG_FB_MODE_HELPERS is not set | 689 | # CONFIG_FB_MODE_HELPERS is not set |
| 667 | # CONFIG_FB_TILEBLITTING is not set | 690 | # CONFIG_FB_TILEBLITTING is not set |
| @@ -671,6 +694,7 @@ CONFIG_FB_SOFT_CURSOR=y | |||
| 671 | # CONFIG_FB_ASILIANT is not set | 694 | # CONFIG_FB_ASILIANT is not set |
| 672 | # CONFIG_FB_IMSTT is not set | 695 | # CONFIG_FB_IMSTT is not set |
| 673 | CONFIG_FB_STI=y | 696 | CONFIG_FB_STI=y |
| 697 | # CONFIG_FB_S1D13XXX is not set | ||
| 674 | # CONFIG_FB_NVIDIA is not set | 698 | # CONFIG_FB_NVIDIA is not set |
| 675 | # CONFIG_FB_RIVA is not set | 699 | # CONFIG_FB_RIVA is not set |
| 676 | # CONFIG_FB_MATROX is not set | 700 | # CONFIG_FB_MATROX is not set |
| @@ -683,9 +707,7 @@ CONFIG_FB_STI=y | |||
| 683 | # CONFIG_FB_KYRO is not set | 707 | # CONFIG_FB_KYRO is not set |
| 684 | # CONFIG_FB_3DFX is not set | 708 | # CONFIG_FB_3DFX is not set |
| 685 | # CONFIG_FB_VOODOO1 is not set | 709 | # CONFIG_FB_VOODOO1 is not set |
| 686 | # CONFIG_FB_CYBLA is not set | ||
| 687 | # CONFIG_FB_TRIDENT is not set | 710 | # CONFIG_FB_TRIDENT is not set |
| 688 | # CONFIG_FB_S1D13XXX is not set | ||
| 689 | # CONFIG_FB_VIRTUAL is not set | 711 | # CONFIG_FB_VIRTUAL is not set |
| 690 | 712 | ||
| 691 | # | 713 | # |
| @@ -695,6 +717,7 @@ CONFIG_DUMMY_CONSOLE=y | |||
| 695 | CONFIG_DUMMY_CONSOLE_COLUMNS=160 | 717 | CONFIG_DUMMY_CONSOLE_COLUMNS=160 |
| 696 | CONFIG_DUMMY_CONSOLE_ROWS=64 | 718 | CONFIG_DUMMY_CONSOLE_ROWS=64 |
| 697 | CONFIG_FRAMEBUFFER_CONSOLE=y | 719 | CONFIG_FRAMEBUFFER_CONSOLE=y |
| 720 | # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set | ||
| 698 | CONFIG_STI_CONSOLE=y | 721 | CONFIG_STI_CONSOLE=y |
| 699 | # CONFIG_FONTS is not set | 722 | # CONFIG_FONTS is not set |
| 700 | CONFIG_FONT_8x8=y | 723 | CONFIG_FONT_8x8=y |
| @@ -713,7 +736,85 @@ CONFIG_LOGO_PARISC_CLUT224=y | |||
| 713 | # | 736 | # |
| 714 | # Sound | 737 | # Sound |
| 715 | # | 738 | # |
| 716 | # CONFIG_SOUND is not set | 739 | CONFIG_SOUND=y |
| 740 | |||
| 741 | # | ||
| 742 | # Advanced Linux Sound Architecture | ||
| 743 | # | ||
| 744 | CONFIG_SND=y | ||
| 745 | CONFIG_SND_TIMER=y | ||
| 746 | CONFIG_SND_PCM=y | ||
| 747 | CONFIG_SND_SEQUENCER=y | ||
| 748 | # CONFIG_SND_SEQ_DUMMY is not set | ||
| 749 | CONFIG_SND_OSSEMUL=y | ||
| 750 | CONFIG_SND_MIXER_OSS=y | ||
| 751 | CONFIG_SND_PCM_OSS=y | ||
| 752 | CONFIG_SND_SEQUENCER_OSS=y | ||
| 753 | CONFIG_SND_SUPPORT_OLD_API=y | ||
| 754 | # CONFIG_SND_VERBOSE_PRINTK is not set | ||
| 755 | # CONFIG_SND_DEBUG is not set | ||
| 756 | |||
| 757 | # | ||
| 758 | # Generic devices | ||
| 759 | # | ||
| 760 | # CONFIG_SND_DUMMY is not set | ||
| 761 | # CONFIG_SND_VIRMIDI is not set | ||
| 762 | # CONFIG_SND_MTPAV is not set | ||
| 763 | # CONFIG_SND_SERIAL_U16550 is not set | ||
| 764 | # CONFIG_SND_MPU401 is not set | ||
| 765 | |||
| 766 | # | ||
| 767 | # PCI devices | ||
| 768 | # | ||
| 769 | # CONFIG_SND_AD1889 is not set | ||
| 770 | # CONFIG_SND_ALI5451 is not set | ||
| 771 | # CONFIG_SND_ATIIXP is not set | ||
| 772 | # CONFIG_SND_ATIIXP_MODEM is not set | ||
| 773 | # CONFIG_SND_AU8810 is not set | ||
| 774 | # CONFIG_SND_AU8820 is not set | ||
| 775 | # CONFIG_SND_AU8830 is not set | ||
| 776 | # CONFIG_SND_BT87X is not set | ||
| 777 | # CONFIG_SND_CA0106 is not set | ||
| 778 | # CONFIG_SND_CMIPCI is not set | ||
| 779 | # CONFIG_SND_CS4281 is not set | ||
| 780 | # CONFIG_SND_CS46XX is not set | ||
| 781 | # CONFIG_SND_EMU10K1 is not set | ||
| 782 | # CONFIG_SND_EMU10K1X is not set | ||
| 783 | # CONFIG_SND_ENS1370 is not set | ||
| 784 | # CONFIG_SND_ENS1371 is not set | ||
| 785 | # CONFIG_SND_ES1938 is not set | ||
| 786 | # CONFIG_SND_ES1968 is not set | ||
| 787 | # CONFIG_SND_FM801 is not set | ||
| 788 | # CONFIG_SND_HDA_INTEL is not set | ||
| 789 | # CONFIG_SND_HDSP is not set | ||
| 790 | # CONFIG_SND_HDSPM is not set | ||
| 791 | # CONFIG_SND_ICE1712 is not set | ||
| 792 | # CONFIG_SND_ICE1724 is not set | ||
| 793 | # CONFIG_SND_INTEL8X0 is not set | ||
| 794 | # CONFIG_SND_KORG1212 is not set | ||
| 795 | # CONFIG_SND_MAESTRO3 is not set | ||
| 796 | # CONFIG_SND_MIXART is not set | ||
| 797 | # CONFIG_SND_NM256 is not set | ||
| 798 | # CONFIG_SND_PCXHR is not set | ||
| 799 | # CONFIG_SND_RME32 is not set | ||
| 800 | # CONFIG_SND_RME96 is not set | ||
| 801 | # CONFIG_SND_RME9652 is not set | ||
| 802 | # CONFIG_SND_SONICVIBES is not set | ||
| 803 | # CONFIG_SND_TRIDENT is not set | ||
| 804 | # CONFIG_SND_VIA82XX is not set | ||
| 805 | # CONFIG_SND_VIA82XX_MODEM is not set | ||
| 806 | # CONFIG_SND_VX222 is not set | ||
| 807 | # CONFIG_SND_YMFPCI is not set | ||
| 808 | |||
| 809 | # | ||
| 810 | # GSC devices | ||
| 811 | # | ||
| 812 | CONFIG_SND_HARMONY=y | ||
| 813 | |||
| 814 | # | ||
| 815 | # Open Sound System | ||
| 816 | # | ||
| 817 | # CONFIG_SOUND_PRIME is not set | ||
| 717 | 818 | ||
| 718 | # | 819 | # |
| 719 | # USB support | 820 | # USB support |
| @@ -723,6 +824,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y | |||
| 723 | # CONFIG_USB is not set | 824 | # CONFIG_USB is not set |
| 724 | 825 | ||
| 725 | # | 826 | # |
| 827 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' | ||
| 828 | # | ||
| 829 | |||
| 830 | # | ||
| 726 | # USB Gadget Support | 831 | # USB Gadget Support |
| 727 | # | 832 | # |
| 728 | # CONFIG_USB_GADGET is not set | 833 | # CONFIG_USB_GADGET is not set |
| @@ -877,18 +982,23 @@ CONFIG_NLS_DEFAULT="iso8859-1" | |||
| 877 | # Kernel hacking | 982 | # Kernel hacking |
| 878 | # | 983 | # |
| 879 | # CONFIG_PRINTK_TIME is not set | 984 | # CONFIG_PRINTK_TIME is not set |
| 880 | CONFIG_DEBUG_KERNEL=y | ||
| 881 | CONFIG_MAGIC_SYSRQ=y | 985 | CONFIG_MAGIC_SYSRQ=y |
| 986 | CONFIG_DEBUG_KERNEL=y | ||
| 882 | CONFIG_LOG_BUF_SHIFT=16 | 987 | CONFIG_LOG_BUF_SHIFT=16 |
| 883 | CONFIG_DETECT_SOFTLOCKUP=y | 988 | CONFIG_DETECT_SOFTLOCKUP=y |
| 884 | # CONFIG_SCHEDSTATS is not set | 989 | # CONFIG_SCHEDSTATS is not set |
| 885 | # CONFIG_DEBUG_SLAB is not set | 990 | # CONFIG_DEBUG_SLAB is not set |
| 991 | # CONFIG_DEBUG_MUTEXES is not set | ||
| 886 | # CONFIG_DEBUG_SPINLOCK is not set | 992 | # CONFIG_DEBUG_SPINLOCK is not set |
| 887 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | 993 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set |
| 888 | # CONFIG_DEBUG_KOBJECT is not set | 994 | # CONFIG_DEBUG_KOBJECT is not set |
| 889 | # CONFIG_DEBUG_INFO is not set | 995 | # CONFIG_DEBUG_INFO is not set |
| 890 | # CONFIG_DEBUG_IOREMAP is not set | 996 | # CONFIG_DEBUG_IOREMAP is not set |
| 891 | # CONFIG_DEBUG_FS is not set | 997 | # CONFIG_DEBUG_FS is not set |
| 998 | # CONFIG_DEBUG_VM is not set | ||
| 999 | CONFIG_FORCED_INLINING=y | ||
| 1000 | # CONFIG_RCU_TORTURE_TEST is not set | ||
| 1001 | # CONFIG_DEBUG_RODATA is not set | ||
| 892 | 1002 | ||
| 893 | # | 1003 | # |
| 894 | # Security options | 1004 | # Security options |
diff --git a/arch/parisc/hpux/entry_hpux.S b/arch/parisc/hpux/entry_hpux.S index fa9bf38787e7..31c8cccfba31 100644 --- a/arch/parisc/hpux/entry_hpux.S +++ b/arch/parisc/hpux/entry_hpux.S | |||
| @@ -22,10 +22,9 @@ | |||
| 22 | #include <linux/linkage.h> | 22 | #include <linux/linkage.h> |
| 23 | #include <asm/unistd.h> | 23 | #include <asm/unistd.h> |
| 24 | 24 | ||
| 25 | .text | ||
| 26 | |||
| 27 | #define ENTRY_NAME(_name_) .word _name_ | 25 | #define ENTRY_NAME(_name_) .word _name_ |
| 28 | 26 | ||
| 27 | .section .rodata,"a" | ||
| 29 | .align 4 | 28 | .align 4 |
| 30 | .export hpux_call_table | 29 | .export hpux_call_table |
| 31 | .import hpux_unimplemented_wrapper | 30 | .import hpux_unimplemented_wrapper |
diff --git a/arch/parisc/hpux/sys_hpux.c b/arch/parisc/hpux/sys_hpux.c index 29b4d61898f2..05273ccced0e 100644 --- a/arch/parisc/hpux/sys_hpux.c +++ b/arch/parisc/hpux/sys_hpux.c | |||
| @@ -468,19 +468,23 @@ int hpux_sysfs(int opcode, unsigned long arg1, unsigned long arg2) | |||
| 468 | if ( opcode == 1 ) { /* GETFSIND */ | 468 | if ( opcode == 1 ) { /* GETFSIND */ |
| 469 | len = strlen_user((char *)arg1); | 469 | len = strlen_user((char *)arg1); |
| 470 | printk(KERN_DEBUG "len of arg1 = %d\n", len); | 470 | printk(KERN_DEBUG "len of arg1 = %d\n", len); |
| 471 | 471 | if (len == 0) | |
| 472 | fsname = (char *) kmalloc(len+1, GFP_KERNEL); | 472 | return 0; |
| 473 | fsname = (char *) kmalloc(len, GFP_KERNEL); | ||
| 473 | if ( !fsname ) { | 474 | if ( !fsname ) { |
| 474 | printk(KERN_DEBUG "failed to kmalloc fsname\n"); | 475 | printk(KERN_DEBUG "failed to kmalloc fsname\n"); |
| 475 | return 0; | 476 | return 0; |
| 476 | } | 477 | } |
| 477 | 478 | ||
| 478 | if ( copy_from_user(fsname, (char *)arg1, len+1) ) { | 479 | if ( copy_from_user(fsname, (char *)arg1, len) ) { |
| 479 | printk(KERN_DEBUG "failed to copy_from_user fsname\n"); | 480 | printk(KERN_DEBUG "failed to copy_from_user fsname\n"); |
| 480 | kfree(fsname); | 481 | kfree(fsname); |
| 481 | return 0; | 482 | return 0; |
| 482 | } | 483 | } |
| 483 | 484 | ||
| 485 | /* String could be altered by userspace after strlen_user() */ | ||
| 486 | fsname[len] = '\0'; | ||
| 487 | |||
| 484 | printk(KERN_DEBUG "that is '%s' as (char *)\n", fsname); | 488 | printk(KERN_DEBUG "that is '%s' as (char *)\n", fsname); |
| 485 | if ( !strcmp(fsname, "hfs") ) { | 489 | if ( !strcmp(fsname, "hfs") ) { |
| 486 | fstype = 0; | 490 | fstype = 0; |
diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c index 2d804e2d16d1..3d569a485a1a 100644 --- a/arch/parisc/kernel/drivers.c +++ b/arch/parisc/kernel/drivers.c | |||
| @@ -408,11 +408,10 @@ static void setup_bus_id(struct parisc_device *padev) | |||
| 408 | 408 | ||
| 409 | struct parisc_device * create_tree_node(char id, struct device *parent) | 409 | struct parisc_device * create_tree_node(char id, struct device *parent) |
| 410 | { | 410 | { |
| 411 | struct parisc_device *dev = kmalloc(sizeof(*dev), GFP_KERNEL); | 411 | struct parisc_device *dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
| 412 | if (!dev) | 412 | if (!dev) |
| 413 | return NULL; | 413 | return NULL; |
| 414 | 414 | ||
| 415 | memset(dev, 0, sizeof(*dev)); | ||
| 416 | dev->hw_path = id; | 415 | dev->hw_path = id; |
| 417 | dev->id.hw_type = HPHW_FAULTY; | 416 | dev->id.hw_type = HPHW_FAULTY; |
| 418 | 417 | ||
diff --git a/arch/parisc/kernel/parisc_ksyms.c b/arch/parisc/kernel/parisc_ksyms.c index f40a777dd388..1d00c365f2b1 100644 --- a/arch/parisc/kernel/parisc_ksyms.c +++ b/arch/parisc/kernel/parisc_ksyms.c | |||
| @@ -48,9 +48,6 @@ EXPORT_SYMBOL(strrchr); | |||
| 48 | EXPORT_SYMBOL(strstr); | 48 | EXPORT_SYMBOL(strstr); |
| 49 | EXPORT_SYMBOL(strpbrk); | 49 | EXPORT_SYMBOL(strpbrk); |
| 50 | 50 | ||
| 51 | #include <linux/pm.h> | ||
| 52 | EXPORT_SYMBOL(pm_power_off); | ||
| 53 | |||
| 54 | #include <asm/atomic.h> | 51 | #include <asm/atomic.h> |
| 55 | EXPORT_SYMBOL(__xchg8); | 52 | EXPORT_SYMBOL(__xchg8); |
| 56 | EXPORT_SYMBOL(__xchg32); | 53 | EXPORT_SYMBOL(__xchg32); |
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index 88cba49c5301..79c7db2705fd 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c | |||
| @@ -47,18 +47,17 @@ | |||
| 47 | * this makes the boot time much longer than necessary. | 47 | * this makes the boot time much longer than necessary. |
| 48 | * 20ms seems to work for all the HP PCI implementations to date. | 48 | * 20ms seems to work for all the HP PCI implementations to date. |
| 49 | * | 49 | * |
| 50 | * XXX: turn into a #defined constant in <asm/pci.h> ? | 50 | * #define pci_post_reset_delay 50 |
| 51 | */ | 51 | */ |
| 52 | int pci_post_reset_delay = 50; | ||
| 53 | 52 | ||
| 54 | struct pci_port_ops *pci_port; | 53 | struct pci_port_ops *pci_port __read_mostly; |
| 55 | struct pci_bios_ops *pci_bios; | 54 | struct pci_bios_ops *pci_bios __read_mostly; |
| 56 | 55 | ||
| 57 | int pci_hba_count = 0; | 56 | static int pci_hba_count __read_mostly; |
| 58 | 57 | ||
| 59 | /* parisc_pci_hba used by pci_port->in/out() ops to lookup bus data. */ | 58 | /* parisc_pci_hba used by pci_port->in/out() ops to lookup bus data. */ |
| 60 | #define PCI_HBA_MAX 32 | 59 | #define PCI_HBA_MAX 32 |
| 61 | struct pci_hba_data *parisc_pci_hba[PCI_HBA_MAX]; | 60 | static struct pci_hba_data *parisc_pci_hba[PCI_HBA_MAX] __read_mostly; |
| 62 | 61 | ||
| 63 | 62 | ||
| 64 | /******************************************************************** | 63 | /******************************************************************** |
| @@ -259,8 +258,10 @@ void __devinit pcibios_resource_to_bus(struct pci_dev *dev, | |||
| 259 | void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | 258 | void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, |
| 260 | struct pci_bus_region *region) | 259 | struct pci_bus_region *region) |
| 261 | { | 260 | { |
| 261 | #ifdef CONFIG_64BIT | ||
| 262 | struct pci_bus *bus = dev->bus; | 262 | struct pci_bus *bus = dev->bus; |
| 263 | struct pci_hba_data *hba = HBA_DATA(bus->bridge->platform_data); | 263 | struct pci_hba_data *hba = HBA_DATA(bus->bridge->platform_data); |
| 264 | #endif | ||
| 264 | 265 | ||
| 265 | if (res->flags & IORESOURCE_MEM) { | 266 | if (res->flags & IORESOURCE_MEM) { |
| 266 | res->start = PCI_HOST_ADDR(hba, region->start); | 267 | res->start = PCI_HOST_ADDR(hba, region->start); |
diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c index 11d406cd0b3e..53f861c82f93 100644 --- a/arch/parisc/kernel/perf.c +++ b/arch/parisc/kernel/perf.c | |||
| @@ -68,20 +68,20 @@ struct rdr_tbl_ent { | |||
| 68 | }; | 68 | }; |
| 69 | 69 | ||
| 70 | static int perf_processor_interface __read_mostly = UNKNOWN_INTF; | 70 | static int perf_processor_interface __read_mostly = UNKNOWN_INTF; |
| 71 | static int perf_enabled __read_mostly = 0; | 71 | static int perf_enabled __read_mostly; |
| 72 | static spinlock_t perf_lock; | 72 | static spinlock_t perf_lock; |
| 73 | struct parisc_device *cpu_device __read_mostly = NULL; | 73 | struct parisc_device *cpu_device __read_mostly; |
| 74 | 74 | ||
| 75 | /* RDRs to write for PCX-W */ | 75 | /* RDRs to write for PCX-W */ |
| 76 | static int perf_rdrs_W[] = | 76 | static const int perf_rdrs_W[] = |
| 77 | { 0, 1, 4, 5, 6, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, -1 }; | 77 | { 0, 1, 4, 5, 6, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, -1 }; |
| 78 | 78 | ||
| 79 | /* RDRs to write for PCX-U */ | 79 | /* RDRs to write for PCX-U */ |
| 80 | static int perf_rdrs_U[] = | 80 | static const int perf_rdrs_U[] = |
| 81 | { 0, 1, 4, 5, 6, 7, 16, 17, 18, 20, 21, 22, 23, 24, 25, -1 }; | 81 | { 0, 1, 4, 5, 6, 7, 16, 17, 18, 20, 21, 22, 23, 24, 25, -1 }; |
| 82 | 82 | ||
| 83 | /* RDR register descriptions for PCX-W */ | 83 | /* RDR register descriptions for PCX-W */ |
| 84 | static struct rdr_tbl_ent perf_rdr_tbl_W[] = { | 84 | static const struct rdr_tbl_ent perf_rdr_tbl_W[] = { |
| 85 | { 19, 1, 8 }, /* RDR 0 */ | 85 | { 19, 1, 8 }, /* RDR 0 */ |
| 86 | { 16, 1, 16 }, /* RDR 1 */ | 86 | { 16, 1, 16 }, /* RDR 1 */ |
| 87 | { 72, 2, 0 }, /* RDR 2 */ | 87 | { 72, 2, 0 }, /* RDR 2 */ |
| @@ -117,7 +117,7 @@ static struct rdr_tbl_ent perf_rdr_tbl_W[] = { | |||
| 117 | }; | 117 | }; |
| 118 | 118 | ||
| 119 | /* RDR register descriptions for PCX-U */ | 119 | /* RDR register descriptions for PCX-U */ |
| 120 | static struct rdr_tbl_ent perf_rdr_tbl_U[] = { | 120 | static const struct rdr_tbl_ent perf_rdr_tbl_U[] = { |
| 121 | { 19, 1, 8 }, /* RDR 0 */ | 121 | { 19, 1, 8 }, /* RDR 0 */ |
| 122 | { 32, 1, 16 }, /* RDR 1 */ | 122 | { 32, 1, 16 }, /* RDR 1 */ |
| 123 | { 20, 1, 0 }, /* RDR 2 */ | 123 | { 20, 1, 0 }, /* RDR 2 */ |
| @@ -156,7 +156,7 @@ static struct rdr_tbl_ent perf_rdr_tbl_U[] = { | |||
| 156 | * A non-zero write_control in the above tables is a byte offset into | 156 | * A non-zero write_control in the above tables is a byte offset into |
| 157 | * this array. | 157 | * this array. |
| 158 | */ | 158 | */ |
| 159 | static uint64_t perf_bitmasks[] = { | 159 | static const uint64_t perf_bitmasks[] = { |
| 160 | 0x0000000000000000ul, /* first dbl word must be zero */ | 160 | 0x0000000000000000ul, /* first dbl word must be zero */ |
| 161 | 0xfdffe00000000000ul, /* RDR0 bitmask */ | 161 | 0xfdffe00000000000ul, /* RDR0 bitmask */ |
| 162 | 0x003f000000000000ul, /* RDR1 bitmask */ | 162 | 0x003f000000000000ul, /* RDR1 bitmask */ |
| @@ -173,7 +173,7 @@ static uint64_t perf_bitmasks[] = { | |||
| 173 | * Write control bitmasks for Pa-8700 processor given | 173 | * Write control bitmasks for Pa-8700 processor given |
| 174 | * somethings have changed slightly. | 174 | * somethings have changed slightly. |
| 175 | */ | 175 | */ |
| 176 | static uint64_t perf_bitmasks_piranha[] = { | 176 | static const uint64_t perf_bitmasks_piranha[] = { |
| 177 | 0x0000000000000000ul, /* first dbl word must be zero */ | 177 | 0x0000000000000000ul, /* first dbl word must be zero */ |
| 178 | 0xfdffe00000000000ul, /* RDR0 bitmask */ | 178 | 0xfdffe00000000000ul, /* RDR0 bitmask */ |
| 179 | 0x003f000000000000ul, /* RDR1 bitmask */ | 179 | 0x003f000000000000ul, /* RDR1 bitmask */ |
| @@ -186,7 +186,7 @@ static uint64_t perf_bitmasks_piranha[] = { | |||
| 186 | 0xfffc000000000000ul | 186 | 0xfffc000000000000ul |
| 187 | }; | 187 | }; |
| 188 | 188 | ||
| 189 | static uint64_t *bitmask_array; /* array of bitmasks to use */ | 189 | static const uint64_t *bitmask_array; /* array of bitmasks to use */ |
| 190 | 190 | ||
| 191 | /****************************************************************************** | 191 | /****************************************************************************** |
| 192 | * Function Prototypes | 192 | * Function Prototypes |
| @@ -200,7 +200,7 @@ static ssize_t perf_write(struct file *file, const char __user *buf, size_t coun | |||
| 200 | static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg); | 200 | static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg); |
| 201 | static void perf_start_counters(void); | 201 | static void perf_start_counters(void); |
| 202 | static int perf_stop_counters(uint32_t *raddr); | 202 | static int perf_stop_counters(uint32_t *raddr); |
| 203 | static struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num); | 203 | static const struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num); |
| 204 | static int perf_rdr_read_ubuf(uint32_t rdr_num, uint64_t *buffer); | 204 | static int perf_rdr_read_ubuf(uint32_t rdr_num, uint64_t *buffer); |
| 205 | static int perf_rdr_clear(uint32_t rdr_num); | 205 | static int perf_rdr_clear(uint32_t rdr_num); |
| 206 | static int perf_write_image(uint64_t *memaddr); | 206 | static int perf_write_image(uint64_t *memaddr); |
| @@ -444,7 +444,6 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 444 | uint32_t raddr[4]; | 444 | uint32_t raddr[4]; |
| 445 | int error = 0; | 445 | int error = 0; |
| 446 | 446 | ||
| 447 | lock_kernel(); | ||
| 448 | switch (cmd) { | 447 | switch (cmd) { |
| 449 | 448 | ||
| 450 | case PA_PERF_ON: | 449 | case PA_PERF_ON: |
| @@ -477,8 +476,6 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 477 | error = -ENOTTY; | 476 | error = -ENOTTY; |
| 478 | } | 477 | } |
| 479 | 478 | ||
| 480 | unlock_kernel(); | ||
| 481 | |||
| 482 | return error; | 479 | return error; |
| 483 | } | 480 | } |
| 484 | 481 | ||
| @@ -655,7 +652,7 @@ static int perf_stop_counters(uint32_t *raddr) | |||
| 655 | * Retrieve a pointer to the description of what this | 652 | * Retrieve a pointer to the description of what this |
| 656 | * RDR contains. | 653 | * RDR contains. |
| 657 | */ | 654 | */ |
| 658 | static struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num) | 655 | static const struct rdr_tbl_ent * perf_rdr_get_entry(uint32_t rdr_num) |
| 659 | { | 656 | { |
| 660 | if (perf_processor_interface == ONYX_INTF) { | 657 | if (perf_processor_interface == ONYX_INTF) { |
| 661 | return &perf_rdr_tbl_U[rdr_num]; | 658 | return &perf_rdr_tbl_U[rdr_num]; |
| @@ -673,7 +670,7 @@ static int perf_rdr_read_ubuf(uint32_t rdr_num, uint64_t *buffer) | |||
| 673 | { | 670 | { |
| 674 | uint64_t data, data_mask = 0; | 671 | uint64_t data, data_mask = 0; |
| 675 | uint32_t width, xbits, i; | 672 | uint32_t width, xbits, i; |
| 676 | struct rdr_tbl_ent *tentry; | 673 | const struct rdr_tbl_ent *tentry; |
| 677 | 674 | ||
| 678 | tentry = perf_rdr_get_entry(rdr_num); | 675 | tentry = perf_rdr_get_entry(rdr_num); |
| 679 | if ((width = tentry->width) == 0) | 676 | if ((width = tentry->width) == 0) |
| @@ -721,7 +718,7 @@ static int perf_rdr_read_ubuf(uint32_t rdr_num, uint64_t *buffer) | |||
| 721 | */ | 718 | */ |
| 722 | static int perf_rdr_clear(uint32_t rdr_num) | 719 | static int perf_rdr_clear(uint32_t rdr_num) |
| 723 | { | 720 | { |
| 724 | struct rdr_tbl_ent *tentry; | 721 | const struct rdr_tbl_ent *tentry; |
| 725 | int32_t i; | 722 | int32_t i; |
| 726 | 723 | ||
| 727 | tentry = perf_rdr_get_entry(rdr_num); | 724 | tentry = perf_rdr_get_entry(rdr_num); |
| @@ -753,10 +750,11 @@ static int perf_write_image(uint64_t *memaddr) | |||
| 753 | uint64_t buffer[MAX_RDR_WORDS]; | 750 | uint64_t buffer[MAX_RDR_WORDS]; |
| 754 | uint64_t *bptr; | 751 | uint64_t *bptr; |
| 755 | uint32_t dwords; | 752 | uint32_t dwords; |
| 756 | uint32_t *intrigue_rdr; | 753 | const uint32_t *intrigue_rdr; |
| 757 | uint64_t *intrigue_bitmask, tmp64; | 754 | const uint64_t *intrigue_bitmask; |
| 755 | uint64_t tmp64; | ||
| 758 | void __iomem *runway; | 756 | void __iomem *runway; |
| 759 | struct rdr_tbl_ent *tentry; | 757 | const struct rdr_tbl_ent *tentry; |
| 760 | int i; | 758 | int i; |
| 761 | 759 | ||
| 762 | /* Clear out counters */ | 760 | /* Clear out counters */ |
| @@ -830,7 +828,7 @@ static int perf_write_image(uint64_t *memaddr) | |||
| 830 | */ | 828 | */ |
| 831 | static void perf_rdr_write(uint32_t rdr_num, uint64_t *buffer) | 829 | static void perf_rdr_write(uint32_t rdr_num, uint64_t *buffer) |
| 832 | { | 830 | { |
| 833 | struct rdr_tbl_ent *tentry; | 831 | const struct rdr_tbl_ent *tentry; |
| 834 | int32_t i; | 832 | int32_t i; |
| 835 | 833 | ||
| 836 | printk("perf_rdr_write\n"); | 834 | printk("perf_rdr_write\n"); |
diff --git a/arch/parisc/kernel/perf_images.h b/arch/parisc/kernel/perf_images.h index d9562fe3f75c..7fef9644df47 100644 --- a/arch/parisc/kernel/perf_images.h +++ b/arch/parisc/kernel/perf_images.h | |||
| @@ -25,7 +25,7 @@ | |||
| 25 | 25 | ||
| 26 | #define PCXU_IMAGE_SIZE 584 | 26 | #define PCXU_IMAGE_SIZE 584 |
| 27 | 27 | ||
| 28 | static uint32_t onyx_images[][PCXU_IMAGE_SIZE/sizeof(uint32_t)] = { | 28 | static uint32_t onyx_images[][PCXU_IMAGE_SIZE/sizeof(uint32_t)] __read_mostly = { |
| 29 | /* | 29 | /* |
| 30 | * CPI: | 30 | * CPI: |
| 31 | * | 31 | * |
| @@ -2093,7 +2093,7 @@ static uint32_t onyx_images[][PCXU_IMAGE_SIZE/sizeof(uint32_t)] = { | |||
| 2093 | }; | 2093 | }; |
| 2094 | #define PCXW_IMAGE_SIZE 576 | 2094 | #define PCXW_IMAGE_SIZE 576 |
| 2095 | 2095 | ||
| 2096 | static uint32_t cuda_images[][PCXW_IMAGE_SIZE/sizeof(uint32_t)] = { | 2096 | static uint32_t cuda_images[][PCXW_IMAGE_SIZE/sizeof(uint32_t)] __read_mostly = { |
| 2097 | /* | 2097 | /* |
| 2098 | * CPI: FROM CPI.IDF (Image 0) | 2098 | * CPI: FROM CPI.IDF (Image 0) |
| 2099 | * | 2099 | * |
diff --git a/arch/parisc/kernel/process.c b/arch/parisc/kernel/process.c index 5da41677e70b..e8dea4177113 100644 --- a/arch/parisc/kernel/process.c +++ b/arch/parisc/kernel/process.c | |||
| @@ -54,27 +54,6 @@ | |||
| 54 | #include <asm/uaccess.h> | 54 | #include <asm/uaccess.h> |
| 55 | #include <asm/unwind.h> | 55 | #include <asm/unwind.h> |
| 56 | 56 | ||
| 57 | static int hlt_counter __read_mostly; | ||
| 58 | |||
| 59 | /* | ||
| 60 | * Power off function, if any | ||
| 61 | */ | ||
| 62 | void (*pm_power_off)(void); | ||
| 63 | |||
| 64 | void disable_hlt(void) | ||
| 65 | { | ||
| 66 | hlt_counter++; | ||
| 67 | } | ||
| 68 | |||
| 69 | EXPORT_SYMBOL(disable_hlt); | ||
| 70 | |||
| 71 | void enable_hlt(void) | ||
| 72 | { | ||
| 73 | hlt_counter--; | ||
| 74 | } | ||
| 75 | |||
| 76 | EXPORT_SYMBOL(enable_hlt); | ||
| 77 | |||
| 78 | void default_idle(void) | 57 | void default_idle(void) |
| 79 | { | 58 | { |
| 80 | barrier(); | 59 | barrier(); |
| @@ -102,12 +81,7 @@ void cpu_idle(void) | |||
| 102 | } | 81 | } |
| 103 | 82 | ||
| 104 | 83 | ||
| 105 | #ifdef __LP64__ | 84 | #define COMMAND_GLOBAL F_EXTEND(0xfffe0030) |
| 106 | #define COMMAND_GLOBAL 0xfffffffffffe0030UL | ||
| 107 | #else | ||
| 108 | #define COMMAND_GLOBAL 0xfffe0030 | ||
| 109 | #endif | ||
| 110 | |||
| 111 | #define CMD_RESET 5 /* reset any module */ | 85 | #define CMD_RESET 5 /* reset any module */ |
| 112 | 86 | ||
| 113 | /* | 87 | /* |
| @@ -162,6 +136,7 @@ void machine_halt(void) | |||
| 162 | */ | 136 | */ |
| 163 | } | 137 | } |
| 164 | 138 | ||
| 139 | void (*chassis_power_off)(void); | ||
| 165 | 140 | ||
| 166 | /* | 141 | /* |
| 167 | * This routine is called from sys_reboot to actually turn off the | 142 | * This routine is called from sys_reboot to actually turn off the |
| @@ -170,8 +145,8 @@ void machine_halt(void) | |||
| 170 | void machine_power_off(void) | 145 | void machine_power_off(void) |
| 171 | { | 146 | { |
| 172 | /* If there is a registered power off handler, call it. */ | 147 | /* If there is a registered power off handler, call it. */ |
| 173 | if(pm_power_off) | 148 | if (chassis_power_off) |
| 174 | pm_power_off(); | 149 | chassis_power_off(); |
| 175 | 150 | ||
| 176 | /* Put the soft power button back under hardware control. | 151 | /* Put the soft power button back under hardware control. |
| 177 | * If the user had already pressed the power button, the | 152 | * If the user had already pressed the power button, the |
| @@ -187,6 +162,8 @@ void machine_power_off(void) | |||
| 187 | KERN_EMERG "Please power this system off now."); | 162 | KERN_EMERG "Please power this system off now."); |
| 188 | } | 163 | } |
| 189 | 164 | ||
| 165 | void (*pm_power_off)(void) = machine_power_off; | ||
| 166 | EXPORT_SYMBOL(pm_power_off); | ||
| 190 | 167 | ||
| 191 | /* | 168 | /* |
| 192 | * Create a kernel thread | 169 | * Create a kernel thread |
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c index 27160e8bf15b..413292f1a4a3 100644 --- a/arch/parisc/kernel/ptrace.c +++ b/arch/parisc/kernel/ptrace.c | |||
| @@ -91,7 +91,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
| 91 | int copied; | 91 | int copied; |
| 92 | 92 | ||
| 93 | #ifdef __LP64__ | 93 | #ifdef __LP64__ |
| 94 | if (is_compat_task(child)) { | 94 | if (personality(child->personality) == PER_LINUX32) { |
| 95 | unsigned int tmp; | 95 | unsigned int tmp; |
| 96 | 96 | ||
| 97 | addr &= 0xffffffffL; | 97 | addr &= 0xffffffffL; |
| @@ -123,7 +123,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
| 123 | case PTRACE_POKEDATA: | 123 | case PTRACE_POKEDATA: |
| 124 | ret = 0; | 124 | ret = 0; |
| 125 | #ifdef __LP64__ | 125 | #ifdef __LP64__ |
| 126 | if (is_compat_task(child)) { | 126 | if (personality(child->personality) == PER_LINUX32) { |
| 127 | unsigned int tmp = (unsigned int)data; | 127 | unsigned int tmp = (unsigned int)data; |
| 128 | DBG("sys_ptrace(POKE%s, %d, %lx, %lx)\n", | 128 | DBG("sys_ptrace(POKE%s, %d, %lx, %lx)\n", |
| 129 | request == PTRACE_POKETEXT ? "TEXT" : "DATA", | 129 | request == PTRACE_POKETEXT ? "TEXT" : "DATA", |
| @@ -146,7 +146,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
| 146 | case PTRACE_PEEKUSR: { | 146 | case PTRACE_PEEKUSR: { |
| 147 | ret = -EIO; | 147 | ret = -EIO; |
| 148 | #ifdef __LP64__ | 148 | #ifdef __LP64__ |
| 149 | if (is_compat_task(child)) { | 149 | if (personality(child->personality) == PER_LINUX32) { |
| 150 | unsigned int tmp; | 150 | unsigned int tmp; |
| 151 | 151 | ||
| 152 | if (addr & (sizeof(int)-1)) | 152 | if (addr & (sizeof(int)-1)) |
| @@ -205,7 +205,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
| 205 | goto out_tsk; | 205 | goto out_tsk; |
| 206 | } | 206 | } |
| 207 | #ifdef __LP64__ | 207 | #ifdef __LP64__ |
| 208 | if (is_compat_task(child)) { | 208 | if (personality(child->personality) == PER_LINUX32) { |
| 209 | if (addr & (sizeof(int)-1)) | 209 | if (addr & (sizeof(int)-1)) |
| 210 | goto out_tsk; | 210 | goto out_tsk; |
| 211 | if ((addr = translate_usr_offset(addr)) < 0) | 211 | if ((addr = translate_usr_offset(addr)) < 0) |
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index 3a25a7bd673e..05767e83cf2d 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c | |||
| @@ -317,7 +317,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
| 317 | 317 | ||
| 318 | if(personality(current->personality) == PER_LINUX32) { | 318 | if(personality(current->personality) == PER_LINUX32) { |
| 319 | DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info); | 319 | DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info); |
| 320 | err |= compat_copy_siginfo_to_user(&compat_frame->info, info); | 320 | err |= copy_siginfo_to_user32(&compat_frame->info, info); |
| 321 | DBG(1,"SETUP_RT_FRAME: 1\n"); | 321 | DBG(1,"SETUP_RT_FRAME: 1\n"); |
| 322 | compat_val = (compat_int_t)current->sas_ss_sp; | 322 | compat_val = (compat_int_t)current->sas_ss_sp; |
| 323 | err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_sp); | 323 | err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_sp); |
diff --git a/arch/parisc/kernel/signal32.c b/arch/parisc/kernel/signal32.c index 0792e20efef3..a6b4231cafa1 100644 --- a/arch/parisc/kernel/signal32.c +++ b/arch/parisc/kernel/signal32.c | |||
| @@ -31,7 +31,6 @@ | |||
| 31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
| 32 | #include <linux/errno.h> | 32 | #include <linux/errno.h> |
| 33 | 33 | ||
| 34 | #include <asm/compat_signal.h> | ||
| 35 | #include <asm/uaccess.h> | 34 | #include <asm/uaccess.h> |
| 36 | 35 | ||
| 37 | #include "signal32.h" | 36 | #include "signal32.h" |
| @@ -398,3 +397,104 @@ setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __ | |||
| 398 | 397 | ||
| 399 | return err; | 398 | return err; |
| 400 | } | 399 | } |
| 400 | |||
| 401 | int | ||
| 402 | copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from) | ||
| 403 | { | ||
| 404 | unsigned long tmp; | ||
| 405 | int err; | ||
| 406 | |||
| 407 | if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t))) | ||
| 408 | return -EFAULT; | ||
| 409 | |||
| 410 | err = __get_user(to->si_signo, &from->si_signo); | ||
| 411 | err |= __get_user(to->si_errno, &from->si_errno); | ||
| 412 | err |= __get_user(to->si_code, &from->si_code); | ||
| 413 | |||
| 414 | if (to->si_code < 0) | ||
| 415 | err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); | ||
| 416 | else { | ||
| 417 | switch (to->si_code >> 16) { | ||
| 418 | case __SI_CHLD >> 16: | ||
| 419 | err |= __get_user(to->si_utime, &from->si_utime); | ||
| 420 | err |= __get_user(to->si_stime, &from->si_stime); | ||
| 421 | err |= __get_user(to->si_status, &from->si_status); | ||
| 422 | default: | ||
| 423 | err |= __get_user(to->si_pid, &from->si_pid); | ||
| 424 | err |= __get_user(to->si_uid, &from->si_uid); | ||
| 425 | break; | ||
| 426 | case __SI_FAULT >> 16: | ||
| 427 | err |= __get_user(tmp, &from->si_addr); | ||
| 428 | to->si_addr = (void __user *) tmp; | ||
| 429 | break; | ||
| 430 | case __SI_POLL >> 16: | ||
| 431 | err |= __get_user(to->si_band, &from->si_band); | ||
| 432 | err |= __get_user(to->si_fd, &from->si_fd); | ||
| 433 | break; | ||
| 434 | case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ | ||
| 435 | case __SI_MESGQ >> 16: | ||
| 436 | err |= __get_user(to->si_pid, &from->si_pid); | ||
| 437 | err |= __get_user(to->si_uid, &from->si_uid); | ||
| 438 | err |= __get_user(to->si_int, &from->si_int); | ||
| 439 | break; | ||
| 440 | } | ||
| 441 | } | ||
| 442 | return err; | ||
| 443 | } | ||
| 444 | |||
| 445 | int | ||
| 446 | copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from) | ||
| 447 | { | ||
| 448 | unsigned int addr; | ||
| 449 | int err; | ||
| 450 | |||
| 451 | if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t))) | ||
| 452 | return -EFAULT; | ||
| 453 | |||
| 454 | /* If you change siginfo_t structure, please be sure | ||
| 455 | this code is fixed accordingly. | ||
| 456 | It should never copy any pad contained in the structure | ||
| 457 | to avoid security leaks, but must copy the generic | ||
| 458 | 3 ints plus the relevant union member. | ||
| 459 | This routine must convert siginfo from 64bit to 32bit as well | ||
| 460 | at the same time. */ | ||
| 461 | err = __put_user(from->si_signo, &to->si_signo); | ||
| 462 | err |= __put_user(from->si_errno, &to->si_errno); | ||
| 463 | err |= __put_user((short)from->si_code, &to->si_code); | ||
| 464 | if (from->si_code < 0) | ||
| 465 | err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE); | ||
| 466 | else { | ||
| 467 | switch (from->si_code >> 16) { | ||
| 468 | case __SI_CHLD >> 16: | ||
| 469 | err |= __put_user(from->si_utime, &to->si_utime); | ||
| 470 | err |= __put_user(from->si_stime, &to->si_stime); | ||
| 471 | err |= __put_user(from->si_status, &to->si_status); | ||
| 472 | default: | ||
| 473 | err |= __put_user(from->si_pid, &to->si_pid); | ||
| 474 | err |= __put_user(from->si_uid, &to->si_uid); | ||
| 475 | break; | ||
| 476 | case __SI_FAULT >> 16: | ||
| 477 | /* avoid type-checking warnings by copying _pad[0] in lieu of si_addr... */ | ||
| 478 | err |= __put_user(from->_sifields._pad[0], &to->si_addr); | ||
| 479 | break; | ||
| 480 | case __SI_POLL >> 16: | ||
| 481 | err |= __put_user(from->si_band, &to->si_band); | ||
| 482 | err |= __put_user(from->si_fd, &to->si_fd); | ||
| 483 | break; | ||
| 484 | case __SI_TIMER >> 16: | ||
| 485 | err |= __put_user(from->si_tid, &to->si_tid); | ||
| 486 | err |= __put_user(from->si_overrun, &to->si_overrun); | ||
| 487 | addr = (unsigned long) from->si_ptr; | ||
| 488 | err |= __put_user(addr, &to->si_ptr); | ||
| 489 | break; | ||
| 490 | case __SI_RT >> 16: /* Not generated by the kernel as of now. */ | ||
| 491 | case __SI_MESGQ >> 16: | ||
| 492 | err |= __put_user(from->si_uid, &to->si_uid); | ||
| 493 | err |= __put_user(from->si_pid, &to->si_pid); | ||
| 494 | addr = (unsigned long) from->si_ptr; | ||
| 495 | err |= __put_user(addr, &to->si_ptr); | ||
| 496 | break; | ||
| 497 | } | ||
| 498 | } | ||
| 499 | return err; | ||
| 500 | } | ||
diff --git a/arch/parisc/kernel/signal32.h b/arch/parisc/kernel/signal32.h index 4d1569e717cc..e39b38a67a87 100644 --- a/arch/parisc/kernel/signal32.h +++ b/arch/parisc/kernel/signal32.h | |||
| @@ -20,8 +20,34 @@ | |||
| 20 | #define _PARISC64_KERNEL_SIGNAL32_H | 20 | #define _PARISC64_KERNEL_SIGNAL32_H |
| 21 | 21 | ||
| 22 | #include <linux/compat.h> | 22 | #include <linux/compat.h> |
| 23 | #include <asm/compat_signal.h> | 23 | |
| 24 | #include <asm/compat_rt_sigframe.h> | 24 | typedef compat_uptr_t compat_sighandler_t; |
| 25 | |||
| 26 | typedef struct compat_sigaltstack { | ||
| 27 | compat_uptr_t ss_sp; | ||
| 28 | compat_int_t ss_flags; | ||
| 29 | compat_size_t ss_size; | ||
| 30 | } compat_stack_t; | ||
| 31 | |||
| 32 | /* Most things should be clean enough to redefine this at will, if care | ||
| 33 | is taken to make libc match. */ | ||
| 34 | |||
| 35 | struct compat_sigaction { | ||
| 36 | compat_sighandler_t sa_handler; | ||
| 37 | compat_uint_t sa_flags; | ||
| 38 | compat_sigset_t sa_mask; /* mask last for extensibility */ | ||
| 39 | }; | ||
| 40 | |||
| 41 | /* 32-bit ucontext as seen from an 64-bit kernel */ | ||
| 42 | struct compat_ucontext { | ||
| 43 | compat_uint_t uc_flags; | ||
| 44 | compat_uptr_t uc_link; | ||
| 45 | compat_stack_t uc_stack; /* struct compat_sigaltstack (12 bytes)*/ | ||
| 46 | /* FIXME: Pad out to get uc_mcontext to start at an 8-byte aligned boundary */ | ||
| 47 | compat_uint_t pad[1]; | ||
| 48 | struct compat_sigcontext uc_mcontext; | ||
| 49 | compat_sigset_t uc_sigmask; /* mask last for extensibility */ | ||
| 50 | }; | ||
| 25 | 51 | ||
| 26 | /* ELF32 signal handling */ | 52 | /* ELF32 signal handling */ |
| 27 | 53 | ||
| @@ -29,6 +55,103 @@ struct k_sigaction32 { | |||
| 29 | struct compat_sigaction sa; | 55 | struct compat_sigaction sa; |
| 30 | }; | 56 | }; |
| 31 | 57 | ||
| 58 | typedef struct compat_siginfo { | ||
| 59 | int si_signo; | ||
| 60 | int si_errno; | ||
| 61 | int si_code; | ||
| 62 | |||
| 63 | union { | ||
| 64 | int _pad[((128/sizeof(int)) - 3)]; | ||
| 65 | |||
| 66 | /* kill() */ | ||
| 67 | struct { | ||
| 68 | unsigned int _pid; /* sender's pid */ | ||
| 69 | unsigned int _uid; /* sender's uid */ | ||
| 70 | } _kill; | ||
| 71 | |||
| 72 | /* POSIX.1b timers */ | ||
| 73 | struct { | ||
| 74 | compat_timer_t _tid; /* timer id */ | ||
| 75 | int _overrun; /* overrun count */ | ||
| 76 | char _pad[sizeof(unsigned int) - sizeof(int)]; | ||
| 77 | compat_sigval_t _sigval; /* same as below */ | ||
| 78 | int _sys_private; /* not to be passed to user */ | ||
| 79 | } _timer; | ||
| 80 | |||
| 81 | /* POSIX.1b signals */ | ||
| 82 | struct { | ||
| 83 | unsigned int _pid; /* sender's pid */ | ||
| 84 | unsigned int _uid; /* sender's uid */ | ||
| 85 | compat_sigval_t _sigval; | ||
| 86 | } _rt; | ||
| 87 | |||
| 88 | /* SIGCHLD */ | ||
| 89 | struct { | ||
| 90 | unsigned int _pid; /* which child */ | ||
| 91 | unsigned int _uid; /* sender's uid */ | ||
| 92 | int _status; /* exit code */ | ||
| 93 | compat_clock_t _utime; | ||
| 94 | compat_clock_t _stime; | ||
| 95 | } _sigchld; | ||
| 96 | |||
| 97 | /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ | ||
| 98 | struct { | ||
| 99 | unsigned int _addr; /* faulting insn/memory ref. */ | ||
| 100 | } _sigfault; | ||
| 101 | |||
| 102 | /* SIGPOLL */ | ||
| 103 | struct { | ||
| 104 | int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ | ||
| 105 | int _fd; | ||
| 106 | } _sigpoll; | ||
| 107 | } _sifields; | ||
| 108 | } compat_siginfo_t; | ||
| 109 | |||
| 110 | int copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from); | ||
| 111 | int copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from); | ||
| 112 | |||
| 113 | /* In a deft move of uber-hackery, we decide to carry the top half of all | ||
| 114 | * 64-bit registers in a non-portable, non-ABI, hidden structure. | ||
| 115 | * Userspace can read the hidden structure if it *wants* but is never | ||
| 116 | * guaranteed to be in the same place. Infact the uc_sigmask from the | ||
| 117 | * ucontext_t structure may push the hidden register file downards | ||
| 118 | */ | ||
| 119 | struct compat_regfile { | ||
| 120 | /* Upper half of all the 64-bit registers that were truncated | ||
| 121 | on a copy to a 32-bit userspace */ | ||
| 122 | compat_int_t rf_gr[32]; | ||
| 123 | compat_int_t rf_iasq[2]; | ||
| 124 | compat_int_t rf_iaoq[2]; | ||
| 125 | compat_int_t rf_sar; | ||
| 126 | }; | ||
| 127 | |||
| 128 | #define COMPAT_SIGRETURN_TRAMP 4 | ||
| 129 | #define COMPAT_SIGRESTARTBLOCK_TRAMP 5 | ||
| 130 | #define COMPAT_TRAMP_SIZE (COMPAT_SIGRETURN_TRAMP + \ | ||
| 131 | COMPAT_SIGRESTARTBLOCK_TRAMP) | ||
| 132 | |||
| 133 | struct compat_rt_sigframe { | ||
| 134 | /* XXX: Must match trampoline size in arch/parisc/kernel/signal.c | ||
| 135 | Secondary to that it must protect the ERESTART_RESTARTBLOCK | ||
| 136 | trampoline we left on the stack (we were bad and didn't | ||
| 137 | change sp so we could run really fast.) */ | ||
| 138 | compat_uint_t tramp[COMPAT_TRAMP_SIZE]; | ||
| 139 | compat_siginfo_t info; | ||
| 140 | struct compat_ucontext uc; | ||
| 141 | /* Hidden location of truncated registers, *must* be last. */ | ||
| 142 | struct compat_regfile regs; | ||
| 143 | }; | ||
| 144 | |||
| 145 | /* | ||
| 146 | * The 32-bit ABI wants at least 48 bytes for a function call frame: | ||
| 147 | * 16 bytes for arg0-arg3, and 32 bytes for magic (the only part of | ||
| 148 | * which Linux/parisc uses is sp-20 for the saved return pointer...) | ||
| 149 | * Then, the stack pointer must be rounded to a cache line (64 bytes). | ||
| 150 | */ | ||
| 151 | #define SIGFRAME32 64 | ||
| 152 | #define FUNCTIONCALLFRAME32 48 | ||
| 153 | #define PARISC_RT_SIGFRAME_SIZE32 (((sizeof(struct compat_rt_sigframe) + FUNCTIONCALLFRAME32) + SIGFRAME32) & -SIGFRAME32) | ||
| 154 | |||
| 32 | void sigset_32to64(sigset_t *s64, compat_sigset_t *s32); | 155 | void sigset_32to64(sigset_t *s64, compat_sigset_t *s32); |
| 33 | void sigset_64to32(compat_sigset_t *s32, sigset_t *s64); | 156 | void sigset_64to32(compat_sigset_t *s32, sigset_t *s64); |
| 34 | int do_sigaltstack32 (const compat_stack_t __user *uss32, | 157 | int do_sigaltstack32 (const compat_stack_t __user *uss32, |
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index d66163492890..af88afef41bd 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S | |||
| @@ -650,6 +650,8 @@ end_linux_gateway_page: | |||
| 650 | #define LWS_ENTRY(_name_) .word (lws_##_name_ - linux_gateway_page) | 650 | #define LWS_ENTRY(_name_) .word (lws_##_name_ - linux_gateway_page) |
| 651 | #endif | 651 | #endif |
| 652 | 652 | ||
| 653 | .section .rodata,"a" | ||
| 654 | |||
| 653 | .align 4096 | 655 | .align 4096 |
| 654 | /* Light-weight-syscall table */ | 656 | /* Light-weight-syscall table */ |
| 655 | /* Start of lws table. */ | 657 | /* Start of lws table. */ |
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index 32cbc0489324..51d2480627d1 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S | |||
| @@ -374,5 +374,24 @@ | |||
| 374 | ENTRY_SAME(keyctl) | 374 | ENTRY_SAME(keyctl) |
| 375 | ENTRY_SAME(ioprio_set) | 375 | ENTRY_SAME(ioprio_set) |
| 376 | ENTRY_SAME(ioprio_get) | 376 | ENTRY_SAME(ioprio_get) |
| 377 | ENTRY_SAME(inotify_init) | ||
| 378 | ENTRY_SAME(inotify_add_watch) /* 270 */ | ||
| 379 | ENTRY_SAME(inotify_rm_watch) | ||
| 380 | ENTRY_COMP(pselect6) | ||
| 381 | ENTRY_COMP(ppoll) | ||
| 382 | ENTRY_SAME(migrate_pages) | ||
| 383 | ENTRY_COMP(openat) /* 275 */ | ||
| 384 | ENTRY_SAME(mkdirat) | ||
| 385 | ENTRY_SAME(mknodat) | ||
| 386 | ENTRY_SAME(fchownat) | ||
| 387 | ENTRY_COMP(futimesat) | ||
| 388 | ENTRY_COMP(newfstatat) /* 280 */ | ||
| 389 | ENTRY_SAME(unlinkat) | ||
| 390 | ENTRY_SAME(renameat) | ||
| 391 | ENTRY_SAME(linkat) | ||
| 392 | ENTRY_SAME(symlinkat) | ||
| 393 | ENTRY_SAME(readlinkat) /* 285 */ | ||
| 394 | ENTRY_SAME(fchmodat) | ||
| 395 | ENTRY_SAME(faccessat) | ||
| 377 | /* Nothing yet */ | 396 | /* Nothing yet */ |
| 378 | 397 | ||
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c index 15914f0235a0..ff200608c851 100644 --- a/arch/parisc/kernel/traps.c +++ b/arch/parisc/kernel/traps.c | |||
| @@ -193,10 +193,9 @@ void show_stack(struct task_struct *task, unsigned long *s) | |||
| 193 | 193 | ||
| 194 | HERE: | 194 | HERE: |
| 195 | asm volatile ("copy %%r30, %0" : "=r"(sp)); | 195 | asm volatile ("copy %%r30, %0" : "=r"(sp)); |
| 196 | r = (struct pt_regs *)kmalloc(sizeof(struct pt_regs), GFP_KERNEL); | 196 | r = kzalloc(sizeof(struct pt_regs), GFP_KERNEL); |
| 197 | if (!r) | 197 | if (!r) |
| 198 | return; | 198 | return; |
| 199 | memset(r, 0, sizeof(struct pt_regs)); | ||
| 200 | r->iaoq[0] = (unsigned long)&&HERE; | 199 | r->iaoq[0] = (unsigned long)&&HERE; |
| 201 | r->gr[2] = (unsigned long)__builtin_return_address(0); | 200 | r->gr[2] = (unsigned long)__builtin_return_address(0); |
| 202 | r->gr[30] = sp; | 201 | r->gr[30] = sp; |
diff --git a/arch/parisc/math-emu/decode_exc.c b/arch/parisc/math-emu/decode_exc.c index f84f2586672b..66c8a9f6a27e 100644 --- a/arch/parisc/math-emu/decode_exc.c +++ b/arch/parisc/math-emu/decode_exc.c | |||
| @@ -337,6 +337,7 @@ decode_fpu(unsigned int Fpu_register[], unsigned int trap_counts[]) | |||
| 337 | } | 337 | } |
| 338 | break; | 338 | break; |
| 339 | case INVALIDEXCEPTION: | 339 | case INVALIDEXCEPTION: |
| 340 | case OPC_2E_INVALIDEXCEPTION: | ||
| 340 | update_trap_counts(Fpu_register, aflags, bflags, trap_counts); | 341 | update_trap_counts(Fpu_register, aflags, bflags, trap_counts); |
| 341 | return SIGNALCODE(SIGFPE, FPE_FLTINV); | 342 | return SIGNALCODE(SIGFPE, FPE_FLTINV); |
| 342 | case DIVISIONBYZEROEXCEPTION: | 343 | case DIVISIONBYZEROEXCEPTION: |
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 720287d46e55..7847ca13d6c2 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c | |||
| @@ -371,17 +371,11 @@ static void __init setup_bootmem(void) | |||
| 371 | 371 | ||
| 372 | void free_initmem(void) | 372 | void free_initmem(void) |
| 373 | { | 373 | { |
| 374 | /* FIXME: */ | ||
| 375 | #if 0 | ||
| 376 | printk(KERN_INFO "NOT FREEING INITMEM (%dk)\n", | ||
| 377 | (&__init_end - &__init_begin) >> 10); | ||
| 378 | return; | ||
| 379 | #else | ||
| 380 | unsigned long addr; | 374 | unsigned long addr; |
| 381 | 375 | ||
| 382 | printk(KERN_INFO "Freeing unused kernel memory: "); | 376 | printk(KERN_INFO "Freeing unused kernel memory: "); |
| 383 | 377 | ||
| 384 | #if 1 | 378 | #ifdef CONFIG_DEBUG_KERNEL |
| 385 | /* Attempt to catch anyone trying to execute code here | 379 | /* Attempt to catch anyone trying to execute code here |
| 386 | * by filling the page with BRK insns. | 380 | * by filling the page with BRK insns. |
| 387 | * | 381 | * |
| @@ -414,9 +408,21 @@ void free_initmem(void) | |||
| 414 | pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BCOMPLETE); | 408 | pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BCOMPLETE); |
| 415 | 409 | ||
| 416 | printk("%luk freed\n", (unsigned long)(&__init_end - &__init_begin) >> 10); | 410 | printk("%luk freed\n", (unsigned long)(&__init_end - &__init_begin) >> 10); |
| 417 | #endif | ||
| 418 | } | 411 | } |
| 419 | 412 | ||
| 413 | |||
| 414 | #ifdef CONFIG_DEBUG_RODATA | ||
| 415 | void mark_rodata_ro(void) | ||
| 416 | { | ||
| 417 | extern char __start_rodata, __end_rodata; | ||
| 418 | /* rodata memory was already mapped with KERNEL_RO access rights by | ||
| 419 | pagetable_init() and map_pages(). No need to do additional stuff here */ | ||
| 420 | printk (KERN_INFO "Write protecting the kernel read-only data: %luk\n", | ||
| 421 | (unsigned long)(&__end_rodata - &__start_rodata) >> 10); | ||
| 422 | } | ||
| 423 | #endif | ||
| 424 | |||
| 425 | |||
| 420 | /* | 426 | /* |
| 421 | * Just an arbitrary offset to serve as a "hole" between mapping areas | 427 | * Just an arbitrary offset to serve as a "hole" between mapping areas |
| 422 | * (between top of physical memory and a potential pcxl dma mapping | 428 | * (between top of physical memory and a potential pcxl dma mapping |
| @@ -477,11 +483,6 @@ void __init mem_init(void) | |||
| 477 | 483 | ||
| 478 | } | 484 | } |
| 479 | 485 | ||
| 480 | int do_check_pgt_cache(int low, int high) | ||
| 481 | { | ||
| 482 | return 0; | ||
| 483 | } | ||
| 484 | |||
| 485 | unsigned long *empty_zero_page __read_mostly; | 486 | unsigned long *empty_zero_page __read_mostly; |
| 486 | 487 | ||
| 487 | void show_mem(void) | 488 | void show_mem(void) |
| @@ -690,7 +691,7 @@ static void __init pagetable_init(void) | |||
| 690 | 691 | ||
| 691 | #ifdef CONFIG_BLK_DEV_INITRD | 692 | #ifdef CONFIG_BLK_DEV_INITRD |
| 692 | if (initrd_end && initrd_end > mem_limit) { | 693 | if (initrd_end && initrd_end > mem_limit) { |
| 693 | printk("initrd: mapping %08lx-%08lx\n", initrd_start, initrd_end); | 694 | printk(KERN_INFO "initrd: mapping %08lx-%08lx\n", initrd_start, initrd_end); |
| 694 | map_pages(initrd_start, __pa(initrd_start), | 695 | map_pages(initrd_start, __pa(initrd_start), |
| 695 | initrd_end - initrd_start, PAGE_KERNEL); | 696 | initrd_end - initrd_start, PAGE_KERNEL); |
| 696 | } | 697 | } |
| @@ -792,8 +793,6 @@ map_hpux_gateway_page(struct task_struct *tsk, struct mm_struct *mm) | |||
| 792 | EXPORT_SYMBOL(map_hpux_gateway_page); | 793 | EXPORT_SYMBOL(map_hpux_gateway_page); |
| 793 | #endif | 794 | #endif |
| 794 | 795 | ||
| 795 | extern void flush_tlb_all_local(void); | ||
| 796 | |||
| 797 | void __init paging_init(void) | 796 | void __init paging_init(void) |
| 798 | { | 797 | { |
| 799 | int i; | 798 | int i; |
| @@ -802,7 +801,7 @@ void __init paging_init(void) | |||
| 802 | pagetable_init(); | 801 | pagetable_init(); |
| 803 | gateway_init(); | 802 | gateway_init(); |
| 804 | flush_cache_all_local(); /* start with known state */ | 803 | flush_cache_all_local(); /* start with known state */ |
| 805 | flush_tlb_all_local(); | 804 | flush_tlb_all_local(NULL); |
| 806 | 805 | ||
| 807 | for (i = 0; i < npmem_ranges; i++) { | 806 | for (i = 0; i < npmem_ranges; i++) { |
| 808 | unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0 }; | 807 | unsigned long zones_size[MAX_NR_ZONES] = { 0, 0, 0 }; |
| @@ -993,7 +992,7 @@ void flush_tlb_all(void) | |||
| 993 | do_recycle++; | 992 | do_recycle++; |
| 994 | } | 993 | } |
| 995 | spin_unlock(&sid_lock); | 994 | spin_unlock(&sid_lock); |
| 996 | on_each_cpu((void (*)(void *))flush_tlb_all_local, NULL, 1, 1); | 995 | on_each_cpu(flush_tlb_all_local, NULL, 1, 1); |
| 997 | if (do_recycle) { | 996 | if (do_recycle) { |
| 998 | spin_lock(&sid_lock); | 997 | spin_lock(&sid_lock); |
| 999 | recycle_sids(recycle_ndirty,recycle_dirty_array); | 998 | recycle_sids(recycle_ndirty,recycle_dirty_array); |
diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index e4362dfa37fb..340730fb8c91 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S | |||
| @@ -66,7 +66,7 @@ _GLOBAL(load_up_fpu) | |||
| 66 | #else | 66 | #else |
| 67 | ld r4,PACACURRENT(r13) | 67 | ld r4,PACACURRENT(r13) |
| 68 | addi r5,r4,THREAD /* Get THREAD */ | 68 | addi r5,r4,THREAD /* Get THREAD */ |
| 69 | ld r4,THREAD_FPEXC_MODE(r5) | 69 | lwz r4,THREAD_FPEXC_MODE(r5) |
| 70 | ori r12,r12,MSR_FP | 70 | ori r12,r12,MSR_FP |
| 71 | or r12,r12,r4 | 71 | or r12,r12,r4 |
| 72 | std r12,_MSR(r1) | 72 | std r12,_MSR(r1) |
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 308268466342..415659629394 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
| @@ -749,11 +749,12 @@ iSeries_secondary_smp_loop: | |||
| 749 | 749 | ||
| 750 | .globl decrementer_iSeries_masked | 750 | .globl decrementer_iSeries_masked |
| 751 | decrementer_iSeries_masked: | 751 | decrementer_iSeries_masked: |
| 752 | /* We may not have a valid TOC pointer in here. */ | ||
| 752 | li r11,1 | 753 | li r11,1 |
| 753 | ld r12,PACALPPACAPTR(r13) | 754 | ld r12,PACALPPACAPTR(r13) |
| 754 | stb r11,LPPACADECRINT(r12) | 755 | stb r11,LPPACADECRINT(r12) |
| 755 | LOAD_REG_ADDRBASE(r12,tb_ticks_per_jiffy) | 756 | LOAD_REG_IMMEDIATE(r12, tb_ticks_per_jiffy) |
| 756 | lwz r12,ADDROFF(tb_ticks_per_jiffy)(r12) | 757 | lwz r12,0(r12) |
| 757 | mtspr SPRN_DEC,r12 | 758 | mtspr SPRN_DEC,r12 |
| 758 | /* fall through */ | 759 | /* fall through */ |
| 759 | 760 | ||
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index 4d9b4388918b..946f3219fd29 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c | |||
| @@ -334,9 +334,6 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, | |||
| 334 | 334 | ||
| 335 | spin_unlock_irqrestore(&(tbl->it_lock), flags); | 335 | spin_unlock_irqrestore(&(tbl->it_lock), flags); |
| 336 | 336 | ||
| 337 | /* Make sure updates are seen by hardware */ | ||
| 338 | mb(); | ||
| 339 | |||
| 340 | DBG("mapped %d elements:\n", outcount); | 337 | DBG("mapped %d elements:\n", outcount); |
| 341 | 338 | ||
| 342 | /* For the sake of iommu_unmap_sg, we clear out the length in the | 339 | /* For the sake of iommu_unmap_sg, we clear out the length in the |
| @@ -347,6 +344,10 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, | |||
| 347 | outs->dma_address = DMA_ERROR_CODE; | 344 | outs->dma_address = DMA_ERROR_CODE; |
| 348 | outs->dma_length = 0; | 345 | outs->dma_length = 0; |
| 349 | } | 346 | } |
| 347 | |||
| 348 | /* Make sure updates are seen by hardware */ | ||
| 349 | mb(); | ||
| 350 | |||
| 350 | return outcount; | 351 | return outcount; |
| 351 | 352 | ||
| 352 | failure: | 353 | failure: |
| @@ -358,6 +359,8 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, | |||
| 358 | npages = (PAGE_ALIGN(s->dma_address + s->dma_length) - vaddr) | 359 | npages = (PAGE_ALIGN(s->dma_address + s->dma_length) - vaddr) |
| 359 | >> PAGE_SHIFT; | 360 | >> PAGE_SHIFT; |
| 360 | __iommu_free(tbl, vaddr, npages); | 361 | __iommu_free(tbl, vaddr, npages); |
| 362 | s->dma_address = DMA_ERROR_CODE; | ||
| 363 | s->dma_length = 0; | ||
| 361 | } | 364 | } |
| 362 | } | 365 | } |
| 363 | spin_unlock_irqrestore(&(tbl->it_lock), flags); | 366 | spin_unlock_irqrestore(&(tbl->it_lock), flags); |
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index d50c8df0183e..294832a7e0a6 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
| @@ -491,7 +491,12 @@ void __init finish_device_tree(void) | |||
| 491 | size = 16; | 491 | size = 16; |
| 492 | finish_node(allnodes, &size, 1); | 492 | finish_node(allnodes, &size, 1); |
| 493 | size -= 16; | 493 | size -= 16; |
| 494 | end = start = (unsigned long) __va(lmb_alloc(size, 128)); | 494 | |
| 495 | if (0 == size) | ||
| 496 | end = start = 0; | ||
| 497 | else | ||
| 498 | end = start = (unsigned long)__va(lmb_alloc(size, 128)); | ||
| 499 | |||
| 495 | finish_node(allnodes, &end, 0); | 500 | finish_node(allnodes, &end, 0); |
| 496 | BUG_ON(end != start + size); | 501 | BUG_ON(end != start + size); |
| 497 | 502 | ||
| @@ -1398,8 +1403,8 @@ struct device_node *of_find_node_by_name(struct device_node *from, | |||
| 1398 | 1403 | ||
| 1399 | read_lock(&devtree_lock); | 1404 | read_lock(&devtree_lock); |
| 1400 | np = from ? from->allnext : allnodes; | 1405 | np = from ? from->allnext : allnodes; |
| 1401 | for (; np != 0; np = np->allnext) | 1406 | for (; np != NULL; np = np->allnext) |
| 1402 | if (np->name != 0 && strcasecmp(np->name, name) == 0 | 1407 | if (np->name != NULL && strcasecmp(np->name, name) == 0 |
| 1403 | && of_node_get(np)) | 1408 | && of_node_get(np)) |
| 1404 | break; | 1409 | break; |
| 1405 | if (from) | 1410 | if (from) |
| @@ -1917,3 +1922,30 @@ int prom_update_property(struct device_node *np, | |||
| 1917 | 1922 | ||
| 1918 | return 0; | 1923 | return 0; |
| 1919 | } | 1924 | } |
| 1925 | |||
| 1926 | #ifdef CONFIG_KEXEC | ||
| 1927 | /* We may have allocated the flat device tree inside the crash kernel region | ||
| 1928 | * in prom_init. If so we need to move it out into regular memory. */ | ||
| 1929 | void kdump_move_device_tree(void) | ||
| 1930 | { | ||
| 1931 | unsigned long start, end; | ||
| 1932 | struct boot_param_header *new; | ||
| 1933 | |||
| 1934 | start = __pa((unsigned long)initial_boot_params); | ||
| 1935 | end = start + initial_boot_params->totalsize; | ||
| 1936 | |||
| 1937 | if (end < crashk_res.start || start > crashk_res.end) | ||
| 1938 | return; | ||
| 1939 | |||
| 1940 | new = (struct boot_param_header*) | ||
| 1941 | __va(lmb_alloc(initial_boot_params->totalsize, PAGE_SIZE)); | ||
| 1942 | |||
| 1943 | memcpy(new, initial_boot_params, initial_boot_params->totalsize); | ||
| 1944 | |||
| 1945 | initial_boot_params = new; | ||
| 1946 | |||
| 1947 | DBG("Flat device tree blob moved to %p\n", initial_boot_params); | ||
| 1948 | |||
| 1949 | /* XXX should we unreserve the old DT? */ | ||
| 1950 | } | ||
| 1951 | #endif /* CONFIG_KEXEC */ | ||
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 7881ec96ef11..ec7153f4d47c 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
| @@ -2098,6 +2098,10 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, | |||
| 2098 | */ | 2098 | */ |
| 2099 | prom_init_stdout(); | 2099 | prom_init_stdout(); |
| 2100 | 2100 | ||
| 2101 | /* Bail if this is a kdump kernel. */ | ||
| 2102 | if (PHYSICAL_START > 0) | ||
| 2103 | prom_panic("Error: You can't boot a kdump kernel from OF!\n"); | ||
| 2104 | |||
| 2101 | /* | 2105 | /* |
| 2102 | * Check for an initrd | 2106 | * Check for an initrd |
| 2103 | */ | 2107 | */ |
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index a8099c806150..3934c227549b 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c | |||
| @@ -465,8 +465,10 @@ u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, | |||
| 465 | if (parent == NULL) | 465 | if (parent == NULL) |
| 466 | return NULL; | 466 | return NULL; |
| 467 | bus = of_match_bus(parent); | 467 | bus = of_match_bus(parent); |
| 468 | if (strcmp(bus->name, "pci")) | 468 | if (strcmp(bus->name, "pci")) { |
| 469 | of_node_put(parent); | ||
| 469 | return NULL; | 470 | return NULL; |
| 471 | } | ||
| 470 | bus->count_cells(dev, &na, &ns); | 472 | bus->count_cells(dev, &na, &ns); |
| 471 | of_node_put(parent); | 473 | of_node_put(parent); |
| 472 | if (!OF_CHECK_COUNTS(na, ns)) | 474 | if (!OF_CHECK_COUNTS(na, ns)) |
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 7fe4a5c944c9..b5b2add7ad1e 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | 22 | ||
| 23 | #include <asm/prom.h> | 23 | #include <asm/prom.h> |
| 24 | #include <asm/rtas.h> | 24 | #include <asm/rtas.h> |
| 25 | #include <asm/hvcall.h> | ||
| 25 | #include <asm/semaphore.h> | 26 | #include <asm/semaphore.h> |
| 26 | #include <asm/machdep.h> | 27 | #include <asm/machdep.h> |
| 27 | #include <asm/page.h> | 28 | #include <asm/page.h> |
| @@ -565,6 +566,7 @@ static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE; | |||
| 565 | #ifdef CONFIG_PPC_PSERIES | 566 | #ifdef CONFIG_PPC_PSERIES |
| 566 | static void rtas_percpu_suspend_me(void *info) | 567 | static void rtas_percpu_suspend_me(void *info) |
| 567 | { | 568 | { |
| 569 | int i; | ||
| 568 | long rc; | 570 | long rc; |
| 569 | long flags; | 571 | long flags; |
| 570 | struct rtas_suspend_me_data *data = | 572 | struct rtas_suspend_me_data *data = |
| @@ -587,18 +589,16 @@ static void rtas_percpu_suspend_me(void *info) | |||
| 587 | 589 | ||
| 588 | if (rc == H_Continue) { | 590 | if (rc == H_Continue) { |
| 589 | data->waiting = 0; | 591 | data->waiting = 0; |
| 590 | rtas_call(ibm_suspend_me_token, 0, 1, | 592 | data->args->args[data->args->nargs] = |
| 591 | data->args->args); | 593 | rtas_call(ibm_suspend_me_token, 0, 1, NULL); |
| 594 | for_each_cpu(i) | ||
| 595 | plpar_hcall_norets(H_PROD,i); | ||
| 592 | } else { | 596 | } else { |
| 593 | data->waiting = -EBUSY; | 597 | data->waiting = -EBUSY; |
| 594 | printk(KERN_ERR "Error on H_Join hypervisor call\n"); | 598 | printk(KERN_ERR "Error on H_Join hypervisor call\n"); |
| 595 | } | 599 | } |
| 596 | 600 | ||
| 597 | out: | 601 | out: |
| 598 | /* before we restore interrupts, make sure we don't | ||
| 599 | * generate a spurious soft lockup errors | ||
| 600 | */ | ||
| 601 | touch_softlockup_watchdog(); | ||
| 602 | local_irq_restore(flags); | 602 | local_irq_restore(flags); |
| 603 | return; | 603 | return; |
| 604 | } | 604 | } |
diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c index 50500093c97f..aaf384c3f04a 100644 --- a/arch/powerpc/kernel/rtas_flash.c +++ b/arch/powerpc/kernel/rtas_flash.c | |||
| @@ -672,8 +672,7 @@ static void rtas_flash_firmware(int reboot_type) | |||
| 672 | static void remove_flash_pde(struct proc_dir_entry *dp) | 672 | static void remove_flash_pde(struct proc_dir_entry *dp) |
| 673 | { | 673 | { |
| 674 | if (dp) { | 674 | if (dp) { |
| 675 | if (dp->data != NULL) | 675 | kfree(dp->data); |
| 676 | kfree(dp->data); | ||
| 677 | dp->owner = NULL; | 676 | dp->owner = NULL; |
| 678 | remove_proc_entry(dp->name, dp->parent); | 677 | remove_proc_entry(dp->name, dp->parent); |
| 679 | } | 678 | } |
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index e29b275e09e0..a717dff695ef 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c | |||
| @@ -398,6 +398,9 @@ void __init setup_system(void) | |||
| 398 | { | 398 | { |
| 399 | DBG(" -> setup_system()\n"); | 399 | DBG(" -> setup_system()\n"); |
| 400 | 400 | ||
| 401 | #ifdef CONFIG_KEXEC | ||
| 402 | kdump_move_device_tree(); | ||
| 403 | #endif | ||
| 401 | /* | 404 | /* |
| 402 | * Unflatten the device-tree passed by prom_init or kexec | 405 | * Unflatten the device-tree passed by prom_init or kexec |
| 403 | */ | 406 | */ |
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index c6d0595da6b5..bd837b5dbf06 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
| @@ -142,11 +142,7 @@ static inline int get_old_sigaction(struct k_sigaction *new_ka, | |||
| 142 | return 0; | 142 | return 0; |
| 143 | } | 143 | } |
| 144 | 144 | ||
| 145 | static inline compat_uptr_t to_user_ptr(void *kp) | 145 | #define to_user_ptr(p) ptr_to_compat(p) |
| 146 | { | ||
| 147 | return (compat_uptr_t)(u64)kp; | ||
| 148 | } | ||
| 149 | |||
| 150 | #define from_user_ptr(p) compat_ptr(p) | 146 | #define from_user_ptr(p) compat_ptr(p) |
| 151 | 147 | ||
| 152 | static inline int save_general_regs(struct pt_regs *regs, | 148 | static inline int save_general_regs(struct pt_regs *regs, |
| @@ -213,8 +209,8 @@ static inline int get_old_sigaction(struct k_sigaction *new_ka, | |||
| 213 | return 0; | 209 | return 0; |
| 214 | } | 210 | } |
| 215 | 211 | ||
| 216 | #define to_user_ptr(p) (p) | 212 | #define to_user_ptr(p) ((unsigned long)(p)) |
| 217 | #define from_user_ptr(p) (p) | 213 | #define from_user_ptr(p) ((void __user *)(p)) |
| 218 | 214 | ||
| 219 | static inline int save_general_regs(struct pt_regs *regs, | 215 | static inline int save_general_regs(struct pt_regs *regs, |
| 220 | struct mcontext __user *frame) | 216 | struct mcontext __user *frame) |
| @@ -526,7 +522,7 @@ long compat_sys_rt_sigaction(int sig, const struct sigaction32 __user *act, | |||
| 526 | 522 | ||
| 527 | ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); | 523 | ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); |
| 528 | if (!ret && oact) { | 524 | if (!ret && oact) { |
| 529 | ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler); | 525 | ret = put_user(to_user_ptr(old_ka.sa.sa_handler), &oact->sa_handler); |
| 530 | ret |= put_sigset_t(&oact->sa_mask, &old_ka.sa.sa_mask); | 526 | ret |= put_sigset_t(&oact->sa_mask, &old_ka.sa.sa_mask); |
| 531 | ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); | 527 | ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); |
| 532 | } | 528 | } |
| @@ -675,8 +671,8 @@ long compat_sys_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo | |||
| 675 | int compat_sys_sigaltstack(u32 __new, u32 __old, int r5, | 671 | int compat_sys_sigaltstack(u32 __new, u32 __old, int r5, |
| 676 | int r6, int r7, int r8, struct pt_regs *regs) | 672 | int r6, int r7, int r8, struct pt_regs *regs) |
| 677 | { | 673 | { |
| 678 | stack_32_t __user * newstack = (stack_32_t __user *)(long) __new; | 674 | stack_32_t __user * newstack = compat_ptr(__new); |
| 679 | stack_32_t __user * oldstack = (stack_32_t __user *)(long) __old; | 675 | stack_32_t __user * oldstack = compat_ptr(__old); |
| 680 | stack_t uss, uoss; | 676 | stack_t uss, uoss; |
| 681 | int ret; | 677 | int ret; |
| 682 | mm_segment_t old_fs; | 678 | mm_segment_t old_fs; |
| @@ -708,7 +704,7 @@ int compat_sys_sigaltstack(u32 __new, u32 __old, int r5, | |||
| 708 | set_fs(old_fs); | 704 | set_fs(old_fs); |
| 709 | /* Copy the stack information to the user output buffer */ | 705 | /* Copy the stack information to the user output buffer */ |
| 710 | if (!ret && oldstack && | 706 | if (!ret && oldstack && |
| 711 | (put_user((long)uoss.ss_sp, &oldstack->ss_sp) || | 707 | (put_user(ptr_to_compat(uoss.ss_sp), &oldstack->ss_sp) || |
| 712 | __put_user(uoss.ss_flags, &oldstack->ss_flags) || | 708 | __put_user(uoss.ss_flags, &oldstack->ss_flags) || |
| 713 | __put_user(uoss.ss_size, &oldstack->ss_size))) | 709 | __put_user(uoss.ss_size, &oldstack->ss_size))) |
| 714 | return -EFAULT; | 710 | return -EFAULT; |
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index b3193116e686..497a5d3df359 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c | |||
| @@ -60,8 +60,8 @@ struct rt_sigframe { | |||
| 60 | struct ucontext uc; | 60 | struct ucontext uc; |
| 61 | unsigned long _unused[2]; | 61 | unsigned long _unused[2]; |
| 62 | unsigned int tramp[TRAMP_SIZE]; | 62 | unsigned int tramp[TRAMP_SIZE]; |
| 63 | struct siginfo *pinfo; | 63 | struct siginfo __user *pinfo; |
| 64 | void *puc; | 64 | void __user *puc; |
| 65 | struct siginfo info; | 65 | struct siginfo info; |
| 66 | /* 64 bit ABI allows for 288 bytes below sp before decrementing it. */ | 66 | /* 64 bit ABI allows for 288 bytes below sp before decrementing it. */ |
| 67 | char abigap[288]; | 67 | char abigap[288]; |
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index c8458c531b25..13595a64f013 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
| @@ -540,6 +540,9 @@ int __devinit start_secondary(void *unused) | |||
| 540 | if (smp_ops->take_timebase) | 540 | if (smp_ops->take_timebase) |
| 541 | smp_ops->take_timebase(); | 541 | smp_ops->take_timebase(); |
| 542 | 542 | ||
| 543 | if (system_state > SYSTEM_BOOTING) | ||
| 544 | per_cpu(last_jiffy, cpu) = get_tb(); | ||
| 545 | |||
| 543 | spin_lock(&call_lock); | 546 | spin_lock(&call_lock); |
| 544 | cpu_set(cpu, cpu_online_map); | 547 | cpu_set(cpu, cpu_online_map); |
| 545 | spin_unlock(&call_lock); | 548 | spin_unlock(&call_lock); |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index c4a294d657b9..1886045a2fd8 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
| @@ -612,10 +612,10 @@ void __init generic_calibrate_decr(void) | |||
| 612 | 612 | ||
| 613 | ppc_tb_freq = DEFAULT_TB_FREQ; /* hardcoded default */ | 613 | ppc_tb_freq = DEFAULT_TB_FREQ; /* hardcoded default */ |
| 614 | node_found = 0; | 614 | node_found = 0; |
| 615 | if (cpu != 0) { | 615 | if (cpu) { |
| 616 | fp = (unsigned int *)get_property(cpu, "timebase-frequency", | 616 | fp = (unsigned int *)get_property(cpu, "timebase-frequency", |
| 617 | NULL); | 617 | NULL); |
| 618 | if (fp != 0) { | 618 | if (fp) { |
| 619 | node_found = 1; | 619 | node_found = 1; |
| 620 | ppc_tb_freq = *fp; | 620 | ppc_tb_freq = *fp; |
| 621 | } | 621 | } |
| @@ -626,10 +626,10 @@ void __init generic_calibrate_decr(void) | |||
| 626 | 626 | ||
| 627 | ppc_proc_freq = DEFAULT_PROC_FREQ; | 627 | ppc_proc_freq = DEFAULT_PROC_FREQ; |
| 628 | node_found = 0; | 628 | node_found = 0; |
| 629 | if (cpu != 0) { | 629 | if (cpu) { |
| 630 | fp = (unsigned int *)get_property(cpu, "clock-frequency", | 630 | fp = (unsigned int *)get_property(cpu, "clock-frequency", |
| 631 | NULL); | 631 | NULL); |
| 632 | if (fp != 0) { | 632 | if (fp) { |
| 633 | node_found = 1; | 633 | node_found = 1; |
| 634 | ppc_proc_freq = *fp; | 634 | ppc_proc_freq = *fp; |
| 635 | } | 635 | } |
diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c index 2da65a9c93f6..5d29dcca523c 100644 --- a/arch/powerpc/kernel/udbg_16550.c +++ b/arch/powerpc/kernel/udbg_16550.c | |||
| @@ -144,7 +144,7 @@ unsigned int udbg_probe_uart_speed(void __iomem *comport, unsigned int clock) | |||
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | #ifdef CONFIG_PPC_MAPLE | 146 | #ifdef CONFIG_PPC_MAPLE |
| 147 | void udbg_maple_real_putc(unsigned char c) | 147 | void udbg_maple_real_putc(char c) |
| 148 | { | 148 | { |
| 149 | if (udbg_comport) { | 149 | if (udbg_comport) { |
| 150 | while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0) | 150 | while ((real_readb(&udbg_comport->lsr) & LSR_THRE) == 0) |
diff --git a/arch/powerpc/mm/lmb.c b/arch/powerpc/mm/lmb.c index 9584608fd768..bbe3eac918e8 100644 --- a/arch/powerpc/mm/lmb.c +++ b/arch/powerpc/mm/lmb.c | |||
| @@ -197,6 +197,8 @@ long __init lmb_reserve(unsigned long base, unsigned long size) | |||
| 197 | { | 197 | { |
| 198 | struct lmb_region *_rgn = &(lmb.reserved); | 198 | struct lmb_region *_rgn = &(lmb.reserved); |
| 199 | 199 | ||
| 200 | BUG_ON(0 == size); | ||
| 201 | |||
| 200 | return lmb_add_region(_rgn, base, size); | 202 | return lmb_add_region(_rgn, base, size); |
| 201 | } | 203 | } |
| 202 | 204 | ||
| @@ -227,6 +229,8 @@ unsigned long __init lmb_alloc_base(unsigned long size, unsigned long align, | |||
| 227 | long i, j; | 229 | long i, j; |
| 228 | unsigned long base = 0; | 230 | unsigned long base = 0; |
| 229 | 231 | ||
| 232 | BUG_ON(0 == size); | ||
| 233 | |||
| 230 | #ifdef CONFIG_PPC32 | 234 | #ifdef CONFIG_PPC32 |
| 231 | /* On 32-bit, make sure we allocate lowmem */ | 235 | /* On 32-bit, make sure we allocate lowmem */ |
| 232 | if (max_addr == LMB_ALLOC_ANYWHERE) | 236 | if (max_addr == LMB_ALLOC_ANYWHERE) |
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 15aac0d78dfa..550517c2dd42 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c | |||
| @@ -435,17 +435,12 @@ void clear_user_page(void *page, unsigned long vaddr, struct page *pg) | |||
| 435 | { | 435 | { |
| 436 | clear_page(page); | 436 | clear_page(page); |
| 437 | 437 | ||
| 438 | if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) | ||
| 439 | return; | ||
| 440 | /* | 438 | /* |
| 441 | * We shouldnt have to do this, but some versions of glibc | 439 | * We shouldnt have to do this, but some versions of glibc |
| 442 | * require it (ld.so assumes zero filled pages are icache clean) | 440 | * require it (ld.so assumes zero filled pages are icache clean) |
| 443 | * - Anton | 441 | * - Anton |
| 444 | */ | 442 | */ |
| 445 | 443 | flush_dcache_page(pg); | |
| 446 | /* avoid an atomic op if possible */ | ||
| 447 | if (test_bit(PG_arch_1, &pg->flags)) | ||
| 448 | clear_bit(PG_arch_1, &pg->flags); | ||
| 449 | } | 444 | } |
| 450 | EXPORT_SYMBOL(clear_user_page); | 445 | EXPORT_SYMBOL(clear_user_page); |
| 451 | 446 | ||
| @@ -469,12 +464,7 @@ void copy_user_page(void *vto, void *vfrom, unsigned long vaddr, | |||
| 469 | return; | 464 | return; |
| 470 | #endif | 465 | #endif |
| 471 | 466 | ||
| 472 | if (cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) | 467 | flush_dcache_page(pg); |
| 473 | return; | ||
| 474 | |||
| 475 | /* avoid an atomic op if possible */ | ||
| 476 | if (test_bit(PG_arch_1, &pg->flags)) | ||
| 477 | clear_bit(PG_arch_1, &pg->flags); | ||
| 478 | } | 468 | } |
| 479 | 469 | ||
| 480 | void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, | 470 | void flush_icache_user_range(struct vm_area_struct *vma, struct page *page, |
diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile index 16031b565be4..3b998a393e3f 100644 --- a/arch/powerpc/platforms/cell/Makefile +++ b/arch/powerpc/platforms/cell/Makefile | |||
| @@ -2,7 +2,7 @@ obj-y += interrupt.o iommu.o setup.o spider-pic.o | |||
| 2 | obj-y += pervasive.o | 2 | obj-y += pervasive.o |
| 3 | 3 | ||
| 4 | obj-$(CONFIG_SMP) += smp.o | 4 | obj-$(CONFIG_SMP) += smp.o |
| 5 | obj-$(CONFIG_SPU_FS) += spufs/ spu-base.o | 5 | obj-$(CONFIG_SPU_FS) += spu-base.o spufs/ |
| 6 | 6 | ||
| 7 | spu-base-y += spu_base.o spu_priv1.o | 7 | spu-base-y += spu_base.o spu_priv1.o |
| 8 | 8 | ||
diff --git a/arch/powerpc/platforms/chrp/chrp.h b/arch/powerpc/platforms/chrp/chrp.h index 3a2057fa314a..814f54742e0f 100644 --- a/arch/powerpc/platforms/chrp/chrp.h +++ b/arch/powerpc/platforms/chrp/chrp.h | |||
| @@ -5,7 +5,6 @@ | |||
| 5 | extern void chrp_nvram_init(void); | 5 | extern void chrp_nvram_init(void); |
| 6 | extern void chrp_get_rtc_time(struct rtc_time *); | 6 | extern void chrp_get_rtc_time(struct rtc_time *); |
| 7 | extern int chrp_set_rtc_time(struct rtc_time *); | 7 | extern int chrp_set_rtc_time(struct rtc_time *); |
| 8 | extern void chrp_calibrate_decr(void); | ||
| 9 | extern long chrp_time_init(void); | 8 | extern long chrp_time_init(void); |
| 10 | 9 | ||
| 11 | extern void chrp_find_bridges(void); | 10 | extern void chrp_find_bridges(void); |
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c index 00c52f27ef4f..8ef279ad36ad 100644 --- a/arch/powerpc/platforms/chrp/pci.c +++ b/arch/powerpc/platforms/chrp/pci.c | |||
| @@ -204,9 +204,11 @@ static void __init setup_peg2(struct pci_controller *hose, struct device_node *d | |||
| 204 | struct device_node *root = find_path_device("/"); | 204 | struct device_node *root = find_path_device("/"); |
| 205 | struct device_node *rtas; | 205 | struct device_node *rtas; |
| 206 | 206 | ||
| 207 | of_node_get(root); | ||
| 207 | rtas = of_find_node_by_name (root, "rtas"); | 208 | rtas = of_find_node_by_name (root, "rtas"); |
| 208 | if (rtas) { | 209 | if (rtas) { |
| 209 | hose->ops = &rtas_pci_ops; | 210 | hose->ops = &rtas_pci_ops; |
| 211 | of_node_put(rtas); | ||
| 210 | } else { | 212 | } else { |
| 211 | printk ("RTAS supporting Pegasos OF not found, please upgrade" | 213 | printk ("RTAS supporting Pegasos OF not found, please upgrade" |
| 212 | " your firmware\n"); | 214 | " your firmware\n"); |
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 2dc87aa5962f..e1fadbf49150 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c | |||
| @@ -506,7 +506,7 @@ void __init chrp_init(void) | |||
| 506 | ppc_md.halt = rtas_halt; | 506 | ppc_md.halt = rtas_halt; |
| 507 | 507 | ||
| 508 | ppc_md.time_init = chrp_time_init; | 508 | ppc_md.time_init = chrp_time_init; |
| 509 | ppc_md.calibrate_decr = chrp_calibrate_decr; | 509 | ppc_md.calibrate_decr = generic_calibrate_decr; |
| 510 | 510 | ||
| 511 | /* this may get overridden with rtas routines later... */ | 511 | /* this may get overridden with rtas routines later... */ |
| 512 | ppc_md.set_rtc_time = chrp_set_rtc_time; | 512 | ppc_md.set_rtc_time = chrp_set_rtc_time; |
diff --git a/arch/powerpc/platforms/chrp/time.c b/arch/powerpc/platforms/chrp/time.c index 36a0f97bb7b1..78df2e7ca88a 100644 --- a/arch/powerpc/platforms/chrp/time.c +++ b/arch/powerpc/platforms/chrp/time.c | |||
| @@ -167,24 +167,3 @@ void chrp_get_rtc_time(struct rtc_time *tm) | |||
| 167 | tm->tm_mon = mon; | 167 | tm->tm_mon = mon; |
| 168 | tm->tm_year = year; | 168 | tm->tm_year = year; |
| 169 | } | 169 | } |
| 170 | |||
| 171 | |||
| 172 | void __init chrp_calibrate_decr(void) | ||
| 173 | { | ||
| 174 | struct device_node *cpu; | ||
| 175 | unsigned int freq, *fp; | ||
| 176 | |||
| 177 | /* | ||
| 178 | * The cpu node should have a timebase-frequency property | ||
| 179 | * to tell us the rate at which the decrementer counts. | ||
| 180 | */ | ||
| 181 | freq = 16666000; /* hardcoded default */ | ||
| 182 | cpu = find_type_devices("cpu"); | ||
| 183 | if (cpu != 0) { | ||
| 184 | fp = (unsigned int *) | ||
| 185 | get_property(cpu, "timebase-frequency", NULL); | ||
| 186 | if (fp != 0) | ||
| 187 | freq = *fp; | ||
| 188 | } | ||
| 189 | ppc_tb_freq = freq; | ||
| 190 | } | ||
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c index 535c802b369f..87eb6bb7f0e7 100644 --- a/arch/powerpc/platforms/powermac/low_i2c.c +++ b/arch/powerpc/platforms/powermac/low_i2c.c | |||
| @@ -1052,8 +1052,7 @@ struct pmac_i2c_bus *pmac_i2c_adapter_to_bus(struct i2c_adapter *adapter) | |||
| 1052 | } | 1052 | } |
| 1053 | EXPORT_SYMBOL_GPL(pmac_i2c_adapter_to_bus); | 1053 | EXPORT_SYMBOL_GPL(pmac_i2c_adapter_to_bus); |
| 1054 | 1054 | ||
| 1055 | extern int pmac_i2c_match_adapter(struct device_node *dev, | 1055 | int pmac_i2c_match_adapter(struct device_node *dev, struct i2c_adapter *adapter) |
| 1056 | struct i2c_adapter *adapter) | ||
| 1057 | { | 1056 | { |
| 1058 | struct pmac_i2c_bus *bus = pmac_i2c_find_bus(dev); | 1057 | struct pmac_i2c_bus *bus = pmac_i2c_find_bus(dev); |
| 1059 | 1058 | ||
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index f671ed253901..de3f30e6b333 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c | |||
| @@ -136,14 +136,14 @@ static void __init fixup_bus_range(struct device_node *bridge) | |||
| 136 | |(((unsigned int)(off)) & 0xFCUL) \ | 136 | |(((unsigned int)(off)) & 0xFCUL) \ |
| 137 | |1UL) | 137 | |1UL) |
| 138 | 138 | ||
| 139 | static unsigned long macrisc_cfg_access(struct pci_controller* hose, | 139 | static volatile void __iomem *macrisc_cfg_access(struct pci_controller* hose, |
| 140 | u8 bus, u8 dev_fn, u8 offset) | 140 | u8 bus, u8 dev_fn, u8 offset) |
| 141 | { | 141 | { |
| 142 | unsigned int caddr; | 142 | unsigned int caddr; |
| 143 | 143 | ||
| 144 | if (bus == hose->first_busno) { | 144 | if (bus == hose->first_busno) { |
| 145 | if (dev_fn < (11 << 3)) | 145 | if (dev_fn < (11 << 3)) |
| 146 | return 0; | 146 | return NULL; |
| 147 | caddr = MACRISC_CFA0(dev_fn, offset); | 147 | caddr = MACRISC_CFA0(dev_fn, offset); |
| 148 | } else | 148 | } else |
| 149 | caddr = MACRISC_CFA1(bus, dev_fn, offset); | 149 | caddr = MACRISC_CFA1(bus, dev_fn, offset); |
| @@ -154,14 +154,14 @@ static unsigned long macrisc_cfg_access(struct pci_controller* hose, | |||
| 154 | } while (in_le32(hose->cfg_addr) != caddr); | 154 | } while (in_le32(hose->cfg_addr) != caddr); |
| 155 | 155 | ||
| 156 | offset &= has_uninorth ? 0x07 : 0x03; | 156 | offset &= has_uninorth ? 0x07 : 0x03; |
| 157 | return ((unsigned long)hose->cfg_data) + offset; | 157 | return hose->cfg_data + offset; |
| 158 | } | 158 | } |
| 159 | 159 | ||
| 160 | static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn, | 160 | static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn, |
| 161 | int offset, int len, u32 *val) | 161 | int offset, int len, u32 *val) |
| 162 | { | 162 | { |
| 163 | struct pci_controller *hose; | 163 | struct pci_controller *hose; |
| 164 | unsigned long addr; | 164 | volatile void __iomem *addr; |
| 165 | 165 | ||
| 166 | hose = pci_bus_to_host(bus); | 166 | hose = pci_bus_to_host(bus); |
| 167 | if (hose == NULL) | 167 | if (hose == NULL) |
| @@ -177,13 +177,13 @@ static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn, | |||
| 177 | */ | 177 | */ |
| 178 | switch (len) { | 178 | switch (len) { |
| 179 | case 1: | 179 | case 1: |
| 180 | *val = in_8((u8 *)addr); | 180 | *val = in_8(addr); |
| 181 | break; | 181 | break; |
| 182 | case 2: | 182 | case 2: |
| 183 | *val = in_le16((u16 *)addr); | 183 | *val = in_le16(addr); |
| 184 | break; | 184 | break; |
| 185 | default: | 185 | default: |
| 186 | *val = in_le32((u32 *)addr); | 186 | *val = in_le32(addr); |
| 187 | break; | 187 | break; |
| 188 | } | 188 | } |
| 189 | return PCIBIOS_SUCCESSFUL; | 189 | return PCIBIOS_SUCCESSFUL; |
| @@ -193,7 +193,7 @@ static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn, | |||
| 193 | int offset, int len, u32 val) | 193 | int offset, int len, u32 val) |
| 194 | { | 194 | { |
| 195 | struct pci_controller *hose; | 195 | struct pci_controller *hose; |
| 196 | unsigned long addr; | 196 | volatile void __iomem *addr; |
| 197 | 197 | ||
| 198 | hose = pci_bus_to_host(bus); | 198 | hose = pci_bus_to_host(bus); |
| 199 | if (hose == NULL) | 199 | if (hose == NULL) |
| @@ -209,16 +209,16 @@ static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn, | |||
| 209 | */ | 209 | */ |
| 210 | switch (len) { | 210 | switch (len) { |
| 211 | case 1: | 211 | case 1: |
| 212 | out_8((u8 *)addr, val); | 212 | out_8(addr, val); |
| 213 | (void) in_8((u8 *)addr); | 213 | (void) in_8(addr); |
| 214 | break; | 214 | break; |
| 215 | case 2: | 215 | case 2: |
| 216 | out_le16((u16 *)addr, val); | 216 | out_le16(addr, val); |
| 217 | (void) in_le16((u16 *)addr); | 217 | (void) in_le16(addr); |
| 218 | break; | 218 | break; |
| 219 | default: | 219 | default: |
| 220 | out_le32((u32 *)addr, val); | 220 | out_le32(addr, val); |
| 221 | (void) in_le32((u32 *)addr); | 221 | (void) in_le32(addr); |
| 222 | break; | 222 | break; |
| 223 | } | 223 | } |
| 224 | return PCIBIOS_SUCCESSFUL; | 224 | return PCIBIOS_SUCCESSFUL; |
| @@ -348,25 +348,23 @@ static int u3_ht_skip_device(struct pci_controller *hose, | |||
| 348 | + (((unsigned int)bus) << 16) \ | 348 | + (((unsigned int)bus) << 16) \ |
| 349 | + 0x01000000UL) | 349 | + 0x01000000UL) |
| 350 | 350 | ||
| 351 | static unsigned long u3_ht_cfg_access(struct pci_controller* hose, | 351 | static volatile void __iomem *u3_ht_cfg_access(struct pci_controller* hose, |
| 352 | u8 bus, u8 devfn, u8 offset) | 352 | u8 bus, u8 devfn, u8 offset) |
| 353 | { | 353 | { |
| 354 | if (bus == hose->first_busno) { | 354 | if (bus == hose->first_busno) { |
| 355 | /* For now, we don't self probe U3 HT bridge */ | 355 | /* For now, we don't self probe U3 HT bridge */ |
| 356 | if (PCI_SLOT(devfn) == 0) | 356 | if (PCI_SLOT(devfn) == 0) |
| 357 | return 0; | 357 | return NULL; |
| 358 | return ((unsigned long)hose->cfg_data) + | 358 | return hose->cfg_data + U3_HT_CFA0(devfn, offset); |
| 359 | U3_HT_CFA0(devfn, offset); | ||
| 360 | } else | 359 | } else |
| 361 | return ((unsigned long)hose->cfg_data) + | 360 | return hose->cfg_data + U3_HT_CFA1(bus, devfn, offset); |
| 362 | U3_HT_CFA1(bus, devfn, offset); | ||
| 363 | } | 361 | } |
| 364 | 362 | ||
| 365 | static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, | 363 | static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, |
| 366 | int offset, int len, u32 *val) | 364 | int offset, int len, u32 *val) |
| 367 | { | 365 | { |
| 368 | struct pci_controller *hose; | 366 | struct pci_controller *hose; |
| 369 | unsigned long addr; | 367 | volatile void __iomem *addr; |
| 370 | 368 | ||
| 371 | hose = pci_bus_to_host(bus); | 369 | hose = pci_bus_to_host(bus); |
| 372 | if (hose == NULL) | 370 | if (hose == NULL) |
| @@ -400,13 +398,13 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn, | |||
| 400 | */ | 398 | */ |
| 401 | switch (len) { | 399 | switch (len) { |
| 402 | case 1: | 400 | case 1: |
| 403 | *val = in_8((u8 *)addr); | 401 | *val = in_8(addr); |
| 404 | break; | 402 | break; |
| 405 | case 2: | 403 | case 2: |
| 406 | *val = in_le16((u16 *)addr); | 404 | *val = in_le16(addr); |
| 407 | break; | 405 | break; |
| 408 | default: | 406 | default: |
| 409 | *val = in_le32((u32 *)addr); | 407 | *val = in_le32(addr); |
| 410 | break; | 408 | break; |
| 411 | } | 409 | } |
| 412 | return PCIBIOS_SUCCESSFUL; | 410 | return PCIBIOS_SUCCESSFUL; |
| @@ -416,7 +414,7 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, | |||
| 416 | int offset, int len, u32 val) | 414 | int offset, int len, u32 val) |
| 417 | { | 415 | { |
| 418 | struct pci_controller *hose; | 416 | struct pci_controller *hose; |
| 419 | unsigned long addr; | 417 | volatile void __iomem *addr; |
| 420 | 418 | ||
| 421 | hose = pci_bus_to_host(bus); | 419 | hose = pci_bus_to_host(bus); |
| 422 | if (hose == NULL) | 420 | if (hose == NULL) |
| @@ -442,16 +440,16 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn, | |||
| 442 | */ | 440 | */ |
| 443 | switch (len) { | 441 | switch (len) { |
| 444 | case 1: | 442 | case 1: |
| 445 | out_8((u8 *)addr, val); | 443 | out_8(addr, val); |
| 446 | (void) in_8((u8 *)addr); | 444 | (void) in_8(addr); |
| 447 | break; | 445 | break; |
| 448 | case 2: | 446 | case 2: |
| 449 | out_le16((u16 *)addr, val); | 447 | out_le16(addr, val); |
| 450 | (void) in_le16((u16 *)addr); | 448 | (void) in_le16(addr); |
| 451 | break; | 449 | break; |
| 452 | default: | 450 | default: |
| 453 | out_le32((u32 *)addr, val); | 451 | out_le32((u32 __iomem *)addr, val); |
| 454 | (void) in_le32((u32 *)addr); | 452 | (void) in_le32(addr); |
| 455 | break; | 453 | break; |
| 456 | } | 454 | } |
| 457 | return PCIBIOS_SUCCESSFUL; | 455 | return PCIBIOS_SUCCESSFUL; |
| @@ -476,7 +474,7 @@ static struct pci_ops u3_ht_pci_ops = | |||
| 476 | |(((unsigned int)(off)) & 0xfcU) \ | 474 | |(((unsigned int)(off)) & 0xfcU) \ |
| 477 | |1UL) | 475 | |1UL) |
| 478 | 476 | ||
| 479 | static unsigned long u4_pcie_cfg_access(struct pci_controller* hose, | 477 | static volatile void __iomem *u4_pcie_cfg_access(struct pci_controller* hose, |
| 480 | u8 bus, u8 dev_fn, int offset) | 478 | u8 bus, u8 dev_fn, int offset) |
| 481 | { | 479 | { |
| 482 | unsigned int caddr; | 480 | unsigned int caddr; |
| @@ -492,14 +490,14 @@ static unsigned long u4_pcie_cfg_access(struct pci_controller* hose, | |||
| 492 | } while (in_le32(hose->cfg_addr) != caddr); | 490 | } while (in_le32(hose->cfg_addr) != caddr); |
| 493 | 491 | ||
| 494 | offset &= 0x03; | 492 | offset &= 0x03; |
| 495 | return ((unsigned long)hose->cfg_data) + offset; | 493 | return hose->cfg_data + offset; |
| 496 | } | 494 | } |
| 497 | 495 | ||
| 498 | static int u4_pcie_read_config(struct pci_bus *bus, unsigned int devfn, | 496 | static int u4_pcie_read_config(struct pci_bus *bus, unsigned int devfn, |
| 499 | int offset, int len, u32 *val) | 497 | int offset, int len, u32 *val) |
| 500 | { | 498 | { |
| 501 | struct pci_controller *hose; | 499 | struct pci_controller *hose; |
| 502 | unsigned long addr; | 500 | volatile void __iomem *addr; |
| 503 | 501 | ||
| 504 | hose = pci_bus_to_host(bus); | 502 | hose = pci_bus_to_host(bus); |
| 505 | if (hose == NULL) | 503 | if (hose == NULL) |
| @@ -515,13 +513,13 @@ static int u4_pcie_read_config(struct pci_bus *bus, unsigned int devfn, | |||
| 515 | */ | 513 | */ |
| 516 | switch (len) { | 514 | switch (len) { |
| 517 | case 1: | 515 | case 1: |
| 518 | *val = in_8((u8 *)addr); | 516 | *val = in_8(addr); |
| 519 | break; | 517 | break; |
| 520 | case 2: | 518 | case 2: |
| 521 | *val = in_le16((u16 *)addr); | 519 | *val = in_le16(addr); |
| 522 | break; | 520 | break; |
| 523 | default: | 521 | default: |
| 524 | *val = in_le32((u32 *)addr); | 522 | *val = in_le32(addr); |
| 525 | break; | 523 | break; |
| 526 | } | 524 | } |
| 527 | return PCIBIOS_SUCCESSFUL; | 525 | return PCIBIOS_SUCCESSFUL; |
| @@ -531,7 +529,7 @@ static int u4_pcie_write_config(struct pci_bus *bus, unsigned int devfn, | |||
| 531 | int offset, int len, u32 val) | 529 | int offset, int len, u32 val) |
| 532 | { | 530 | { |
| 533 | struct pci_controller *hose; | 531 | struct pci_controller *hose; |
| 534 | unsigned long addr; | 532 | volatile void __iomem *addr; |
| 535 | 533 | ||
| 536 | hose = pci_bus_to_host(bus); | 534 | hose = pci_bus_to_host(bus); |
| 537 | if (hose == NULL) | 535 | if (hose == NULL) |
| @@ -547,16 +545,16 @@ static int u4_pcie_write_config(struct pci_bus *bus, unsigned int devfn, | |||
| 547 | */ | 545 | */ |
| 548 | switch (len) { | 546 | switch (len) { |
| 549 | case 1: | 547 | case 1: |
| 550 | out_8((u8 *)addr, val); | 548 | out_8(addr, val); |
| 551 | (void) in_8((u8 *)addr); | 549 | (void) in_8(addr); |
| 552 | break; | 550 | break; |
| 553 | case 2: | 551 | case 2: |
| 554 | out_le16((u16 *)addr, val); | 552 | out_le16(addr, val); |
| 555 | (void) in_le16((u16 *)addr); | 553 | (void) in_le16(addr); |
| 556 | break; | 554 | break; |
| 557 | default: | 555 | default: |
| 558 | out_le32((u32 *)addr, val); | 556 | out_le32(addr, val); |
| 559 | (void) in_le32((u32 *)addr); | 557 | (void) in_le32(addr); |
| 560 | break; | 558 | break; |
| 561 | } | 559 | } |
| 562 | return PCIBIOS_SUCCESSFUL; | 560 | return PCIBIOS_SUCCESSFUL; |
| @@ -773,8 +771,7 @@ static void __init setup_u3_ht(struct pci_controller* hose) | |||
| 773 | * the reg address cell, we shall fix that by killing struct | 771 | * the reg address cell, we shall fix that by killing struct |
| 774 | * reg_property and using some accessor functions instead | 772 | * reg_property and using some accessor functions instead |
| 775 | */ | 773 | */ |
| 776 | hose->cfg_data = (volatile unsigned char *)ioremap(0xf2000000, | 774 | hose->cfg_data = ioremap(0xf2000000, 0x02000000); |
| 777 | 0x02000000); | ||
| 778 | 775 | ||
| 779 | /* | 776 | /* |
| 780 | * /ht node doesn't expose a "ranges" property, so we "remove" | 777 | * /ht node doesn't expose a "ranges" property, so we "remove" |
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 89c4c3636161..1955462f4082 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c | |||
| @@ -82,8 +82,6 @@ | |||
| 82 | 82 | ||
| 83 | #undef SHOW_GATWICK_IRQS | 83 | #undef SHOW_GATWICK_IRQS |
| 84 | 84 | ||
| 85 | unsigned char drive_info; | ||
| 86 | |||
| 87 | int ppc_override_l2cr = 0; | 85 | int ppc_override_l2cr = 0; |
| 88 | int ppc_override_l2cr_value; | 86 | int ppc_override_l2cr_value; |
| 89 | int has_l2cache = 0; | 87 | int has_l2cache = 0; |
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c index 6373372932ba..e3cbba49fd6e 100644 --- a/arch/powerpc/platforms/pseries/eeh_driver.c +++ b/arch/powerpc/platforms/pseries/eeh_driver.c | |||
| @@ -333,7 +333,7 @@ void handle_eeh_events (struct eeh_event *event) | |||
| 333 | rc = eeh_reset_device(frozen_pdn, NULL); | 333 | rc = eeh_reset_device(frozen_pdn, NULL); |
| 334 | if (rc) | 334 | if (rc) |
| 335 | goto hard_fail; | 335 | goto hard_fail; |
| 336 | pci_walk_bus(frozen_bus, eeh_report_reset, 0); | 336 | pci_walk_bus(frozen_bus, eeh_report_reset, NULL); |
| 337 | } | 337 | } |
| 338 | 338 | ||
| 339 | /* If all devices reported they can proceed, the re-enable PIO */ | 339 | /* If all devices reported they can proceed, the re-enable PIO */ |
| @@ -342,11 +342,11 @@ void handle_eeh_events (struct eeh_event *event) | |||
| 342 | rc = eeh_reset_device(frozen_pdn, NULL); | 342 | rc = eeh_reset_device(frozen_pdn, NULL); |
| 343 | if (rc) | 343 | if (rc) |
| 344 | goto hard_fail; | 344 | goto hard_fail; |
| 345 | pci_walk_bus(frozen_bus, eeh_report_reset, 0); | 345 | pci_walk_bus(frozen_bus, eeh_report_reset, NULL); |
| 346 | } | 346 | } |
| 347 | 347 | ||
| 348 | /* Tell all device drivers that they can resume operations */ | 348 | /* Tell all device drivers that they can resume operations */ |
| 349 | pci_walk_bus(frozen_bus, eeh_report_resume, 0); | 349 | pci_walk_bus(frozen_bus, eeh_report_resume, NULL); |
| 350 | 350 | ||
| 351 | return; | 351 | return; |
| 352 | 352 | ||
| @@ -367,7 +367,7 @@ hard_fail: | |||
| 367 | eeh_slot_error_detail(frozen_pdn, 2 /* Permanent Error */); | 367 | eeh_slot_error_detail(frozen_pdn, 2 /* Permanent Error */); |
| 368 | 368 | ||
| 369 | /* Notify all devices that they're about to go down. */ | 369 | /* Notify all devices that they're about to go down. */ |
| 370 | pci_walk_bus(frozen_bus, eeh_report_failure, 0); | 370 | pci_walk_bus(frozen_bus, eeh_report_failure, NULL); |
| 371 | 371 | ||
| 372 | /* Shut down the device drivers for good. */ | 372 | /* Shut down the device drivers for good. */ |
| 373 | pcibios_remove_pci_devices(frozen_bus); | 373 | pcibios_remove_pci_devices(frozen_bus); |
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index da6cebaf72cd..9edeca83f434 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
| @@ -585,7 +585,7 @@ static int pSeries_pci_probe_mode(struct pci_bus *bus) | |||
| 585 | static void pseries_kexec_cpu_down(int crash_shutdown, int secondary) | 585 | static void pseries_kexec_cpu_down(int crash_shutdown, int secondary) |
| 586 | { | 586 | { |
| 587 | /* Don't risk a hypervisor call if we're crashing */ | 587 | /* Don't risk a hypervisor call if we're crashing */ |
| 588 | if (!crash_shutdown) { | 588 | if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) { |
| 589 | unsigned long vpa = __pa(get_lppaca()); | 589 | unsigned long vpa = __pa(get_lppaca()); |
| 590 | 590 | ||
| 591 | if (unregister_vpa(hard_smp_processor_id(), vpa)) { | 591 | if (unregister_vpa(hard_smp_processor_id(), vpa)) { |
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index 977de9db8754..6298264efe36 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c | |||
| @@ -59,7 +59,7 @@ static unsigned long dart_tablesize; | |||
| 59 | static u32 *dart_vbase; | 59 | static u32 *dart_vbase; |
| 60 | 60 | ||
| 61 | /* Mapped base address for the dart */ | 61 | /* Mapped base address for the dart */ |
| 62 | static unsigned int *__iomem dart; | 62 | static unsigned int __iomem *dart; |
| 63 | 63 | ||
| 64 | /* Dummy val that entries are set to when unused */ | 64 | /* Dummy val that entries are set to when unused */ |
| 65 | static unsigned int dart_emptyval; | 65 | static unsigned int dart_emptyval; |
diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S index 3e6ca7f5843f..c1e89ad0684d 100644 --- a/arch/ppc/kernel/head_8xx.S +++ b/arch/ppc/kernel/head_8xx.S | |||
| @@ -810,13 +810,16 @@ initial_mmu: | |||
| 810 | mtspr SPRN_MD_TWC, r9 | 810 | mtspr SPRN_MD_TWC, r9 |
| 811 | li r11, MI_BOOTINIT /* Create RPN for address 0 */ | 811 | li r11, MI_BOOTINIT /* Create RPN for address 0 */ |
| 812 | addis r11, r11, 0x0080 /* Add 8M */ | 812 | addis r11, r11, 0x0080 /* Add 8M */ |
| 813 | mtspr SPRN_MD_RPN, r8 | 813 | mtspr SPRN_MD_RPN, r11 |
| 814 | |||
| 815 | addi r10, r10, 0x0100 | ||
| 816 | mtspr SPRN_MD_CTR, r10 | ||
| 814 | 817 | ||
| 815 | addis r8, r8, 0x0080 /* Add 8M */ | 818 | addis r8, r8, 0x0080 /* Add 8M */ |
| 816 | mtspr SPRN_MD_EPN, r8 | 819 | mtspr SPRN_MD_EPN, r8 |
| 817 | mtspr SPRN_MD_TWC, r9 | 820 | mtspr SPRN_MD_TWC, r9 |
| 818 | addis r11, r11, 0x0080 /* Add 8M */ | 821 | addis r11, r11, 0x0080 /* Add 8M */ |
| 819 | mtspr SPRN_MD_RPN, r8 | 822 | mtspr SPRN_MD_RPN, r11 |
| 820 | #endif | 823 | #endif |
| 821 | 824 | ||
| 822 | /* Since the cache is enabled according to the information we | 825 | /* Since the cache is enabled according to the information we |
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index 3a6e4bcb3c53..15bd9b448a48 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c | |||
| @@ -186,11 +186,15 @@ EXPORT_SYMBOL(flush_tlb_kernel_range); | |||
| 186 | EXPORT_SYMBOL(flush_tlb_page); | 186 | EXPORT_SYMBOL(flush_tlb_page); |
| 187 | EXPORT_SYMBOL(_tlbie); | 187 | EXPORT_SYMBOL(_tlbie); |
| 188 | #ifdef CONFIG_ALTIVEC | 188 | #ifdef CONFIG_ALTIVEC |
| 189 | #ifndef CONFIG_SMP | ||
| 189 | EXPORT_SYMBOL(last_task_used_altivec); | 190 | EXPORT_SYMBOL(last_task_used_altivec); |
| 191 | #endif | ||
| 190 | EXPORT_SYMBOL(giveup_altivec); | 192 | EXPORT_SYMBOL(giveup_altivec); |
| 191 | #endif /* CONFIG_ALTIVEC */ | 193 | #endif /* CONFIG_ALTIVEC */ |
| 192 | #ifdef CONFIG_SPE | 194 | #ifdef CONFIG_SPE |
| 195 | #ifndef CONFIG_SMP | ||
| 193 | EXPORT_SYMBOL(last_task_used_spe); | 196 | EXPORT_SYMBOL(last_task_used_spe); |
| 197 | #endif | ||
| 194 | EXPORT_SYMBOL(giveup_spe); | 198 | EXPORT_SYMBOL(giveup_spe); |
| 195 | #endif /* CONFIG_SPE */ | 199 | #endif /* CONFIG_SPE */ |
| 196 | #ifdef CONFIG_SMP | 200 | #ifdef CONFIG_SMP |
diff --git a/arch/ppc/platforms/4xx/bamboo.c b/arch/ppc/platforms/4xx/bamboo.c index 159b228eca1e..0ec53f049338 100644 --- a/arch/ppc/platforms/4xx/bamboo.c +++ b/arch/ppc/platforms/4xx/bamboo.c | |||
| @@ -332,8 +332,8 @@ bamboo_early_serial_map(void) | |||
| 332 | port.irq = 0; | 332 | port.irq = 0; |
| 333 | port.uartclk = clocks.uart0; | 333 | port.uartclk = clocks.uart0; |
| 334 | port.regshift = 0; | 334 | port.regshift = 0; |
| 335 | port.iotype = SERIAL_IO_MEM; | 335 | port.iotype = UPIO_MEM; |
| 336 | port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; | 336 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
| 337 | port.line = 0; | 337 | port.line = 0; |
| 338 | 338 | ||
| 339 | if (early_serial_setup(&port) != 0) { | 339 | if (early_serial_setup(&port) != 0) { |
diff --git a/arch/ppc/platforms/4xx/bubinga.c b/arch/ppc/platforms/4xx/bubinga.c index 8110f55668c5..ce48a4f08cbb 100644 --- a/arch/ppc/platforms/4xx/bubinga.c +++ b/arch/ppc/platforms/4xx/bubinga.c | |||
| @@ -97,8 +97,8 @@ bubinga_early_serial_map(void) | |||
| 97 | port.irq = ACTING_UART0_INT; | 97 | port.irq = ACTING_UART0_INT; |
| 98 | port.uartclk = uart_clock; | 98 | port.uartclk = uart_clock; |
| 99 | port.regshift = 0; | 99 | port.regshift = 0; |
| 100 | port.iotype = SERIAL_IO_MEM; | 100 | port.iotype = UPIO_MEM; |
| 101 | port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; | 101 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
| 102 | port.line = 0; | 102 | port.line = 0; |
| 103 | 103 | ||
| 104 | if (early_serial_setup(&port) != 0) { | 104 | if (early_serial_setup(&port) != 0) { |
diff --git a/arch/ppc/platforms/4xx/ebony.c b/arch/ppc/platforms/4xx/ebony.c index 64ebae19cdbb..9a828b623417 100644 --- a/arch/ppc/platforms/4xx/ebony.c +++ b/arch/ppc/platforms/4xx/ebony.c | |||
| @@ -225,8 +225,8 @@ ebony_early_serial_map(void) | |||
| 225 | port.irq = 0; | 225 | port.irq = 0; |
| 226 | port.uartclk = clocks.uart0; | 226 | port.uartclk = clocks.uart0; |
| 227 | port.regshift = 0; | 227 | port.regshift = 0; |
| 228 | port.iotype = SERIAL_IO_MEM; | 228 | port.iotype = UPIO_MEM; |
| 229 | port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; | 229 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
| 230 | port.line = 0; | 230 | port.line = 0; |
| 231 | 231 | ||
| 232 | if (early_serial_setup(&port) != 0) { | 232 | if (early_serial_setup(&port) != 0) { |
diff --git a/arch/ppc/platforms/4xx/luan.c b/arch/ppc/platforms/4xx/luan.c index d810b736d9bf..21d29132aebd 100644 --- a/arch/ppc/platforms/4xx/luan.c +++ b/arch/ppc/platforms/4xx/luan.c | |||
| @@ -279,8 +279,8 @@ luan_early_serial_map(void) | |||
| 279 | port.irq = UART0_INT; | 279 | port.irq = UART0_INT; |
| 280 | port.uartclk = clocks.uart0; | 280 | port.uartclk = clocks.uart0; |
| 281 | port.regshift = 0; | 281 | port.regshift = 0; |
| 282 | port.iotype = SERIAL_IO_MEM; | 282 | port.iotype = UPIO_MEM; |
| 283 | port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; | 283 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
| 284 | port.line = 0; | 284 | port.line = 0; |
| 285 | 285 | ||
| 286 | if (early_serial_setup(&port) != 0) { | 286 | if (early_serial_setup(&port) != 0) { |
diff --git a/arch/ppc/platforms/4xx/ocotea.c b/arch/ppc/platforms/4xx/ocotea.c index 73b2c98158f6..4f355b6acab2 100644 --- a/arch/ppc/platforms/4xx/ocotea.c +++ b/arch/ppc/platforms/4xx/ocotea.c | |||
| @@ -248,8 +248,8 @@ ocotea_early_serial_map(void) | |||
| 248 | port.irq = UART0_INT; | 248 | port.irq = UART0_INT; |
| 249 | port.uartclk = clocks.uart0; | 249 | port.uartclk = clocks.uart0; |
| 250 | port.regshift = 0; | 250 | port.regshift = 0; |
| 251 | port.iotype = SERIAL_IO_MEM; | 251 | port.iotype = UPIO_MEM; |
| 252 | port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; | 252 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
| 253 | port.line = 0; | 253 | port.line = 0; |
| 254 | 254 | ||
| 255 | if (early_serial_setup(&port) != 0) { | 255 | if (early_serial_setup(&port) != 0) { |
diff --git a/arch/ppc/platforms/4xx/xilinx_ml300.c b/arch/ppc/platforms/4xx/xilinx_ml300.c index 0b1b77d986bf..e90d97f64f76 100644 --- a/arch/ppc/platforms/4xx/xilinx_ml300.c +++ b/arch/ppc/platforms/4xx/xilinx_ml300.c | |||
| @@ -95,8 +95,8 @@ ml300_early_serial_map(void) | |||
| 95 | port.irq = old_ports[i].irq; | 95 | port.irq = old_ports[i].irq; |
| 96 | port.uartclk = old_ports[i].baud_base * 16; | 96 | port.uartclk = old_ports[i].baud_base * 16; |
| 97 | port.regshift = old_ports[i].iomem_reg_shift; | 97 | port.regshift = old_ports[i].iomem_reg_shift; |
| 98 | port.iotype = SERIAL_IO_MEM; | 98 | port.iotype = UPIO_MEM; |
| 99 | port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; | 99 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
| 100 | port.line = i; | 100 | port.line = i; |
| 101 | 101 | ||
| 102 | if (early_serial_setup(&port) != 0) { | 102 | if (early_serial_setup(&port) != 0) { |
diff --git a/arch/ppc/platforms/4xx/yucca.c b/arch/ppc/platforms/4xx/yucca.c index e60f4bd437ec..b065b8babcd3 100644 --- a/arch/ppc/platforms/4xx/yucca.c +++ b/arch/ppc/platforms/4xx/yucca.c | |||
| @@ -305,8 +305,8 @@ yucca_early_serial_map(void) | |||
| 305 | port.irq = UART0_INT; | 305 | port.irq = UART0_INT; |
| 306 | port.uartclk = clocks.uart0; | 306 | port.uartclk = clocks.uart0; |
| 307 | port.regshift = 0; | 307 | port.regshift = 0; |
| 308 | port.iotype = SERIAL_IO_MEM; | 308 | port.iotype = UPIO_MEM; |
| 309 | port.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST; | 309 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST; |
| 310 | port.line = 0; | 310 | port.line = 0; |
| 311 | 311 | ||
| 312 | if (early_serial_setup(&port) != 0) { | 312 | if (early_serial_setup(&port) != 0) { |
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c index 012e1e652c03..1a659bbc1860 100644 --- a/arch/ppc/platforms/83xx/mpc834x_sys.c +++ b/arch/ppc/platforms/83xx/mpc834x_sys.c | |||
| @@ -301,14 +301,14 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | |||
| 301 | struct uart_port p; | 301 | struct uart_port p; |
| 302 | 302 | ||
| 303 | memset(&p, 0, sizeof (p)); | 303 | memset(&p, 0, sizeof (p)); |
| 304 | p.iotype = SERIAL_IO_MEM; | 304 | p.iotype = UPIO_MEM; |
| 305 | p.membase = (unsigned char __iomem *)(VIRT_IMMRBAR + 0x4500); | 305 | p.membase = (unsigned char __iomem *)(VIRT_IMMRBAR + 0x4500); |
| 306 | p.uartclk = binfo->bi_busfreq; | 306 | p.uartclk = binfo->bi_busfreq; |
| 307 | 307 | ||
| 308 | gen550_init(0, &p); | 308 | gen550_init(0, &p); |
| 309 | 309 | ||
| 310 | memset(&p, 0, sizeof (p)); | 310 | memset(&p, 0, sizeof (p)); |
| 311 | p.iotype = SERIAL_IO_MEM; | 311 | p.iotype = UPIO_MEM; |
| 312 | p.membase = (unsigned char __iomem *)(VIRT_IMMRBAR + 0x4600); | 312 | p.membase = (unsigned char __iomem *)(VIRT_IMMRBAR + 0x4600); |
| 313 | p.uartclk = binfo->bi_busfreq; | 313 | p.uartclk = binfo->bi_busfreq; |
| 314 | 314 | ||
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c index 2eceb1e6f4eb..408d64f18e1a 100644 --- a/arch/ppc/platforms/85xx/mpc8540_ads.c +++ b/arch/ppc/platforms/85xx/mpc8540_ads.c | |||
| @@ -162,14 +162,14 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | |||
| 162 | binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0); | 162 | binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0); |
| 163 | 163 | ||
| 164 | memset(&p, 0, sizeof (p)); | 164 | memset(&p, 0, sizeof (p)); |
| 165 | p.iotype = SERIAL_IO_MEM; | 165 | p.iotype = UPIO_MEM; |
| 166 | p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART0_OFFSET; | 166 | p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART0_OFFSET; |
| 167 | p.uartclk = binfo->bi_busfreq; | 167 | p.uartclk = binfo->bi_busfreq; |
| 168 | 168 | ||
| 169 | gen550_init(0, &p); | 169 | gen550_init(0, &p); |
| 170 | 170 | ||
| 171 | memset(&p, 0, sizeof (p)); | 171 | memset(&p, 0, sizeof (p)); |
| 172 | p.iotype = SERIAL_IO_MEM; | 172 | p.iotype = UPIO_MEM; |
| 173 | p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART1_OFFSET; | 173 | p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART1_OFFSET; |
| 174 | p.uartclk = binfo->bi_busfreq; | 174 | p.uartclk = binfo->bi_busfreq; |
| 175 | 175 | ||
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c index b332ebae6bd3..1801ab392e22 100644 --- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c +++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c | |||
| @@ -534,14 +534,14 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | |||
| 534 | binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0); | 534 | binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0); |
| 535 | 535 | ||
| 536 | memset(&p, 0, sizeof (p)); | 536 | memset(&p, 0, sizeof (p)); |
| 537 | p.iotype = SERIAL_IO_MEM; | 537 | p.iotype = UPIO_MEM; |
| 538 | p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART0_OFFSET; | 538 | p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART0_OFFSET; |
| 539 | p.uartclk = binfo->bi_busfreq; | 539 | p.uartclk = binfo->bi_busfreq; |
| 540 | 540 | ||
| 541 | gen550_init(0, &p); | 541 | gen550_init(0, &p); |
| 542 | 542 | ||
| 543 | memset(&p, 0, sizeof (p)); | 543 | memset(&p, 0, sizeof (p)); |
| 544 | p.iotype = SERIAL_IO_MEM; | 544 | p.iotype = UPIO_MEM; |
| 545 | p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART1_OFFSET; | 545 | p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART1_OFFSET; |
| 546 | p.uartclk = binfo->bi_busfreq; | 546 | p.uartclk = binfo->bi_busfreq; |
| 547 | 547 | ||
diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c index e777ba824aa9..8a72221f816c 100644 --- a/arch/ppc/platforms/85xx/sbc8560.c +++ b/arch/ppc/platforms/85xx/sbc8560.c | |||
| @@ -64,7 +64,7 @@ sbc8560_early_serial_map(void) | |||
| 64 | uart_req.irq = MPC85xx_IRQ_EXT9; | 64 | uart_req.irq = MPC85xx_IRQ_EXT9; |
| 65 | uart_req.flags = STD_COM_FLAGS; | 65 | uart_req.flags = STD_COM_FLAGS; |
| 66 | uart_req.uartclk = BASE_BAUD * 16; | 66 | uart_req.uartclk = BASE_BAUD * 16; |
| 67 | uart_req.iotype = SERIAL_IO_MEM; | 67 | uart_req.iotype = UPIO_MEM; |
| 68 | uart_req.mapbase = UARTA_ADDR; | 68 | uart_req.mapbase = UARTA_ADDR; |
| 69 | uart_req.membase = ioremap(uart_req.mapbase, MPC85xx_UART0_SIZE); | 69 | uart_req.membase = ioremap(uart_req.mapbase, MPC85xx_UART0_SIZE); |
| 70 | uart_req.type = PORT_16650; | 70 | uart_req.type = PORT_16650; |
diff --git a/arch/ppc/platforms/85xx/tqm85xx.c b/arch/ppc/platforms/85xx/tqm85xx.c index b436f4d0a3fa..a5e38ba62732 100644 --- a/arch/ppc/platforms/85xx/tqm85xx.c +++ b/arch/ppc/platforms/85xx/tqm85xx.c | |||
| @@ -346,14 +346,14 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | |||
| 346 | binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0); | 346 | binfo->bi_immr_base, MPC85xx_CCSRBAR_SIZE, _PAGE_IO, 0); |
| 347 | 347 | ||
| 348 | memset(&p, 0, sizeof (p)); | 348 | memset(&p, 0, sizeof (p)); |
| 349 | p.iotype = SERIAL_IO_MEM; | 349 | p.iotype = UPIO_MEM; |
| 350 | p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART0_OFFSET; | 350 | p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART0_OFFSET; |
| 351 | p.uartclk = binfo->bi_busfreq; | 351 | p.uartclk = binfo->bi_busfreq; |
| 352 | 352 | ||
| 353 | gen550_init(0, &p); | 353 | gen550_init(0, &p); |
| 354 | 354 | ||
| 355 | memset(&p, 0, sizeof (p)); | 355 | memset(&p, 0, sizeof (p)); |
| 356 | p.iotype = SERIAL_IO_MEM; | 356 | p.iotype = UPIO_MEM; |
| 357 | p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART1_OFFSET; | 357 | p.membase = (void *) binfo->bi_immr_base + MPC85xx_UART1_OFFSET; |
| 358 | p.uartclk = binfo->bi_busfreq; | 358 | p.uartclk = binfo->bi_busfreq; |
| 359 | 359 | ||
diff --git a/arch/ppc/platforms/chestnut.c b/arch/ppc/platforms/chestnut.c index 48a4a510d598..aefcc0e7be57 100644 --- a/arch/ppc/platforms/chestnut.c +++ b/arch/ppc/platforms/chestnut.c | |||
| @@ -116,7 +116,7 @@ chestnut_early_serial_map(void) | |||
| 116 | port.uartclk = BASE_BAUD * 16; | 116 | port.uartclk = BASE_BAUD * 16; |
| 117 | port.irq = UART0_INT; | 117 | port.irq = UART0_INT; |
| 118 | port.flags = STD_COM_FLAGS | UPF_IOREMAP; | 118 | port.flags = STD_COM_FLAGS | UPF_IOREMAP; |
| 119 | port.iotype = SERIAL_IO_MEM; | 119 | port.iotype = UPIO_MEM; |
| 120 | port.mapbase = CHESTNUT_UART0_IO_BASE; | 120 | port.mapbase = CHESTNUT_UART0_IO_BASE; |
| 121 | port.regshift = 0; | 121 | port.regshift = 0; |
| 122 | 122 | ||
diff --git a/arch/ppc/platforms/ev64260.c b/arch/ppc/platforms/ev64260.c index 32358b3fb236..ffde8f6f6302 100644 --- a/arch/ppc/platforms/ev64260.c +++ b/arch/ppc/platforms/ev64260.c | |||
| @@ -330,7 +330,7 @@ ev64260_early_serial_map(void) | |||
| 330 | port.irq = EV64260_UART_0_IRQ; | 330 | port.irq = EV64260_UART_0_IRQ; |
| 331 | port.uartclk = BASE_BAUD * 16; | 331 | port.uartclk = BASE_BAUD * 16; |
| 332 | port.regshift = 2; | 332 | port.regshift = 2; |
| 333 | port.iotype = SERIAL_IO_MEM; | 333 | port.iotype = UPIO_MEM; |
| 334 | port.flags = STD_COM_FLAGS; | 334 | port.flags = STD_COM_FLAGS; |
| 335 | 335 | ||
| 336 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) | 336 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) |
diff --git a/arch/ppc/platforms/radstone_ppc7d.c b/arch/ppc/platforms/radstone_ppc7d.c index 708b8739ecdd..872c0a3ba3c7 100644 --- a/arch/ppc/platforms/radstone_ppc7d.c +++ b/arch/ppc/platforms/radstone_ppc7d.c | |||
| @@ -100,7 +100,7 @@ static void __init ppc7d_early_serial_map(void) | |||
| 100 | serial_req.uartclk = UART_CLK; | 100 | serial_req.uartclk = UART_CLK; |
| 101 | serial_req.irq = 4; | 101 | serial_req.irq = 4; |
| 102 | serial_req.flags = STD_COM_FLAGS; | 102 | serial_req.flags = STD_COM_FLAGS; |
| 103 | serial_req.iotype = SERIAL_IO_MEM; | 103 | serial_req.iotype = UPIO_MEM; |
| 104 | serial_req.membase = (u_char *) PPC7D_SERIAL_0; | 104 | serial_req.membase = (u_char *) PPC7D_SERIAL_0; |
| 105 | 105 | ||
| 106 | gen550_init(0, &serial_req); | 106 | gen550_init(0, &serial_req); |
diff --git a/arch/ppc/platforms/spruce.c b/arch/ppc/platforms/spruce.c index 5ad70d357cb9..69e1de7971f2 100644 --- a/arch/ppc/platforms/spruce.c +++ b/arch/ppc/platforms/spruce.c | |||
| @@ -176,8 +176,8 @@ spruce_early_serial_map(void) | |||
| 176 | memset(&serial_req, 0, sizeof(serial_req)); | 176 | memset(&serial_req, 0, sizeof(serial_req)); |
| 177 | serial_req.uartclk = uart_clk; | 177 | serial_req.uartclk = uart_clk; |
| 178 | serial_req.irq = UART0_INT; | 178 | serial_req.irq = UART0_INT; |
| 179 | serial_req.flags = ASYNC_BOOT_AUTOCONF; | 179 | serial_req.flags = UPF_BOOT_AUTOCONF; |
| 180 | serial_req.iotype = SERIAL_IO_MEM; | 180 | serial_req.iotype = UPIO_MEM; |
| 181 | serial_req.membase = (u_char *)UART0_IO_BASE; | 181 | serial_req.membase = (u_char *)UART0_IO_BASE; |
| 182 | serial_req.regshift = 0; | 182 | serial_req.regshift = 0; |
| 183 | 183 | ||
diff --git a/arch/ppc/syslib/ocp.c b/arch/ppc/syslib/ocp.c index ab34b1d6072f..2fe28ded2c60 100644 --- a/arch/ppc/syslib/ocp.c +++ b/arch/ppc/syslib/ocp.c | |||
| @@ -189,8 +189,8 @@ ocp_device_resume(struct device *dev) | |||
| 189 | struct bus_type ocp_bus_type = { | 189 | struct bus_type ocp_bus_type = { |
| 190 | .name = "ocp", | 190 | .name = "ocp", |
| 191 | .match = ocp_device_match, | 191 | .match = ocp_device_match, |
| 192 | .probe = ocp_driver_probe, | 192 | .probe = ocp_device_probe, |
| 193 | .remove = ocp_driver_remove, | 193 | .remove = ocp_device_remove, |
| 194 | .suspend = ocp_device_suspend, | 194 | .suspend = ocp_device_suspend, |
| 195 | .resume = ocp_device_resume, | 195 | .resume = ocp_device_resume, |
| 196 | }; | 196 | }; |
diff --git a/arch/ppc/syslib/ppc83xx_setup.c b/arch/ppc/syslib/ppc83xx_setup.c index 1b5fe9e398d4..7bada82527a8 100644 --- a/arch/ppc/syslib/ppc83xx_setup.c +++ b/arch/ppc/syslib/ppc83xx_setup.c | |||
| @@ -108,7 +108,7 @@ mpc83xx_early_serial_map(void) | |||
| 108 | 108 | ||
| 109 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) | 109 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) |
| 110 | memset(&serial_req, 0, sizeof (serial_req)); | 110 | memset(&serial_req, 0, sizeof (serial_req)); |
| 111 | serial_req.iotype = SERIAL_IO_MEM; | 111 | serial_req.iotype = UPIO_MEM; |
| 112 | serial_req.mapbase = pdata[0].mapbase; | 112 | serial_req.mapbase = pdata[0].mapbase; |
| 113 | serial_req.membase = pdata[0].membase; | 113 | serial_req.membase = pdata[0].membase; |
| 114 | serial_req.regshift = 0; | 114 | serial_req.regshift = 0; |
diff --git a/arch/ppc/syslib/ppc85xx_setup.c b/arch/ppc/syslib/ppc85xx_setup.c index 1a47ff4b831d..e4dda43fdaa7 100644 --- a/arch/ppc/syslib/ppc85xx_setup.c +++ b/arch/ppc/syslib/ppc85xx_setup.c | |||
| @@ -90,7 +90,7 @@ mpc85xx_early_serial_map(void) | |||
| 90 | 90 | ||
| 91 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) | 91 | #if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) |
| 92 | memset(&serial_req, 0, sizeof (serial_req)); | 92 | memset(&serial_req, 0, sizeof (serial_req)); |
| 93 | serial_req.iotype = SERIAL_IO_MEM; | 93 | serial_req.iotype = UPIO_MEM; |
| 94 | serial_req.mapbase = pdata[0].mapbase; | 94 | serial_req.mapbase = pdata[0].mapbase; |
| 95 | serial_req.membase = pdata[0].membase; | 95 | serial_req.membase = pdata[0].membase; |
| 96 | serial_req.regshift = 0; | 96 | serial_req.regshift = 0; |
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index bf9a7a361b34..cc20f0e3a7d3 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c | |||
| @@ -100,12 +100,12 @@ | |||
| 100 | #define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid) | 100 | #define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid) |
| 101 | #define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid) | 101 | #define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid) |
| 102 | 102 | ||
| 103 | asmlinkage long sys32_chown16(const char * filename, u16 user, u16 group) | 103 | asmlinkage long sys32_chown16(const char __user * filename, u16 user, u16 group) |
| 104 | { | 104 | { |
| 105 | return sys_chown(filename, low2highuid(user), low2highgid(group)); | 105 | return sys_chown(filename, low2highuid(user), low2highgid(group)); |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | asmlinkage long sys32_lchown16(const char * filename, u16 user, u16 group) | 108 | asmlinkage long sys32_lchown16(const char __user * filename, u16 user, u16 group) |
| 109 | { | 109 | { |
| 110 | return sys_lchown(filename, low2highuid(user), low2highgid(group)); | 110 | return sys_lchown(filename, low2highuid(user), low2highgid(group)); |
| 111 | } | 111 | } |
| @@ -141,7 +141,7 @@ asmlinkage long sys32_setresuid16(u16 ruid, u16 euid, u16 suid) | |||
| 141 | low2highuid(suid)); | 141 | low2highuid(suid)); |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | asmlinkage long sys32_getresuid16(u16 *ruid, u16 *euid, u16 *suid) | 144 | asmlinkage long sys32_getresuid16(u16 __user *ruid, u16 __user *euid, u16 __user *suid) |
| 145 | { | 145 | { |
| 146 | int retval; | 146 | int retval; |
| 147 | 147 | ||
| @@ -158,7 +158,7 @@ asmlinkage long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid) | |||
| 158 | low2highgid(sgid)); | 158 | low2highgid(sgid)); |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | asmlinkage long sys32_getresgid16(u16 *rgid, u16 *egid, u16 *sgid) | 161 | asmlinkage long sys32_getresgid16(u16 __user *rgid, u16 __user *egid, u16 __user *sgid) |
| 162 | { | 162 | { |
| 163 | int retval; | 163 | int retval; |
| 164 | 164 | ||
| @@ -179,7 +179,7 @@ asmlinkage long sys32_setfsgid16(u16 gid) | |||
| 179 | return sys_setfsgid((gid_t)gid); | 179 | return sys_setfsgid((gid_t)gid); |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | static int groups16_to_user(u16 *grouplist, struct group_info *group_info) | 182 | static int groups16_to_user(u16 __user *grouplist, struct group_info *group_info) |
| 183 | { | 183 | { |
| 184 | int i; | 184 | int i; |
| 185 | u16 group; | 185 | u16 group; |
| @@ -193,7 +193,7 @@ static int groups16_to_user(u16 *grouplist, struct group_info *group_info) | |||
| 193 | return 0; | 193 | return 0; |
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | static int groups16_from_user(struct group_info *group_info, u16 *grouplist) | 196 | static int groups16_from_user(struct group_info *group_info, u16 __user *grouplist) |
| 197 | { | 197 | { |
| 198 | int i; | 198 | int i; |
| 199 | u16 group; | 199 | u16 group; |
| @@ -207,7 +207,7 @@ static int groups16_from_user(struct group_info *group_info, u16 *grouplist) | |||
| 207 | return 0; | 207 | return 0; |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | asmlinkage long sys32_getgroups16(int gidsetsize, u16 *grouplist) | 210 | asmlinkage long sys32_getgroups16(int gidsetsize, u16 __user *grouplist) |
| 211 | { | 211 | { |
| 212 | int i; | 212 | int i; |
| 213 | 213 | ||
| @@ -231,7 +231,7 @@ out: | |||
| 231 | return i; | 231 | return i; |
| 232 | } | 232 | } |
| 233 | 233 | ||
| 234 | asmlinkage long sys32_setgroups16(int gidsetsize, u16 *grouplist) | 234 | asmlinkage long sys32_setgroups16(int gidsetsize, u16 __user *grouplist) |
| 235 | { | 235 | { |
| 236 | struct group_info *group_info; | 236 | struct group_info *group_info; |
| 237 | int retval; | 237 | int retval; |
| @@ -278,14 +278,14 @@ asmlinkage long sys32_getegid16(void) | |||
| 278 | 278 | ||
| 279 | /* 32-bit timeval and related flotsam. */ | 279 | /* 32-bit timeval and related flotsam. */ |
| 280 | 280 | ||
| 281 | static inline long get_tv32(struct timeval *o, struct compat_timeval *i) | 281 | static inline long get_tv32(struct timeval *o, struct compat_timeval __user *i) |
| 282 | { | 282 | { |
| 283 | return (!access_ok(VERIFY_READ, o, sizeof(*o)) || | 283 | return (!access_ok(VERIFY_READ, o, sizeof(*o)) || |
| 284 | (__get_user(o->tv_sec, &i->tv_sec) || | 284 | (__get_user(o->tv_sec, &i->tv_sec) || |
| 285 | __get_user(o->tv_usec, &i->tv_usec))); | 285 | __get_user(o->tv_usec, &i->tv_usec))); |
| 286 | } | 286 | } |
| 287 | 287 | ||
| 288 | static inline long put_tv32(struct compat_timeval *o, struct timeval *i) | 288 | static inline long put_tv32(struct compat_timeval __user *o, struct timeval *i) |
| 289 | { | 289 | { |
| 290 | return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || | 290 | return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || |
| 291 | (__put_user(i->tv_sec, &o->tv_sec) || | 291 | (__put_user(i->tv_sec, &o->tv_sec) || |
| @@ -341,7 +341,7 @@ asmlinkage long sys32_ipc(u32 call, int first, int second, int third, u32 ptr) | |||
| 341 | return -ENOSYS; | 341 | return -ENOSYS; |
| 342 | } | 342 | } |
| 343 | 343 | ||
| 344 | asmlinkage long sys32_truncate64(const char * path, unsigned long high, unsigned long low) | 344 | asmlinkage long sys32_truncate64(const char __user * path, unsigned long high, unsigned long low) |
| 345 | { | 345 | { |
| 346 | if ((int)high < 0) | 346 | if ((int)high < 0) |
| 347 | return -EINVAL; | 347 | return -EINVAL; |
| @@ -357,7 +357,7 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned | |||
| 357 | return sys_ftruncate(fd, (high << 32) | low); | 357 | return sys_ftruncate(fd, (high << 32) | low); |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf) | 360 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) |
| 361 | { | 361 | { |
| 362 | int err; | 362 | int err; |
| 363 | 363 | ||
| @@ -591,7 +591,7 @@ sys32_delete_module(const char __user *name_user, unsigned int flags) | |||
| 591 | 591 | ||
| 592 | extern struct timezone sys_tz; | 592 | extern struct timezone sys_tz; |
| 593 | 593 | ||
| 594 | asmlinkage long sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz) | 594 | asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) |
| 595 | { | 595 | { |
| 596 | if (tv) { | 596 | if (tv) { |
| 597 | struct timeval ktv; | 597 | struct timeval ktv; |
| @@ -606,7 +606,7 @@ asmlinkage long sys32_gettimeofday(struct compat_timeval *tv, struct timezone *t | |||
| 606 | return 0; | 606 | return 0; |
| 607 | } | 607 | } |
| 608 | 608 | ||
| 609 | static inline long get_ts32(struct timespec *o, struct compat_timeval *i) | 609 | static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i) |
| 610 | { | 610 | { |
| 611 | long usec; | 611 | long usec; |
| 612 | 612 | ||
| @@ -620,7 +620,7 @@ static inline long get_ts32(struct timespec *o, struct compat_timeval *i) | |||
| 620 | return 0; | 620 | return 0; |
| 621 | } | 621 | } |
| 622 | 622 | ||
| 623 | asmlinkage long sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz) | 623 | asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) |
| 624 | { | 624 | { |
| 625 | struct timespec kts; | 625 | struct timespec kts; |
| 626 | struct timezone ktz; | 626 | struct timezone ktz; |
| @@ -645,7 +645,7 @@ asmlinkage long sys32_pause(void) | |||
| 645 | return -ERESTARTNOHAND; | 645 | return -ERESTARTNOHAND; |
| 646 | } | 646 | } |
| 647 | 647 | ||
| 648 | asmlinkage long sys32_pread64(unsigned int fd, char *ubuf, | 648 | asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf, |
| 649 | size_t count, u32 poshi, u32 poslo) | 649 | size_t count, u32 poshi, u32 poslo) |
| 650 | { | 650 | { |
| 651 | if ((compat_ssize_t) count < 0) | 651 | if ((compat_ssize_t) count < 0) |
| @@ -653,7 +653,7 @@ asmlinkage long sys32_pread64(unsigned int fd, char *ubuf, | |||
| 653 | return sys_pread64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo)); | 653 | return sys_pread64(fd, ubuf, count, ((loff_t)AA(poshi) << 32) | AA(poslo)); |
| 654 | } | 654 | } |
| 655 | 655 | ||
| 656 | asmlinkage long sys32_pwrite64(unsigned int fd, const char *ubuf, | 656 | asmlinkage long sys32_pwrite64(unsigned int fd, const char __user *ubuf, |
| 657 | size_t count, u32 poshi, u32 poslo) | 657 | size_t count, u32 poshi, u32 poslo) |
| 658 | { | 658 | { |
| 659 | if ((compat_ssize_t) count < 0) | 659 | if ((compat_ssize_t) count < 0) |
| @@ -666,7 +666,7 @@ asmlinkage compat_ssize_t sys32_readahead(int fd, u32 offhi, u32 offlo, s32 coun | |||
| 666 | return sys_readahead(fd, ((loff_t)AA(offhi) << 32) | AA(offlo), count); | 666 | return sys_readahead(fd, ((loff_t)AA(offhi) << 32) | AA(offlo), count); |
| 667 | } | 667 | } |
| 668 | 668 | ||
| 669 | asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, size_t count) | 669 | asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, size_t count) |
| 670 | { | 670 | { |
| 671 | mm_segment_t old_fs = get_fs(); | 671 | mm_segment_t old_fs = get_fs(); |
| 672 | int ret; | 672 | int ret; |
| @@ -686,7 +686,7 @@ asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, size | |||
| 686 | } | 686 | } |
| 687 | 687 | ||
| 688 | asmlinkage long sys32_sendfile64(int out_fd, int in_fd, | 688 | asmlinkage long sys32_sendfile64(int out_fd, int in_fd, |
| 689 | compat_loff_t *offset, s32 count) | 689 | compat_loff_t __user *offset, s32 count) |
| 690 | { | 690 | { |
| 691 | mm_segment_t old_fs = get_fs(); | 691 | mm_segment_t old_fs = get_fs(); |
| 692 | int ret; | 692 | int ret; |
| @@ -722,7 +722,7 @@ struct timex32 { | |||
| 722 | 722 | ||
| 723 | extern int do_adjtimex(struct timex *); | 723 | extern int do_adjtimex(struct timex *); |
| 724 | 724 | ||
| 725 | asmlinkage long sys32_adjtimex(struct timex32 *utp) | 725 | asmlinkage long sys32_adjtimex(struct timex32 __user *utp) |
| 726 | { | 726 | { |
| 727 | struct timex txc; | 727 | struct timex txc; |
| 728 | int ret; | 728 | int ret; |
| @@ -789,12 +789,13 @@ struct __sysctl_args32 { | |||
| 789 | u32 __unused[4]; | 789 | u32 __unused[4]; |
| 790 | }; | 790 | }; |
| 791 | 791 | ||
| 792 | asmlinkage long sys32_sysctl(struct __sysctl_args32 *args) | 792 | asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) |
| 793 | { | 793 | { |
| 794 | struct __sysctl_args32 tmp; | 794 | struct __sysctl_args32 tmp; |
| 795 | int error; | 795 | int error; |
| 796 | size_t oldlen, *oldlenp = NULL; | 796 | size_t oldlen; |
| 797 | unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7; | 797 | size_t __user *oldlenp = NULL; |
| 798 | unsigned long addr = (((unsigned long)&args->__unused[0]) + 7) & ~7; | ||
| 798 | 799 | ||
| 799 | if (copy_from_user(&tmp, args, sizeof(tmp))) | 800 | if (copy_from_user(&tmp, args, sizeof(tmp))) |
| 800 | return -EFAULT; | 801 | return -EFAULT; |
| @@ -806,20 +807,20 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 *args) | |||
| 806 | basically copy the whole sysctl.c here, and | 807 | basically copy the whole sysctl.c here, and |
| 807 | glibc's __sysctl uses rw memory for the structure | 808 | glibc's __sysctl uses rw memory for the structure |
| 808 | anyway. */ | 809 | anyway. */ |
| 809 | if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) || | 810 | if (get_user(oldlen, (u32 __user *)compat_ptr(tmp.oldlenp)) || |
| 810 | put_user(oldlen, (size_t *)addr)) | 811 | put_user(oldlen, (size_t __user *)addr)) |
| 811 | return -EFAULT; | 812 | return -EFAULT; |
| 812 | oldlenp = (size_t *)addr; | 813 | oldlenp = (size_t __user *)addr; |
| 813 | } | 814 | } |
| 814 | 815 | ||
| 815 | lock_kernel(); | 816 | lock_kernel(); |
| 816 | error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval), | 817 | error = do_sysctl(compat_ptr(tmp.name), tmp.nlen, compat_ptr(tmp.oldval), |
| 817 | oldlenp, (void *)A(tmp.newval), tmp.newlen); | 818 | oldlenp, compat_ptr(tmp.newval), tmp.newlen); |
| 818 | unlock_kernel(); | 819 | unlock_kernel(); |
| 819 | if (oldlenp) { | 820 | if (oldlenp) { |
| 820 | if (!error) { | 821 | if (!error) { |
| 821 | if (get_user(oldlen, (size_t *)addr) || | 822 | if (get_user(oldlen, (size_t __user *)addr) || |
| 822 | put_user(oldlen, (u32 *)A(tmp.oldlenp))) | 823 | put_user(oldlen, (u32 __user *)compat_ptr(tmp.oldlenp))) |
| 823 | error = -EFAULT; | 824 | error = -EFAULT; |
| 824 | } | 825 | } |
| 825 | copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)); | 826 | copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)); |
| @@ -853,7 +854,7 @@ struct stat64_emu31 { | |||
| 853 | unsigned long st_ino; | 854 | unsigned long st_ino; |
| 854 | }; | 855 | }; |
| 855 | 856 | ||
| 856 | static int cp_stat64(struct stat64_emu31 *ubuf, struct kstat *stat) | 857 | static int cp_stat64(struct stat64_emu31 __user *ubuf, struct kstat *stat) |
| 857 | { | 858 | { |
| 858 | struct stat64_emu31 tmp; | 859 | struct stat64_emu31 tmp; |
| 859 | 860 | ||
| @@ -877,7 +878,7 @@ static int cp_stat64(struct stat64_emu31 *ubuf, struct kstat *stat) | |||
| 877 | return copy_to_user(ubuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; | 878 | return copy_to_user(ubuf,&tmp,sizeof(tmp)) ? -EFAULT : 0; |
| 878 | } | 879 | } |
| 879 | 880 | ||
| 880 | asmlinkage long sys32_stat64(char * filename, struct stat64_emu31 * statbuf) | 881 | asmlinkage long sys32_stat64(char __user * filename, struct stat64_emu31 __user * statbuf) |
| 881 | { | 882 | { |
| 882 | struct kstat stat; | 883 | struct kstat stat; |
| 883 | int ret = vfs_stat(filename, &stat); | 884 | int ret = vfs_stat(filename, &stat); |
| @@ -886,7 +887,7 @@ asmlinkage long sys32_stat64(char * filename, struct stat64_emu31 * statbuf) | |||
| 886 | return ret; | 887 | return ret; |
| 887 | } | 888 | } |
| 888 | 889 | ||
| 889 | asmlinkage long sys32_lstat64(char * filename, struct stat64_emu31 * statbuf) | 890 | asmlinkage long sys32_lstat64(char __user * filename, struct stat64_emu31 __user * statbuf) |
| 890 | { | 891 | { |
| 891 | struct kstat stat; | 892 | struct kstat stat; |
| 892 | int ret = vfs_lstat(filename, &stat); | 893 | int ret = vfs_lstat(filename, &stat); |
| @@ -895,7 +896,7 @@ asmlinkage long sys32_lstat64(char * filename, struct stat64_emu31 * statbuf) | |||
| 895 | return ret; | 896 | return ret; |
| 896 | } | 897 | } |
| 897 | 898 | ||
| 898 | asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 * statbuf) | 899 | asmlinkage long sys32_fstat64(unsigned long fd, struct stat64_emu31 __user * statbuf) |
| 899 | { | 900 | { |
| 900 | struct kstat stat; | 901 | struct kstat stat; |
| 901 | int ret = vfs_fstat(fd, &stat); | 902 | int ret = vfs_fstat(fd, &stat); |
| @@ -952,7 +953,7 @@ out: | |||
| 952 | 953 | ||
| 953 | 954 | ||
| 954 | asmlinkage unsigned long | 955 | asmlinkage unsigned long |
| 955 | old32_mmap(struct mmap_arg_struct_emu31 *arg) | 956 | old32_mmap(struct mmap_arg_struct_emu31 __user *arg) |
| 956 | { | 957 | { |
| 957 | struct mmap_arg_struct_emu31 a; | 958 | struct mmap_arg_struct_emu31 a; |
| 958 | int error = -EFAULT; | 959 | int error = -EFAULT; |
| @@ -970,7 +971,7 @@ out: | |||
| 970 | } | 971 | } |
| 971 | 972 | ||
| 972 | asmlinkage long | 973 | asmlinkage long |
| 973 | sys32_mmap2(struct mmap_arg_struct_emu31 *arg) | 974 | sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg) |
| 974 | { | 975 | { |
| 975 | struct mmap_arg_struct_emu31 a; | 976 | struct mmap_arg_struct_emu31 a; |
| 976 | int error = -EFAULT; | 977 | int error = -EFAULT; |
| @@ -982,7 +983,7 @@ out: | |||
| 982 | return error; | 983 | return error; |
| 983 | } | 984 | } |
| 984 | 985 | ||
| 985 | asmlinkage long sys32_read(unsigned int fd, char * buf, size_t count) | 986 | asmlinkage long sys32_read(unsigned int fd, char __user * buf, size_t count) |
| 986 | { | 987 | { |
| 987 | if ((compat_ssize_t) count < 0) | 988 | if ((compat_ssize_t) count < 0) |
| 988 | return -EINVAL; | 989 | return -EINVAL; |
| @@ -990,7 +991,7 @@ asmlinkage long sys32_read(unsigned int fd, char * buf, size_t count) | |||
| 990 | return sys_read(fd, buf, count); | 991 | return sys_read(fd, buf, count); |
| 991 | } | 992 | } |
| 992 | 993 | ||
| 993 | asmlinkage long sys32_write(unsigned int fd, char * buf, size_t count) | 994 | asmlinkage long sys32_write(unsigned int fd, char __user * buf, size_t count) |
| 994 | { | 995 | { |
| 995 | if ((compat_ssize_t) count < 0) | 996 | if ((compat_ssize_t) count < 0) |
| 996 | return -EINVAL; | 997 | return -EINVAL; |
| @@ -1002,12 +1003,12 @@ asmlinkage long sys32_clone(struct pt_regs regs) | |||
| 1002 | { | 1003 | { |
| 1003 | unsigned long clone_flags; | 1004 | unsigned long clone_flags; |
| 1004 | unsigned long newsp; | 1005 | unsigned long newsp; |
| 1005 | int *parent_tidptr, *child_tidptr; | 1006 | int __user *parent_tidptr, *child_tidptr; |
| 1006 | 1007 | ||
| 1007 | clone_flags = regs.gprs[3] & 0xffffffffUL; | 1008 | clone_flags = regs.gprs[3] & 0xffffffffUL; |
| 1008 | newsp = regs.orig_gpr2 & 0x7fffffffUL; | 1009 | newsp = regs.orig_gpr2 & 0x7fffffffUL; |
| 1009 | parent_tidptr = (int *) (regs.gprs[4] & 0x7fffffffUL); | 1010 | parent_tidptr = compat_ptr(regs.gprs[4]); |
| 1010 | child_tidptr = (int *) (regs.gprs[5] & 0x7fffffffUL); | 1011 | child_tidptr = compat_ptr(regs.gprs[5]); |
| 1011 | if (!newsp) | 1012 | if (!newsp) |
| 1012 | newsp = regs.gprs[15]; | 1013 | newsp = regs.gprs[15]; |
| 1013 | return do_fork(clone_flags, newsp, ®s, 0, | 1014 | return do_fork(clone_flags, newsp, ®s, 0, |
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index 6e27ac68ec3f..83b33fe1923c 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S | |||
| @@ -1486,7 +1486,7 @@ sys_inotify_rm_watch_wrapper: | |||
| 1486 | 1486 | ||
| 1487 | .globl compat_sys_openat_wrapper | 1487 | .globl compat_sys_openat_wrapper |
| 1488 | compat_sys_openat_wrapper: | 1488 | compat_sys_openat_wrapper: |
| 1489 | lgfr %r2,%r2 # int | 1489 | llgfr %r2,%r2 # unsigned int |
| 1490 | llgtr %r3,%r3 # const char * | 1490 | llgtr %r3,%r3 # const char * |
| 1491 | lgfr %r4,%r4 # int | 1491 | lgfr %r4,%r4 # int |
| 1492 | lgfr %r5,%r5 # int | 1492 | lgfr %r5,%r5 # int |
| @@ -1518,14 +1518,14 @@ sys_fchownat_wrapper: | |||
| 1518 | 1518 | ||
| 1519 | .globl compat_sys_futimesat_wrapper | 1519 | .globl compat_sys_futimesat_wrapper |
| 1520 | compat_sys_futimesat_wrapper: | 1520 | compat_sys_futimesat_wrapper: |
| 1521 | lgfr %r2,%r2 # int | 1521 | llgfr %r2,%r2 # unsigned int |
| 1522 | llgtr %r3,%r3 # char * | 1522 | llgtr %r3,%r3 # char * |
| 1523 | llgtr %r4,%r4 # struct timeval * | 1523 | llgtr %r4,%r4 # struct timeval * |
| 1524 | jg compat_sys_futimesat | 1524 | jg compat_sys_futimesat |
| 1525 | 1525 | ||
| 1526 | .globl compat_sys_newfstatat_wrapper | 1526 | .globl compat_sys_newfstatat_wrapper |
| 1527 | compat_sys_newfstatat_wrapper: | 1527 | compat_sys_newfstatat_wrapper: |
| 1528 | lgfr %r2,%r2 # int | 1528 | llgfr %r2,%r2 # unsigned int |
| 1529 | llgtr %r3,%r3 # char * | 1529 | llgtr %r3,%r3 # char * |
| 1530 | llgtr %r4,%r4 # struct stat * | 1530 | llgtr %r4,%r4 # struct stat * |
| 1531 | lgfr %r5,%r5 # int | 1531 | lgfr %r5,%r5 # int |
diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c index 6a63553493c5..e351780bb660 100644 --- a/arch/s390/kernel/sys_s390.c +++ b/arch/s390/kernel/sys_s390.c | |||
| @@ -122,8 +122,8 @@ out: | |||
| 122 | #ifndef CONFIG_64BIT | 122 | #ifndef CONFIG_64BIT |
| 123 | struct sel_arg_struct { | 123 | struct sel_arg_struct { |
| 124 | unsigned long n; | 124 | unsigned long n; |
| 125 | fd_set *inp, *outp, *exp; | 125 | fd_set __user *inp, *outp, *exp; |
| 126 | struct timeval *tvp; | 126 | struct timeval __user *tvp; |
| 127 | }; | 127 | }; |
| 128 | 128 | ||
| 129 | asmlinkage long old_select(struct sel_arg_struct __user *arg) | 129 | asmlinkage long old_select(struct sel_arg_struct __user *arg) |
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 5d21e9e6e7b4..a46793beeddd 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c | |||
| @@ -486,7 +486,7 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code) | |||
| 486 | info.si_signo = signal; | 486 | info.si_signo = signal; |
| 487 | info.si_errno = 0; | 487 | info.si_errno = 0; |
| 488 | info.si_code = ILL_ILLOPC; | 488 | info.si_code = ILL_ILLOPC; |
| 489 | info.si_addr = (void *) location; | 489 | info.si_addr = (void __user *) location; |
| 490 | do_trap(interruption_code, signal, | 490 | do_trap(interruption_code, signal, |
| 491 | "illegal operation", regs, &info); | 491 | "illegal operation", regs, &info); |
| 492 | } | 492 | } |
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c index 2d5cb1385753..b075ab499d05 100644 --- a/arch/s390/mm/cmm.c +++ b/arch/s390/mm/cmm.c | |||
| @@ -42,8 +42,8 @@ static volatile long cmm_timed_pages_target = 0; | |||
| 42 | static long cmm_timeout_pages = 0; | 42 | static long cmm_timeout_pages = 0; |
| 43 | static long cmm_timeout_seconds = 0; | 43 | static long cmm_timeout_seconds = 0; |
| 44 | 44 | ||
| 45 | static struct cmm_page_array *cmm_page_list = 0; | 45 | static struct cmm_page_array *cmm_page_list = NULL; |
| 46 | static struct cmm_page_array *cmm_timed_page_list = 0; | 46 | static struct cmm_page_array *cmm_timed_page_list = NULL; |
| 47 | 47 | ||
| 48 | static unsigned long cmm_thread_active = 0; | 48 | static unsigned long cmm_thread_active = 0; |
| 49 | static struct work_struct cmm_thread_starter; | 49 | static struct work_struct cmm_thread_starter; |
| @@ -259,7 +259,7 @@ static struct ctl_table cmm_table[]; | |||
| 259 | 259 | ||
| 260 | static int | 260 | static int |
| 261 | cmm_pages_handler(ctl_table *ctl, int write, struct file *filp, | 261 | cmm_pages_handler(ctl_table *ctl, int write, struct file *filp, |
| 262 | void *buffer, size_t *lenp, loff_t *ppos) | 262 | void __user *buffer, size_t *lenp, loff_t *ppos) |
| 263 | { | 263 | { |
| 264 | char buf[16], *p; | 264 | char buf[16], *p; |
| 265 | long pages; | 265 | long pages; |
| @@ -300,7 +300,7 @@ cmm_pages_handler(ctl_table *ctl, int write, struct file *filp, | |||
| 300 | 300 | ||
| 301 | static int | 301 | static int |
| 302 | cmm_timeout_handler(ctl_table *ctl, int write, struct file *filp, | 302 | cmm_timeout_handler(ctl_table *ctl, int write, struct file *filp, |
| 303 | void *buffer, size_t *lenp, loff_t *ppos) | 303 | void __user *buffer, size_t *lenp, loff_t *ppos) |
| 304 | { | 304 | { |
| 305 | char buf[64], *p; | 305 | char buf[64], *p; |
| 306 | long pages, seconds; | 306 | long pages, seconds; |
| @@ -419,7 +419,7 @@ cmm_init (void) | |||
| 419 | #ifdef CONFIG_CMM_IUCV | 419 | #ifdef CONFIG_CMM_IUCV |
| 420 | smsg_register_callback(SMSG_PREFIX, cmm_smsg_target); | 420 | smsg_register_callback(SMSG_PREFIX, cmm_smsg_target); |
| 421 | #endif | 421 | #endif |
| 422 | INIT_WORK(&cmm_thread_starter, (void *) cmm_start_thread, 0); | 422 | INIT_WORK(&cmm_thread_starter, (void *) cmm_start_thread, NULL); |
| 423 | init_waitqueue_head(&cmm_thread_wait); | 423 | init_waitqueue_head(&cmm_thread_wait); |
| 424 | init_timer(&cmm_timer); | 424 | init_timer(&cmm_timer); |
| 425 | return 0; | 425 | return 0; |
diff --git a/arch/sh/boards/renesas/rts7751r2d/io.c b/arch/sh/boards/renesas/rts7751r2d/io.c index c46f9154cfd5..123abbbc91e0 100644 --- a/arch/sh/boards/renesas/rts7751r2d/io.c +++ b/arch/sh/boards/renesas/rts7751r2d/io.c | |||
| @@ -216,24 +216,26 @@ void rts7751r2d_insb(unsigned long port, void *addr, unsigned long count) | |||
| 216 | { | 216 | { |
| 217 | volatile __u8 *bp; | 217 | volatile __u8 *bp; |
| 218 | volatile __u16 *p; | 218 | volatile __u16 *p; |
| 219 | unsigned char *s = addr; | ||
| 219 | 220 | ||
| 220 | if (CHECK_AX88796L_PORT(port)) { | 221 | if (CHECK_AX88796L_PORT(port)) { |
| 221 | p = (volatile unsigned short *)port88796l(port, 0); | 222 | p = (volatile unsigned short *)port88796l(port, 0); |
| 222 | while (count--) *((unsigned char *) addr)++ = *p & 0xff; | 223 | while (count--) *s++ = *p & 0xff; |
| 223 | } else if (PXSEG(port)) | 224 | } else if (PXSEG(port)) |
| 224 | while (count--) *((unsigned char *) addr)++ = *(volatile unsigned char *)port; | 225 | while (count--) *s++ = *(volatile unsigned char *)port; |
| 225 | else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { | 226 | else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { |
| 226 | bp = (__u8 *)PCI_IOMAP(port); | 227 | bp = (__u8 *)PCI_IOMAP(port); |
| 227 | while (count--) *((volatile unsigned char *) addr)++ = *bp; | 228 | while (count--) *s++ = *bp; |
| 228 | } else { | 229 | } else { |
| 229 | p = (volatile unsigned short *)port2adr(port); | 230 | p = (volatile unsigned short *)port2adr(port); |
| 230 | while (count--) *((unsigned char *) addr)++ = *p & 0xff; | 231 | while (count--) *s++ = *p & 0xff; |
| 231 | } | 232 | } |
| 232 | } | 233 | } |
| 233 | 234 | ||
| 234 | void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count) | 235 | void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count) |
| 235 | { | 236 | { |
| 236 | volatile __u16 *p; | 237 | volatile __u16 *p; |
| 238 | __u16 *s = addr; | ||
| 237 | 239 | ||
| 238 | if (CHECK_AX88796L_PORT(port)) | 240 | if (CHECK_AX88796L_PORT(port)) |
| 239 | p = (volatile unsigned short *)port88796l(port, 1); | 241 | p = (volatile unsigned short *)port88796l(port, 1); |
| @@ -243,7 +245,7 @@ void rts7751r2d_insw(unsigned long port, void *addr, unsigned long count) | |||
| 243 | p = (volatile unsigned short *)PCI_IOMAP(port); | 245 | p = (volatile unsigned short *)PCI_IOMAP(port); |
| 244 | else | 246 | else |
| 245 | p = (volatile unsigned short *)port2adr(port); | 247 | p = (volatile unsigned short *)port2adr(port); |
| 246 | while (count--) *((__u16 *) addr)++ = *p; | 248 | while (count--) *s++ = *p; |
| 247 | } | 249 | } |
| 248 | 250 | ||
| 249 | void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count) | 251 | void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count) |
| @@ -252,8 +254,9 @@ void rts7751r2d_insl(unsigned long port, void *addr, unsigned long count) | |||
| 252 | maybebadio(insl, port); | 254 | maybebadio(insl, port); |
| 253 | else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { | 255 | else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { |
| 254 | volatile __u32 *p = (__u32 *)PCI_IOMAP(port); | 256 | volatile __u32 *p = (__u32 *)PCI_IOMAP(port); |
| 257 | __u32 *s = addr; | ||
| 255 | 258 | ||
| 256 | while (count--) *((__u32 *) addr)++ = *p; | 259 | while (count--) *s++ = *p; |
| 257 | } else | 260 | } else |
| 258 | maybebadio(insl, port); | 261 | maybebadio(insl, port); |
| 259 | } | 262 | } |
| @@ -262,24 +265,26 @@ void rts7751r2d_outsb(unsigned long port, const void *addr, unsigned long count) | |||
| 262 | { | 265 | { |
| 263 | volatile __u8 *bp; | 266 | volatile __u8 *bp; |
| 264 | volatile __u16 *p; | 267 | volatile __u16 *p; |
| 268 | const __u8 *s = addr; | ||
| 265 | 269 | ||
| 266 | if (CHECK_AX88796L_PORT(port)) { | 270 | if (CHECK_AX88796L_PORT(port)) { |
| 267 | p = (volatile unsigned short *)port88796l(port, 0); | 271 | p = (volatile unsigned short *)port88796l(port, 0); |
| 268 | while (count--) *p = *((unsigned char *) addr)++; | 272 | while (count--) *p = *s++; |
| 269 | } else if (PXSEG(port)) | 273 | } else if (PXSEG(port)) |
| 270 | while (count--) *(volatile unsigned char *)port = *((unsigned char *) addr)++; | 274 | while (count--) *(volatile unsigned char *)port = *s++; |
| 271 | else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { | 275 | else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { |
| 272 | bp = (__u8 *)PCI_IOMAP(port); | 276 | bp = (__u8 *)PCI_IOMAP(port); |
| 273 | while (count--) *bp = *((volatile unsigned char *) addr)++; | 277 | while (count--) *bp = *s++; |
| 274 | } else { | 278 | } else { |
| 275 | p = (volatile unsigned short *)port2adr(port); | 279 | p = (volatile unsigned short *)port2adr(port); |
| 276 | while (count--) *p = *((unsigned char *) addr)++; | 280 | while (count--) *p = *s++; |
| 277 | } | 281 | } |
| 278 | } | 282 | } |
| 279 | 283 | ||
| 280 | void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count) | 284 | void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count) |
| 281 | { | 285 | { |
| 282 | volatile __u16 *p; | 286 | volatile __u16 *p; |
| 287 | const __u16 *s = addr; | ||
| 283 | 288 | ||
| 284 | if (CHECK_AX88796L_PORT(port)) | 289 | if (CHECK_AX88796L_PORT(port)) |
| 285 | p = (volatile unsigned short *)port88796l(port, 1); | 290 | p = (volatile unsigned short *)port88796l(port, 1); |
| @@ -289,7 +294,7 @@ void rts7751r2d_outsw(unsigned long port, const void *addr, unsigned long count) | |||
| 289 | p = (volatile unsigned short *)PCI_IOMAP(port); | 294 | p = (volatile unsigned short *)PCI_IOMAP(port); |
| 290 | else | 295 | else |
| 291 | p = (volatile unsigned short *)port2adr(port); | 296 | p = (volatile unsigned short *)port2adr(port); |
| 292 | while (count--) *p = *((__u16 *) addr)++; | 297 | while (count--) *p = *s++; |
| 293 | } | 298 | } |
| 294 | 299 | ||
| 295 | void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count) | 300 | void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count) |
| @@ -298,8 +303,9 @@ void rts7751r2d_outsl(unsigned long port, const void *addr, unsigned long count) | |||
| 298 | maybebadio(outsl, port); | 303 | maybebadio(outsl, port); |
| 299 | else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { | 304 | else if (CHECK_SH7751_PCIIO(port) || shifted_port(port)) { |
| 300 | volatile __u32 *p = (__u32 *)PCI_IOMAP(port); | 305 | volatile __u32 *p = (__u32 *)PCI_IOMAP(port); |
| 306 | const __u32 *s = addr; | ||
| 301 | 307 | ||
| 302 | while (count--) *p = *((__u32 *) addr)++; | 308 | while (count--) *p = *s++; |
| 303 | } else | 309 | } else |
| 304 | maybebadio(outsl, port); | 310 | maybebadio(outsl, port); |
| 305 | } | 311 | } |
diff --git a/arch/sh64/kernel/sh_ksyms.c b/arch/sh64/kernel/sh_ksyms.c index 472b450e61be..de29c45f23a7 100644 --- a/arch/sh64/kernel/sh_ksyms.c +++ b/arch/sh64/kernel/sh_ksyms.c | |||
| @@ -31,14 +31,6 @@ | |||
| 31 | 31 | ||
| 32 | extern int dump_fpu(struct pt_regs *, elf_fpregset_t *); | 32 | extern int dump_fpu(struct pt_regs *, elf_fpregset_t *); |
| 33 | 33 | ||
| 34 | #if 0 | ||
| 35 | /* Not yet - there's no declaration of drive_info anywhere. */ | ||
| 36 | #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE) | ||
| 37 | extern struct drive_info_struct drive_info; | ||
| 38 | EXPORT_SYMBOL(drive_info); | ||
| 39 | #endif | ||
| 40 | #endif | ||
| 41 | |||
| 42 | /* platform dependent support */ | 34 | /* platform dependent support */ |
| 43 | EXPORT_SYMBOL(dump_fpu); | 35 | EXPORT_SYMBOL(dump_fpu); |
| 44 | EXPORT_SYMBOL(iounmap); | 36 | EXPORT_SYMBOL(iounmap); |
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index 267ec8f6fb58..887f6a160c58 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S | |||
| @@ -38,7 +38,7 @@ | |||
| 38 | 38 | ||
| 39 | #define curptr g6 | 39 | #define curptr g6 |
| 40 | 40 | ||
| 41 | #define NR_SYSCALLS 299 /* Each OS is different... */ | 41 | #define NR_SYSCALLS 300 /* Each OS is different... */ |
| 42 | 42 | ||
| 43 | /* These are just handy. */ | 43 | /* These are just handy. */ |
| 44 | #define _SV save %sp, -STACKFRAME_SZ, %sp | 44 | #define _SV save %sp, -STACKFRAME_SZ, %sp |
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index fbb05a452e51..118cac84a0f5 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c | |||
| @@ -54,7 +54,7 @@ void (*pm_idle)(void); | |||
| 54 | * This is done via auxio, but could be used as a fallback | 54 | * This is done via auxio, but could be used as a fallback |
| 55 | * handler when auxio is not present-- unused for now... | 55 | * handler when auxio is not present-- unused for now... |
| 56 | */ | 56 | */ |
| 57 | void (*pm_power_off)(void); | 57 | void (*pm_power_off)(void) = machine_power_off; |
| 58 | 58 | ||
| 59 | /* | 59 | /* |
| 60 | * sysctl - toggle power-off restriction for serial console | 60 | * sysctl - toggle power-off restriction for serial console |
diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index 6877ae4cd1d9..c0314705d73a 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S | |||
| @@ -78,7 +78,7 @@ sys_call_table: | |||
| 78 | /*280*/ .long sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat | 78 | /*280*/ .long sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat |
| 79 | /*285*/ .long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_newfstatat | 79 | /*285*/ .long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_newfstatat |
| 80 | /*290*/ .long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat | 80 | /*290*/ .long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat |
| 81 | /*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll | 81 | /*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare |
| 82 | 82 | ||
| 83 | #ifdef CONFIG_SUNOS_EMUL | 83 | #ifdef CONFIG_SUNOS_EMUL |
| 84 | /* Now the SunOS syscall table. */ | 84 | /* Now the SunOS syscall table. */ |
| @@ -190,5 +190,6 @@ sunos_sys_table: | |||
| 190 | /*290*/ .long sunos_nosys, sunos_nosys, sunos_nosys | 190 | /*290*/ .long sunos_nosys, sunos_nosys, sunos_nosys |
| 191 | .long sunos_nosys, sunos_nosys, sunos_nosys | 191 | .long sunos_nosys, sunos_nosys, sunos_nosys |
| 192 | .long sunos_nosys, sunos_nosys, sunos_nosys | 192 | .long sunos_nosys, sunos_nosys, sunos_nosys |
| 193 | .long sunos_nosys | ||
| 193 | 194 | ||
| 194 | #endif | 195 | #endif |
diff --git a/arch/sparc64/boot/.gitignore b/arch/sparc64/boot/.gitignore new file mode 100644 index 000000000000..36356f9d498e --- /dev/null +++ b/arch/sparc64/boot/.gitignore | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | image | ||
| 2 | tftpboot.img | ||
| 3 | vmlinux.aout | ||
| 4 | piggyback | ||
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 9ceddad0fb49..069d49777b2a 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | # | 1 | # |
| 2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
| 3 | # Linux kernel version: 2.6.16-rc1 | 3 | # Linux kernel version: 2.6.16-rc2 |
| 4 | # Wed Jan 18 13:41:02 2006 | 4 | # Tue Feb 7 17:47:18 2006 |
| 5 | # | 5 | # |
| 6 | CONFIG_SPARC=y | 6 | CONFIG_SPARC=y |
| 7 | CONFIG_SPARC64=y | 7 | CONFIG_SPARC64=y |
| @@ -23,7 +23,6 @@ CONFIG_HZ=250 | |||
| 23 | # Code maturity level options | 23 | # Code maturity level options |
| 24 | # | 24 | # |
| 25 | CONFIG_EXPERIMENTAL=y | 25 | CONFIG_EXPERIMENTAL=y |
| 26 | CONFIG_CLEAN_COMPILE=y | ||
| 27 | CONFIG_BROKEN_ON_SMP=y | 26 | CONFIG_BROKEN_ON_SMP=y |
| 28 | CONFIG_INIT_ENV_ARG_LIMIT=32 | 27 | CONFIG_INIT_ENV_ARG_LIMIT=32 |
| 29 | 28 | ||
| @@ -31,7 +30,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32 | |||
| 31 | # General setup | 30 | # General setup |
| 32 | # | 31 | # |
| 33 | CONFIG_LOCALVERSION="" | 32 | CONFIG_LOCALVERSION="" |
| 34 | CONFIG_LOCALVERSION_AUTO=y | 33 | # CONFIG_LOCALVERSION_AUTO is not set |
| 35 | CONFIG_SWAP=y | 34 | CONFIG_SWAP=y |
| 36 | CONFIG_SYSVIPC=y | 35 | CONFIG_SYSVIPC=y |
| 37 | CONFIG_POSIX_MQUEUE=y | 36 | CONFIG_POSIX_MQUEUE=y |
| @@ -155,6 +154,7 @@ CONFIG_NET=y | |||
| 155 | # | 154 | # |
| 156 | # Networking options | 155 | # Networking options |
| 157 | # | 156 | # |
| 157 | # CONFIG_NETDEBUG is not set | ||
| 158 | CONFIG_PACKET=y | 158 | CONFIG_PACKET=y |
| 159 | CONFIG_PACKET_MMAP=y | 159 | CONFIG_PACKET_MMAP=y |
| 160 | CONFIG_UNIX=y | 160 | CONFIG_UNIX=y |
| @@ -224,6 +224,11 @@ CONFIG_IP_DCCP_TFRC_LIB=m | |||
| 224 | # SCTP Configuration (EXPERIMENTAL) | 224 | # SCTP Configuration (EXPERIMENTAL) |
| 225 | # | 225 | # |
| 226 | # CONFIG_IP_SCTP is not set | 226 | # CONFIG_IP_SCTP is not set |
| 227 | |||
| 228 | # | ||
| 229 | # TIPC Configuration (EXPERIMENTAL) | ||
| 230 | # | ||
| 231 | # CONFIG_TIPC is not set | ||
| 227 | # CONFIG_ATM is not set | 232 | # CONFIG_ATM is not set |
| 228 | # CONFIG_BRIDGE is not set | 233 | # CONFIG_BRIDGE is not set |
| 229 | CONFIG_VLAN_8021Q=m | 234 | CONFIG_VLAN_8021Q=m |
| @@ -233,11 +238,6 @@ CONFIG_VLAN_8021Q=m | |||
| 233 | # CONFIG_ATALK is not set | 238 | # CONFIG_ATALK is not set |
| 234 | # CONFIG_X25 is not set | 239 | # CONFIG_X25 is not set |
| 235 | # CONFIG_LAPB is not set | 240 | # CONFIG_LAPB is not set |
| 236 | |||
| 237 | # | ||
| 238 | # TIPC Configuration (EXPERIMENTAL) | ||
| 239 | # | ||
| 240 | # CONFIG_TIPC is not set | ||
| 241 | # CONFIG_NET_DIVERT is not set | 241 | # CONFIG_NET_DIVERT is not set |
| 242 | # CONFIG_ECONET is not set | 242 | # CONFIG_ECONET is not set |
| 243 | # CONFIG_WAN_ROUTER is not set | 243 | # CONFIG_WAN_ROUTER is not set |
| @@ -657,6 +657,7 @@ CONFIG_SERIAL_SUNSU_CONSOLE=y | |||
| 657 | CONFIG_SERIAL_SUNSAB=m | 657 | CONFIG_SERIAL_SUNSAB=m |
| 658 | CONFIG_SERIAL_CORE=y | 658 | CONFIG_SERIAL_CORE=y |
| 659 | CONFIG_SERIAL_CORE_CONSOLE=y | 659 | CONFIG_SERIAL_CORE_CONSOLE=y |
| 660 | # CONFIG_SERIAL_JSM is not set | ||
| 660 | CONFIG_UNIX98_PTYS=y | 661 | CONFIG_UNIX98_PTYS=y |
| 661 | # CONFIG_LEGACY_PTYS is not set | 662 | # CONFIG_LEGACY_PTYS is not set |
| 662 | 663 | ||
| @@ -765,6 +766,7 @@ CONFIG_HWMON=y | |||
| 765 | # CONFIG_SENSORS_ASB100 is not set | 766 | # CONFIG_SENSORS_ASB100 is not set |
| 766 | # CONFIG_SENSORS_ATXP1 is not set | 767 | # CONFIG_SENSORS_ATXP1 is not set |
| 767 | # CONFIG_SENSORS_DS1621 is not set | 768 | # CONFIG_SENSORS_DS1621 is not set |
| 769 | # CONFIG_SENSORS_F71805F is not set | ||
| 768 | # CONFIG_SENSORS_FSCHER is not set | 770 | # CONFIG_SENSORS_FSCHER is not set |
| 769 | # CONFIG_SENSORS_FSCPOS is not set | 771 | # CONFIG_SENSORS_FSCPOS is not set |
| 770 | # CONFIG_SENSORS_GL518SM is not set | 772 | # CONFIG_SENSORS_GL518SM is not set |
| @@ -1118,6 +1120,10 @@ CONFIG_USB_HIDDEV=y | |||
| 1118 | # | 1120 | # |
| 1119 | 1121 | ||
| 1120 | # | 1122 | # |
| 1123 | # EDAC - error detection and reporting (RAS) | ||
| 1124 | # | ||
| 1125 | |||
| 1126 | # | ||
| 1121 | # Misc Linux/SPARC drivers | 1127 | # Misc Linux/SPARC drivers |
| 1122 | # | 1128 | # |
| 1123 | CONFIG_SUN_OPENPROMIO=m | 1129 | CONFIG_SUN_OPENPROMIO=m |
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index 12911e7463f2..a73553ae7e53 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S | |||
| @@ -25,7 +25,7 @@ | |||
| 25 | 25 | ||
| 26 | #define curptr g6 | 26 | #define curptr g6 |
| 27 | 27 | ||
| 28 | #define NR_SYSCALLS 299 /* Each OS is different... */ | 28 | #define NR_SYSCALLS 300 /* Each OS is different... */ |
| 29 | 29 | ||
| 30 | .text | 30 | .text |
| 31 | .align 32 | 31 | .align 32 |
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index 2881faf36635..5928b3c33e27 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S | |||
| @@ -79,7 +79,7 @@ sys_call_table32: | |||
| 79 | /*280*/ .word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat | 79 | /*280*/ .word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl, compat_sys_openat |
| 80 | .word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_newfstatat | 80 | .word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_newfstatat |
| 81 | /*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat | 81 | /*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat |
| 82 | .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll | 82 | .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare |
| 83 | 83 | ||
| 84 | #endif /* CONFIG_COMPAT */ | 84 | #endif /* CONFIG_COMPAT */ |
| 85 | 85 | ||
| @@ -148,7 +148,7 @@ sys_call_table: | |||
| 148 | /*280*/ .word sys_nis_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat | 148 | /*280*/ .word sys_nis_syscall, sys_add_key, sys_request_key, sys_keyctl, sys_openat |
| 149 | .word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, compat_sys_newfstatat | 149 | .word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, compat_sys_newfstatat |
| 150 | /*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat | 150 | /*285*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat |
| 151 | .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll | 151 | .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare |
| 152 | 152 | ||
| 153 | #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ | 153 | #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ |
| 154 | defined(CONFIG_SOLARIS_EMUL_MODULE) | 154 | defined(CONFIG_SOLARIS_EMUL_MODULE) |
| @@ -261,4 +261,5 @@ sunos_sys_table: | |||
| 261 | /*290*/ .word sunos_nosys, sunos_nosys, sunos_nosys | 261 | /*290*/ .word sunos_nosys, sunos_nosys, sunos_nosys |
| 262 | .word sunos_nosys, sunos_nosys, sunos_nosys | 262 | .word sunos_nosys, sunos_nosys, sunos_nosys |
| 263 | .word sunos_nosys, sunos_nosys, sunos_nosys | 263 | .word sunos_nosys, sunos_nosys, sunos_nosys |
| 264 | .word sunos_nosys | ||
| 264 | #endif | 265 | #endif |
diff --git a/arch/sparc64/solaris/systbl.S b/arch/sparc64/solaris/systbl.S index d25667eeae10..7043ca18caf9 100644 --- a/arch/sparc64/solaris/systbl.S +++ b/arch/sparc64/solaris/systbl.S | |||
| @@ -283,32 +283,3 @@ solaris_sys_table: | |||
| 283 | .word solaris_unimplemented /* 253 */ | 283 | .word solaris_unimplemented /* 253 */ |
| 284 | .word solaris_unimplemented /* 254 */ | 284 | .word solaris_unimplemented /* 254 */ |
| 285 | .word solaris_unimplemented /* 255 */ | 285 | .word solaris_unimplemented /* 255 */ |
| 286 | .word solaris_unimplemented /* 256 */ | ||
| 287 | .word solaris_unimplemented /* 257 */ | ||
| 288 | .word solaris_unimplemented /* 258 */ | ||
| 289 | .word solaris_unimplemented /* 259 */ | ||
| 290 | .word solaris_unimplemented /* 260 */ | ||
| 291 | .word solaris_unimplemented /* 261 */ | ||
| 292 | .word solaris_unimplemented /* 262 */ | ||
| 293 | .word solaris_unimplemented /* 263 */ | ||
| 294 | .word solaris_unimplemented /* 264 */ | ||
| 295 | .word solaris_unimplemented /* 265 */ | ||
| 296 | .word solaris_unimplemented /* 266 */ | ||
| 297 | .word solaris_unimplemented /* 267 */ | ||
| 298 | .word solaris_unimplemented /* 268 */ | ||
| 299 | .word solaris_unimplemented /* 269 */ | ||
| 300 | .word solaris_unimplemented /* 270 */ | ||
| 301 | .word solaris_unimplemented /* 271 */ | ||
| 302 | .word solaris_unimplemented /* 272 */ | ||
| 303 | .word solaris_unimplemented /* 273 */ | ||
| 304 | .word solaris_unimplemented /* 274 */ | ||
| 305 | .word solaris_unimplemented /* 275 */ | ||
| 306 | .word solaris_unimplemented /* 276 */ | ||
| 307 | .word solaris_unimplemented /* 277 */ | ||
| 308 | .word solaris_unimplemented /* 278 */ | ||
| 309 | .word solaris_unimplemented /* 279 */ | ||
| 310 | .word solaris_unimplemented /* 280 */ | ||
| 311 | .word solaris_unimplemented /* 281 */ | ||
| 312 | .word solaris_unimplemented /* 282 */ | ||
| 313 | .word solaris_unimplemented /* 283 */ | ||
| 314 | |||
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 5d50d4a44abf..2f880cb167a5 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include <termios.h> | 9 | #include <termios.h> |
| 10 | #include <string.h> | 10 | #include <string.h> |
| 11 | #include <signal.h> | 11 | #include <signal.h> |
| 12 | #include <sched.h> | ||
| 12 | #include <sys/stat.h> | 13 | #include <sys/stat.h> |
| 13 | #include <sys/ioctl.h> | 14 | #include <sys/ioctl.h> |
| 14 | #include <sys/socket.h> | 15 | #include <sys/socket.h> |
| @@ -73,7 +74,6 @@ static void winch_handler(int sig) | |||
| 73 | struct winch_data { | 74 | struct winch_data { |
| 74 | int pty_fd; | 75 | int pty_fd; |
| 75 | int pipe_fd; | 76 | int pipe_fd; |
| 76 | int close_me; | ||
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | static int winch_thread(void *arg) | 79 | static int winch_thread(void *arg) |
| @@ -84,7 +84,6 @@ static int winch_thread(void *arg) | |||
| 84 | int count, err; | 84 | int count, err; |
| 85 | char c = 1; | 85 | char c = 1; |
| 86 | 86 | ||
| 87 | os_close_file(data->close_me); | ||
| 88 | pty_fd = data->pty_fd; | 87 | pty_fd = data->pty_fd; |
| 89 | pipe_fd = data->pipe_fd; | 88 | pipe_fd = data->pipe_fd; |
| 90 | count = os_write_file(pipe_fd, &c, sizeof(c)); | 89 | count = os_write_file(pipe_fd, &c, sizeof(c)); |
| @@ -153,15 +152,16 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) | |||
| 153 | } | 152 | } |
| 154 | 153 | ||
| 155 | data = ((struct winch_data) { .pty_fd = fd, | 154 | data = ((struct winch_data) { .pty_fd = fd, |
| 156 | .pipe_fd = fds[1], | 155 | .pipe_fd = fds[1] } ); |
| 157 | .close_me = fds[0] } ); | 156 | /* CLONE_FILES so this thread doesn't hold open files which are open |
| 158 | err = run_helper_thread(winch_thread, &data, 0, &stack, 0); | 157 | * now, but later closed. This is a problem with /dev/net/tun. |
| 158 | */ | ||
| 159 | err = run_helper_thread(winch_thread, &data, CLONE_FILES, &stack, 0); | ||
| 159 | if(err < 0){ | 160 | if(err < 0){ |
| 160 | printk("fork of winch_thread failed - errno = %d\n", errno); | 161 | printk("fork of winch_thread failed - errno = %d\n", errno); |
| 161 | goto out_close; | 162 | goto out_close; |
| 162 | } | 163 | } |
| 163 | 164 | ||
| 164 | os_close_file(fds[1]); | ||
| 165 | *fd_out = fds[0]; | 165 | *fd_out = fds[0]; |
| 166 | n = os_read_file(fds[0], &c, sizeof(c)); | 166 | n = os_read_file(fds[0], &c, sizeof(c)); |
| 167 | if(n != sizeof(c)){ | 167 | if(n != sizeof(c)){ |
| @@ -169,13 +169,12 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out) | |||
| 169 | printk("read failed, err = %d\n", -n); | 169 | printk("read failed, err = %d\n", -n); |
| 170 | printk("fd %d will not support SIGWINCH\n", fd); | 170 | printk("fd %d will not support SIGWINCH\n", fd); |
| 171 | err = -EINVAL; | 171 | err = -EINVAL; |
| 172 | goto out_close1; | 172 | goto out_close; |
| 173 | } | 173 | } |
| 174 | return err ; | 174 | return err ; |
| 175 | 175 | ||
| 176 | out_close: | 176 | out_close: |
| 177 | os_close_file(fds[1]); | 177 | os_close_file(fds[1]); |
| 178 | out_close1: | ||
| 179 | os_close_file(fds[0]); | 178 | os_close_file(fds[0]); |
| 180 | out: | 179 | out: |
| 181 | return err; | 180 | return err; |
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 8ebb2241ad42..8c7279bb353b 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c | |||
| @@ -131,9 +131,8 @@ static int uml_net_open(struct net_device *dev) | |||
| 131 | SA_INTERRUPT | SA_SHIRQ, dev->name, dev); | 131 | SA_INTERRUPT | SA_SHIRQ, dev->name, dev); |
| 132 | if(err != 0){ | 132 | if(err != 0){ |
| 133 | printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err); | 133 | printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err); |
| 134 | if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user); | ||
| 135 | lp->fd = -1; | ||
| 136 | err = -ENETUNREACH; | 134 | err = -ENETUNREACH; |
| 135 | goto out_close; | ||
| 137 | } | 136 | } |
| 138 | 137 | ||
| 139 | lp->tl.data = (unsigned long) &lp->user; | 138 | lp->tl.data = (unsigned long) &lp->user; |
| @@ -145,9 +144,19 @@ static int uml_net_open(struct net_device *dev) | |||
| 145 | */ | 144 | */ |
| 146 | while((err = uml_net_rx(dev)) > 0) ; | 145 | while((err = uml_net_rx(dev)) > 0) ; |
| 147 | 146 | ||
| 148 | out: | ||
| 149 | spin_unlock(&lp->lock); | 147 | spin_unlock(&lp->lock); |
| 150 | return(err); | 148 | |
| 149 | spin_lock(&opened_lock); | ||
| 150 | list_add(&lp->list, &opened); | ||
| 151 | spin_unlock(&opened_lock); | ||
| 152 | |||
| 153 | return 0; | ||
| 154 | out_close: | ||
| 155 | if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user); | ||
| 156 | lp->fd = -1; | ||
| 157 | out: | ||
| 158 | spin_unlock(&lp->lock); | ||
| 159 | return err; | ||
| 151 | } | 160 | } |
| 152 | 161 | ||
| 153 | static int uml_net_close(struct net_device *dev) | 162 | static int uml_net_close(struct net_device *dev) |
| @@ -161,9 +170,13 @@ static int uml_net_close(struct net_device *dev) | |||
| 161 | if(lp->close != NULL) | 170 | if(lp->close != NULL) |
| 162 | (*lp->close)(lp->fd, &lp->user); | 171 | (*lp->close)(lp->fd, &lp->user); |
| 163 | lp->fd = -1; | 172 | lp->fd = -1; |
| 164 | list_del(&lp->list); | ||
| 165 | 173 | ||
| 166 | spin_unlock(&lp->lock); | 174 | spin_unlock(&lp->lock); |
| 175 | |||
| 176 | spin_lock(&opened_lock); | ||
| 177 | list_del(&lp->list); | ||
| 178 | spin_unlock(&opened_lock); | ||
| 179 | |||
| 167 | return 0; | 180 | return 0; |
| 168 | } | 181 | } |
| 169 | 182 | ||
| @@ -410,11 +423,7 @@ static int eth_configure(int n, void *init, char *mac, | |||
| 410 | if (device->have_mac) | 423 | if (device->have_mac) |
| 411 | set_ether_mac(dev, device->mac); | 424 | set_ether_mac(dev, device->mac); |
| 412 | 425 | ||
| 413 | spin_lock(&opened_lock); | 426 | return 0; |
| 414 | list_add(&lp->list, &opened); | ||
| 415 | spin_unlock(&opened_lock); | ||
| 416 | |||
| 417 | return(0); | ||
| 418 | } | 427 | } |
| 419 | 428 | ||
| 420 | static struct uml_net *find_device(int n) | 429 | static struct uml_net *find_device(int n) |
diff --git a/arch/um/include/registers.h b/arch/um/include/registers.h index 4892e5fcef07..83b688ca198f 100644 --- a/arch/um/include/registers.h +++ b/arch/um/include/registers.h | |||
| @@ -14,7 +14,7 @@ extern int restore_fp_registers(int pid, unsigned long *fp_regs); | |||
| 14 | extern void save_registers(int pid, union uml_pt_regs *regs); | 14 | extern void save_registers(int pid, union uml_pt_regs *regs); |
| 15 | extern void restore_registers(int pid, union uml_pt_regs *regs); | 15 | extern void restore_registers(int pid, union uml_pt_regs *regs); |
| 16 | extern void init_registers(int pid); | 16 | extern void init_registers(int pid); |
| 17 | extern void get_safe_registers(unsigned long * regs); | 17 | extern void get_safe_registers(unsigned long * regs, unsigned long * fp_regs); |
| 18 | extern void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer); | 18 | extern void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer); |
| 19 | 19 | ||
| 20 | #endif | 20 | #endif |
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c deleted file mode 100644 index eea1c9c4bb0f..000000000000 --- a/arch/um/kernel/skas/process.c +++ /dev/null | |||
| @@ -1,569 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2002- 2004 Jeff Dike (jdike@addtoit.com) | ||
| 3 | * Licensed under the GPL | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <stdlib.h> | ||
| 7 | #include <string.h> | ||
| 8 | #include <unistd.h> | ||
| 9 | #include <errno.h> | ||
| 10 | #include <signal.h> | ||
| 11 | #include <setjmp.h> | ||
| 12 | #include <sched.h> | ||
| 13 | #include <sys/wait.h> | ||
| 14 | #include <sys/mman.h> | ||
| 15 | #include <sys/user.h> | ||
| 16 | #include <sys/time.h> | ||
| 17 | #include <asm/unistd.h> | ||
| 18 | #include <asm/types.h> | ||
| 19 | #include "user.h" | ||
| 20 | #include "ptrace_user.h" | ||
| 21 | #include "sysdep/ptrace.h" | ||
| 22 | #include "user_util.h" | ||
| 23 | #include "kern_util.h" | ||
| 24 | #include "skas.h" | ||
| 25 | #include "stub-data.h" | ||
| 26 | #include "mm_id.h" | ||
| 27 | #include "sysdep/sigcontext.h" | ||
| 28 | #include "sysdep/stub.h" | ||
| 29 | #include "os.h" | ||
| 30 | #include "proc_mm.h" | ||
| 31 | #include "skas_ptrace.h" | ||
| 32 | #include "chan_user.h" | ||
| 33 | #include "registers.h" | ||
| 34 | #include "mem.h" | ||
| 35 | #include "uml-config.h" | ||
| 36 | #include "process.h" | ||
| 37 | |||
| 38 | int is_skas_winch(int pid, int fd, void *data) | ||
| 39 | { | ||
| 40 | if(pid != os_getpgrp()) | ||
| 41 | return(0); | ||
| 42 | |||
| 43 | register_winch_irq(-1, fd, -1, data); | ||
| 44 | return(1); | ||
| 45 | } | ||
| 46 | |||
| 47 | void wait_stub_done(int pid, int sig, char * fname) | ||
| 48 | { | ||
| 49 | int n, status, err; | ||
| 50 | |||
| 51 | do { | ||
| 52 | if ( sig != -1 ) { | ||
| 53 | err = ptrace(PTRACE_CONT, pid, 0, sig); | ||
| 54 | if(err) | ||
| 55 | panic("%s : continue failed, errno = %d\n", | ||
| 56 | fname, errno); | ||
| 57 | } | ||
| 58 | sig = 0; | ||
| 59 | |||
| 60 | CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); | ||
| 61 | } while((n >= 0) && WIFSTOPPED(status) && | ||
| 62 | ((WSTOPSIG(status) == SIGVTALRM) || | ||
| 63 | /* running UML inside a detached screen can cause | ||
| 64 | * SIGWINCHes | ||
| 65 | */ | ||
| 66 | (WSTOPSIG(status) == SIGWINCH))); | ||
| 67 | |||
| 68 | if((n < 0) || !WIFSTOPPED(status) || | ||
| 69 | (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){ | ||
| 70 | unsigned long regs[HOST_FRAME_SIZE]; | ||
| 71 | if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) | ||
| 72 | printk("Failed to get registers from stub, " | ||
| 73 | "errno = %d\n", errno); | ||
| 74 | else { | ||
| 75 | int i; | ||
| 76 | |||
| 77 | printk("Stub registers -\n"); | ||
| 78 | for(i = 0; i < HOST_FRAME_SIZE; i++) | ||
| 79 | printk("\t%d - %lx\n", i, regs[i]); | ||
| 80 | } | ||
| 81 | panic("%s : failed to wait for SIGUSR1/SIGTRAP, " | ||
| 82 | "pid = %d, n = %d, errno = %d, status = 0x%x\n", | ||
| 83 | fname, pid, n, errno, status); | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | void get_skas_faultinfo(int pid, struct faultinfo * fi) | ||
| 88 | { | ||
| 89 | int err; | ||
| 90 | |||
| 91 | if(ptrace_faultinfo){ | ||
| 92 | err = ptrace(PTRACE_FAULTINFO, pid, 0, fi); | ||
| 93 | if(err) | ||
| 94 | panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, " | ||
| 95 | "errno = %d\n", errno); | ||
| 96 | |||
| 97 | /* Special handling for i386, which has different structs */ | ||
| 98 | if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo)) | ||
| 99 | memset((char *)fi + sizeof(struct ptrace_faultinfo), 0, | ||
| 100 | sizeof(struct faultinfo) - | ||
| 101 | sizeof(struct ptrace_faultinfo)); | ||
| 102 | } | ||
| 103 | else { | ||
| 104 | wait_stub_done(pid, SIGSEGV, "get_skas_faultinfo"); | ||
| 105 | |||
| 106 | /* faultinfo is prepared by the stub-segv-handler at start of | ||
| 107 | * the stub stack page. We just have to copy it. | ||
| 108 | */ | ||
| 109 | memcpy(fi, (void *)current_stub_stack(), sizeof(*fi)); | ||
| 110 | } | ||
| 111 | } | ||
| 112 | |||
| 113 | static void handle_segv(int pid, union uml_pt_regs * regs) | ||
| 114 | { | ||
| 115 | get_skas_faultinfo(pid, ®s->skas.faultinfo); | ||
| 116 | segv(regs->skas.faultinfo, 0, 1, NULL); | ||
| 117 | } | ||
| 118 | |||
| 119 | /*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/ | ||
| 120 | static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu) | ||
| 121 | { | ||
| 122 | int err, status; | ||
| 123 | |||
| 124 | /* Mark this as a syscall */ | ||
| 125 | UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->skas.regs); | ||
| 126 | |||
| 127 | if (!local_using_sysemu) | ||
| 128 | { | ||
| 129 | err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid); | ||
| 130 | if(err < 0) | ||
| 131 | panic("handle_trap - nullifying syscall failed errno = %d\n", | ||
| 132 | errno); | ||
| 133 | |||
| 134 | err = ptrace(PTRACE_SYSCALL, pid, 0, 0); | ||
| 135 | if(err < 0) | ||
| 136 | panic("handle_trap - continuing to end of syscall failed, " | ||
| 137 | "errno = %d\n", errno); | ||
| 138 | |||
| 139 | CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); | ||
| 140 | if((err < 0) || !WIFSTOPPED(status) || | ||
| 141 | (WSTOPSIG(status) != SIGTRAP + 0x80)) | ||
| 142 | panic("handle_trap - failed to wait at end of syscall, " | ||
| 143 | "errno = %d, status = %d\n", errno, status); | ||
| 144 | } | ||
| 145 | |||
| 146 | handle_syscall(regs); | ||
| 147 | } | ||
| 148 | |||
| 149 | extern int __syscall_stub_start; | ||
| 150 | int stub_code_fd = -1; | ||
| 151 | __u64 stub_code_offset; | ||
| 152 | |||
| 153 | static int userspace_tramp(void *stack) | ||
| 154 | { | ||
| 155 | void *addr; | ||
| 156 | |||
| 157 | ptrace(PTRACE_TRACEME, 0, 0, 0); | ||
| 158 | |||
| 159 | init_new_thread_signals(1); | ||
| 160 | enable_timer(); | ||
| 161 | |||
| 162 | if(!proc_mm){ | ||
| 163 | /* This has a pte, but it can't be mapped in with the usual | ||
| 164 | * tlb_flush mechanism because this is part of that mechanism | ||
| 165 | */ | ||
| 166 | addr = mmap64((void *) UML_CONFIG_STUB_CODE, page_size(), | ||
| 167 | PROT_EXEC, MAP_FIXED | MAP_PRIVATE, | ||
| 168 | stub_code_fd, stub_code_offset); | ||
| 169 | if(addr == MAP_FAILED){ | ||
| 170 | printk("mapping stub code failed, errno = %d\n", | ||
| 171 | errno); | ||
| 172 | exit(1); | ||
| 173 | } | ||
| 174 | |||
| 175 | if(stack != NULL){ | ||
| 176 | int fd; | ||
| 177 | __u64 offset; | ||
| 178 | |||
| 179 | fd = phys_mapping(to_phys(stack), &offset); | ||
| 180 | addr = mmap((void *) UML_CONFIG_STUB_DATA, page_size(), | ||
| 181 | PROT_READ | PROT_WRITE, | ||
| 182 | MAP_FIXED | MAP_SHARED, fd, offset); | ||
| 183 | if(addr == MAP_FAILED){ | ||
| 184 | printk("mapping stub stack failed, " | ||
| 185 | "errno = %d\n", errno); | ||
| 186 | exit(1); | ||
| 187 | } | ||
| 188 | } | ||
| 189 | } | ||
| 190 | if(!ptrace_faultinfo){ | ||
| 191 | unsigned long v = UML_CONFIG_STUB_CODE + | ||
| 192 | (unsigned long) stub_segv_handler - | ||
| 193 | (unsigned long) &__syscall_stub_start; | ||
| 194 | |||
| 195 | set_sigstack((void *) UML_CONFIG_STUB_DATA, page_size()); | ||
| 196 | set_handler(SIGSEGV, (void *) v, SA_ONSTACK, | ||
| 197 | SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, | ||
| 198 | SIGUSR1, -1); | ||
| 199 | } | ||
| 200 | |||
| 201 | os_stop_process(os_getpid()); | ||
| 202 | return(0); | ||
| 203 | } | ||
| 204 | |||
| 205 | /* Each element set once, and only accessed by a single processor anyway */ | ||
| 206 | #undef NR_CPUS | ||
| 207 | #define NR_CPUS 1 | ||
| 208 | int userspace_pid[NR_CPUS]; | ||
| 209 | |||
| 210 | int start_userspace(unsigned long stub_stack) | ||
| 211 | { | ||
| 212 | void *stack; | ||
| 213 | unsigned long sp; | ||
| 214 | int pid, status, n, flags; | ||
| 215 | |||
| 216 | if ( stub_code_fd == -1 ) | ||
| 217 | stub_code_fd = phys_mapping(to_phys(&__syscall_stub_start), | ||
| 218 | &stub_code_offset); | ||
| 219 | |||
| 220 | stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, | ||
| 221 | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); | ||
| 222 | if(stack == MAP_FAILED) | ||
| 223 | panic("start_userspace : mmap failed, errno = %d", errno); | ||
| 224 | sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *); | ||
| 225 | |||
| 226 | flags = CLONE_FILES | SIGCHLD; | ||
| 227 | if(proc_mm) flags |= CLONE_VM; | ||
| 228 | pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack); | ||
| 229 | if(pid < 0) | ||
| 230 | panic("start_userspace : clone failed, errno = %d", errno); | ||
| 231 | |||
| 232 | do { | ||
| 233 | CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); | ||
| 234 | if(n < 0) | ||
| 235 | panic("start_userspace : wait failed, errno = %d", | ||
| 236 | errno); | ||
| 237 | } while(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM)); | ||
| 238 | |||
| 239 | if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) | ||
| 240 | panic("start_userspace : expected SIGSTOP, got status = %d", | ||
| 241 | status); | ||
| 242 | |||
| 243 | if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, (void *)PTRACE_O_TRACESYSGOOD) < 0) | ||
| 244 | panic("start_userspace : PTRACE_SETOPTIONS failed, errno=%d\n", | ||
| 245 | errno); | ||
| 246 | |||
| 247 | if(munmap(stack, PAGE_SIZE) < 0) | ||
| 248 | panic("start_userspace : munmap failed, errno = %d\n", errno); | ||
| 249 | |||
| 250 | return(pid); | ||
| 251 | } | ||
| 252 | |||
| 253 | void userspace(union uml_pt_regs *regs) | ||
| 254 | { | ||
| 255 | int err, status, op, pid = userspace_pid[0]; | ||
| 256 | int local_using_sysemu; /*To prevent races if using_sysemu changes under us.*/ | ||
| 257 | |||
| 258 | while(1){ | ||
| 259 | restore_registers(pid, regs); | ||
| 260 | |||
| 261 | /* Now we set local_using_sysemu to be used for one loop */ | ||
| 262 | local_using_sysemu = get_using_sysemu(); | ||
| 263 | |||
| 264 | op = SELECT_PTRACE_OPERATION(local_using_sysemu, singlestepping(NULL)); | ||
| 265 | |||
| 266 | err = ptrace(op, pid, 0, 0); | ||
| 267 | if(err) | ||
| 268 | panic("userspace - could not resume userspace process, " | ||
| 269 | "pid=%d, ptrace operation = %d, errno = %d\n", | ||
| 270 | op, errno); | ||
| 271 | |||
| 272 | CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); | ||
| 273 | if(err < 0) | ||
| 274 | panic("userspace - waitpid failed, errno = %d\n", | ||
| 275 | errno); | ||
| 276 | |||
| 277 | regs->skas.is_user = 1; | ||
| 278 | save_registers(pid, regs); | ||
| 279 | UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */ | ||
| 280 | |||
| 281 | if(WIFSTOPPED(status)){ | ||
| 282 | switch(WSTOPSIG(status)){ | ||
| 283 | case SIGSEGV: | ||
| 284 | if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo) | ||
| 285 | user_signal(SIGSEGV, regs, pid); | ||
| 286 | else handle_segv(pid, regs); | ||
| 287 | break; | ||
| 288 | case SIGTRAP + 0x80: | ||
| 289 | handle_trap(pid, regs, local_using_sysemu); | ||
| 290 | break; | ||
| 291 | case SIGTRAP: | ||
| 292 | relay_signal(SIGTRAP, regs); | ||
| 293 | break; | ||
| 294 | case SIGIO: | ||
| 295 | case SIGVTALRM: | ||
| 296 | case SIGILL: | ||
| 297 | case SIGBUS: | ||
| 298 | case SIGFPE: | ||
| 299 | case SIGWINCH: | ||
| 300 | user_signal(WSTOPSIG(status), regs, pid); | ||
| 301 | break; | ||
| 302 | default: | ||
| 303 | printk("userspace - child stopped with signal " | ||
| 304 | "%d\n", WSTOPSIG(status)); | ||
| 305 | } | ||
| 306 | pid = userspace_pid[0]; | ||
| 307 | interrupt_end(); | ||
| 308 | |||
| 309 | /* Avoid -ERESTARTSYS handling in host */ | ||
| 310 | PT_SYSCALL_NR(regs->skas.regs) = -1; | ||
| 311 | } | ||
| 312 | } | ||
| 313 | } | ||
| 314 | #define INIT_JMP_NEW_THREAD 0 | ||
| 315 | #define INIT_JMP_REMOVE_SIGSTACK 1 | ||
| 316 | #define INIT_JMP_CALLBACK 2 | ||
| 317 | #define INIT_JMP_HALT 3 | ||
| 318 | #define INIT_JMP_REBOOT 4 | ||
| 319 | |||
| 320 | |||
| 321 | int copy_context_skas0(unsigned long new_stack, int pid) | ||
| 322 | { | ||
| 323 | int err; | ||
| 324 | unsigned long regs[MAX_REG_NR]; | ||
| 325 | unsigned long current_stack = current_stub_stack(); | ||
| 326 | struct stub_data *data = (struct stub_data *) current_stack; | ||
| 327 | struct stub_data *child_data = (struct stub_data *) new_stack; | ||
| 328 | __u64 new_offset; | ||
| 329 | int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset); | ||
| 330 | |||
| 331 | /* prepare offset and fd of child's stack as argument for parent's | ||
| 332 | * and child's mmap2 calls | ||
| 333 | */ | ||
| 334 | *data = ((struct stub_data) { .offset = MMAP_OFFSET(new_offset), | ||
| 335 | .fd = new_fd, | ||
| 336 | .timer = ((struct itimerval) | ||
| 337 | { { 0, 1000000 / hz() }, | ||
| 338 | { 0, 1000000 / hz() }})}); | ||
| 339 | get_safe_registers(regs); | ||
| 340 | |||
| 341 | /* Set parent's instruction pointer to start of clone-stub */ | ||
| 342 | regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + | ||
| 343 | (unsigned long) stub_clone_handler - | ||
| 344 | (unsigned long) &__syscall_stub_start; | ||
| 345 | regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE - | ||
| 346 | sizeof(void *); | ||
| 347 | err = ptrace_setregs(pid, regs); | ||
| 348 | if(err < 0) | ||
| 349 | panic("copy_context_skas0 : PTRACE_SETREGS failed, " | ||
| 350 | "pid = %d, errno = %d\n", pid, errno); | ||
| 351 | |||
| 352 | /* set a well known return code for detection of child write failure */ | ||
| 353 | child_data->err = 12345678; | ||
| 354 | |||
| 355 | /* Wait, until parent has finished its work: read child's pid from | ||
| 356 | * parent's stack, and check, if bad result. | ||
| 357 | */ | ||
| 358 | wait_stub_done(pid, 0, "copy_context_skas0"); | ||
| 359 | |||
| 360 | pid = data->err; | ||
| 361 | if(pid < 0) | ||
| 362 | panic("copy_context_skas0 - stub-parent reports error %d\n", | ||
| 363 | pid); | ||
| 364 | |||
| 365 | /* Wait, until child has finished too: read child's result from | ||
| 366 | * child's stack and check it. | ||
| 367 | */ | ||
| 368 | wait_stub_done(pid, -1, "copy_context_skas0"); | ||
| 369 | if (child_data->err != UML_CONFIG_STUB_DATA) | ||
| 370 | panic("copy_context_skas0 - stub-child reports error %d\n", | ||
| 371 | child_data->err); | ||
| 372 | |||
| 373 | if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, | ||
| 374 | (void *)PTRACE_O_TRACESYSGOOD) < 0) | ||
| 375 | panic("copy_context_skas0 : PTRACE_SETOPTIONS failed, " | ||
| 376 | "errno = %d\n", errno); | ||
| 377 | |||
| 378 | return pid; | ||
| 379 | } | ||
| 380 | |||
| 381 | /* | ||
| 382 | * This is used only, if stub pages are needed, while proc_mm is | ||
| 383 | * availabl. Opening /proc/mm creates a new mm_context, which lacks | ||
| 384 | * the stub-pages. Thus, we map them using /proc/mm-fd | ||
| 385 | */ | ||
| 386 | void map_stub_pages(int fd, unsigned long code, | ||
| 387 | unsigned long data, unsigned long stack) | ||
| 388 | { | ||
| 389 | struct proc_mm_op mmop; | ||
| 390 | int n; | ||
| 391 | |||
| 392 | mmop = ((struct proc_mm_op) { .op = MM_MMAP, | ||
| 393 | .u = | ||
| 394 | { .mmap = | ||
| 395 | { .addr = code, | ||
| 396 | .len = PAGE_SIZE, | ||
| 397 | .prot = PROT_EXEC, | ||
| 398 | .flags = MAP_FIXED | MAP_PRIVATE, | ||
| 399 | .fd = stub_code_fd, | ||
| 400 | .offset = stub_code_offset | ||
| 401 | } } }); | ||
| 402 | n = os_write_file(fd, &mmop, sizeof(mmop)); | ||
| 403 | if(n != sizeof(mmop)) | ||
| 404 | panic("map_stub_pages : /proc/mm map for code failed, " | ||
| 405 | "err = %d\n", -n); | ||
| 406 | |||
| 407 | if ( stack ) { | ||
| 408 | __u64 map_offset; | ||
| 409 | int map_fd = phys_mapping(to_phys((void *)stack), &map_offset); | ||
| 410 | mmop = ((struct proc_mm_op) | ||
| 411 | { .op = MM_MMAP, | ||
| 412 | .u = | ||
| 413 | { .mmap = | ||
| 414 | { .addr = data, | ||
| 415 | .len = PAGE_SIZE, | ||
| 416 | .prot = PROT_READ | PROT_WRITE, | ||
| 417 | .flags = MAP_FIXED | MAP_SHARED, | ||
| 418 | .fd = map_fd, | ||
| 419 | .offset = map_offset | ||
| 420 | } } }); | ||
| 421 | n = os_write_file(fd, &mmop, sizeof(mmop)); | ||
| 422 | if(n != sizeof(mmop)) | ||
| 423 | panic("map_stub_pages : /proc/mm map for data failed, " | ||
| 424 | "err = %d\n", -n); | ||
| 425 | } | ||
| 426 | } | ||
| 427 | |||
| 428 | void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | ||
| 429 | void (*handler)(int)) | ||
| 430 | { | ||
| 431 | unsigned long flags; | ||
| 432 | sigjmp_buf switch_buf, fork_buf; | ||
| 433 | |||
| 434 | *switch_buf_ptr = &switch_buf; | ||
| 435 | *fork_buf_ptr = &fork_buf; | ||
| 436 | |||
| 437 | /* Somewhat subtle - siglongjmp restores the signal mask before doing | ||
| 438 | * the longjmp. This means that when jumping from one stack to another | ||
| 439 | * when the target stack has interrupts enabled, an interrupt may occur | ||
| 440 | * on the source stack. This is bad when starting up a process because | ||
| 441 | * it's not supposed to get timer ticks until it has been scheduled. | ||
| 442 | * So, we disable interrupts around the sigsetjmp to ensure that | ||
| 443 | * they can't happen until we get back here where they are safe. | ||
| 444 | */ | ||
| 445 | flags = get_signals(); | ||
| 446 | block_signals(); | ||
| 447 | if(sigsetjmp(fork_buf, 1) == 0) | ||
| 448 | new_thread_proc(stack, handler); | ||
| 449 | |||
| 450 | remove_sigstack(); | ||
| 451 | |||
| 452 | set_signals(flags); | ||
| 453 | } | ||
| 454 | |||
| 455 | void thread_wait(void *sw, void *fb) | ||
| 456 | { | ||
| 457 | sigjmp_buf buf, **switch_buf = sw, *fork_buf; | ||
| 458 | |||
| 459 | *switch_buf = &buf; | ||
| 460 | fork_buf = fb; | ||
| 461 | if(sigsetjmp(buf, 1) == 0) | ||
| 462 | siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK); | ||
| 463 | } | ||
| 464 | |||
| 465 | void switch_threads(void *me, void *next) | ||
| 466 | { | ||
| 467 | sigjmp_buf my_buf, **me_ptr = me, *next_buf = next; | ||
| 468 | |||
| 469 | *me_ptr = &my_buf; | ||
| 470 | if(sigsetjmp(my_buf, 1) == 0) | ||
| 471 | siglongjmp(*next_buf, 1); | ||
| 472 | } | ||
| 473 | |||
| 474 | static sigjmp_buf initial_jmpbuf; | ||
| 475 | |||
| 476 | /* XXX Make these percpu */ | ||
| 477 | static void (*cb_proc)(void *arg); | ||
| 478 | static void *cb_arg; | ||
| 479 | static sigjmp_buf *cb_back; | ||
| 480 | |||
| 481 | int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | ||
| 482 | { | ||
| 483 | sigjmp_buf **switch_buf = switch_buf_ptr; | ||
| 484 | int n; | ||
| 485 | |||
| 486 | set_handler(SIGWINCH, (__sighandler_t) sig_handler, | ||
| 487 | SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM, | ||
| 488 | SIGVTALRM, -1); | ||
| 489 | |||
| 490 | *fork_buf_ptr = &initial_jmpbuf; | ||
| 491 | n = sigsetjmp(initial_jmpbuf, 1); | ||
| 492 | switch(n){ | ||
| 493 | case INIT_JMP_NEW_THREAD: | ||
| 494 | new_thread_proc((void *) stack, new_thread_handler); | ||
| 495 | break; | ||
| 496 | case INIT_JMP_REMOVE_SIGSTACK: | ||
| 497 | remove_sigstack(); | ||
| 498 | break; | ||
| 499 | case INIT_JMP_CALLBACK: | ||
| 500 | (*cb_proc)(cb_arg); | ||
| 501 | siglongjmp(*cb_back, 1); | ||
| 502 | break; | ||
| 503 | case INIT_JMP_HALT: | ||
| 504 | kmalloc_ok = 0; | ||
| 505 | return(0); | ||
| 506 | case INIT_JMP_REBOOT: | ||
| 507 | kmalloc_ok = 0; | ||
| 508 | return(1); | ||
| 509 | default: | ||
| 510 | panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); | ||
| 511 | } | ||
| 512 | siglongjmp(**switch_buf, 1); | ||
| 513 | } | ||
| 514 | |||
| 515 | void initial_thread_cb_skas(void (*proc)(void *), void *arg) | ||
| 516 | { | ||
| 517 | sigjmp_buf here; | ||
| 518 | |||
| 519 | cb_proc = proc; | ||
| 520 | cb_arg = arg; | ||
| 521 | cb_back = &here; | ||
| 522 | |||
| 523 | block_signals(); | ||
| 524 | if(sigsetjmp(here, 1) == 0) | ||
| 525 | siglongjmp(initial_jmpbuf, INIT_JMP_CALLBACK); | ||
| 526 | unblock_signals(); | ||
| 527 | |||
| 528 | cb_proc = NULL; | ||
| 529 | cb_arg = NULL; | ||
| 530 | cb_back = NULL; | ||
| 531 | } | ||
| 532 | |||
| 533 | void halt_skas(void) | ||
| 534 | { | ||
| 535 | block_signals(); | ||
| 536 | siglongjmp(initial_jmpbuf, INIT_JMP_HALT); | ||
| 537 | } | ||
| 538 | |||
| 539 | void reboot_skas(void) | ||
| 540 | { | ||
| 541 | block_signals(); | ||
| 542 | siglongjmp(initial_jmpbuf, INIT_JMP_REBOOT); | ||
| 543 | } | ||
| 544 | |||
| 545 | void switch_mm_skas(struct mm_id *mm_idp) | ||
| 546 | { | ||
| 547 | int err; | ||
| 548 | |||
| 549 | #warning need cpu pid in switch_mm_skas | ||
| 550 | if(proc_mm){ | ||
| 551 | err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, | ||
| 552 | mm_idp->u.mm_fd); | ||
| 553 | if(err) | ||
| 554 | panic("switch_mm_skas - PTRACE_SWITCH_MM failed, " | ||
| 555 | "errno = %d\n", errno); | ||
| 556 | } | ||
| 557 | else userspace_pid[0] = mm_idp->u.pid; | ||
| 558 | } | ||
| 559 | |||
| 560 | /* | ||
| 561 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
| 562 | * Emacs will notice this stuff at the end of the file and automatically | ||
| 563 | * adjust the settings for this buffer only. This must remain at the end | ||
| 564 | * of the file. | ||
| 565 | * --------------------------------------------------------------------------- | ||
| 566 | * Local variables: | ||
| 567 | * c-file-style: "linux" | ||
| 568 | * End: | ||
| 569 | */ | ||
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index e2d3ca445ef5..27cdf9164422 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c | |||
| @@ -193,6 +193,24 @@ __uml_setup("root=", uml_root_setup, | |||
| 193 | " root=/dev/ubd5\n\n" | 193 | " root=/dev/ubd5\n\n" |
| 194 | ); | 194 | ); |
| 195 | 195 | ||
| 196 | #ifndef CONFIG_MODE_TT | ||
| 197 | |||
| 198 | static int __init no_skas_debug_setup(char *line, int *add) | ||
| 199 | { | ||
| 200 | printf("'debug' is not necessary to gdb UML in skas mode - run \n"); | ||
| 201 | printf("'gdb linux' and disable CONFIG_CMDLINE_ON_HOST if gdb \n"); | ||
| 202 | printf("doesn't work as expected\n"); | ||
| 203 | |||
| 204 | return 0; | ||
| 205 | } | ||
| 206 | |||
| 207 | __uml_setup("debug", no_skas_debug_setup, | ||
| 208 | "debug\n" | ||
| 209 | " this flag is not needed to run gdb on UML in skas mode\n\n" | ||
| 210 | ); | ||
| 211 | |||
| 212 | #endif | ||
| 213 | |||
| 196 | #ifdef CONFIG_SMP | 214 | #ifdef CONFIG_SMP |
| 197 | static int __init uml_ncpus_setup(char *line, int *add) | 215 | static int __init uml_ncpus_setup(char *line, int *add) |
| 198 | { | 216 | { |
diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c index 52945338b64d..87c3aa0252db 100644 --- a/arch/um/os-Linux/drivers/tuntap_user.c +++ b/arch/um/os-Linux/drivers/tuntap_user.c | |||
| @@ -122,6 +122,7 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, | |||
| 122 | return(-EINVAL); | 122 | return(-EINVAL); |
| 123 | } | 123 | } |
| 124 | *fd_out = ((int *) CMSG_DATA(cmsg))[0]; | 124 | *fd_out = ((int *) CMSG_DATA(cmsg))[0]; |
| 125 | os_set_exec_close(*fd_out, 1); | ||
| 125 | return(0); | 126 | return(0); |
| 126 | } | 127 | } |
| 127 | 128 | ||
| @@ -137,7 +138,8 @@ static int tuntap_open(void *data) | |||
| 137 | return(err); | 138 | return(err); |
| 138 | 139 | ||
| 139 | if(pri->fixed_config){ | 140 | if(pri->fixed_config){ |
| 140 | pri->fd = os_open_file("/dev/net/tun", of_rdwr(OPENFLAGS()), 0); | 141 | pri->fd = os_open_file("/dev/net/tun", |
| 142 | of_cloexec(of_rdwr(OPENFLAGS())), 0); | ||
| 141 | if(pri->fd < 0){ | 143 | if(pri->fd < 0){ |
| 142 | printk("Failed to open /dev/net/tun, err = %d\n", | 144 | printk("Failed to open /dev/net/tun, err = %d\n", |
| 143 | -pri->fd); | 145 | -pri->fd); |
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index 9890e9090f58..fbb080c2fc26 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c | |||
| @@ -60,7 +60,7 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) | |||
| 60 | 60 | ||
| 61 | multi_count++; | 61 | multi_count++; |
| 62 | 62 | ||
| 63 | get_safe_registers(regs); | 63 | get_safe_registers(regs, NULL); |
| 64 | regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + | 64 | regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + |
| 65 | ((unsigned long) &batch_syscall_stub - | 65 | ((unsigned long) &batch_syscall_stub - |
| 66 | (unsigned long) &__syscall_stub_start); | 66 | (unsigned long) &__syscall_stub_start); |
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 120a21c5883f..bbf34cb91ce1 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c | |||
| @@ -310,16 +310,12 @@ void userspace(union uml_pt_regs *regs) | |||
| 310 | } | 310 | } |
| 311 | } | 311 | } |
| 312 | } | 312 | } |
| 313 | #define INIT_JMP_NEW_THREAD 0 | ||
| 314 | #define INIT_JMP_REMOVE_SIGSTACK 1 | ||
| 315 | #define INIT_JMP_CALLBACK 2 | ||
| 316 | #define INIT_JMP_HALT 3 | ||
| 317 | #define INIT_JMP_REBOOT 4 | ||
| 318 | 313 | ||
| 319 | int copy_context_skas0(unsigned long new_stack, int pid) | 314 | int copy_context_skas0(unsigned long new_stack, int pid) |
| 320 | { | 315 | { |
| 321 | int err; | 316 | int err; |
| 322 | unsigned long regs[MAX_REG_NR]; | 317 | unsigned long regs[HOST_FRAME_SIZE]; |
| 318 | unsigned long fp_regs[HOST_FP_SIZE]; | ||
| 323 | unsigned long current_stack = current_stub_stack(); | 319 | unsigned long current_stack = current_stub_stack(); |
| 324 | struct stub_data *data = (struct stub_data *) current_stack; | 320 | struct stub_data *data = (struct stub_data *) current_stack; |
| 325 | struct stub_data *child_data = (struct stub_data *) new_stack; | 321 | struct stub_data *child_data = (struct stub_data *) new_stack; |
| @@ -334,7 +330,7 @@ int copy_context_skas0(unsigned long new_stack, int pid) | |||
| 334 | .timer = ((struct itimerval) | 330 | .timer = ((struct itimerval) |
| 335 | { { 0, 1000000 / hz() }, | 331 | { { 0, 1000000 / hz() }, |
| 336 | { 0, 1000000 / hz() }})}); | 332 | { 0, 1000000 / hz() }})}); |
| 337 | get_safe_registers(regs); | 333 | get_safe_registers(regs, fp_regs); |
| 338 | 334 | ||
| 339 | /* Set parent's instruction pointer to start of clone-stub */ | 335 | /* Set parent's instruction pointer to start of clone-stub */ |
| 340 | regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + | 336 | regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + |
| @@ -350,6 +346,11 @@ int copy_context_skas0(unsigned long new_stack, int pid) | |||
| 350 | panic("copy_context_skas0 : PTRACE_SETREGS failed, " | 346 | panic("copy_context_skas0 : PTRACE_SETREGS failed, " |
| 351 | "pid = %d, errno = %d\n", pid, errno); | 347 | "pid = %d, errno = %d\n", pid, errno); |
| 352 | 348 | ||
| 349 | err = ptrace_setfpregs(pid, fp_regs); | ||
| 350 | if(err < 0) | ||
| 351 | panic("copy_context_skas0 : PTRACE_SETFPREGS failed, " | ||
| 352 | "pid = %d, errno = %d\n", pid, errno); | ||
| 353 | |||
| 353 | /* set a well known return code for detection of child write failure */ | 354 | /* set a well known return code for detection of child write failure */ |
| 354 | child_data->err = 12345678; | 355 | child_data->err = 12345678; |
| 355 | 356 | ||
| @@ -457,6 +458,12 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | |||
| 457 | set_signals(flags); | 458 | set_signals(flags); |
| 458 | } | 459 | } |
| 459 | 460 | ||
| 461 | #define INIT_JMP_NEW_THREAD 0 | ||
| 462 | #define INIT_JMP_REMOVE_SIGSTACK 1 | ||
| 463 | #define INIT_JMP_CALLBACK 2 | ||
| 464 | #define INIT_JMP_HALT 3 | ||
| 465 | #define INIT_JMP_REBOOT 4 | ||
| 466 | |||
| 460 | void thread_wait(void *sw, void *fb) | 467 | void thread_wait(void *sw, void *fb) |
| 461 | { | 468 | { |
| 462 | sigjmp_buf buf, **switch_buf = sw, *fork_buf; | 469 | sigjmp_buf buf, **switch_buf = sw, *fork_buf; |
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 6c5b17ed59e1..829d6b0d8b02 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c | |||
| @@ -49,6 +49,7 @@ static int ptrace_child(void *arg) | |||
| 49 | int pid = os_getpid(), ppid = getppid(); | 49 | int pid = os_getpid(), ppid = getppid(); |
| 50 | int sc_result; | 50 | int sc_result; |
| 51 | 51 | ||
| 52 | change_sig(SIGWINCH, 0); | ||
| 52 | if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){ | 53 | if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){ |
| 53 | perror("ptrace"); | 54 | perror("ptrace"); |
| 54 | os_kill_process(pid, 0); | 55 | os_kill_process(pid, 0); |
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c index aee4812333c6..7a6f6b99ceff 100644 --- a/arch/um/os-Linux/sys-i386/registers.c +++ b/arch/um/os-Linux/sys-i386/registers.c | |||
| @@ -122,9 +122,12 @@ void init_registers(int pid) | |||
| 122 | err); | 122 | err); |
| 123 | } | 123 | } |
| 124 | 124 | ||
| 125 | void get_safe_registers(unsigned long *regs) | 125 | void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) |
| 126 | { | 126 | { |
| 127 | memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long)); | 127 | memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long)); |
| 128 | if(fp_regs != NULL) | ||
| 129 | memcpy(fp_regs, exec_fp_regs, | ||
| 130 | HOST_FP_SIZE * sizeof(unsigned long)); | ||
| 128 | } | 131 | } |
| 129 | 132 | ||
| 130 | void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer) | 133 | void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer) |
diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c index 4b638dfb52b0..001941fa1a1e 100644 --- a/arch/um/os-Linux/sys-x86_64/registers.c +++ b/arch/um/os-Linux/sys-x86_64/registers.c | |||
| @@ -70,9 +70,12 @@ void init_registers(int pid) | |||
| 70 | err); | 70 | err); |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | void get_safe_registers(unsigned long *regs) | 73 | void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) |
| 74 | { | 74 | { |
| 75 | memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long)); | 75 | memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long)); |
| 76 | if(fp_regs != NULL) | ||
| 77 | memcpy(fp_regs, exec_fp_regs, | ||
| 78 | HOST_FP_SIZE * sizeof(unsigned long)); | ||
| 76 | } | 79 | } |
| 77 | 80 | ||
| 78 | void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer) | 81 | void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer) |
diff --git a/arch/um/sys-x86_64/ptrace_user.c b/arch/um/sys-x86_64/ptrace_user.c index 12e404c6fa46..b5f9c33e311e 100644 --- a/arch/um/sys-x86_64/ptrace_user.c +++ b/arch/um/sys-x86_64/ptrace_user.c | |||
| @@ -24,6 +24,13 @@ int ptrace_setregs(long pid, unsigned long *regs) | |||
| 24 | return(0); | 24 | return(0); |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | int ptrace_setfpregs(long pid, unsigned long *regs) | ||
| 28 | { | ||
| 29 | if (ptrace(PTRACE_SETFPREGS, pid, 0, regs) < 0) | ||
| 30 | return -errno; | ||
| 31 | return 0; | ||
| 32 | } | ||
| 33 | |||
| 27 | void ptrace_pokeuser(unsigned long addr, unsigned long data) | 34 | void ptrace_pokeuser(unsigned long addr, unsigned long data) |
| 28 | { | 35 | { |
| 29 | panic("ptrace_pokeuser"); | 36 | panic("ptrace_pokeuser"); |
diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c index 5a585bfbb8c2..7bd54a921cf7 100644 --- a/arch/um/sys-x86_64/user-offsets.c +++ b/arch/um/sys-x86_64/user-offsets.c | |||
| @@ -57,7 +57,7 @@ void foo(void) | |||
| 57 | #endif | 57 | #endif |
| 58 | 58 | ||
| 59 | DEFINE_LONGS(HOST_FRAME_SIZE, FRAME_SIZE); | 59 | DEFINE_LONGS(HOST_FRAME_SIZE, FRAME_SIZE); |
| 60 | DEFINE(HOST_FP_SIZE, 0); | 60 | DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long)); |
| 61 | DEFINE(HOST_XFP_SIZE, 0); | 61 | DEFINE(HOST_XFP_SIZE, 0); |
| 62 | DEFINE_LONGS(HOST_RBX, RBX); | 62 | DEFINE_LONGS(HOST_RBX, RBX); |
| 63 | DEFINE_LONGS(HOST_RCX, RCX); | 63 | DEFINE_LONGS(HOST_RCX, RCX); |
diff --git a/arch/v850/kernel/simcons.c b/arch/v850/kernel/simcons.c index 7f0efaa025c9..3975aa02cef8 100644 --- a/arch/v850/kernel/simcons.c +++ b/arch/v850/kernel/simcons.c | |||
| @@ -117,6 +117,7 @@ late_initcall(simcons_tty_init); | |||
| 117 | tty driver. */ | 117 | tty driver. */ |
| 118 | void simcons_poll_tty (struct tty_struct *tty) | 118 | void simcons_poll_tty (struct tty_struct *tty) |
| 119 | { | 119 | { |
| 120 | char buf[32]; /* Not the nicest way to do it but I need it correct first */ | ||
| 120 | int flip = 0, send_break = 0; | 121 | int flip = 0, send_break = 0; |
| 121 | struct pollfd pfd; | 122 | struct pollfd pfd; |
| 122 | pfd.fd = 0; | 123 | pfd.fd = 0; |
| @@ -124,21 +125,15 @@ void simcons_poll_tty (struct tty_struct *tty) | |||
| 124 | 125 | ||
| 125 | if (V850_SIM_SYSCALL (poll, &pfd, 1, 0) > 0) { | 126 | if (V850_SIM_SYSCALL (poll, &pfd, 1, 0) > 0) { |
| 126 | if (pfd.revents & POLLIN) { | 127 | if (pfd.revents & POLLIN) { |
| 127 | int left = TTY_FLIPBUF_SIZE - tty->flip.count; | 128 | /* Real block hardware knows the transfer size before |
| 128 | 129 | transfer so the new tty buffering doesn't try to handle | |
| 129 | if (left > 0) { | 130 | this rather weird simulator specific case well */ |
| 130 | unsigned char *buf = tty->flip.char_buf_ptr; | 131 | int rd = V850_SIM_SYSCALL (read, 0, buf, 32); |
| 131 | int rd = V850_SIM_SYSCALL (read, 0, buf, left); | 132 | if (rd > 0) { |
| 132 | 133 | tty_insert_flip_string(tty, buf, rd); | |
| 133 | if (rd > 0) { | 134 | flip = 1; |
| 134 | tty->flip.count += rd; | 135 | } else |
| 135 | tty->flip.char_buf_ptr += rd; | 136 | send_break = 1; |
| 136 | memset (tty->flip.flag_buf_ptr, 0, rd); | ||
| 137 | tty->flip.flag_buf_ptr += rd; | ||
| 138 | flip = 1; | ||
| 139 | } else | ||
| 140 | send_break = 1; | ||
| 141 | } | ||
| 142 | } else if (pfd.revents & POLLERR) | 137 | } else if (pfd.revents & POLLERR) |
| 143 | send_break = 1; | 138 | send_break = 1; |
| 144 | } | 139 | } |
diff --git a/arch/x86_64/Kconfig.debug b/arch/x86_64/Kconfig.debug index fcb06a50fdd2..ea31b4c62105 100644 --- a/arch/x86_64/Kconfig.debug +++ b/arch/x86_64/Kconfig.debug | |||
| @@ -2,13 +2,6 @@ menu "Kernel hacking" | |||
| 2 | 2 | ||
| 3 | source "lib/Kconfig.debug" | 3 | source "lib/Kconfig.debug" |
| 4 | 4 | ||
| 5 | config INIT_DEBUG | ||
| 6 | bool "Debug __init statements" | ||
| 7 | depends on DEBUG_KERNEL | ||
| 8 | help | ||
| 9 | Fill __init and __initdata at the end of boot. This helps debugging | ||
| 10 | illegal uses of __init and __initdata after initialization. | ||
| 11 | |||
| 12 | config DEBUG_RODATA | 5 | config DEBUG_RODATA |
| 13 | bool "Write protect kernel read-only data structures" | 6 | bool "Write protect kernel read-only data structures" |
| 14 | depends on DEBUG_KERNEL | 7 | depends on DEBUG_KERNEL |
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig index 09a3eb743315..56832929a543 100644 --- a/arch/x86_64/defconfig +++ b/arch/x86_64/defconfig | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | # | 1 | # |
| 2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
| 3 | # Linux kernel version: 2.6.15-git12 | 3 | # Linux kernel version: 2.6.16-rc1-git2 |
| 4 | # Mon Jan 16 13:09:08 2006 | 4 | # Thu Jan 19 10:05:21 2006 |
| 5 | # | 5 | # |
| 6 | CONFIG_X86_64=y | 6 | CONFIG_X86_64=y |
| 7 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
| @@ -310,6 +310,11 @@ CONFIG_IPV6=y | |||
| 310 | # SCTP Configuration (EXPERIMENTAL) | 310 | # SCTP Configuration (EXPERIMENTAL) |
| 311 | # | 311 | # |
| 312 | # CONFIG_IP_SCTP is not set | 312 | # CONFIG_IP_SCTP is not set |
| 313 | |||
| 314 | # | ||
| 315 | # TIPC Configuration (EXPERIMENTAL) | ||
| 316 | # | ||
| 317 | # CONFIG_TIPC is not set | ||
| 313 | # CONFIG_ATM is not set | 318 | # CONFIG_ATM is not set |
| 314 | # CONFIG_BRIDGE is not set | 319 | # CONFIG_BRIDGE is not set |
| 315 | # CONFIG_VLAN_8021Q is not set | 320 | # CONFIG_VLAN_8021Q is not set |
| @@ -319,11 +324,6 @@ CONFIG_IPV6=y | |||
| 319 | # CONFIG_ATALK is not set | 324 | # CONFIG_ATALK is not set |
| 320 | # CONFIG_X25 is not set | 325 | # CONFIG_X25 is not set |
| 321 | # CONFIG_LAPB is not set | 326 | # CONFIG_LAPB is not set |
| 322 | |||
| 323 | # | ||
| 324 | # TIPC Configuration (EXPERIMENTAL) | ||
| 325 | # | ||
| 326 | # CONFIG_TIPC is not set | ||
| 327 | # CONFIG_NET_DIVERT is not set | 327 | # CONFIG_NET_DIVERT is not set |
| 328 | # CONFIG_ECONET is not set | 328 | # CONFIG_ECONET is not set |
| 329 | # CONFIG_WAN_ROUTER is not set | 329 | # CONFIG_WAN_ROUTER is not set |
| @@ -1098,6 +1098,12 @@ CONFIG_USB_MON=y | |||
| 1098 | # | 1098 | # |
| 1099 | 1099 | ||
| 1100 | # | 1100 | # |
| 1101 | # EDAC - error detection and reporting (RAS) | ||
| 1102 | # | ||
| 1103 | # CONFIG_EDAC is not set | ||
| 1104 | # CONFIG_EDAC_POLL is not set | ||
| 1105 | |||
| 1106 | # | ||
| 1101 | # Firmware Drivers | 1107 | # Firmware Drivers |
| 1102 | # | 1108 | # |
| 1103 | # CONFIG_EDD is not set | 1109 | # CONFIG_EDD is not set |
| @@ -1290,6 +1296,7 @@ CONFIG_DEBUG_FS=y | |||
| 1290 | # CONFIG_DEBUG_VM is not set | 1296 | # CONFIG_DEBUG_VM is not set |
| 1291 | # CONFIG_FRAME_POINTER is not set | 1297 | # CONFIG_FRAME_POINTER is not set |
| 1292 | # CONFIG_FORCED_INLINING is not set | 1298 | # CONFIG_FORCED_INLINING is not set |
| 1299 | # CONFIG_UNWIND_INFO is not set | ||
| 1293 | # CONFIG_RCU_TORTURE_TEST is not set | 1300 | # CONFIG_RCU_TORTURE_TEST is not set |
| 1294 | CONFIG_INIT_DEBUG=y | 1301 | CONFIG_INIT_DEBUG=y |
| 1295 | # CONFIG_DEBUG_RODATA is not set | 1302 | # CONFIG_DEBUG_RODATA is not set |
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S index 067c0f47bd0d..ada4535d0161 100644 --- a/arch/x86_64/ia32/ia32entry.S +++ b/arch/x86_64/ia32/ia32entry.S | |||
| @@ -685,6 +685,9 @@ ia32_sys_call_table: | |||
| 685 | .quad sys_readlinkat /* 305 */ | 685 | .quad sys_readlinkat /* 305 */ |
| 686 | .quad sys_fchmodat | 686 | .quad sys_fchmodat |
| 687 | .quad sys_faccessat | 687 | .quad sys_faccessat |
| 688 | .quad sys_ni_syscall /* pselect6 for now */ | ||
| 689 | .quad sys_ni_syscall /* ppoll for now */ | ||
| 690 | .quad sys_unshare /* 310 */ | ||
| 688 | ia32_syscall_end: | 691 | ia32_syscall_end: |
| 689 | .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8 | 692 | .rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8 |
| 690 | .quad ni_syscall | 693 | .quad ni_syscall |
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c index 5d3c5b07b8db..6147770b4347 100644 --- a/arch/x86_64/kernel/apic.c +++ b/arch/x86_64/kernel/apic.c | |||
| @@ -35,8 +35,12 @@ | |||
| 35 | #include <asm/mach_apic.h> | 35 | #include <asm/mach_apic.h> |
| 36 | #include <asm/nmi.h> | 36 | #include <asm/nmi.h> |
| 37 | #include <asm/idle.h> | 37 | #include <asm/idle.h> |
| 38 | #include <asm/proto.h> | ||
| 39 | #include <asm/timex.h> | ||
| 38 | 40 | ||
| 39 | int apic_verbosity; | 41 | int apic_verbosity; |
| 42 | int apic_runs_main_timer; | ||
| 43 | int apic_calibrate_pmtmr __initdata; | ||
| 40 | 44 | ||
| 41 | int disable_apic_timer __initdata; | 45 | int disable_apic_timer __initdata; |
| 42 | 46 | ||
| @@ -68,6 +72,26 @@ int get_maxlvt(void) | |||
| 68 | return maxlvt; | 72 | return maxlvt; |
| 69 | } | 73 | } |
| 70 | 74 | ||
| 75 | /* | ||
| 76 | * 'what should we do if we get a hw irq event on an illegal vector'. | ||
| 77 | * each architecture has to answer this themselves. | ||
| 78 | */ | ||
| 79 | void ack_bad_irq(unsigned int irq) | ||
| 80 | { | ||
| 81 | printk("unexpected IRQ trap at vector %02x\n", irq); | ||
| 82 | /* | ||
| 83 | * Currently unexpected vectors happen only on SMP and APIC. | ||
| 84 | * We _must_ ack these because every local APIC has only N | ||
| 85 | * irq slots per priority level, and a 'hanging, unacked' IRQ | ||
| 86 | * holds up an irq slot - in excessive cases (when multiple | ||
| 87 | * unexpected vectors occur) that might lock up the APIC | ||
| 88 | * completely. | ||
| 89 | * But don't ack when the APIC is disabled. -AK | ||
| 90 | */ | ||
| 91 | if (!disable_apic) | ||
| 92 | ack_APIC_irq(); | ||
| 93 | } | ||
| 94 | |||
| 71 | void clear_local_APIC(void) | 95 | void clear_local_APIC(void) |
| 72 | { | 96 | { |
| 73 | int maxlvt; | 97 | int maxlvt; |
| @@ -702,9 +726,17 @@ static void setup_APIC_timer(unsigned int clocks) | |||
| 702 | c2 |= inb_p(0x40) << 8; | 726 | c2 |= inb_p(0x40) << 8; |
| 703 | } while (c2 - c1 < 300); | 727 | } while (c2 - c1 < 300); |
| 704 | } | 728 | } |
| 705 | |||
| 706 | __setup_APIC_LVTT(clocks); | 729 | __setup_APIC_LVTT(clocks); |
| 707 | 730 | /* Turn off PIT interrupt if we use APIC timer as main timer. | |
| 731 | Only works with the PM timer right now | ||
| 732 | TBD fix it for HPET too. */ | ||
| 733 | if (vxtime.mode == VXTIME_PMTMR && | ||
| 734 | smp_processor_id() == boot_cpu_id && | ||
| 735 | apic_runs_main_timer == 1 && | ||
| 736 | !cpu_isset(boot_cpu_id, timer_interrupt_broadcast_ipi_mask)) { | ||
| 737 | stop_timer_interrupt(); | ||
| 738 | apic_runs_main_timer++; | ||
| 739 | } | ||
| 708 | local_irq_restore(flags); | 740 | local_irq_restore(flags); |
| 709 | } | 741 | } |
| 710 | 742 | ||
| @@ -735,14 +767,27 @@ static int __init calibrate_APIC_clock(void) | |||
| 735 | __setup_APIC_LVTT(1000000000); | 767 | __setup_APIC_LVTT(1000000000); |
| 736 | 768 | ||
| 737 | apic_start = apic_read(APIC_TMCCT); | 769 | apic_start = apic_read(APIC_TMCCT); |
| 738 | rdtscl(tsc_start); | 770 | #ifdef CONFIG_X86_PM_TIMER |
| 739 | 771 | if (apic_calibrate_pmtmr && pmtmr_ioport) { | |
| 740 | do { | 772 | pmtimer_wait(5000); /* 5ms wait */ |
| 741 | apic = apic_read(APIC_TMCCT); | 773 | apic = apic_read(APIC_TMCCT); |
| 742 | rdtscl(tsc); | 774 | result = (apic_start - apic) * 1000L / 5; |
| 743 | } while ((tsc - tsc_start) < TICK_COUNT && (apic - apic_start) < TICK_COUNT); | 775 | } else |
| 776 | #endif | ||
| 777 | { | ||
| 778 | rdtscl(tsc_start); | ||
| 779 | |||
| 780 | do { | ||
| 781 | apic = apic_read(APIC_TMCCT); | ||
| 782 | rdtscl(tsc); | ||
| 783 | } while ((tsc - tsc_start) < TICK_COUNT && | ||
| 784 | (apic - apic_start) < TICK_COUNT); | ||
| 785 | |||
| 786 | result = (apic_start - apic) * 1000L * cpu_khz / | ||
| 787 | (tsc - tsc_start); | ||
| 788 | } | ||
| 789 | printk("result %d\n", result); | ||
| 744 | 790 | ||
| 745 | result = (apic_start - apic) * 1000L * cpu_khz / (tsc - tsc_start); | ||
| 746 | 791 | ||
| 747 | printk(KERN_INFO "Detected %d.%03d MHz APIC timer.\n", | 792 | printk(KERN_INFO "Detected %d.%03d MHz APIC timer.\n", |
| 748 | result / 1000 / 1000, result / 1000 % 1000); | 793 | result / 1000 / 1000, result / 1000 % 1000); |
| @@ -872,6 +917,8 @@ void smp_local_timer_interrupt(struct pt_regs *regs) | |||
| 872 | #ifdef CONFIG_SMP | 917 | #ifdef CONFIG_SMP |
| 873 | update_process_times(user_mode(regs)); | 918 | update_process_times(user_mode(regs)); |
| 874 | #endif | 919 | #endif |
| 920 | if (apic_runs_main_timer > 1 && smp_processor_id() == boot_cpu_id) | ||
| 921 | main_timer_handler(regs); | ||
| 875 | /* | 922 | /* |
| 876 | * We take the 'long' return path, and there every subsystem | 923 | * We take the 'long' return path, and there every subsystem |
| 877 | * grabs the appropriate locks (kernel lock/ irq lock). | 924 | * grabs the appropriate locks (kernel lock/ irq lock). |
| @@ -924,7 +971,7 @@ void smp_apic_timer_interrupt(struct pt_regs *regs) | |||
| 924 | * multi-chassis. Use available data to take a good guess. | 971 | * multi-chassis. Use available data to take a good guess. |
| 925 | * If in doubt, go HPET. | 972 | * If in doubt, go HPET. |
| 926 | */ | 973 | */ |
| 927 | __init int oem_force_hpet_timer(void) | 974 | __cpuinit int oem_force_hpet_timer(void) |
| 928 | { | 975 | { |
| 929 | int i, clusters, zeros; | 976 | int i, clusters, zeros; |
| 930 | unsigned id; | 977 | unsigned id; |
| @@ -1081,10 +1128,34 @@ static __init int setup_nolapic(char *str) | |||
| 1081 | 1128 | ||
| 1082 | static __init int setup_noapictimer(char *str) | 1129 | static __init int setup_noapictimer(char *str) |
| 1083 | { | 1130 | { |
| 1131 | if (str[0] != ' ' && str[0] != 0) | ||
| 1132 | return -1; | ||
| 1084 | disable_apic_timer = 1; | 1133 | disable_apic_timer = 1; |
| 1085 | return 0; | 1134 | return 0; |
| 1086 | } | 1135 | } |
| 1087 | 1136 | ||
| 1137 | static __init int setup_apicmaintimer(char *str) | ||
| 1138 | { | ||
| 1139 | apic_runs_main_timer = 1; | ||
| 1140 | nohpet = 1; | ||
| 1141 | return 0; | ||
| 1142 | } | ||
| 1143 | __setup("apicmaintimer", setup_apicmaintimer); | ||
| 1144 | |||
| 1145 | static __init int setup_noapicmaintimer(char *str) | ||
| 1146 | { | ||
| 1147 | apic_runs_main_timer = -1; | ||
| 1148 | return 0; | ||
| 1149 | } | ||
| 1150 | __setup("noapicmaintimer", setup_noapicmaintimer); | ||
| 1151 | |||
| 1152 | static __init int setup_apicpmtimer(char *s) | ||
| 1153 | { | ||
| 1154 | apic_calibrate_pmtmr = 1; | ||
| 1155 | return setup_apicmaintimer(NULL); | ||
| 1156 | } | ||
| 1157 | __setup("apicpmtimer", setup_apicpmtimer); | ||
| 1158 | |||
| 1088 | /* dummy parsing: see setup.c */ | 1159 | /* dummy parsing: see setup.c */ |
| 1089 | 1160 | ||
| 1090 | __setup("disableapic", setup_disableapic); | 1161 | __setup("disableapic", setup_disableapic); |
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index dbdba56e8faa..b150c87a08c6 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S | |||
| @@ -499,7 +499,9 @@ ENTRY(stub_rt_sigreturn) | |||
| 499 | movq %gs:pda_irqstackptr,%rax | 499 | movq %gs:pda_irqstackptr,%rax |
| 500 | cmoveq %rax,%rsp /*todo This needs CFI annotation! */ | 500 | cmoveq %rax,%rsp /*todo This needs CFI annotation! */ |
| 501 | pushq %rdi # save old stack | 501 | pushq %rdi # save old stack |
| 502 | #ifndef CONFIG_DEBUG_INFO | ||
| 502 | CFI_ADJUST_CFA_OFFSET 8 | 503 | CFI_ADJUST_CFA_OFFSET 8 |
| 504 | #endif | ||
| 503 | call \func | 505 | call \func |
| 504 | .endm | 506 | .endm |
| 505 | 507 | ||
| @@ -509,7 +511,9 @@ ENTRY(common_interrupt) | |||
| 509 | /* 0(%rsp): oldrsp-ARGOFFSET */ | 511 | /* 0(%rsp): oldrsp-ARGOFFSET */ |
| 510 | ret_from_intr: | 512 | ret_from_intr: |
| 511 | popq %rdi | 513 | popq %rdi |
| 514 | #ifndef CONFIG_DEBUG_INFO | ||
| 512 | CFI_ADJUST_CFA_OFFSET -8 | 515 | CFI_ADJUST_CFA_OFFSET -8 |
| 516 | #endif | ||
| 513 | cli | 517 | cli |
| 514 | decl %gs:pda_irqcount | 518 | decl %gs:pda_irqcount |
| 515 | #ifdef CONFIG_DEBUG_INFO | 519 | #ifdef CONFIG_DEBUG_INFO |
| @@ -922,7 +926,7 @@ KPROBE_ENTRY(debug) | |||
| 922 | .previous .text | 926 | .previous .text |
| 923 | 927 | ||
| 924 | /* runs on exception stack */ | 928 | /* runs on exception stack */ |
| 925 | ENTRY(nmi) | 929 | KPROBE_ENTRY(nmi) |
| 926 | INTR_FRAME | 930 | INTR_FRAME |
| 927 | pushq $-1 | 931 | pushq $-1 |
| 928 | CFI_ADJUST_CFA_OFFSET 8 | 932 | CFI_ADJUST_CFA_OFFSET 8 |
| @@ -969,6 +973,7 @@ paranoid_schedule: | |||
| 969 | cli | 973 | cli |
| 970 | jmp paranoid_userspace | 974 | jmp paranoid_userspace |
| 971 | CFI_ENDPROC | 975 | CFI_ENDPROC |
| 976 | .previous .text | ||
| 972 | 977 | ||
| 973 | KPROBE_ENTRY(int3) | 978 | KPROBE_ENTRY(int3) |
| 974 | INTR_FRAME | 979 | INTR_FRAME |
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 1a5060b434b8..4282d72b2a26 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c | |||
| @@ -304,6 +304,14 @@ void __init check_ioapic(void) | |||
| 304 | #endif | 304 | #endif |
| 305 | /* RED-PEN skip them on mptables too? */ | 305 | /* RED-PEN skip them on mptables too? */ |
| 306 | return; | 306 | return; |
| 307 | case PCI_VENDOR_ID_ATI: | ||
| 308 | if (apic_runs_main_timer != 0) | ||
| 309 | break; | ||
| 310 | printk(KERN_INFO | ||
| 311 | "ATI board detected. Using APIC/PM timer.\n"); | ||
| 312 | apic_runs_main_timer = 1; | ||
| 313 | nohpet = 1; | ||
| 314 | return; | ||
| 307 | } | 315 | } |
| 308 | 316 | ||
| 309 | /* No multi-function device? */ | 317 | /* No multi-function device? */ |
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index 13a2eada6c95..b8b9529fa89e 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c | |||
| @@ -380,7 +380,7 @@ static void __cpuinit mce_cpu_features(struct cpuinfo_x86 *c) | |||
| 380 | */ | 380 | */ |
| 381 | void __cpuinit mcheck_init(struct cpuinfo_x86 *c) | 381 | void __cpuinit mcheck_init(struct cpuinfo_x86 *c) |
| 382 | { | 382 | { |
| 383 | static cpumask_t mce_cpus __initdata = CPU_MASK_NONE; | 383 | static cpumask_t mce_cpus = CPU_MASK_NONE; |
| 384 | 384 | ||
| 385 | mce_cpu_quirks(c); | 385 | mce_cpu_quirks(c); |
| 386 | 386 | ||
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index 5fae6f0cd994..8be407a1f62d 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/sysdev.h> | 24 | #include <linux/sysdev.h> |
| 25 | #include <linux/nmi.h> | 25 | #include <linux/nmi.h> |
| 26 | #include <linux/sysctl.h> | 26 | #include <linux/sysctl.h> |
| 27 | #include <linux/kprobes.h> | ||
| 27 | 28 | ||
| 28 | #include <asm/smp.h> | 29 | #include <asm/smp.h> |
| 29 | #include <asm/mtrr.h> | 30 | #include <asm/mtrr.h> |
| @@ -468,7 +469,7 @@ void touch_nmi_watchdog (void) | |||
| 468 | touch_softlockup_watchdog(); | 469 | touch_softlockup_watchdog(); |
| 469 | } | 470 | } |
| 470 | 471 | ||
| 471 | void nmi_watchdog_tick (struct pt_regs * regs, unsigned reason) | 472 | void __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) |
| 472 | { | 473 | { |
| 473 | int sum; | 474 | int sum; |
| 474 | int touched = 0; | 475 | int touched = 0; |
| @@ -512,14 +513,14 @@ void nmi_watchdog_tick (struct pt_regs * regs, unsigned reason) | |||
| 512 | } | 513 | } |
| 513 | } | 514 | } |
| 514 | 515 | ||
| 515 | static int dummy_nmi_callback(struct pt_regs * regs, int cpu) | 516 | static __kprobes int dummy_nmi_callback(struct pt_regs * regs, int cpu) |
| 516 | { | 517 | { |
| 517 | return 0; | 518 | return 0; |
| 518 | } | 519 | } |
| 519 | 520 | ||
| 520 | static nmi_callback_t nmi_callback = dummy_nmi_callback; | 521 | static nmi_callback_t nmi_callback = dummy_nmi_callback; |
| 521 | 522 | ||
| 522 | asmlinkage void do_nmi(struct pt_regs * regs, long error_code) | 523 | asmlinkage __kprobes void do_nmi(struct pt_regs * regs, long error_code) |
| 523 | { | 524 | { |
| 524 | int cpu = safe_smp_processor_id(); | 525 | int cpu = safe_smp_processor_id(); |
| 525 | 526 | ||
diff --git a/arch/x86_64/kernel/pci-dma.c b/arch/x86_64/kernel/pci-dma.c index 2f5d8328e2b9..4ed391edd47a 100644 --- a/arch/x86_64/kernel/pci-dma.c +++ b/arch/x86_64/kernel/pci-dma.c | |||
| @@ -107,6 +107,9 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, | |||
| 107 | goto again; | 107 | goto again; |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | /* Let low level make its own zone decisions */ | ||
| 111 | gfp &= ~(GFP_DMA32|GFP_DMA); | ||
| 112 | |||
| 110 | if (dma_ops->alloc_coherent) | 113 | if (dma_ops->alloc_coherent) |
| 111 | return dma_ops->alloc_coherent(dev, size, | 114 | return dma_ops->alloc_coherent(dev, size, |
| 112 | dma_handle, gfp); | 115 | dma_handle, gfp); |
diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c index c37fc7726ba6..2fe23a6c361b 100644 --- a/arch/x86_64/kernel/pci-gart.c +++ b/arch/x86_64/kernel/pci-gart.c | |||
| @@ -457,9 +457,12 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) | |||
| 457 | error: | 457 | error: |
| 458 | flush_gart(NULL); | 458 | flush_gart(NULL); |
| 459 | gart_unmap_sg(dev, sg, nents, dir); | 459 | gart_unmap_sg(dev, sg, nents, dir); |
| 460 | /* When it was forced try again unforced */ | 460 | /* When it was forced or merged try again in a dumb way */ |
| 461 | if (force_iommu) | 461 | if (force_iommu || iommu_merge) { |
| 462 | return dma_map_sg_nonforce(dev, sg, nents, dir); | 462 | out = dma_map_sg_nonforce(dev, sg, nents, dir); |
| 463 | if (out > 0) | ||
| 464 | return out; | ||
| 465 | } | ||
| 463 | if (panic_on_overflow) | 466 | if (panic_on_overflow) |
| 464 | panic("dma_map_sg: overflow on %lu pages\n", pages); | 467 | panic("dma_map_sg: overflow on %lu pages\n", pages); |
| 465 | iommu_full(dev, pages << PAGE_SHIFT, dir); | 468 | iommu_full(dev, pages << PAGE_SHIFT, dir); |
| @@ -642,9 +645,18 @@ static int __init pci_iommu_init(void) | |||
| 642 | (no_agp && init_k8_gatt(&info) < 0)) { | 645 | (no_agp && init_k8_gatt(&info) < 0)) { |
| 643 | no_iommu = 1; | 646 | no_iommu = 1; |
| 644 | no_iommu_init(); | 647 | no_iommu_init(); |
| 648 | printk(KERN_INFO "PCI-DMA: Disabling IOMMU.\n"); | ||
| 649 | if (end_pfn > MAX_DMA32_PFN) { | ||
| 650 | printk(KERN_ERR "WARNING more than 4GB of memory " | ||
| 651 | "but IOMMU not compiled in.\n" | ||
| 652 | KERN_ERR "WARNING 32bit PCI may malfunction.\n" | ||
| 653 | KERN_ERR "You might want to enable " | ||
| 654 | "CONFIG_GART_IOMMU\n"); | ||
| 655 | } | ||
| 645 | return -1; | 656 | return -1; |
| 646 | } | 657 | } |
| 647 | 658 | ||
| 659 | printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n"); | ||
| 648 | aper_size = info.aper_size * 1024 * 1024; | 660 | aper_size = info.aper_size * 1024 * 1024; |
| 649 | iommu_size = check_iommu_size(info.aper_base, aper_size); | 661 | iommu_size = check_iommu_size(info.aper_base, aper_size); |
| 650 | iommu_pages = iommu_size >> PAGE_SHIFT; | 662 | iommu_pages = iommu_size >> PAGE_SHIFT; |
| @@ -718,7 +730,6 @@ static int __init pci_iommu_init(void) | |||
| 718 | 730 | ||
| 719 | flush_gart(NULL); | 731 | flush_gart(NULL); |
| 720 | 732 | ||
| 721 | printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n"); | ||
| 722 | dma_ops = &gart_dma_ops; | 733 | dma_ops = &gart_dma_ops; |
| 723 | 734 | ||
| 724 | return 0; | 735 | return 0; |
diff --git a/arch/x86_64/kernel/pci-nommu.c b/arch/x86_64/kernel/pci-nommu.c index e41564975195..44adcc2d5e5b 100644 --- a/arch/x86_64/kernel/pci-nommu.c +++ b/arch/x86_64/kernel/pci-nommu.c | |||
| @@ -88,12 +88,5 @@ void __init no_iommu_init(void) | |||
| 88 | { | 88 | { |
| 89 | if (dma_ops) | 89 | if (dma_ops) |
| 90 | return; | 90 | return; |
| 91 | printk(KERN_INFO "PCI-DMA: Disabling IOMMU.\n"); | ||
| 92 | dma_ops = &nommu_dma_ops; | 91 | dma_ops = &nommu_dma_ops; |
| 93 | if (end_pfn > MAX_DMA32_PFN) { | ||
| 94 | printk(KERN_ERR | ||
| 95 | "WARNING more than 4GB of memory but IOMMU not compiled in.\n" | ||
| 96 | KERN_ERR "WARNING 32bit PCI may malfunction.\n" | ||
| 97 | KERN_ERR "You might want to enable CONFIG_GART_IOMMU\n"); | ||
| 98 | } | ||
| 99 | } | 92 | } |
diff --git a/arch/x86_64/kernel/pci-swiotlb.c b/arch/x86_64/kernel/pci-swiotlb.c index 3569a25ad7fb..990ed67896f2 100644 --- a/arch/x86_64/kernel/pci-swiotlb.c +++ b/arch/x86_64/kernel/pci-swiotlb.c | |||
| @@ -35,8 +35,8 @@ void pci_swiotlb_init(void) | |||
| 35 | (end_pfn > MAX_DMA32_PFN || force_iommu)) | 35 | (end_pfn > MAX_DMA32_PFN || force_iommu)) |
| 36 | swiotlb = 1; | 36 | swiotlb = 1; |
| 37 | if (swiotlb) { | 37 | if (swiotlb) { |
| 38 | swiotlb_init(); | ||
| 39 | printk(KERN_INFO "PCI-DMA: Using software bounce buffering for IO (SWIOTLB)\n"); | 38 | printk(KERN_INFO "PCI-DMA: Using software bounce buffering for IO (SWIOTLB)\n"); |
| 39 | swiotlb_init(); | ||
| 40 | dma_ops = &swiotlb_dma_ops; | 40 | dma_ops = &swiotlb_dma_ops; |
| 41 | } | 41 | } |
| 42 | } | 42 | } |
diff --git a/arch/x86_64/kernel/pmtimer.c b/arch/x86_64/kernel/pmtimer.c index feb5f108dd26..5c51d10408a6 100644 --- a/arch/x86_64/kernel/pmtimer.c +++ b/arch/x86_64/kernel/pmtimer.c | |||
| @@ -80,6 +80,31 @@ int pmtimer_mark_offset(void) | |||
| 80 | return lost - 1; | 80 | return lost - 1; |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | static unsigned pmtimer_wait_tick(void) | ||
| 84 | { | ||
| 85 | u32 a, b; | ||
| 86 | for (a = b = inl(pmtmr_ioport) & ACPI_PM_MASK; | ||
| 87 | a == b; | ||
| 88 | b = inl(pmtmr_ioport) & ACPI_PM_MASK) | ||
| 89 | ; | ||
| 90 | return b; | ||
| 91 | } | ||
| 92 | |||
| 93 | /* note: wait time is rounded up to one tick */ | ||
| 94 | void pmtimer_wait(unsigned us) | ||
| 95 | { | ||
| 96 | u32 a, b; | ||
| 97 | a = pmtimer_wait_tick(); | ||
| 98 | do { | ||
| 99 | b = inl(pmtmr_ioport); | ||
| 100 | } while (cyc2us(b - a) < us); | ||
| 101 | } | ||
| 102 | |||
| 103 | void pmtimer_resume(void) | ||
| 104 | { | ||
| 105 | last_pmtmr_tick = inl(pmtmr_ioport); | ||
| 106 | } | ||
| 107 | |||
| 83 | unsigned int do_gettimeoffset_pm(void) | 108 | unsigned int do_gettimeoffset_pm(void) |
| 84 | { | 109 | { |
| 85 | u32 now, offset, delta = 0; | 110 | u32 now, offset, delta = 0; |
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index 8ded407e4a94..22a05dec81a2 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c | |||
| @@ -516,8 +516,10 @@ out: | |||
| 516 | * This could still be optimized: | 516 | * This could still be optimized: |
| 517 | * - fold all the options into a flag word and test it with a single test. | 517 | * - fold all the options into a flag word and test it with a single test. |
| 518 | * - could test fs/gs bitsliced | 518 | * - could test fs/gs bitsliced |
| 519 | * | ||
| 520 | * Kprobes not supported here. Set the probe on schedule instead. | ||
| 519 | */ | 521 | */ |
| 520 | struct task_struct * | 522 | __kprobes struct task_struct * |
| 521 | __switch_to(struct task_struct *prev_p, struct task_struct *next_p) | 523 | __switch_to(struct task_struct *prev_p, struct task_struct *next_p) |
| 522 | { | 524 | { |
| 523 | struct thread_struct *prev = &prev_p->thread, | 525 | struct thread_struct *prev = &prev_p->thread, |
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 28895c03cb11..9435ab7d6fb8 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c | |||
| @@ -94,7 +94,6 @@ unsigned long saved_video_mode; | |||
| 94 | /* | 94 | /* |
| 95 | * Setup options | 95 | * Setup options |
| 96 | */ | 96 | */ |
| 97 | struct drive_info_struct { char dummy[32]; } drive_info; | ||
| 98 | struct screen_info screen_info; | 97 | struct screen_info screen_info; |
| 99 | struct sys_desc_table_struct { | 98 | struct sys_desc_table_struct { |
| 100 | unsigned short length; | 99 | unsigned short length; |
| @@ -572,7 +571,6 @@ void __init setup_arch(char **cmdline_p) | |||
| 572 | unsigned long kernel_end; | 571 | unsigned long kernel_end; |
| 573 | 572 | ||
| 574 | ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); | 573 | ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); |
| 575 | drive_info = DRIVE_INFO; | ||
| 576 | screen_info = SCREEN_INFO; | 574 | screen_info = SCREEN_INFO; |
| 577 | edid_info = EDID_INFO; | 575 | edid_info = EDID_INFO; |
| 578 | saved_video_mode = SAVED_VIDEO_MODE; | 576 | saved_video_mode = SAVED_VIDEO_MODE; |
| @@ -741,7 +739,7 @@ void __init setup_arch(char **cmdline_p) | |||
| 741 | e820_setup_gap(); | 739 | e820_setup_gap(); |
| 742 | 740 | ||
| 743 | #ifdef CONFIG_GART_IOMMU | 741 | #ifdef CONFIG_GART_IOMMU |
| 744 | iommu_hole_init(); | 742 | iommu_hole_init(); |
| 745 | #endif | 743 | #endif |
| 746 | 744 | ||
| 747 | #ifdef CONFIG_VT | 745 | #ifdef CONFIG_VT |
| @@ -877,6 +875,7 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c) | |||
| 877 | static int __init init_amd(struct cpuinfo_x86 *c) | 875 | static int __init init_amd(struct cpuinfo_x86 *c) |
| 878 | { | 876 | { |
| 879 | int r; | 877 | int r; |
| 878 | unsigned level; | ||
| 880 | 879 | ||
| 881 | #ifdef CONFIG_SMP | 880 | #ifdef CONFIG_SMP |
| 882 | unsigned long value; | 881 | unsigned long value; |
| @@ -899,6 +898,11 @@ static int __init init_amd(struct cpuinfo_x86 *c) | |||
| 899 | 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */ | 898 | 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */ |
| 900 | clear_bit(0*32+31, &c->x86_capability); | 899 | clear_bit(0*32+31, &c->x86_capability); |
| 901 | 900 | ||
| 901 | /* On C+ stepping K8 rep microcode works well for copy/memset */ | ||
| 902 | level = cpuid_eax(1); | ||
| 903 | if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)) | ||
| 904 | set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability); | ||
| 905 | |||
| 902 | r = get_model_name(c); | 906 | r = get_model_name(c); |
| 903 | if (!r) { | 907 | if (!r) { |
| 904 | switch (c->x86) { | 908 | switch (c->x86) { |
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index a28756ef7cef..67e4e28f4df8 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c | |||
| @@ -59,6 +59,7 @@ | |||
| 59 | #include <asm/nmi.h> | 59 | #include <asm/nmi.h> |
| 60 | #include <asm/irq.h> | 60 | #include <asm/irq.h> |
| 61 | #include <asm/hw_irq.h> | 61 | #include <asm/hw_irq.h> |
| 62 | #include <asm/numa.h> | ||
| 62 | 63 | ||
| 63 | /* Number of siblings per CPU package */ | 64 | /* Number of siblings per CPU package */ |
| 64 | int smp_num_siblings = 1; | 65 | int smp_num_siblings = 1; |
| @@ -890,6 +891,7 @@ do_rest: | |||
| 890 | if (boot_error) { | 891 | if (boot_error) { |
| 891 | cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */ | 892 | cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */ |
| 892 | clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */ | 893 | clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */ |
| 894 | clear_node_cpumask(cpu); /* was set by numa_add_cpu */ | ||
| 893 | cpu_clear(cpu, cpu_present_map); | 895 | cpu_clear(cpu, cpu_present_map); |
| 894 | cpu_clear(cpu, cpu_possible_map); | 896 | cpu_clear(cpu, cpu_possible_map); |
| 895 | x86_cpu_to_apicid[cpu] = BAD_APICID; | 897 | x86_cpu_to_apicid[cpu] = BAD_APICID; |
| @@ -1187,6 +1189,7 @@ void remove_cpu_from_maps(void) | |||
| 1187 | cpu_clear(cpu, cpu_callout_map); | 1189 | cpu_clear(cpu, cpu_callout_map); |
| 1188 | cpu_clear(cpu, cpu_callin_map); | 1190 | cpu_clear(cpu, cpu_callin_map); |
| 1189 | clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */ | 1191 | clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */ |
| 1192 | clear_node_cpumask(cpu); | ||
| 1190 | } | 1193 | } |
| 1191 | 1194 | ||
| 1192 | int __cpu_disable(void) | 1195 | int __cpu_disable(void) |
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index f8c47c688443..dba7237be5c1 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c | |||
| @@ -51,7 +51,7 @@ extern int using_apic_timer; | |||
| 51 | DEFINE_SPINLOCK(rtc_lock); | 51 | DEFINE_SPINLOCK(rtc_lock); |
| 52 | DEFINE_SPINLOCK(i8253_lock); | 52 | DEFINE_SPINLOCK(i8253_lock); |
| 53 | 53 | ||
| 54 | static int nohpet __initdata = 0; | 54 | int nohpet __initdata = 0; |
| 55 | static int notsc __initdata = 0; | 55 | static int notsc __initdata = 0; |
| 56 | 56 | ||
| 57 | #undef HPET_HACK_ENABLE_DANGEROUS | 57 | #undef HPET_HACK_ENABLE_DANGEROUS |
| @@ -345,7 +345,7 @@ static noinline void handle_lost_ticks(int lost, struct pt_regs *regs) | |||
| 345 | #endif | 345 | #endif |
| 346 | } | 346 | } |
| 347 | 347 | ||
| 348 | static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 348 | void main_timer_handler(struct pt_regs *regs) |
| 349 | { | 349 | { |
| 350 | static unsigned long rtc_update = 0; | 350 | static unsigned long rtc_update = 0; |
| 351 | unsigned long tsc; | 351 | unsigned long tsc; |
| @@ -458,12 +458,17 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
| 458 | } | 458 | } |
| 459 | 459 | ||
| 460 | write_sequnlock(&xtime_lock); | 460 | write_sequnlock(&xtime_lock); |
| 461 | } | ||
| 461 | 462 | ||
| 463 | static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | ||
| 464 | { | ||
| 465 | if (apic_runs_main_timer > 1) | ||
| 466 | return IRQ_HANDLED; | ||
| 467 | main_timer_handler(regs); | ||
| 462 | #ifdef CONFIG_X86_LOCAL_APIC | 468 | #ifdef CONFIG_X86_LOCAL_APIC |
| 463 | if (using_apic_timer) | 469 | if (using_apic_timer) |
| 464 | smp_send_timer_broadcast_ipi(); | 470 | smp_send_timer_broadcast_ipi(); |
| 465 | #endif | 471 | #endif |
| 466 | |||
| 467 | return IRQ_HANDLED; | 472 | return IRQ_HANDLED; |
| 468 | } | 473 | } |
| 469 | 474 | ||
| @@ -743,7 +748,7 @@ static __init int late_hpet_init(void) | |||
| 743 | * Timer0 and Timer1 is used by platform. | 748 | * Timer0 and Timer1 is used by platform. |
| 744 | */ | 749 | */ |
| 745 | hd.hd_phys_address = vxtime.hpet_address; | 750 | hd.hd_phys_address = vxtime.hpet_address; |
| 746 | hd.hd_address = (void *)fix_to_virt(FIX_HPET_BASE); | 751 | hd.hd_address = (void __iomem *)fix_to_virt(FIX_HPET_BASE); |
| 747 | hd.hd_nirqs = ntimer; | 752 | hd.hd_nirqs = ntimer; |
| 748 | hd.hd_flags = HPET_DATA_PLATFORM; | 753 | hd.hd_flags = HPET_DATA_PLATFORM; |
| 749 | hpet_reserve_timer(&hd, 0); | 754 | hpet_reserve_timer(&hd, 0); |
| @@ -843,17 +848,43 @@ static int hpet_reenable(void) | |||
| 843 | return hpet_timer_stop_set_go(hpet_tick); | 848 | return hpet_timer_stop_set_go(hpet_tick); |
| 844 | } | 849 | } |
| 845 | 850 | ||
| 846 | void __init pit_init(void) | 851 | #define PIT_MODE 0x43 |
| 852 | #define PIT_CH0 0x40 | ||
| 853 | |||
| 854 | static void __init __pit_init(int val, u8 mode) | ||
| 847 | { | 855 | { |
| 848 | unsigned long flags; | 856 | unsigned long flags; |
| 849 | 857 | ||
| 850 | spin_lock_irqsave(&i8253_lock, flags); | 858 | spin_lock_irqsave(&i8253_lock, flags); |
| 851 | outb_p(0x34, 0x43); /* binary, mode 2, LSB/MSB, ch 0 */ | 859 | outb_p(mode, PIT_MODE); |
| 852 | outb_p(LATCH & 0xff, 0x40); /* LSB */ | 860 | outb_p(val & 0xff, PIT_CH0); /* LSB */ |
| 853 | outb_p(LATCH >> 8, 0x40); /* MSB */ | 861 | outb_p(val >> 8, PIT_CH0); /* MSB */ |
| 854 | spin_unlock_irqrestore(&i8253_lock, flags); | 862 | spin_unlock_irqrestore(&i8253_lock, flags); |
| 855 | } | 863 | } |
| 856 | 864 | ||
| 865 | void __init pit_init(void) | ||
| 866 | { | ||
| 867 | __pit_init(LATCH, 0x34); /* binary, mode 2, LSB/MSB, ch 0 */ | ||
| 868 | } | ||
| 869 | |||
| 870 | void __init pit_stop_interrupt(void) | ||
| 871 | { | ||
| 872 | __pit_init(0, 0x30); /* mode 0 */ | ||
| 873 | } | ||
| 874 | |||
| 875 | void __init stop_timer_interrupt(void) | ||
| 876 | { | ||
| 877 | char *name; | ||
| 878 | if (vxtime.hpet_address) { | ||
| 879 | name = "HPET"; | ||
| 880 | hpet_timer_stop_set_go(0); | ||
| 881 | } else { | ||
| 882 | name = "PIT"; | ||
| 883 | pit_stop_interrupt(); | ||
| 884 | } | ||
| 885 | printk(KERN_INFO "timer: %s interrupt stopped.\n", name); | ||
| 886 | } | ||
| 887 | |||
| 857 | int __init time_setup(char *str) | 888 | int __init time_setup(char *str) |
| 858 | { | 889 | { |
| 859 | report_lost_ticks = 1; | 890 | report_lost_ticks = 1; |
| @@ -932,7 +963,7 @@ void __init time_init(void) | |||
| 932 | * Make an educated guess if the TSC is trustworthy and synchronized | 963 | * Make an educated guess if the TSC is trustworthy and synchronized |
| 933 | * over all CPUs. | 964 | * over all CPUs. |
| 934 | */ | 965 | */ |
| 935 | __init int unsynchronized_tsc(void) | 966 | __cpuinit int unsynchronized_tsc(void) |
| 936 | { | 967 | { |
| 937 | #ifdef CONFIG_SMP | 968 | #ifdef CONFIG_SMP |
| 938 | if (oem_force_hpet_timer()) | 969 | if (oem_force_hpet_timer()) |
| @@ -1016,9 +1047,21 @@ static int timer_resume(struct sys_device *dev) | |||
| 1016 | write_seqlock_irqsave(&xtime_lock,flags); | 1047 | write_seqlock_irqsave(&xtime_lock,flags); |
| 1017 | xtime.tv_sec = sec; | 1048 | xtime.tv_sec = sec; |
| 1018 | xtime.tv_nsec = 0; | 1049 | xtime.tv_nsec = 0; |
| 1050 | if (vxtime.mode == VXTIME_HPET) { | ||
| 1051 | if (hpet_use_timer) | ||
| 1052 | vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick; | ||
| 1053 | else | ||
| 1054 | vxtime.last = hpet_readl(HPET_COUNTER); | ||
| 1055 | #ifdef CONFIG_X86_PM_TIMER | ||
| 1056 | } else if (vxtime.mode == VXTIME_PMTMR) { | ||
| 1057 | pmtimer_resume(); | ||
| 1058 | #endif | ||
| 1059 | } else | ||
| 1060 | vxtime.last_tsc = get_cycles_sync(); | ||
| 1019 | write_sequnlock_irqrestore(&xtime_lock,flags); | 1061 | write_sequnlock_irqrestore(&xtime_lock,flags); |
| 1020 | jiffies += sleep_length; | 1062 | jiffies += sleep_length; |
| 1021 | wall_jiffies += sleep_length; | 1063 | wall_jiffies += sleep_length; |
| 1064 | monotonic_base += sleep_length * (NSEC_PER_SEC/HZ); | ||
| 1022 | touch_softlockup_watchdog(); | 1065 | touch_softlockup_watchdog(); |
| 1023 | return 0; | 1066 | return 0; |
| 1024 | } | 1067 | } |
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 8bb0aeda78b9..ee1b2da9e5e7 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c | |||
| @@ -372,7 +372,7 @@ void out_of_line_bug(void) | |||
| 372 | static DEFINE_SPINLOCK(die_lock); | 372 | static DEFINE_SPINLOCK(die_lock); |
| 373 | static int die_owner = -1; | 373 | static int die_owner = -1; |
| 374 | 374 | ||
| 375 | unsigned long oops_begin(void) | 375 | unsigned __kprobes long oops_begin(void) |
| 376 | { | 376 | { |
| 377 | int cpu = safe_smp_processor_id(); | 377 | int cpu = safe_smp_processor_id(); |
| 378 | unsigned long flags; | 378 | unsigned long flags; |
| @@ -391,7 +391,7 @@ unsigned long oops_begin(void) | |||
| 391 | return flags; | 391 | return flags; |
| 392 | } | 392 | } |
| 393 | 393 | ||
| 394 | void oops_end(unsigned long flags) | 394 | void __kprobes oops_end(unsigned long flags) |
| 395 | { | 395 | { |
| 396 | die_owner = -1; | 396 | die_owner = -1; |
| 397 | bust_spinlocks(0); | 397 | bust_spinlocks(0); |
| @@ -400,7 +400,7 @@ void oops_end(unsigned long flags) | |||
| 400 | panic("Oops"); | 400 | panic("Oops"); |
| 401 | } | 401 | } |
| 402 | 402 | ||
| 403 | void __die(const char * str, struct pt_regs * regs, long err) | 403 | void __kprobes __die(const char * str, struct pt_regs * regs, long err) |
| 404 | { | 404 | { |
| 405 | static int die_counter; | 405 | static int die_counter; |
| 406 | printk(KERN_EMERG "%s: %04lx [%u] ", str, err & 0xffff,++die_counter); | 406 | printk(KERN_EMERG "%s: %04lx [%u] ", str, err & 0xffff,++die_counter); |
| @@ -432,7 +432,7 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
| 432 | do_exit(SIGSEGV); | 432 | do_exit(SIGSEGV); |
| 433 | } | 433 | } |
| 434 | 434 | ||
| 435 | void die_nmi(char *str, struct pt_regs *regs) | 435 | void __kprobes die_nmi(char *str, struct pt_regs *regs) |
| 436 | { | 436 | { |
| 437 | unsigned long flags = oops_begin(); | 437 | unsigned long flags = oops_begin(); |
| 438 | 438 | ||
| @@ -575,7 +575,8 @@ asmlinkage void __kprobes do_general_protection(struct pt_regs * regs, | |||
| 575 | } | 575 | } |
| 576 | } | 576 | } |
| 577 | 577 | ||
| 578 | static void mem_parity_error(unsigned char reason, struct pt_regs * regs) | 578 | static __kprobes void |
| 579 | mem_parity_error(unsigned char reason, struct pt_regs * regs) | ||
| 579 | { | 580 | { |
| 580 | printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n"); | 581 | printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n"); |
| 581 | printk("You probably have a hardware problem with your RAM chips\n"); | 582 | printk("You probably have a hardware problem with your RAM chips\n"); |
| @@ -585,7 +586,8 @@ static void mem_parity_error(unsigned char reason, struct pt_regs * regs) | |||
| 585 | outb(reason, 0x61); | 586 | outb(reason, 0x61); |
| 586 | } | 587 | } |
| 587 | 588 | ||
| 588 | static void io_check_error(unsigned char reason, struct pt_regs * regs) | 589 | static __kprobes void |
| 590 | io_check_error(unsigned char reason, struct pt_regs * regs) | ||
| 589 | { | 591 | { |
| 590 | printk("NMI: IOCK error (debug interrupt?)\n"); | 592 | printk("NMI: IOCK error (debug interrupt?)\n"); |
| 591 | show_registers(regs); | 593 | show_registers(regs); |
| @@ -598,7 +600,8 @@ static void io_check_error(unsigned char reason, struct pt_regs * regs) | |||
| 598 | outb(reason, 0x61); | 600 | outb(reason, 0x61); |
| 599 | } | 601 | } |
| 600 | 602 | ||
| 601 | static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs) | 603 | static __kprobes void |
| 604 | unknown_nmi_error(unsigned char reason, struct pt_regs * regs) | ||
| 602 | { printk("Uhhuh. NMI received for unknown reason %02x.\n", reason); | 605 | { printk("Uhhuh. NMI received for unknown reason %02x.\n", reason); |
| 603 | printk("Dazed and confused, but trying to continue\n"); | 606 | printk("Dazed and confused, but trying to continue\n"); |
| 604 | printk("Do you have a strange power saving mode enabled?\n"); | 607 | printk("Do you have a strange power saving mode enabled?\n"); |
| @@ -606,7 +609,7 @@ static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs) | |||
| 606 | 609 | ||
| 607 | /* Runs on IST stack. This code must keep interrupts off all the time. | 610 | /* Runs on IST stack. This code must keep interrupts off all the time. |
| 608 | Nested NMIs are prevented by the CPU. */ | 611 | Nested NMIs are prevented by the CPU. */ |
| 609 | asmlinkage void default_do_nmi(struct pt_regs *regs) | 612 | asmlinkage __kprobes void default_do_nmi(struct pt_regs *regs) |
| 610 | { | 613 | { |
| 611 | unsigned char reason = 0; | 614 | unsigned char reason = 0; |
| 612 | int cpu; | 615 | int cpu; |
| @@ -658,7 +661,7 @@ asmlinkage void __kprobes do_int3(struct pt_regs * regs, long error_code) | |||
| 658 | /* Help handler running on IST stack to switch back to user stack | 661 | /* Help handler running on IST stack to switch back to user stack |
| 659 | for scheduling or signal handling. The actual stack switch is done in | 662 | for scheduling or signal handling. The actual stack switch is done in |
| 660 | entry.S */ | 663 | entry.S */ |
| 661 | asmlinkage struct pt_regs *sync_regs(struct pt_regs *eregs) | 664 | asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) |
| 662 | { | 665 | { |
| 663 | struct pt_regs *regs = eregs; | 666 | struct pt_regs *regs = eregs; |
| 664 | /* Did already sync */ | 667 | /* Did already sync */ |
diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index b0eed1faf740..74db0062d4a2 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S | |||
| @@ -172,13 +172,15 @@ SECTIONS | |||
| 172 | . = ALIGN(4096); | 172 | . = ALIGN(4096); |
| 173 | __initramfs_start = .; | 173 | __initramfs_start = .; |
| 174 | .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) } | 174 | .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { *(.init.ramfs) } |
| 175 | __initramfs_end = .; | 175 | __initramfs_end = .; |
| 176 | . = ALIGN(32); | 176 | /* temporary here to work around NR_CPUS. If you see this comment in 2.6.17+ |
| 177 | complain */ | ||
| 178 | . = ALIGN(4096); | ||
| 179 | __init_end = .; | ||
| 180 | . = ALIGN(CONFIG_X86_L1_CACHE_BYTES); | ||
| 177 | __per_cpu_start = .; | 181 | __per_cpu_start = .; |
| 178 | .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) } | 182 | .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { *(.data.percpu) } |
| 179 | __per_cpu_end = .; | 183 | __per_cpu_end = .; |
| 180 | . = ALIGN(4096); | ||
| 181 | __init_end = .; | ||
| 182 | 184 | ||
| 183 | . = ALIGN(4096); | 185 | . = ALIGN(4096); |
| 184 | __nosave_begin = .; | 186 | __nosave_begin = .; |
diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c index b614d54d2ae4..3496abc8d372 100644 --- a/arch/x86_64/kernel/x8664_ksyms.c +++ b/arch/x86_64/kernel/x8664_ksyms.c | |||
| @@ -39,11 +39,6 @@ extern void __write_lock_failed(rwlock_t *rw); | |||
| 39 | extern void __read_lock_failed(rwlock_t *rw); | 39 | extern void __read_lock_failed(rwlock_t *rw); |
| 40 | #endif | 40 | #endif |
| 41 | 41 | ||
| 42 | #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE) | ||
| 43 | extern struct drive_info_struct drive_info; | ||
| 44 | EXPORT_SYMBOL(drive_info); | ||
| 45 | #endif | ||
| 46 | |||
| 47 | /* platform dependent support */ | 42 | /* platform dependent support */ |
| 48 | EXPORT_SYMBOL(boot_cpu_data); | 43 | EXPORT_SYMBOL(boot_cpu_data); |
| 49 | //EXPORT_SYMBOL(dump_fpu); | 44 | //EXPORT_SYMBOL(dump_fpu); |
diff --git a/arch/x86_64/lib/clear_page.S b/arch/x86_64/lib/clear_page.S index 43d9fa136180..1f81b79b796c 100644 --- a/arch/x86_64/lib/clear_page.S +++ b/arch/x86_64/lib/clear_page.S | |||
| @@ -5,8 +5,46 @@ | |||
| 5 | .globl clear_page | 5 | .globl clear_page |
| 6 | .p2align 4 | 6 | .p2align 4 |
| 7 | clear_page: | 7 | clear_page: |
| 8 | xorl %eax,%eax | ||
| 9 | movl $4096/64,%ecx | ||
| 10 | .p2align 4 | ||
| 11 | .Lloop: | ||
| 12 | decl %ecx | ||
| 13 | #define PUT(x) movq %rax,x*8(%rdi) | ||
| 14 | movq %rax,(%rdi) | ||
| 15 | PUT(1) | ||
| 16 | PUT(2) | ||
| 17 | PUT(3) | ||
| 18 | PUT(4) | ||
| 19 | PUT(5) | ||
| 20 | PUT(6) | ||
| 21 | PUT(7) | ||
| 22 | leaq 64(%rdi),%rdi | ||
| 23 | jnz .Lloop | ||
| 24 | nop | ||
| 25 | ret | ||
| 26 | clear_page_end: | ||
| 27 | |||
| 28 | /* Some CPUs run faster using the string instructions. | ||
| 29 | It is also a lot simpler. Use this when possible */ | ||
| 30 | |||
| 31 | #include <asm/cpufeature.h> | ||
| 32 | |||
| 33 | .section .altinstructions,"a" | ||
| 34 | .align 8 | ||
| 35 | .quad clear_page | ||
| 36 | .quad clear_page_c | ||
| 37 | .byte X86_FEATURE_REP_GOOD | ||
| 38 | .byte clear_page_end-clear_page | ||
| 39 | .byte clear_page_c_end-clear_page_c | ||
| 40 | .previous | ||
| 41 | |||
| 42 | .section .altinstr_replacement,"ax" | ||
| 43 | clear_page_c: | ||
| 8 | movl $4096/8,%ecx | 44 | movl $4096/8,%ecx |
| 9 | xorl %eax,%eax | 45 | xorl %eax,%eax |
| 10 | rep | 46 | rep |
| 11 | stosq | 47 | stosq |
| 12 | ret | 48 | ret |
| 49 | clear_page_c_end: | ||
| 50 | .previous | ||
diff --git a/arch/x86_64/lib/copy_page.S b/arch/x86_64/lib/copy_page.S index 621a19769406..8fa19d96a7ee 100644 --- a/arch/x86_64/lib/copy_page.S +++ b/arch/x86_64/lib/copy_page.S | |||
| @@ -8,7 +8,94 @@ | |||
| 8 | .globl copy_page | 8 | .globl copy_page |
| 9 | .p2align 4 | 9 | .p2align 4 |
| 10 | copy_page: | 10 | copy_page: |
| 11 | subq $3*8,%rsp | ||
| 12 | movq %rbx,(%rsp) | ||
| 13 | movq %r12,1*8(%rsp) | ||
| 14 | movq %r13,2*8(%rsp) | ||
| 15 | |||
| 16 | movl $(4096/64)-5,%ecx | ||
| 17 | .p2align 4 | ||
| 18 | .Loop64: | ||
| 19 | dec %rcx | ||
| 20 | |||
| 21 | movq (%rsi), %rax | ||
| 22 | movq 8 (%rsi), %rbx | ||
| 23 | movq 16 (%rsi), %rdx | ||
| 24 | movq 24 (%rsi), %r8 | ||
| 25 | movq 32 (%rsi), %r9 | ||
| 26 | movq 40 (%rsi), %r10 | ||
| 27 | movq 48 (%rsi), %r11 | ||
| 28 | movq 56 (%rsi), %r12 | ||
| 29 | |||
| 30 | prefetcht0 5*64(%rsi) | ||
| 31 | |||
| 32 | movq %rax, (%rdi) | ||
| 33 | movq %rbx, 8 (%rdi) | ||
| 34 | movq %rdx, 16 (%rdi) | ||
| 35 | movq %r8, 24 (%rdi) | ||
| 36 | movq %r9, 32 (%rdi) | ||
| 37 | movq %r10, 40 (%rdi) | ||
| 38 | movq %r11, 48 (%rdi) | ||
| 39 | movq %r12, 56 (%rdi) | ||
| 40 | |||
| 41 | leaq 64 (%rsi), %rsi | ||
| 42 | leaq 64 (%rdi), %rdi | ||
| 43 | |||
| 44 | jnz .Loop64 | ||
| 45 | |||
| 46 | movl $5,%ecx | ||
| 47 | .p2align 4 | ||
| 48 | .Loop2: | ||
| 49 | decl %ecx | ||
| 50 | |||
| 51 | movq (%rsi), %rax | ||
| 52 | movq 8 (%rsi), %rbx | ||
| 53 | movq 16 (%rsi), %rdx | ||
| 54 | movq 24 (%rsi), %r8 | ||
| 55 | movq 32 (%rsi), %r9 | ||
| 56 | movq 40 (%rsi), %r10 | ||
| 57 | movq 48 (%rsi), %r11 | ||
| 58 | movq 56 (%rsi), %r12 | ||
| 59 | |||
| 60 | movq %rax, (%rdi) | ||
| 61 | movq %rbx, 8 (%rdi) | ||
| 62 | movq %rdx, 16 (%rdi) | ||
| 63 | movq %r8, 24 (%rdi) | ||
| 64 | movq %r9, 32 (%rdi) | ||
| 65 | movq %r10, 40 (%rdi) | ||
| 66 | movq %r11, 48 (%rdi) | ||
| 67 | movq %r12, 56 (%rdi) | ||
| 68 | |||
| 69 | leaq 64(%rdi),%rdi | ||
| 70 | leaq 64(%rsi),%rsi | ||
| 71 | |||
| 72 | jnz .Loop2 | ||
| 73 | |||
| 74 | movq (%rsp),%rbx | ||
| 75 | movq 1*8(%rsp),%r12 | ||
| 76 | movq 2*8(%rsp),%r13 | ||
| 77 | addq $3*8,%rsp | ||
| 78 | ret | ||
| 79 | |||
| 80 | /* Some CPUs run faster using the string copy instructions. | ||
| 81 | It is also a lot simpler. Use this when possible */ | ||
| 82 | |||
| 83 | #include <asm/cpufeature.h> | ||
| 84 | |||
| 85 | .section .altinstructions,"a" | ||
| 86 | .align 8 | ||
| 87 | .quad copy_page | ||
| 88 | .quad copy_page_c | ||
| 89 | .byte X86_FEATURE_REP_GOOD | ||
| 90 | .byte copy_page_c_end-copy_page_c | ||
| 91 | .byte copy_page_c_end-copy_page_c | ||
| 92 | .previous | ||
| 93 | |||
| 94 | .section .altinstr_replacement,"ax" | ||
| 95 | copy_page_c: | ||
| 11 | movl $4096/8,%ecx | 96 | movl $4096/8,%ecx |
| 12 | rep | 97 | rep |
| 13 | movsq | 98 | movsq |
| 14 | ret | 99 | ret |
| 100 | copy_page_c_end: | ||
| 101 | .previous | ||
diff --git a/arch/x86_64/lib/copy_user.S b/arch/x86_64/lib/copy_user.S index 79422b6559c3..f64569b83b54 100644 --- a/arch/x86_64/lib/copy_user.S +++ b/arch/x86_64/lib/copy_user.S | |||
| @@ -4,9 +4,12 @@ | |||
| 4 | * Functions to copy from and to user space. | 4 | * Functions to copy from and to user space. |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #define FIX_ALIGNMENT 1 | ||
| 8 | |||
| 7 | #include <asm/current.h> | 9 | #include <asm/current.h> |
| 8 | #include <asm/asm-offsets.h> | 10 | #include <asm/asm-offsets.h> |
| 9 | #include <asm/thread_info.h> | 11 | #include <asm/thread_info.h> |
| 12 | #include <asm/cpufeature.h> | ||
| 10 | 13 | ||
| 11 | /* Standard copy_to_user with segment limit checking */ | 14 | /* Standard copy_to_user with segment limit checking */ |
| 12 | .globl copy_to_user | 15 | .globl copy_to_user |
| @@ -18,7 +21,23 @@ copy_to_user: | |||
| 18 | jc bad_to_user | 21 | jc bad_to_user |
| 19 | cmpq threadinfo_addr_limit(%rax),%rcx | 22 | cmpq threadinfo_addr_limit(%rax),%rcx |
| 20 | jae bad_to_user | 23 | jae bad_to_user |
| 21 | jmp copy_user_generic | 24 | 2: |
| 25 | .byte 0xe9 /* 32bit jump */ | ||
| 26 | .long .Lcug-1f | ||
| 27 | 1: | ||
| 28 | |||
| 29 | .section .altinstr_replacement,"ax" | ||
| 30 | 3: .byte 0xe9 /* replacement jmp with 8 bit immediate */ | ||
| 31 | .long copy_user_generic_c-1b /* offset */ | ||
| 32 | .previous | ||
| 33 | .section .altinstructions,"a" | ||
| 34 | .align 8 | ||
| 35 | .quad 2b | ||
| 36 | .quad 3b | ||
| 37 | .byte X86_FEATURE_REP_GOOD | ||
| 38 | .byte 5 | ||
| 39 | .byte 5 | ||
| 40 | .previous | ||
| 22 | 41 | ||
| 23 | /* Standard copy_from_user with segment limit checking */ | 42 | /* Standard copy_from_user with segment limit checking */ |
| 24 | .globl copy_from_user | 43 | .globl copy_from_user |
| @@ -53,44 +72,230 @@ bad_to_user: | |||
| 53 | * rsi source | 72 | * rsi source |
| 54 | * rdx count | 73 | * rdx count |
| 55 | * | 74 | * |
| 56 | * Only 4GB of copy is supported. This shouldn't be a problem | ||
| 57 | * because the kernel normally only writes from/to page sized chunks | ||
| 58 | * even if user space passed a longer buffer. | ||
| 59 | * And more would be dangerous because both Intel and AMD have | ||
| 60 | * errata with rep movsq > 4GB. If someone feels the need to fix | ||
| 61 | * this please consider this. | ||
| 62 | * | ||
| 63 | * Output: | 75 | * Output: |
| 64 | * eax uncopied bytes or 0 if successful. | 76 | * eax uncopied bytes or 0 if successful. |
| 65 | */ | 77 | */ |
| 66 | |||
| 67 | .globl copy_user_generic | 78 | .globl copy_user_generic |
| 79 | .p2align 4 | ||
| 68 | copy_user_generic: | 80 | copy_user_generic: |
| 81 | .byte 0x66,0x66,0x90 /* 5 byte nop for replacement jump */ | ||
| 82 | .byte 0x66,0x90 | ||
| 83 | 1: | ||
| 84 | .section .altinstr_replacement,"ax" | ||
| 85 | 2: .byte 0xe9 /* near jump with 32bit immediate */ | ||
| 86 | .long copy_user_generic_c-1b /* offset */ | ||
| 87 | .previous | ||
| 88 | .section .altinstructions,"a" | ||
| 89 | .align 8 | ||
| 90 | .quad copy_user_generic | ||
| 91 | .quad 2b | ||
| 92 | .byte X86_FEATURE_REP_GOOD | ||
| 93 | .byte 5 | ||
| 94 | .byte 5 | ||
| 95 | .previous | ||
| 96 | .Lcug: | ||
| 97 | pushq %rbx | ||
| 98 | xorl %eax,%eax /*zero for the exception handler */ | ||
| 99 | |||
| 100 | #ifdef FIX_ALIGNMENT | ||
| 101 | /* check for bad alignment of destination */ | ||
| 102 | movl %edi,%ecx | ||
| 103 | andl $7,%ecx | ||
| 104 | jnz .Lbad_alignment | ||
| 105 | .Lafter_bad_alignment: | ||
| 106 | #endif | ||
| 107 | |||
| 108 | movq %rdx,%rcx | ||
| 109 | |||
| 110 | movl $64,%ebx | ||
| 111 | shrq $6,%rdx | ||
| 112 | decq %rdx | ||
| 113 | js .Lhandle_tail | ||
| 114 | |||
| 115 | .p2align 4 | ||
| 116 | .Lloop: | ||
| 117 | .Ls1: movq (%rsi),%r11 | ||
| 118 | .Ls2: movq 1*8(%rsi),%r8 | ||
| 119 | .Ls3: movq 2*8(%rsi),%r9 | ||
| 120 | .Ls4: movq 3*8(%rsi),%r10 | ||
| 121 | .Ld1: movq %r11,(%rdi) | ||
| 122 | .Ld2: movq %r8,1*8(%rdi) | ||
| 123 | .Ld3: movq %r9,2*8(%rdi) | ||
| 124 | .Ld4: movq %r10,3*8(%rdi) | ||
| 125 | |||
| 126 | .Ls5: movq 4*8(%rsi),%r11 | ||
| 127 | .Ls6: movq 5*8(%rsi),%r8 | ||
| 128 | .Ls7: movq 6*8(%rsi),%r9 | ||
| 129 | .Ls8: movq 7*8(%rsi),%r10 | ||
| 130 | .Ld5: movq %r11,4*8(%rdi) | ||
| 131 | .Ld6: movq %r8,5*8(%rdi) | ||
| 132 | .Ld7: movq %r9,6*8(%rdi) | ||
| 133 | .Ld8: movq %r10,7*8(%rdi) | ||
| 134 | |||
| 135 | decq %rdx | ||
| 136 | |||
| 137 | leaq 64(%rsi),%rsi | ||
| 138 | leaq 64(%rdi),%rdi | ||
| 139 | |||
| 140 | jns .Lloop | ||
| 141 | |||
| 142 | .p2align 4 | ||
| 143 | .Lhandle_tail: | ||
| 144 | movl %ecx,%edx | ||
| 145 | andl $63,%ecx | ||
| 146 | shrl $3,%ecx | ||
| 147 | jz .Lhandle_7 | ||
| 148 | movl $8,%ebx | ||
| 149 | .p2align 4 | ||
| 150 | .Lloop_8: | ||
| 151 | .Ls9: movq (%rsi),%r8 | ||
| 152 | .Ld9: movq %r8,(%rdi) | ||
| 153 | decl %ecx | ||
| 154 | leaq 8(%rdi),%rdi | ||
| 155 | leaq 8(%rsi),%rsi | ||
| 156 | jnz .Lloop_8 | ||
| 157 | |||
| 158 | .Lhandle_7: | ||
| 159 | movl %edx,%ecx | ||
| 160 | andl $7,%ecx | ||
| 161 | jz .Lende | ||
| 162 | .p2align 4 | ||
| 163 | .Lloop_1: | ||
| 164 | .Ls10: movb (%rsi),%bl | ||
| 165 | .Ld10: movb %bl,(%rdi) | ||
| 166 | incq %rdi | ||
| 167 | incq %rsi | ||
| 168 | decl %ecx | ||
| 169 | jnz .Lloop_1 | ||
| 170 | |||
| 171 | .Lende: | ||
| 172 | popq %rbx | ||
| 173 | ret | ||
| 174 | |||
| 175 | #ifdef FIX_ALIGNMENT | ||
| 176 | /* align destination */ | ||
| 177 | .p2align 4 | ||
| 178 | .Lbad_alignment: | ||
| 179 | movl $8,%r9d | ||
| 180 | subl %ecx,%r9d | ||
| 181 | movl %r9d,%ecx | ||
| 182 | cmpq %r9,%rdx | ||
| 183 | jz .Lhandle_7 | ||
| 184 | js .Lhandle_7 | ||
| 185 | .Lalign_1: | ||
| 186 | .Ls11: movb (%rsi),%bl | ||
| 187 | .Ld11: movb %bl,(%rdi) | ||
| 188 | incq %rsi | ||
| 189 | incq %rdi | ||
| 190 | decl %ecx | ||
| 191 | jnz .Lalign_1 | ||
| 192 | subq %r9,%rdx | ||
| 193 | jmp .Lafter_bad_alignment | ||
| 194 | #endif | ||
| 195 | |||
| 196 | /* table sorted by exception address */ | ||
| 197 | .section __ex_table,"a" | ||
| 198 | .align 8 | ||
| 199 | .quad .Ls1,.Ls1e | ||
| 200 | .quad .Ls2,.Ls2e | ||
| 201 | .quad .Ls3,.Ls3e | ||
| 202 | .quad .Ls4,.Ls4e | ||
| 203 | .quad .Ld1,.Ls1e | ||
| 204 | .quad .Ld2,.Ls2e | ||
| 205 | .quad .Ld3,.Ls3e | ||
| 206 | .quad .Ld4,.Ls4e | ||
| 207 | .quad .Ls5,.Ls5e | ||
| 208 | .quad .Ls6,.Ls6e | ||
| 209 | .quad .Ls7,.Ls7e | ||
| 210 | .quad .Ls8,.Ls8e | ||
| 211 | .quad .Ld5,.Ls5e | ||
| 212 | .quad .Ld6,.Ls6e | ||
| 213 | .quad .Ld7,.Ls7e | ||
| 214 | .quad .Ld8,.Ls8e | ||
| 215 | .quad .Ls9,.Le_quad | ||
| 216 | .quad .Ld9,.Le_quad | ||
| 217 | .quad .Ls10,.Le_byte | ||
| 218 | .quad .Ld10,.Le_byte | ||
| 219 | #ifdef FIX_ALIGNMENT | ||
| 220 | .quad .Ls11,.Lzero_rest | ||
| 221 | .quad .Ld11,.Lzero_rest | ||
| 222 | #endif | ||
| 223 | .quad .Le5,.Le_zero | ||
| 224 | .previous | ||
| 225 | |||
| 226 | /* compute 64-offset for main loop. 8 bytes accuracy with error on the | ||
| 227 | pessimistic side. this is gross. it would be better to fix the | ||
| 228 | interface. */ | ||
| 229 | /* eax: zero, ebx: 64 */ | ||
| 230 | .Ls1e: addl $8,%eax | ||
| 231 | .Ls2e: addl $8,%eax | ||
| 232 | .Ls3e: addl $8,%eax | ||
| 233 | .Ls4e: addl $8,%eax | ||
| 234 | .Ls5e: addl $8,%eax | ||
| 235 | .Ls6e: addl $8,%eax | ||
| 236 | .Ls7e: addl $8,%eax | ||
| 237 | .Ls8e: addl $8,%eax | ||
| 238 | addq %rbx,%rdi /* +64 */ | ||
| 239 | subq %rax,%rdi /* correct destination with computed offset */ | ||
| 240 | |||
| 241 | shlq $6,%rdx /* loop counter * 64 (stride length) */ | ||
| 242 | addq %rax,%rdx /* add offset to loopcnt */ | ||
| 243 | andl $63,%ecx /* remaining bytes */ | ||
| 244 | addq %rcx,%rdx /* add them */ | ||
| 245 | jmp .Lzero_rest | ||
| 246 | |||
| 247 | /* exception on quad word loop in tail handling */ | ||
| 248 | /* ecx: loopcnt/8, %edx: length, rdi: correct */ | ||
| 249 | .Le_quad: | ||
| 250 | shll $3,%ecx | ||
| 251 | andl $7,%edx | ||
| 252 | addl %ecx,%edx | ||
| 253 | /* edx: bytes to zero, rdi: dest, eax:zero */ | ||
| 254 | .Lzero_rest: | ||
| 255 | movq %rdx,%rcx | ||
| 256 | .Le_byte: | ||
| 257 | xorl %eax,%eax | ||
| 258 | .Le5: rep | ||
| 259 | stosb | ||
| 260 | /* when there is another exception while zeroing the rest just return */ | ||
| 261 | .Le_zero: | ||
| 262 | movq %rdx,%rax | ||
| 263 | jmp .Lende | ||
| 264 | |||
| 265 | /* Some CPUs run faster using the string copy instructions. | ||
| 266 | This is also a lot simpler. Use them when possible. | ||
| 267 | Patch in jmps to this code instead of copying it fully | ||
| 268 | to avoid unwanted aliasing in the exception tables. */ | ||
| 269 | |||
| 270 | /* rdi destination | ||
| 271 | * rsi source | ||
| 272 | * rdx count | ||
| 273 | * | ||
| 274 | * Output: | ||
| 275 | * eax uncopied bytes or 0 if successfull. | ||
| 276 | * | ||
| 277 | * Only 4GB of copy is supported. This shouldn't be a problem | ||
| 278 | * because the kernel normally only writes from/to page sized chunks | ||
| 279 | * even if user space passed a longer buffer. | ||
| 280 | * And more would be dangerous because both Intel and AMD have | ||
| 281 | * errata with rep movsq > 4GB. If someone feels the need to fix | ||
| 282 | * this please consider this. | ||
| 283 | */ | ||
| 284 | copy_user_generic_c: | ||
| 69 | movl %edx,%ecx | 285 | movl %edx,%ecx |
| 70 | shrl $3,%ecx | 286 | shrl $3,%ecx |
| 71 | andl $7,%edx | 287 | andl $7,%edx |
| 72 | jz 5f | ||
| 73 | 1: rep | 288 | 1: rep |
| 74 | movsq | 289 | movsq |
| 75 | movl %edx,%ecx | 290 | movl %edx,%ecx |
| 76 | xor %eax,%eax | ||
| 77 | 2: rep | 291 | 2: rep |
| 78 | movsb | 292 | movsb |
| 293 | 4: movl %ecx,%eax | ||
| 79 | ret | 294 | ret |
| 80 | /* align here? */ | ||
| 81 | 5: xorl %eax,%eax | ||
| 82 | 6: rep movsq | ||
| 83 | ret | ||
| 84 | |||
| 85 | .section .fixup,"ax" | ||
| 86 | 3: lea (%rdx,%rcx,8),%rax | 295 | 3: lea (%rdx,%rcx,8),%rax |
| 87 | ret | 296 | ret |
| 88 | 4: movl %ecx,%eax | ||
| 89 | ret | ||
| 90 | .previous | ||
| 91 | 297 | ||
| 92 | .section __ex_table,"a" | 298 | .section __ex_table,"a" |
| 93 | .quad 1b,3b | 299 | .quad 1b,3b |
| 94 | .quad 2b,4b | 300 | .quad 2b,4b |
| 95 | .quad 6b,4b | ||
| 96 | .previous | 301 | .previous |
diff --git a/arch/x86_64/lib/memcpy.S b/arch/x86_64/lib/memcpy.S index 92dd80544602..5554948b5554 100644 --- a/arch/x86_64/lib/memcpy.S +++ b/arch/x86_64/lib/memcpy.S | |||
| @@ -11,8 +11,6 @@ | |||
| 11 | * | 11 | * |
| 12 | * Output: | 12 | * Output: |
| 13 | * rax original destination | 13 | * rax original destination |
| 14 | * | ||
| 15 | * TODO: check best memcpy for PSC | ||
| 16 | */ | 14 | */ |
| 17 | 15 | ||
| 18 | .globl __memcpy | 16 | .globl __memcpy |
| @@ -20,6 +18,95 @@ | |||
| 20 | .p2align 4 | 18 | .p2align 4 |
| 21 | __memcpy: | 19 | __memcpy: |
| 22 | memcpy: | 20 | memcpy: |
| 21 | pushq %rbx | ||
| 22 | movq %rdi,%rax | ||
| 23 | |||
| 24 | movl %edx,%ecx | ||
| 25 | shrl $6,%ecx | ||
| 26 | jz .Lhandle_tail | ||
| 27 | |||
| 28 | .p2align 4 | ||
| 29 | .Lloop_64: | ||
| 30 | decl %ecx | ||
| 31 | |||
| 32 | movq (%rsi),%r11 | ||
| 33 | movq 8(%rsi),%r8 | ||
| 34 | |||
| 35 | movq %r11,(%rdi) | ||
| 36 | movq %r8,1*8(%rdi) | ||
| 37 | |||
| 38 | movq 2*8(%rsi),%r9 | ||
| 39 | movq 3*8(%rsi),%r10 | ||
| 40 | |||
| 41 | movq %r9,2*8(%rdi) | ||
| 42 | movq %r10,3*8(%rdi) | ||
| 43 | |||
| 44 | movq 4*8(%rsi),%r11 | ||
| 45 | movq 5*8(%rsi),%r8 | ||
| 46 | |||
| 47 | movq %r11,4*8(%rdi) | ||
| 48 | movq %r8,5*8(%rdi) | ||
| 49 | |||
| 50 | movq 6*8(%rsi),%r9 | ||
| 51 | movq 7*8(%rsi),%r10 | ||
| 52 | |||
| 53 | movq %r9,6*8(%rdi) | ||
| 54 | movq %r10,7*8(%rdi) | ||
| 55 | |||
| 56 | leaq 64(%rsi),%rsi | ||
| 57 | leaq 64(%rdi),%rdi | ||
| 58 | jnz .Lloop_64 | ||
| 59 | |||
| 60 | .Lhandle_tail: | ||
| 61 | movl %edx,%ecx | ||
| 62 | andl $63,%ecx | ||
| 63 | shrl $3,%ecx | ||
| 64 | jz .Lhandle_7 | ||
| 65 | .p2align 4 | ||
| 66 | .Lloop_8: | ||
| 67 | decl %ecx | ||
| 68 | movq (%rsi),%r8 | ||
| 69 | movq %r8,(%rdi) | ||
| 70 | leaq 8(%rdi),%rdi | ||
| 71 | leaq 8(%rsi),%rsi | ||
| 72 | jnz .Lloop_8 | ||
| 73 | |||
| 74 | .Lhandle_7: | ||
| 75 | movl %edx,%ecx | ||
| 76 | andl $7,%ecx | ||
| 77 | jz .Lende | ||
| 78 | .p2align 4 | ||
| 79 | .Lloop_1: | ||
| 80 | movb (%rsi),%r8b | ||
| 81 | movb %r8b,(%rdi) | ||
| 82 | incq %rdi | ||
| 83 | incq %rsi | ||
| 84 | decl %ecx | ||
| 85 | jnz .Lloop_1 | ||
| 86 | |||
| 87 | .Lende: | ||
| 88 | popq %rbx | ||
| 89 | ret | ||
| 90 | .Lfinal: | ||
| 91 | |||
| 92 | /* Some CPUs run faster using the string copy instructions. | ||
| 93 | It is also a lot simpler. Use this when possible */ | ||
| 94 | |||
| 95 | .section .altinstructions,"a" | ||
| 96 | .align 8 | ||
| 97 | .quad memcpy | ||
| 98 | .quad memcpy_c | ||
| 99 | .byte X86_FEATURE_REP_GOOD | ||
| 100 | .byte .Lfinal-memcpy | ||
| 101 | .byte memcpy_c_end-memcpy_c | ||
| 102 | .previous | ||
| 103 | |||
| 104 | .section .altinstr_replacement,"ax" | ||
| 105 | /* rdi destination | ||
| 106 | * rsi source | ||
| 107 | * rdx count | ||
| 108 | */ | ||
| 109 | memcpy_c: | ||
| 23 | movq %rdi,%rax | 110 | movq %rdi,%rax |
| 24 | movl %edx,%ecx | 111 | movl %edx,%ecx |
| 25 | shrl $3,%ecx | 112 | shrl $3,%ecx |
| @@ -30,3 +117,5 @@ memcpy: | |||
| 30 | rep | 117 | rep |
| 31 | movsb | 118 | movsb |
| 32 | ret | 119 | ret |
| 120 | memcpy_c_end: | ||
| 121 | .previous | ||
diff --git a/arch/x86_64/lib/memset.S b/arch/x86_64/lib/memset.S index 2aa48f24ed1e..ad397f2c7de8 100644 --- a/arch/x86_64/lib/memset.S +++ b/arch/x86_64/lib/memset.S | |||
| @@ -13,6 +13,98 @@ | |||
| 13 | .p2align 4 | 13 | .p2align 4 |
| 14 | memset: | 14 | memset: |
| 15 | __memset: | 15 | __memset: |
| 16 | movq %rdi,%r10 | ||
| 17 | movq %rdx,%r11 | ||
| 18 | |||
| 19 | /* expand byte value */ | ||
| 20 | movzbl %sil,%ecx | ||
| 21 | movabs $0x0101010101010101,%rax | ||
| 22 | mul %rcx /* with rax, clobbers rdx */ | ||
| 23 | |||
| 24 | /* align dst */ | ||
| 25 | movl %edi,%r9d | ||
| 26 | andl $7,%r9d | ||
| 27 | jnz .Lbad_alignment | ||
| 28 | .Lafter_bad_alignment: | ||
| 29 | |||
| 30 | movl %r11d,%ecx | ||
| 31 | shrl $6,%ecx | ||
| 32 | jz .Lhandle_tail | ||
| 33 | |||
| 34 | .p2align 4 | ||
| 35 | .Lloop_64: | ||
| 36 | decl %ecx | ||
| 37 | movq %rax,(%rdi) | ||
| 38 | movq %rax,8(%rdi) | ||
| 39 | movq %rax,16(%rdi) | ||
| 40 | movq %rax,24(%rdi) | ||
| 41 | movq %rax,32(%rdi) | ||
| 42 | movq %rax,40(%rdi) | ||
| 43 | movq %rax,48(%rdi) | ||
| 44 | movq %rax,56(%rdi) | ||
| 45 | leaq 64(%rdi),%rdi | ||
| 46 | jnz .Lloop_64 | ||
| 47 | |||
| 48 | /* Handle tail in loops. The loops should be faster than hard | ||
| 49 | to predict jump tables. */ | ||
| 50 | .p2align 4 | ||
| 51 | .Lhandle_tail: | ||
| 52 | movl %r11d,%ecx | ||
| 53 | andl $63&(~7),%ecx | ||
| 54 | jz .Lhandle_7 | ||
| 55 | shrl $3,%ecx | ||
| 56 | .p2align 4 | ||
| 57 | .Lloop_8: | ||
| 58 | decl %ecx | ||
| 59 | movq %rax,(%rdi) | ||
| 60 | leaq 8(%rdi),%rdi | ||
| 61 | jnz .Lloop_8 | ||
| 62 | |||
| 63 | .Lhandle_7: | ||
| 64 | movl %r11d,%ecx | ||
| 65 | andl $7,%ecx | ||
| 66 | jz .Lende | ||
| 67 | .p2align 4 | ||
| 68 | .Lloop_1: | ||
| 69 | decl %ecx | ||
| 70 | movb %al,(%rdi) | ||
| 71 | leaq 1(%rdi),%rdi | ||
| 72 | jnz .Lloop_1 | ||
| 73 | |||
| 74 | .Lende: | ||
| 75 | movq %r10,%rax | ||
| 76 | ret | ||
| 77 | |||
| 78 | .Lbad_alignment: | ||
| 79 | cmpq $7,%r11 | ||
| 80 | jbe .Lhandle_7 | ||
| 81 | movq %rax,(%rdi) /* unaligned store */ | ||
| 82 | movq $8,%r8 | ||
| 83 | subq %r9,%r8 | ||
| 84 | addq %r8,%rdi | ||
| 85 | subq %r8,%r11 | ||
| 86 | jmp .Lafter_bad_alignment | ||
| 87 | |||
| 88 | /* Some CPUs run faster using the string instructions. | ||
| 89 | It is also a lot simpler. Use this when possible */ | ||
| 90 | |||
| 91 | #include <asm/cpufeature.h> | ||
| 92 | |||
| 93 | .section .altinstructions,"a" | ||
| 94 | .align 8 | ||
| 95 | .quad memset | ||
| 96 | .quad memset_c | ||
| 97 | .byte X86_FEATURE_REP_GOOD | ||
| 98 | .byte memset_c_end-memset_c | ||
| 99 | .byte memset_c_end-memset_c | ||
| 100 | .previous | ||
| 101 | |||
| 102 | .section .altinstr_replacement,"ax" | ||
| 103 | /* rdi destination | ||
| 104 | * rsi value | ||
| 105 | * rdx count | ||
| 106 | */ | ||
| 107 | memset_c: | ||
| 16 | movq %rdi,%r9 | 108 | movq %rdi,%r9 |
| 17 | movl %edx,%r8d | 109 | movl %edx,%r8d |
| 18 | andl $7,%r8d | 110 | andl $7,%r8d |
| @@ -29,3 +121,5 @@ __memset: | |||
| 29 | stosb | 121 | stosb |
| 30 | movq %r9,%rax | 122 | movq %r9,%rax |
| 31 | ret | 123 | ret |
| 124 | memset_c_end: | ||
| 125 | .previous | ||
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c index 26eac194064b..2e7c3c8ffe03 100644 --- a/arch/x86_64/mm/fault.c +++ b/arch/x86_64/mm/fault.c | |||
| @@ -33,7 +33,6 @@ | |||
| 33 | #include <asm/proto.h> | 33 | #include <asm/proto.h> |
| 34 | #include <asm/kdebug.h> | 34 | #include <asm/kdebug.h> |
| 35 | #include <asm-generic/sections.h> | 35 | #include <asm-generic/sections.h> |
| 36 | #include <asm/kdebug.h> | ||
| 37 | 36 | ||
| 38 | /* Page fault error code bits */ | 37 | /* Page fault error code bits */ |
| 39 | #define PF_PROT (1<<0) /* or no page found */ | 38 | #define PF_PROT (1<<0) /* or no page found */ |
| @@ -157,8 +156,8 @@ void dump_pagetable(unsigned long address) | |||
| 157 | 156 | ||
| 158 | pgd = __va((unsigned long)pgd & PHYSICAL_PAGE_MASK); | 157 | pgd = __va((unsigned long)pgd & PHYSICAL_PAGE_MASK); |
| 159 | pgd += pgd_index(address); | 158 | pgd += pgd_index(address); |
| 160 | printk("PGD %lx ", pgd_val(*pgd)); | ||
| 161 | if (bad_address(pgd)) goto bad; | 159 | if (bad_address(pgd)) goto bad; |
| 160 | printk("PGD %lx ", pgd_val(*pgd)); | ||
| 162 | if (!pgd_present(*pgd)) goto ret; | 161 | if (!pgd_present(*pgd)) goto ret; |
| 163 | 162 | ||
| 164 | pud = __pud_offset_k((pud_t *)pgd_page(*pgd), address); | 163 | pud = __pud_offset_k((pud_t *)pgd_page(*pgd), address); |
diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c index 8b7f85608fa8..cd25300726fc 100644 --- a/arch/x86_64/mm/srat.c +++ b/arch/x86_64/mm/srat.c | |||
| @@ -26,6 +26,10 @@ static nodemask_t nodes_found __initdata; | |||
| 26 | static struct node nodes[MAX_NUMNODES] __initdata; | 26 | static struct node nodes[MAX_NUMNODES] __initdata; |
| 27 | static u8 pxm2node[256] = { [0 ... 255] = 0xff }; | 27 | static u8 pxm2node[256] = { [0 ... 255] = 0xff }; |
| 28 | 28 | ||
| 29 | /* Too small nodes confuse the VM badly. Usually they result | ||
| 30 | from BIOS bugs. */ | ||
| 31 | #define NODE_MIN_SIZE (4*1024*1024) | ||
| 32 | |||
| 29 | static int node_to_pxm(int n); | 33 | static int node_to_pxm(int n); |
| 30 | 34 | ||
| 31 | int pxm_to_node(int pxm) | 35 | int pxm_to_node(int pxm) |
| @@ -131,7 +135,12 @@ void __init | |||
| 131 | acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa) | 135 | acpi_numa_processor_affinity_init(struct acpi_table_processor_affinity *pa) |
| 132 | { | 136 | { |
| 133 | int pxm, node; | 137 | int pxm, node; |
| 134 | if (srat_disabled() || pa->flags.enabled == 0) | 138 | if (srat_disabled()) |
| 139 | return; | ||
| 140 | if (pa->header.length != sizeof(struct acpi_table_processor_affinity)) { bad_srat(); | ||
| 141 | return; | ||
| 142 | } | ||
| 143 | if (pa->flags.enabled == 0) | ||
| 135 | return; | 144 | return; |
| 136 | pxm = pa->proximity_domain; | 145 | pxm = pa->proximity_domain; |
| 137 | node = setup_node(pxm); | 146 | node = setup_node(pxm); |
| @@ -155,8 +164,16 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) | |||
| 155 | int node, pxm; | 164 | int node, pxm; |
| 156 | int i; | 165 | int i; |
| 157 | 166 | ||
| 158 | if (srat_disabled() || ma->flags.enabled == 0) | 167 | if (srat_disabled()) |
| 168 | return; | ||
| 169 | if (ma->header.length != sizeof(struct acpi_table_memory_affinity)) { | ||
| 170 | bad_srat(); | ||
| 159 | return; | 171 | return; |
| 172 | } | ||
| 173 | if (ma->flags.enabled == 0) | ||
| 174 | return; | ||
| 175 | start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32); | ||
| 176 | end = start + (ma->length_lo | ((u64)ma->length_hi << 32)); | ||
| 160 | pxm = ma->proximity_domain; | 177 | pxm = ma->proximity_domain; |
| 161 | node = setup_node(pxm); | 178 | node = setup_node(pxm); |
| 162 | if (node < 0) { | 179 | if (node < 0) { |
| @@ -164,8 +181,6 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma) | |||
| 164 | bad_srat(); | 181 | bad_srat(); |
| 165 | return; | 182 | return; |
| 166 | } | 183 | } |
| 167 | start = ma->base_addr_lo | ((u64)ma->base_addr_hi << 32); | ||
| 168 | end = start + (ma->length_lo | ((u64)ma->length_hi << 32)); | ||
| 169 | /* It is fine to add this area to the nodes data it will be used later*/ | 184 | /* It is fine to add this area to the nodes data it will be used later*/ |
| 170 | if (ma->flags.hot_pluggable == 1) | 185 | if (ma->flags.hot_pluggable == 1) |
| 171 | printk(KERN_INFO "SRAT: hot plug zone found %lx - %lx \n", | 186 | printk(KERN_INFO "SRAT: hot plug zone found %lx - %lx \n", |
| @@ -223,6 +238,16 @@ static int nodes_cover_memory(void) | |||
| 223 | return 1; | 238 | return 1; |
| 224 | } | 239 | } |
| 225 | 240 | ||
| 241 | static void unparse_node(int node) | ||
| 242 | { | ||
| 243 | int i; | ||
| 244 | node_clear(node, nodes_parsed); | ||
| 245 | for (i = 0; i < MAX_LOCAL_APIC; i++) { | ||
| 246 | if (apicid_to_node[i] == node) | ||
| 247 | apicid_to_node[i] = NUMA_NO_NODE; | ||
| 248 | } | ||
| 249 | } | ||
| 250 | |||
| 226 | void __init acpi_numa_arch_fixup(void) {} | 251 | void __init acpi_numa_arch_fixup(void) {} |
| 227 | 252 | ||
| 228 | /* Use the information discovered above to actually set up the nodes. */ | 253 | /* Use the information discovered above to actually set up the nodes. */ |
| @@ -230,16 +255,16 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end) | |||
| 230 | { | 255 | { |
| 231 | int i; | 256 | int i; |
| 232 | 257 | ||
| 233 | if (acpi_numa <= 0) | ||
| 234 | return -1; | ||
| 235 | |||
| 236 | /* First clean up the node list */ | 258 | /* First clean up the node list */ |
| 237 | for_each_node_mask(i, nodes_parsed) { | 259 | for (i = 0; i < MAX_NUMNODES; i++) { |
| 238 | cutoff_node(i, start, end); | 260 | cutoff_node(i, start, end); |
| 239 | if (nodes[i].start == nodes[i].end) | 261 | if ((nodes[i].end - nodes[i].start) < NODE_MIN_SIZE) |
| 240 | node_clear(i, nodes_parsed); | 262 | unparse_node(i); |
| 241 | } | 263 | } |
| 242 | 264 | ||
| 265 | if (acpi_numa <= 0) | ||
| 266 | return -1; | ||
| 267 | |||
| 243 | if (!nodes_cover_memory()) { | 268 | if (!nodes_cover_memory()) { |
| 244 | bad_srat(); | 269 | bad_srat(); |
| 245 | return -1; | 270 | return -1; |
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index 00d4ddbf980c..18f371fe37f8 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c | |||
| @@ -46,10 +46,10 @@ static char __iomem *get_virt(unsigned int seg, unsigned bus) | |||
| 46 | if (pci_mmcfg_config_num == 1 && | 46 | if (pci_mmcfg_config_num == 1 && |
| 47 | cfg->pci_segment_group_number == 0 && | 47 | cfg->pci_segment_group_number == 0 && |
| 48 | (cfg->start_bus_number | cfg->end_bus_number) == 0) | 48 | (cfg->start_bus_number | cfg->end_bus_number) == 0) |
| 49 | return cfg->base_address; | 49 | return pci_mmcfg_virt[0].virt; |
| 50 | 50 | ||
| 51 | /* Fall back to type 0 */ | 51 | /* Fall back to type 0 */ |
| 52 | return 0; | 52 | return NULL; |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) | 55 | static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) |
diff --git a/arch/xtensa/platform-iss/console.c b/arch/xtensa/platform-iss/console.c index 4fbddf92a921..94fdfe474ac1 100644 --- a/arch/xtensa/platform-iss/console.c +++ b/arch/xtensa/platform-iss/console.c | |||
| @@ -128,9 +128,7 @@ static void rs_poll(unsigned long priv) | |||
| 128 | 128 | ||
| 129 | while (__simc(SYS_select_one, 0, XTISS_SELECT_ONE_READ, (int)&tv,0,0)){ | 129 | while (__simc(SYS_select_one, 0, XTISS_SELECT_ONE_READ, (int)&tv,0,0)){ |
| 130 | __simc (SYS_read, 0, (unsigned long)&c, 1, 0, 0); | 130 | __simc (SYS_read, 0, (unsigned long)&c, 1, 0, 0); |
| 131 | tty->flip.count++; | 131 | tty_insert_flip_char(tty, c, TTY_NORMAL); |
| 132 | *tty->flip.char_buf_ptr++ = c; | ||
| 133 | *tty->flip.flag_buf_ptr++ = TTY_NORMAL; | ||
| 134 | i++; | 132 | i++; |
| 135 | } | 133 | } |
| 136 | 134 | ||
diff --git a/block/elevator.c b/block/elevator.c index 96a61e029ce5..24b702d649a9 100644 --- a/block/elevator.c +++ b/block/elevator.c | |||
| @@ -293,7 +293,7 @@ void elv_requeue_request(request_queue_t *q, struct request *rq) | |||
| 293 | 293 | ||
| 294 | rq->flags &= ~REQ_STARTED; | 294 | rq->flags &= ~REQ_STARTED; |
| 295 | 295 | ||
| 296 | __elv_add_request(q, rq, ELEVATOR_INSERT_REQUEUE, 0); | 296 | elv_insert(q, rq, ELEVATOR_INSERT_REQUEUE); |
| 297 | } | 297 | } |
| 298 | 298 | ||
| 299 | static void elv_drain_elevator(request_queue_t *q) | 299 | static void elv_drain_elevator(request_queue_t *q) |
| @@ -310,40 +310,11 @@ static void elv_drain_elevator(request_queue_t *q) | |||
| 310 | } | 310 | } |
| 311 | } | 311 | } |
| 312 | 312 | ||
| 313 | void __elv_add_request(request_queue_t *q, struct request *rq, int where, | 313 | void elv_insert(request_queue_t *q, struct request *rq, int where) |
| 314 | int plug) | ||
| 315 | { | 314 | { |
| 316 | struct list_head *pos; | 315 | struct list_head *pos; |
| 317 | unsigned ordseq; | 316 | unsigned ordseq; |
| 318 | 317 | ||
| 319 | if (q->ordcolor) | ||
| 320 | rq->flags |= REQ_ORDERED_COLOR; | ||
| 321 | |||
| 322 | if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) { | ||
| 323 | /* | ||
| 324 | * toggle ordered color | ||
| 325 | */ | ||
| 326 | q->ordcolor ^= 1; | ||
| 327 | |||
| 328 | /* | ||
| 329 | * barriers implicitly indicate back insertion | ||
| 330 | */ | ||
| 331 | if (where == ELEVATOR_INSERT_SORT) | ||
| 332 | where = ELEVATOR_INSERT_BACK; | ||
| 333 | |||
| 334 | /* | ||
| 335 | * this request is scheduling boundary, update end_sector | ||
| 336 | */ | ||
| 337 | if (blk_fs_request(rq)) { | ||
| 338 | q->end_sector = rq_end_sector(rq); | ||
| 339 | q->boundary_rq = rq; | ||
| 340 | } | ||
| 341 | } else if (!(rq->flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT) | ||
| 342 | where = ELEVATOR_INSERT_BACK; | ||
| 343 | |||
| 344 | if (plug) | ||
| 345 | blk_plug_device(q); | ||
| 346 | |||
| 347 | rq->q = q; | 318 | rq->q = q; |
| 348 | 319 | ||
| 349 | switch (where) { | 320 | switch (where) { |
| @@ -424,6 +395,42 @@ void __elv_add_request(request_queue_t *q, struct request *rq, int where, | |||
| 424 | } | 395 | } |
| 425 | } | 396 | } |
| 426 | 397 | ||
| 398 | void __elv_add_request(request_queue_t *q, struct request *rq, int where, | ||
| 399 | int plug) | ||
| 400 | { | ||
| 401 | if (q->ordcolor) | ||
| 402 | rq->flags |= REQ_ORDERED_COLOR; | ||
| 403 | |||
| 404 | if (rq->flags & (REQ_SOFTBARRIER | REQ_HARDBARRIER)) { | ||
| 405 | /* | ||
| 406 | * toggle ordered color | ||
| 407 | */ | ||
| 408 | if (blk_barrier_rq(rq)) | ||
| 409 | q->ordcolor ^= 1; | ||
| 410 | |||
| 411 | /* | ||
| 412 | * barriers implicitly indicate back insertion | ||
| 413 | */ | ||
| 414 | if (where == ELEVATOR_INSERT_SORT) | ||
| 415 | where = ELEVATOR_INSERT_BACK; | ||
| 416 | |||
| 417 | /* | ||
| 418 | * this request is scheduling boundary, update | ||
| 419 | * end_sector | ||
| 420 | */ | ||
| 421 | if (blk_fs_request(rq)) { | ||
| 422 | q->end_sector = rq_end_sector(rq); | ||
| 423 | q->boundary_rq = rq; | ||
| 424 | } | ||
| 425 | } else if (!(rq->flags & REQ_ELVPRIV) && where == ELEVATOR_INSERT_SORT) | ||
| 426 | where = ELEVATOR_INSERT_BACK; | ||
| 427 | |||
| 428 | if (plug) | ||
| 429 | blk_plug_device(q); | ||
| 430 | |||
| 431 | elv_insert(q, rq, where); | ||
| 432 | } | ||
| 433 | |||
| 427 | void elv_add_request(request_queue_t *q, struct request *rq, int where, | 434 | void elv_add_request(request_queue_t *q, struct request *rq, int where, |
| 428 | int plug) | 435 | int plug) |
| 429 | { | 436 | { |
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index f9fc07efd2da..03d9c82b0fe7 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c | |||
| @@ -454,7 +454,7 @@ static void queue_flush(request_queue_t *q, unsigned which) | |||
| 454 | rq->end_io = end_io; | 454 | rq->end_io = end_io; |
| 455 | q->prepare_flush_fn(q, rq); | 455 | q->prepare_flush_fn(q, rq); |
| 456 | 456 | ||
| 457 | __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0); | 457 | elv_insert(q, rq, ELEVATOR_INSERT_FRONT); |
| 458 | } | 458 | } |
| 459 | 459 | ||
| 460 | static inline struct request *start_ordered(request_queue_t *q, | 460 | static inline struct request *start_ordered(request_queue_t *q, |
| @@ -490,7 +490,7 @@ static inline struct request *start_ordered(request_queue_t *q, | |||
| 490 | else | 490 | else |
| 491 | q->ordseq |= QUEUE_ORDSEQ_POSTFLUSH; | 491 | q->ordseq |= QUEUE_ORDSEQ_POSTFLUSH; |
| 492 | 492 | ||
| 493 | __elv_add_request(q, rq, ELEVATOR_INSERT_FRONT, 0); | 493 | elv_insert(q, rq, ELEVATOR_INSERT_FRONT); |
| 494 | 494 | ||
| 495 | if (q->ordered & QUEUE_ORDERED_PREFLUSH) { | 495 | if (q->ordered & QUEUE_ORDERED_PREFLUSH) { |
| 496 | queue_flush(q, QUEUE_ORDERED_PREFLUSH); | 496 | queue_flush(q, QUEUE_ORDERED_PREFLUSH); |
| @@ -508,7 +508,7 @@ static inline struct request *start_ordered(request_queue_t *q, | |||
| 508 | 508 | ||
| 509 | int blk_do_ordered(request_queue_t *q, struct request **rqp) | 509 | int blk_do_ordered(request_queue_t *q, struct request **rqp) |
| 510 | { | 510 | { |
| 511 | struct request *rq = *rqp, *allowed_rq; | 511 | struct request *rq = *rqp; |
| 512 | int is_barrier = blk_fs_request(rq) && blk_barrier_rq(rq); | 512 | int is_barrier = blk_fs_request(rq) && blk_barrier_rq(rq); |
| 513 | 513 | ||
| 514 | if (!q->ordseq) { | 514 | if (!q->ordseq) { |
| @@ -532,32 +532,26 @@ int blk_do_ordered(request_queue_t *q, struct request **rqp) | |||
| 532 | } | 532 | } |
| 533 | } | 533 | } |
| 534 | 534 | ||
| 535 | /* | ||
| 536 | * Ordered sequence in progress | ||
| 537 | */ | ||
| 538 | |||
| 539 | /* Special requests are not subject to ordering rules. */ | ||
| 540 | if (!blk_fs_request(rq) && | ||
| 541 | rq != &q->pre_flush_rq && rq != &q->post_flush_rq) | ||
| 542 | return 1; | ||
| 543 | |||
| 535 | if (q->ordered & QUEUE_ORDERED_TAG) { | 544 | if (q->ordered & QUEUE_ORDERED_TAG) { |
| 545 | /* Ordered by tag. Blocking the next barrier is enough. */ | ||
| 536 | if (is_barrier && rq != &q->bar_rq) | 546 | if (is_barrier && rq != &q->bar_rq) |
| 537 | *rqp = NULL; | 547 | *rqp = NULL; |
| 538 | return 1; | 548 | } else { |
| 539 | } | 549 | /* Ordered by draining. Wait for turn. */ |
| 540 | 550 | WARN_ON(blk_ordered_req_seq(rq) < blk_ordered_cur_seq(q)); | |
| 541 | switch (blk_ordered_cur_seq(q)) { | 551 | if (blk_ordered_req_seq(rq) > blk_ordered_cur_seq(q)) |
| 542 | case QUEUE_ORDSEQ_PREFLUSH: | 552 | *rqp = NULL; |
| 543 | allowed_rq = &q->pre_flush_rq; | ||
| 544 | break; | ||
| 545 | case QUEUE_ORDSEQ_BAR: | ||
| 546 | allowed_rq = &q->bar_rq; | ||
| 547 | break; | ||
| 548 | case QUEUE_ORDSEQ_POSTFLUSH: | ||
| 549 | allowed_rq = &q->post_flush_rq; | ||
| 550 | break; | ||
| 551 | default: | ||
| 552 | allowed_rq = NULL; | ||
| 553 | break; | ||
| 554 | } | 553 | } |
| 555 | 554 | ||
| 556 | if (rq != allowed_rq && | ||
| 557 | (blk_fs_request(rq) || rq == &q->pre_flush_rq || | ||
| 558 | rq == &q->post_flush_rq)) | ||
| 559 | *rqp = NULL; | ||
| 560 | |||
| 561 | return 1; | 555 | return 1; |
| 562 | } | 556 | } |
| 563 | 557 | ||
| @@ -3453,7 +3447,7 @@ int __init blk_dev_init(void) | |||
| 3453 | iocontext_cachep = kmem_cache_create("blkdev_ioc", | 3447 | iocontext_cachep = kmem_cache_create("blkdev_ioc", |
| 3454 | sizeof(struct io_context), 0, SLAB_PANIC, NULL, NULL); | 3448 | sizeof(struct io_context), 0, SLAB_PANIC, NULL, NULL); |
| 3455 | 3449 | ||
| 3456 | for (i = 0; i < NR_CPUS; i++) | 3450 | for_each_cpu(i) |
| 3457 | INIT_LIST_HEAD(&per_cpu(blk_cpu_done, i)); | 3451 | INIT_LIST_HEAD(&per_cpu(blk_cpu_done, i)); |
| 3458 | 3452 | ||
| 3459 | open_softirq(BLOCK_SOFTIRQ, blk_done_softirq, NULL); | 3453 | open_softirq(BLOCK_SOFTIRQ, blk_done_softirq, NULL); |
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c index cc72210687eb..24f7af9d0abc 100644 --- a/block/scsi_ioctl.c +++ b/block/scsi_ioctl.c | |||
| @@ -310,6 +310,8 @@ static int sg_io(struct file *file, request_queue_t *q, | |||
| 310 | if (!rq->timeout) | 310 | if (!rq->timeout) |
| 311 | rq->timeout = BLK_DEFAULT_TIMEOUT; | 311 | rq->timeout = BLK_DEFAULT_TIMEOUT; |
| 312 | 312 | ||
| 313 | rq->retries = 0; | ||
| 314 | |||
| 313 | start_time = jiffies; | 315 | start_time = jiffies; |
| 314 | 316 | ||
| 315 | /* ignore return value. All information is passed back to caller | 317 | /* ignore return value. All information is passed back to caller |
| @@ -427,6 +429,7 @@ static int sg_scsi_ioctl(struct file *file, request_queue_t *q, | |||
| 427 | rq->data = buffer; | 429 | rq->data = buffer; |
| 428 | rq->data_len = bytes; | 430 | rq->data_len = bytes; |
| 429 | rq->flags |= REQ_BLOCK_PC; | 431 | rq->flags |= REQ_BLOCK_PC; |
| 432 | rq->retries = 0; | ||
| 430 | 433 | ||
| 431 | blk_execute_rq(q, bd_disk, rq, 0); | 434 | blk_execute_rq(q, bd_disk, rq, 0); |
| 432 | err = rq->errors & 0xff; /* only 8 bit SCSI status */ | 435 | err = rq->errors & 0xff; /* only 8 bit SCSI status */ |
diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c index 47ac90e615f4..2953e2cc56f0 100644 --- a/crypto/scatterwalk.c +++ b/crypto/scatterwalk.c | |||
| @@ -17,7 +17,6 @@ | |||
| 17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
| 18 | #include <linux/pagemap.h> | 18 | #include <linux/pagemap.h> |
| 19 | #include <linux/highmem.h> | 19 | #include <linux/highmem.h> |
| 20 | #include <asm/bug.h> | ||
| 21 | #include <asm/scatterlist.h> | 20 | #include <asm/scatterlist.h> |
| 22 | #include "internal.h" | 21 | #include "internal.h" |
| 23 | #include "scatterwalk.h" | 22 | #include "scatterwalk.h" |
diff --git a/drivers/Makefile b/drivers/Makefile index 619dd964c51c..5c69b86db624 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
| @@ -69,7 +69,7 @@ obj-$(CONFIG_EISA) += eisa/ | |||
| 69 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ | 69 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ |
| 70 | obj-$(CONFIG_MMC) += mmc/ | 70 | obj-$(CONFIG_MMC) += mmc/ |
| 71 | obj-$(CONFIG_INFINIBAND) += infiniband/ | 71 | obj-$(CONFIG_INFINIBAND) += infiniband/ |
| 72 | obj-$(CONFIG_SGI_IOC4) += sn/ | 72 | obj-$(CONFIG_SGI_SN) += sn/ |
| 73 | obj-y += firmware/ | 73 | obj-y += firmware/ |
| 74 | obj-$(CONFIG_CRYPTO) += crypto/ | 74 | obj-$(CONFIG_CRYPTO) += crypto/ |
| 75 | obj-$(CONFIG_SUPERH) += sh/ | 75 | obj-$(CONFIG_SUPERH) += sh/ |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index be2dae52f6fa..eb730a80952c 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
| @@ -94,7 +94,9 @@ static int set_max_cstate(struct dmi_system_id *id) | |||
| 94 | return 0; | 94 | return 0; |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | static struct dmi_system_id __initdata processor_power_dmi_table[] = { | 97 | /* Actually this shouldn't be __cpuinitdata, would be better to fix the |
| 98 | callers to only run once -AK */ | ||
| 99 | static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = { | ||
| 98 | { set_max_cstate, "IBM ThinkPad R40e", { | 100 | { set_max_cstate, "IBM ThinkPad R40e", { |
| 99 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), | 101 | DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), |
| 100 | DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW")}, (void *)1}, | 102 | DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW")}, (void *)1}, |
| @@ -899,7 +901,7 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) | |||
| 899 | case ACPI_STATE_C3: | 901 | case ACPI_STATE_C3: |
| 900 | acpi_processor_power_verify_c3(pr, cx); | 902 | acpi_processor_power_verify_c3(pr, cx); |
| 901 | #ifdef ARCH_APICTIMER_STOPS_ON_C3 | 903 | #ifdef ARCH_APICTIMER_STOPS_ON_C3 |
| 902 | if (c->x86_vendor == X86_VENDOR_INTEL) { | 904 | if (cx->valid && c->x86_vendor == X86_VENDOR_INTEL) { |
| 903 | on_each_cpu(switch_APIC_timer_to_ipi, | 905 | on_each_cpu(switch_APIC_timer_to_ipi, |
| 904 | &mask, 1, 1); | 906 | &mask, 1, 1); |
| 905 | } | 907 | } |
diff --git a/drivers/base/Makefile b/drivers/base/Makefile index f12898d53078..e99471d3232b 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile | |||
| @@ -8,6 +8,7 @@ obj-y += power/ | |||
| 8 | obj-$(CONFIG_FW_LOADER) += firmware_class.o | 8 | obj-$(CONFIG_FW_LOADER) += firmware_class.o |
| 9 | obj-$(CONFIG_NUMA) += node.o | 9 | obj-$(CONFIG_NUMA) += node.o |
| 10 | obj-$(CONFIG_MEMORY_HOTPLUG) += memory.o | 10 | obj-$(CONFIG_MEMORY_HOTPLUG) += memory.o |
| 11 | obj-$(CONFIG_SMP) += topology.o | ||
| 11 | 12 | ||
| 12 | ifeq ($(CONFIG_DEBUG_DRIVER),y) | 13 | ifeq ($(CONFIG_DEBUG_DRIVER),y) |
| 13 | EXTRA_CFLAGS += -DDEBUG | 14 | EXTRA_CFLAGS += -DDEBUG |
diff --git a/drivers/base/base.h b/drivers/base/base.h index e3b548d46cff..5735b38582d0 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
| @@ -19,6 +19,10 @@ extern void bus_remove_driver(struct device_driver *); | |||
| 19 | extern void driver_detach(struct device_driver * drv); | 19 | extern void driver_detach(struct device_driver * drv); |
| 20 | extern int driver_probe_device(struct device_driver *, struct device *); | 20 | extern int driver_probe_device(struct device_driver *, struct device *); |
| 21 | 21 | ||
| 22 | extern void sysdev_shutdown(void); | ||
| 23 | extern int sysdev_suspend(pm_message_t state); | ||
| 24 | extern int sysdev_resume(void); | ||
| 25 | |||
| 22 | static inline struct class_device *to_class_dev(struct kobject *obj) | 26 | static inline struct class_device *to_class_dev(struct kobject *obj) |
| 23 | { | 27 | { |
| 24 | return container_of(obj, struct class_device, kobj); | 28 | return container_of(obj, struct class_device, kobj); |
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 29f6af554e71..c3141565d59d 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
| @@ -133,6 +133,8 @@ static struct kobj_type ktype_bus = { | |||
| 133 | decl_subsys(bus, &ktype_bus, NULL); | 133 | decl_subsys(bus, &ktype_bus, NULL); |
| 134 | 134 | ||
| 135 | 135 | ||
| 136 | #ifdef CONFIG_HOTPLUG | ||
| 137 | |||
| 136 | /* Manually detach a device from its associated driver. */ | 138 | /* Manually detach a device from its associated driver. */ |
| 137 | static int driver_helper(struct device *dev, void *data) | 139 | static int driver_helper(struct device *dev, void *data) |
| 138 | { | 140 | { |
| @@ -193,6 +195,7 @@ static ssize_t driver_bind(struct device_driver *drv, | |||
| 193 | } | 195 | } |
| 194 | static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); | 196 | static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); |
| 195 | 197 | ||
| 198 | #endif | ||
| 196 | 199 | ||
| 197 | static struct device * next_device(struct klist_iter * i) | 200 | static struct device * next_device(struct klist_iter * i) |
| 198 | { | 201 | { |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index d1a05224627e..105a0d61eb1f 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
| @@ -303,7 +303,7 @@ static int block_size_init(void) | |||
| 303 | */ | 303 | */ |
| 304 | #ifdef CONFIG_ARCH_MEMORY_PROBE | 304 | #ifdef CONFIG_ARCH_MEMORY_PROBE |
| 305 | static ssize_t | 305 | static ssize_t |
| 306 | memory_probe_store(struct class *class, const char __user *buf, size_t count) | 306 | memory_probe_store(struct class *class, const char *buf, size_t count) |
| 307 | { | 307 | { |
| 308 | u64 phys_addr; | 308 | u64 phys_addr; |
| 309 | int ret; | 309 | int ret; |
diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c index 0a7aa07b9a2a..317edbf0feca 100644 --- a/drivers/base/power/resume.c +++ b/drivers/base/power/resume.c | |||
| @@ -9,10 +9,9 @@ | |||
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <linux/device.h> | 11 | #include <linux/device.h> |
| 12 | #include "../base.h" | ||
| 12 | #include "power.h" | 13 | #include "power.h" |
| 13 | 14 | ||
| 14 | extern int sysdev_resume(void); | ||
| 15 | |||
| 16 | 15 | ||
| 17 | /** | 16 | /** |
| 18 | * resume_device - Restore state for one device. | 17 | * resume_device - Restore state for one device. |
diff --git a/drivers/base/power/shutdown.c b/drivers/base/power/shutdown.c index c2475f3134ea..8826a5b6673e 100644 --- a/drivers/base/power/shutdown.c +++ b/drivers/base/power/shutdown.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <linux/device.h> | 12 | #include <linux/device.h> |
| 13 | #include <asm/semaphore.h> | 13 | #include <asm/semaphore.h> |
| 14 | 14 | ||
| 15 | #include "../base.h" | ||
| 15 | #include "power.h" | 16 | #include "power.h" |
| 16 | 17 | ||
| 17 | #define to_dev(node) container_of(node, struct device, kobj.entry) | 18 | #define to_dev(node) container_of(node, struct device, kobj.entry) |
| @@ -28,7 +29,6 @@ extern struct subsystem devices_subsys; | |||
| 28 | * they only get one called once when interrupts are disabled. | 29 | * they only get one called once when interrupts are disabled. |
| 29 | */ | 30 | */ |
| 30 | 31 | ||
| 31 | extern int sysdev_shutdown(void); | ||
| 32 | 32 | ||
| 33 | /** | 33 | /** |
| 34 | * device_shutdown - call ->shutdown() on each device to shutdown. | 34 | * device_shutdown - call ->shutdown() on each device to shutdown. |
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c index 50501764d050..8660779fb288 100644 --- a/drivers/base/power/suspend.c +++ b/drivers/base/power/suspend.c | |||
| @@ -9,10 +9,9 @@ | |||
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <linux/device.h> | 11 | #include <linux/device.h> |
| 12 | #include "../base.h" | ||
| 12 | #include "power.h" | 13 | #include "power.h" |
| 13 | 14 | ||
| 14 | extern int sysdev_suspend(pm_message_t state); | ||
| 15 | |||
| 16 | /* | 15 | /* |
| 17 | * The entries in the dpm_active list are in a depth first order, simply | 16 | * The entries in the dpm_active list are in a depth first order, simply |
| 18 | * because children are guaranteed to be discovered after parents, and | 17 | * because children are guaranteed to be discovered after parents, and |
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index f3a0c562bcb5..40d7242a07c1 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c | |||
| @@ -27,22 +27,30 @@ | |||
| 27 | 27 | ||
| 28 | static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf) | 28 | static ssize_t state_show(struct device * dev, struct device_attribute *attr, char * buf) |
| 29 | { | 29 | { |
| 30 | return sprintf(buf, "%u\n", dev->power.power_state.event); | 30 | if (dev->power.power_state.event) |
| 31 | return sprintf(buf, "2\n"); | ||
| 32 | else | ||
| 33 | return sprintf(buf, "0\n"); | ||
| 31 | } | 34 | } |
| 32 | 35 | ||
| 33 | static ssize_t state_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t n) | 36 | static ssize_t state_store(struct device * dev, struct device_attribute *attr, const char * buf, size_t n) |
| 34 | { | 37 | { |
| 35 | pm_message_t state; | 38 | pm_message_t state; |
| 36 | char * rest; | 39 | int error = -EINVAL; |
| 37 | int error = 0; | ||
| 38 | 40 | ||
| 39 | state.event = simple_strtoul(buf, &rest, 10); | 41 | state.event = PM_EVENT_SUSPEND; |
| 40 | if (*rest) | 42 | /* Older apps expected to write "3" here - confused with PCI D3 */ |
| 41 | return -EINVAL; | 43 | if ((n == 1) && !strcmp(buf, "3")) |
| 42 | if (state.event) | ||
| 43 | error = dpm_runtime_suspend(dev, state); | 44 | error = dpm_runtime_suspend(dev, state); |
| 44 | else | 45 | |
| 46 | if ((n == 1) && !strcmp(buf, "2")) | ||
| 47 | error = dpm_runtime_suspend(dev, state); | ||
| 48 | |||
| 49 | if ((n == 1) && !strcmp(buf, "0")) { | ||
| 45 | dpm_runtime_resume(dev); | 50 | dpm_runtime_resume(dev); |
| 51 | error = 0; | ||
| 52 | } | ||
| 53 | |||
| 46 | return error ? error : n; | 54 | return error ? error : n; |
| 47 | } | 55 | } |
| 48 | 56 | ||
diff --git a/drivers/base/sys.c b/drivers/base/sys.c index 66ed8f2fece5..6fc23ab127bd 100644 --- a/drivers/base/sys.c +++ b/drivers/base/sys.c | |||
| @@ -21,8 +21,11 @@ | |||
| 21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
| 22 | #include <linux/string.h> | 22 | #include <linux/string.h> |
| 23 | #include <linux/pm.h> | 23 | #include <linux/pm.h> |
| 24 | #include <linux/device.h> | ||
| 24 | #include <asm/semaphore.h> | 25 | #include <asm/semaphore.h> |
| 25 | 26 | ||
| 27 | #include "base.h" | ||
| 28 | |||
| 26 | extern struct subsystem devices_subsys; | 29 | extern struct subsystem devices_subsys; |
| 27 | 30 | ||
| 28 | #define to_sysdev(k) container_of(k, struct sys_device, kobj) | 31 | #define to_sysdev(k) container_of(k, struct sys_device, kobj) |
diff --git a/drivers/base/topology.c b/drivers/base/topology.c new file mode 100644 index 000000000000..915810f6237e --- /dev/null +++ b/drivers/base/topology.c | |||
| @@ -0,0 +1,148 @@ | |||
| 1 | /* | ||
| 2 | * driver/base/topology.c - Populate sysfs with cpu topology information | ||
| 3 | * | ||
| 4 | * Written by: Zhang Yanmin, Intel Corporation | ||
| 5 | * | ||
| 6 | * Copyright (C) 2006, Intel Corp. | ||
| 7 | * | ||
| 8 | * All rights reserved. | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, but | ||
| 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
| 18 | * NON INFRINGEMENT. See the GNU General Public License for more | ||
| 19 | * details. | ||
| 20 | * | ||
| 21 | * You should have received a copy of the GNU General Public License | ||
| 22 | * along with this program; if not, write to the Free Software | ||
| 23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 24 | * | ||
| 25 | */ | ||
| 26 | #include <linux/sysdev.h> | ||
| 27 | #include <linux/init.h> | ||
| 28 | #include <linux/mm.h> | ||
| 29 | #include <linux/cpu.h> | ||
| 30 | #include <linux/module.h> | ||
| 31 | #include <linux/topology.h> | ||
| 32 | |||
| 33 | #define define_one_ro(_name) \ | ||
| 34 | static SYSDEV_ATTR(_name, 0444, show_##_name, NULL) | ||
| 35 | |||
| 36 | #define define_id_show_func(name) \ | ||
| 37 | static ssize_t show_##name(struct sys_device *dev, char *buf) \ | ||
| 38 | { \ | ||
| 39 | unsigned int cpu = dev->id; \ | ||
| 40 | return sprintf(buf, "%d\n", topology_##name(cpu)); \ | ||
| 41 | } | ||
| 42 | |||
| 43 | #define define_siblings_show_func(name) \ | ||
| 44 | static ssize_t show_##name(struct sys_device *dev, char *buf) \ | ||
| 45 | { \ | ||
| 46 | ssize_t len = -1; \ | ||
| 47 | unsigned int cpu = dev->id; \ | ||
| 48 | len = cpumask_scnprintf(buf, NR_CPUS+1, topology_##name(cpu)); \ | ||
| 49 | return (len + sprintf(buf + len, "\n")); \ | ||
| 50 | } | ||
| 51 | |||
| 52 | #ifdef topology_physical_package_id | ||
| 53 | define_id_show_func(physical_package_id); | ||
| 54 | define_one_ro(physical_package_id); | ||
| 55 | #define ref_physical_package_id_attr &attr_physical_package_id.attr, | ||
| 56 | #else | ||
| 57 | #define ref_physical_package_id_attr | ||
| 58 | #endif | ||
| 59 | |||
| 60 | #ifdef topology_core_id | ||
| 61 | define_id_show_func(core_id); | ||
| 62 | define_one_ro(core_id); | ||
| 63 | #define ref_core_id_attr &attr_core_id.attr, | ||
| 64 | #else | ||
| 65 | #define ref_core_id_attr | ||
| 66 | #endif | ||
| 67 | |||
| 68 | #ifdef topology_thread_siblings | ||
| 69 | define_siblings_show_func(thread_siblings); | ||
| 70 | define_one_ro(thread_siblings); | ||
| 71 | #define ref_thread_siblings_attr &attr_thread_siblings.attr, | ||
| 72 | #else | ||
| 73 | #define ref_thread_siblings_attr | ||
| 74 | #endif | ||
| 75 | |||
| 76 | #ifdef topology_core_siblings | ||
| 77 | define_siblings_show_func(core_siblings); | ||
| 78 | define_one_ro(core_siblings); | ||
| 79 | #define ref_core_siblings_attr &attr_core_siblings.attr, | ||
| 80 | #else | ||
| 81 | #define ref_core_siblings_attr | ||
| 82 | #endif | ||
| 83 | |||
| 84 | static struct attribute *default_attrs[] = { | ||
| 85 | ref_physical_package_id_attr | ||
| 86 | ref_core_id_attr | ||
| 87 | ref_thread_siblings_attr | ||
| 88 | ref_core_siblings_attr | ||
| 89 | NULL | ||
| 90 | }; | ||
| 91 | |||
| 92 | static struct attribute_group topology_attr_group = { | ||
| 93 | .attrs = default_attrs, | ||
| 94 | .name = "topology" | ||
| 95 | }; | ||
| 96 | |||
| 97 | /* Add/Remove cpu_topology interface for CPU device */ | ||
| 98 | static int __cpuinit topology_add_dev(struct sys_device * sys_dev) | ||
| 99 | { | ||
| 100 | sysfs_create_group(&sys_dev->kobj, &topology_attr_group); | ||
| 101 | return 0; | ||
| 102 | } | ||
| 103 | |||
| 104 | static int __cpuinit topology_remove_dev(struct sys_device * sys_dev) | ||
| 105 | { | ||
| 106 | sysfs_remove_group(&sys_dev->kobj, &topology_attr_group); | ||
| 107 | return 0; | ||
| 108 | } | ||
| 109 | |||
| 110 | static int __cpuinit topology_cpu_callback(struct notifier_block *nfb, | ||
| 111 | unsigned long action, void *hcpu) | ||
| 112 | { | ||
| 113 | unsigned int cpu = (unsigned long)hcpu; | ||
| 114 | struct sys_device *sys_dev; | ||
| 115 | |||
| 116 | sys_dev = get_cpu_sysdev(cpu); | ||
| 117 | switch (action) { | ||
| 118 | case CPU_ONLINE: | ||
| 119 | topology_add_dev(sys_dev); | ||
| 120 | break; | ||
| 121 | case CPU_DEAD: | ||
| 122 | topology_remove_dev(sys_dev); | ||
| 123 | break; | ||
| 124 | } | ||
| 125 | return NOTIFY_OK; | ||
| 126 | } | ||
| 127 | |||
| 128 | static struct notifier_block topology_cpu_notifier = | ||
| 129 | { | ||
| 130 | .notifier_call = topology_cpu_callback, | ||
| 131 | }; | ||
| 132 | |||
| 133 | static int __cpuinit topology_sysfs_init(void) | ||
| 134 | { | ||
| 135 | int i; | ||
| 136 | |||
| 137 | for_each_online_cpu(i) { | ||
| 138 | topology_cpu_callback(&topology_cpu_notifier, CPU_ONLINE, | ||
| 139 | (void *)(long)i); | ||
| 140 | } | ||
| 141 | |||
| 142 | register_cpu_notifier(&topology_cpu_notifier); | ||
| 143 | |||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | |||
| 147 | device_initcall(topology_sysfs_init); | ||
| 148 | |||
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 139cbba76180..8b1331677407 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig | |||
| @@ -433,12 +433,12 @@ config CDROM_PKTCDVD_BUFFERS | |||
| 433 | This controls the maximum number of active concurrent packets. More | 433 | This controls the maximum number of active concurrent packets. More |
| 434 | concurrent packets can increase write performance, but also require | 434 | concurrent packets can increase write performance, but also require |
| 435 | more memory. Each concurrent packet will require approximately 64Kb | 435 | more memory. Each concurrent packet will require approximately 64Kb |
| 436 | of non-swappable kernel memory, memory which will be allocated at | 436 | of non-swappable kernel memory, memory which will be allocated when |
| 437 | pktsetup time. | 437 | a disc is opened for writing. |
| 438 | 438 | ||
| 439 | config CDROM_PKTCDVD_WCACHE | 439 | config CDROM_PKTCDVD_WCACHE |
| 440 | bool "Enable write caching" | 440 | bool "Enable write caching (EXPERIMENTAL)" |
| 441 | depends on CDROM_PKTCDVD | 441 | depends on CDROM_PKTCDVD && EXPERIMENTAL |
| 442 | help | 442 | help |
| 443 | If enabled, write caching will be set for the CD-R/W device. For now | 443 | If enabled, write caching will be set for the CD-R/W device. For now |
| 444 | this option is dangerous unless the CD-RW media is known good, as we | 444 | this option is dangerous unless the CD-RW media is known good, as we |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 12d7b9bdfa93..0d65394707db 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
| @@ -2183,6 +2183,7 @@ static void cciss_softirq_done(struct request *rq) | |||
| 2183 | { | 2183 | { |
| 2184 | CommandList_struct *cmd = rq->completion_data; | 2184 | CommandList_struct *cmd = rq->completion_data; |
| 2185 | ctlr_info_t *h = hba[cmd->ctlr]; | 2185 | ctlr_info_t *h = hba[cmd->ctlr]; |
| 2186 | unsigned long flags; | ||
| 2186 | u64bit temp64; | 2187 | u64bit temp64; |
| 2187 | int i, ddir; | 2188 | int i, ddir; |
| 2188 | 2189 | ||
| @@ -2205,10 +2206,10 @@ static void cciss_softirq_done(struct request *rq) | |||
| 2205 | printk("Done with %p\n", rq); | 2206 | printk("Done with %p\n", rq); |
| 2206 | #endif /* CCISS_DEBUG */ | 2207 | #endif /* CCISS_DEBUG */ |
| 2207 | 2208 | ||
| 2208 | spin_lock_irq(&h->lock); | 2209 | spin_lock_irqsave(&h->lock, flags); |
| 2209 | end_that_request_last(rq, rq->errors); | 2210 | end_that_request_last(rq, rq->errors); |
| 2210 | cmd_free(h, cmd,1); | 2211 | cmd_free(h, cmd,1); |
| 2211 | spin_unlock_irq(&h->lock); | 2212 | spin_unlock_irqrestore(&h->lock, flags); |
| 2212 | } | 2213 | } |
| 2213 | 2214 | ||
| 2214 | /* checks the status of the job and calls complete buffers to mark all | 2215 | /* checks the status of the job and calls complete buffers to mark all |
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 93affeeef7bd..4e7dbcc425ff 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
| @@ -43,8 +43,6 @@ | |||
| 43 | * | 43 | * |
| 44 | *************************************************************************/ | 44 | *************************************************************************/ |
| 45 | 45 | ||
| 46 | #define VERSION_CODE "v0.2.0a 2004-07-14 Jens Axboe (axboe@suse.de) and petero2@telia.com" | ||
| 47 | |||
| 48 | #include <linux/pktcdvd.h> | 46 | #include <linux/pktcdvd.h> |
| 49 | #include <linux/config.h> | 47 | #include <linux/config.h> |
| 50 | #include <linux/module.h> | 48 | #include <linux/module.h> |
| @@ -131,7 +129,7 @@ static struct bio *pkt_bio_alloc(int nr_iovecs) | |||
| 131 | /* | 129 | /* |
| 132 | * Allocate a packet_data struct | 130 | * Allocate a packet_data struct |
| 133 | */ | 131 | */ |
| 134 | static struct packet_data *pkt_alloc_packet_data(void) | 132 | static struct packet_data *pkt_alloc_packet_data(int frames) |
| 135 | { | 133 | { |
| 136 | int i; | 134 | int i; |
| 137 | struct packet_data *pkt; | 135 | struct packet_data *pkt; |
| @@ -140,11 +138,12 @@ static struct packet_data *pkt_alloc_packet_data(void) | |||
| 140 | if (!pkt) | 138 | if (!pkt) |
| 141 | goto no_pkt; | 139 | goto no_pkt; |
| 142 | 140 | ||
| 143 | pkt->w_bio = pkt_bio_alloc(PACKET_MAX_SIZE); | 141 | pkt->frames = frames; |
| 142 | pkt->w_bio = pkt_bio_alloc(frames); | ||
| 144 | if (!pkt->w_bio) | 143 | if (!pkt->w_bio) |
| 145 | goto no_bio; | 144 | goto no_bio; |
| 146 | 145 | ||
| 147 | for (i = 0; i < PAGES_PER_PACKET; i++) { | 146 | for (i = 0; i < frames / FRAMES_PER_PAGE; i++) { |
| 148 | pkt->pages[i] = alloc_page(GFP_KERNEL|__GFP_ZERO); | 147 | pkt->pages[i] = alloc_page(GFP_KERNEL|__GFP_ZERO); |
| 149 | if (!pkt->pages[i]) | 148 | if (!pkt->pages[i]) |
| 150 | goto no_page; | 149 | goto no_page; |
| @@ -152,7 +151,7 @@ static struct packet_data *pkt_alloc_packet_data(void) | |||
| 152 | 151 | ||
| 153 | spin_lock_init(&pkt->lock); | 152 | spin_lock_init(&pkt->lock); |
| 154 | 153 | ||
| 155 | for (i = 0; i < PACKET_MAX_SIZE; i++) { | 154 | for (i = 0; i < frames; i++) { |
| 156 | struct bio *bio = pkt_bio_alloc(1); | 155 | struct bio *bio = pkt_bio_alloc(1); |
| 157 | if (!bio) | 156 | if (!bio) |
| 158 | goto no_rd_bio; | 157 | goto no_rd_bio; |
| @@ -162,14 +161,14 @@ static struct packet_data *pkt_alloc_packet_data(void) | |||
| 162 | return pkt; | 161 | return pkt; |
| 163 | 162 | ||
| 164 | no_rd_bio: | 163 | no_rd_bio: |
| 165 | for (i = 0; i < PACKET_MAX_SIZE; i++) { | 164 | for (i = 0; i < frames; i++) { |
| 166 | struct bio *bio = pkt->r_bios[i]; | 165 | struct bio *bio = pkt->r_bios[i]; |
| 167 | if (bio) | 166 | if (bio) |
| 168 | bio_put(bio); | 167 | bio_put(bio); |
| 169 | } | 168 | } |
| 170 | 169 | ||
| 171 | no_page: | 170 | no_page: |
| 172 | for (i = 0; i < PAGES_PER_PACKET; i++) | 171 | for (i = 0; i < frames / FRAMES_PER_PAGE; i++) |
| 173 | if (pkt->pages[i]) | 172 | if (pkt->pages[i]) |
| 174 | __free_page(pkt->pages[i]); | 173 | __free_page(pkt->pages[i]); |
| 175 | bio_put(pkt->w_bio); | 174 | bio_put(pkt->w_bio); |
| @@ -186,12 +185,12 @@ static void pkt_free_packet_data(struct packet_data *pkt) | |||
| 186 | { | 185 | { |
| 187 | int i; | 186 | int i; |
| 188 | 187 | ||
| 189 | for (i = 0; i < PACKET_MAX_SIZE; i++) { | 188 | for (i = 0; i < pkt->frames; i++) { |
| 190 | struct bio *bio = pkt->r_bios[i]; | 189 | struct bio *bio = pkt->r_bios[i]; |
| 191 | if (bio) | 190 | if (bio) |
| 192 | bio_put(bio); | 191 | bio_put(bio); |
| 193 | } | 192 | } |
| 194 | for (i = 0; i < PAGES_PER_PACKET; i++) | 193 | for (i = 0; i < pkt->frames / FRAMES_PER_PAGE; i++) |
| 195 | __free_page(pkt->pages[i]); | 194 | __free_page(pkt->pages[i]); |
| 196 | bio_put(pkt->w_bio); | 195 | bio_put(pkt->w_bio); |
| 197 | kfree(pkt); | 196 | kfree(pkt); |
| @@ -206,17 +205,17 @@ static void pkt_shrink_pktlist(struct pktcdvd_device *pd) | |||
| 206 | list_for_each_entry_safe(pkt, next, &pd->cdrw.pkt_free_list, list) { | 205 | list_for_each_entry_safe(pkt, next, &pd->cdrw.pkt_free_list, list) { |
| 207 | pkt_free_packet_data(pkt); | 206 | pkt_free_packet_data(pkt); |
| 208 | } | 207 | } |
| 208 | INIT_LIST_HEAD(&pd->cdrw.pkt_free_list); | ||
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | static int pkt_grow_pktlist(struct pktcdvd_device *pd, int nr_packets) | 211 | static int pkt_grow_pktlist(struct pktcdvd_device *pd, int nr_packets) |
| 212 | { | 212 | { |
| 213 | struct packet_data *pkt; | 213 | struct packet_data *pkt; |
| 214 | 214 | ||
| 215 | INIT_LIST_HEAD(&pd->cdrw.pkt_free_list); | 215 | BUG_ON(!list_empty(&pd->cdrw.pkt_free_list)); |
| 216 | INIT_LIST_HEAD(&pd->cdrw.pkt_active_list); | 216 | |
| 217 | spin_lock_init(&pd->cdrw.active_list_lock); | ||
| 218 | while (nr_packets > 0) { | 217 | while (nr_packets > 0) { |
| 219 | pkt = pkt_alloc_packet_data(); | 218 | pkt = pkt_alloc_packet_data(pd->settings.size >> 2); |
| 220 | if (!pkt) { | 219 | if (!pkt) { |
| 221 | pkt_shrink_pktlist(pd); | 220 | pkt_shrink_pktlist(pd); |
| 222 | return 0; | 221 | return 0; |
| @@ -951,7 +950,7 @@ try_next_bio: | |||
| 951 | 950 | ||
| 952 | pd->current_sector = zone + pd->settings.size; | 951 | pd->current_sector = zone + pd->settings.size; |
| 953 | pkt->sector = zone; | 952 | pkt->sector = zone; |
| 954 | pkt->frames = pd->settings.size >> 2; | 953 | BUG_ON(pkt->frames != pd->settings.size >> 2); |
| 955 | pkt->write_size = 0; | 954 | pkt->write_size = 0; |
| 956 | 955 | ||
| 957 | /* | 956 | /* |
| @@ -1639,7 +1638,7 @@ static int pkt_probe_settings(struct pktcdvd_device *pd) | |||
| 1639 | pd->settings.size = be32_to_cpu(ti.fixed_packet_size) << 2; | 1638 | pd->settings.size = be32_to_cpu(ti.fixed_packet_size) << 2; |
| 1640 | if (pd->settings.size == 0) { | 1639 | if (pd->settings.size == 0) { |
| 1641 | printk("pktcdvd: detected zero packet size!\n"); | 1640 | printk("pktcdvd: detected zero packet size!\n"); |
| 1642 | pd->settings.size = 128; | 1641 | return -ENXIO; |
| 1643 | } | 1642 | } |
| 1644 | if (pd->settings.size > PACKET_MAX_SECTORS) { | 1643 | if (pd->settings.size > PACKET_MAX_SECTORS) { |
| 1645 | printk("pktcdvd: packet size is too big\n"); | 1644 | printk("pktcdvd: packet size is too big\n"); |
| @@ -1987,8 +1986,14 @@ static int pkt_open_dev(struct pktcdvd_device *pd, int write) | |||
| 1987 | if ((ret = pkt_set_segment_merging(pd, q))) | 1986 | if ((ret = pkt_set_segment_merging(pd, q))) |
| 1988 | goto out_unclaim; | 1987 | goto out_unclaim; |
| 1989 | 1988 | ||
| 1990 | if (write) | 1989 | if (write) { |
| 1990 | if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) { | ||
| 1991 | printk("pktcdvd: not enough memory for buffers\n"); | ||
| 1992 | ret = -ENOMEM; | ||
| 1993 | goto out_unclaim; | ||
| 1994 | } | ||
| 1991 | printk("pktcdvd: %lukB available on disc\n", lba << 1); | 1995 | printk("pktcdvd: %lukB available on disc\n", lba << 1); |
| 1996 | } | ||
| 1992 | 1997 | ||
| 1993 | return 0; | 1998 | return 0; |
| 1994 | 1999 | ||
| @@ -2014,6 +2019,8 @@ static void pkt_release_dev(struct pktcdvd_device *pd, int flush) | |||
| 2014 | pkt_set_speed(pd, MAX_SPEED, MAX_SPEED); | 2019 | pkt_set_speed(pd, MAX_SPEED, MAX_SPEED); |
| 2015 | bd_release(pd->bdev); | 2020 | bd_release(pd->bdev); |
| 2016 | blkdev_put(pd->bdev); | 2021 | blkdev_put(pd->bdev); |
| 2022 | |||
| 2023 | pkt_shrink_pktlist(pd); | ||
| 2017 | } | 2024 | } |
| 2018 | 2025 | ||
| 2019 | static struct pktcdvd_device *pkt_find_dev_from_minor(int dev_minor) | 2026 | static struct pktcdvd_device *pkt_find_dev_from_minor(int dev_minor) |
| @@ -2379,12 +2386,6 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) | |||
| 2379 | /* This is safe, since we have a reference from open(). */ | 2386 | /* This is safe, since we have a reference from open(). */ |
| 2380 | __module_get(THIS_MODULE); | 2387 | __module_get(THIS_MODULE); |
| 2381 | 2388 | ||
| 2382 | if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) { | ||
| 2383 | printk("pktcdvd: not enough memory for buffers\n"); | ||
| 2384 | ret = -ENOMEM; | ||
| 2385 | goto out_mem; | ||
| 2386 | } | ||
| 2387 | |||
| 2388 | pd->bdev = bdev; | 2389 | pd->bdev = bdev; |
| 2389 | set_blocksize(bdev, CD_FRAMESIZE); | 2390 | set_blocksize(bdev, CD_FRAMESIZE); |
| 2390 | 2391 | ||
| @@ -2395,7 +2396,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) | |||
| 2395 | if (IS_ERR(pd->cdrw.thread)) { | 2396 | if (IS_ERR(pd->cdrw.thread)) { |
| 2396 | printk("pktcdvd: can't start kernel thread\n"); | 2397 | printk("pktcdvd: can't start kernel thread\n"); |
| 2397 | ret = -ENOMEM; | 2398 | ret = -ENOMEM; |
| 2398 | goto out_thread; | 2399 | goto out_mem; |
| 2399 | } | 2400 | } |
| 2400 | 2401 | ||
| 2401 | proc = create_proc_entry(pd->name, 0, pkt_proc); | 2402 | proc = create_proc_entry(pd->name, 0, pkt_proc); |
| @@ -2406,8 +2407,6 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) | |||
| 2406 | DPRINTK("pktcdvd: writer %s mapped to %s\n", pd->name, bdevname(bdev, b)); | 2407 | DPRINTK("pktcdvd: writer %s mapped to %s\n", pd->name, bdevname(bdev, b)); |
| 2407 | return 0; | 2408 | return 0; |
| 2408 | 2409 | ||
| 2409 | out_thread: | ||
| 2410 | pkt_shrink_pktlist(pd); | ||
| 2411 | out_mem: | 2410 | out_mem: |
| 2412 | blkdev_put(bdev); | 2411 | blkdev_put(bdev); |
| 2413 | /* This is safe: open() is still holding a reference. */ | 2412 | /* This is safe: open() is still holding a reference. */ |
| @@ -2503,6 +2502,10 @@ static int pkt_setup_dev(struct pkt_ctrl_command *ctrl_cmd) | |||
| 2503 | goto out_mem; | 2502 | goto out_mem; |
| 2504 | pd->disk = disk; | 2503 | pd->disk = disk; |
| 2505 | 2504 | ||
| 2505 | INIT_LIST_HEAD(&pd->cdrw.pkt_free_list); | ||
| 2506 | INIT_LIST_HEAD(&pd->cdrw.pkt_active_list); | ||
| 2507 | spin_lock_init(&pd->cdrw.active_list_lock); | ||
| 2508 | |||
| 2506 | spin_lock_init(&pd->lock); | 2509 | spin_lock_init(&pd->lock); |
| 2507 | spin_lock_init(&pd->iosched.lock); | 2510 | spin_lock_init(&pd->iosched.lock); |
| 2508 | sprintf(pd->name, "pktcdvd%d", idx); | 2511 | sprintf(pd->name, "pktcdvd%d", idx); |
| @@ -2567,8 +2570,6 @@ static int pkt_remove_dev(struct pkt_ctrl_command *ctrl_cmd) | |||
| 2567 | 2570 | ||
| 2568 | blkdev_put(pd->bdev); | 2571 | blkdev_put(pd->bdev); |
| 2569 | 2572 | ||
| 2570 | pkt_shrink_pktlist(pd); | ||
| 2571 | |||
| 2572 | remove_proc_entry(pd->name, pkt_proc); | 2573 | remove_proc_entry(pd->name, pkt_proc); |
| 2573 | DPRINTK("pktcdvd: writer %s unmapped\n", pd->name); | 2574 | DPRINTK("pktcdvd: writer %s unmapped\n", pd->name); |
| 2574 | 2575 | ||
| @@ -2678,7 +2679,6 @@ static int __init pkt_init(void) | |||
| 2678 | 2679 | ||
| 2679 | pkt_proc = proc_mkdir("pktcdvd", proc_root_driver); | 2680 | pkt_proc = proc_mkdir("pktcdvd", proc_root_driver); |
| 2680 | 2681 | ||
| 2681 | DPRINTK("pktcdvd: %s\n", VERSION_CODE); | ||
| 2682 | return 0; | 2682 | return 0; |
| 2683 | 2683 | ||
| 2684 | out: | 2684 | out: |
diff --git a/drivers/block/umem.c b/drivers/block/umem.c index a3614e6a68d0..4ada1268b40d 100644 --- a/drivers/block/umem.c +++ b/drivers/block/umem.c | |||
| @@ -882,7 +882,7 @@ static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_i | |||
| 882 | card->card_number, dev->bus->number, dev->devfn); | 882 | card->card_number, dev->bus->number, dev->devfn); |
| 883 | 883 | ||
| 884 | if (pci_set_dma_mask(dev, 0xffffffffffffffffLL) && | 884 | if (pci_set_dma_mask(dev, 0xffffffffffffffffLL) && |
| 885 | !pci_set_dma_mask(dev, 0xffffffffLL)) { | 885 | pci_set_dma_mask(dev, 0xffffffffLL)) { |
| 886 | printk(KERN_WARNING "MM%d: NO suitable DMA found\n",num_cards); | 886 | printk(KERN_WARNING "MM%d: NO suitable DMA found\n",num_cards); |
| 887 | return -ENOMEM; | 887 | return -ENOMEM; |
| 888 | } | 888 | } |
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index 193446e6a08a..e27617259552 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c | |||
| @@ -42,8 +42,6 @@ | |||
| 42 | #include <linux/proc_fs.h> | 42 | #include <linux/proc_fs.h> |
| 43 | #include <linux/seq_file.h> | 43 | #include <linux/seq_file.h> |
| 44 | 44 | ||
| 45 | #include <asm/bug.h> | ||
| 46 | |||
| 47 | #include <asm/vio.h> | 45 | #include <asm/vio.h> |
| 48 | #include <asm/scatterlist.h> | 46 | #include <asm/scatterlist.h> |
| 49 | #include <asm/iseries/hv_types.h> | 47 | #include <asm/iseries/hv_types.h> |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 4c67727d75b1..05ba410682a3 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
| @@ -222,7 +222,7 @@ config SYNCLINKMP | |||
| 222 | 222 | ||
| 223 | config SYNCLINK_GT | 223 | config SYNCLINK_GT |
| 224 | tristate "SyncLink GT/AC support" | 224 | tristate "SyncLink GT/AC support" |
| 225 | depends on SERIAL_NONSTANDARD | 225 | depends on SERIAL_NONSTANDARD && PCI |
| 226 | help | 226 | help |
| 227 | Support for SyncLink GT and SyncLink AC families of | 227 | Support for SyncLink GT and SyncLink AC families of |
| 228 | synchronous and asynchronous serial adapters | 228 | synchronous and asynchronous serial adapters |
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c index 39c61a71176e..cc7acf877dc0 100644 --- a/drivers/char/cyclades.c +++ b/drivers/char/cyclades.c | |||
| @@ -1233,7 +1233,7 @@ cyy_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
| 1233 | } | 1233 | } |
| 1234 | info->idle_stats.recv_idle = jiffies; | 1234 | info->idle_stats.recv_idle = jiffies; |
| 1235 | } | 1235 | } |
| 1236 | schedule_delayed_work(&tty->buf.work, 1); | 1236 | tty_schedule_flip(tty); |
| 1237 | } | 1237 | } |
| 1238 | /* end of service */ | 1238 | /* end of service */ |
| 1239 | cy_writeb(base_addr+(CyRIR<<index), (save_xir & 0x3f)); | 1239 | cy_writeb(base_addr+(CyRIR<<index), (save_xir & 0x3f)); |
| @@ -1606,7 +1606,7 @@ cyz_handle_rx(struct cyclades_port *info, | |||
| 1606 | } | 1606 | } |
| 1607 | #endif | 1607 | #endif |
| 1608 | info->idle_stats.recv_idle = jiffies; | 1608 | info->idle_stats.recv_idle = jiffies; |
| 1609 | schedule_delayed_work(&tty->buf.work, 1); | 1609 | tty_schedule_flip(tty); |
| 1610 | } | 1610 | } |
| 1611 | /* Update rx_get */ | 1611 | /* Update rx_get */ |
| 1612 | cy_writel(&buf_ctrl->rx_get, new_rx_get); | 1612 | cy_writel(&buf_ctrl->rx_get, new_rx_get); |
| @@ -1809,7 +1809,7 @@ cyz_handle_cmd(struct cyclades_card *cinfo) | |||
| 1809 | if(delta_count) | 1809 | if(delta_count) |
| 1810 | cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); | 1810 | cy_sched_event(info, Cy_EVENT_DELTA_WAKEUP); |
| 1811 | if(special_count) | 1811 | if(special_count) |
| 1812 | schedule_delayed_work(&tty->buf.work, 1); | 1812 | tty_schedule_flip(tty); |
| 1813 | } | 1813 | } |
| 1814 | } | 1814 | } |
| 1815 | 1815 | ||
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c index 5485382cadec..bd7be09ea53d 100644 --- a/drivers/char/drm/ati_pcigart.c +++ b/drivers/char/drm/ati_pcigart.c | |||
| @@ -59,17 +59,16 @@ static void *drm_ati_alloc_pcigart_table(void) | |||
| 59 | int i; | 59 | int i; |
| 60 | DRM_DEBUG("%s\n", __FUNCTION__); | 60 | DRM_DEBUG("%s\n", __FUNCTION__); |
| 61 | 61 | ||
| 62 | address = __get_free_pages(GFP_KERNEL, ATI_PCIGART_TABLE_ORDER); | 62 | address = __get_free_pages(GFP_KERNEL | __GFP_COMP, |
| 63 | ATI_PCIGART_TABLE_ORDER); | ||
| 63 | if (address == 0UL) { | 64 | if (address == 0UL) { |
| 64 | return 0; | 65 | return NULL; |
| 65 | } | 66 | } |
| 66 | 67 | ||
| 67 | page = virt_to_page(address); | 68 | page = virt_to_page(address); |
| 68 | 69 | ||
| 69 | for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) { | 70 | for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) |
| 70 | get_page(page); | ||
| 71 | SetPageReserved(page); | 71 | SetPageReserved(page); |
| 72 | } | ||
| 73 | 72 | ||
| 74 | DRM_DEBUG("%s: returning 0x%08lx\n", __FUNCTION__, address); | 73 | DRM_DEBUG("%s: returning 0x%08lx\n", __FUNCTION__, address); |
| 75 | return (void *)address; | 74 | return (void *)address; |
| @@ -83,10 +82,8 @@ static void drm_ati_free_pcigart_table(void *address) | |||
| 83 | 82 | ||
| 84 | page = virt_to_page((unsigned long)address); | 83 | page = virt_to_page((unsigned long)address); |
| 85 | 84 | ||
| 86 | for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) { | 85 | for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) |
| 87 | __put_page(page); | ||
| 88 | ClearPageReserved(page); | 86 | ClearPageReserved(page); |
| 89 | } | ||
| 90 | 87 | ||
| 91 | free_pages((unsigned long)address, ATI_PCIGART_TABLE_ORDER); | 88 | free_pages((unsigned long)address, ATI_PCIGART_TABLE_ORDER); |
| 92 | } | 89 | } |
| @@ -127,7 +124,7 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info) | |||
| 127 | if (gart_info->gart_table_location == DRM_ATI_GART_MAIN | 124 | if (gart_info->gart_table_location == DRM_ATI_GART_MAIN |
| 128 | && gart_info->addr) { | 125 | && gart_info->addr) { |
| 129 | drm_ati_free_pcigart_table(gart_info->addr); | 126 | drm_ati_free_pcigart_table(gart_info->addr); |
| 130 | gart_info->addr = 0; | 127 | gart_info->addr = NULL; |
| 131 | } | 128 | } |
| 132 | 129 | ||
| 133 | return 1; | 130 | return 1; |
| @@ -168,7 +165,7 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info) | |||
| 168 | if (bus_address == 0) { | 165 | if (bus_address == 0) { |
| 169 | DRM_ERROR("unable to map PCIGART pages!\n"); | 166 | DRM_ERROR("unable to map PCIGART pages!\n"); |
| 170 | drm_ati_free_pcigart_table(address); | 167 | drm_ati_free_pcigart_table(address); |
| 171 | address = 0; | 168 | address = NULL; |
| 172 | goto done; | 169 | goto done; |
| 173 | } | 170 | } |
| 174 | } else { | 171 | } else { |
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index 54b561e69486..107df9fdba4e 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
| @@ -57,6 +57,7 @@ | |||
| 57 | #include <linux/smp_lock.h> /* For (un)lock_kernel */ | 57 | #include <linux/smp_lock.h> /* For (un)lock_kernel */ |
| 58 | #include <linux/mm.h> | 58 | #include <linux/mm.h> |
| 59 | #include <linux/cdev.h> | 59 | #include <linux/cdev.h> |
| 60 | #include <linux/mutex.h> | ||
| 60 | #if defined(__alpha__) || defined(__powerpc__) | 61 | #if defined(__alpha__) || defined(__powerpc__) |
| 61 | #include <asm/pgtable.h> /* For pte_wrprotect */ | 62 | #include <asm/pgtable.h> /* For pte_wrprotect */ |
| 62 | #endif | 63 | #endif |
| @@ -623,7 +624,7 @@ typedef struct drm_device { | |||
| 623 | /** \name Locks */ | 624 | /** \name Locks */ |
| 624 | /*@{ */ | 625 | /*@{ */ |
| 625 | spinlock_t count_lock; /**< For inuse, drm_device::open_count, drm_device::buf_use */ | 626 | spinlock_t count_lock; /**< For inuse, drm_device::open_count, drm_device::buf_use */ |
| 626 | struct semaphore struct_sem; /**< For others */ | 627 | struct mutex struct_mutex; /**< For others */ |
| 627 | /*@} */ | 628 | /*@} */ |
| 628 | 629 | ||
| 629 | /** \name Usage Counters */ | 630 | /** \name Usage Counters */ |
| @@ -658,7 +659,7 @@ typedef struct drm_device { | |||
| 658 | /*@{ */ | 659 | /*@{ */ |
| 659 | drm_ctx_list_t *ctxlist; /**< Linked list of context handles */ | 660 | drm_ctx_list_t *ctxlist; /**< Linked list of context handles */ |
| 660 | int ctx_count; /**< Number of context handles */ | 661 | int ctx_count; /**< Number of context handles */ |
| 661 | struct semaphore ctxlist_sem; /**< For ctxlist */ | 662 | struct mutex ctxlist_mutex; /**< For ctxlist */ |
| 662 | 663 | ||
| 663 | drm_map_t **context_sareas; /**< per-context SAREA's */ | 664 | drm_map_t **context_sareas; /**< per-context SAREA's */ |
| 664 | int max_context; | 665 | int max_context; |
| @@ -979,7 +980,7 @@ extern int drm_put_head(drm_head_t * head); | |||
| 979 | extern unsigned int drm_debug; | 980 | extern unsigned int drm_debug; |
| 980 | extern unsigned int drm_cards_limit; | 981 | extern unsigned int drm_cards_limit; |
| 981 | extern drm_head_t **drm_heads; | 982 | extern drm_head_t **drm_heads; |
| 982 | extern struct drm_sysfs_class *drm_class; | 983 | extern struct class *drm_class; |
| 983 | extern struct proc_dir_entry *drm_proc_root; | 984 | extern struct proc_dir_entry *drm_proc_root; |
| 984 | 985 | ||
| 985 | /* Proc support (drm_proc.h) */ | 986 | /* Proc support (drm_proc.h) */ |
| @@ -1010,11 +1011,9 @@ extern void __drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah); | |||
| 1010 | extern void drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah); | 1011 | extern void drm_pci_free(drm_device_t * dev, drm_dma_handle_t * dmah); |
| 1011 | 1012 | ||
| 1012 | /* sysfs support (drm_sysfs.c) */ | 1013 | /* sysfs support (drm_sysfs.c) */ |
| 1013 | struct drm_sysfs_class; | 1014 | extern struct class *drm_sysfs_create(struct module *owner, char *name); |
| 1014 | extern struct drm_sysfs_class *drm_sysfs_create(struct module *owner, | 1015 | extern void drm_sysfs_destroy(struct class *cs); |
| 1015 | char *name); | 1016 | extern struct class_device *drm_sysfs_device_add(struct class *cs, |
| 1016 | extern void drm_sysfs_destroy(struct drm_sysfs_class *cs); | ||
| 1017 | extern struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, | ||
| 1018 | drm_head_t *head); | 1017 | drm_head_t *head); |
| 1019 | extern void drm_sysfs_device_remove(struct class_device *class_dev); | 1018 | extern void drm_sysfs_device_remove(struct class_device *class_dev); |
| 1020 | 1019 | ||
diff --git a/drivers/char/drm/drm_auth.c b/drivers/char/drm/drm_auth.c index a47b502bc7cc..2a37586a7ee8 100644 --- a/drivers/char/drm/drm_auth.c +++ b/drivers/char/drm/drm_auth.c | |||
| @@ -56,7 +56,7 @@ static int drm_hash_magic(drm_magic_t magic) | |||
| 56 | * \param magic magic number. | 56 | * \param magic magic number. |
| 57 | * | 57 | * |
| 58 | * Searches in drm_device::magiclist within all files with the same hash key | 58 | * Searches in drm_device::magiclist within all files with the same hash key |
| 59 | * the one with matching magic number, while holding the drm_device::struct_sem | 59 | * the one with matching magic number, while holding the drm_device::struct_mutex |
| 60 | * lock. | 60 | * lock. |
| 61 | */ | 61 | */ |
| 62 | static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic) | 62 | static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic) |
| @@ -65,14 +65,14 @@ static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic) | |||
| 65 | drm_magic_entry_t *pt; | 65 | drm_magic_entry_t *pt; |
| 66 | int hash = drm_hash_magic(magic); | 66 | int hash = drm_hash_magic(magic); |
| 67 | 67 | ||
| 68 | down(&dev->struct_sem); | 68 | mutex_lock(&dev->struct_mutex); |
| 69 | for (pt = dev->magiclist[hash].head; pt; pt = pt->next) { | 69 | for (pt = dev->magiclist[hash].head; pt; pt = pt->next) { |
| 70 | if (pt->magic == magic) { | 70 | if (pt->magic == magic) { |
| 71 | retval = pt->priv; | 71 | retval = pt->priv; |
| 72 | break; | 72 | break; |
| 73 | } | 73 | } |
| 74 | } | 74 | } |
| 75 | up(&dev->struct_sem); | 75 | mutex_unlock(&dev->struct_mutex); |
| 76 | return retval; | 76 | return retval; |
| 77 | } | 77 | } |
| 78 | 78 | ||
| @@ -85,7 +85,7 @@ static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic) | |||
| 85 | * | 85 | * |
| 86 | * Creates a drm_magic_entry structure and appends to the linked list | 86 | * Creates a drm_magic_entry structure and appends to the linked list |
| 87 | * associated the magic number hash key in drm_device::magiclist, while holding | 87 | * associated the magic number hash key in drm_device::magiclist, while holding |
| 88 | * the drm_device::struct_sem lock. | 88 | * the drm_device::struct_mutex lock. |
| 89 | */ | 89 | */ |
| 90 | static int drm_add_magic(drm_device_t * dev, drm_file_t * priv, | 90 | static int drm_add_magic(drm_device_t * dev, drm_file_t * priv, |
| 91 | drm_magic_t magic) | 91 | drm_magic_t magic) |
| @@ -104,7 +104,7 @@ static int drm_add_magic(drm_device_t * dev, drm_file_t * priv, | |||
| 104 | entry->priv = priv; | 104 | entry->priv = priv; |
| 105 | entry->next = NULL; | 105 | entry->next = NULL; |
| 106 | 106 | ||
| 107 | down(&dev->struct_sem); | 107 | mutex_lock(&dev->struct_mutex); |
| 108 | if (dev->magiclist[hash].tail) { | 108 | if (dev->magiclist[hash].tail) { |
| 109 | dev->magiclist[hash].tail->next = entry; | 109 | dev->magiclist[hash].tail->next = entry; |
| 110 | dev->magiclist[hash].tail = entry; | 110 | dev->magiclist[hash].tail = entry; |
| @@ -112,7 +112,7 @@ static int drm_add_magic(drm_device_t * dev, drm_file_t * priv, | |||
| 112 | dev->magiclist[hash].head = entry; | 112 | dev->magiclist[hash].head = entry; |
| 113 | dev->magiclist[hash].tail = entry; | 113 | dev->magiclist[hash].tail = entry; |
| 114 | } | 114 | } |
| 115 | up(&dev->struct_sem); | 115 | mutex_unlock(&dev->struct_mutex); |
| 116 | 116 | ||
| 117 | return 0; | 117 | return 0; |
| 118 | } | 118 | } |
| @@ -124,7 +124,7 @@ static int drm_add_magic(drm_device_t * dev, drm_file_t * priv, | |||
| 124 | * \param magic magic number. | 124 | * \param magic magic number. |
| 125 | * | 125 | * |
| 126 | * Searches and unlinks the entry in drm_device::magiclist with the magic | 126 | * Searches and unlinks the entry in drm_device::magiclist with the magic |
| 127 | * number hash key, while holding the drm_device::struct_sem lock. | 127 | * number hash key, while holding the drm_device::struct_mutex lock. |
| 128 | */ | 128 | */ |
| 129 | static int drm_remove_magic(drm_device_t * dev, drm_magic_t magic) | 129 | static int drm_remove_magic(drm_device_t * dev, drm_magic_t magic) |
| 130 | { | 130 | { |
| @@ -135,7 +135,7 @@ static int drm_remove_magic(drm_device_t * dev, drm_magic_t magic) | |||
| 135 | DRM_DEBUG("%d\n", magic); | 135 | DRM_DEBUG("%d\n", magic); |
| 136 | hash = drm_hash_magic(magic); | 136 | hash = drm_hash_magic(magic); |
| 137 | 137 | ||
| 138 | down(&dev->struct_sem); | 138 | mutex_lock(&dev->struct_mutex); |
| 139 | for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) { | 139 | for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) { |
| 140 | if (pt->magic == magic) { | 140 | if (pt->magic == magic) { |
| 141 | if (dev->magiclist[hash].head == pt) { | 141 | if (dev->magiclist[hash].head == pt) { |
| @@ -147,11 +147,11 @@ static int drm_remove_magic(drm_device_t * dev, drm_magic_t magic) | |||
| 147 | if (prev) { | 147 | if (prev) { |
| 148 | prev->next = pt->next; | 148 | prev->next = pt->next; |
| 149 | } | 149 | } |
| 150 | up(&dev->struct_sem); | 150 | mutex_unlock(&dev->struct_mutex); |
| 151 | return 0; | 151 | return 0; |
| 152 | } | 152 | } |
| 153 | } | 153 | } |
| 154 | up(&dev->struct_sem); | 154 | mutex_unlock(&dev->struct_mutex); |
| 155 | 155 | ||
| 156 | drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC); | 156 | drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC); |
| 157 | 157 | ||
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index 1db12dcb6802..e2637b4d51de 100644 --- a/drivers/char/drm/drm_bufs.c +++ b/drivers/char/drm/drm_bufs.c | |||
| @@ -255,14 +255,14 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, | |||
| 255 | memset(list, 0, sizeof(*list)); | 255 | memset(list, 0, sizeof(*list)); |
| 256 | list->map = map; | 256 | list->map = map; |
| 257 | 257 | ||
| 258 | down(&dev->struct_sem); | 258 | mutex_lock(&dev->struct_mutex); |
| 259 | list_add(&list->head, &dev->maplist->head); | 259 | list_add(&list->head, &dev->maplist->head); |
| 260 | /* Assign a 32-bit handle */ | 260 | /* Assign a 32-bit handle */ |
| 261 | /* We do it here so that dev->struct_sem protects the increment */ | 261 | /* We do it here so that dev->struct_mutex protects the increment */ |
| 262 | list->user_token = HandleID(map->type == _DRM_SHM | 262 | list->user_token = HandleID(map->type == _DRM_SHM |
| 263 | ? (unsigned long)map->handle | 263 | ? (unsigned long)map->handle |
| 264 | : map->offset, dev); | 264 | : map->offset, dev); |
| 265 | up(&dev->struct_sem); | 265 | mutex_unlock(&dev->struct_mutex); |
| 266 | 266 | ||
| 267 | *maplist = list; | 267 | *maplist = list; |
| 268 | return 0; | 268 | return 0; |
| @@ -392,9 +392,9 @@ int drm_rmmap(drm_device_t *dev, drm_local_map_t *map) | |||
| 392 | { | 392 | { |
| 393 | int ret; | 393 | int ret; |
| 394 | 394 | ||
| 395 | down(&dev->struct_sem); | 395 | mutex_lock(&dev->struct_mutex); |
| 396 | ret = drm_rmmap_locked(dev, map); | 396 | ret = drm_rmmap_locked(dev, map); |
| 397 | up(&dev->struct_sem); | 397 | mutex_unlock(&dev->struct_mutex); |
| 398 | 398 | ||
| 399 | return ret; | 399 | return ret; |
| 400 | } | 400 | } |
| @@ -423,7 +423,7 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp, | |||
| 423 | return -EFAULT; | 423 | return -EFAULT; |
| 424 | } | 424 | } |
| 425 | 425 | ||
| 426 | down(&dev->struct_sem); | 426 | mutex_lock(&dev->struct_mutex); |
| 427 | list_for_each(list, &dev->maplist->head) { | 427 | list_for_each(list, &dev->maplist->head) { |
| 428 | drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head); | 428 | drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head); |
| 429 | 429 | ||
| @@ -439,7 +439,7 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp, | |||
| 439 | * find anything. | 439 | * find anything. |
| 440 | */ | 440 | */ |
| 441 | if (list == (&dev->maplist->head)) { | 441 | if (list == (&dev->maplist->head)) { |
| 442 | up(&dev->struct_sem); | 442 | mutex_unlock(&dev->struct_mutex); |
| 443 | return -EINVAL; | 443 | return -EINVAL; |
| 444 | } | 444 | } |
| 445 | 445 | ||
| @@ -448,13 +448,13 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp, | |||
| 448 | 448 | ||
| 449 | /* Register and framebuffer maps are permanent */ | 449 | /* Register and framebuffer maps are permanent */ |
| 450 | if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) { | 450 | if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) { |
| 451 | up(&dev->struct_sem); | 451 | mutex_unlock(&dev->struct_mutex); |
| 452 | return 0; | 452 | return 0; |
| 453 | } | 453 | } |
| 454 | 454 | ||
| 455 | ret = drm_rmmap_locked(dev, map); | 455 | ret = drm_rmmap_locked(dev, map); |
| 456 | 456 | ||
| 457 | up(&dev->struct_sem); | 457 | mutex_unlock(&dev->struct_mutex); |
| 458 | 458 | ||
| 459 | return ret; | 459 | return ret; |
| 460 | } | 460 | } |
| @@ -566,16 +566,16 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 566 | atomic_inc(&dev->buf_alloc); | 566 | atomic_inc(&dev->buf_alloc); |
| 567 | spin_unlock(&dev->count_lock); | 567 | spin_unlock(&dev->count_lock); |
| 568 | 568 | ||
| 569 | down(&dev->struct_sem); | 569 | mutex_lock(&dev->struct_mutex); |
| 570 | entry = &dma->bufs[order]; | 570 | entry = &dma->bufs[order]; |
| 571 | if (entry->buf_count) { | 571 | if (entry->buf_count) { |
| 572 | up(&dev->struct_sem); | 572 | mutex_unlock(&dev->struct_mutex); |
| 573 | atomic_dec(&dev->buf_alloc); | 573 | atomic_dec(&dev->buf_alloc); |
| 574 | return -ENOMEM; /* May only call once for each order */ | 574 | return -ENOMEM; /* May only call once for each order */ |
| 575 | } | 575 | } |
| 576 | 576 | ||
| 577 | if (count < 0 || count > 4096) { | 577 | if (count < 0 || count > 4096) { |
| 578 | up(&dev->struct_sem); | 578 | mutex_unlock(&dev->struct_mutex); |
| 579 | atomic_dec(&dev->buf_alloc); | 579 | atomic_dec(&dev->buf_alloc); |
| 580 | return -EINVAL; | 580 | return -EINVAL; |
| 581 | } | 581 | } |
| @@ -583,7 +583,7 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 583 | entry->buflist = drm_alloc(count * sizeof(*entry->buflist), | 583 | entry->buflist = drm_alloc(count * sizeof(*entry->buflist), |
| 584 | DRM_MEM_BUFS); | 584 | DRM_MEM_BUFS); |
| 585 | if (!entry->buflist) { | 585 | if (!entry->buflist) { |
| 586 | up(&dev->struct_sem); | 586 | mutex_unlock(&dev->struct_mutex); |
| 587 | atomic_dec(&dev->buf_alloc); | 587 | atomic_dec(&dev->buf_alloc); |
| 588 | return -ENOMEM; | 588 | return -ENOMEM; |
| 589 | } | 589 | } |
| @@ -616,7 +616,7 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 616 | /* Set count correctly so we free the proper amount. */ | 616 | /* Set count correctly so we free the proper amount. */ |
| 617 | entry->buf_count = count; | 617 | entry->buf_count = count; |
| 618 | drm_cleanup_buf_error(dev, entry); | 618 | drm_cleanup_buf_error(dev, entry); |
| 619 | up(&dev->struct_sem); | 619 | mutex_unlock(&dev->struct_mutex); |
| 620 | atomic_dec(&dev->buf_alloc); | 620 | atomic_dec(&dev->buf_alloc); |
| 621 | return -ENOMEM; | 621 | return -ENOMEM; |
| 622 | } | 622 | } |
| @@ -638,7 +638,7 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 638 | if (!temp_buflist) { | 638 | if (!temp_buflist) { |
| 639 | /* Free the entry because it isn't valid */ | 639 | /* Free the entry because it isn't valid */ |
| 640 | drm_cleanup_buf_error(dev, entry); | 640 | drm_cleanup_buf_error(dev, entry); |
| 641 | up(&dev->struct_sem); | 641 | mutex_unlock(&dev->struct_mutex); |
| 642 | atomic_dec(&dev->buf_alloc); | 642 | atomic_dec(&dev->buf_alloc); |
| 643 | return -ENOMEM; | 643 | return -ENOMEM; |
| 644 | } | 644 | } |
| @@ -656,7 +656,7 @@ int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 656 | DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); | 656 | DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); |
| 657 | DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count); | 657 | DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count); |
| 658 | 658 | ||
| 659 | up(&dev->struct_sem); | 659 | mutex_unlock(&dev->struct_mutex); |
| 660 | 660 | ||
| 661 | request->count = entry->buf_count; | 661 | request->count = entry->buf_count; |
| 662 | request->size = size; | 662 | request->size = size; |
| @@ -722,16 +722,16 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 722 | atomic_inc(&dev->buf_alloc); | 722 | atomic_inc(&dev->buf_alloc); |
| 723 | spin_unlock(&dev->count_lock); | 723 | spin_unlock(&dev->count_lock); |
| 724 | 724 | ||
| 725 | down(&dev->struct_sem); | 725 | mutex_lock(&dev->struct_mutex); |
| 726 | entry = &dma->bufs[order]; | 726 | entry = &dma->bufs[order]; |
| 727 | if (entry->buf_count) { | 727 | if (entry->buf_count) { |
| 728 | up(&dev->struct_sem); | 728 | mutex_unlock(&dev->struct_mutex); |
| 729 | atomic_dec(&dev->buf_alloc); | 729 | atomic_dec(&dev->buf_alloc); |
| 730 | return -ENOMEM; /* May only call once for each order */ | 730 | return -ENOMEM; /* May only call once for each order */ |
| 731 | } | 731 | } |
| 732 | 732 | ||
| 733 | if (count < 0 || count > 4096) { | 733 | if (count < 0 || count > 4096) { |
| 734 | up(&dev->struct_sem); | 734 | mutex_unlock(&dev->struct_mutex); |
| 735 | atomic_dec(&dev->buf_alloc); | 735 | atomic_dec(&dev->buf_alloc); |
| 736 | return -EINVAL; | 736 | return -EINVAL; |
| 737 | } | 737 | } |
| @@ -739,7 +739,7 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 739 | entry->buflist = drm_alloc(count * sizeof(*entry->buflist), | 739 | entry->buflist = drm_alloc(count * sizeof(*entry->buflist), |
| 740 | DRM_MEM_BUFS); | 740 | DRM_MEM_BUFS); |
| 741 | if (!entry->buflist) { | 741 | if (!entry->buflist) { |
| 742 | up(&dev->struct_sem); | 742 | mutex_unlock(&dev->struct_mutex); |
| 743 | atomic_dec(&dev->buf_alloc); | 743 | atomic_dec(&dev->buf_alloc); |
| 744 | return -ENOMEM; | 744 | return -ENOMEM; |
| 745 | } | 745 | } |
| @@ -750,7 +750,7 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 750 | if (!entry->seglist) { | 750 | if (!entry->seglist) { |
| 751 | drm_free(entry->buflist, | 751 | drm_free(entry->buflist, |
| 752 | count * sizeof(*entry->buflist), DRM_MEM_BUFS); | 752 | count * sizeof(*entry->buflist), DRM_MEM_BUFS); |
| 753 | up(&dev->struct_sem); | 753 | mutex_unlock(&dev->struct_mutex); |
| 754 | atomic_dec(&dev->buf_alloc); | 754 | atomic_dec(&dev->buf_alloc); |
| 755 | return -ENOMEM; | 755 | return -ENOMEM; |
| 756 | } | 756 | } |
| @@ -766,7 +766,7 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 766 | count * sizeof(*entry->buflist), DRM_MEM_BUFS); | 766 | count * sizeof(*entry->buflist), DRM_MEM_BUFS); |
| 767 | drm_free(entry->seglist, | 767 | drm_free(entry->seglist, |
| 768 | count * sizeof(*entry->seglist), DRM_MEM_SEGS); | 768 | count * sizeof(*entry->seglist), DRM_MEM_SEGS); |
| 769 | up(&dev->struct_sem); | 769 | mutex_unlock(&dev->struct_mutex); |
| 770 | atomic_dec(&dev->buf_alloc); | 770 | atomic_dec(&dev->buf_alloc); |
| 771 | return -ENOMEM; | 771 | return -ENOMEM; |
| 772 | } | 772 | } |
| @@ -790,7 +790,7 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 790 | drm_free(temp_pagelist, | 790 | drm_free(temp_pagelist, |
| 791 | (dma->page_count + (count << page_order)) | 791 | (dma->page_count + (count << page_order)) |
| 792 | * sizeof(*dma->pagelist), DRM_MEM_PAGES); | 792 | * sizeof(*dma->pagelist), DRM_MEM_PAGES); |
| 793 | up(&dev->struct_sem); | 793 | mutex_unlock(&dev->struct_mutex); |
| 794 | atomic_dec(&dev->buf_alloc); | 794 | atomic_dec(&dev->buf_alloc); |
| 795 | return -ENOMEM; | 795 | return -ENOMEM; |
| 796 | } | 796 | } |
| @@ -831,7 +831,7 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 831 | (count << page_order)) | 831 | (count << page_order)) |
| 832 | * sizeof(*dma->pagelist), | 832 | * sizeof(*dma->pagelist), |
| 833 | DRM_MEM_PAGES); | 833 | DRM_MEM_PAGES); |
| 834 | up(&dev->struct_sem); | 834 | mutex_unlock(&dev->struct_mutex); |
| 835 | atomic_dec(&dev->buf_alloc); | 835 | atomic_dec(&dev->buf_alloc); |
| 836 | return -ENOMEM; | 836 | return -ENOMEM; |
| 837 | } | 837 | } |
| @@ -853,7 +853,7 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 853 | drm_free(temp_pagelist, | 853 | drm_free(temp_pagelist, |
| 854 | (dma->page_count + (count << page_order)) | 854 | (dma->page_count + (count << page_order)) |
| 855 | * sizeof(*dma->pagelist), DRM_MEM_PAGES); | 855 | * sizeof(*dma->pagelist), DRM_MEM_PAGES); |
| 856 | up(&dev->struct_sem); | 856 | mutex_unlock(&dev->struct_mutex); |
| 857 | atomic_dec(&dev->buf_alloc); | 857 | atomic_dec(&dev->buf_alloc); |
| 858 | return -ENOMEM; | 858 | return -ENOMEM; |
| 859 | } | 859 | } |
| @@ -878,7 +878,7 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 878 | dma->page_count += entry->seg_count << page_order; | 878 | dma->page_count += entry->seg_count << page_order; |
| 879 | dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order); | 879 | dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order); |
| 880 | 880 | ||
| 881 | up(&dev->struct_sem); | 881 | mutex_unlock(&dev->struct_mutex); |
| 882 | 882 | ||
| 883 | request->count = entry->buf_count; | 883 | request->count = entry->buf_count; |
| 884 | request->size = size; | 884 | request->size = size; |
| @@ -948,16 +948,16 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 948 | atomic_inc(&dev->buf_alloc); | 948 | atomic_inc(&dev->buf_alloc); |
| 949 | spin_unlock(&dev->count_lock); | 949 | spin_unlock(&dev->count_lock); |
| 950 | 950 | ||
| 951 | down(&dev->struct_sem); | 951 | mutex_lock(&dev->struct_mutex); |
| 952 | entry = &dma->bufs[order]; | 952 | entry = &dma->bufs[order]; |
| 953 | if (entry->buf_count) { | 953 | if (entry->buf_count) { |
| 954 | up(&dev->struct_sem); | 954 | mutex_unlock(&dev->struct_mutex); |
| 955 | atomic_dec(&dev->buf_alloc); | 955 | atomic_dec(&dev->buf_alloc); |
| 956 | return -ENOMEM; /* May only call once for each order */ | 956 | return -ENOMEM; /* May only call once for each order */ |
| 957 | } | 957 | } |
| 958 | 958 | ||
| 959 | if (count < 0 || count > 4096) { | 959 | if (count < 0 || count > 4096) { |
| 960 | up(&dev->struct_sem); | 960 | mutex_unlock(&dev->struct_mutex); |
| 961 | atomic_dec(&dev->buf_alloc); | 961 | atomic_dec(&dev->buf_alloc); |
| 962 | return -EINVAL; | 962 | return -EINVAL; |
| 963 | } | 963 | } |
| @@ -965,7 +965,7 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 965 | entry->buflist = drm_alloc(count * sizeof(*entry->buflist), | 965 | entry->buflist = drm_alloc(count * sizeof(*entry->buflist), |
| 966 | DRM_MEM_BUFS); | 966 | DRM_MEM_BUFS); |
| 967 | if (!entry->buflist) { | 967 | if (!entry->buflist) { |
| 968 | up(&dev->struct_sem); | 968 | mutex_unlock(&dev->struct_mutex); |
| 969 | atomic_dec(&dev->buf_alloc); | 969 | atomic_dec(&dev->buf_alloc); |
| 970 | return -ENOMEM; | 970 | return -ENOMEM; |
| 971 | } | 971 | } |
| @@ -999,7 +999,7 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 999 | /* Set count correctly so we free the proper amount. */ | 999 | /* Set count correctly so we free the proper amount. */ |
| 1000 | entry->buf_count = count; | 1000 | entry->buf_count = count; |
| 1001 | drm_cleanup_buf_error(dev, entry); | 1001 | drm_cleanup_buf_error(dev, entry); |
| 1002 | up(&dev->struct_sem); | 1002 | mutex_unlock(&dev->struct_mutex); |
| 1003 | atomic_dec(&dev->buf_alloc); | 1003 | atomic_dec(&dev->buf_alloc); |
| 1004 | return -ENOMEM; | 1004 | return -ENOMEM; |
| 1005 | } | 1005 | } |
| @@ -1022,7 +1022,7 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 1022 | if (!temp_buflist) { | 1022 | if (!temp_buflist) { |
| 1023 | /* Free the entry because it isn't valid */ | 1023 | /* Free the entry because it isn't valid */ |
| 1024 | drm_cleanup_buf_error(dev, entry); | 1024 | drm_cleanup_buf_error(dev, entry); |
| 1025 | up(&dev->struct_sem); | 1025 | mutex_unlock(&dev->struct_mutex); |
| 1026 | atomic_dec(&dev->buf_alloc); | 1026 | atomic_dec(&dev->buf_alloc); |
| 1027 | return -ENOMEM; | 1027 | return -ENOMEM; |
| 1028 | } | 1028 | } |
| @@ -1040,7 +1040,7 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 1040 | DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); | 1040 | DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); |
| 1041 | DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count); | 1041 | DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count); |
| 1042 | 1042 | ||
| 1043 | up(&dev->struct_sem); | 1043 | mutex_unlock(&dev->struct_mutex); |
| 1044 | 1044 | ||
| 1045 | request->count = entry->buf_count; | 1045 | request->count = entry->buf_count; |
| 1046 | request->size = size; | 1046 | request->size = size; |
| @@ -1110,16 +1110,16 @@ int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 1110 | atomic_inc(&dev->buf_alloc); | 1110 | atomic_inc(&dev->buf_alloc); |
| 1111 | spin_unlock(&dev->count_lock); | 1111 | spin_unlock(&dev->count_lock); |
| 1112 | 1112 | ||
| 1113 | down(&dev->struct_sem); | 1113 | mutex_lock(&dev->struct_mutex); |
| 1114 | entry = &dma->bufs[order]; | 1114 | entry = &dma->bufs[order]; |
| 1115 | if (entry->buf_count) { | 1115 | if (entry->buf_count) { |
| 1116 | up(&dev->struct_sem); | 1116 | mutex_unlock(&dev->struct_mutex); |
| 1117 | atomic_dec(&dev->buf_alloc); | 1117 | atomic_dec(&dev->buf_alloc); |
| 1118 | return -ENOMEM; /* May only call once for each order */ | 1118 | return -ENOMEM; /* May only call once for each order */ |
| 1119 | } | 1119 | } |
| 1120 | 1120 | ||
| 1121 | if (count < 0 || count > 4096) { | 1121 | if (count < 0 || count > 4096) { |
| 1122 | up(&dev->struct_sem); | 1122 | mutex_unlock(&dev->struct_mutex); |
| 1123 | atomic_dec(&dev->buf_alloc); | 1123 | atomic_dec(&dev->buf_alloc); |
| 1124 | return -EINVAL; | 1124 | return -EINVAL; |
| 1125 | } | 1125 | } |
| @@ -1127,7 +1127,7 @@ int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 1127 | entry->buflist = drm_alloc(count * sizeof(*entry->buflist), | 1127 | entry->buflist = drm_alloc(count * sizeof(*entry->buflist), |
| 1128 | DRM_MEM_BUFS); | 1128 | DRM_MEM_BUFS); |
| 1129 | if (!entry->buflist) { | 1129 | if (!entry->buflist) { |
| 1130 | up(&dev->struct_sem); | 1130 | mutex_unlock(&dev->struct_mutex); |
| 1131 | atomic_dec(&dev->buf_alloc); | 1131 | atomic_dec(&dev->buf_alloc); |
| 1132 | return -ENOMEM; | 1132 | return -ENOMEM; |
| 1133 | } | 1133 | } |
| @@ -1160,7 +1160,7 @@ int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 1160 | /* Set count correctly so we free the proper amount. */ | 1160 | /* Set count correctly so we free the proper amount. */ |
| 1161 | entry->buf_count = count; | 1161 | entry->buf_count = count; |
| 1162 | drm_cleanup_buf_error(dev, entry); | 1162 | drm_cleanup_buf_error(dev, entry); |
| 1163 | up(&dev->struct_sem); | 1163 | mutex_unlock(&dev->struct_mutex); |
| 1164 | atomic_dec(&dev->buf_alloc); | 1164 | atomic_dec(&dev->buf_alloc); |
| 1165 | return -ENOMEM; | 1165 | return -ENOMEM; |
| 1166 | } | 1166 | } |
| @@ -1182,7 +1182,7 @@ int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 1182 | if (!temp_buflist) { | 1182 | if (!temp_buflist) { |
| 1183 | /* Free the entry because it isn't valid */ | 1183 | /* Free the entry because it isn't valid */ |
| 1184 | drm_cleanup_buf_error(dev, entry); | 1184 | drm_cleanup_buf_error(dev, entry); |
| 1185 | up(&dev->struct_sem); | 1185 | mutex_unlock(&dev->struct_mutex); |
| 1186 | atomic_dec(&dev->buf_alloc); | 1186 | atomic_dec(&dev->buf_alloc); |
| 1187 | return -ENOMEM; | 1187 | return -ENOMEM; |
| 1188 | } | 1188 | } |
| @@ -1200,7 +1200,7 @@ int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request) | |||
| 1200 | DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); | 1200 | DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count); |
| 1201 | DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count); | 1201 | DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count); |
| 1202 | 1202 | ||
| 1203 | up(&dev->struct_sem); | 1203 | mutex_unlock(&dev->struct_mutex); |
| 1204 | 1204 | ||
| 1205 | request->count = entry->buf_count; | 1205 | request->count = entry->buf_count; |
| 1206 | request->size = size; | 1206 | request->size = size; |
diff --git a/drivers/char/drm/drm_context.c b/drivers/char/drm/drm_context.c index f84254526949..83094c73da67 100644 --- a/drivers/char/drm/drm_context.c +++ b/drivers/char/drm/drm_context.c | |||
| @@ -53,7 +53,7 @@ | |||
| 53 | * \param ctx_handle context handle. | 53 | * \param ctx_handle context handle. |
| 54 | * | 54 | * |
| 55 | * Clears the bit specified by \p ctx_handle in drm_device::ctx_bitmap and the entry | 55 | * Clears the bit specified by \p ctx_handle in drm_device::ctx_bitmap and the entry |
| 56 | * in drm_device::context_sareas, while holding the drm_device::struct_sem | 56 | * in drm_device::context_sareas, while holding the drm_device::struct_mutex |
| 57 | * lock. | 57 | * lock. |
| 58 | */ | 58 | */ |
| 59 | void drm_ctxbitmap_free(drm_device_t * dev, int ctx_handle) | 59 | void drm_ctxbitmap_free(drm_device_t * dev, int ctx_handle) |
| @@ -64,10 +64,10 @@ void drm_ctxbitmap_free(drm_device_t * dev, int ctx_handle) | |||
| 64 | goto failed; | 64 | goto failed; |
| 65 | 65 | ||
| 66 | if (ctx_handle < DRM_MAX_CTXBITMAP) { | 66 | if (ctx_handle < DRM_MAX_CTXBITMAP) { |
| 67 | down(&dev->struct_sem); | 67 | mutex_lock(&dev->struct_mutex); |
| 68 | clear_bit(ctx_handle, dev->ctx_bitmap); | 68 | clear_bit(ctx_handle, dev->ctx_bitmap); |
| 69 | dev->context_sareas[ctx_handle] = NULL; | 69 | dev->context_sareas[ctx_handle] = NULL; |
| 70 | up(&dev->struct_sem); | 70 | mutex_unlock(&dev->struct_mutex); |
| 71 | return; | 71 | return; |
| 72 | } | 72 | } |
| 73 | failed: | 73 | failed: |
| @@ -83,7 +83,7 @@ void drm_ctxbitmap_free(drm_device_t * dev, int ctx_handle) | |||
| 83 | * | 83 | * |
| 84 | * Find the first zero bit in drm_device::ctx_bitmap and (re)allocates | 84 | * Find the first zero bit in drm_device::ctx_bitmap and (re)allocates |
| 85 | * drm_device::context_sareas to accommodate the new entry while holding the | 85 | * drm_device::context_sareas to accommodate the new entry while holding the |
| 86 | * drm_device::struct_sem lock. | 86 | * drm_device::struct_mutex lock. |
| 87 | */ | 87 | */ |
| 88 | static int drm_ctxbitmap_next(drm_device_t * dev) | 88 | static int drm_ctxbitmap_next(drm_device_t * dev) |
| 89 | { | 89 | { |
| @@ -92,7 +92,7 @@ static int drm_ctxbitmap_next(drm_device_t * dev) | |||
| 92 | if (!dev->ctx_bitmap) | 92 | if (!dev->ctx_bitmap) |
| 93 | return -1; | 93 | return -1; |
| 94 | 94 | ||
| 95 | down(&dev->struct_sem); | 95 | mutex_lock(&dev->struct_mutex); |
| 96 | bit = find_first_zero_bit(dev->ctx_bitmap, DRM_MAX_CTXBITMAP); | 96 | bit = find_first_zero_bit(dev->ctx_bitmap, DRM_MAX_CTXBITMAP); |
| 97 | if (bit < DRM_MAX_CTXBITMAP) { | 97 | if (bit < DRM_MAX_CTXBITMAP) { |
| 98 | set_bit(bit, dev->ctx_bitmap); | 98 | set_bit(bit, dev->ctx_bitmap); |
| @@ -113,7 +113,7 @@ static int drm_ctxbitmap_next(drm_device_t * dev) | |||
| 113 | DRM_MEM_MAPS); | 113 | DRM_MEM_MAPS); |
| 114 | if (!ctx_sareas) { | 114 | if (!ctx_sareas) { |
| 115 | clear_bit(bit, dev->ctx_bitmap); | 115 | clear_bit(bit, dev->ctx_bitmap); |
| 116 | up(&dev->struct_sem); | 116 | mutex_unlock(&dev->struct_mutex); |
| 117 | return -1; | 117 | return -1; |
| 118 | } | 118 | } |
| 119 | dev->context_sareas = ctx_sareas; | 119 | dev->context_sareas = ctx_sareas; |
| @@ -126,16 +126,16 @@ static int drm_ctxbitmap_next(drm_device_t * dev) | |||
| 126 | DRM_MEM_MAPS); | 126 | DRM_MEM_MAPS); |
| 127 | if (!dev->context_sareas) { | 127 | if (!dev->context_sareas) { |
| 128 | clear_bit(bit, dev->ctx_bitmap); | 128 | clear_bit(bit, dev->ctx_bitmap); |
| 129 | up(&dev->struct_sem); | 129 | mutex_unlock(&dev->struct_mutex); |
| 130 | return -1; | 130 | return -1; |
| 131 | } | 131 | } |
| 132 | dev->context_sareas[bit] = NULL; | 132 | dev->context_sareas[bit] = NULL; |
| 133 | } | 133 | } |
| 134 | } | 134 | } |
| 135 | up(&dev->struct_sem); | 135 | mutex_unlock(&dev->struct_mutex); |
| 136 | return bit; | 136 | return bit; |
| 137 | } | 137 | } |
| 138 | up(&dev->struct_sem); | 138 | mutex_unlock(&dev->struct_mutex); |
| 139 | return -1; | 139 | return -1; |
| 140 | } | 140 | } |
| 141 | 141 | ||
| @@ -145,24 +145,24 @@ static int drm_ctxbitmap_next(drm_device_t * dev) | |||
| 145 | * \param dev DRM device. | 145 | * \param dev DRM device. |
| 146 | * | 146 | * |
| 147 | * Allocates and initialize drm_device::ctx_bitmap and drm_device::context_sareas, while holding | 147 | * Allocates and initialize drm_device::ctx_bitmap and drm_device::context_sareas, while holding |
| 148 | * the drm_device::struct_sem lock. | 148 | * the drm_device::struct_mutex lock. |
| 149 | */ | 149 | */ |
| 150 | int drm_ctxbitmap_init(drm_device_t * dev) | 150 | int drm_ctxbitmap_init(drm_device_t * dev) |
| 151 | { | 151 | { |
| 152 | int i; | 152 | int i; |
| 153 | int temp; | 153 | int temp; |
| 154 | 154 | ||
| 155 | down(&dev->struct_sem); | 155 | mutex_lock(&dev->struct_mutex); |
| 156 | dev->ctx_bitmap = (unsigned long *)drm_alloc(PAGE_SIZE, | 156 | dev->ctx_bitmap = (unsigned long *)drm_alloc(PAGE_SIZE, |
| 157 | DRM_MEM_CTXBITMAP); | 157 | DRM_MEM_CTXBITMAP); |
| 158 | if (dev->ctx_bitmap == NULL) { | 158 | if (dev->ctx_bitmap == NULL) { |
| 159 | up(&dev->struct_sem); | 159 | mutex_unlock(&dev->struct_mutex); |
| 160 | return -ENOMEM; | 160 | return -ENOMEM; |
| 161 | } | 161 | } |
| 162 | memset((void *)dev->ctx_bitmap, 0, PAGE_SIZE); | 162 | memset((void *)dev->ctx_bitmap, 0, PAGE_SIZE); |
| 163 | dev->context_sareas = NULL; | 163 | dev->context_sareas = NULL; |
| 164 | dev->max_context = -1; | 164 | dev->max_context = -1; |
| 165 | up(&dev->struct_sem); | 165 | mutex_unlock(&dev->struct_mutex); |
| 166 | 166 | ||
| 167 | for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { | 167 | for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { |
| 168 | temp = drm_ctxbitmap_next(dev); | 168 | temp = drm_ctxbitmap_next(dev); |
| @@ -178,17 +178,17 @@ int drm_ctxbitmap_init(drm_device_t * dev) | |||
| 178 | * \param dev DRM device. | 178 | * \param dev DRM device. |
| 179 | * | 179 | * |
| 180 | * Frees drm_device::ctx_bitmap and drm_device::context_sareas, while holding | 180 | * Frees drm_device::ctx_bitmap and drm_device::context_sareas, while holding |
| 181 | * the drm_device::struct_sem lock. | 181 | * the drm_device::struct_mutex lock. |
| 182 | */ | 182 | */ |
| 183 | void drm_ctxbitmap_cleanup(drm_device_t * dev) | 183 | void drm_ctxbitmap_cleanup(drm_device_t * dev) |
| 184 | { | 184 | { |
| 185 | down(&dev->struct_sem); | 185 | mutex_lock(&dev->struct_mutex); |
| 186 | if (dev->context_sareas) | 186 | if (dev->context_sareas) |
| 187 | drm_free(dev->context_sareas, | 187 | drm_free(dev->context_sareas, |
| 188 | sizeof(*dev->context_sareas) * | 188 | sizeof(*dev->context_sareas) * |
| 189 | dev->max_context, DRM_MEM_MAPS); | 189 | dev->max_context, DRM_MEM_MAPS); |
| 190 | drm_free((void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP); | 190 | drm_free((void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP); |
| 191 | up(&dev->struct_sem); | 191 | mutex_unlock(&dev->struct_mutex); |
| 192 | } | 192 | } |
| 193 | 193 | ||
| 194 | /*@}*/ | 194 | /*@}*/ |
| @@ -222,15 +222,15 @@ int drm_getsareactx(struct inode *inode, struct file *filp, | |||
| 222 | if (copy_from_user(&request, argp, sizeof(request))) | 222 | if (copy_from_user(&request, argp, sizeof(request))) |
| 223 | return -EFAULT; | 223 | return -EFAULT; |
| 224 | 224 | ||
| 225 | down(&dev->struct_sem); | 225 | mutex_lock(&dev->struct_mutex); |
| 226 | if (dev->max_context < 0 | 226 | if (dev->max_context < 0 |
| 227 | || request.ctx_id >= (unsigned)dev->max_context) { | 227 | || request.ctx_id >= (unsigned)dev->max_context) { |
| 228 | up(&dev->struct_sem); | 228 | mutex_unlock(&dev->struct_mutex); |
| 229 | return -EINVAL; | 229 | return -EINVAL; |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | map = dev->context_sareas[request.ctx_id]; | 232 | map = dev->context_sareas[request.ctx_id]; |
| 233 | up(&dev->struct_sem); | 233 | mutex_unlock(&dev->struct_mutex); |
| 234 | 234 | ||
| 235 | request.handle = NULL; | 235 | request.handle = NULL; |
| 236 | list_for_each_entry(_entry, &dev->maplist->head, head) { | 236 | list_for_each_entry(_entry, &dev->maplist->head, head) { |
| @@ -274,7 +274,7 @@ int drm_setsareactx(struct inode *inode, struct file *filp, | |||
| 274 | (drm_ctx_priv_map_t __user *) arg, sizeof(request))) | 274 | (drm_ctx_priv_map_t __user *) arg, sizeof(request))) |
| 275 | return -EFAULT; | 275 | return -EFAULT; |
| 276 | 276 | ||
| 277 | down(&dev->struct_sem); | 277 | mutex_lock(&dev->struct_mutex); |
| 278 | list_for_each(list, &dev->maplist->head) { | 278 | list_for_each(list, &dev->maplist->head) { |
| 279 | r_list = list_entry(list, drm_map_list_t, head); | 279 | r_list = list_entry(list, drm_map_list_t, head); |
| 280 | if (r_list->map | 280 | if (r_list->map |
| @@ -282,7 +282,7 @@ int drm_setsareactx(struct inode *inode, struct file *filp, | |||
| 282 | goto found; | 282 | goto found; |
| 283 | } | 283 | } |
| 284 | bad: | 284 | bad: |
| 285 | up(&dev->struct_sem); | 285 | mutex_unlock(&dev->struct_mutex); |
| 286 | return -EINVAL; | 286 | return -EINVAL; |
| 287 | 287 | ||
| 288 | found: | 288 | found: |
| @@ -294,7 +294,7 @@ int drm_setsareactx(struct inode *inode, struct file *filp, | |||
| 294 | if (request.ctx_id >= (unsigned)dev->max_context) | 294 | if (request.ctx_id >= (unsigned)dev->max_context) |
| 295 | goto bad; | 295 | goto bad; |
| 296 | dev->context_sareas[request.ctx_id] = map; | 296 | dev->context_sareas[request.ctx_id] = map; |
| 297 | up(&dev->struct_sem); | 297 | mutex_unlock(&dev->struct_mutex); |
| 298 | return 0; | 298 | return 0; |
| 299 | } | 299 | } |
| 300 | 300 | ||
| @@ -448,10 +448,10 @@ int drm_addctx(struct inode *inode, struct file *filp, | |||
| 448 | ctx_entry->handle = ctx.handle; | 448 | ctx_entry->handle = ctx.handle; |
| 449 | ctx_entry->tag = priv; | 449 | ctx_entry->tag = priv; |
| 450 | 450 | ||
| 451 | down(&dev->ctxlist_sem); | 451 | mutex_lock(&dev->ctxlist_mutex); |
| 452 | list_add(&ctx_entry->head, &dev->ctxlist->head); | 452 | list_add(&ctx_entry->head, &dev->ctxlist->head); |
| 453 | ++dev->ctx_count; | 453 | ++dev->ctx_count; |
| 454 | up(&dev->ctxlist_sem); | 454 | mutex_unlock(&dev->ctxlist_mutex); |
| 455 | 455 | ||
| 456 | if (copy_to_user(argp, &ctx, sizeof(ctx))) | 456 | if (copy_to_user(argp, &ctx, sizeof(ctx))) |
| 457 | return -EFAULT; | 457 | return -EFAULT; |
| @@ -574,7 +574,7 @@ int drm_rmctx(struct inode *inode, struct file *filp, | |||
| 574 | drm_ctxbitmap_free(dev, ctx.handle); | 574 | drm_ctxbitmap_free(dev, ctx.handle); |
| 575 | } | 575 | } |
| 576 | 576 | ||
| 577 | down(&dev->ctxlist_sem); | 577 | mutex_lock(&dev->ctxlist_mutex); |
| 578 | if (!list_empty(&dev->ctxlist->head)) { | 578 | if (!list_empty(&dev->ctxlist->head)) { |
| 579 | drm_ctx_list_t *pos, *n; | 579 | drm_ctx_list_t *pos, *n; |
| 580 | 580 | ||
| @@ -586,7 +586,7 @@ int drm_rmctx(struct inode *inode, struct file *filp, | |||
| 586 | } | 586 | } |
| 587 | } | 587 | } |
| 588 | } | 588 | } |
| 589 | up(&dev->ctxlist_sem); | 589 | mutex_unlock(&dev->ctxlist_mutex); |
| 590 | 590 | ||
| 591 | return 0; | 591 | return 0; |
| 592 | } | 592 | } |
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c index c4fa5a29582b..dc6bbe8a18dc 100644 --- a/drivers/char/drm/drm_drv.c +++ b/drivers/char/drm/drm_drv.c | |||
| @@ -151,7 +151,7 @@ int drm_lastclose(drm_device_t * dev) | |||
| 151 | if (dev->irq_enabled) | 151 | if (dev->irq_enabled) |
| 152 | drm_irq_uninstall(dev); | 152 | drm_irq_uninstall(dev); |
| 153 | 153 | ||
| 154 | down(&dev->struct_sem); | 154 | mutex_lock(&dev->struct_mutex); |
| 155 | del_timer(&dev->timer); | 155 | del_timer(&dev->timer); |
| 156 | 156 | ||
| 157 | /* Clear pid list */ | 157 | /* Clear pid list */ |
| @@ -231,7 +231,7 @@ int drm_lastclose(drm_device_t * dev) | |||
| 231 | dev->lock.filp = NULL; | 231 | dev->lock.filp = NULL; |
| 232 | wake_up_interruptible(&dev->lock.lock_queue); | 232 | wake_up_interruptible(&dev->lock.lock_queue); |
| 233 | } | 233 | } |
| 234 | up(&dev->struct_sem); | 234 | mutex_unlock(&dev->struct_mutex); |
| 235 | 235 | ||
| 236 | DRM_DEBUG("lastclose completed\n"); | 236 | DRM_DEBUG("lastclose completed\n"); |
| 237 | return 0; | 237 | return 0; |
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c index 403f44a1bf01..641f7633878c 100644 --- a/drivers/char/drm/drm_fops.c +++ b/drivers/char/drm/drm_fops.c | |||
| @@ -262,7 +262,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, | |||
| 262 | goto out_free; | 262 | goto out_free; |
| 263 | } | 263 | } |
| 264 | 264 | ||
| 265 | down(&dev->struct_sem); | 265 | mutex_lock(&dev->struct_mutex); |
| 266 | if (!dev->file_last) { | 266 | if (!dev->file_last) { |
| 267 | priv->next = NULL; | 267 | priv->next = NULL; |
| 268 | priv->prev = NULL; | 268 | priv->prev = NULL; |
| @@ -276,7 +276,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, | |||
| 276 | dev->file_last->next = priv; | 276 | dev->file_last->next = priv; |
| 277 | dev->file_last = priv; | 277 | dev->file_last = priv; |
| 278 | } | 278 | } |
| 279 | up(&dev->struct_sem); | 279 | mutex_unlock(&dev->struct_mutex); |
| 280 | 280 | ||
| 281 | #ifdef __alpha__ | 281 | #ifdef __alpha__ |
| 282 | /* | 282 | /* |
| @@ -413,7 +413,7 @@ int drm_release(struct inode *inode, struct file *filp) | |||
| 413 | 413 | ||
| 414 | drm_fasync(-1, filp, 0); | 414 | drm_fasync(-1, filp, 0); |
| 415 | 415 | ||
| 416 | down(&dev->ctxlist_sem); | 416 | mutex_lock(&dev->ctxlist_mutex); |
| 417 | if (dev->ctxlist && (!list_empty(&dev->ctxlist->head))) { | 417 | if (dev->ctxlist && (!list_empty(&dev->ctxlist->head))) { |
| 418 | drm_ctx_list_t *pos, *n; | 418 | drm_ctx_list_t *pos, *n; |
| 419 | 419 | ||
| @@ -432,9 +432,9 @@ int drm_release(struct inode *inode, struct file *filp) | |||
| 432 | } | 432 | } |
| 433 | } | 433 | } |
| 434 | } | 434 | } |
| 435 | up(&dev->ctxlist_sem); | 435 | mutex_unlock(&dev->ctxlist_mutex); |
| 436 | 436 | ||
| 437 | down(&dev->struct_sem); | 437 | mutex_lock(&dev->struct_mutex); |
| 438 | if (priv->remove_auth_on_close == 1) { | 438 | if (priv->remove_auth_on_close == 1) { |
| 439 | drm_file_t *temp = dev->file_first; | 439 | drm_file_t *temp = dev->file_first; |
| 440 | while (temp) { | 440 | while (temp) { |
| @@ -452,7 +452,7 @@ int drm_release(struct inode *inode, struct file *filp) | |||
| 452 | } else { | 452 | } else { |
| 453 | dev->file_last = priv->prev; | 453 | dev->file_last = priv->prev; |
| 454 | } | 454 | } |
| 455 | up(&dev->struct_sem); | 455 | mutex_unlock(&dev->struct_mutex); |
| 456 | 456 | ||
| 457 | if (dev->driver->postclose) | 457 | if (dev->driver->postclose) |
| 458 | dev->driver->postclose(dev, priv); | 458 | dev->driver->postclose(dev, priv); |
diff --git a/drivers/char/drm/drm_ioctl.c b/drivers/char/drm/drm_ioctl.c index bcd4e604d3ec..555f323b8a32 100644 --- a/drivers/char/drm/drm_ioctl.c +++ b/drivers/char/drm/drm_ioctl.c | |||
| @@ -194,9 +194,9 @@ int drm_getmap(struct inode *inode, struct file *filp, | |||
| 194 | return -EFAULT; | 194 | return -EFAULT; |
| 195 | idx = map.offset; | 195 | idx = map.offset; |
| 196 | 196 | ||
| 197 | down(&dev->struct_sem); | 197 | mutex_lock(&dev->struct_mutex); |
| 198 | if (idx < 0) { | 198 | if (idx < 0) { |
| 199 | up(&dev->struct_sem); | 199 | mutex_unlock(&dev->struct_mutex); |
| 200 | return -EINVAL; | 200 | return -EINVAL; |
| 201 | } | 201 | } |
| 202 | 202 | ||
| @@ -209,7 +209,7 @@ int drm_getmap(struct inode *inode, struct file *filp, | |||
| 209 | i++; | 209 | i++; |
| 210 | } | 210 | } |
| 211 | if (!r_list || !r_list->map) { | 211 | if (!r_list || !r_list->map) { |
| 212 | up(&dev->struct_sem); | 212 | mutex_unlock(&dev->struct_mutex); |
| 213 | return -EINVAL; | 213 | return -EINVAL; |
| 214 | } | 214 | } |
| 215 | 215 | ||
| @@ -219,7 +219,7 @@ int drm_getmap(struct inode *inode, struct file *filp, | |||
| 219 | map.flags = r_list->map->flags; | 219 | map.flags = r_list->map->flags; |
| 220 | map.handle = (void *)(unsigned long)r_list->user_token; | 220 | map.handle = (void *)(unsigned long)r_list->user_token; |
| 221 | map.mtrr = r_list->map->mtrr; | 221 | map.mtrr = r_list->map->mtrr; |
| 222 | up(&dev->struct_sem); | 222 | mutex_unlock(&dev->struct_mutex); |
| 223 | 223 | ||
| 224 | if (copy_to_user(argp, &map, sizeof(map))) | 224 | if (copy_to_user(argp, &map, sizeof(map))) |
| 225 | return -EFAULT; | 225 | return -EFAULT; |
| @@ -253,11 +253,11 @@ int drm_getclient(struct inode *inode, struct file *filp, | |||
| 253 | if (copy_from_user(&client, argp, sizeof(client))) | 253 | if (copy_from_user(&client, argp, sizeof(client))) |
| 254 | return -EFAULT; | 254 | return -EFAULT; |
| 255 | idx = client.idx; | 255 | idx = client.idx; |
| 256 | down(&dev->struct_sem); | 256 | mutex_lock(&dev->struct_mutex); |
| 257 | for (i = 0, pt = dev->file_first; i < idx && pt; i++, pt = pt->next) ; | 257 | for (i = 0, pt = dev->file_first; i < idx && pt; i++, pt = pt->next) ; |
| 258 | 258 | ||
| 259 | if (!pt) { | 259 | if (!pt) { |
| 260 | up(&dev->struct_sem); | 260 | mutex_unlock(&dev->struct_mutex); |
| 261 | return -EINVAL; | 261 | return -EINVAL; |
| 262 | } | 262 | } |
| 263 | client.auth = pt->authenticated; | 263 | client.auth = pt->authenticated; |
| @@ -265,7 +265,7 @@ int drm_getclient(struct inode *inode, struct file *filp, | |||
| 265 | client.uid = pt->uid; | 265 | client.uid = pt->uid; |
| 266 | client.magic = pt->magic; | 266 | client.magic = pt->magic; |
| 267 | client.iocs = pt->ioctl_count; | 267 | client.iocs = pt->ioctl_count; |
| 268 | up(&dev->struct_sem); | 268 | mutex_unlock(&dev->struct_mutex); |
| 269 | 269 | ||
| 270 | if (copy_to_user(argp, &client, sizeof(client))) | 270 | if (copy_to_user(argp, &client, sizeof(client))) |
| 271 | return -EFAULT; | 271 | return -EFAULT; |
| @@ -292,7 +292,7 @@ int drm_getstats(struct inode *inode, struct file *filp, | |||
| 292 | 292 | ||
| 293 | memset(&stats, 0, sizeof(stats)); | 293 | memset(&stats, 0, sizeof(stats)); |
| 294 | 294 | ||
| 295 | down(&dev->struct_sem); | 295 | mutex_lock(&dev->struct_mutex); |
| 296 | 296 | ||
| 297 | for (i = 0; i < dev->counters; i++) { | 297 | for (i = 0; i < dev->counters; i++) { |
| 298 | if (dev->types[i] == _DRM_STAT_LOCK) | 298 | if (dev->types[i] == _DRM_STAT_LOCK) |
| @@ -305,7 +305,7 @@ int drm_getstats(struct inode *inode, struct file *filp, | |||
| 305 | 305 | ||
| 306 | stats.count = dev->counters; | 306 | stats.count = dev->counters; |
| 307 | 307 | ||
| 308 | up(&dev->struct_sem); | 308 | mutex_unlock(&dev->struct_mutex); |
| 309 | 309 | ||
| 310 | if (copy_to_user((drm_stats_t __user *) arg, &stats, sizeof(stats))) | 310 | if (copy_to_user((drm_stats_t __user *) arg, &stats, sizeof(stats))) |
| 311 | return -EFAULT; | 311 | return -EFAULT; |
diff --git a/drivers/char/drm/drm_irq.c b/drivers/char/drm/drm_irq.c index b0d4b236e837..611a1173091d 100644 --- a/drivers/char/drm/drm_irq.c +++ b/drivers/char/drm/drm_irq.c | |||
| @@ -98,20 +98,20 @@ static int drm_irq_install(drm_device_t * dev) | |||
| 98 | if (dev->irq == 0) | 98 | if (dev->irq == 0) |
| 99 | return -EINVAL; | 99 | return -EINVAL; |
| 100 | 100 | ||
| 101 | down(&dev->struct_sem); | 101 | mutex_lock(&dev->struct_mutex); |
| 102 | 102 | ||
| 103 | /* Driver must have been initialized */ | 103 | /* Driver must have been initialized */ |
| 104 | if (!dev->dev_private) { | 104 | if (!dev->dev_private) { |
| 105 | up(&dev->struct_sem); | 105 | mutex_unlock(&dev->struct_mutex); |
| 106 | return -EINVAL; | 106 | return -EINVAL; |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | if (dev->irq_enabled) { | 109 | if (dev->irq_enabled) { |
| 110 | up(&dev->struct_sem); | 110 | mutex_unlock(&dev->struct_mutex); |
| 111 | return -EBUSY; | 111 | return -EBUSY; |
| 112 | } | 112 | } |
| 113 | dev->irq_enabled = 1; | 113 | dev->irq_enabled = 1; |
| 114 | up(&dev->struct_sem); | 114 | mutex_unlock(&dev->struct_mutex); |
| 115 | 115 | ||
| 116 | DRM_DEBUG("%s: irq=%d\n", __FUNCTION__, dev->irq); | 116 | DRM_DEBUG("%s: irq=%d\n", __FUNCTION__, dev->irq); |
| 117 | 117 | ||
| @@ -135,9 +135,9 @@ static int drm_irq_install(drm_device_t * dev) | |||
| 135 | ret = request_irq(dev->irq, dev->driver->irq_handler, | 135 | ret = request_irq(dev->irq, dev->driver->irq_handler, |
| 136 | sh_flags, dev->devname, dev); | 136 | sh_flags, dev->devname, dev); |
| 137 | if (ret < 0) { | 137 | if (ret < 0) { |
| 138 | down(&dev->struct_sem); | 138 | mutex_lock(&dev->struct_mutex); |
| 139 | dev->irq_enabled = 0; | 139 | dev->irq_enabled = 0; |
| 140 | up(&dev->struct_sem); | 140 | mutex_unlock(&dev->struct_mutex); |
| 141 | return ret; | 141 | return ret; |
| 142 | } | 142 | } |
| 143 | 143 | ||
| @@ -161,10 +161,10 @@ int drm_irq_uninstall(drm_device_t * dev) | |||
| 161 | if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) | 161 | if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) |
| 162 | return -EINVAL; | 162 | return -EINVAL; |
| 163 | 163 | ||
| 164 | down(&dev->struct_sem); | 164 | mutex_lock(&dev->struct_mutex); |
| 165 | irq_enabled = dev->irq_enabled; | 165 | irq_enabled = dev->irq_enabled; |
| 166 | dev->irq_enabled = 0; | 166 | dev->irq_enabled = 0; |
| 167 | up(&dev->struct_sem); | 167 | mutex_unlock(&dev->struct_mutex); |
| 168 | 168 | ||
| 169 | if (!irq_enabled) | 169 | if (!irq_enabled) |
| 170 | return -EINVAL; | 170 | return -EINVAL; |
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h index 5b1d3a04458d..8fd6357a48da 100644 --- a/drivers/char/drm/drm_pciids.h +++ b/drivers/char/drm/drm_pciids.h | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | Please contact dri-devel@lists.sf.net to add new cards to this list | 3 | Please contact dri-devel@lists.sf.net to add new cards to this list |
| 4 | */ | 4 | */ |
| 5 | #define radeon_PCI_IDS \ | 5 | #define radeon_PCI_IDS \ |
| 6 | {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350},\ | ||
| 6 | {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP}, \ | 7 | {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|CHIP_IS_IGP}, \ |
| 7 | {0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP}, \ | 8 | {0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|CHIP_IS_IGP}, \ |
| 8 | {0x1002, 0x4144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ | 9 | {0x1002, 0x4144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \ |
| @@ -242,5 +243,6 @@ | |||
| 242 | {0x8086, 0x2582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 243 | {0x8086, 0x2582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
| 243 | {0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 244 | {0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
| 244 | {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | 245 | {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ |
| 246 | {0x8086, 0x27a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \ | ||
| 245 | {0, 0, 0} | 247 | {0, 0, 0} |
| 246 | 248 | ||
diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c index 6f943e3309ef..362a270af0f1 100644 --- a/drivers/char/drm/drm_proc.c +++ b/drivers/char/drm/drm_proc.c | |||
| @@ -258,7 +258,7 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request, | |||
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | /** | 260 | /** |
| 261 | * Simply calls _vm_info() while holding the drm_device::struct_sem lock. | 261 | * Simply calls _vm_info() while holding the drm_device::struct_mutex lock. |
| 262 | */ | 262 | */ |
| 263 | static int drm_vm_info(char *buf, char **start, off_t offset, int request, | 263 | static int drm_vm_info(char *buf, char **start, off_t offset, int request, |
| 264 | int *eof, void *data) | 264 | int *eof, void *data) |
| @@ -266,9 +266,9 @@ static int drm_vm_info(char *buf, char **start, off_t offset, int request, | |||
| 266 | drm_device_t *dev = (drm_device_t *) data; | 266 | drm_device_t *dev = (drm_device_t *) data; |
| 267 | int ret; | 267 | int ret; |
| 268 | 268 | ||
| 269 | down(&dev->struct_sem); | 269 | mutex_lock(&dev->struct_mutex); |
| 270 | ret = drm__vm_info(buf, start, offset, request, eof, data); | 270 | ret = drm__vm_info(buf, start, offset, request, eof, data); |
| 271 | up(&dev->struct_sem); | 271 | mutex_unlock(&dev->struct_mutex); |
| 272 | return ret; | 272 | return ret; |
| 273 | } | 273 | } |
| 274 | 274 | ||
| @@ -331,7 +331,7 @@ static int drm__queues_info(char *buf, char **start, off_t offset, | |||
| 331 | } | 331 | } |
| 332 | 332 | ||
| 333 | /** | 333 | /** |
| 334 | * Simply calls _queues_info() while holding the drm_device::struct_sem lock. | 334 | * Simply calls _queues_info() while holding the drm_device::struct_mutex lock. |
| 335 | */ | 335 | */ |
| 336 | static int drm_queues_info(char *buf, char **start, off_t offset, int request, | 336 | static int drm_queues_info(char *buf, char **start, off_t offset, int request, |
| 337 | int *eof, void *data) | 337 | int *eof, void *data) |
| @@ -339,9 +339,9 @@ static int drm_queues_info(char *buf, char **start, off_t offset, int request, | |||
| 339 | drm_device_t *dev = (drm_device_t *) data; | 339 | drm_device_t *dev = (drm_device_t *) data; |
| 340 | int ret; | 340 | int ret; |
| 341 | 341 | ||
| 342 | down(&dev->struct_sem); | 342 | mutex_lock(&dev->struct_mutex); |
| 343 | ret = drm__queues_info(buf, start, offset, request, eof, data); | 343 | ret = drm__queues_info(buf, start, offset, request, eof, data); |
| 344 | up(&dev->struct_sem); | 344 | mutex_unlock(&dev->struct_mutex); |
| 345 | return ret; | 345 | return ret; |
| 346 | } | 346 | } |
| 347 | 347 | ||
| @@ -403,7 +403,7 @@ static int drm__bufs_info(char *buf, char **start, off_t offset, int request, | |||
| 403 | } | 403 | } |
| 404 | 404 | ||
| 405 | /** | 405 | /** |
| 406 | * Simply calls _bufs_info() while holding the drm_device::struct_sem lock. | 406 | * Simply calls _bufs_info() while holding the drm_device::struct_mutex lock. |
| 407 | */ | 407 | */ |
| 408 | static int drm_bufs_info(char *buf, char **start, off_t offset, int request, | 408 | static int drm_bufs_info(char *buf, char **start, off_t offset, int request, |
| 409 | int *eof, void *data) | 409 | int *eof, void *data) |
| @@ -411,9 +411,9 @@ static int drm_bufs_info(char *buf, char **start, off_t offset, int request, | |||
| 411 | drm_device_t *dev = (drm_device_t *) data; | 411 | drm_device_t *dev = (drm_device_t *) data; |
| 412 | int ret; | 412 | int ret; |
| 413 | 413 | ||
| 414 | down(&dev->struct_sem); | 414 | mutex_lock(&dev->struct_mutex); |
| 415 | ret = drm__bufs_info(buf, start, offset, request, eof, data); | 415 | ret = drm__bufs_info(buf, start, offset, request, eof, data); |
| 416 | up(&dev->struct_sem); | 416 | mutex_unlock(&dev->struct_mutex); |
| 417 | return ret; | 417 | return ret; |
| 418 | } | 418 | } |
| 419 | 419 | ||
| @@ -459,7 +459,7 @@ static int drm__clients_info(char *buf, char **start, off_t offset, | |||
| 459 | } | 459 | } |
| 460 | 460 | ||
| 461 | /** | 461 | /** |
| 462 | * Simply calls _clients_info() while holding the drm_device::struct_sem lock. | 462 | * Simply calls _clients_info() while holding the drm_device::struct_mutex lock. |
| 463 | */ | 463 | */ |
| 464 | static int drm_clients_info(char *buf, char **start, off_t offset, | 464 | static int drm_clients_info(char *buf, char **start, off_t offset, |
| 465 | int request, int *eof, void *data) | 465 | int request, int *eof, void *data) |
| @@ -467,9 +467,9 @@ static int drm_clients_info(char *buf, char **start, off_t offset, | |||
| 467 | drm_device_t *dev = (drm_device_t *) data; | 467 | drm_device_t *dev = (drm_device_t *) data; |
| 468 | int ret; | 468 | int ret; |
| 469 | 469 | ||
| 470 | down(&dev->struct_sem); | 470 | mutex_lock(&dev->struct_mutex); |
| 471 | ret = drm__clients_info(buf, start, offset, request, eof, data); | 471 | ret = drm__clients_info(buf, start, offset, request, eof, data); |
| 472 | up(&dev->struct_sem); | 472 | mutex_unlock(&dev->struct_mutex); |
| 473 | return ret; | 473 | return ret; |
| 474 | } | 474 | } |
| 475 | 475 | ||
| @@ -540,9 +540,9 @@ static int drm_vma_info(char *buf, char **start, off_t offset, int request, | |||
| 540 | drm_device_t *dev = (drm_device_t *) data; | 540 | drm_device_t *dev = (drm_device_t *) data; |
| 541 | int ret; | 541 | int ret; |
| 542 | 542 | ||
| 543 | down(&dev->struct_sem); | 543 | mutex_lock(&dev->struct_mutex); |
| 544 | ret = drm__vma_info(buf, start, offset, request, eof, data); | 544 | ret = drm__vma_info(buf, start, offset, request, eof, data); |
| 545 | up(&dev->struct_sem); | 545 | mutex_unlock(&dev->struct_mutex); |
| 546 | return ret; | 546 | return ret; |
| 547 | } | 547 | } |
| 548 | #endif | 548 | #endif |
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c index 42d766359caa..68073e14fdec 100644 --- a/drivers/char/drm/drm_stub.c +++ b/drivers/char/drm/drm_stub.c | |||
| @@ -50,7 +50,7 @@ module_param_named(cards_limit, drm_cards_limit, int, 0444); | |||
| 50 | module_param_named(debug, drm_debug, int, 0600); | 50 | module_param_named(debug, drm_debug, int, 0600); |
| 51 | 51 | ||
| 52 | drm_head_t **drm_heads; | 52 | drm_head_t **drm_heads; |
| 53 | struct drm_sysfs_class *drm_class; | 53 | struct class *drm_class; |
| 54 | struct proc_dir_entry *drm_proc_root; | 54 | struct proc_dir_entry *drm_proc_root; |
| 55 | 55 | ||
| 56 | static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, | 56 | static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, |
| @@ -61,8 +61,8 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, | |||
| 61 | 61 | ||
| 62 | spin_lock_init(&dev->count_lock); | 62 | spin_lock_init(&dev->count_lock); |
| 63 | init_timer(&dev->timer); | 63 | init_timer(&dev->timer); |
| 64 | sema_init(&dev->struct_sem, 1); | 64 | mutex_init(&dev->struct_mutex); |
| 65 | sema_init(&dev->ctxlist_sem, 1); | 65 | mutex_init(&dev->ctxlist_mutex); |
| 66 | 66 | ||
| 67 | dev->pdev = pdev; | 67 | dev->pdev = pdev; |
| 68 | 68 | ||
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c index 68e43ddc16ae..0b9f98a7eb10 100644 --- a/drivers/char/drm/drm_sysfs.c +++ b/drivers/char/drm/drm_sysfs.c | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | |||
| 1 | /* | 2 | /* |
| 2 | * drm_sysfs.c - Modifications to drm_sysfs_class.c to support | 3 | * drm_sysfs.c - Modifications to drm_sysfs_class.c to support |
| 3 | * extra sysfs attribute from DRM. Normal drm_sysfs_class | 4 | * extra sysfs attribute from DRM. Normal drm_sysfs_class |
| @@ -19,36 +20,6 @@ | |||
| 19 | #include "drm_core.h" | 20 | #include "drm_core.h" |
| 20 | #include "drmP.h" | 21 | #include "drmP.h" |
| 21 | 22 | ||
| 22 | struct drm_sysfs_class { | ||
| 23 | struct class_device_attribute attr; | ||
| 24 | struct class class; | ||
| 25 | }; | ||
| 26 | #define to_drm_sysfs_class(d) container_of(d, struct drm_sysfs_class, class) | ||
| 27 | |||
| 28 | struct simple_dev { | ||
| 29 | dev_t dev; | ||
| 30 | struct class_device class_dev; | ||
| 31 | }; | ||
| 32 | #define to_simple_dev(d) container_of(d, struct simple_dev, class_dev) | ||
| 33 | |||
| 34 | static void release_simple_dev(struct class_device *class_dev) | ||
| 35 | { | ||
| 36 | struct simple_dev *s_dev = to_simple_dev(class_dev); | ||
| 37 | kfree(s_dev); | ||
| 38 | } | ||
| 39 | |||
| 40 | static ssize_t show_dev(struct class_device *class_dev, char *buf) | ||
| 41 | { | ||
| 42 | struct simple_dev *s_dev = to_simple_dev(class_dev); | ||
| 43 | return print_dev_t(buf, s_dev->dev); | ||
| 44 | } | ||
| 45 | |||
| 46 | static void drm_sysfs_class_release(struct class *class) | ||
| 47 | { | ||
| 48 | struct drm_sysfs_class *cs = to_drm_sysfs_class(class); | ||
| 49 | kfree(cs); | ||
| 50 | } | ||
| 51 | |||
| 52 | /* Display the version of drm_core. This doesn't work right in current design */ | 23 | /* Display the version of drm_core. This doesn't work right in current design */ |
| 53 | static ssize_t version_show(struct class *dev, char *buf) | 24 | static ssize_t version_show(struct class *dev, char *buf) |
| 54 | { | 25 | { |
| @@ -69,38 +40,16 @@ static CLASS_ATTR(version, S_IRUGO, version_show, NULL); | |||
| 69 | * Note, the pointer created here is to be destroyed when finished by making a | 40 | * Note, the pointer created here is to be destroyed when finished by making a |
| 70 | * call to drm_sysfs_destroy(). | 41 | * call to drm_sysfs_destroy(). |
| 71 | */ | 42 | */ |
| 72 | struct drm_sysfs_class *drm_sysfs_create(struct module *owner, char *name) | 43 | struct class *drm_sysfs_create(struct module *owner, char *name) |
| 73 | { | 44 | { |
| 74 | struct drm_sysfs_class *cs; | 45 | struct class *class; |
| 75 | int retval; | 46 | |
| 76 | 47 | class = class_create(owner, name); | |
| 77 | cs = kmalloc(sizeof(*cs), GFP_KERNEL); | 48 | if (!class) |
| 78 | if (!cs) { | 49 | return class; |
| 79 | retval = -ENOMEM; | 50 | |
| 80 | goto error; | 51 | class_create_file(class, &class_attr_version); |
| 81 | } | 52 | return class; |
| 82 | memset(cs, 0x00, sizeof(*cs)); | ||
| 83 | |||
| 84 | cs->class.name = name; | ||
| 85 | cs->class.class_release = drm_sysfs_class_release; | ||
| 86 | cs->class.release = release_simple_dev; | ||
| 87 | |||
| 88 | cs->attr.attr.name = "dev"; | ||
| 89 | cs->attr.attr.mode = S_IRUGO; | ||
| 90 | cs->attr.attr.owner = owner; | ||
| 91 | cs->attr.show = show_dev; | ||
| 92 | cs->attr.store = NULL; | ||
| 93 | |||
| 94 | retval = class_register(&cs->class); | ||
| 95 | if (retval) | ||
| 96 | goto error; | ||
| 97 | class_create_file(&cs->class, &class_attr_version); | ||
| 98 | |||
| 99 | return cs; | ||
| 100 | |||
| 101 | error: | ||
| 102 | kfree(cs); | ||
| 103 | return ERR_PTR(retval); | ||
| 104 | } | 53 | } |
| 105 | 54 | ||
| 106 | /** | 55 | /** |
| @@ -110,12 +59,13 @@ struct drm_sysfs_class *drm_sysfs_create(struct module *owner, char *name) | |||
| 110 | * Note, the pointer to be destroyed must have been created with a call to | 59 | * Note, the pointer to be destroyed must have been created with a call to |
| 111 | * drm_sysfs_create(). | 60 | * drm_sysfs_create(). |
| 112 | */ | 61 | */ |
| 113 | void drm_sysfs_destroy(struct drm_sysfs_class *cs) | 62 | void drm_sysfs_destroy(struct class *class) |
| 114 | { | 63 | { |
| 115 | if ((cs == NULL) || (IS_ERR(cs))) | 64 | if ((class == NULL) || (IS_ERR(class))) |
| 116 | return; | 65 | return; |
| 117 | 66 | ||
| 118 | class_unregister(&cs->class); | 67 | class_remove_file(class, &class_attr_version); |
| 68 | class_destroy(class); | ||
| 119 | } | 69 | } |
| 120 | 70 | ||
| 121 | static ssize_t show_dri(struct class_device *class_device, char *buf) | 71 | static ssize_t show_dri(struct class_device *class_device, char *buf) |
| @@ -132,7 +82,7 @@ static struct class_device_attribute class_device_attrs[] = { | |||
| 132 | 82 | ||
| 133 | /** | 83 | /** |
| 134 | * drm_sysfs_device_add - adds a class device to sysfs for a character driver | 84 | * drm_sysfs_device_add - adds a class device to sysfs for a character driver |
| 135 | * @cs: pointer to the struct drm_sysfs_class that this device should be registered to. | 85 | * @cs: pointer to the struct class that this device should be registered to. |
| 136 | * @dev: the dev_t for the device to be added. | 86 | * @dev: the dev_t for the device to be added. |
| 137 | * @device: a pointer to a struct device that is assiociated with this class device. | 87 | * @device: a pointer to a struct device that is assiociated with this class device. |
| 138 | * @fmt: string for the class device's name | 88 | * @fmt: string for the class device's name |
| @@ -141,46 +91,26 @@ static struct class_device_attribute class_device_attrs[] = { | |||
| 141 | * class. A "dev" file will be created, showing the dev_t for the device. The | 91 | * class. A "dev" file will be created, showing the dev_t for the device. The |
| 142 | * pointer to the struct class_device will be returned from the call. Any further | 92 | * pointer to the struct class_device will be returned from the call. Any further |
| 143 | * sysfs files that might be required can be created using this pointer. | 93 | * sysfs files that might be required can be created using this pointer. |
| 144 | * Note: the struct drm_sysfs_class passed to this function must have previously been | 94 | * Note: the struct class passed to this function must have previously been |
| 145 | * created with a call to drm_sysfs_create(). | 95 | * created with a call to drm_sysfs_create(). |
| 146 | */ | 96 | */ |
| 147 | struct class_device *drm_sysfs_device_add(struct drm_sysfs_class *cs, | 97 | struct class_device *drm_sysfs_device_add(struct class *cs, drm_head_t *head) |
| 148 | drm_head_t *head) | ||
| 149 | { | 98 | { |
| 150 | struct simple_dev *s_dev = NULL; | 99 | struct class_device *class_dev; |
| 151 | int i, retval; | 100 | int i; |
| 152 | |||
| 153 | if ((cs == NULL) || (IS_ERR(cs))) { | ||
| 154 | retval = -ENODEV; | ||
| 155 | goto error; | ||
| 156 | } | ||
| 157 | |||
| 158 | s_dev = kmalloc(sizeof(*s_dev), GFP_KERNEL); | ||
| 159 | if (!s_dev) { | ||
| 160 | retval = -ENOMEM; | ||
| 161 | goto error; | ||
| 162 | } | ||
| 163 | memset(s_dev, 0x00, sizeof(*s_dev)); | ||
| 164 | |||
| 165 | s_dev->dev = MKDEV(DRM_MAJOR, head->minor); | ||
| 166 | s_dev->class_dev.dev = &(head->dev->pdev)->dev; | ||
| 167 | s_dev->class_dev.class = &cs->class; | ||
| 168 | 101 | ||
| 169 | snprintf(s_dev->class_dev.class_id, BUS_ID_SIZE, "card%d", head->minor); | 102 | class_dev = class_device_create(cs, NULL, |
| 170 | retval = class_device_register(&s_dev->class_dev); | 103 | MKDEV(DRM_MAJOR, head->minor), |
| 171 | if (retval) | 104 | &(head->dev->pdev)->dev, |
| 172 | goto error; | 105 | "card%d", head->minor); |
| 106 | if (!class_dev) | ||
| 107 | return NULL; | ||
| 173 | 108 | ||
| 174 | class_device_create_file(&s_dev->class_dev, &cs->attr); | 109 | class_set_devdata(class_dev, head); |
| 175 | class_set_devdata(&s_dev->class_dev, head); | ||
| 176 | 110 | ||
| 177 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) | 111 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) |
| 178 | class_device_create_file(&s_dev->class_dev, &class_device_attrs[i]); | 112 | class_device_create_file(class_dev, &class_device_attrs[i]); |
| 179 | return &s_dev->class_dev; | 113 | return class_dev; |
| 180 | |||
| 181 | error: | ||
| 182 | kfree(s_dev); | ||
| 183 | return ERR_PTR(retval); | ||
| 184 | } | 114 | } |
| 185 | 115 | ||
| 186 | /** | 116 | /** |
| @@ -192,10 +122,9 @@ error: | |||
| 192 | */ | 122 | */ |
| 193 | void drm_sysfs_device_remove(struct class_device *class_dev) | 123 | void drm_sysfs_device_remove(struct class_device *class_dev) |
| 194 | { | 124 | { |
| 195 | struct simple_dev *s_dev = to_simple_dev(class_dev); | ||
| 196 | int i; | 125 | int i; |
| 197 | 126 | ||
| 198 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) | 127 | for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) |
| 199 | class_device_remove_file(&s_dev->class_dev, &class_device_attrs[i]); | 128 | class_device_remove_file(class_dev, &class_device_attrs[i]); |
| 200 | class_device_unregister(&s_dev->class_dev); | 129 | class_device_unregister(class_dev); |
| 201 | } | 130 | } |
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c index 3f73aa774c80..0291cd62c69f 100644 --- a/drivers/char/drm/drm_vm.c +++ b/drivers/char/drm/drm_vm.c | |||
| @@ -188,7 +188,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) | |||
| 188 | 188 | ||
| 189 | map = vma->vm_private_data; | 189 | map = vma->vm_private_data; |
| 190 | 190 | ||
| 191 | down(&dev->struct_sem); | 191 | mutex_lock(&dev->struct_mutex); |
| 192 | for (pt = dev->vmalist, prev = NULL; pt; pt = next) { | 192 | for (pt = dev->vmalist, prev = NULL; pt; pt = next) { |
| 193 | next = pt->next; | 193 | next = pt->next; |
| 194 | if (pt->vma->vm_private_data == map) | 194 | if (pt->vma->vm_private_data == map) |
| @@ -248,7 +248,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) | |||
| 248 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 248 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); |
| 249 | } | 249 | } |
| 250 | } | 250 | } |
| 251 | up(&dev->struct_sem); | 251 | mutex_unlock(&dev->struct_mutex); |
| 252 | } | 252 | } |
| 253 | 253 | ||
| 254 | /** | 254 | /** |
| @@ -404,12 +404,12 @@ static void drm_vm_open(struct vm_area_struct *vma) | |||
| 404 | 404 | ||
| 405 | vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS); | 405 | vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS); |
| 406 | if (vma_entry) { | 406 | if (vma_entry) { |
| 407 | down(&dev->struct_sem); | 407 | mutex_lock(&dev->struct_mutex); |
| 408 | vma_entry->vma = vma; | 408 | vma_entry->vma = vma; |
| 409 | vma_entry->next = dev->vmalist; | 409 | vma_entry->next = dev->vmalist; |
| 410 | vma_entry->pid = current->pid; | 410 | vma_entry->pid = current->pid; |
| 411 | dev->vmalist = vma_entry; | 411 | dev->vmalist = vma_entry; |
| 412 | up(&dev->struct_sem); | 412 | mutex_unlock(&dev->struct_mutex); |
| 413 | } | 413 | } |
| 414 | } | 414 | } |
| 415 | 415 | ||
| @@ -431,7 +431,7 @@ static void drm_vm_close(struct vm_area_struct *vma) | |||
| 431 | vma->vm_start, vma->vm_end - vma->vm_start); | 431 | vma->vm_start, vma->vm_end - vma->vm_start); |
| 432 | atomic_dec(&dev->vma_count); | 432 | atomic_dec(&dev->vma_count); |
| 433 | 433 | ||
| 434 | down(&dev->struct_sem); | 434 | mutex_lock(&dev->struct_mutex); |
| 435 | for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) { | 435 | for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) { |
| 436 | if (pt->vma == vma) { | 436 | if (pt->vma == vma) { |
| 437 | if (prev) { | 437 | if (prev) { |
| @@ -443,7 +443,7 @@ static void drm_vm_close(struct vm_area_struct *vma) | |||
| 443 | break; | 443 | break; |
| 444 | } | 444 | } |
| 445 | } | 445 | } |
| 446 | up(&dev->struct_sem); | 446 | mutex_unlock(&dev->struct_mutex); |
| 447 | } | 447 | } |
| 448 | 448 | ||
| 449 | /** | 449 | /** |
diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c index cc1b89086876..ae0aa6d7e0bb 100644 --- a/drivers/char/drm/i810_dma.c +++ b/drivers/char/drm/i810_dma.c | |||
| @@ -958,7 +958,7 @@ static int i810_flush_queue(drm_device_t * dev) | |||
| 958 | } | 958 | } |
| 959 | 959 | ||
| 960 | /* Must be called with the lock held */ | 960 | /* Must be called with the lock held */ |
| 961 | void i810_reclaim_buffers(drm_device_t * dev, struct file *filp) | 961 | static void i810_reclaim_buffers(drm_device_t * dev, struct file *filp) |
| 962 | { | 962 | { |
| 963 | drm_device_dma_t *dma = dev->dma; | 963 | drm_device_dma_t *dma = dev->dma; |
| 964 | int i; | 964 | int i; |
diff --git a/drivers/char/drm/i810_drv.h b/drivers/char/drm/i810_drv.h index a18b80d91920..e8cf3ff606f0 100644 --- a/drivers/char/drm/i810_drv.h +++ b/drivers/char/drm/i810_drv.h | |||
| @@ -113,8 +113,6 @@ typedef struct drm_i810_private { | |||
| 113 | } drm_i810_private_t; | 113 | } drm_i810_private_t; |
| 114 | 114 | ||
| 115 | /* i810_dma.c */ | 115 | /* i810_dma.c */ |
| 116 | extern void i810_reclaim_buffers(drm_device_t * dev, struct file *filp); | ||
| 117 | |||
| 118 | extern int i810_driver_dma_quiescent(drm_device_t * dev); | 116 | extern int i810_driver_dma_quiescent(drm_device_t * dev); |
| 119 | extern void i810_driver_reclaim_buffers_locked(drm_device_t * dev, | 117 | extern void i810_driver_reclaim_buffers_locked(drm_device_t * dev, |
| 120 | struct file *filp); | 118 | struct file *filp); |
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c index 4fea32aed6d2..163f2cbfe60d 100644 --- a/drivers/char/drm/i830_dma.c +++ b/drivers/char/drm/i830_dma.c | |||
| @@ -1239,7 +1239,7 @@ static int i830_flush_queue(drm_device_t * dev) | |||
| 1239 | } | 1239 | } |
| 1240 | 1240 | ||
| 1241 | /* Must be called with the lock held */ | 1241 | /* Must be called with the lock held */ |
| 1242 | void i830_reclaim_buffers(drm_device_t * dev, struct file *filp) | 1242 | static void i830_reclaim_buffers(drm_device_t * dev, struct file *filp) |
| 1243 | { | 1243 | { |
| 1244 | drm_device_dma_t *dma = dev->dma; | 1244 | drm_device_dma_t *dma = dev->dma; |
| 1245 | int i; | 1245 | int i; |
diff --git a/drivers/char/drm/i830_drv.h b/drivers/char/drm/i830_drv.h index bf9075b576bd..85bc5be6f916 100644 --- a/drivers/char/drm/i830_drv.h +++ b/drivers/char/drm/i830_drv.h | |||
| @@ -123,9 +123,6 @@ typedef struct drm_i830_private { | |||
| 123 | extern drm_ioctl_desc_t i830_ioctls[]; | 123 | extern drm_ioctl_desc_t i830_ioctls[]; |
| 124 | extern int i830_max_ioctl; | 124 | extern int i830_max_ioctl; |
| 125 | 125 | ||
| 126 | /* i830_dma.c */ | ||
| 127 | extern void i830_reclaim_buffers(drm_device_t * dev, struct file *filp); | ||
| 128 | |||
| 129 | /* i830_irq.c */ | 126 | /* i830_irq.c */ |
| 130 | extern int i830_irq_emit(struct inode *inode, struct file *filp, | 127 | extern int i830_irq_emit(struct inode *inode, struct file *filp, |
| 131 | unsigned int cmd, unsigned long arg); | 128 | unsigned int cmd, unsigned long arg); |
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c index 9140703da1ba..1ff4c7ca0bff 100644 --- a/drivers/char/drm/i915_dma.c +++ b/drivers/char/drm/i915_dma.c | |||
| @@ -344,18 +344,20 @@ static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords) | |||
| 344 | int i; | 344 | int i; |
| 345 | RING_LOCALS; | 345 | RING_LOCALS; |
| 346 | 346 | ||
| 347 | if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8) | ||
| 348 | return DRM_ERR(EINVAL); | ||
| 349 | |||
| 350 | BEGIN_LP_RING(((dwords+1)&~1)); | ||
| 351 | |||
| 347 | for (i = 0; i < dwords;) { | 352 | for (i = 0; i < dwords;) { |
| 348 | int cmd, sz; | 353 | int cmd, sz; |
| 349 | 354 | ||
| 350 | if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd))) | 355 | if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd))) |
| 351 | return DRM_ERR(EINVAL); | 356 | return DRM_ERR(EINVAL); |
| 352 | 357 | ||
| 353 | /* printk("%d/%d ", i, dwords); */ | ||
| 354 | |||
| 355 | if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords) | 358 | if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords) |
| 356 | return DRM_ERR(EINVAL); | 359 | return DRM_ERR(EINVAL); |
| 357 | 360 | ||
| 358 | BEGIN_LP_RING(sz); | ||
| 359 | OUT_RING(cmd); | 361 | OUT_RING(cmd); |
| 360 | 362 | ||
| 361 | while (++i, --sz) { | 363 | while (++i, --sz) { |
| @@ -365,9 +367,13 @@ static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords) | |||
| 365 | } | 367 | } |
| 366 | OUT_RING(cmd); | 368 | OUT_RING(cmd); |
| 367 | } | 369 | } |
| 368 | ADVANCE_LP_RING(); | ||
| 369 | } | 370 | } |
| 370 | 371 | ||
| 372 | if (dwords & 1) | ||
| 373 | OUT_RING(0); | ||
| 374 | |||
| 375 | ADVANCE_LP_RING(); | ||
| 376 | |||
| 371 | return 0; | 377 | return 0; |
| 372 | } | 378 | } |
| 373 | 379 | ||
| @@ -401,6 +407,21 @@ static int i915_emit_box(drm_device_t * dev, | |||
| 401 | return 0; | 407 | return 0; |
| 402 | } | 408 | } |
| 403 | 409 | ||
| 410 | static void i915_emit_breadcrumb(drm_device_t *dev) | ||
| 411 | { | ||
| 412 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 413 | RING_LOCALS; | ||
| 414 | |||
| 415 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; | ||
| 416 | |||
| 417 | BEGIN_LP_RING(4); | ||
| 418 | OUT_RING(CMD_STORE_DWORD_IDX); | ||
| 419 | OUT_RING(20); | ||
| 420 | OUT_RING(dev_priv->counter); | ||
| 421 | OUT_RING(0); | ||
| 422 | ADVANCE_LP_RING(); | ||
| 423 | } | ||
| 424 | |||
| 404 | static int i915_dispatch_cmdbuffer(drm_device_t * dev, | 425 | static int i915_dispatch_cmdbuffer(drm_device_t * dev, |
| 405 | drm_i915_cmdbuffer_t * cmd) | 426 | drm_i915_cmdbuffer_t * cmd) |
| 406 | { | 427 | { |
| @@ -429,6 +450,7 @@ static int i915_dispatch_cmdbuffer(drm_device_t * dev, | |||
| 429 | return ret; | 450 | return ret; |
| 430 | } | 451 | } |
| 431 | 452 | ||
| 453 | i915_emit_breadcrumb(dev); | ||
| 432 | return 0; | 454 | return 0; |
| 433 | } | 455 | } |
| 434 | 456 | ||
| @@ -475,12 +497,7 @@ static int i915_dispatch_batchbuffer(drm_device_t * dev, | |||
| 475 | 497 | ||
| 476 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; | 498 | dev_priv->sarea_priv->last_enqueue = dev_priv->counter++; |
| 477 | 499 | ||
| 478 | BEGIN_LP_RING(4); | 500 | i915_emit_breadcrumb(dev); |
| 479 | OUT_RING(CMD_STORE_DWORD_IDX); | ||
| 480 | OUT_RING(20); | ||
| 481 | OUT_RING(dev_priv->counter); | ||
| 482 | OUT_RING(0); | ||
| 483 | ADVANCE_LP_RING(); | ||
| 484 | 501 | ||
| 485 | return 0; | 502 | return 0; |
| 486 | } | 503 | } |
| @@ -657,7 +674,7 @@ static int i915_getparam(DRM_IOCTL_ARGS) | |||
| 657 | value = READ_BREADCRUMB(dev_priv); | 674 | value = READ_BREADCRUMB(dev_priv); |
| 658 | break; | 675 | break; |
| 659 | default: | 676 | default: |
| 660 | DRM_ERROR("Unkown parameter %d\n", param.param); | 677 | DRM_ERROR("Unknown parameter %d\n", param.param); |
| 661 | return DRM_ERR(EINVAL); | 678 | return DRM_ERR(EINVAL); |
| 662 | } | 679 | } |
| 663 | 680 | ||
| @@ -742,7 +759,8 @@ drm_ioctl_desc_t i915_ioctls[] = { | |||
| 742 | [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, DRM_AUTH}, | 759 | [DRM_IOCTL_NR(DRM_I915_ALLOC)] = {i915_mem_alloc, DRM_AUTH}, |
| 743 | [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, DRM_AUTH}, | 760 | [DRM_IOCTL_NR(DRM_I915_FREE)] = {i915_mem_free, DRM_AUTH}, |
| 744 | [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, | 761 | [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] = {i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
| 745 | [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, DRM_AUTH} | 762 | [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] = {i915_cmdbuffer, DRM_AUTH}, |
| 763 | [DRM_IOCTL_NR(DRM_I915_DESTROY_HEAP)] = { i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY } | ||
| 746 | }; | 764 | }; |
| 747 | 765 | ||
| 748 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); | 766 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); |
diff --git a/drivers/char/drm/i915_drm.h b/drivers/char/drm/i915_drm.h index 77412ddac007..4cb3da578330 100644 --- a/drivers/char/drm/i915_drm.h +++ b/drivers/char/drm/i915_drm.h | |||
| @@ -74,6 +74,30 @@ typedef struct _drm_i915_sarea { | |||
| 74 | int pf_active; | 74 | int pf_active; |
| 75 | int pf_current_page; /* which buffer is being displayed? */ | 75 | int pf_current_page; /* which buffer is being displayed? */ |
| 76 | int perf_boxes; /* performance boxes to be displayed */ | 76 | int perf_boxes; /* performance boxes to be displayed */ |
| 77 | int width, height; /* screen size in pixels */ | ||
| 78 | |||
| 79 | drm_handle_t front_handle; | ||
| 80 | int front_offset; | ||
| 81 | int front_size; | ||
| 82 | |||
| 83 | drm_handle_t back_handle; | ||
| 84 | int back_offset; | ||
| 85 | int back_size; | ||
| 86 | |||
| 87 | drm_handle_t depth_handle; | ||
| 88 | int depth_offset; | ||
| 89 | int depth_size; | ||
| 90 | |||
| 91 | drm_handle_t tex_handle; | ||
| 92 | int tex_offset; | ||
| 93 | int tex_size; | ||
| 94 | int log_tex_granularity; | ||
| 95 | int pitch; | ||
| 96 | int rotation; /* 0, 90, 180 or 270 */ | ||
| 97 | int rotated_offset; | ||
| 98 | int rotated_size; | ||
| 99 | int rotated_pitch; | ||
| 100 | int virtualX, virtualY; | ||
| 77 | } drm_i915_sarea_t; | 101 | } drm_i915_sarea_t; |
| 78 | 102 | ||
| 79 | /* Flags for perf_boxes | 103 | /* Flags for perf_boxes |
| @@ -99,6 +123,7 @@ typedef struct _drm_i915_sarea { | |||
| 99 | #define DRM_I915_FREE 0x09 | 123 | #define DRM_I915_FREE 0x09 |
| 100 | #define DRM_I915_INIT_HEAP 0x0a | 124 | #define DRM_I915_INIT_HEAP 0x0a |
| 101 | #define DRM_I915_CMDBUFFER 0x0b | 125 | #define DRM_I915_CMDBUFFER 0x0b |
| 126 | #define DRM_I915_DESTROY_HEAP 0x0c | ||
| 102 | 127 | ||
| 103 | #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) | 128 | #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) |
| 104 | #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) | 129 | #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) |
| @@ -112,6 +137,7 @@ typedef struct _drm_i915_sarea { | |||
| 112 | #define DRM_IOCTL_I915_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_FREE, drm_i915_mem_free_t) | 137 | #define DRM_IOCTL_I915_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_FREE, drm_i915_mem_free_t) |
| 113 | #define DRM_IOCTL_I915_INIT_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT_HEAP, drm_i915_mem_init_heap_t) | 138 | #define DRM_IOCTL_I915_INIT_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT_HEAP, drm_i915_mem_init_heap_t) |
| 114 | #define DRM_IOCTL_I915_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t) | 139 | #define DRM_IOCTL_I915_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t) |
| 140 | #define DRM_IOCTL_I915_DESTROY_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_DESTROY_HEAP, drm_i915_mem_destroy_heap_t) | ||
| 115 | 141 | ||
| 116 | /* Allow drivers to submit batchbuffers directly to hardware, relying | 142 | /* Allow drivers to submit batchbuffers directly to hardware, relying |
| 117 | * on the security mechanisms provided by hardware. | 143 | * on the security mechanisms provided by hardware. |
| @@ -191,4 +217,11 @@ typedef struct drm_i915_mem_init_heap { | |||
| 191 | int start; | 217 | int start; |
| 192 | } drm_i915_mem_init_heap_t; | 218 | } drm_i915_mem_init_heap_t; |
| 193 | 219 | ||
| 220 | /* Allow memory manager to be torn down and re-initialized (eg on | ||
| 221 | * rotate): | ||
| 222 | */ | ||
| 223 | typedef struct drm_i915_mem_destroy_heap { | ||
| 224 | int region; | ||
| 225 | } drm_i915_mem_destroy_heap_t; | ||
| 226 | |||
| 194 | #endif /* _I915_DRM_H_ */ | 227 | #endif /* _I915_DRM_H_ */ |
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h index c6c71b45f101..7a65666899e4 100644 --- a/drivers/char/drm/i915_drv.h +++ b/drivers/char/drm/i915_drv.h | |||
| @@ -37,16 +37,17 @@ | |||
| 37 | 37 | ||
| 38 | #define DRIVER_NAME "i915" | 38 | #define DRIVER_NAME "i915" |
| 39 | #define DRIVER_DESC "Intel Graphics" | 39 | #define DRIVER_DESC "Intel Graphics" |
| 40 | #define DRIVER_DATE "20051209" | 40 | #define DRIVER_DATE "20060119" |
| 41 | 41 | ||
| 42 | /* Interface history: | 42 | /* Interface history: |
| 43 | * | 43 | * |
| 44 | * 1.1: Original. | 44 | * 1.1: Original. |
| 45 | * 1.2: Add Power Management | 45 | * 1.2: Add Power Management |
| 46 | * 1.3: Add vblank support | 46 | * 1.3: Add vblank support |
| 47 | * 1.4: Fix cmdbuffer path, add heap destroy | ||
| 47 | */ | 48 | */ |
| 48 | #define DRIVER_MAJOR 1 | 49 | #define DRIVER_MAJOR 1 |
| 49 | #define DRIVER_MINOR 3 | 50 | #define DRIVER_MINOR 4 |
| 50 | #define DRIVER_PATCHLEVEL 0 | 51 | #define DRIVER_PATCHLEVEL 0 |
| 51 | 52 | ||
| 52 | typedef struct _drm_i915_ring_buffer { | 53 | typedef struct _drm_i915_ring_buffer { |
| @@ -123,6 +124,7 @@ extern void i915_driver_irq_uninstall(drm_device_t * dev); | |||
| 123 | extern int i915_mem_alloc(DRM_IOCTL_ARGS); | 124 | extern int i915_mem_alloc(DRM_IOCTL_ARGS); |
| 124 | extern int i915_mem_free(DRM_IOCTL_ARGS); | 125 | extern int i915_mem_free(DRM_IOCTL_ARGS); |
| 125 | extern int i915_mem_init_heap(DRM_IOCTL_ARGS); | 126 | extern int i915_mem_init_heap(DRM_IOCTL_ARGS); |
| 127 | extern int i915_mem_destroy_heap(DRM_IOCTL_ARGS); | ||
| 126 | extern void i915_mem_takedown(struct mem_block **heap); | 128 | extern void i915_mem_takedown(struct mem_block **heap); |
| 127 | extern void i915_mem_release(drm_device_t * dev, | 129 | extern void i915_mem_release(drm_device_t * dev, |
| 128 | DRMFILE filp, struct mem_block *heap); | 130 | DRMFILE filp, struct mem_block *heap); |
diff --git a/drivers/char/drm/i915_mem.c b/drivers/char/drm/i915_mem.c index ba87ff17ff64..52c67324df58 100644 --- a/drivers/char/drm/i915_mem.c +++ b/drivers/char/drm/i915_mem.c | |||
| @@ -365,3 +365,34 @@ int i915_mem_init_heap(DRM_IOCTL_ARGS) | |||
| 365 | 365 | ||
| 366 | return init_heap(heap, initheap.start, initheap.size); | 366 | return init_heap(heap, initheap.start, initheap.size); |
| 367 | } | 367 | } |
| 368 | |||
| 369 | int i915_mem_destroy_heap( DRM_IOCTL_ARGS ) | ||
| 370 | { | ||
| 371 | DRM_DEVICE; | ||
| 372 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
| 373 | drm_i915_mem_destroy_heap_t destroyheap; | ||
| 374 | struct mem_block **heap; | ||
| 375 | |||
| 376 | if ( !dev_priv ) { | ||
| 377 | DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ ); | ||
| 378 | return DRM_ERR(EINVAL); | ||
| 379 | } | ||
| 380 | |||
| 381 | DRM_COPY_FROM_USER_IOCTL( destroyheap, (drm_i915_mem_destroy_heap_t *)data, | ||
| 382 | sizeof(destroyheap) ); | ||
| 383 | |||
| 384 | heap = get_heap( dev_priv, destroyheap.region ); | ||
| 385 | if (!heap) { | ||
| 386 | DRM_ERROR("get_heap failed"); | ||
| 387 | return DRM_ERR(EFAULT); | ||
| 388 | } | ||
| 389 | |||
| 390 | if (!*heap) { | ||
| 391 | DRM_ERROR("heap not initialized?"); | ||
| 392 | return DRM_ERR(EFAULT); | ||
| 393 | } | ||
| 394 | |||
| 395 | i915_mem_takedown( heap ); | ||
| 396 | return 0; | ||
| 397 | } | ||
| 398 | |||
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c index 915665c7fe7c..9bb8ae0c1c27 100644 --- a/drivers/char/drm/radeon_cp.c +++ b/drivers/char/drm/radeon_cp.c | |||
| @@ -1640,7 +1640,7 @@ static int radeon_do_cleanup_cp(drm_device_t * dev) | |||
| 1640 | if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) | 1640 | if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) |
| 1641 | { | 1641 | { |
| 1642 | drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); | 1642 | drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); |
| 1643 | dev_priv->gart_info.addr = 0; | 1643 | dev_priv->gart_info.addr = NULL; |
| 1644 | } | 1644 | } |
| 1645 | } | 1645 | } |
| 1646 | /* only clear to the start of flags */ | 1646 | /* only clear to the start of flags */ |
diff --git a/drivers/char/drm/savage_bci.c b/drivers/char/drm/savage_bci.c index 0d426deeefec..59c7520bf9a2 100644 --- a/drivers/char/drm/savage_bci.c +++ b/drivers/char/drm/savage_bci.c | |||
| @@ -32,6 +32,8 @@ | |||
| 32 | #define SAVAGE_EVENT_USEC_TIMEOUT 5000000 /* 5s */ | 32 | #define SAVAGE_EVENT_USEC_TIMEOUT 5000000 /* 5s */ |
| 33 | #define SAVAGE_FREELIST_DEBUG 0 | 33 | #define SAVAGE_FREELIST_DEBUG 0 |
| 34 | 34 | ||
| 35 | static int savage_do_cleanup_bci(drm_device_t *dev); | ||
| 36 | |||
| 35 | static int | 37 | static int |
| 36 | savage_bci_wait_fifo_shadow(drm_savage_private_t * dev_priv, unsigned int n) | 38 | savage_bci_wait_fifo_shadow(drm_savage_private_t * dev_priv, unsigned int n) |
| 37 | { | 39 | { |
| @@ -895,7 +897,7 @@ static int savage_do_init_bci(drm_device_t * dev, drm_savage_init_t * init) | |||
| 895 | return 0; | 897 | return 0; |
| 896 | } | 898 | } |
| 897 | 899 | ||
| 898 | int savage_do_cleanup_bci(drm_device_t * dev) | 900 | static int savage_do_cleanup_bci(drm_device_t * dev) |
| 899 | { | 901 | { |
| 900 | drm_savage_private_t *dev_priv = dev->dev_private; | 902 | drm_savage_private_t *dev_priv = dev->dev_private; |
| 901 | 903 | ||
diff --git a/drivers/char/drm/savage_drv.h b/drivers/char/drm/savage_drv.h index dd46cb85439c..8f04b3d82292 100644 --- a/drivers/char/drm/savage_drv.h +++ b/drivers/char/drm/savage_drv.h | |||
| @@ -212,7 +212,6 @@ extern int savage_driver_load(drm_device_t *dev, unsigned long chipset); | |||
| 212 | extern int savage_driver_firstopen(drm_device_t *dev); | 212 | extern int savage_driver_firstopen(drm_device_t *dev); |
| 213 | extern void savage_driver_lastclose(drm_device_t *dev); | 213 | extern void savage_driver_lastclose(drm_device_t *dev); |
| 214 | extern int savage_driver_unload(drm_device_t *dev); | 214 | extern int savage_driver_unload(drm_device_t *dev); |
| 215 | extern int savage_do_cleanup_bci(drm_device_t * dev); | ||
| 216 | extern void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp); | 215 | extern void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp); |
| 217 | 216 | ||
| 218 | /* state functions */ | 217 | /* state functions */ |
diff --git a/drivers/char/drm/via_dma.c b/drivers/char/drm/via_dma.c index 593c0b8f650a..a691ae74129d 100644 --- a/drivers/char/drm/via_dma.c +++ b/drivers/char/drm/via_dma.c | |||
| @@ -222,7 +222,7 @@ static int via_initialize(drm_device_t * dev, | |||
| 222 | return 0; | 222 | return 0; |
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | int via_dma_init(DRM_IOCTL_ARGS) | 225 | static int via_dma_init(DRM_IOCTL_ARGS) |
| 226 | { | 226 | { |
| 227 | DRM_DEVICE; | 227 | DRM_DEVICE; |
| 228 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; | 228 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; |
| @@ -321,7 +321,7 @@ int via_driver_dma_quiescent(drm_device_t * dev) | |||
| 321 | return 0; | 321 | return 0; |
| 322 | } | 322 | } |
| 323 | 323 | ||
| 324 | int via_flush_ioctl(DRM_IOCTL_ARGS) | 324 | static int via_flush_ioctl(DRM_IOCTL_ARGS) |
| 325 | { | 325 | { |
| 326 | DRM_DEVICE; | 326 | DRM_DEVICE; |
| 327 | 327 | ||
| @@ -330,7 +330,7 @@ int via_flush_ioctl(DRM_IOCTL_ARGS) | |||
| 330 | return via_driver_dma_quiescent(dev); | 330 | return via_driver_dma_quiescent(dev); |
| 331 | } | 331 | } |
| 332 | 332 | ||
| 333 | int via_cmdbuffer(DRM_IOCTL_ARGS) | 333 | static int via_cmdbuffer(DRM_IOCTL_ARGS) |
| 334 | { | 334 | { |
| 335 | DRM_DEVICE; | 335 | DRM_DEVICE; |
| 336 | drm_via_cmdbuffer_t cmdbuf; | 336 | drm_via_cmdbuffer_t cmdbuf; |
| @@ -375,7 +375,7 @@ static int via_dispatch_pci_cmdbuffer(drm_device_t * dev, | |||
| 375 | return ret; | 375 | return ret; |
| 376 | } | 376 | } |
| 377 | 377 | ||
| 378 | int via_pci_cmdbuffer(DRM_IOCTL_ARGS) | 378 | static int via_pci_cmdbuffer(DRM_IOCTL_ARGS) |
| 379 | { | 379 | { |
| 380 | DRM_DEVICE; | 380 | DRM_DEVICE; |
| 381 | drm_via_cmdbuffer_t cmdbuf; | 381 | drm_via_cmdbuffer_t cmdbuf; |
| @@ -665,7 +665,7 @@ static void via_cmdbuf_reset(drm_via_private_t * dev_priv) | |||
| 665 | * User interface to the space and lag functions. | 665 | * User interface to the space and lag functions. |
| 666 | */ | 666 | */ |
| 667 | 667 | ||
| 668 | int via_cmdbuf_size(DRM_IOCTL_ARGS) | 668 | static int via_cmdbuf_size(DRM_IOCTL_ARGS) |
| 669 | { | 669 | { |
| 670 | DRM_DEVICE; | 670 | DRM_DEVICE; |
| 671 | drm_via_cmdbuf_size_t d_siz; | 671 | drm_via_cmdbuf_size_t d_siz; |
diff --git a/drivers/char/drm/via_dmablit.c b/drivers/char/drm/via_dmablit.c index 9d5e027dae0e..b7f17457b424 100644 --- a/drivers/char/drm/via_dmablit.c +++ b/drivers/char/drm/via_dmablit.c | |||
| @@ -108,7 +108,7 @@ via_map_blit_for_device(struct pci_dev *pdev, | |||
| 108 | int num_desc = 0; | 108 | int num_desc = 0; |
| 109 | int cur_line; | 109 | int cur_line; |
| 110 | dma_addr_t next = 0 | VIA_DMA_DPR_EC; | 110 | dma_addr_t next = 0 | VIA_DMA_DPR_EC; |
| 111 | drm_via_descriptor_t *desc_ptr = 0; | 111 | drm_via_descriptor_t *desc_ptr = NULL; |
| 112 | 112 | ||
| 113 | if (mode == 1) | 113 | if (mode == 1) |
| 114 | desc_ptr = vsg->desc_pages[cur_descriptor_page]; | 114 | desc_ptr = vsg->desc_pages[cur_descriptor_page]; |
| @@ -167,7 +167,7 @@ via_map_blit_for_device(struct pci_dev *pdev, | |||
| 167 | */ | 167 | */ |
| 168 | 168 | ||
| 169 | 169 | ||
| 170 | void | 170 | static void |
| 171 | via_free_sg_info(struct pci_dev *pdev, drm_via_sg_info_t *vsg) | 171 | via_free_sg_info(struct pci_dev *pdev, drm_via_sg_info_t *vsg) |
| 172 | { | 172 | { |
| 173 | struct page *page; | 173 | struct page *page; |
| @@ -581,7 +581,7 @@ via_build_sg_info(drm_device_t *dev, drm_via_sg_info_t *vsg, drm_via_dmablit_t * | |||
| 581 | int ret = 0; | 581 | int ret = 0; |
| 582 | 582 | ||
| 583 | vsg->direction = (draw) ? DMA_TO_DEVICE : DMA_FROM_DEVICE; | 583 | vsg->direction = (draw) ? DMA_TO_DEVICE : DMA_FROM_DEVICE; |
| 584 | vsg->bounce_buffer = 0; | 584 | vsg->bounce_buffer = NULL; |
| 585 | 585 | ||
| 586 | vsg->state = dr_via_sg_init; | 586 | vsg->state = dr_via_sg_init; |
| 587 | 587 | ||
diff --git a/drivers/char/drm/via_drv.h b/drivers/char/drm/via_drv.h index aad4f99f5405..52bcc7b1ba45 100644 --- a/drivers/char/drm/via_drv.h +++ b/drivers/char/drm/via_drv.h | |||
| @@ -110,11 +110,6 @@ extern int via_mem_free(DRM_IOCTL_ARGS); | |||
| 110 | extern int via_agp_init(DRM_IOCTL_ARGS); | 110 | extern int via_agp_init(DRM_IOCTL_ARGS); |
| 111 | extern int via_map_init(DRM_IOCTL_ARGS); | 111 | extern int via_map_init(DRM_IOCTL_ARGS); |
| 112 | extern int via_decoder_futex(DRM_IOCTL_ARGS); | 112 | extern int via_decoder_futex(DRM_IOCTL_ARGS); |
| 113 | extern int via_dma_init(DRM_IOCTL_ARGS); | ||
| 114 | extern int via_cmdbuffer(DRM_IOCTL_ARGS); | ||
| 115 | extern int via_flush_ioctl(DRM_IOCTL_ARGS); | ||
| 116 | extern int via_pci_cmdbuffer(DRM_IOCTL_ARGS); | ||
| 117 | extern int via_cmdbuf_size(DRM_IOCTL_ARGS); | ||
| 118 | extern int via_wait_irq(DRM_IOCTL_ARGS); | 113 | extern int via_wait_irq(DRM_IOCTL_ARGS); |
| 119 | extern int via_dma_blit_sync( DRM_IOCTL_ARGS ); | 114 | extern int via_dma_blit_sync( DRM_IOCTL_ARGS ); |
| 120 | extern int via_dma_blit( DRM_IOCTL_ARGS ); | 115 | extern int via_dma_blit( DRM_IOCTL_ARGS ); |
| @@ -139,8 +134,6 @@ extern int via_driver_dma_quiescent(drm_device_t * dev); | |||
| 139 | extern void via_init_futex(drm_via_private_t * dev_priv); | 134 | extern void via_init_futex(drm_via_private_t * dev_priv); |
| 140 | extern void via_cleanup_futex(drm_via_private_t * dev_priv); | 135 | extern void via_cleanup_futex(drm_via_private_t * dev_priv); |
| 141 | extern void via_release_futex(drm_via_private_t * dev_priv, int context); | 136 | extern void via_release_futex(drm_via_private_t * dev_priv, int context); |
| 142 | extern int via_driver_irq_wait(drm_device_t * dev, unsigned int irq, | ||
| 143 | int force_sequence, unsigned int *sequence); | ||
| 144 | 137 | ||
| 145 | extern void via_dmablit_handler(drm_device_t *dev, int engine, int from_irq); | 138 | extern void via_dmablit_handler(drm_device_t *dev, int engine, int from_irq); |
| 146 | extern void via_init_dmablit(drm_device_t *dev); | 139 | extern void via_init_dmablit(drm_device_t *dev); |
diff --git a/drivers/char/drm/via_irq.c b/drivers/char/drm/via_irq.c index 56d7e3daea12..6152415644e9 100644 --- a/drivers/char/drm/via_irq.c +++ b/drivers/char/drm/via_irq.c | |||
| @@ -190,7 +190,7 @@ int via_driver_vblank_wait(drm_device_t * dev, unsigned int *sequence) | |||
| 190 | return ret; | 190 | return ret; |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | int | 193 | static int |
| 194 | via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence, | 194 | via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence, |
| 195 | unsigned int *sequence) | 195 | unsigned int *sequence) |
| 196 | { | 196 | { |
diff --git a/drivers/char/esp.c b/drivers/char/esp.c index 3f3ac039f4d9..57539d8f9f7c 100644 --- a/drivers/char/esp.c +++ b/drivers/char/esp.c | |||
| @@ -359,7 +359,7 @@ static inline void receive_chars_pio(struct esp_struct *info, int num_bytes) | |||
| 359 | } | 359 | } |
| 360 | } | 360 | } |
| 361 | 361 | ||
| 362 | schedule_delayed_work(&tty->buf.work, 1); | 362 | tty_schedule_flip(tty); |
| 363 | 363 | ||
| 364 | info->stat_flags &= ~ESP_STAT_RX_TIMEOUT; | 364 | info->stat_flags &= ~ESP_STAT_RX_TIMEOUT; |
| 365 | release_pio_buffer(pio_buf); | 365 | release_pio_buffer(pio_buf); |
| @@ -426,7 +426,7 @@ static inline void receive_chars_dma_done(struct esp_struct *info, | |||
| 426 | } | 426 | } |
| 427 | tty_insert_flip_char(tty, dma_buffer[num_bytes - 1], statflag); | 427 | tty_insert_flip_char(tty, dma_buffer[num_bytes - 1], statflag); |
| 428 | } | 428 | } |
| 429 | schedule_delayed_work(&tty->buf.work, 1); | 429 | tty_schedule_flip(tty); |
| 430 | } | 430 | } |
| 431 | 431 | ||
| 432 | if (dma_bytes != num_bytes) { | 432 | if (dma_bytes != num_bytes) { |
diff --git a/drivers/char/ip2/i2cmd.c b/drivers/char/ip2/i2cmd.c index cb8f4198e9a3..e7af647800b6 100644 --- a/drivers/char/ip2/i2cmd.c +++ b/drivers/char/ip2/i2cmd.c | |||
| @@ -139,7 +139,6 @@ static UCHAR ct79[] = { 2, BYP, 0x4F,0 }; // XMIT_NOW | |||
| 139 | //static UCHAR ct86[]={ 2, BTH, 0x56,0 }; // RCV_ENABLE | 139 | //static UCHAR ct86[]={ 2, BTH, 0x56,0 }; // RCV_ENABLE |
| 140 | static UCHAR ct87[] = { 1, BYP, 0x57 }; // HW_TEST | 140 | static UCHAR ct87[] = { 1, BYP, 0x57 }; // HW_TEST |
| 141 | //static UCHAR ct88[]={ 3, BTH, 0x58,0,0 }; // RCV_THRESHOLD | 141 | //static UCHAR ct88[]={ 3, BTH, 0x58,0,0 }; // RCV_THRESHOLD |
| 142 | static UCHAR ct89[]={ 1, BYP, 0x59 }; // DSS_NOW | ||
| 143 | //static UCHAR ct90[]={ 3, BYP, 0x5A,0,0 }; // Set SILO | 142 | //static UCHAR ct90[]={ 3, BYP, 0x5A,0,0 }; // Set SILO |
| 144 | //static UCHAR ct91[]={ 2, BYP, 0x5B,0 }; // timed break | 143 | //static UCHAR ct91[]={ 2, BYP, 0x5B,0 }; // timed break |
| 145 | 144 | ||
diff --git a/drivers/char/ip2main.c b/drivers/char/ip2main.c index 56e93a5a1e24..48fcfba37bfa 100644 --- a/drivers/char/ip2main.c +++ b/drivers/char/ip2main.c | |||
| @@ -2906,65 +2906,16 @@ ip2_ipl_ioctl ( struct inode *pInode, struct file *pFile, UINT cmd, ULONG arg ) | |||
| 2906 | rc = -EINVAL; | 2906 | rc = -EINVAL; |
| 2907 | break; | 2907 | break; |
| 2908 | case 3: // Trace device | 2908 | case 3: // Trace device |
| 2909 | if ( cmd == 1 ) { | 2909 | /* |
| 2910 | rc = put_user(iiSendPendingMail, pIndex++ ); | 2910 | * akpm: This used to write a whole bunch of function addresses |
| 2911 | rc = put_user(i2InitChannels, pIndex++ ); | 2911 | * to userspace, which generated lots of put_user() warnings. |
| 2912 | rc = put_user(i2QueueNeeds, pIndex++ ); | 2912 | * I killed it all. Just return "success" and don't do |
| 2913 | rc = put_user(i2QueueCommands, pIndex++ ); | 2913 | * anything. |
| 2914 | rc = put_user(i2GetStatus, pIndex++ ); | 2914 | */ |
| 2915 | rc = put_user(i2Input, pIndex++ ); | 2915 | if (cmd == 1) |
| 2916 | rc = put_user(i2InputFlush, pIndex++ ); | 2916 | rc = 0; |
| 2917 | rc = put_user(i2Output, pIndex++ ); | 2917 | else |
| 2918 | rc = put_user(i2FlushOutput, pIndex++ ); | ||
| 2919 | rc = put_user(i2DrainWakeup, pIndex++ ); | ||
| 2920 | rc = put_user(i2DrainOutput, pIndex++ ); | ||
| 2921 | rc = put_user(i2OutputFree, pIndex++ ); | ||
| 2922 | rc = put_user(i2StripFifo, pIndex++ ); | ||
| 2923 | rc = put_user(i2StuffFifoBypass, pIndex++ ); | ||
| 2924 | rc = put_user(i2StuffFifoFlow, pIndex++ ); | ||
| 2925 | rc = put_user(i2StuffFifoInline, pIndex++ ); | ||
| 2926 | rc = put_user(i2ServiceBoard, pIndex++ ); | ||
| 2927 | rc = put_user(serviceOutgoingFifo, pIndex++ ); | ||
| 2928 | // rc = put_user(ip2_init, pIndex++ ); | ||
| 2929 | rc = put_user(ip2_init_board, pIndex++ ); | ||
| 2930 | rc = put_user(find_eisa_board, pIndex++ ); | ||
| 2931 | rc = put_user(set_irq, pIndex++ ); | ||
| 2932 | rc = put_user(ip2_interrupt, pIndex++ ); | ||
| 2933 | rc = put_user(ip2_poll, pIndex++ ); | ||
| 2934 | rc = put_user(service_all_boards, pIndex++ ); | ||
| 2935 | rc = put_user(do_input, pIndex++ ); | ||
| 2936 | rc = put_user(do_status, pIndex++ ); | ||
| 2937 | #ifndef IP2DEBUG_OPEN | ||
| 2938 | rc = put_user(0, pIndex++ ); | ||
| 2939 | #else | ||
| 2940 | rc = put_user(open_sanity_check, pIndex++ ); | ||
| 2941 | #endif | ||
| 2942 | rc = put_user(ip2_open, pIndex++ ); | ||
| 2943 | rc = put_user(ip2_close, pIndex++ ); | ||
| 2944 | rc = put_user(ip2_hangup, pIndex++ ); | ||
| 2945 | rc = put_user(ip2_write, pIndex++ ); | ||
| 2946 | rc = put_user(ip2_putchar, pIndex++ ); | ||
| 2947 | rc = put_user(ip2_flush_chars, pIndex++ ); | ||
| 2948 | rc = put_user(ip2_write_room, pIndex++ ); | ||
| 2949 | rc = put_user(ip2_chars_in_buf, pIndex++ ); | ||
| 2950 | rc = put_user(ip2_flush_buffer, pIndex++ ); | ||
| 2951 | |||
| 2952 | //rc = put_user(ip2_wait_until_sent, pIndex++ ); | ||
| 2953 | rc = put_user(0, pIndex++ ); | ||
| 2954 | |||
| 2955 | rc = put_user(ip2_throttle, pIndex++ ); | ||
| 2956 | rc = put_user(ip2_unthrottle, pIndex++ ); | ||
| 2957 | rc = put_user(ip2_ioctl, pIndex++ ); | ||
| 2958 | rc = put_user(0, pIndex++ ); | ||
| 2959 | rc = put_user(get_serial_info, pIndex++ ); | ||
| 2960 | rc = put_user(set_serial_info, pIndex++ ); | ||
| 2961 | rc = put_user(ip2_set_termios, pIndex++ ); | ||
| 2962 | rc = put_user(ip2_set_line_discipline, pIndex++ ); | ||
| 2963 | rc = put_user(set_params, pIndex++ ); | ||
| 2964 | } else { | ||
| 2965 | rc = -EINVAL; | 2918 | rc = -EINVAL; |
| 2966 | } | ||
| 2967 | |||
| 2968 | break; | 2919 | break; |
| 2969 | 2920 | ||
| 2970 | default: | 2921 | default: |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 0097f06fa67b..d745004281d0 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
| @@ -481,7 +481,7 @@ int ipmi_validate_addr(struct ipmi_addr *addr, int len) | |||
| 481 | } | 481 | } |
| 482 | 482 | ||
| 483 | if ((addr->channel == IPMI_BMC_CHANNEL) | 483 | if ((addr->channel == IPMI_BMC_CHANNEL) |
| 484 | || (addr->channel >= IPMI_NUM_CHANNELS) | 484 | || (addr->channel >= IPMI_MAX_CHANNELS) |
| 485 | || (addr->channel < 0)) | 485 | || (addr->channel < 0)) |
| 486 | return -EINVAL; | 486 | return -EINVAL; |
| 487 | 487 | ||
| @@ -1321,7 +1321,7 @@ static int i_ipmi_request(ipmi_user_t user, | |||
| 1321 | unsigned char ipmb_seq; | 1321 | unsigned char ipmb_seq; |
| 1322 | long seqid; | 1322 | long seqid; |
| 1323 | 1323 | ||
| 1324 | if (addr->channel >= IPMI_NUM_CHANNELS) { | 1324 | if (addr->channel >= IPMI_MAX_CHANNELS) { |
| 1325 | spin_lock_irqsave(&intf->counter_lock, flags); | 1325 | spin_lock_irqsave(&intf->counter_lock, flags); |
| 1326 | intf->sent_invalid_commands++; | 1326 | intf->sent_invalid_commands++; |
| 1327 | spin_unlock_irqrestore(&intf->counter_lock, flags); | 1327 | spin_unlock_irqrestore(&intf->counter_lock, flags); |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 6ed213bd702c..e59b638766ef 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
| @@ -1270,36 +1270,36 @@ static int try_init_port(int intf_num, struct smi_info **new_info) | |||
| 1270 | return 0; | 1270 | return 0; |
| 1271 | } | 1271 | } |
| 1272 | 1272 | ||
| 1273 | static unsigned char mem_inb(struct si_sm_io *io, unsigned int offset) | 1273 | static unsigned char intf_mem_inb(struct si_sm_io *io, unsigned int offset) |
| 1274 | { | 1274 | { |
| 1275 | return readb((io->addr)+(offset * io->regspacing)); | 1275 | return readb((io->addr)+(offset * io->regspacing)); |
| 1276 | } | 1276 | } |
| 1277 | 1277 | ||
| 1278 | static void mem_outb(struct si_sm_io *io, unsigned int offset, | 1278 | static void intf_mem_outb(struct si_sm_io *io, unsigned int offset, |
| 1279 | unsigned char b) | 1279 | unsigned char b) |
| 1280 | { | 1280 | { |
| 1281 | writeb(b, (io->addr)+(offset * io->regspacing)); | 1281 | writeb(b, (io->addr)+(offset * io->regspacing)); |
| 1282 | } | 1282 | } |
| 1283 | 1283 | ||
| 1284 | static unsigned char mem_inw(struct si_sm_io *io, unsigned int offset) | 1284 | static unsigned char intf_mem_inw(struct si_sm_io *io, unsigned int offset) |
| 1285 | { | 1285 | { |
| 1286 | return (readw((io->addr)+(offset * io->regspacing)) >> io->regshift) | 1286 | return (readw((io->addr)+(offset * io->regspacing)) >> io->regshift) |
| 1287 | && 0xff; | 1287 | && 0xff; |
| 1288 | } | 1288 | } |
| 1289 | 1289 | ||
| 1290 | static void mem_outw(struct si_sm_io *io, unsigned int offset, | 1290 | static void intf_mem_outw(struct si_sm_io *io, unsigned int offset, |
| 1291 | unsigned char b) | 1291 | unsigned char b) |
| 1292 | { | 1292 | { |
| 1293 | writeb(b << io->regshift, (io->addr)+(offset * io->regspacing)); | 1293 | writeb(b << io->regshift, (io->addr)+(offset * io->regspacing)); |
| 1294 | } | 1294 | } |
| 1295 | 1295 | ||
| 1296 | static unsigned char mem_inl(struct si_sm_io *io, unsigned int offset) | 1296 | static unsigned char intf_mem_inl(struct si_sm_io *io, unsigned int offset) |
| 1297 | { | 1297 | { |
| 1298 | return (readl((io->addr)+(offset * io->regspacing)) >> io->regshift) | 1298 | return (readl((io->addr)+(offset * io->regspacing)) >> io->regshift) |
| 1299 | && 0xff; | 1299 | && 0xff; |
| 1300 | } | 1300 | } |
| 1301 | 1301 | ||
| 1302 | static void mem_outl(struct si_sm_io *io, unsigned int offset, | 1302 | static void intf_mem_outl(struct si_sm_io *io, unsigned int offset, |
| 1303 | unsigned char b) | 1303 | unsigned char b) |
| 1304 | { | 1304 | { |
| 1305 | writel(b << io->regshift, (io->addr)+(offset * io->regspacing)); | 1305 | writel(b << io->regshift, (io->addr)+(offset * io->regspacing)); |
| @@ -1349,16 +1349,16 @@ static int mem_setup(struct smi_info *info) | |||
| 1349 | upon the register size. */ | 1349 | upon the register size. */ |
| 1350 | switch (info->io.regsize) { | 1350 | switch (info->io.regsize) { |
| 1351 | case 1: | 1351 | case 1: |
| 1352 | info->io.inputb = mem_inb; | 1352 | info->io.inputb = intf_mem_inb; |
| 1353 | info->io.outputb = mem_outb; | 1353 | info->io.outputb = intf_mem_outb; |
| 1354 | break; | 1354 | break; |
| 1355 | case 2: | 1355 | case 2: |
| 1356 | info->io.inputb = mem_inw; | 1356 | info->io.inputb = intf_mem_inw; |
| 1357 | info->io.outputb = mem_outw; | 1357 | info->io.outputb = intf_mem_outw; |
| 1358 | break; | 1358 | break; |
| 1359 | case 4: | 1359 | case 4: |
| 1360 | info->io.inputb = mem_inl; | 1360 | info->io.inputb = intf_mem_inl; |
| 1361 | info->io.outputb = mem_outl; | 1361 | info->io.outputb = intf_mem_outl; |
| 1362 | break; | 1362 | break; |
| 1363 | #ifdef readq | 1363 | #ifdef readq |
| 1364 | case 8: | 1364 | case 8: |
diff --git a/drivers/char/rio/cirrus.h b/drivers/char/rio/cirrus.h index 217ff09f2fa1..89bd94eb45be 100644 --- a/drivers/char/rio/cirrus.h +++ b/drivers/char/rio/cirrus.h | |||
| @@ -40,148 +40,6 @@ | |||
| 40 | #endif | 40 | #endif |
| 41 | #define _cirrus_h 1 | 41 | #define _cirrus_h 1 |
| 42 | 42 | ||
| 43 | #ifdef RTA | ||
| 44 | #define TO_UART RX | ||
| 45 | #define TO_DRIVER TX | ||
| 46 | #endif | ||
| 47 | |||
| 48 | #ifdef HOST | ||
| 49 | #define TO_UART TX | ||
| 50 | #define TO_DRIVER RX | ||
| 51 | #endif | ||
| 52 | #ifdef RTA | ||
| 53 | /* Miscellaneous defines for CIRRUS addresses and related logic for | ||
| 54 | interrupts etc. | ||
| 55 | */ | ||
| 56 | #define MAP(a) ((short *)(cirrus_base + (a))) | ||
| 57 | #define outp(a,b) (*MAP (a) =(b)) | ||
| 58 | #define inp(a) ((*MAP (a)) & 0xff) | ||
| 59 | #define CIRRUS_FIRST (short*)0x7300 | ||
| 60 | #define CIRRUS_SECOND (short*)0x7200 | ||
| 61 | #define CIRRUS_THIRD (short*)0x7100 | ||
| 62 | #define CIRRUS_FOURTH (short*)0x7000 | ||
| 63 | #define PORTS_ON_CIRRUS 4 | ||
| 64 | #define CIRRUS_FIFO_SIZE 12 | ||
| 65 | #define SPACE 0x20 | ||
| 66 | #define TAB 0x09 | ||
| 67 | #define LINE_FEED 0x0a | ||
| 68 | #define CARRIAGE_RETURN 0x0d | ||
| 69 | #define BACKSPACE 0x08 | ||
| 70 | #define SPACES_IN_TABS 8 | ||
| 71 | #define SEND_ESCAPE 0x00 | ||
| 72 | #define START_BREAK 0x81 | ||
| 73 | #define TIMER_TICK 0x82 | ||
| 74 | #define STOP_BREAK 0x83 | ||
| 75 | #define BASE(a) ((a) < 4 ? (short*)CIRRUS_FIRST : ((a) < 8 ? (short *)CIRRUS_SECOND : ((a) < 12 ? (short*)CIRRUS_THIRD : (short *)CIRRUS_FOURTH))) | ||
| 76 | #define txack1 ((short *)0x7104) | ||
| 77 | #define rxack1 ((short *)0x7102) | ||
| 78 | #define mdack1 ((short *)0x7106) | ||
| 79 | #define txack2 ((short *)0x7006) | ||
| 80 | #define rxack2 ((short *)0x7004) | ||
| 81 | #define mdack2 ((short *)0x7100) | ||
| 82 | #define int_latch ((short *) 0x7800) | ||
| 83 | #define int_status ((short *) 0x7c00) | ||
| 84 | #define tx1_pending 0x20 | ||
| 85 | #define rx1_pending 0x10 | ||
| 86 | #define md1_pending 0x40 | ||
| 87 | #define tx2_pending 0x02 | ||
| 88 | #define rx2_pending 0x01 | ||
| 89 | #define md2_pending 0x40 | ||
| 90 | #define module1_bits 0x07 | ||
| 91 | #define module1_modern 0x08 | ||
| 92 | #define module2_bits 0x70 | ||
| 93 | #define module2_modern 0x80 | ||
| 94 | #define module_blank 0xf | ||
| 95 | #define rs232_d25 0x0 | ||
| 96 | #define rs232_rj45 0x1 | ||
| 97 | #define rs422_d25 0x3 | ||
| 98 | #define parallel 0x5 | ||
| 99 | |||
| 100 | #define CLK0 0x00 | ||
| 101 | #define CLK1 0x01 | ||
| 102 | #define CLK2 0x02 | ||
| 103 | #define CLK3 0x03 | ||
| 104 | #define CLK4 0x04 | ||
| 105 | |||
| 106 | #define CIRRUS_REVC 0x42 | ||
| 107 | #define CIRRUS_REVE 0x44 | ||
| 108 | |||
| 109 | #define TURNON 1 | ||
| 110 | #define TURNOFF 0 | ||
| 111 | |||
| 112 | /* The list of CIRRUS registers. | ||
| 113 | NB. These registers are relative values on 8 bit boundaries whereas | ||
| 114 | on the RTA's the CIRRUS registers are on word boundaries. Use pointer | ||
| 115 | arithmetic (short *) to obtain the real addresses required */ | ||
| 116 | #define ccr 0x05 /* Channel Command Register */ | ||
| 117 | #define ier 0x06 /* Interrupt Enable Register */ | ||
| 118 | #define cor1 0x08 /* Channel Option Register 1 */ | ||
| 119 | #define cor2 0x09 /* Channel Option Register 2 */ | ||
| 120 | #define cor3 0x0a /* Channel Option Register 3 */ | ||
| 121 | #define cor4 0x1e /* Channel Option Register 4 */ | ||
| 122 | #define cor5 0x1f /* Channel Option Register 5 */ | ||
| 123 | |||
| 124 | #define ccsr 0x0b /* Channel Control Status Register */ | ||
| 125 | #define rdcr 0x0e /* Receive Data Count Register */ | ||
| 126 | #define tdcr 0x12 /* Transmit Data Count Register */ | ||
| 127 | #define mcor1 0x15 /* Modem Change Option Register 1 */ | ||
| 128 | #define mcor2 0x16 /* Modem Change Option Regsiter 2 */ | ||
| 129 | |||
| 130 | #define livr 0x18 /* Local Interrupt Vector Register */ | ||
| 131 | #define schr1 0x1a /* Special Character Register 1 */ | ||
| 132 | #define schr2 0x1b /* Special Character Register 2 */ | ||
| 133 | #define schr3 0x1c /* Special Character Register 3 */ | ||
| 134 | #define schr4 0x1d /* Special Character Register 4 */ | ||
| 135 | |||
| 136 | #define rtr 0x20 /* Receive Timer Register */ | ||
| 137 | #define rtpr 0x21 /* Receive Timeout Period Register */ | ||
| 138 | #define lnc 0x24 /* Lnext character */ | ||
| 139 | |||
| 140 | #define rivr 0x43 /* Receive Interrupt Vector Register */ | ||
| 141 | #define tivr 0x42 /* Transmit Interrupt Vector Register */ | ||
| 142 | #define mivr 0x41 /* Modem Interrupt Vector Register */ | ||
| 143 | #define gfrcr 0x40 /* Global Firmware Revision code Reg */ | ||
| 144 | #define ricr 0x44 /* Receive Interrupting Channel Reg */ | ||
| 145 | #define ticr 0x45 /* Transmit Interrupting Channel Reg */ | ||
| 146 | #define micr 0x46 /* Modem Interrupting Channel Register */ | ||
| 147 | |||
| 148 | #define gcr 0x4b /* Global configuration register */ | ||
| 149 | #define misr 0x4c /* Modem interrupt status register */ | ||
| 150 | |||
| 151 | #define rbusr 0x59 | ||
| 152 | #define tbusr 0x5a | ||
| 153 | #define mbusr 0x5b | ||
| 154 | |||
| 155 | #define eoir 0x60 /* End Of Interrupt Register */ | ||
| 156 | #define rdsr 0x62 /* Receive Data / Status Register */ | ||
| 157 | #define tdr 0x63 /* Transmit Data Register */ | ||
| 158 | #define svrr 0x67 /* Service Request Register */ | ||
| 159 | |||
| 160 | #define car 0x68 /* Channel Access Register */ | ||
| 161 | #define mir 0x69 /* Modem Interrupt Register */ | ||
| 162 | #define tir 0x6a /* Transmit Interrupt Register */ | ||
| 163 | #define rir 0x6b /* Receive Interrupt Register */ | ||
| 164 | #define msvr1 0x6c /* Modem Signal Value Register 1 */ | ||
| 165 | #define msvr2 0x6d /* Modem Signal Value Register 2 */ | ||
| 166 | #define psvr 0x6f /* Printer Signal Value Register */ | ||
| 167 | |||
| 168 | #define tbpr 0x72 /* Transmit Baud Rate Period Register */ | ||
| 169 | #define tcor 0x76 /* Transmit Clock Option Register */ | ||
| 170 | |||
| 171 | #define rbpr 0x78 /* Receive Baud Rate Period Register */ | ||
| 172 | #define rber 0x7a /* Receive Baud Rate Extension Register */ | ||
| 173 | #define rcor 0x7c /* Receive Clock Option Register */ | ||
| 174 | #define ppr 0x7e /* Prescalar Period Register */ | ||
| 175 | |||
| 176 | /* Misc registers used for forcing the 1400 out of its reset woes */ | ||
| 177 | #define airl 0x6d | ||
| 178 | #define airm 0x6e | ||
| 179 | #define airh 0x6f | ||
| 180 | #define btcr 0x66 | ||
| 181 | #define mtcr 0x6c | ||
| 182 | #define tber 0x74 | ||
| 183 | |||
| 184 | #endif /* #ifdef RTA */ | ||
| 185 | 43 | ||
| 186 | 44 | ||
| 187 | /* Bit fields for particular registers */ | 45 | /* Bit fields for particular registers */ |
diff --git a/drivers/char/rio/defaults.h b/drivers/char/rio/defaults.h index 5b600c32ac02..d55c2f6a9877 100644 --- a/drivers/char/rio/defaults.h +++ b/drivers/char/rio/defaults.h | |||
| @@ -45,13 +45,6 @@ static char *_rio_defaults_h_sccs = "@(#)defaults.h 1.1"; | |||
| 45 | #define MILLISECOND (int) (1000/64) /* 15.625 low ticks */ | 45 | #define MILLISECOND (int) (1000/64) /* 15.625 low ticks */ |
| 46 | #define SECOND (int) 15625 /* Low priority ticks */ | 46 | #define SECOND (int) 15625 /* Low priority ticks */ |
| 47 | 47 | ||
| 48 | #ifdef RTA | ||
| 49 | #define RX_LIMIT (ushort) 3 | ||
| 50 | #endif | ||
| 51 | #ifdef HOST | ||
| 52 | #define RX_LIMIT (ushort) 1 | ||
| 53 | #endif | ||
| 54 | |||
| 55 | #define LINK_TIMEOUT (int) (POLL_PERIOD / 2) | 48 | #define LINK_TIMEOUT (int) (POLL_PERIOD / 2) |
| 56 | 49 | ||
| 57 | 50 | ||
diff --git a/drivers/char/rio/link.h b/drivers/char/rio/link.h index bfba5b0c033e..48d68ca7f825 100644 --- a/drivers/char/rio/link.h +++ b/drivers/char/rio/link.h | |||
| @@ -102,30 +102,14 @@ | |||
| 102 | /* | 102 | /* |
| 103 | ** LED stuff | 103 | ** LED stuff |
| 104 | */ | 104 | */ |
| 105 | #if defined(RTA) | ||
| 106 | #define LED_OFF ((ushort) 0) /* LED off */ | ||
| 107 | #define LED_RED ((ushort) 1) /* LED Red */ | ||
| 108 | #define LED_GREEN ((ushort) 2) /* LED Green */ | ||
| 109 | #define LED_ORANGE ((ushort) 4) /* LED Orange */ | ||
| 110 | #define LED_1TO8_OPEN ((ushort) 1) /* Port 1->8 LED on */ | ||
| 111 | #define LED_9TO16_OPEN ((ushort) 2) /* Port 9->16 LED on */ | ||
| 112 | #define LED_SET_COLOUR(colour) (link->led = (colour)) | ||
| 113 | #define LED_OR_COLOUR(colour) (link->led |= (colour)) | ||
| 114 | #define LED_TIMEOUT(time) (link->led_timeout = RioTimePlus(RioTime(),(time))) | ||
| 115 | #else | ||
| 116 | #define LED_SET_COLOUR(colour) | 105 | #define LED_SET_COLOUR(colour) |
| 117 | #define LED_OR_COLOUR(colour) | 106 | #define LED_OR_COLOUR(colour) |
| 118 | #define LED_TIMEOUT(time) | 107 | #define LED_TIMEOUT(time) |
| 119 | #endif /* RTA */ | ||
| 120 | 108 | ||
| 121 | struct LPB { | 109 | struct LPB { |
| 122 | WORD link_number; /* Link Number */ | 110 | WORD link_number; /* Link Number */ |
| 123 | Channel_ptr in_ch; /* Link In Channel */ | 111 | Channel_ptr in_ch; /* Link In Channel */ |
| 124 | Channel_ptr out_ch; /* Link Out Channel */ | 112 | Channel_ptr out_ch; /* Link Out Channel */ |
| 125 | #ifdef RTA | ||
| 126 | uchar stat_led; /* Port open leds */ | ||
| 127 | uchar led; /* True, light led! */ | ||
| 128 | #endif | ||
| 129 | BYTE attached_serial[4]; /* Attached serial number */ | 113 | BYTE attached_serial[4]; /* Attached serial number */ |
| 130 | BYTE attached_host_serial[4]; | 114 | BYTE attached_host_serial[4]; |
| 131 | /* Serial number of Host who | 115 | /* Serial number of Host who |
| @@ -144,30 +128,12 @@ struct LPB { | |||
| 144 | WORD WaitNoBoot; /* Secs to hold off booting */ | 128 | WORD WaitNoBoot; /* Secs to hold off booting */ |
| 145 | PKT_ptr add_packet_list; /* Add packets to here */ | 129 | PKT_ptr add_packet_list; /* Add packets to here */ |
| 146 | PKT_ptr remove_packet_list; /* Send packets from here */ | 130 | PKT_ptr remove_packet_list; /* Send packets from here */ |
| 147 | #ifdef RTA | ||
| 148 | #ifdef DCIRRUS | ||
| 149 | #define QBUFS_PER_REDIRECT (4 / PKTS_PER_BUFFER + 1) | ||
| 150 | #else | ||
| 151 | #define QBUFS_PER_REDIRECT (8 / PKTS_PER_BUFFER + 1) | ||
| 152 | #endif | ||
| 153 | PKT_ptr_ptr rd_add; /* Add a new Packet here */ | ||
| 154 | Q_BUF_ptr rd_add_qb; /* Pointer to the add Q buf */ | ||
| 155 | PKT_ptr_ptr rd_add_st_qbb; /* Pointer to start of the Q's buf */ | ||
| 156 | PKT_ptr_ptr rd_add_end_qbb; /* Pointer to the end of the Q's buf */ | ||
| 157 | PKT_ptr_ptr rd_remove; /* Remove a Packet here */ | ||
| 158 | Q_BUF_ptr rd_remove_qb; /* Pointer to the remove Q buf */ | ||
| 159 | PKT_ptr_ptr rd_remove_st_qbb; /* Pointer to the start of the Q buf */ | ||
| 160 | PKT_ptr_ptr rd_remove_end_qbb; /* Pointer to the end of the Q buf */ | ||
| 161 | ushort pkts_in_q; /* Packets in queue */ | ||
| 162 | #endif | ||
| 163 | 131 | ||
| 164 | Channel_ptr lrt_fail_chan; /* Lrt's failure channel */ | 132 | Channel_ptr lrt_fail_chan; /* Lrt's failure channel */ |
| 165 | Channel_ptr ltt_fail_chan; /* Ltt's failure channel */ | 133 | Channel_ptr ltt_fail_chan; /* Ltt's failure channel */ |
| 166 | 134 | ||
| 167 | #if defined (HOST) || defined (INKERNEL) | ||
| 168 | /* RUP structure for HOST to driver communications */ | 135 | /* RUP structure for HOST to driver communications */ |
| 169 | struct RUP rup; | 136 | struct RUP rup; |
| 170 | #endif | ||
| 171 | struct RUP link_rup; /* RUP for the link (POLL, | 137 | struct RUP link_rup; /* RUP for the link (POLL, |
| 172 | topology etc.) */ | 138 | topology etc.) */ |
| 173 | WORD attached_link; /* Number of attached link */ | 139 | WORD attached_link; /* Number of attached link */ |
diff --git a/drivers/char/rio/list.h b/drivers/char/rio/list.h index 36aad4c9cb3a..79b853140ae5 100644 --- a/drivers/char/rio/list.h +++ b/drivers/char/rio/list.h | |||
| @@ -44,8 +44,6 @@ static char *_rio_list_h_sccs = "@(#)list.h 1.9"; | |||
| 44 | 44 | ||
| 45 | #define PKT_IN_USE 0x1 | 45 | #define PKT_IN_USE 0x1 |
| 46 | 46 | ||
| 47 | #ifdef INKERNEL | ||
| 48 | |||
| 49 | #define ZERO_PTR (ushort) 0x8000 | 47 | #define ZERO_PTR (ushort) 0x8000 |
| 50 | #define CaD PortP->Caddr | 48 | #define CaD PortP->Caddr |
| 51 | 49 | ||
| @@ -54,143 +52,5 @@ static char *_rio_list_h_sccs = "@(#)list.h 1.9"; | |||
| 54 | ** to by the TxAdd pointer has PKT_IN_USE clear in its address. | 52 | ** to by the TxAdd pointer has PKT_IN_USE clear in its address. |
| 55 | */ | 53 | */ |
| 56 | 54 | ||
| 57 | #ifndef linux | ||
| 58 | #if defined( MIPS ) && !defined( MIPSEISA ) | ||
| 59 | /* May the shoes of the Devil dance on your grave for creating this */ | ||
| 60 | #define can_add_transmit(PacketP,PortP) \ | ||
| 61 | (!((uint)(PacketP = (struct PKT *)RIO_PTR(CaD,RINDW(PortP->TxAdd))) \ | ||
| 62 | & (PKT_IN_USE<<2))) | ||
| 63 | |||
| 64 | #elif defined(MIPSEISA) || defined(nx6000) || \ | ||
| 65 | defined(drs6000) || defined(UWsparc) | ||
| 66 | |||
| 67 | #define can_add_transmit(PacketP,PortP) \ | ||
| 68 | (!((uint)(PacketP = (struct PKT *)RIO_PTR(CaD,RINDW(PortP->TxAdd))) \ | ||
| 69 | & PKT_IN_USE)) | ||
| 70 | |||
| 71 | #else | ||
| 72 | #define can_add_transmit(PacketP,PortP) \ | ||
| 73 | (!((uint)(PacketP = (struct PKT *)RIO_PTR(CaD,*PortP->TxAdd)) \ | ||
| 74 | & PKT_IN_USE)) | ||
| 75 | #endif | ||
| 76 | |||
| 77 | /* | ||
| 78 | ** To add a packet to the queue, you set the PKT_IN_USE bit in the address, | ||
| 79 | ** and then move the TxAdd pointer along one position to point to the next | ||
| 80 | ** packet pointer. You must wrap the pointer from the end back to the start. | ||
| 81 | */ | ||
| 82 | #if defined(MIPS) || defined(nx6000) || defined(drs6000) || defined(UWsparc) | ||
| 83 | # define add_transmit(PortP) \ | ||
| 84 | WINDW(PortP->TxAdd,RINDW(PortP->TxAdd) | PKT_IN_USE);\ | ||
| 85 | if (PortP->TxAdd == PortP->TxEnd)\ | ||
| 86 | PortP->TxAdd = PortP->TxStart;\ | ||
| 87 | else\ | ||
| 88 | PortP->TxAdd++;\ | ||
| 89 | WWORD(PortP->PhbP->tx_add , RIO_OFF(CaD,PortP->TxAdd)); | ||
| 90 | #elif defined(AIX) | ||
| 91 | # define add_transmit(PortP) \ | ||
| 92 | {\ | ||
| 93 | register ushort *TxAddP = (ushort *)RIO_PTR(Cad,PortP->TxAddO);\ | ||
| 94 | WINDW( TxAddP, RINDW( TxAddP ) | PKT_IN_USE );\ | ||
| 95 | if (PortP->TxAddO == PortP->TxEndO )\ | ||
| 96 | PortP->TxAddO = PortP->TxStartO;\ | ||
| 97 | else\ | ||
| 98 | PortP->TxAddO += sizeof(ushort);\ | ||
| 99 | WWORD(((PHB *)RIO_PTR(Cad,PortP->PhbO))->tx_add , PortP->TxAddO );\ | ||
| 100 | } | ||
| 101 | #else | ||
| 102 | # define add_transmit(PortP) \ | ||
| 103 | *PortP->TxAdd |= PKT_IN_USE;\ | ||
| 104 | if (PortP->TxAdd == PortP->TxEnd)\ | ||
| 105 | PortP->TxAdd = PortP->TxStart;\ | ||
| 106 | else\ | ||
| 107 | PortP->TxAdd++;\ | ||
| 108 | PortP->PhbP->tx_add = RIO_OFF(CaD,PortP->TxAdd); | ||
| 109 | #endif | ||
| 110 | |||
| 111 | /* | ||
| 112 | ** can_remove_receive( PacketP, PortP ) returns non-zero if PKT_IN_USE is set | ||
| 113 | ** for the next packet on the queue. It will also set PacketP to point to the | ||
| 114 | ** relevant packet, [having cleared the PKT_IN_USE bit]. If PKT_IN_USE is clear, | ||
| 115 | ** then can_remove_receive() returns 0. | ||
| 116 | */ | ||
| 117 | #if defined(MIPS) || defined(nx6000) || defined(drs6000) || defined(UWsparc) | ||
| 118 | # define can_remove_receive(PacketP,PortP) \ | ||
| 119 | ((RINDW(PortP->RxRemove) & PKT_IN_USE) ? \ | ||
| 120 | (PacketP=(struct PKT *)RIO_PTR(CaD,(RINDW(PortP->RxRemove) & ~PKT_IN_USE))):0) | ||
| 121 | #elif defined(AIX) | ||
| 122 | # define can_remove_receive(PacketP,PortP) \ | ||
| 123 | ((RINDW((ushort *)RIO_PTR(Cad,PortP->RxRemoveO)) & PKT_IN_USE) ? \ | ||
| 124 | (PacketP=(struct PKT *)RIO_PTR(Cad,RINDW((ushort *)RIO_PTR(Cad,PortP->RxRemoveO)) & ~PKT_IN_USE)):0) | ||
| 125 | #else | ||
| 126 | # define can_remove_receive(PacketP,PortP) \ | ||
| 127 | ((*PortP->RxRemove & PKT_IN_USE) ? \ | ||
| 128 | (PacketP=(struct PKT *)RIO_PTR(CaD,(*PortP->RxRemove & ~PKT_IN_USE))):0) | ||
| 129 | #endif | ||
| 130 | |||
| 131 | |||
| 132 | /* | ||
| 133 | ** Will God see it within his heart to forgive us for this thing that | ||
| 134 | ** we have created? To remove a packet from the receive queue you clear | ||
| 135 | ** its PKT_IN_USE bit, and then bump the pointers. Once the pointers | ||
| 136 | ** get to the end, they must be wrapped back to the start. | ||
| 137 | */ | ||
| 138 | #if defined(MIPS) || defined(nx6000) || defined(drs6000) || defined(UWsparc) | ||
| 139 | # define remove_receive(PortP) \ | ||
| 140 | WINDW(PortP->RxRemove, (RINDW(PortP->RxRemove) & ~PKT_IN_USE));\ | ||
| 141 | if (PortP->RxRemove == PortP->RxEnd)\ | ||
| 142 | PortP->RxRemove = PortP->RxStart;\ | ||
| 143 | else\ | ||
| 144 | PortP->RxRemove++;\ | ||
| 145 | WWORD(PortP->PhbP->rx_remove , RIO_OFF(CaD,PortP->RxRemove)); | ||
| 146 | #elif defined(AIX) | ||
| 147 | # define remove_receive(PortP) \ | ||
| 148 | {\ | ||
| 149 | register ushort *RxRemoveP = (ushort *)RIO_PTR(Cad,PortP->RxRemoveO);\ | ||
| 150 | WINDW( RxRemoveP, RINDW( RxRemoveP ) & ~PKT_IN_USE );\ | ||
| 151 | if (PortP->RxRemoveO == PortP->RxEndO)\ | ||
| 152 | PortP->RxRemoveO = PortP->RxStartO;\ | ||
| 153 | else\ | ||
| 154 | PortP->RxRemoveO += sizeof(ushort);\ | ||
| 155 | WWORD(((PHB *)RIO_PTR(Cad,PortP->PhbO))->rx_remove, PortP->RxRemoveO );\ | ||
| 156 | } | ||
| 157 | #else | ||
| 158 | # define remove_receive(PortP) \ | ||
| 159 | *PortP->RxRemove &= ~PKT_IN_USE;\ | ||
| 160 | if (PortP->RxRemove == PortP->RxEnd)\ | ||
| 161 | PortP->RxRemove = PortP->RxStart;\ | ||
| 162 | else\ | ||
| 163 | PortP->RxRemove++;\ | ||
| 164 | PortP->PhbP->rx_remove = RIO_OFF(CaD,PortP->RxRemove); | ||
| 165 | #endif | ||
| 166 | #endif | ||
| 167 | |||
| 168 | |||
| 169 | #else /* !IN_KERNEL */ | ||
| 170 | |||
| 171 | #define ZERO_PTR NULL | ||
| 172 | |||
| 173 | |||
| 174 | #ifdef HOST | ||
| 175 | /* #define can_remove_transmit(pkt,phb) ((((char*)pkt = (*(char**)(phb->tx_remove))-1) || 1)) && (*phb->u3.s2.tx_remove_ptr & PKT_IN_USE)) */ | ||
| 176 | #define remove_transmit(phb) *phb->u3.s2.tx_remove_ptr &= ~(ushort)PKT_IN_USE;\ | ||
| 177 | if (phb->tx_remove == phb->tx_end)\ | ||
| 178 | phb->tx_remove = phb->tx_start;\ | ||
| 179 | else\ | ||
| 180 | phb->tx_remove++; | ||
| 181 | #define can_add_receive(phb) !(*phb->u4.s2.rx_add_ptr & PKT_IN_USE) | ||
| 182 | #define add_receive(pkt,phb) *phb->rx_add = pkt;\ | ||
| 183 | *phb->u4.s2.rx_add_ptr |= PKT_IN_USE;\ | ||
| 184 | if (phb->rx_add == phb->rx_end)\ | ||
| 185 | phb->rx_add = phb->rx_start;\ | ||
| 186 | else\ | ||
| 187 | phb->rx_add++; | ||
| 188 | #endif | ||
| 189 | #endif | ||
| 190 | |||
| 191 | #ifdef RTA | ||
| 192 | #define splx(oldspl) if ((oldspl) == 0) spl0() | ||
| 193 | #endif | ||
| 194 | |||
| 195 | #endif /* ifndef _list.h */ | 55 | #endif /* ifndef _list.h */ |
| 196 | /*********** end of file ***********/ | 56 | /*********** end of file ***********/ |
diff --git a/drivers/char/rio/parmmap.h b/drivers/char/rio/parmmap.h index fe4e00567065..e24acc1d1844 100644 --- a/drivers/char/rio/parmmap.h +++ b/drivers/char/rio/parmmap.h | |||
| @@ -78,14 +78,9 @@ struct PARM_MAP { | |||
| 78 | WORD idle_count; /* Idle time counter */ | 78 | WORD idle_count; /* Idle time counter */ |
| 79 | WORD busy_count; /* Busy counter */ | 79 | WORD busy_count; /* Busy counter */ |
| 80 | WORD idle_control; /* Control Idle Process */ | 80 | WORD idle_control; /* Control Idle Process */ |
| 81 | #if defined(HOST) || defined(INKERNEL) | ||
| 82 | WORD tx_intr; /* TX interrupt pending */ | 81 | WORD tx_intr; /* TX interrupt pending */ |
| 83 | WORD rx_intr; /* RX interrupt pending */ | 82 | WORD rx_intr; /* RX interrupt pending */ |
| 84 | WORD rup_intr; /* RUP interrupt pending */ | 83 | WORD rup_intr; /* RUP interrupt pending */ |
| 85 | #endif | ||
| 86 | #if defined(RTA) | ||
| 87 | WORD dying_count; /* Count of processes dead */ | ||
| 88 | #endif | ||
| 89 | }; | 84 | }; |
| 90 | 85 | ||
| 91 | #endif | 86 | #endif |
diff --git a/drivers/char/rio/phb.h b/drivers/char/rio/phb.h index 3baebf8513af..2663ca0306e2 100644 --- a/drivers/char/rio/phb.h +++ b/drivers/char/rio/phb.h | |||
| @@ -44,17 +44,6 @@ | |||
| 44 | #endif | 44 | #endif |
| 45 | 45 | ||
| 46 | 46 | ||
| 47 | /************************************************* | ||
| 48 | * Set the LIMIT values. | ||
| 49 | ************************************************/ | ||
| 50 | #ifdef RTA | ||
| 51 | #define RX_LIMIT (ushort) 3 | ||
| 52 | #endif | ||
| 53 | #ifdef HOST | ||
| 54 | #define RX_LIMIT (ushort) 1 | ||
| 55 | #endif | ||
| 56 | |||
| 57 | |||
| 58 | /************************************************* | 47 | /************************************************* |
| 59 | * Handshake asserted. Deasserted by the LTT(s) | 48 | * Handshake asserted. Deasserted by the LTT(s) |
| 60 | ************************************************/ | 49 | ************************************************/ |
| @@ -69,11 +58,7 @@ | |||
| 69 | /************************************************* | 58 | /************************************************* |
| 70 | * Maximum number of PHB's | 59 | * Maximum number of PHB's |
| 71 | ************************************************/ | 60 | ************************************************/ |
| 72 | #if defined (HOST) || defined (INKERNEL) | ||
| 73 | #define MAX_PHB ((ushort) 128) /* range 0-127 */ | 61 | #define MAX_PHB ((ushort) 128) /* range 0-127 */ |
| 74 | #else | ||
| 75 | #define MAX_PHB ((ushort) 8) /* range 0-7 */ | ||
| 76 | #endif | ||
| 77 | 62 | ||
| 78 | /************************************************* | 63 | /************************************************* |
| 79 | * Defines for the mode fields | 64 | * Defines for the mode fields |
| @@ -139,141 +124,23 @@ | |||
| 139 | * the start. The pointer tx_add points to a SPACE to put a Packet. | 124 | * the start. The pointer tx_add points to a SPACE to put a Packet. |
| 140 | * The pointer tx_remove points to the next Packet to remove | 125 | * The pointer tx_remove points to the next Packet to remove |
| 141 | *************************************************************************/ | 126 | *************************************************************************/ |
| 142 | #ifndef INKERNEL | ||
| 143 | #define src_unit u2.s2.unit | ||
| 144 | #define src_port u2.s2.port | ||
| 145 | #define dest_unit u1.s1.unit | ||
| 146 | #define dest_port u1.s1.port | ||
| 147 | #endif | ||
| 148 | #ifdef HOST | ||
| 149 | #define tx_start u3.s1.tx_start_ptr_ptr | ||
| 150 | #define tx_add u3.s1.tx_add_ptr_ptr | ||
| 151 | #define tx_end u3.s1.tx_end_ptr_ptr | ||
| 152 | #define tx_remove u3.s1.tx_remove_ptr_ptr | ||
| 153 | #define rx_start u4.s1.rx_start_ptr_ptr | ||
| 154 | #define rx_add u4.s1.rx_add_ptr_ptr | ||
| 155 | #define rx_end u4.s1.rx_end_ptr_ptr | ||
| 156 | #define rx_remove u4.s1.rx_remove_ptr_ptr | ||
| 157 | #endif | ||
| 158 | typedef struct PHB PHB; | 127 | typedef struct PHB PHB; |
| 159 | struct PHB { | 128 | struct PHB { |
| 160 | #ifdef RTA | ||
| 161 | ushort port; | ||
| 162 | #endif | ||
| 163 | #ifdef INKERNEL | ||
| 164 | WORD source; | 129 | WORD source; |
| 165 | #else | ||
| 166 | union { | ||
| 167 | ushort source; /* Complete source */ | ||
| 168 | struct { | ||
| 169 | unsigned char unit; /* Source unit */ | ||
| 170 | unsigned char port; /* Source port */ | ||
| 171 | } s2; | ||
| 172 | } u2; | ||
| 173 | #endif | ||
| 174 | WORD handshake; | 130 | WORD handshake; |
| 175 | WORD status; | 131 | WORD status; |
| 176 | NUMBER timeout; /* Maximum of 1.9 seconds */ | 132 | NUMBER timeout; /* Maximum of 1.9 seconds */ |
| 177 | WORD link; /* Send down this link */ | 133 | WORD link; /* Send down this link */ |
| 178 | #ifdef INKERNEL | ||
| 179 | WORD destination; | 134 | WORD destination; |
| 180 | #else | ||
| 181 | union { | ||
| 182 | ushort destination; /* Complete destination */ | ||
| 183 | struct { | ||
| 184 | unsigned char unit; /* Destination unit */ | ||
| 185 | unsigned char port; /* Destination port */ | ||
| 186 | } s1; | ||
| 187 | } u1; | ||
| 188 | #endif | ||
| 189 | #ifdef RTA | ||
| 190 | ushort tx_pkts_added; | ||
| 191 | ushort tx_pkts_removed; | ||
| 192 | Q_BUF_ptr tx_q_start; /* Start of the Q list chain */ | ||
| 193 | short num_tx_q_bufs; /* Number of Q buffers in the chain */ | ||
| 194 | PKT_ptr_ptr tx_add; /* Add a new Packet here */ | ||
| 195 | Q_BUF_ptr tx_add_qb; /* Pointer to the add Q buf */ | ||
| 196 | PKT_ptr_ptr tx_add_st_qbb; /* Pointer to start of the Q's buf */ | ||
| 197 | PKT_ptr_ptr tx_add_end_qbb; /* Pointer to the end of the Q's buf */ | ||
| 198 | PKT_ptr_ptr tx_remove; /* Remove a Packet here */ | ||
| 199 | Q_BUF_ptr tx_remove_qb; /* Pointer to the remove Q buf */ | ||
| 200 | PKT_ptr_ptr tx_remove_st_qbb; /* Pointer to the start of the Q buf */ | ||
| 201 | PKT_ptr_ptr tx_remove_end_qbb; /* Pointer to the end of the Q buf */ | ||
| 202 | #endif | ||
| 203 | #ifdef INKERNEL | ||
| 204 | PKT_ptr_ptr tx_start; | 135 | PKT_ptr_ptr tx_start; |
| 205 | PKT_ptr_ptr tx_end; | 136 | PKT_ptr_ptr tx_end; |
| 206 | PKT_ptr_ptr tx_add; | 137 | PKT_ptr_ptr tx_add; |
| 207 | PKT_ptr_ptr tx_remove; | 138 | PKT_ptr_ptr tx_remove; |
| 208 | #endif | ||
| 209 | #ifdef HOST | ||
| 210 | union { | ||
| 211 | struct { | ||
| 212 | PKT_ptr_ptr tx_start_ptr_ptr; | ||
| 213 | PKT_ptr_ptr tx_end_ptr_ptr; | ||
| 214 | PKT_ptr_ptr tx_add_ptr_ptr; | ||
| 215 | PKT_ptr_ptr tx_remove_ptr_ptr; | ||
| 216 | } s1; | ||
| 217 | struct { | ||
| 218 | ushort *tx_start_ptr; | ||
| 219 | ushort *tx_end_ptr; | ||
| 220 | ushort *tx_add_ptr; | ||
| 221 | ushort *tx_remove_ptr; | ||
| 222 | } s2; | ||
| 223 | } u3; | ||
| 224 | #endif | ||
| 225 | 139 | ||
| 226 | #ifdef RTA | ||
| 227 | ushort rx_pkts_added; | ||
| 228 | ushort rx_pkts_removed; | ||
| 229 | Q_BUF_ptr rx_q_start; /* Start of the Q list chain */ | ||
| 230 | short num_rx_q_bufs; /* Number of Q buffers in the chain */ | ||
| 231 | PKT_ptr_ptr rx_add; /* Add a new Packet here */ | ||
| 232 | Q_BUF_ptr rx_add_qb; /* Pointer to the add Q buf */ | ||
| 233 | PKT_ptr_ptr rx_add_st_qbb; /* Pointer to start of the Q's buf */ | ||
| 234 | PKT_ptr_ptr rx_add_end_qbb; /* Pointer to the end of the Q's buf */ | ||
| 235 | PKT_ptr_ptr rx_remove; /* Remove a Packet here */ | ||
| 236 | Q_BUF_ptr rx_remove_qb; /* Pointer to the remove Q buf */ | ||
| 237 | PKT_ptr_ptr rx_remove_st_qbb; /* Pointer to the start of the Q buf */ | ||
| 238 | PKT_ptr_ptr rx_remove_end_qbb; /* Pointer to the end of the Q buf */ | ||
| 239 | #endif | ||
| 240 | #ifdef INKERNEL | ||
| 241 | PKT_ptr_ptr rx_start; | 140 | PKT_ptr_ptr rx_start; |
| 242 | PKT_ptr_ptr rx_end; | 141 | PKT_ptr_ptr rx_end; |
| 243 | PKT_ptr_ptr rx_add; | 142 | PKT_ptr_ptr rx_add; |
| 244 | PKT_ptr_ptr rx_remove; | 143 | PKT_ptr_ptr rx_remove; |
| 245 | #endif | ||
| 246 | #ifdef HOST | ||
| 247 | union { | ||
| 248 | struct { | ||
| 249 | PKT_ptr_ptr rx_start_ptr_ptr; | ||
| 250 | PKT_ptr_ptr rx_end_ptr_ptr; | ||
| 251 | PKT_ptr_ptr rx_add_ptr_ptr; | ||
| 252 | PKT_ptr_ptr rx_remove_ptr_ptr; | ||
| 253 | } s1; | ||
| 254 | struct { | ||
| 255 | ushort *rx_start_ptr; | ||
| 256 | ushort *rx_end_ptr; | ||
| 257 | ushort *rx_add_ptr; | ||
| 258 | ushort *rx_remove_ptr; | ||
| 259 | } s2; | ||
| 260 | } u4; | ||
| 261 | #endif | ||
| 262 | |||
| 263 | #ifdef RTA /* some fields for the remotes */ | ||
| 264 | ushort flush_count; /* Count of write flushes */ | ||
| 265 | ushort txmode; /* Modes for tx */ | ||
| 266 | ushort rxmode; /* Modes for rx */ | ||
| 267 | ushort portmode; /* Generic modes */ | ||
| 268 | ushort column; /* TAB3 column count */ | ||
| 269 | ushort tx_subscript; /* (TX) Subscript into data field */ | ||
| 270 | ushort rx_subscript; /* (RX) Subscript into data field */ | ||
| 271 | PKT_ptr rx_incomplete; /* Hold an incomplete packet here */ | ||
| 272 | ushort modem_bits; /* Modem bits to mask */ | ||
| 273 | ushort lastModem; /* Modem control lines. */ | ||
| 274 | ushort addr; /* Address for sub commands */ | ||
| 275 | ushort MonitorTstate; /* TRUE if monitoring tstop */ | ||
| 276 | #endif | ||
| 277 | 144 | ||
| 278 | }; | 145 | }; |
| 279 | 146 | ||
diff --git a/drivers/char/rio/pkt.h b/drivers/char/rio/pkt.h index 882fd429ac2e..7011e52e82db 100644 --- a/drivers/char/rio/pkt.h +++ b/drivers/char/rio/pkt.h | |||
| @@ -70,39 +70,12 @@ | |||
| 70 | #define CONTROL_DATA_WNDW (DATA_WNDW << 8) | 70 | #define CONTROL_DATA_WNDW (DATA_WNDW << 8) |
| 71 | 71 | ||
| 72 | struct PKT { | 72 | struct PKT { |
| 73 | #ifdef INKERNEL | ||
| 74 | BYTE dest_unit; /* Destination Unit Id */ | 73 | BYTE dest_unit; /* Destination Unit Id */ |
| 75 | BYTE dest_port; /* Destination POrt */ | 74 | BYTE dest_port; /* Destination POrt */ |
| 76 | BYTE src_unit; /* Source Unit Id */ | 75 | BYTE src_unit; /* Source Unit Id */ |
| 77 | BYTE src_port; /* Source POrt */ | 76 | BYTE src_port; /* Source POrt */ |
| 78 | #else | ||
| 79 | union { | ||
| 80 | ushort destination; /* Complete destination */ | ||
| 81 | struct { | ||
| 82 | unsigned char unit; /* Destination unit */ | ||
| 83 | unsigned char port; /* Destination port */ | ||
| 84 | } s1; | ||
| 85 | } u1; | ||
| 86 | union { | ||
| 87 | ushort source; /* Complete source */ | ||
| 88 | struct { | ||
| 89 | unsigned char unit; /* Source unit */ | ||
| 90 | unsigned char port; /* Source port */ | ||
| 91 | } s2; | ||
| 92 | } u2; | ||
| 93 | #endif | ||
| 94 | #ifdef INKERNEL | ||
| 95 | BYTE len; | 77 | BYTE len; |
| 96 | BYTE control; | 78 | BYTE control; |
| 97 | #else | ||
| 98 | union { | ||
| 99 | ushort control; | ||
| 100 | struct { | ||
| 101 | unsigned char len; | ||
| 102 | unsigned char control; | ||
| 103 | } s3; | ||
| 104 | } u3; | ||
| 105 | #endif | ||
| 106 | BYTE data[PKT_MAX_DATA_LEN]; | 79 | BYTE data[PKT_MAX_DATA_LEN]; |
| 107 | /* Actual data :-) */ | 80 | /* Actual data :-) */ |
| 108 | WORD csum; /* C-SUM */ | 81 | WORD csum; /* C-SUM */ |
diff --git a/drivers/char/rio/qbuf.h b/drivers/char/rio/qbuf.h index acd9e8e5307d..391ffc335535 100644 --- a/drivers/char/rio/qbuf.h +++ b/drivers/char/rio/qbuf.h | |||
| @@ -46,11 +46,7 @@ static char *_rio_qbuf_h_sccs = "@(#)qbuf.h 1.1"; | |||
| 46 | 46 | ||
| 47 | 47 | ||
| 48 | 48 | ||
| 49 | #ifdef HOST | ||
| 50 | #define PKTS_PER_BUFFER 1 | ||
| 51 | #else | ||
| 52 | #define PKTS_PER_BUFFER (220 / PKT_LENGTH) | 49 | #define PKTS_PER_BUFFER (220 / PKT_LENGTH) |
| 53 | #endif | ||
| 54 | 50 | ||
| 55 | typedef struct Q_BUF Q_BUF; | 51 | typedef struct Q_BUF Q_BUF; |
| 56 | struct Q_BUF { | 52 | struct Q_BUF { |
diff --git a/drivers/char/rio/riotypes.h b/drivers/char/rio/riotypes.h index 9b67e2468bec..46084d5c7e98 100644 --- a/drivers/char/rio/riotypes.h +++ b/drivers/char/rio/riotypes.h | |||
| @@ -43,9 +43,6 @@ | |||
| 43 | #endif | 43 | #endif |
| 44 | #endif | 44 | #endif |
| 45 | 45 | ||
| 46 | #ifdef INKERNEL | ||
| 47 | |||
| 48 | #if !defined(MIPSAT) | ||
| 49 | typedef unsigned short NUMBER_ptr; | 46 | typedef unsigned short NUMBER_ptr; |
| 50 | typedef unsigned short WORD_ptr; | 47 | typedef unsigned short WORD_ptr; |
| 51 | typedef unsigned short BYTE_ptr; | 48 | typedef unsigned short BYTE_ptr; |
| @@ -65,69 +62,6 @@ typedef unsigned short RUP_ptr; | |||
| 65 | typedef unsigned short short_ptr; | 62 | typedef unsigned short short_ptr; |
| 66 | typedef unsigned short u_short_ptr; | 63 | typedef unsigned short u_short_ptr; |
| 67 | typedef unsigned short ushort_ptr; | 64 | typedef unsigned short ushort_ptr; |
| 68 | #else | ||
| 69 | /* MIPSAT types */ | ||
| 70 | typedef char RIO_POINTER[8]; | ||
| 71 | typedef RIO_POINTER NUMBER_ptr; | ||
| 72 | typedef RIO_POINTER WORD_ptr; | ||
| 73 | typedef RIO_POINTER BYTE_ptr; | ||
| 74 | typedef RIO_POINTER char_ptr; | ||
| 75 | typedef RIO_POINTER Channel_ptr; | ||
| 76 | typedef RIO_POINTER FREE_LIST_ptr_ptr; | ||
| 77 | typedef RIO_POINTER FREE_LIST_ptr; | ||
| 78 | typedef RIO_POINTER LPB_ptr; | ||
| 79 | typedef RIO_POINTER Process_ptr; | ||
| 80 | typedef RIO_POINTER PHB_ptr; | ||
| 81 | typedef RIO_POINTER PKT_ptr; | ||
| 82 | typedef RIO_POINTER PKT_ptr_ptr; | ||
| 83 | typedef RIO_POINTER Q_BUF_ptr; | ||
| 84 | typedef RIO_POINTER Q_BUF_ptr_ptr; | ||
| 85 | typedef RIO_POINTER ROUTE_STR_ptr; | ||
| 86 | typedef RIO_POINTER RUP_ptr; | ||
| 87 | typedef RIO_POINTER short_ptr; | ||
| 88 | typedef RIO_POINTER u_short_ptr; | ||
| 89 | typedef RIO_POINTER ushort_ptr; | ||
| 90 | #endif | ||
| 91 | |||
| 92 | #else /* not INKERNEL */ | ||
| 93 | typedef unsigned char BYTE; | ||
| 94 | typedef unsigned short WORD; | ||
| 95 | typedef unsigned long DWORD; | ||
| 96 | typedef short NUMBER; | ||
| 97 | typedef short *NUMBER_ptr; | ||
| 98 | typedef unsigned short *WORD_ptr; | ||
| 99 | typedef unsigned char *BYTE_ptr; | ||
| 100 | typedef unsigned char uchar; | ||
| 101 | typedef unsigned short ushort; | ||
| 102 | typedef unsigned int uint; | ||
| 103 | typedef unsigned long ulong; | ||
| 104 | typedef unsigned char u_char; | ||
| 105 | typedef unsigned short u_short; | ||
| 106 | typedef unsigned int u_int; | ||
| 107 | typedef unsigned long u_long; | ||
| 108 | typedef unsigned short ERROR; | ||
| 109 | typedef unsigned long ID; | ||
| 110 | typedef char *char_ptr; | ||
| 111 | typedef Channel *Channel_ptr; | ||
| 112 | typedef struct FREE_LIST *FREE_LIST_ptr; | ||
| 113 | typedef struct FREE_LIST **FREE_LIST_ptr_ptr; | ||
| 114 | typedef struct LPB *LPB_ptr; | ||
| 115 | typedef struct Process *Process_ptr; | ||
| 116 | typedef struct PHB *PHB_ptr; | ||
| 117 | typedef struct PKT *PKT_ptr; | ||
| 118 | typedef struct PKT **PKT_ptr_ptr; | ||
| 119 | typedef struct Q_BUF *Q_BUF_ptr; | ||
| 120 | typedef struct Q_BUF **Q_BUF_ptr_ptr; | ||
| 121 | typedef struct ROUTE_STR *ROUTE_STR_ptr; | ||
| 122 | typedef struct RUP *RUP_ptr; | ||
| 123 | typedef short *short_ptr; | ||
| 124 | typedef u_short *u_short_ptr; | ||
| 125 | typedef ushort *ushort_ptr; | ||
| 126 | typedef struct PKT PKT; | ||
| 127 | typedef struct LPB LPB; | ||
| 128 | typedef struct RUP RUP; | ||
| 129 | #endif | ||
| 130 | |||
| 131 | 65 | ||
| 132 | #endif /* __riotypes__ */ | 66 | #endif /* __riotypes__ */ |
| 133 | 67 | ||
diff --git a/drivers/char/rio/rup.h b/drivers/char/rio/rup.h index 8d44fec91dd5..f74f67c6f702 100644 --- a/drivers/char/rio/rup.h +++ b/drivers/char/rio/rup.h | |||
| @@ -43,12 +43,7 @@ | |||
| 43 | #endif | 43 | #endif |
| 44 | #endif | 44 | #endif |
| 45 | 45 | ||
| 46 | #if defined( HOST ) || defined( INKERNEL ) | ||
| 47 | #define MAX_RUP ((short) 16) | 46 | #define MAX_RUP ((short) 16) |
| 48 | #endif | ||
| 49 | #ifdef RTA | ||
| 50 | #define MAX_RUP ((short) 1) | ||
| 51 | #endif | ||
| 52 | 47 | ||
| 53 | #define PKTS_PER_RUP ((short) 2) /* They are always used in pairs */ | 48 | #define PKTS_PER_RUP ((short) 2) /* They are always used in pairs */ |
| 54 | 49 | ||
diff --git a/drivers/char/rio/sam.h b/drivers/char/rio/sam.h index 31494054b213..6f754e19015d 100644 --- a/drivers/char/rio/sam.h +++ b/drivers/char/rio/sam.h | |||
| @@ -43,10 +43,6 @@ | |||
| 43 | #endif | 43 | #endif |
| 44 | 44 | ||
| 45 | 45 | ||
| 46 | #if !defined( HOST ) && !defined( INKERNEL ) | ||
| 47 | #define RTA 1 | ||
| 48 | #endif | ||
| 49 | |||
| 50 | #define NUM_FREE_LIST_UNITS 500 | 46 | #define NUM_FREE_LIST_UNITS 500 |
| 51 | 47 | ||
| 52 | #ifndef FALSE | 48 | #ifndef FALSE |
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index 0949dcef0697..7edc6a4dbdc4 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
| @@ -433,7 +433,7 @@ static void rp_do_receive(struct r_port *info, | |||
| 433 | count += ToRecv; | 433 | count += ToRecv; |
| 434 | } | 434 | } |
| 435 | /* Push the data up to the tty layer */ | 435 | /* Push the data up to the tty layer */ |
| 436 | ld->receive_buf(tty, cbuf, fbuf, count); | 436 | ld->receive_buf(tty, chead, fhead, count); |
| 437 | done: | 437 | done: |
| 438 | tty_ldisc_deref(ld); | 438 | tty_ldisc_deref(ld); |
| 439 | } | 439 | } |
diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c index 80a5b840e22f..fee68cc895f8 100644 --- a/drivers/char/ser_a2232.c +++ b/drivers/char/ser_a2232.c | |||
| @@ -103,6 +103,7 @@ | |||
| 103 | 103 | ||
| 104 | #include <linux/serial.h> | 104 | #include <linux/serial.h> |
| 105 | #include <linux/generic_serial.h> | 105 | #include <linux/generic_serial.h> |
| 106 | #include <linux/tty_flip.h> | ||
| 106 | 107 | ||
| 107 | #include "ser_a2232.h" | 108 | #include "ser_a2232.h" |
| 108 | #include "ser_a2232fw.h" | 109 | #include "ser_a2232fw.h" |
diff --git a/drivers/char/sx.c b/drivers/char/sx.c index 64bf89cb574f..c2490e270f1f 100644 --- a/drivers/char/sx.c +++ b/drivers/char/sx.c | |||
| @@ -931,7 +931,7 @@ static int sx_set_real_termios (void *ptr) | |||
| 931 | case CS6:sx_write_channel_byte (port, hi_mask, 0x3f);break; | 931 | case CS6:sx_write_channel_byte (port, hi_mask, 0x3f);break; |
| 932 | case CS5:sx_write_channel_byte (port, hi_mask, 0x1f);break; | 932 | case CS5:sx_write_channel_byte (port, hi_mask, 0x1f);break; |
| 933 | default: | 933 | default: |
| 934 | printk (KERN_INFO "sx: Invalid wordsize: %d\n", CFLAG & CSIZE); | 934 | printk (KERN_INFO "sx: Invalid wordsize: %u\n", CFLAG & CSIZE); |
| 935 | break; | 935 | break; |
| 936 | } | 936 | } |
| 937 | 937 | ||
| @@ -958,7 +958,7 @@ static int sx_set_real_termios (void *ptr) | |||
| 958 | } else { | 958 | } else { |
| 959 | set_bit(TTY_HW_COOK_IN, &port->gs.tty->flags); | 959 | set_bit(TTY_HW_COOK_IN, &port->gs.tty->flags); |
| 960 | } | 960 | } |
| 961 | sx_dprintk (SX_DEBUG_TERMIOS, "iflags: %x(%d) ", | 961 | sx_dprintk (SX_DEBUG_TERMIOS, "iflags: %x(%d) ", |
| 962 | port->gs.tty->termios->c_iflag, | 962 | port->gs.tty->termios->c_iflag, |
| 963 | I_OTHER(port->gs.tty)); | 963 | I_OTHER(port->gs.tty)); |
| 964 | 964 | ||
| @@ -973,7 +973,7 @@ static int sx_set_real_termios (void *ptr) | |||
| 973 | } else { | 973 | } else { |
| 974 | clear_bit(TTY_HW_COOK_OUT, &port->gs.tty->flags); | 974 | clear_bit(TTY_HW_COOK_OUT, &port->gs.tty->flags); |
| 975 | } | 975 | } |
| 976 | sx_dprintk (SX_DEBUG_TERMIOS, "oflags: %x(%d)\n", | 976 | sx_dprintk (SX_DEBUG_TERMIOS, "oflags: %x(%d)\n", |
| 977 | port->gs.tty->termios->c_oflag, | 977 | port->gs.tty->termios->c_oflag, |
| 978 | O_OTHER(port->gs.tty)); | 978 | O_OTHER(port->gs.tty)); |
| 979 | /* port->c_dcd = sx_get_CD (port); */ | 979 | /* port->c_dcd = sx_get_CD (port); */ |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index eb8b5be4e249..076e07c1da38 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
| @@ -253,6 +253,7 @@ static void tty_buffer_free_all(struct tty_struct *tty) | |||
| 253 | 253 | ||
| 254 | static void tty_buffer_init(struct tty_struct *tty) | 254 | static void tty_buffer_init(struct tty_struct *tty) |
| 255 | { | 255 | { |
| 256 | spin_lock_init(&tty->buf.lock); | ||
| 256 | tty->buf.head = NULL; | 257 | tty->buf.head = NULL; |
| 257 | tty->buf.tail = NULL; | 258 | tty->buf.tail = NULL; |
| 258 | tty->buf.free = NULL; | 259 | tty->buf.free = NULL; |
| @@ -266,6 +267,7 @@ static struct tty_buffer *tty_buffer_alloc(size_t size) | |||
| 266 | p->used = 0; | 267 | p->used = 0; |
| 267 | p->size = size; | 268 | p->size = size; |
| 268 | p->next = NULL; | 269 | p->next = NULL; |
| 270 | p->active = 0; | ||
| 269 | p->char_buf_ptr = (char *)(p->data); | 271 | p->char_buf_ptr = (char *)(p->data); |
| 270 | p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; | 272 | p->flag_buf_ptr = (unsigned char *)p->char_buf_ptr + size; |
| 271 | /* printk("Flip create %p\n", p); */ | 273 | /* printk("Flip create %p\n", p); */ |
| @@ -312,25 +314,36 @@ static struct tty_buffer *tty_buffer_find(struct tty_struct *tty, size_t size) | |||
| 312 | 314 | ||
| 313 | int tty_buffer_request_room(struct tty_struct *tty, size_t size) | 315 | int tty_buffer_request_room(struct tty_struct *tty, size_t size) |
| 314 | { | 316 | { |
| 315 | struct tty_buffer *b = tty->buf.tail, *n; | 317 | struct tty_buffer *b, *n; |
| 316 | int left = 0; | 318 | int left; |
| 319 | unsigned long flags; | ||
| 320 | |||
| 321 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
| 317 | 322 | ||
| 318 | /* OPTIMISATION: We could keep a per tty "zero" sized buffer to | 323 | /* OPTIMISATION: We could keep a per tty "zero" sized buffer to |
| 319 | remove this conditional if its worth it. This would be invisible | 324 | remove this conditional if its worth it. This would be invisible |
| 320 | to the callers */ | 325 | to the callers */ |
| 321 | if(b != NULL) | 326 | if ((b = tty->buf.tail) != NULL) { |
| 322 | left = b->size - b->used; | 327 | left = b->size - b->used; |
| 323 | if(left >= size) | 328 | b->active = 1; |
| 324 | return size; | 329 | } else |
| 325 | /* This is the slow path - looking for new buffers to use */ | 330 | left = 0; |
| 326 | n = tty_buffer_find(tty, size); | 331 | |
| 327 | if(n == NULL) | 332 | if (left < size) { |
| 328 | return left; | 333 | /* This is the slow path - looking for new buffers to use */ |
| 329 | if(b != NULL) | 334 | if ((n = tty_buffer_find(tty, size)) != NULL) { |
| 330 | b->next = n; | 335 | if (b != NULL) { |
| 331 | else | 336 | b->next = n; |
| 332 | tty->buf.head = n; | 337 | b->active = 0; |
| 333 | tty->buf.tail = n; | 338 | } else |
| 339 | tty->buf.head = n; | ||
| 340 | tty->buf.tail = n; | ||
| 341 | n->active = 1; | ||
| 342 | } else | ||
| 343 | size = left; | ||
| 344 | } | ||
| 345 | |||
| 346 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
| 334 | return size; | 347 | return size; |
| 335 | } | 348 | } |
| 336 | 349 | ||
| @@ -396,10 +409,12 @@ EXPORT_SYMBOL_GPL(tty_insert_flip_string_flags); | |||
| 396 | int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_t size) | 409 | int tty_prepare_flip_string(struct tty_struct *tty, unsigned char **chars, size_t size) |
| 397 | { | 410 | { |
| 398 | int space = tty_buffer_request_room(tty, size); | 411 | int space = tty_buffer_request_room(tty, size); |
| 399 | struct tty_buffer *tb = tty->buf.tail; | 412 | if (likely(space)) { |
| 400 | *chars = tb->char_buf_ptr + tb->used; | 413 | struct tty_buffer *tb = tty->buf.tail; |
| 401 | memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); | 414 | *chars = tb->char_buf_ptr + tb->used; |
| 402 | tb->used += space; | 415 | memset(tb->flag_buf_ptr + tb->used, TTY_NORMAL, space); |
| 416 | tb->used += space; | ||
| 417 | } | ||
| 403 | return space; | 418 | return space; |
| 404 | } | 419 | } |
| 405 | 420 | ||
| @@ -416,10 +431,12 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string); | |||
| 416 | int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size) | 431 | int tty_prepare_flip_string_flags(struct tty_struct *tty, unsigned char **chars, char **flags, size_t size) |
| 417 | { | 432 | { |
| 418 | int space = tty_buffer_request_room(tty, size); | 433 | int space = tty_buffer_request_room(tty, size); |
| 419 | struct tty_buffer *tb = tty->buf.tail; | 434 | if (likely(space)) { |
| 420 | *chars = tb->char_buf_ptr + tb->used; | 435 | struct tty_buffer *tb = tty->buf.tail; |
| 421 | *flags = tb->flag_buf_ptr + tb->used; | 436 | *chars = tb->char_buf_ptr + tb->used; |
| 422 | tb->used += space; | 437 | *flags = tb->flag_buf_ptr + tb->used; |
| 438 | tb->used += space; | ||
| 439 | } | ||
| 423 | return space; | 440 | return space; |
| 424 | } | 441 | } |
| 425 | 442 | ||
| @@ -2747,20 +2764,20 @@ static void flush_to_ldisc(void *private_) | |||
| 2747 | schedule_delayed_work(&tty->buf.work, 1); | 2764 | schedule_delayed_work(&tty->buf.work, 1); |
| 2748 | goto out; | 2765 | goto out; |
| 2749 | } | 2766 | } |
| 2750 | spin_lock_irqsave(&tty->read_lock, flags); | 2767 | spin_lock_irqsave(&tty->buf.lock, flags); |
| 2751 | while((tbuf = tty->buf.head) != NULL) { | 2768 | while((tbuf = tty->buf.head) != NULL && !tbuf->active) { |
| 2752 | tty->buf.head = tbuf->next; | 2769 | tty->buf.head = tbuf->next; |
| 2753 | if (tty->buf.head == NULL) | 2770 | if (tty->buf.head == NULL) |
| 2754 | tty->buf.tail = NULL; | 2771 | tty->buf.tail = NULL; |
| 2755 | spin_unlock_irqrestore(&tty->read_lock, flags); | 2772 | spin_unlock_irqrestore(&tty->buf.lock, flags); |
| 2756 | /* printk("Process buffer %p for %d\n", tbuf, tbuf->used); */ | 2773 | /* printk("Process buffer %p for %d\n", tbuf, tbuf->used); */ |
| 2757 | disc->receive_buf(tty, tbuf->char_buf_ptr, | 2774 | disc->receive_buf(tty, tbuf->char_buf_ptr, |
| 2758 | tbuf->flag_buf_ptr, | 2775 | tbuf->flag_buf_ptr, |
| 2759 | tbuf->used); | 2776 | tbuf->used); |
| 2760 | spin_lock_irqsave(&tty->read_lock, flags); | 2777 | spin_lock_irqsave(&tty->buf.lock, flags); |
| 2761 | tty_buffer_free(tty, tbuf); | 2778 | tty_buffer_free(tty, tbuf); |
| 2762 | } | 2779 | } |
| 2763 | spin_unlock_irqrestore(&tty->read_lock, flags); | 2780 | spin_unlock_irqrestore(&tty->buf.lock, flags); |
| 2764 | out: | 2781 | out: |
| 2765 | tty_ldisc_deref(disc); | 2782 | tty_ldisc_deref(disc); |
| 2766 | } | 2783 | } |
| @@ -2852,6 +2869,12 @@ EXPORT_SYMBOL(tty_get_baud_rate); | |||
| 2852 | 2869 | ||
| 2853 | void tty_flip_buffer_push(struct tty_struct *tty) | 2870 | void tty_flip_buffer_push(struct tty_struct *tty) |
| 2854 | { | 2871 | { |
| 2872 | unsigned long flags; | ||
| 2873 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
| 2874 | if (tty->buf.tail != NULL) | ||
| 2875 | tty->buf.tail->active = 0; | ||
| 2876 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
| 2877 | |||
| 2855 | if (tty->low_latency) | 2878 | if (tty->low_latency) |
| 2856 | flush_to_ldisc((void *) tty); | 2879 | flush_to_ldisc((void *) tty); |
| 2857 | else | 2880 | else |
diff --git a/drivers/char/watchdog/sbc_epx_c3.c b/drivers/char/watchdog/sbc_epx_c3.c index 951764614ebf..837b1ec3ffe3 100644 --- a/drivers/char/watchdog/sbc_epx_c3.c +++ b/drivers/char/watchdog/sbc_epx_c3.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/notifier.h> | 25 | #include <linux/notifier.h> |
| 26 | #include <linux/reboot.h> | 26 | #include <linux/reboot.h> |
| 27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
| 28 | #include <linux/ioport.h> | ||
| 28 | #include <asm/uaccess.h> | 29 | #include <asm/uaccess.h> |
| 29 | #include <asm/io.h> | 30 | #include <asm/io.h> |
| 30 | 31 | ||
| @@ -91,7 +92,7 @@ static int epx_c3_release(struct inode *inode, struct file *file) | |||
| 91 | return 0; | 92 | return 0; |
| 92 | } | 93 | } |
| 93 | 94 | ||
| 94 | static ssize_t epx_c3_write(struct file *file, const char *data, | 95 | static ssize_t epx_c3_write(struct file *file, const char __user *data, |
| 95 | size_t len, loff_t *ppos) | 96 | size_t len, loff_t *ppos) |
| 96 | { | 97 | { |
| 97 | /* Refresh the timer. */ | 98 | /* Refresh the timer. */ |
| @@ -104,6 +105,7 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file, | |||
| 104 | unsigned int cmd, unsigned long arg) | 105 | unsigned int cmd, unsigned long arg) |
| 105 | { | 106 | { |
| 106 | int options, retval = -EINVAL; | 107 | int options, retval = -EINVAL; |
| 108 | int __user *argp = (void __user *)arg; | ||
| 107 | static struct watchdog_info ident = { | 109 | static struct watchdog_info ident = { |
| 108 | .options = WDIOF_KEEPALIVEPING | | 110 | .options = WDIOF_KEEPALIVEPING | |
| 109 | WDIOF_MAGICCLOSE, | 111 | WDIOF_MAGICCLOSE, |
| @@ -113,20 +115,19 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file, | |||
| 113 | 115 | ||
| 114 | switch (cmd) { | 116 | switch (cmd) { |
| 115 | case WDIOC_GETSUPPORT: | 117 | case WDIOC_GETSUPPORT: |
| 116 | if (copy_to_user((struct watchdog_info *)arg, | 118 | if (copy_to_user(argp, &ident, sizeof(ident))) |
| 117 | &ident, sizeof(ident))) | ||
| 118 | return -EFAULT; | 119 | return -EFAULT; |
| 119 | return 0; | 120 | return 0; |
| 120 | case WDIOC_GETSTATUS: | 121 | case WDIOC_GETSTATUS: |
| 121 | case WDIOC_GETBOOTSTATUS: | 122 | case WDIOC_GETBOOTSTATUS: |
| 122 | return put_user(0,(int *)arg); | 123 | return put_user(0, argp); |
| 123 | case WDIOC_KEEPALIVE: | 124 | case WDIOC_KEEPALIVE: |
| 124 | epx_c3_pet(); | 125 | epx_c3_pet(); |
| 125 | return 0; | 126 | return 0; |
| 126 | case WDIOC_GETTIMEOUT: | 127 | case WDIOC_GETTIMEOUT: |
| 127 | return put_user(WATCHDOG_TIMEOUT,(int *)arg); | 128 | return put_user(WATCHDOG_TIMEOUT, argp); |
| 128 | case WDIOC_SETOPTIONS: { | 129 | case WDIOC_SETOPTIONS: |
| 129 | if (get_user(options, (int *)arg)) | 130 | if (get_user(options, argp)) |
| 130 | return -EFAULT; | 131 | return -EFAULT; |
| 131 | 132 | ||
| 132 | if (options & WDIOS_DISABLECARD) { | 133 | if (options & WDIOS_DISABLECARD) { |
| @@ -140,7 +141,6 @@ static int epx_c3_ioctl(struct inode *inode, struct file *file, | |||
| 140 | } | 141 | } |
| 141 | 142 | ||
| 142 | return retval; | 143 | return retval; |
| 143 | } | ||
| 144 | default: | 144 | default: |
| 145 | return -ENOIOCTLCMD; | 145 | return -ENOIOCTLCMD; |
| 146 | } | 146 | } |
| @@ -181,11 +181,14 @@ static int __init watchdog_init(void) | |||
| 181 | { | 181 | { |
| 182 | int ret; | 182 | int ret; |
| 183 | 183 | ||
| 184 | if (!request_region(EPXC3_WATCHDOG_CTL_REG, 2, "epxc3_watchdog")) | ||
| 185 | return -EBUSY; | ||
| 186 | |||
| 184 | ret = register_reboot_notifier(&epx_c3_notifier); | 187 | ret = register_reboot_notifier(&epx_c3_notifier); |
| 185 | if (ret) { | 188 | if (ret) { |
| 186 | printk(KERN_ERR PFX "cannot register reboot notifier " | 189 | printk(KERN_ERR PFX "cannot register reboot notifier " |
| 187 | "(err=%d)\n", ret); | 190 | "(err=%d)\n", ret); |
| 188 | return ret; | 191 | goto out; |
| 189 | } | 192 | } |
| 190 | 193 | ||
| 191 | ret = misc_register(&epx_c3_miscdev); | 194 | ret = misc_register(&epx_c3_miscdev); |
| @@ -193,18 +196,23 @@ static int __init watchdog_init(void) | |||
| 193 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d " | 196 | printk(KERN_ERR PFX "cannot register miscdev on minor=%d " |
| 194 | "(err=%d)\n", WATCHDOG_MINOR, ret); | 197 | "(err=%d)\n", WATCHDOG_MINOR, ret); |
| 195 | unregister_reboot_notifier(&epx_c3_notifier); | 198 | unregister_reboot_notifier(&epx_c3_notifier); |
| 196 | return ret; | 199 | goto out; |
| 197 | } | 200 | } |
| 198 | 201 | ||
| 199 | printk(banner); | 202 | printk(banner); |
| 200 | 203 | ||
| 201 | return 0; | 204 | return 0; |
| 205 | |||
| 206 | out: | ||
| 207 | release_region(EPXC3_WATCHDOG_CTL_REG, 2); | ||
| 208 | return ret; | ||
| 202 | } | 209 | } |
| 203 | 210 | ||
| 204 | static void __exit watchdog_exit(void) | 211 | static void __exit watchdog_exit(void) |
| 205 | { | 212 | { |
| 206 | misc_deregister(&epx_c3_miscdev); | 213 | misc_deregister(&epx_c3_miscdev); |
| 207 | unregister_reboot_notifier(&epx_c3_notifier); | 214 | unregister_reboot_notifier(&epx_c3_notifier); |
| 215 | release_region(EPXC3_WATCHDOG_CTL_REG, 2); | ||
| 208 | } | 216 | } |
| 209 | 217 | ||
| 210 | module_init(watchdog_init); | 218 | module_init(watchdog_init); |
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index 4819e7fc00dd..18a455651121 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig | |||
| @@ -11,7 +11,6 @@ menu 'EDAC - error detection and reporting (RAS)' | |||
| 11 | config EDAC | 11 | config EDAC |
| 12 | tristate "EDAC core system error reporting" | 12 | tristate "EDAC core system error reporting" |
| 13 | depends on X86 | 13 | depends on X86 |
| 14 | default y | ||
| 15 | help | 14 | help |
| 16 | EDAC is designed to report errors in the core system. | 15 | EDAC is designed to report errors in the core system. |
| 17 | These are low-level errors that are reported in the CPU or | 16 | These are low-level errors that are reported in the CPU or |
| @@ -46,7 +45,7 @@ config EDAC_MM_EDAC | |||
| 46 | 45 | ||
| 47 | config EDAC_AMD76X | 46 | config EDAC_AMD76X |
| 48 | tristate "AMD 76x (760, 762, 768)" | 47 | tristate "AMD 76x (760, 762, 768)" |
| 49 | depends on EDAC_MM_EDAC && PCI | 48 | depends on EDAC_MM_EDAC && PCI && X86_32 |
| 50 | help | 49 | help |
| 51 | Support for error detection and correction on the AMD 76x | 50 | Support for error detection and correction on the AMD 76x |
| 52 | series of chipsets used with the Athlon processor. | 51 | series of chipsets used with the Athlon processor. |
diff --git a/drivers/edac/e752x_edac.c b/drivers/edac/e752x_edac.c index 770a5a633079..c454ded2b060 100644 --- a/drivers/edac/e752x_edac.c +++ b/drivers/edac/e752x_edac.c | |||
| @@ -1039,10 +1039,10 @@ MODULE_DEVICE_TABLE(pci, e752x_pci_tbl); | |||
| 1039 | 1039 | ||
| 1040 | 1040 | ||
| 1041 | static struct pci_driver e752x_driver = { | 1041 | static struct pci_driver e752x_driver = { |
| 1042 | name: BS_MOD_STR, | 1042 | .name = BS_MOD_STR, |
| 1043 | probe: e752x_init_one, | 1043 | .probe = e752x_init_one, |
| 1044 | remove: __devexit_p(e752x_remove_one), | 1044 | .remove = __devexit_p(e752x_remove_one), |
| 1045 | id_table: e752x_pci_tbl, | 1045 | .id_table = e752x_pci_tbl, |
| 1046 | }; | 1046 | }; |
| 1047 | 1047 | ||
| 1048 | 1048 | ||
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 4be9bd0a1267..b10ee4698b1d 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | #include <linux/config.h> | 16 | #include <linux/config.h> |
| 17 | #include <linux/version.h> | ||
| 18 | #include <linux/module.h> | 17 | #include <linux/module.h> |
| 19 | #include <linux/proc_fs.h> | 18 | #include <linux/proc_fs.h> |
| 20 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
diff --git a/drivers/edac/i82875p_edac.c b/drivers/edac/i82875p_edac.c index 009c08fe5d69..1991f94af753 100644 --- a/drivers/edac/i82875p_edac.c +++ b/drivers/edac/i82875p_edac.c | |||
| @@ -159,7 +159,7 @@ enum i82875p_chips { | |||
| 159 | 159 | ||
| 160 | struct i82875p_pvt { | 160 | struct i82875p_pvt { |
| 161 | struct pci_dev *ovrfl_pdev; | 161 | struct pci_dev *ovrfl_pdev; |
| 162 | void *ovrfl_window; | 162 | void __iomem *ovrfl_window; |
| 163 | }; | 163 | }; |
| 164 | 164 | ||
| 165 | 165 | ||
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index c58295914365..7230d4e08196 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
| @@ -113,6 +113,16 @@ config SENSORS_DS1621 | |||
| 113 | This driver can also be built as a module. If so, the module | 113 | This driver can also be built as a module. If so, the module |
| 114 | will be called ds1621. | 114 | will be called ds1621. |
| 115 | 115 | ||
| 116 | config SENSORS_F71805F | ||
| 117 | tristate "Fintek F71805F/FG" | ||
| 118 | depends on HWMON && EXPERIMENTAL | ||
| 119 | help | ||
| 120 | If you say yes here you get support for hardware monitoring | ||
| 121 | features of the Fintek F71805F/FG chips. | ||
| 122 | |||
| 123 | This driver can also be built as a module. If so, the module | ||
| 124 | will be called f71805f. | ||
| 125 | |||
| 116 | config SENSORS_FSCHER | 126 | config SENSORS_FSCHER |
| 117 | tristate "FSC Hermes" | 127 | tristate "FSC Hermes" |
| 118 | depends on HWMON && I2C && EXPERIMENTAL | 128 | depends on HWMON && I2C && EXPERIMENTAL |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 06d4a1d14105..fbdb8d911a72 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
| @@ -18,6 +18,7 @@ obj-$(CONFIG_SENSORS_ADM1031) += adm1031.o | |||
| 18 | obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o | 18 | obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o |
| 19 | obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o | 19 | obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o |
| 20 | obj-$(CONFIG_SENSORS_DS1621) += ds1621.o | 20 | obj-$(CONFIG_SENSORS_DS1621) += ds1621.o |
| 21 | obj-$(CONFIG_SENSORS_F71805F) += f71805f.o | ||
| 21 | obj-$(CONFIG_SENSORS_FSCHER) += fscher.o | 22 | obj-$(CONFIG_SENSORS_FSCHER) += fscher.o |
| 22 | obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o | 23 | obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o |
| 23 | obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o | 24 | obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o |
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c new file mode 100644 index 000000000000..e029e0a94ecc --- /dev/null +++ b/drivers/hwmon/f71805f.c | |||
| @@ -0,0 +1,908 @@ | |||
| 1 | /* | ||
| 2 | * f71805f.c - driver for the Fintek F71805F/FG Super-I/O chip integrated | ||
| 3 | * hardware monitoring features | ||
| 4 | * Copyright (C) 2005 Jean Delvare <khali@linux-fr.org> | ||
| 5 | * | ||
| 6 | * The F71805F/FG is a LPC Super-I/O chip made by Fintek. It integrates | ||
| 7 | * complete hardware monitoring features: voltage, fan and temperature | ||
| 8 | * sensors, and manual and automatic fan speed control. | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include <linux/module.h> | ||
| 26 | #include <linux/init.h> | ||
| 27 | #include <linux/slab.h> | ||
| 28 | #include <linux/jiffies.h> | ||
| 29 | #include <linux/platform_device.h> | ||
| 30 | #include <linux/hwmon.h> | ||
| 31 | #include <linux/hwmon-sysfs.h> | ||
| 32 | #include <linux/err.h> | ||
| 33 | #include <asm/io.h> | ||
| 34 | |||
| 35 | static struct platform_device *pdev; | ||
| 36 | |||
| 37 | #define DRVNAME "f71805f" | ||
| 38 | |||
| 39 | /* | ||
| 40 | * Super-I/O constants and functions | ||
| 41 | */ | ||
| 42 | |||
| 43 | #define F71805F_LD_HWM 0x04 | ||
| 44 | |||
| 45 | #define SIO_REG_LDSEL 0x07 /* Logical device select */ | ||
| 46 | #define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ | ||
| 47 | #define SIO_REG_DEVREV 0x22 /* Device revision */ | ||
| 48 | #define SIO_REG_MANID 0x23 /* Fintek ID (2 bytes) */ | ||
| 49 | #define SIO_REG_ENABLE 0x30 /* Logical device enable */ | ||
| 50 | #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ | ||
| 51 | |||
| 52 | #define SIO_FINTEK_ID 0x1934 | ||
| 53 | #define SIO_F71805F_ID 0x0406 | ||
| 54 | |||
| 55 | static inline int | ||
| 56 | superio_inb(int base, int reg) | ||
| 57 | { | ||
| 58 | outb(reg, base); | ||
| 59 | return inb(base + 1); | ||
| 60 | } | ||
| 61 | |||
| 62 | static int | ||
| 63 | superio_inw(int base, int reg) | ||
| 64 | { | ||
| 65 | int val; | ||
| 66 | outb(reg++, base); | ||
| 67 | val = inb(base + 1) << 8; | ||
| 68 | outb(reg, base); | ||
| 69 | val |= inb(base + 1); | ||
| 70 | return val; | ||
| 71 | } | ||
| 72 | |||
| 73 | static inline void | ||
| 74 | superio_select(int base, int ld) | ||
| 75 | { | ||
| 76 | outb(SIO_REG_LDSEL, base); | ||
| 77 | outb(ld, base + 1); | ||
| 78 | } | ||
| 79 | |||
| 80 | static inline void | ||
| 81 | superio_enter(int base) | ||
| 82 | { | ||
| 83 | outb(0x87, base); | ||
| 84 | outb(0x87, base); | ||
| 85 | } | ||
| 86 | |||
| 87 | static inline void | ||
| 88 | superio_exit(int base) | ||
| 89 | { | ||
| 90 | outb(0xaa, base); | ||
| 91 | } | ||
| 92 | |||
| 93 | /* | ||
| 94 | * ISA constants | ||
| 95 | */ | ||
| 96 | |||
| 97 | #define REGION_LENGTH 2 | ||
| 98 | #define ADDR_REG_OFFSET 0 | ||
| 99 | #define DATA_REG_OFFSET 1 | ||
| 100 | |||
| 101 | static struct resource f71805f_resource __initdata = { | ||
| 102 | .flags = IORESOURCE_IO, | ||
| 103 | }; | ||
| 104 | |||
| 105 | /* | ||
| 106 | * Registers | ||
| 107 | */ | ||
| 108 | |||
| 109 | /* in nr from 0 to 8 (8-bit values) */ | ||
| 110 | #define F71805F_REG_IN(nr) (0x10 + (nr)) | ||
| 111 | #define F71805F_REG_IN_HIGH(nr) (0x40 + 2 * (nr)) | ||
| 112 | #define F71805F_REG_IN_LOW(nr) (0x41 + 2 * (nr)) | ||
| 113 | /* fan nr from 0 to 2 (12-bit values, two registers) */ | ||
| 114 | #define F71805F_REG_FAN(nr) (0x20 + 2 * (nr)) | ||
| 115 | #define F71805F_REG_FAN_LOW(nr) (0x28 + 2 * (nr)) | ||
| 116 | #define F71805F_REG_FAN_CTRL(nr) (0x60 + 16 * (nr)) | ||
| 117 | /* temp nr from 0 to 2 (8-bit values) */ | ||
| 118 | #define F71805F_REG_TEMP(nr) (0x1B + (nr)) | ||
| 119 | #define F71805F_REG_TEMP_HIGH(nr) (0x54 + 2 * (nr)) | ||
| 120 | #define F71805F_REG_TEMP_HYST(nr) (0x55 + 2 * (nr)) | ||
| 121 | #define F71805F_REG_TEMP_MODE 0x01 | ||
| 122 | |||
| 123 | #define F71805F_REG_START 0x00 | ||
| 124 | /* status nr from 0 to 2 */ | ||
| 125 | #define F71805F_REG_STATUS(nr) (0x36 + (nr)) | ||
| 126 | |||
| 127 | /* | ||
| 128 | * Data structures and manipulation thereof | ||
| 129 | */ | ||
| 130 | |||
| 131 | struct f71805f_data { | ||
| 132 | unsigned short addr; | ||
| 133 | const char *name; | ||
| 134 | struct semaphore lock; | ||
| 135 | struct class_device *class_dev; | ||
| 136 | |||
| 137 | struct semaphore update_lock; | ||
| 138 | char valid; /* !=0 if following fields are valid */ | ||
| 139 | unsigned long last_updated; /* In jiffies */ | ||
| 140 | unsigned long last_limits; /* In jiffies */ | ||
| 141 | |||
| 142 | /* Register values */ | ||
| 143 | u8 in[9]; | ||
| 144 | u8 in_high[9]; | ||
| 145 | u8 in_low[9]; | ||
| 146 | u16 fan[3]; | ||
| 147 | u16 fan_low[3]; | ||
| 148 | u8 fan_enabled; /* Read once at init time */ | ||
| 149 | u8 temp[3]; | ||
| 150 | u8 temp_high[3]; | ||
| 151 | u8 temp_hyst[3]; | ||
| 152 | u8 temp_mode; | ||
| 153 | u8 alarms[3]; | ||
| 154 | }; | ||
| 155 | |||
| 156 | static inline long in_from_reg(u8 reg) | ||
| 157 | { | ||
| 158 | return (reg * 8); | ||
| 159 | } | ||
| 160 | |||
| 161 | /* The 2 least significant bits are not used */ | ||
| 162 | static inline u8 in_to_reg(long val) | ||
| 163 | { | ||
| 164 | if (val <= 0) | ||
| 165 | return 0; | ||
| 166 | if (val >= 2016) | ||
| 167 | return 0xfc; | ||
| 168 | return (((val + 16) / 32) << 2); | ||
| 169 | } | ||
| 170 | |||
| 171 | /* in0 is downscaled by a factor 2 internally */ | ||
| 172 | static inline long in0_from_reg(u8 reg) | ||
| 173 | { | ||
| 174 | return (reg * 16); | ||
| 175 | } | ||
| 176 | |||
| 177 | static inline u8 in0_to_reg(long val) | ||
| 178 | { | ||
| 179 | if (val <= 0) | ||
| 180 | return 0; | ||
| 181 | if (val >= 4032) | ||
| 182 | return 0xfc; | ||
| 183 | return (((val + 32) / 64) << 2); | ||
| 184 | } | ||
| 185 | |||
| 186 | /* The 4 most significant bits are not used */ | ||
| 187 | static inline long fan_from_reg(u16 reg) | ||
| 188 | { | ||
| 189 | reg &= 0xfff; | ||
| 190 | if (!reg || reg == 0xfff) | ||
| 191 | return 0; | ||
| 192 | return (1500000 / reg); | ||
| 193 | } | ||
| 194 | |||
| 195 | static inline u16 fan_to_reg(long rpm) | ||
| 196 | { | ||
| 197 | /* If the low limit is set below what the chip can measure, | ||
| 198 | store the largest possible 12-bit value in the registers, | ||
| 199 | so that no alarm will ever trigger. */ | ||
| 200 | if (rpm < 367) | ||
| 201 | return 0xfff; | ||
| 202 | return (1500000 / rpm); | ||
| 203 | } | ||
| 204 | |||
| 205 | static inline long temp_from_reg(u8 reg) | ||
| 206 | { | ||
| 207 | return (reg * 1000); | ||
| 208 | } | ||
| 209 | |||
| 210 | static inline u8 temp_to_reg(long val) | ||
| 211 | { | ||
| 212 | if (val < 0) | ||
| 213 | val = 0; | ||
| 214 | else if (val > 1000 * 0xff) | ||
| 215 | val = 0xff; | ||
| 216 | return ((val + 500) / 1000); | ||
| 217 | } | ||
| 218 | |||
| 219 | /* | ||
| 220 | * Device I/O access | ||
| 221 | */ | ||
| 222 | |||
| 223 | static u8 f71805f_read8(struct f71805f_data *data, u8 reg) | ||
| 224 | { | ||
| 225 | u8 val; | ||
| 226 | |||
| 227 | down(&data->lock); | ||
| 228 | outb(reg, data->addr + ADDR_REG_OFFSET); | ||
| 229 | val = inb(data->addr + DATA_REG_OFFSET); | ||
| 230 | up(&data->lock); | ||
| 231 | |||
| 232 | return val; | ||
| 233 | } | ||
| 234 | |||
| 235 | static void f71805f_write8(struct f71805f_data *data, u8 reg, u8 val) | ||
| 236 | { | ||
| 237 | down(&data->lock); | ||
| 238 | outb(reg, data->addr + ADDR_REG_OFFSET); | ||
| 239 | outb(val, data->addr + DATA_REG_OFFSET); | ||
| 240 | up(&data->lock); | ||
| 241 | } | ||
| 242 | |||
| 243 | /* It is important to read the MSB first, because doing so latches the | ||
| 244 | value of the LSB, so we are sure both bytes belong to the same value. */ | ||
| 245 | static u16 f71805f_read16(struct f71805f_data *data, u8 reg) | ||
| 246 | { | ||
| 247 | u16 val; | ||
| 248 | |||
| 249 | down(&data->lock); | ||
| 250 | outb(reg, data->addr + ADDR_REG_OFFSET); | ||
| 251 | val = inb(data->addr + DATA_REG_OFFSET) << 8; | ||
| 252 | outb(++reg, data->addr + ADDR_REG_OFFSET); | ||
| 253 | val |= inb(data->addr + DATA_REG_OFFSET); | ||
| 254 | up(&data->lock); | ||
| 255 | |||
| 256 | return val; | ||
| 257 | } | ||
| 258 | |||
| 259 | static void f71805f_write16(struct f71805f_data *data, u8 reg, u16 val) | ||
| 260 | { | ||
| 261 | down(&data->lock); | ||
| 262 | outb(reg, data->addr + ADDR_REG_OFFSET); | ||
| 263 | outb(val >> 8, data->addr + DATA_REG_OFFSET); | ||
| 264 | outb(++reg, data->addr + ADDR_REG_OFFSET); | ||
| 265 | outb(val & 0xff, data->addr + DATA_REG_OFFSET); | ||
| 266 | up(&data->lock); | ||
| 267 | } | ||
| 268 | |||
| 269 | static struct f71805f_data *f71805f_update_device(struct device *dev) | ||
| 270 | { | ||
| 271 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
| 272 | int nr; | ||
| 273 | |||
| 274 | down(&data->update_lock); | ||
| 275 | |||
| 276 | /* Limit registers cache is refreshed after 60 seconds */ | ||
| 277 | if (time_after(jiffies, data->last_updated + 60 * HZ) | ||
| 278 | || !data->valid) { | ||
| 279 | for (nr = 0; nr < 9; nr++) { | ||
| 280 | data->in_high[nr] = f71805f_read8(data, | ||
| 281 | F71805F_REG_IN_HIGH(nr)); | ||
| 282 | data->in_low[nr] = f71805f_read8(data, | ||
| 283 | F71805F_REG_IN_LOW(nr)); | ||
| 284 | } | ||
| 285 | for (nr = 0; nr < 3; nr++) { | ||
| 286 | if (data->fan_enabled & (1 << nr)) | ||
| 287 | data->fan_low[nr] = f71805f_read16(data, | ||
| 288 | F71805F_REG_FAN_LOW(nr)); | ||
| 289 | } | ||
| 290 | for (nr = 0; nr < 3; nr++) { | ||
| 291 | data->temp_high[nr] = f71805f_read8(data, | ||
| 292 | F71805F_REG_TEMP_HIGH(nr)); | ||
| 293 | data->temp_hyst[nr] = f71805f_read8(data, | ||
| 294 | F71805F_REG_TEMP_HYST(nr)); | ||
| 295 | } | ||
| 296 | data->temp_mode = f71805f_read8(data, F71805F_REG_TEMP_MODE); | ||
| 297 | |||
| 298 | data->last_limits = jiffies; | ||
| 299 | } | ||
| 300 | |||
| 301 | /* Measurement registers cache is refreshed after 1 second */ | ||
| 302 | if (time_after(jiffies, data->last_updated + HZ) | ||
| 303 | || !data->valid) { | ||
| 304 | for (nr = 0; nr < 9; nr++) { | ||
| 305 | data->in[nr] = f71805f_read8(data, | ||
| 306 | F71805F_REG_IN(nr)); | ||
| 307 | } | ||
| 308 | for (nr = 0; nr < 3; nr++) { | ||
| 309 | if (data->fan_enabled & (1 << nr)) | ||
| 310 | data->fan[nr] = f71805f_read16(data, | ||
| 311 | F71805F_REG_FAN(nr)); | ||
| 312 | } | ||
| 313 | for (nr = 0; nr < 3; nr++) { | ||
| 314 | data->temp[nr] = f71805f_read8(data, | ||
| 315 | F71805F_REG_TEMP(nr)); | ||
| 316 | } | ||
| 317 | for (nr = 0; nr < 3; nr++) { | ||
| 318 | data->alarms[nr] = f71805f_read8(data, | ||
| 319 | F71805F_REG_STATUS(nr)); | ||
| 320 | } | ||
| 321 | |||
| 322 | data->last_updated = jiffies; | ||
| 323 | data->valid = 1; | ||
| 324 | } | ||
| 325 | |||
| 326 | up(&data->update_lock); | ||
| 327 | |||
| 328 | return data; | ||
| 329 | } | ||
| 330 | |||
| 331 | /* | ||
| 332 | * Sysfs interface | ||
| 333 | */ | ||
| 334 | |||
| 335 | static ssize_t show_in0(struct device *dev, struct device_attribute *devattr, | ||
| 336 | char *buf) | ||
| 337 | { | ||
| 338 | struct f71805f_data *data = f71805f_update_device(dev); | ||
| 339 | |||
| 340 | return sprintf(buf, "%ld\n", in0_from_reg(data->in[0])); | ||
| 341 | } | ||
| 342 | |||
| 343 | static ssize_t show_in0_max(struct device *dev, struct device_attribute | ||
| 344 | *devattr, char *buf) | ||
| 345 | { | ||
| 346 | struct f71805f_data *data = f71805f_update_device(dev); | ||
| 347 | |||
| 348 | return sprintf(buf, "%ld\n", in0_from_reg(data->in_high[0])); | ||
| 349 | } | ||
| 350 | |||
| 351 | static ssize_t show_in0_min(struct device *dev, struct device_attribute | ||
| 352 | *devattr, char *buf) | ||
| 353 | { | ||
| 354 | struct f71805f_data *data = f71805f_update_device(dev); | ||
| 355 | |||
| 356 | return sprintf(buf, "%ld\n", in0_from_reg(data->in_low[0])); | ||
| 357 | } | ||
| 358 | |||
| 359 | static ssize_t set_in0_max(struct device *dev, struct device_attribute | ||
| 360 | *devattr, const char *buf, size_t count) | ||
| 361 | { | ||
| 362 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
| 363 | long val = simple_strtol(buf, NULL, 10); | ||
| 364 | |||
| 365 | down(&data->update_lock); | ||
| 366 | data->in_high[0] = in0_to_reg(val); | ||
| 367 | f71805f_write8(data, F71805F_REG_IN_HIGH(0), data->in_high[0]); | ||
| 368 | up(&data->update_lock); | ||
| 369 | |||
| 370 | return count; | ||
| 371 | } | ||
| 372 | |||
| 373 | static ssize_t set_in0_min(struct device *dev, struct device_attribute | ||
| 374 | *devattr, const char *buf, size_t count) | ||
| 375 | { | ||
| 376 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
| 377 | long val = simple_strtol(buf, NULL, 10); | ||
| 378 | |||
| 379 | down(&data->update_lock); | ||
| 380 | data->in_low[0] = in0_to_reg(val); | ||
| 381 | f71805f_write8(data, F71805F_REG_IN_LOW(0), data->in_low[0]); | ||
| 382 | up(&data->update_lock); | ||
| 383 | |||
| 384 | return count; | ||
| 385 | } | ||
| 386 | |||
| 387 | static DEVICE_ATTR(in0_input, S_IRUGO, show_in0, NULL); | ||
| 388 | static DEVICE_ATTR(in0_max, S_IRUGO| S_IWUSR, show_in0_max, set_in0_max); | ||
| 389 | static DEVICE_ATTR(in0_min, S_IRUGO| S_IWUSR, show_in0_min, set_in0_min); | ||
| 390 | |||
| 391 | static ssize_t show_in(struct device *dev, struct device_attribute *devattr, | ||
| 392 | char *buf) | ||
| 393 | { | ||
| 394 | struct f71805f_data *data = f71805f_update_device(dev); | ||
| 395 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 396 | int nr = attr->index; | ||
| 397 | |||
| 398 | return sprintf(buf, "%ld\n", in_from_reg(data->in[nr])); | ||
| 399 | } | ||
| 400 | |||
| 401 | static ssize_t show_in_max(struct device *dev, struct device_attribute | ||
| 402 | *devattr, char *buf) | ||
| 403 | { | ||
| 404 | struct f71805f_data *data = f71805f_update_device(dev); | ||
| 405 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 406 | int nr = attr->index; | ||
| 407 | |||
| 408 | return sprintf(buf, "%ld\n", in_from_reg(data->in_high[nr])); | ||
| 409 | } | ||
| 410 | |||
| 411 | static ssize_t show_in_min(struct device *dev, struct device_attribute | ||
| 412 | *devattr, char *buf) | ||
| 413 | { | ||
| 414 | struct f71805f_data *data = f71805f_update_device(dev); | ||
| 415 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 416 | int nr = attr->index; | ||
| 417 | |||
| 418 | return sprintf(buf, "%ld\n", in_from_reg(data->in_low[nr])); | ||
| 419 | } | ||
| 420 | |||
| 421 | static ssize_t set_in_max(struct device *dev, struct device_attribute | ||
| 422 | *devattr, const char *buf, size_t count) | ||
| 423 | { | ||
| 424 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
| 425 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 426 | int nr = attr->index; | ||
| 427 | long val = simple_strtol(buf, NULL, 10); | ||
| 428 | |||
| 429 | down(&data->update_lock); | ||
| 430 | data->in_high[nr] = in_to_reg(val); | ||
| 431 | f71805f_write8(data, F71805F_REG_IN_HIGH(nr), data->in_high[nr]); | ||
| 432 | up(&data->update_lock); | ||
| 433 | |||
| 434 | return count; | ||
| 435 | } | ||
| 436 | |||
| 437 | static ssize_t set_in_min(struct device *dev, struct device_attribute | ||
| 438 | *devattr, const char *buf, size_t count) | ||
| 439 | { | ||
| 440 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
| 441 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 442 | int nr = attr->index; | ||
| 443 | long val = simple_strtol(buf, NULL, 10); | ||
| 444 | |||
| 445 | down(&data->update_lock); | ||
| 446 | data->in_low[nr] = in_to_reg(val); | ||
| 447 | f71805f_write8(data, F71805F_REG_IN_LOW(nr), data->in_low[nr]); | ||
| 448 | up(&data->update_lock); | ||
| 449 | |||
| 450 | return count; | ||
| 451 | } | ||
| 452 | |||
| 453 | #define sysfs_in(offset) \ | ||
| 454 | static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \ | ||
| 455 | show_in, NULL, offset); \ | ||
| 456 | static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ | ||
| 457 | show_in_max, set_in_max, offset); \ | ||
| 458 | static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ | ||
| 459 | show_in_min, set_in_min, offset) | ||
| 460 | |||
| 461 | sysfs_in(1); | ||
| 462 | sysfs_in(2); | ||
| 463 | sysfs_in(3); | ||
| 464 | sysfs_in(4); | ||
| 465 | sysfs_in(5); | ||
| 466 | sysfs_in(6); | ||
| 467 | sysfs_in(7); | ||
| 468 | sysfs_in(8); | ||
| 469 | |||
| 470 | static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, | ||
| 471 | char *buf) | ||
| 472 | { | ||
| 473 | struct f71805f_data *data = f71805f_update_device(dev); | ||
| 474 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 475 | int nr = attr->index; | ||
| 476 | |||
| 477 | return sprintf(buf, "%ld\n", fan_from_reg(data->fan[nr])); | ||
| 478 | } | ||
| 479 | |||
| 480 | static ssize_t show_fan_min(struct device *dev, struct device_attribute | ||
| 481 | *devattr, char *buf) | ||
| 482 | { | ||
| 483 | struct f71805f_data *data = f71805f_update_device(dev); | ||
| 484 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 485 | int nr = attr->index; | ||
| 486 | |||
| 487 | return sprintf(buf, "%ld\n", fan_from_reg(data->fan_low[nr])); | ||
| 488 | } | ||
| 489 | |||
| 490 | static ssize_t set_fan_min(struct device *dev, struct device_attribute | ||
| 491 | *devattr, const char *buf, size_t count) | ||
| 492 | { | ||
| 493 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
| 494 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 495 | int nr = attr->index; | ||
| 496 | long val = simple_strtol(buf, NULL, 10); | ||
| 497 | |||
| 498 | down(&data->update_lock); | ||
| 499 | data->fan_low[nr] = fan_to_reg(val); | ||
| 500 | f71805f_write16(data, F71805F_REG_FAN_LOW(nr), data->fan_low[nr]); | ||
| 501 | up(&data->update_lock); | ||
| 502 | |||
| 503 | return count; | ||
| 504 | } | ||
| 505 | |||
| 506 | #define sysfs_fan(offset) \ | ||
| 507 | static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \ | ||
| 508 | show_fan, NULL, offset - 1); \ | ||
| 509 | static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ | ||
| 510 | show_fan_min, set_fan_min, offset - 1) | ||
| 511 | |||
| 512 | sysfs_fan(1); | ||
| 513 | sysfs_fan(2); | ||
| 514 | sysfs_fan(3); | ||
| 515 | |||
| 516 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, | ||
| 517 | char *buf) | ||
| 518 | { | ||
| 519 | struct f71805f_data *data = f71805f_update_device(dev); | ||
| 520 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 521 | int nr = attr->index; | ||
| 522 | |||
| 523 | return sprintf(buf, "%ld\n", temp_from_reg(data->temp[nr])); | ||
| 524 | } | ||
| 525 | |||
| 526 | static ssize_t show_temp_max(struct device *dev, struct device_attribute | ||
| 527 | *devattr, char *buf) | ||
| 528 | { | ||
| 529 | struct f71805f_data *data = f71805f_update_device(dev); | ||
| 530 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 531 | int nr = attr->index; | ||
| 532 | |||
| 533 | return sprintf(buf, "%ld\n", temp_from_reg(data->temp_high[nr])); | ||
| 534 | } | ||
| 535 | |||
| 536 | static ssize_t show_temp_hyst(struct device *dev, struct device_attribute | ||
| 537 | *devattr, char *buf) | ||
| 538 | { | ||
| 539 | struct f71805f_data *data = f71805f_update_device(dev); | ||
| 540 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 541 | int nr = attr->index; | ||
| 542 | |||
| 543 | return sprintf(buf, "%ld\n", temp_from_reg(data->temp_hyst[nr])); | ||
| 544 | } | ||
| 545 | |||
| 546 | static ssize_t show_temp_type(struct device *dev, struct device_attribute | ||
| 547 | *devattr, char *buf) | ||
| 548 | { | ||
| 549 | struct f71805f_data *data = f71805f_update_device(dev); | ||
| 550 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 551 | int nr = attr->index; | ||
| 552 | |||
| 553 | /* 3 is diode, 4 is thermistor */ | ||
| 554 | return sprintf(buf, "%u\n", (data->temp_mode & (1 << nr)) ? 3 : 4); | ||
| 555 | } | ||
| 556 | |||
| 557 | static ssize_t set_temp_max(struct device *dev, struct device_attribute | ||
| 558 | *devattr, const char *buf, size_t count) | ||
| 559 | { | ||
| 560 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
| 561 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 562 | int nr = attr->index; | ||
| 563 | long val = simple_strtol(buf, NULL, 10); | ||
| 564 | |||
| 565 | down(&data->update_lock); | ||
| 566 | data->temp_high[nr] = temp_to_reg(val); | ||
| 567 | f71805f_write8(data, F71805F_REG_TEMP_HIGH(nr), data->temp_high[nr]); | ||
| 568 | up(&data->update_lock); | ||
| 569 | |||
| 570 | return count; | ||
| 571 | } | ||
| 572 | |||
| 573 | static ssize_t set_temp_hyst(struct device *dev, struct device_attribute | ||
| 574 | *devattr, const char *buf, size_t count) | ||
| 575 | { | ||
| 576 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
| 577 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
| 578 | int nr = attr->index; | ||
| 579 | long val = simple_strtol(buf, NULL, 10); | ||
| 580 | |||
| 581 | down(&data->update_lock); | ||
| 582 | data->temp_hyst[nr] = temp_to_reg(val); | ||
| 583 | f71805f_write8(data, F71805F_REG_TEMP_HYST(nr), data->temp_hyst[nr]); | ||
| 584 | up(&data->update_lock); | ||
| 585 | |||
| 586 | return count; | ||
| 587 | } | ||
| 588 | |||
| 589 | #define sysfs_temp(offset) \ | ||
| 590 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ | ||
| 591 | show_temp, NULL, offset - 1); \ | ||
| 592 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ | ||
| 593 | show_temp_max, set_temp_max, offset - 1); \ | ||
| 594 | static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \ | ||
| 595 | show_temp_hyst, set_temp_hyst, offset - 1); \ | ||
| 596 | static SENSOR_DEVICE_ATTR(temp##offset##_type, S_IRUGO, \ | ||
| 597 | show_temp_type, NULL, offset - 1) | ||
| 598 | |||
| 599 | sysfs_temp(1); | ||
| 600 | sysfs_temp(2); | ||
| 601 | sysfs_temp(3); | ||
| 602 | |||
| 603 | static ssize_t show_alarms_in(struct device *dev, struct device_attribute | ||
| 604 | *devattr, char *buf) | ||
| 605 | { | ||
| 606 | struct f71805f_data *data = f71805f_update_device(dev); | ||
| 607 | |||
| 608 | return sprintf(buf, "%d\n", data->alarms[0] | | ||
| 609 | ((data->alarms[1] & 0x01) << 8)); | ||
| 610 | } | ||
| 611 | |||
| 612 | static ssize_t show_alarms_fan(struct device *dev, struct device_attribute | ||
| 613 | *devattr, char *buf) | ||
| 614 | { | ||
| 615 | struct f71805f_data *data = f71805f_update_device(dev); | ||
| 616 | |||
| 617 | return sprintf(buf, "%d\n", data->alarms[2] & 0x07); | ||
| 618 | } | ||
| 619 | |||
| 620 | static ssize_t show_alarms_temp(struct device *dev, struct device_attribute | ||
| 621 | *devattr, char *buf) | ||
| 622 | { | ||
| 623 | struct f71805f_data *data = f71805f_update_device(dev); | ||
| 624 | |||
| 625 | return sprintf(buf, "%d\n", (data->alarms[1] >> 3) & 0x07); | ||
| 626 | } | ||
| 627 | |||
| 628 | static DEVICE_ATTR(alarms_in, S_IRUGO, show_alarms_in, NULL); | ||
| 629 | static DEVICE_ATTR(alarms_fan, S_IRUGO, show_alarms_fan, NULL); | ||
| 630 | static DEVICE_ATTR(alarms_temp, S_IRUGO, show_alarms_temp, NULL); | ||
| 631 | |||
| 632 | static ssize_t show_name(struct device *dev, struct device_attribute | ||
| 633 | *devattr, char *buf) | ||
| 634 | { | ||
| 635 | struct f71805f_data *data = dev_get_drvdata(dev); | ||
| 636 | |||
| 637 | return sprintf(buf, "%s\n", data->name); | ||
| 638 | } | ||
| 639 | |||
| 640 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
| 641 | |||
| 642 | /* | ||
| 643 | * Device registration and initialization | ||
| 644 | */ | ||
| 645 | |||
| 646 | static void __devinit f71805f_init_device(struct f71805f_data *data) | ||
| 647 | { | ||
| 648 | u8 reg; | ||
| 649 | int i; | ||
| 650 | |||
| 651 | reg = f71805f_read8(data, F71805F_REG_START); | ||
| 652 | if ((reg & 0x41) != 0x01) { | ||
| 653 | printk(KERN_DEBUG DRVNAME ": Starting monitoring " | ||
| 654 | "operations\n"); | ||
| 655 | f71805f_write8(data, F71805F_REG_START, (reg | 0x01) & ~0x40); | ||
| 656 | } | ||
| 657 | |||
| 658 | /* Fan monitoring can be disabled. If it is, we won't be polling | ||
| 659 | the register values, and won't create the related sysfs files. */ | ||
| 660 | for (i = 0; i < 3; i++) { | ||
| 661 | reg = f71805f_read8(data, F71805F_REG_FAN_CTRL(i)); | ||
| 662 | if (!(reg & 0x80)) | ||
| 663 | data->fan_enabled |= (1 << i); | ||
| 664 | } | ||
| 665 | } | ||
| 666 | |||
| 667 | static int __devinit f71805f_probe(struct platform_device *pdev) | ||
| 668 | { | ||
| 669 | struct f71805f_data *data; | ||
| 670 | struct resource *res; | ||
| 671 | int err; | ||
| 672 | |||
| 673 | if (!(data = kzalloc(sizeof(struct f71805f_data), GFP_KERNEL))) { | ||
| 674 | err = -ENOMEM; | ||
| 675 | printk(KERN_ERR DRVNAME ": Out of memory\n"); | ||
| 676 | goto exit; | ||
| 677 | } | ||
| 678 | |||
| 679 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | ||
| 680 | data->addr = res->start; | ||
| 681 | init_MUTEX(&data->lock); | ||
| 682 | data->name = "f71805f"; | ||
| 683 | init_MUTEX(&data->update_lock); | ||
| 684 | |||
| 685 | platform_set_drvdata(pdev, data); | ||
| 686 | |||
| 687 | data->class_dev = hwmon_device_register(&pdev->dev); | ||
| 688 | if (IS_ERR(data->class_dev)) { | ||
| 689 | err = PTR_ERR(data->class_dev); | ||
| 690 | dev_err(&pdev->dev, "Class registration failed (%d)\n", err); | ||
| 691 | goto exit_free; | ||
| 692 | } | ||
| 693 | |||
| 694 | /* Initialize the F71805F chip */ | ||
| 695 | f71805f_init_device(data); | ||
| 696 | |||
| 697 | /* Register sysfs interface files */ | ||
| 698 | device_create_file(&pdev->dev, &dev_attr_in0_input); | ||
| 699 | device_create_file(&pdev->dev, &dev_attr_in0_max); | ||
| 700 | device_create_file(&pdev->dev, &dev_attr_in0_min); | ||
| 701 | device_create_file(&pdev->dev, &sensor_dev_attr_in1_input.dev_attr); | ||
| 702 | device_create_file(&pdev->dev, &sensor_dev_attr_in2_input.dev_attr); | ||
| 703 | device_create_file(&pdev->dev, &sensor_dev_attr_in3_input.dev_attr); | ||
| 704 | device_create_file(&pdev->dev, &sensor_dev_attr_in4_input.dev_attr); | ||
| 705 | device_create_file(&pdev->dev, &sensor_dev_attr_in5_input.dev_attr); | ||
| 706 | device_create_file(&pdev->dev, &sensor_dev_attr_in6_input.dev_attr); | ||
| 707 | device_create_file(&pdev->dev, &sensor_dev_attr_in7_input.dev_attr); | ||
| 708 | device_create_file(&pdev->dev, &sensor_dev_attr_in8_input.dev_attr); | ||
| 709 | device_create_file(&pdev->dev, &sensor_dev_attr_in1_max.dev_attr); | ||
| 710 | device_create_file(&pdev->dev, &sensor_dev_attr_in2_max.dev_attr); | ||
| 711 | device_create_file(&pdev->dev, &sensor_dev_attr_in3_max.dev_attr); | ||
| 712 | device_create_file(&pdev->dev, &sensor_dev_attr_in4_max.dev_attr); | ||
| 713 | device_create_file(&pdev->dev, &sensor_dev_attr_in5_max.dev_attr); | ||
| 714 | device_create_file(&pdev->dev, &sensor_dev_attr_in6_max.dev_attr); | ||
| 715 | device_create_file(&pdev->dev, &sensor_dev_attr_in7_max.dev_attr); | ||
| 716 | device_create_file(&pdev->dev, &sensor_dev_attr_in8_max.dev_attr); | ||
| 717 | device_create_file(&pdev->dev, &sensor_dev_attr_in1_min.dev_attr); | ||
| 718 | device_create_file(&pdev->dev, &sensor_dev_attr_in2_min.dev_attr); | ||
| 719 | device_create_file(&pdev->dev, &sensor_dev_attr_in3_min.dev_attr); | ||
| 720 | device_create_file(&pdev->dev, &sensor_dev_attr_in4_min.dev_attr); | ||
| 721 | device_create_file(&pdev->dev, &sensor_dev_attr_in5_min.dev_attr); | ||
| 722 | device_create_file(&pdev->dev, &sensor_dev_attr_in6_min.dev_attr); | ||
| 723 | device_create_file(&pdev->dev, &sensor_dev_attr_in7_min.dev_attr); | ||
| 724 | device_create_file(&pdev->dev, &sensor_dev_attr_in8_min.dev_attr); | ||
| 725 | if (data->fan_enabled & (1 << 0)) { | ||
| 726 | device_create_file(&pdev->dev, | ||
| 727 | &sensor_dev_attr_fan1_input.dev_attr); | ||
| 728 | device_create_file(&pdev->dev, | ||
| 729 | &sensor_dev_attr_fan1_min.dev_attr); | ||
| 730 | } | ||
| 731 | if (data->fan_enabled & (1 << 1)) { | ||
| 732 | device_create_file(&pdev->dev, | ||
| 733 | &sensor_dev_attr_fan2_input.dev_attr); | ||
| 734 | device_create_file(&pdev->dev, | ||
| 735 | &sensor_dev_attr_fan2_min.dev_attr); | ||
| 736 | } | ||
| 737 | if (data->fan_enabled & (1 << 2)) { | ||
| 738 | device_create_file(&pdev->dev, | ||
| 739 | &sensor_dev_attr_fan3_input.dev_attr); | ||
| 740 | device_create_file(&pdev->dev, | ||
| 741 | &sensor_dev_attr_fan3_min.dev_attr); | ||
| 742 | } | ||
| 743 | device_create_file(&pdev->dev, | ||
| 744 | &sensor_dev_attr_temp1_input.dev_attr); | ||
| 745 | device_create_file(&pdev->dev, | ||
| 746 | &sensor_dev_attr_temp2_input.dev_attr); | ||
| 747 | device_create_file(&pdev->dev, | ||
| 748 | &sensor_dev_attr_temp3_input.dev_attr); | ||
| 749 | device_create_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr); | ||
| 750 | device_create_file(&pdev->dev, &sensor_dev_attr_temp2_max.dev_attr); | ||
| 751 | device_create_file(&pdev->dev, &sensor_dev_attr_temp3_max.dev_attr); | ||
| 752 | device_create_file(&pdev->dev, | ||
| 753 | &sensor_dev_attr_temp1_max_hyst.dev_attr); | ||
| 754 | device_create_file(&pdev->dev, | ||
| 755 | &sensor_dev_attr_temp2_max_hyst.dev_attr); | ||
| 756 | device_create_file(&pdev->dev, | ||
| 757 | &sensor_dev_attr_temp3_max_hyst.dev_attr); | ||
| 758 | device_create_file(&pdev->dev, &sensor_dev_attr_temp1_type.dev_attr); | ||
| 759 | device_create_file(&pdev->dev, &sensor_dev_attr_temp2_type.dev_attr); | ||
| 760 | device_create_file(&pdev->dev, &sensor_dev_attr_temp3_type.dev_attr); | ||
| 761 | device_create_file(&pdev->dev, &dev_attr_alarms_in); | ||
| 762 | device_create_file(&pdev->dev, &dev_attr_alarms_fan); | ||
| 763 | device_create_file(&pdev->dev, &dev_attr_alarms_temp); | ||
| 764 | device_create_file(&pdev->dev, &dev_attr_name); | ||
| 765 | |||
| 766 | return 0; | ||
| 767 | |||
| 768 | exit_free: | ||
| 769 | kfree(data); | ||
| 770 | exit: | ||
| 771 | return err; | ||
| 772 | } | ||
| 773 | |||
| 774 | static int __devexit f71805f_remove(struct platform_device *pdev) | ||
| 775 | { | ||
| 776 | struct f71805f_data *data = platform_get_drvdata(pdev); | ||
| 777 | |||
| 778 | platform_set_drvdata(pdev, NULL); | ||
| 779 | hwmon_device_unregister(data->class_dev); | ||
| 780 | kfree(data); | ||
| 781 | |||
| 782 | return 0; | ||
| 783 | } | ||
| 784 | |||
| 785 | static struct platform_driver f71805f_driver = { | ||
| 786 | .driver = { | ||
| 787 | .owner = THIS_MODULE, | ||
| 788 | .name = DRVNAME, | ||
| 789 | }, | ||
| 790 | .probe = f71805f_probe, | ||
| 791 | .remove = __devexit_p(f71805f_remove), | ||
| 792 | }; | ||
| 793 | |||
| 794 | static int __init f71805f_device_add(unsigned short address) | ||
| 795 | { | ||
| 796 | int err; | ||
| 797 | |||
| 798 | pdev = platform_device_alloc(DRVNAME, address); | ||
| 799 | if (!pdev) { | ||
| 800 | err = -ENOMEM; | ||
| 801 | printk(KERN_ERR DRVNAME ": Device allocation failed\n"); | ||
| 802 | goto exit; | ||
| 803 | } | ||
| 804 | |||
| 805 | f71805f_resource.start = address; | ||
| 806 | f71805f_resource.end = address + REGION_LENGTH - 1; | ||
| 807 | f71805f_resource.name = pdev->name; | ||
| 808 | err = platform_device_add_resources(pdev, &f71805f_resource, 1); | ||
| 809 | if (err) { | ||
| 810 | printk(KERN_ERR DRVNAME ": Device resource addition failed " | ||
| 811 | "(%d)\n", err); | ||
| 812 | goto exit_device_put; | ||
| 813 | } | ||
| 814 | |||
| 815 | err = platform_device_add(pdev); | ||
| 816 | if (err) { | ||
| 817 | printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n", | ||
| 818 | err); | ||
| 819 | goto exit_device_put; | ||
| 820 | } | ||
| 821 | |||
| 822 | return 0; | ||
| 823 | |||
| 824 | exit_device_put: | ||
| 825 | platform_device_put(pdev); | ||
| 826 | exit: | ||
| 827 | return err; | ||
| 828 | } | ||
| 829 | |||
| 830 | static int __init f71805f_find(int sioaddr, unsigned short *address) | ||
| 831 | { | ||
| 832 | int err = -ENODEV; | ||
| 833 | u16 devid; | ||
| 834 | |||
| 835 | superio_enter(sioaddr); | ||
| 836 | |||
| 837 | devid = superio_inw(sioaddr, SIO_REG_MANID); | ||
| 838 | if (devid != SIO_FINTEK_ID) | ||
| 839 | goto exit; | ||
| 840 | |||
| 841 | devid = superio_inw(sioaddr, SIO_REG_DEVID); | ||
| 842 | if (devid != SIO_F71805F_ID) { | ||
| 843 | printk(KERN_INFO DRVNAME ": Unsupported Fintek device, " | ||
| 844 | "skipping\n"); | ||
| 845 | goto exit; | ||
| 846 | } | ||
| 847 | |||
| 848 | superio_select(sioaddr, F71805F_LD_HWM); | ||
| 849 | if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { | ||
| 850 | printk(KERN_WARNING DRVNAME ": Device not activated, " | ||
| 851 | "skipping\n"); | ||
| 852 | goto exit; | ||
| 853 | } | ||
| 854 | |||
| 855 | *address = superio_inw(sioaddr, SIO_REG_ADDR); | ||
| 856 | if (*address == 0) { | ||
| 857 | printk(KERN_WARNING DRVNAME ": Base address not set, " | ||
| 858 | "skipping\n"); | ||
| 859 | goto exit; | ||
| 860 | } | ||
| 861 | |||
| 862 | err = 0; | ||
| 863 | printk(KERN_INFO DRVNAME ": Found F71805F chip at %#x, revision %u\n", | ||
| 864 | *address, superio_inb(sioaddr, SIO_REG_DEVREV)); | ||
| 865 | |||
| 866 | exit: | ||
| 867 | superio_exit(sioaddr); | ||
| 868 | return err; | ||
| 869 | } | ||
| 870 | |||
| 871 | static int __init f71805f_init(void) | ||
| 872 | { | ||
| 873 | int err; | ||
| 874 | unsigned short address; | ||
| 875 | |||
| 876 | if (f71805f_find(0x2e, &address) | ||
| 877 | && f71805f_find(0x4e, &address)) | ||
| 878 | return -ENODEV; | ||
| 879 | |||
| 880 | err = platform_driver_register(&f71805f_driver); | ||
| 881 | if (err) | ||
| 882 | goto exit; | ||
| 883 | |||
| 884 | /* Sets global pdev as a side effect */ | ||
| 885 | err = f71805f_device_add(address); | ||
| 886 | if (err) | ||
| 887 | goto exit_driver; | ||
| 888 | |||
| 889 | return 0; | ||
| 890 | |||
| 891 | exit_driver: | ||
| 892 | platform_driver_unregister(&f71805f_driver); | ||
| 893 | exit: | ||
| 894 | return err; | ||
| 895 | } | ||
| 896 | |||
| 897 | static void __exit f71805f_exit(void) | ||
| 898 | { | ||
| 899 | platform_device_unregister(pdev); | ||
| 900 | platform_driver_unregister(&f71805f_driver); | ||
| 901 | } | ||
| 902 | |||
| 903 | MODULE_AUTHOR("Jean Delvare <khali@linux-fr>"); | ||
| 904 | MODULE_LICENSE("GPL"); | ||
| 905 | MODULE_DESCRIPTION("F71805F hardware monitoring driver"); | ||
| 906 | |||
| 907 | module_init(f71805f_init); | ||
| 908 | module_exit(f71805f_exit); | ||
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 0da7c9c508c3..e87d52c59940 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
| @@ -45,8 +45,7 @@ | |||
| 45 | 45 | ||
| 46 | 46 | ||
| 47 | /* Addresses to scan */ | 47 | /* Addresses to scan */ |
| 48 | static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, | 48 | static unsigned short normal_i2c[] = { 0x2d, I2C_CLIENT_END }; |
| 49 | 0x2e, 0x2f, I2C_CLIENT_END }; | ||
| 50 | static unsigned short isa_address; | 49 | static unsigned short isa_address; |
| 51 | 50 | ||
| 52 | /* Insmod parameters */ | 51 | /* Insmod parameters */ |
| @@ -830,6 +829,11 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind) | |||
| 830 | if ((err = i2c_attach_client(new_client))) | 829 | if ((err = i2c_attach_client(new_client))) |
| 831 | goto ERROR2; | 830 | goto ERROR2; |
| 832 | 831 | ||
| 832 | if (!is_isa) | ||
| 833 | dev_info(&new_client->dev, "The I2C interface to IT87xxF " | ||
| 834 | "hardware monitoring chips is deprecated. Please " | ||
| 835 | "report if you still rely on it.\n"); | ||
| 836 | |||
| 833 | /* Check PWM configuration */ | 837 | /* Check PWM configuration */ |
| 834 | enable_pwm_interface = it87_check_pwm(new_client); | 838 | enable_pwm_interface = it87_check_pwm(new_client); |
| 835 | 839 | ||
diff --git a/drivers/hwmon/lm77.c b/drivers/hwmon/lm77.c index a2f420d01fb7..df9e02aaa70a 100644 --- a/drivers/hwmon/lm77.c +++ b/drivers/hwmon/lm77.c | |||
| @@ -87,15 +87,15 @@ static struct i2c_driver lm77_driver = { | |||
| 87 | 87 | ||
| 88 | /* In the temperature registers, the low 3 bits are not part of the | 88 | /* In the temperature registers, the low 3 bits are not part of the |
| 89 | temperature values; they are the status bits. */ | 89 | temperature values; they are the status bits. */ |
| 90 | static inline u16 LM77_TEMP_TO_REG(int temp) | 90 | static inline s16 LM77_TEMP_TO_REG(int temp) |
| 91 | { | 91 | { |
| 92 | int ntemp = SENSORS_LIMIT(temp, LM77_TEMP_MIN, LM77_TEMP_MAX); | 92 | int ntemp = SENSORS_LIMIT(temp, LM77_TEMP_MIN, LM77_TEMP_MAX); |
| 93 | return (u16)((ntemp / 500) * 8); | 93 | return (ntemp / 500) * 8; |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | static inline int LM77_TEMP_FROM_REG(u16 reg) | 96 | static inline int LM77_TEMP_FROM_REG(s16 reg) |
| 97 | { | 97 | { |
| 98 | return ((int)reg / 8) * 500; | 98 | return (reg / 8) * 500; |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | /* sysfs stuff */ | 101 | /* sysfs stuff */ |
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c index b176bf0c4c7b..a2f6bb676235 100644 --- a/drivers/hwmon/w83792d.c +++ b/drivers/hwmon/w83792d.c | |||
| @@ -303,10 +303,6 @@ struct w83792d_data { | |||
| 303 | static int w83792d_attach_adapter(struct i2c_adapter *adapter); | 303 | static int w83792d_attach_adapter(struct i2c_adapter *adapter); |
| 304 | static int w83792d_detect(struct i2c_adapter *adapter, int address, int kind); | 304 | static int w83792d_detect(struct i2c_adapter *adapter, int address, int kind); |
| 305 | static int w83792d_detach_client(struct i2c_client *client); | 305 | static int w83792d_detach_client(struct i2c_client *client); |
| 306 | |||
| 307 | static int w83792d_read_value(struct i2c_client *client, u8 register); | ||
| 308 | static int w83792d_write_value(struct i2c_client *client, u8 register, | ||
| 309 | u8 value); | ||
| 310 | static struct w83792d_data *w83792d_update_device(struct device *dev); | 306 | static struct w83792d_data *w83792d_update_device(struct device *dev); |
| 311 | 307 | ||
| 312 | #ifdef DEBUG | 308 | #ifdef DEBUG |
| @@ -329,6 +325,20 @@ static inline long in_count_from_reg(int nr, struct w83792d_data *data) | |||
| 329 | return ((data->in[nr] << 2) | ((data->low_bits >> (2 * nr)) & 0x03)); | 325 | return ((data->in[nr] << 2) | ((data->low_bits >> (2 * nr)) & 0x03)); |
| 330 | } | 326 | } |
| 331 | 327 | ||
| 328 | /* The SMBus locks itself. The Winbond W83792D chip has a bank register, | ||
| 329 | but the driver only accesses registers in bank 0, so we don't have | ||
| 330 | to switch banks and lock access between switches. */ | ||
| 331 | static inline int w83792d_read_value(struct i2c_client *client, u8 reg) | ||
| 332 | { | ||
| 333 | return i2c_smbus_read_byte_data(client, reg); | ||
| 334 | } | ||
| 335 | |||
| 336 | static inline int | ||
| 337 | w83792d_write_value(struct i2c_client *client, u8 reg, u8 value) | ||
| 338 | { | ||
| 339 | return i2c_smbus_write_byte_data(client, reg, value); | ||
| 340 | } | ||
| 341 | |||
| 332 | /* following are the sysfs callback functions */ | 342 | /* following are the sysfs callback functions */ |
| 333 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, | 343 | static ssize_t show_in(struct device *dev, struct device_attribute *attr, |
| 334 | char *buf) | 344 | char *buf) |
| @@ -1386,19 +1396,6 @@ w83792d_detach_client(struct i2c_client *client) | |||
| 1386 | return 0; | 1396 | return 0; |
| 1387 | } | 1397 | } |
| 1388 | 1398 | ||
| 1389 | /* The SMBus locks itself. The Winbond W83792D chip has a bank register, | ||
| 1390 | but the driver only accesses registers in bank 0, so we don't have | ||
| 1391 | to switch banks and lock access between switches. */ | ||
| 1392 | static int w83792d_read_value(struct i2c_client *client, u8 reg) | ||
| 1393 | { | ||
| 1394 | return i2c_smbus_read_byte_data(client, reg); | ||
| 1395 | } | ||
| 1396 | |||
| 1397 | static int w83792d_write_value(struct i2c_client *client, u8 reg, u8 value) | ||
| 1398 | { | ||
| 1399 | return i2c_smbus_write_byte_data(client, reg, value); | ||
| 1400 | } | ||
| 1401 | |||
| 1402 | static void | 1399 | static void |
| 1403 | w83792d_init_client(struct i2c_client *client) | 1400 | w83792d_init_client(struct i2c_client *client) |
| 1404 | { | 1401 | { |
diff --git a/drivers/i2c/algos/i2c-algo-sibyte.c b/drivers/i2c/algos/i2c-algo-sibyte.c index 938848ae162d..3df3f09995c2 100644 --- a/drivers/i2c/algos/i2c-algo-sibyte.c +++ b/drivers/i2c/algos/i2c-algo-sibyte.c | |||
| @@ -202,7 +202,7 @@ EXPORT_SYMBOL(i2c_sibyte_del_bus); | |||
| 202 | #ifdef MODULE | 202 | #ifdef MODULE |
| 203 | MODULE_AUTHOR("Kip Walker, Broadcom Corp."); | 203 | MODULE_AUTHOR("Kip Walker, Broadcom Corp."); |
| 204 | MODULE_DESCRIPTION("SiByte I2C-Bus algorithm"); | 204 | MODULE_DESCRIPTION("SiByte I2C-Bus algorithm"); |
| 205 | MODULE_PARM(bit_scan, "i"); | 205 | module_param(bit_scan, int, 0); |
| 206 | MODULE_PARM_DESC(bit_scan, "Scan for active chips on the bus"); | 206 | MODULE_PARM_DESC(bit_scan, "Scan for active chips on the bus"); |
| 207 | MODULE_LICENSE("GPL"); | 207 | MODULE_LICENSE("GPL"); |
| 208 | 208 | ||
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 08d5b8fed2dc..ff92735c7c85 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
| @@ -124,6 +124,7 @@ config I2C_I801 | |||
| 124 | ICH6 | 124 | ICH6 |
| 125 | ICH7 | 125 | ICH7 |
| 126 | ESB2 | 126 | ESB2 |
| 127 | ICH8 | ||
| 127 | 128 | ||
| 128 | This driver can also be built as a module. If so, the module | 129 | This driver can also be built as a module. If so, the module |
| 129 | will be called i2c-i801. | 130 | will be called i2c-i801. |
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 1c752ddc10e2..8e0f3158215f 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
| @@ -32,6 +32,7 @@ | |||
| 32 | ICH6 266A | 32 | ICH6 266A |
| 33 | ICH7 27DA | 33 | ICH7 27DA |
| 34 | ESB2 269B | 34 | ESB2 269B |
| 35 | ICH8 283E | ||
| 35 | This driver supports several versions of Intel's I/O Controller Hubs (ICH). | 36 | This driver supports several versions of Intel's I/O Controller Hubs (ICH). |
| 36 | For SMBus support, they are similar to the PIIX4 and are part | 37 | For SMBus support, they are similar to the PIIX4 and are part |
| 37 | of Intel's '810' and other chipsets. | 38 | of Intel's '810' and other chipsets. |
| @@ -527,6 +528,7 @@ static struct pci_device_id i801_ids[] = { | |||
| 527 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) }, | 528 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_16) }, |
| 528 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) }, | 529 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_17) }, |
| 529 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) }, | 530 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_17) }, |
| 531 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_5) }, | ||
| 530 | { 0, } | 532 | { 0, } |
| 531 | }; | 533 | }; |
| 532 | 534 | ||
diff --git a/drivers/i2c/busses/i2c-parport-light.c b/drivers/i2c/busses/i2c-parport-light.c index 3e5eba9fcacb..c63025a4c861 100644 --- a/drivers/i2c/busses/i2c-parport-light.c +++ b/drivers/i2c/busses/i2c-parport-light.c | |||
| @@ -121,14 +121,11 @@ static struct i2c_adapter parport_adapter = { | |||
| 121 | 121 | ||
| 122 | static int __init i2c_parport_init(void) | 122 | static int __init i2c_parport_init(void) |
| 123 | { | 123 | { |
| 124 | int type_count; | 124 | if (type < 0 || type >= ARRAY_SIZE(adapter_parm)) { |
| 125 | |||
| 126 | type_count = sizeof(adapter_parm)/sizeof(struct adapter_parm); | ||
| 127 | if (type < 0 || type >= type_count) { | ||
| 128 | printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); | 125 | printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); |
| 129 | type = 0; | 126 | type = 0; |
| 130 | } | 127 | } |
| 131 | 128 | ||
| 132 | if (base == 0) { | 129 | if (base == 0) { |
| 133 | printk(KERN_INFO "i2c-parport: using default base 0x%x\n", DEFAULT_BASE); | 130 | printk(KERN_INFO "i2c-parport: using default base 0x%x\n", DEFAULT_BASE); |
| 134 | base = DEFAULT_BASE; | 131 | base = DEFAULT_BASE; |
| @@ -152,7 +149,7 @@ static int __init i2c_parport_init(void) | |||
| 152 | release_region(base, 3); | 149 | release_region(base, 3); |
| 153 | return -ENODEV; | 150 | return -ENODEV; |
| 154 | } | 151 | } |
| 155 | 152 | ||
| 156 | return 0; | 153 | return 0; |
| 157 | } | 154 | } |
| 158 | 155 | ||
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c index 2854d858fc9b..7e2e8cd1c14a 100644 --- a/drivers/i2c/busses/i2c-parport.c +++ b/drivers/i2c/busses/i2c-parport.c | |||
| @@ -241,14 +241,11 @@ static struct parport_driver i2c_parport_driver = { | |||
| 241 | 241 | ||
| 242 | static int __init i2c_parport_init(void) | 242 | static int __init i2c_parport_init(void) |
| 243 | { | 243 | { |
| 244 | int type_count; | 244 | if (type < 0 || type >= ARRAY_SIZE(adapter_parm)) { |
| 245 | |||
| 246 | type_count = sizeof(adapter_parm)/sizeof(struct adapter_parm); | ||
| 247 | if (type < 0 || type >= type_count) { | ||
| 248 | printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); | 245 | printk(KERN_WARNING "i2c-parport: invalid type (%d)\n", type); |
| 249 | type = 0; | 246 | type = 0; |
| 250 | } | 247 | } |
| 251 | 248 | ||
| 252 | return parport_register_driver(&i2c_parport_driver); | 249 | return parport_register_driver(&i2c_parport_driver); |
| 253 | } | 250 | } |
| 254 | 251 | ||
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c index 86e2234faf80..7579f4b256a8 100644 --- a/drivers/i2c/busses/i2c-pxa.c +++ b/drivers/i2c/busses/i2c-pxa.c | |||
| @@ -861,7 +861,7 @@ static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id, struct pt_regs *r | |||
| 861 | decode_ISR(isr); | 861 | decode_ISR(isr); |
| 862 | } | 862 | } |
| 863 | 863 | ||
| 864 | if (i2c->irqlogidx < sizeof(i2c->isrlog)/sizeof(u32)) | 864 | if (i2c->irqlogidx < ARRAY_SIZE(i2c->isrlog)) |
| 865 | i2c->isrlog[i2c->irqlogidx++] = isr; | 865 | i2c->isrlog[i2c->irqlogidx++] = isr; |
| 866 | 866 | ||
| 867 | show_state(i2c); | 867 | show_state(i2c); |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 0ce58b506046..1a2c9ab5d9e3 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
| @@ -946,6 +946,20 @@ s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 *val | |||
| 946 | } | 946 | } |
| 947 | } | 947 | } |
| 948 | 948 | ||
| 949 | s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command, | ||
| 950 | u8 length, u8 *values) | ||
| 951 | { | ||
| 952 | union i2c_smbus_data data; | ||
| 953 | |||
| 954 | if (length > I2C_SMBUS_BLOCK_MAX) | ||
| 955 | length = I2C_SMBUS_BLOCK_MAX; | ||
| 956 | data.block[0] = length; | ||
| 957 | memcpy(data.block + 1, values, length); | ||
| 958 | return i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
| 959 | I2C_SMBUS_WRITE, command, | ||
| 960 | I2C_SMBUS_I2C_BLOCK_DATA, &data); | ||
| 961 | } | ||
| 962 | |||
| 949 | /* Simulate a SMBus command using the i2c protocol | 963 | /* Simulate a SMBus command using the i2c protocol |
| 950 | No checking of parameters is done! */ | 964 | No checking of parameters is done! */ |
| 951 | static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, | 965 | static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr, |
| @@ -1150,6 +1164,7 @@ EXPORT_SYMBOL(i2c_smbus_read_word_data); | |||
| 1150 | EXPORT_SYMBOL(i2c_smbus_write_word_data); | 1164 | EXPORT_SYMBOL(i2c_smbus_write_word_data); |
| 1151 | EXPORT_SYMBOL(i2c_smbus_write_block_data); | 1165 | EXPORT_SYMBOL(i2c_smbus_write_block_data); |
| 1152 | EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data); | 1166 | EXPORT_SYMBOL(i2c_smbus_read_i2c_block_data); |
| 1167 | EXPORT_SYMBOL(i2c_smbus_write_i2c_block_data); | ||
| 1153 | 1168 | ||
| 1154 | MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>"); | 1169 | MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>"); |
| 1155 | MODULE_DESCRIPTION("I2C-Bus main module"); | 1170 | MODULE_DESCRIPTION("I2C-Bus main module"); |
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 1c81174595b3..d633081fa4c5 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig | |||
| @@ -52,9 +52,9 @@ config IDE | |||
| 52 | 52 | ||
| 53 | if IDE | 53 | if IDE |
| 54 | 54 | ||
| 55 | config IDE_MAX_HWIFS | 55 | config IDE_MAX_HWIFS |
| 56 | int "Max IDE interfaces" | 56 | int "Max IDE interfaces" |
| 57 | depends on ALPHA || SUPERH | 57 | depends on ALPHA || SUPERH || IA64 |
| 58 | default 4 | 58 | default 4 |
| 59 | help | 59 | help |
| 60 | This is the maximum number of IDE hardware interfaces that will | 60 | This is the maximum number of IDE hardware interfaces that will |
| @@ -162,8 +162,8 @@ config BLK_DEV_IDECS | |||
| 162 | tristate "PCMCIA IDE support" | 162 | tristate "PCMCIA IDE support" |
| 163 | depends on PCMCIA | 163 | depends on PCMCIA |
| 164 | help | 164 | help |
| 165 | Support for outboard IDE disks, tape drives, and CD-ROM drives | 165 | Support for Compact Flash cards, outboard IDE disks, tape drives, |
| 166 | connected through a PCMCIA card. | 166 | and CD-ROM drives connected through a PCMCIA card. |
| 167 | 167 | ||
| 168 | config BLK_DEV_IDECD | 168 | config BLK_DEV_IDECD |
| 169 | tristate "Include IDE/ATAPI CDROM support" | 169 | tristate "Include IDE/ATAPI CDROM support" |
| @@ -267,7 +267,7 @@ config IDE_TASK_IOCTL | |||
| 267 | help | 267 | help |
| 268 | This is a direct raw access to the media. It is a complex but | 268 | This is a direct raw access to the media. It is a complex but |
| 269 | elegant solution to test and validate the domain of the hardware and | 269 | elegant solution to test and validate the domain of the hardware and |
| 270 | perform below the driver data recover if needed. This is the most | 270 | perform below the driver data recovery if needed. This is the most |
| 271 | basic form of media-forensics. | 271 | basic form of media-forensics. |
| 272 | 272 | ||
| 273 | If you are unsure, say N here. | 273 | If you are unsure, say N here. |
| @@ -525,7 +525,7 @@ config BLK_DEV_CS5520 | |||
| 525 | tristate "Cyrix CS5510/20 MediaGX chipset support (VERY EXPERIMENTAL)" | 525 | tristate "Cyrix CS5510/20 MediaGX chipset support (VERY EXPERIMENTAL)" |
| 526 | depends on EXPERIMENTAL | 526 | depends on EXPERIMENTAL |
| 527 | help | 527 | help |
| 528 | Include support for PIO tuning an virtual DMA on the Cyrix MediaGX | 528 | Include support for PIO tuning and virtual DMA on the Cyrix MediaGX |
| 529 | 5510/5520 chipset. This will automatically be detected and | 529 | 5510/5520 chipset. This will automatically be detected and |
| 530 | configured if found. | 530 | configured if found. |
| 531 | 531 | ||
| @@ -662,7 +662,7 @@ config PDC202XX_BURST | |||
| 662 | 662 | ||
| 663 | It was originally designed for the PDC20246/Ultra33, whose BIOS will | 663 | It was originally designed for the PDC20246/Ultra33, whose BIOS will |
| 664 | only setup UDMA on the first two PDC20246 cards. It has also been | 664 | only setup UDMA on the first two PDC20246 cards. It has also been |
| 665 | used succesfully on a PDC20265/Ultra100, allowing use of UDMA modes | 665 | used successfully on a PDC20265/Ultra100, allowing use of UDMA modes |
| 666 | when the PDC20265 BIOS has been disabled (for faster boot up). | 666 | when the PDC20265 BIOS has been disabled (for faster boot up). |
| 667 | 667 | ||
| 668 | Please read the comments at the top of | 668 | Please read the comments at the top of |
| @@ -673,13 +673,6 @@ config PDC202XX_BURST | |||
| 673 | config BLK_DEV_PDC202XX_NEW | 673 | config BLK_DEV_PDC202XX_NEW |
| 674 | tristate "PROMISE PDC202{68|69|70|71|75|76|77} support" | 674 | tristate "PROMISE PDC202{68|69|70|71|75|76|77} support" |
| 675 | 675 | ||
| 676 | # FIXME - probably wants to be one for old and for new | ||
| 677 | config PDC202XX_FORCE | ||
| 678 | bool "Enable controller even if disabled by BIOS" | ||
| 679 | depends on BLK_DEV_PDC202XX_NEW | ||
| 680 | help | ||
| 681 | Enable the PDC202xx controller even if it has been disabled in the BIOS setup. | ||
| 682 | |||
| 683 | config BLK_DEV_SVWKS | 676 | config BLK_DEV_SVWKS |
| 684 | tristate "ServerWorks OSB4/CSB5/CSB6 chipsets support" | 677 | tristate "ServerWorks OSB4/CSB5/CSB6 chipsets support" |
| 685 | help | 678 | help |
| @@ -722,7 +715,7 @@ config BLK_DEV_SIS5513 | |||
| 722 | config BLK_DEV_SLC90E66 | 715 | config BLK_DEV_SLC90E66 |
| 723 | tristate "SLC90E66 chipset support" | 716 | tristate "SLC90E66 chipset support" |
| 724 | help | 717 | help |
| 725 | This driver ensures (U)DMA support for Victroy66 SouthBridges for | 718 | This driver ensures (U)DMA support for Victory66 SouthBridges for |
| 726 | SMsC with Intel NorthBridges. This is an Ultra66 based chipset. | 719 | SMsC with Intel NorthBridges. This is an Ultra66 based chipset. |
| 727 | The nice thing about it is that you can mix Ultra/DMA/PIO devices | 720 | The nice thing about it is that you can mix Ultra/DMA/PIO devices |
| 728 | and it will handle timing cycles. Since this is an improved | 721 | and it will handle timing cycles. Since this is an improved |
| @@ -1060,7 +1053,7 @@ config IDEDMA_IVB | |||
| 1060 | in that mode with an 80c ribbon. | 1053 | in that mode with an 80c ribbon. |
| 1061 | 1054 | ||
| 1062 | If you are experiencing compatibility or performance problems, you | 1055 | If you are experiencing compatibility or performance problems, you |
| 1063 | MAY try to answering Y here. However, it does not necessarily solve | 1056 | MAY try to answer Y here. However, it does not necessarily solve |
| 1064 | any of your problems, it could even cause more of them. | 1057 | any of your problems, it could even cause more of them. |
| 1065 | 1058 | ||
| 1066 | It is normally safe to answer Y; however, the default is N. | 1059 | It is normally safe to answer Y; however, the default is N. |
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index ca25f9e3d0f4..09086b8b6486 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
| @@ -190,7 +190,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |||
| 190 | if (lba48) { | 190 | if (lba48) { |
| 191 | task_ioreg_t tasklets[10]; | 191 | task_ioreg_t tasklets[10]; |
| 192 | 192 | ||
| 193 | pr_debug("%s: LBA=0x%012llx\n", drive->name, block); | 193 | pr_debug("%s: LBA=0x%012llx\n", drive->name, |
| 194 | (unsigned long long)block); | ||
| 194 | 195 | ||
| 195 | tasklets[0] = 0; | 196 | tasklets[0] = 0; |
| 196 | tasklets[1] = 0; | 197 | tasklets[1] = 0; |
| @@ -317,7 +318,8 @@ static ide_startstop_t ide_do_rw_disk (ide_drive_t *drive, struct request *rq, s | |||
| 317 | 318 | ||
| 318 | pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n", | 319 | pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n", |
| 319 | drive->name, rq_data_dir(rq) == READ ? "read" : "writ", | 320 | drive->name, rq_data_dir(rq) == READ ? "read" : "writ", |
| 320 | block, rq->nr_sectors, (unsigned long)rq->buffer); | 321 | (unsigned long long)block, rq->nr_sectors, |
| 322 | (unsigned long)rq->buffer); | ||
| 321 | 323 | ||
| 322 | if (hwif->rw_disk) | 324 | if (hwif->rw_disk) |
| 323 | hwif->rw_disk(drive, rq); | 325 | hwif->rw_disk(drive, rq); |
| @@ -776,7 +778,7 @@ static void update_ordered(ide_drive_t *drive) | |||
| 776 | ide_id_has_flush_cache_ext(id)); | 778 | ide_id_has_flush_cache_ext(id)); |
| 777 | 779 | ||
| 778 | printk(KERN_INFO "%s: cache flushes %ssupported\n", | 780 | printk(KERN_INFO "%s: cache flushes %ssupported\n", |
| 779 | drive->name, barrier ? "" : "not"); | 781 | drive->name, barrier ? "" : "not "); |
| 780 | 782 | ||
| 781 | if (barrier) { | 783 | if (barrier) { |
| 782 | ordered = QUEUE_ORDERED_DRAIN_FLUSH; | 784 | ordered = QUEUE_ORDERED_DRAIN_FLUSH; |
| @@ -889,11 +891,7 @@ static void idedisk_setup (ide_drive_t *drive) | |||
| 889 | if (drive->id_read == 0) | 891 | if (drive->id_read == 0) |
| 890 | return; | 892 | return; |
| 891 | 893 | ||
| 892 | /* | 894 | if (drive->removable) { |
| 893 | * CompactFlash cards and their brethern look just like hard drives | ||
| 894 | * to us, but they are removable and don't have a doorlock mechanism. | ||
| 895 | */ | ||
| 896 | if (drive->removable && !(drive->is_flash)) { | ||
| 897 | /* | 895 | /* |
| 898 | * Removable disks (eg. SYQUEST); ignore 'WD' drives | 896 | * Removable disks (eg. SYQUEST); ignore 'WD' drives |
| 899 | */ | 897 | */ |
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 8d50df4526a4..c01615dec202 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
| @@ -55,8 +55,8 @@ | |||
| 55 | #include <asm/io.h> | 55 | #include <asm/io.h> |
| 56 | #include <asm/bitops.h> | 56 | #include <asm/bitops.h> |
| 57 | 57 | ||
| 58 | int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate, | 58 | static int __ide_end_request(ide_drive_t *drive, struct request *rq, |
| 59 | int nr_sectors) | 59 | int uptodate, int nr_sectors) |
| 60 | { | 60 | { |
| 61 | int ret = 1; | 61 | int ret = 1; |
| 62 | 62 | ||
| @@ -91,7 +91,6 @@ int __ide_end_request(ide_drive_t *drive, struct request *rq, int uptodate, | |||
| 91 | 91 | ||
| 92 | return ret; | 92 | return ret; |
| 93 | } | 93 | } |
| 94 | EXPORT_SYMBOL(__ide_end_request); | ||
| 95 | 94 | ||
| 96 | /** | 95 | /** |
| 97 | * ide_end_request - complete an IDE I/O | 96 | * ide_end_request - complete an IDE I/O |
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index af7af958ab3e..b72dde70840a 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
| @@ -1243,6 +1243,7 @@ int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout) | |||
| 1243 | */ | 1243 | */ |
| 1244 | if (stat == 0xff) | 1244 | if (stat == 0xff) |
| 1245 | return -ENODEV; | 1245 | return -ENODEV; |
| 1246 | touch_softlockup_watchdog(); | ||
| 1246 | } | 1247 | } |
| 1247 | return -EBUSY; | 1248 | return -EBUSY; |
| 1248 | } | 1249 | } |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index e7425546b4b1..427d1c204174 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
| @@ -125,45 +125,6 @@ static void ide_disk_init_mult_count(ide_drive_t *drive) | |||
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | /** | 127 | /** |
| 128 | * drive_is_flashcard - check for compact flash | ||
| 129 | * @drive: drive to check | ||
| 130 | * | ||
| 131 | * CompactFlash cards and their brethern pretend to be removable | ||
| 132 | * hard disks, except: | ||
| 133 | * (1) they never have a slave unit, and | ||
| 134 | * (2) they don't have doorlock mechanisms. | ||
| 135 | * This test catches them, and is invoked elsewhere when setting | ||
| 136 | * appropriate config bits. | ||
| 137 | * | ||
| 138 | * FIXME: This treatment is probably applicable for *all* PCMCIA (PC CARD) | ||
| 139 | * devices, so in linux 2.3.x we should change this to just treat all | ||
| 140 | * PCMCIA drives this way, and get rid of the model-name tests below | ||
| 141 | * (too big of an interface change for 2.4.x). | ||
| 142 | * At that time, we might also consider parameterizing the timeouts and | ||
| 143 | * retries, since these are MUCH faster than mechanical drives. -M.Lord | ||
| 144 | */ | ||
| 145 | |||
| 146 | static inline int drive_is_flashcard (ide_drive_t *drive) | ||
| 147 | { | ||
| 148 | struct hd_driveid *id = drive->id; | ||
| 149 | |||
| 150 | if (drive->removable) { | ||
| 151 | if (id->config == 0x848a) return 1; /* CompactFlash */ | ||
| 152 | if (!strncmp(id->model, "KODAK ATA_FLASH", 15) /* Kodak */ | ||
| 153 | || !strncmp(id->model, "Hitachi CV", 10) /* Hitachi */ | ||
| 154 | || !strncmp(id->model, "SunDisk SDCFB", 13) /* old SanDisk */ | ||
| 155 | || !strncmp(id->model, "SanDisk SDCFB", 13) /* SanDisk */ | ||
| 156 | || !strncmp(id->model, "HAGIWARA HPC", 12) /* Hagiwara */ | ||
| 157 | || !strncmp(id->model, "LEXAR ATA_FLASH", 15) /* Lexar */ | ||
| 158 | || !strncmp(id->model, "ATA_FLASH", 9)) /* Simple Tech */ | ||
| 159 | { | ||
| 160 | return 1; /* yes, it is a flash memory card */ | ||
| 161 | } | ||
| 162 | } | ||
| 163 | return 0; /* no, it is not a flash memory card */ | ||
| 164 | } | ||
| 165 | |||
| 166 | /** | ||
| 167 | * do_identify - identify a drive | 128 | * do_identify - identify a drive |
| 168 | * @drive: drive to identify | 129 | * @drive: drive to identify |
| 169 | * @cmd: command used | 130 | * @cmd: command used |
| @@ -278,13 +239,17 @@ static inline void do_identify (ide_drive_t *drive, u8 cmd) | |||
| 278 | /* | 239 | /* |
| 279 | * Not an ATAPI device: looks like a "regular" hard disk | 240 | * Not an ATAPI device: looks like a "regular" hard disk |
| 280 | */ | 241 | */ |
| 281 | if (id->config & (1<<7)) | 242 | |
| 243 | /* | ||
| 244 | * 0x848a = CompactFlash device | ||
| 245 | * These are *not* removable in Linux definition of the term | ||
| 246 | */ | ||
| 247 | |||
| 248 | if ((id->config != 0x848a) && (id->config & (1<<7))) | ||
| 282 | drive->removable = 1; | 249 | drive->removable = 1; |
| 283 | 250 | ||
| 284 | if (drive_is_flashcard(drive)) | ||
| 285 | drive->is_flash = 1; | ||
| 286 | drive->media = ide_disk; | 251 | drive->media = ide_disk; |
| 287 | printk("%s DISK drive\n", (drive->is_flash) ? "CFA" : "ATA" ); | 252 | printk("%s DISK drive\n", (id->config == 0x848a) ? "CFA" : "ATA" ); |
| 288 | QUIRK_LIST(drive); | 253 | QUIRK_LIST(drive); |
| 289 | return; | 254 | return; |
| 290 | 255 | ||
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index afeb02bbb722..b2cc43702f65 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
| @@ -242,7 +242,6 @@ static void init_hwif_data(ide_hwif_t *hwif, unsigned int index) | |||
| 242 | drive->name[2] = 'a' + (index * MAX_DRIVES) + unit; | 242 | drive->name[2] = 'a' + (index * MAX_DRIVES) + unit; |
| 243 | drive->max_failures = IDE_DEFAULT_MAX_FAILURES; | 243 | drive->max_failures = IDE_DEFAULT_MAX_FAILURES; |
| 244 | drive->using_dma = 0; | 244 | drive->using_dma = 0; |
| 245 | drive->is_flash = 0; | ||
| 246 | drive->vdma = 0; | 245 | drive->vdma = 0; |
| 247 | INIT_LIST_HEAD(&drive->list); | 246 | INIT_LIST_HEAD(&drive->list); |
| 248 | init_completion(&drive->gendev_rel_comp); | 247 | init_completion(&drive->gendev_rel_comp); |
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c index a21b1e11eef4..c743e68c33aa 100644 --- a/drivers/ide/pci/aec62xx.c +++ b/drivers/ide/pci/aec62xx.c | |||
| @@ -262,6 +262,21 @@ static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const ch | |||
| 262 | else | 262 | else |
| 263 | pci_set_drvdata(dev, (void *) aec6xxx_34_base); | 263 | pci_set_drvdata(dev, (void *) aec6xxx_34_base); |
| 264 | 264 | ||
| 265 | /* These are necessary to get AEC6280 Macintosh cards to work */ | ||
| 266 | if ((dev->device == PCI_DEVICE_ID_ARTOP_ATP865) || | ||
| 267 | (dev->device == PCI_DEVICE_ID_ARTOP_ATP865R)) { | ||
| 268 | u8 reg49h = 0, reg4ah = 0; | ||
| 269 | /* Clear reset and test bits. */ | ||
| 270 | pci_read_config_byte(dev, 0x49, ®49h); | ||
| 271 | pci_write_config_byte(dev, 0x49, reg49h & ~0x30); | ||
| 272 | /* Enable chip interrupt output. */ | ||
| 273 | pci_read_config_byte(dev, 0x4a, ®4ah); | ||
| 274 | pci_write_config_byte(dev, 0x4a, reg4ah & ~0x01); | ||
| 275 | /* Enable burst mode. */ | ||
| 276 | pci_read_config_byte(dev, 0x4a, ®4ah); | ||
| 277 | pci_write_config_byte(dev, 0x4a, reg4ah | 0x80); | ||
| 278 | } | ||
| 279 | |||
| 265 | return dev->irq; | 280 | return dev->irq; |
| 266 | } | 281 | } |
| 267 | 282 | ||
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index 7b589d948bf9..940bdd4c5784 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c | |||
| @@ -1288,6 +1288,10 @@ static void __devinit hpt37x_clocking(ide_hwif_t *hwif) | |||
| 1288 | goto init_hpt37X_done; | 1288 | goto init_hpt37X_done; |
| 1289 | } | 1289 | } |
| 1290 | } | 1290 | } |
| 1291 | if (!pci_get_drvdata(dev)) { | ||
| 1292 | printk("No Clock Stabilization!!!\n"); | ||
| 1293 | return; | ||
| 1294 | } | ||
| 1291 | pll_recal: | 1295 | pll_recal: |
| 1292 | if (adjust & 1) | 1296 | if (adjust & 1) |
| 1293 | pll -= (adjust >> 1); | 1297 | pll -= (adjust >> 1); |
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c index 108fda83fea4..38f41b377ff6 100644 --- a/drivers/ide/pci/it821x.c +++ b/drivers/ide/pci/it821x.c | |||
| @@ -733,7 +733,7 @@ static void __devinit it8212_disable_raid(struct pci_dev *dev) | |||
| 733 | 733 | ||
| 734 | pci_write_config_dword(dev,0x4C, 0x02040204); | 734 | pci_write_config_dword(dev,0x4C, 0x02040204); |
| 735 | pci_write_config_byte(dev, 0x42, 0x36); | 735 | pci_write_config_byte(dev, 0x42, 0x36); |
| 736 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0); | 736 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20); |
| 737 | } | 737 | } |
| 738 | 738 | ||
| 739 | static unsigned int __devinit init_chipset_it821x(struct pci_dev *dev, const char *name) | 739 | static unsigned int __devinit init_chipset_it821x(struct pci_dev *dev, const char *name) |
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index fe06ebb0e5bf..acd63173199b 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c | |||
| @@ -420,9 +420,6 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = { | |||
| 420 | .init_hwif = init_hwif_pdc202new, | 420 | .init_hwif = init_hwif_pdc202new, |
| 421 | .channels = 2, | 421 | .channels = 2, |
| 422 | .autodma = AUTODMA, | 422 | .autodma = AUTODMA, |
| 423 | #ifndef CONFIG_PDC202XX_FORCE | ||
| 424 | .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, | ||
| 425 | #endif | ||
| 426 | .bootable = OFF_BOARD, | 423 | .bootable = OFF_BOARD, |
| 427 | },{ /* 3 */ | 424 | },{ /* 3 */ |
| 428 | .name = "PDC20271", | 425 | .name = "PDC20271", |
| @@ -447,9 +444,6 @@ static ide_pci_device_t pdcnew_chipsets[] __devinitdata = { | |||
| 447 | .init_hwif = init_hwif_pdc202new, | 444 | .init_hwif = init_hwif_pdc202new, |
| 448 | .channels = 2, | 445 | .channels = 2, |
| 449 | .autodma = AUTODMA, | 446 | .autodma = AUTODMA, |
| 450 | #ifndef CONFIG_PDC202XX_FORCE | ||
| 451 | .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, | ||
| 452 | #endif | ||
| 453 | .bootable = OFF_BOARD, | 447 | .bootable = OFF_BOARD, |
| 454 | },{ /* 6 */ | 448 | },{ /* 6 */ |
| 455 | .name = "PDC20277", | 449 | .name = "PDC20277", |
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index ad9d95817f95..6f8f8645b02c 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c | |||
| @@ -786,9 +786,6 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = { | |||
| 786 | .init_dma = init_dma_pdc202xx, | 786 | .init_dma = init_dma_pdc202xx, |
| 787 | .channels = 2, | 787 | .channels = 2, |
| 788 | .autodma = AUTODMA, | 788 | .autodma = AUTODMA, |
| 789 | #ifndef CONFIG_PDC202XX_FORCE | ||
| 790 | .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, | ||
| 791 | #endif | ||
| 792 | .bootable = OFF_BOARD, | 789 | .bootable = OFF_BOARD, |
| 793 | .extra = 16, | 790 | .extra = 16, |
| 794 | },{ /* 1 */ | 791 | },{ /* 1 */ |
| @@ -799,9 +796,6 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = { | |||
| 799 | .init_dma = init_dma_pdc202xx, | 796 | .init_dma = init_dma_pdc202xx, |
| 800 | .channels = 2, | 797 | .channels = 2, |
| 801 | .autodma = AUTODMA, | 798 | .autodma = AUTODMA, |
| 802 | #ifndef CONFIG_PDC202XX_FORCE | ||
| 803 | .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, | ||
| 804 | #endif | ||
| 805 | .bootable = OFF_BOARD, | 799 | .bootable = OFF_BOARD, |
| 806 | .extra = 48, | 800 | .extra = 48, |
| 807 | .flags = IDEPCI_FLAG_FORCE_PDC, | 801 | .flags = IDEPCI_FLAG_FORCE_PDC, |
| @@ -813,9 +807,6 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = { | |||
| 813 | .init_dma = init_dma_pdc202xx, | 807 | .init_dma = init_dma_pdc202xx, |
| 814 | .channels = 2, | 808 | .channels = 2, |
| 815 | .autodma = AUTODMA, | 809 | .autodma = AUTODMA, |
| 816 | #ifndef CONFIG_PDC202XX_FORCE | ||
| 817 | .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, | ||
| 818 | #endif | ||
| 819 | .bootable = OFF_BOARD, | 810 | .bootable = OFF_BOARD, |
| 820 | .extra = 48, | 811 | .extra = 48, |
| 821 | },{ /* 3 */ | 812 | },{ /* 3 */ |
| @@ -826,9 +817,6 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = { | |||
| 826 | .init_dma = init_dma_pdc202xx, | 817 | .init_dma = init_dma_pdc202xx, |
| 827 | .channels = 2, | 818 | .channels = 2, |
| 828 | .autodma = AUTODMA, | 819 | .autodma = AUTODMA, |
| 829 | #ifndef CONFIG_PDC202XX_FORCE | ||
| 830 | .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, | ||
| 831 | #endif | ||
| 832 | .bootable = OFF_BOARD, | 820 | .bootable = OFF_BOARD, |
| 833 | .extra = 48, | 821 | .extra = 48, |
| 834 | .flags = IDEPCI_FLAG_FORCE_PDC, | 822 | .flags = IDEPCI_FLAG_FORCE_PDC, |
| @@ -840,9 +828,6 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = { | |||
| 840 | .init_dma = init_dma_pdc202xx, | 828 | .init_dma = init_dma_pdc202xx, |
| 841 | .channels = 2, | 829 | .channels = 2, |
| 842 | .autodma = AUTODMA, | 830 | .autodma = AUTODMA, |
| 843 | #ifndef CONFIG_PDC202XX_FORCE | ||
| 844 | .enablebits = {{0x50,0x02,0x02}, {0x50,0x04,0x04}}, | ||
| 845 | #endif | ||
| 846 | .bootable = OFF_BOARD, | 831 | .bootable = OFF_BOARD, |
| 847 | .extra = 48, | 832 | .extra = 48, |
| 848 | } | 833 | } |
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c index b3e77df63cef..e9b83e1a3028 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/pci/piix.c | |||
| @@ -135,6 +135,7 @@ static u8 piix_ratemask (ide_drive_t *drive) | |||
| 135 | case PCI_DEVICE_ID_INTEL_ICH6_19: | 135 | case PCI_DEVICE_ID_INTEL_ICH6_19: |
| 136 | case PCI_DEVICE_ID_INTEL_ICH7_21: | 136 | case PCI_DEVICE_ID_INTEL_ICH7_21: |
| 137 | case PCI_DEVICE_ID_INTEL_ESB2_18: | 137 | case PCI_DEVICE_ID_INTEL_ESB2_18: |
| 138 | case PCI_DEVICE_ID_INTEL_ICH8_6: | ||
| 138 | mode = 3; | 139 | mode = 3; |
| 139 | break; | 140 | break; |
| 140 | /* UDMA 66 capable */ | 141 | /* UDMA 66 capable */ |
| @@ -449,6 +450,7 @@ static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char | |||
| 449 | case PCI_DEVICE_ID_INTEL_ICH6_19: | 450 | case PCI_DEVICE_ID_INTEL_ICH6_19: |
| 450 | case PCI_DEVICE_ID_INTEL_ICH7_21: | 451 | case PCI_DEVICE_ID_INTEL_ICH7_21: |
| 451 | case PCI_DEVICE_ID_INTEL_ESB2_18: | 452 | case PCI_DEVICE_ID_INTEL_ESB2_18: |
| 453 | case PCI_DEVICE_ID_INTEL_ICH8_6: | ||
| 452 | { | 454 | { |
| 453 | unsigned int extra = 0; | 455 | unsigned int extra = 0; |
| 454 | pci_read_config_dword(dev, 0x54, &extra); | 456 | pci_read_config_dword(dev, 0x54, &extra); |
| @@ -575,6 +577,7 @@ static ide_pci_device_t piix_pci_info[] __devinitdata = { | |||
| 575 | /* 21 */ DECLARE_PIIX_DEV("ICH7"), | 577 | /* 21 */ DECLARE_PIIX_DEV("ICH7"), |
| 576 | /* 22 */ DECLARE_PIIX_DEV("ICH4"), | 578 | /* 22 */ DECLARE_PIIX_DEV("ICH4"), |
| 577 | /* 23 */ DECLARE_PIIX_DEV("ESB2"), | 579 | /* 23 */ DECLARE_PIIX_DEV("ESB2"), |
| 580 | /* 24 */ DECLARE_PIIX_DEV("ICH8M"), | ||
| 578 | }; | 581 | }; |
| 579 | 582 | ||
| 580 | /** | 583 | /** |
| @@ -651,6 +654,7 @@ static struct pci_device_id piix_pci_tbl[] = { | |||
| 651 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 21}, | 654 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 21}, |
| 652 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 22}, | 655 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 22}, |
| 653 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_18, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 23}, | 656 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB2_18, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 23}, |
| 657 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH8_6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 24}, | ||
| 654 | { 0, }, | 658 | { 0, }, |
| 655 | }; | 659 | }; |
| 656 | MODULE_DEVICE_TABLE(pci, piix_pci_tbl); | 660 | MODULE_DEVICE_TABLE(pci, piix_pci_tbl); |
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c index 4ee597d08797..2b286e865163 100644 --- a/drivers/ide/pci/sgiioc4.c +++ b/drivers/ide/pci/sgiioc4.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2003 Silicon Graphics, Inc. All Rights Reserved. | 2 | * Copyright (c) 2003-2006 Silicon Graphics, Inc. All Rights Reserved. |
| 3 | * | 3 | * |
| 4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
| 5 | * under the terms of version 2 of the GNU General Public License | 5 | * under the terms of version 2 of the GNU General Public License |
| @@ -510,7 +510,7 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir) | |||
| 510 | drive->name); | 510 | drive->name); |
| 511 | goto use_pio_instead; | 511 | goto use_pio_instead; |
| 512 | } else { | 512 | } else { |
| 513 | u32 xcount, bcount = | 513 | u32 bcount = |
| 514 | 0x10000 - (cur_addr & 0xffff); | 514 | 0x10000 - (cur_addr & 0xffff); |
| 515 | 515 | ||
| 516 | if (bcount > cur_len) | 516 | if (bcount > cur_len) |
| @@ -525,8 +525,7 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir) | |||
| 525 | *table = 0x0; | 525 | *table = 0x0; |
| 526 | table++; | 526 | table++; |
| 527 | 527 | ||
| 528 | xcount = bcount & 0xffff; | 528 | *table = cpu_to_be32(bcount); |
| 529 | *table = cpu_to_be32(xcount); | ||
| 530 | table++; | 529 | table++; |
| 531 | 530 | ||
| 532 | cur_addr += bcount; | 531 | cur_addr += bcount; |
| @@ -680,7 +679,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d) | |||
| 680 | return -EIO; | 679 | return -EIO; |
| 681 | 680 | ||
| 682 | /* Create /proc/ide entries */ | 681 | /* Create /proc/ide entries */ |
| 683 | create_proc_ide_interfaces(); | 682 | create_proc_ide_interfaces(); |
| 684 | 683 | ||
| 685 | return 0; | 684 | return 0; |
| 686 | } | 685 | } |
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c index e95c4293a496..f6a05965a4e8 100644 --- a/drivers/infiniband/core/ucm.c +++ b/drivers/infiniband/core/ucm.c | |||
| @@ -1319,15 +1319,6 @@ static struct class ucm_class = { | |||
| 1319 | .release = ib_ucm_release_class_dev | 1319 | .release = ib_ucm_release_class_dev |
| 1320 | }; | 1320 | }; |
| 1321 | 1321 | ||
| 1322 | static ssize_t show_dev(struct class_device *class_dev, char *buf) | ||
| 1323 | { | ||
| 1324 | struct ib_ucm_device *dev; | ||
| 1325 | |||
| 1326 | dev = container_of(class_dev, struct ib_ucm_device, class_dev); | ||
| 1327 | return print_dev_t(buf, dev->dev.dev); | ||
| 1328 | } | ||
| 1329 | static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL); | ||
| 1330 | |||
| 1331 | static ssize_t show_ibdev(struct class_device *class_dev, char *buf) | 1322 | static ssize_t show_ibdev(struct class_device *class_dev, char *buf) |
| 1332 | { | 1323 | { |
| 1333 | struct ib_ucm_device *dev; | 1324 | struct ib_ucm_device *dev; |
| @@ -1364,15 +1355,13 @@ static void ib_ucm_add_one(struct ib_device *device) | |||
| 1364 | 1355 | ||
| 1365 | ucm_dev->class_dev.class = &ucm_class; | 1356 | ucm_dev->class_dev.class = &ucm_class; |
| 1366 | ucm_dev->class_dev.dev = device->dma_device; | 1357 | ucm_dev->class_dev.dev = device->dma_device; |
| 1358 | ucm_dev->class_dev.devt = ucm_dev->dev.dev; | ||
| 1367 | snprintf(ucm_dev->class_dev.class_id, BUS_ID_SIZE, "ucm%d", | 1359 | snprintf(ucm_dev->class_dev.class_id, BUS_ID_SIZE, "ucm%d", |
| 1368 | ucm_dev->devnum); | 1360 | ucm_dev->devnum); |
| 1369 | if (class_device_register(&ucm_dev->class_dev)) | 1361 | if (class_device_register(&ucm_dev->class_dev)) |
| 1370 | goto err_cdev; | 1362 | goto err_cdev; |
| 1371 | 1363 | ||
| 1372 | if (class_device_create_file(&ucm_dev->class_dev, | 1364 | if (class_device_create_file(&ucm_dev->class_dev, |
| 1373 | &class_device_attr_dev)) | ||
| 1374 | goto err_class; | ||
| 1375 | if (class_device_create_file(&ucm_dev->class_dev, | ||
| 1376 | &class_device_attr_ibdev)) | 1365 | &class_device_attr_ibdev)) |
| 1377 | goto err_class; | 1366 | goto err_class; |
| 1378 | 1367 | ||
diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig index 0ef560144be3..6dfc94122dd9 100644 --- a/drivers/isdn/hisax/Kconfig +++ b/drivers/isdn/hisax/Kconfig | |||
| @@ -351,7 +351,7 @@ config HISAX_ENTERNOW_PCI | |||
| 351 | 351 | ||
| 352 | config HISAX_AMD7930 | 352 | config HISAX_AMD7930 |
| 353 | bool "Am7930 (EXPERIMENTAL)" | 353 | bool "Am7930 (EXPERIMENTAL)" |
| 354 | depends on EXPERIMENTAL && SPARC | 354 | depends on EXPERIMENTAL && SPARC && BROKEN |
| 355 | help | 355 | help |
| 356 | This enables HiSax support for the AMD7930 chips on some SPARCs. | 356 | This enables HiSax support for the AMD7930 chips on some SPARCs. |
| 357 | This code is not finished yet. | 357 | This code is not finished yet. |
diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h index 1b85ce166af8..11fe537e2f6f 100644 --- a/drivers/isdn/hisax/hisax.h +++ b/drivers/isdn/hisax/hisax.h | |||
| @@ -216,7 +216,7 @@ struct Layer1 { | |||
| 216 | #define GROUP_TEI 127 | 216 | #define GROUP_TEI 127 |
| 217 | #define TEI_SAPI 63 | 217 | #define TEI_SAPI 63 |
| 218 | #define CTRL_SAPI 0 | 218 | #define CTRL_SAPI 0 |
| 219 | #define PACKET_NOACK 250 | 219 | #define PACKET_NOACK 7 |
| 220 | 220 | ||
| 221 | /* Layer2 Flags */ | 221 | /* Layer2 Flags */ |
| 222 | 222 | ||
diff --git a/drivers/isdn/sc/ioctl.c b/drivers/isdn/sc/ioctl.c index 3314a5a19854..94c9afb7017c 100644 --- a/drivers/isdn/sc/ioctl.c +++ b/drivers/isdn/sc/ioctl.c | |||
| @@ -71,14 +71,14 @@ int sc_ioctl(int card, scs_ioctl *data) | |||
| 71 | /* | 71 | /* |
| 72 | * Get the SRec from user space | 72 | * Get the SRec from user space |
| 73 | */ | 73 | */ |
| 74 | if (copy_from_user(srec, data->dataptr, sizeof(srec))) { | 74 | if (copy_from_user(srec, data->dataptr, SCIOC_SRECSIZE)) { |
| 75 | kfree(rcvmsg); | 75 | kfree(rcvmsg); |
| 76 | kfree(srec); | 76 | kfree(srec); |
| 77 | return -EFAULT; | 77 | return -EFAULT; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | status = send_and_receive(card, CMPID, cmReqType2, cmReqClass0, cmReqLoadProc, | 80 | status = send_and_receive(card, CMPID, cmReqType2, cmReqClass0, cmReqLoadProc, |
| 81 | 0, sizeof(srec), srec, rcvmsg, SAR_TIMEOUT); | 81 | 0, SCIOC_SRECSIZE, srec, rcvmsg, SAR_TIMEOUT); |
| 82 | kfree(rcvmsg); | 82 | kfree(rcvmsg); |
| 83 | kfree(srec); | 83 | kfree(srec); |
| 84 | 84 | ||
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index 7d4a0ac28c06..12ad462737ba 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig | |||
| @@ -187,6 +187,14 @@ config WINDFARM_PM91 | |||
| 187 | This driver provides thermal control for the PowerMac9,1 | 187 | This driver provides thermal control for the PowerMac9,1 |
| 188 | which is the recent (SMU based) single CPU desktop G5 | 188 | which is the recent (SMU based) single CPU desktop G5 |
| 189 | 189 | ||
| 190 | config WINDFARM_PM112 | ||
| 191 | tristate "Support for thermal management on PowerMac11,2" | ||
| 192 | depends on WINDFARM && I2C && PMAC_SMU | ||
| 193 | select I2C_POWERMAC | ||
| 194 | help | ||
| 195 | This driver provides thermal control for the PowerMac11,2 | ||
| 196 | which are the recent dual and quad G5 machines using the | ||
| 197 | 970MP dual-core processor. | ||
| 190 | 198 | ||
| 191 | config ANSLCD | 199 | config ANSLCD |
| 192 | tristate "Support for ANS LCD display" | 200 | tristate "Support for ANS LCD display" |
diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile index f4657aa81fb0..6081acdea404 100644 --- a/drivers/macintosh/Makefile +++ b/drivers/macintosh/Makefile | |||
| @@ -35,3 +35,8 @@ obj-$(CONFIG_WINDFARM_PM91) += windfarm_smu_controls.o \ | |||
| 35 | windfarm_smu_sensors.o \ | 35 | windfarm_smu_sensors.o \ |
| 36 | windfarm_lm75_sensor.o windfarm_pid.o \ | 36 | windfarm_lm75_sensor.o windfarm_pid.o \ |
| 37 | windfarm_cpufreq_clamp.o windfarm_pm91.o | 37 | windfarm_cpufreq_clamp.o windfarm_pm91.o |
| 38 | obj-$(CONFIG_WINDFARM_PM112) += windfarm_pm112.o windfarm_smu_sat.o \ | ||
| 39 | windfarm_smu_controls.o \ | ||
| 40 | windfarm_smu_sensors.o \ | ||
| 41 | windfarm_max6690_sensor.o \ | ||
| 42 | windfarm_lm75_sensor.o windfarm_pid.o | ||
diff --git a/drivers/macintosh/windfarm.h b/drivers/macintosh/windfarm.h index 3f0cb0312ea3..7a2482cc26a7 100644 --- a/drivers/macintosh/windfarm.h +++ b/drivers/macintosh/windfarm.h | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/list.h> | 14 | #include <linux/list.h> |
| 15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 16 | #include <linux/notifier.h> | 16 | #include <linux/notifier.h> |
| 17 | #include <linux/device.h> | ||
| 17 | 18 | ||
| 18 | /* Display a 16.16 fixed point value */ | 19 | /* Display a 16.16 fixed point value */ |
| 19 | #define FIX32TOPRINT(f) ((f) >> 16),((((f) & 0xffff) * 1000) >> 16) | 20 | #define FIX32TOPRINT(f) ((f) >> 16),((((f) & 0xffff) * 1000) >> 16) |
| @@ -39,6 +40,7 @@ struct wf_control { | |||
| 39 | char *name; | 40 | char *name; |
| 40 | int type; | 41 | int type; |
| 41 | struct kref ref; | 42 | struct kref ref; |
| 43 | struct device_attribute attr; | ||
| 42 | }; | 44 | }; |
| 43 | 45 | ||
| 44 | #define WF_CONTROL_TYPE_GENERIC 0 | 46 | #define WF_CONTROL_TYPE_GENERIC 0 |
| @@ -87,6 +89,7 @@ struct wf_sensor { | |||
| 87 | struct wf_sensor_ops *ops; | 89 | struct wf_sensor_ops *ops; |
| 88 | char *name; | 90 | char *name; |
| 89 | struct kref ref; | 91 | struct kref ref; |
| 92 | struct device_attribute attr; | ||
| 90 | }; | 93 | }; |
| 91 | 94 | ||
| 92 | /* Same lifetime rules as controls */ | 95 | /* Same lifetime rules as controls */ |
diff --git a/drivers/macintosh/windfarm_core.c b/drivers/macintosh/windfarm_core.c index 6c2a471ea6c0..bb8d5efe19bf 100644 --- a/drivers/macintosh/windfarm_core.c +++ b/drivers/macintosh/windfarm_core.c | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <linux/reboot.h> | 33 | #include <linux/reboot.h> |
| 34 | #include <linux/device.h> | 34 | #include <linux/device.h> |
| 35 | #include <linux/platform_device.h> | 35 | #include <linux/platform_device.h> |
| 36 | #include <linux/mutex.h> | ||
| 36 | 37 | ||
| 37 | #include "windfarm.h" | 38 | #include "windfarm.h" |
| 38 | 39 | ||
| @@ -48,13 +49,17 @@ | |||
| 48 | 49 | ||
| 49 | static LIST_HEAD(wf_controls); | 50 | static LIST_HEAD(wf_controls); |
| 50 | static LIST_HEAD(wf_sensors); | 51 | static LIST_HEAD(wf_sensors); |
| 51 | static DECLARE_MUTEX(wf_lock); | 52 | static DEFINE_MUTEX(wf_lock); |
| 52 | static struct notifier_block *wf_client_list; | 53 | static struct notifier_block *wf_client_list; |
| 53 | static int wf_client_count; | 54 | static int wf_client_count; |
| 54 | static unsigned int wf_overtemp; | 55 | static unsigned int wf_overtemp; |
| 55 | static unsigned int wf_overtemp_counter; | 56 | static unsigned int wf_overtemp_counter; |
| 56 | struct task_struct *wf_thread; | 57 | struct task_struct *wf_thread; |
| 57 | 58 | ||
| 59 | static struct platform_device wf_platform_device = { | ||
| 60 | .name = "windfarm", | ||
| 61 | }; | ||
| 62 | |||
| 58 | /* | 63 | /* |
| 59 | * Utilities & tick thread | 64 | * Utilities & tick thread |
| 60 | */ | 65 | */ |
| @@ -156,26 +161,67 @@ static void wf_control_release(struct kref *kref) | |||
| 156 | kfree(ct); | 161 | kfree(ct); |
| 157 | } | 162 | } |
| 158 | 163 | ||
| 164 | static ssize_t wf_show_control(struct device *dev, | ||
| 165 | struct device_attribute *attr, char *buf) | ||
| 166 | { | ||
| 167 | struct wf_control *ctrl = container_of(attr, struct wf_control, attr); | ||
| 168 | s32 val = 0; | ||
| 169 | int err; | ||
| 170 | |||
| 171 | err = ctrl->ops->get_value(ctrl, &val); | ||
| 172 | if (err < 0) | ||
| 173 | return err; | ||
| 174 | return sprintf(buf, "%d\n", val); | ||
| 175 | } | ||
| 176 | |||
| 177 | /* This is really only for debugging... */ | ||
| 178 | static ssize_t wf_store_control(struct device *dev, | ||
| 179 | struct device_attribute *attr, | ||
| 180 | const char *buf, size_t count) | ||
| 181 | { | ||
| 182 | struct wf_control *ctrl = container_of(attr, struct wf_control, attr); | ||
| 183 | int val; | ||
| 184 | int err; | ||
| 185 | char *endp; | ||
| 186 | |||
| 187 | val = simple_strtoul(buf, &endp, 0); | ||
| 188 | while (endp < buf + count && (*endp == ' ' || *endp == '\n')) | ||
| 189 | ++endp; | ||
| 190 | if (endp - buf < count) | ||
| 191 | return -EINVAL; | ||
| 192 | err = ctrl->ops->set_value(ctrl, val); | ||
| 193 | if (err < 0) | ||
| 194 | return err; | ||
| 195 | return count; | ||
| 196 | } | ||
| 197 | |||
| 159 | int wf_register_control(struct wf_control *new_ct) | 198 | int wf_register_control(struct wf_control *new_ct) |
| 160 | { | 199 | { |
| 161 | struct wf_control *ct; | 200 | struct wf_control *ct; |
| 162 | 201 | ||
| 163 | down(&wf_lock); | 202 | mutex_lock(&wf_lock); |
| 164 | list_for_each_entry(ct, &wf_controls, link) { | 203 | list_for_each_entry(ct, &wf_controls, link) { |
| 165 | if (!strcmp(ct->name, new_ct->name)) { | 204 | if (!strcmp(ct->name, new_ct->name)) { |
| 166 | printk(KERN_WARNING "windfarm: trying to register" | 205 | printk(KERN_WARNING "windfarm: trying to register" |
| 167 | " duplicate control %s\n", ct->name); | 206 | " duplicate control %s\n", ct->name); |
| 168 | up(&wf_lock); | 207 | mutex_unlock(&wf_lock); |
| 169 | return -EEXIST; | 208 | return -EEXIST; |
| 170 | } | 209 | } |
| 171 | } | 210 | } |
| 172 | kref_init(&new_ct->ref); | 211 | kref_init(&new_ct->ref); |
| 173 | list_add(&new_ct->link, &wf_controls); | 212 | list_add(&new_ct->link, &wf_controls); |
| 174 | 213 | ||
| 214 | new_ct->attr.attr.name = new_ct->name; | ||
| 215 | new_ct->attr.attr.owner = THIS_MODULE; | ||
| 216 | new_ct->attr.attr.mode = 0644; | ||
| 217 | new_ct->attr.show = wf_show_control; | ||
| 218 | new_ct->attr.store = wf_store_control; | ||
| 219 | device_create_file(&wf_platform_device.dev, &new_ct->attr); | ||
| 220 | |||
| 175 | DBG("wf: Registered control %s\n", new_ct->name); | 221 | DBG("wf: Registered control %s\n", new_ct->name); |
| 176 | 222 | ||
| 177 | wf_notify(WF_EVENT_NEW_CONTROL, new_ct); | 223 | wf_notify(WF_EVENT_NEW_CONTROL, new_ct); |
| 178 | up(&wf_lock); | 224 | mutex_unlock(&wf_lock); |
| 179 | 225 | ||
| 180 | return 0; | 226 | return 0; |
| 181 | } | 227 | } |
| @@ -183,9 +229,9 @@ EXPORT_SYMBOL_GPL(wf_register_control); | |||
| 183 | 229 | ||
| 184 | void wf_unregister_control(struct wf_control *ct) | 230 | void wf_unregister_control(struct wf_control *ct) |
| 185 | { | 231 | { |
| 186 | down(&wf_lock); | 232 | mutex_lock(&wf_lock); |
| 187 | list_del(&ct->link); | 233 | list_del(&ct->link); |
| 188 | up(&wf_lock); | 234 | mutex_unlock(&wf_lock); |
| 189 | 235 | ||
| 190 | DBG("wf: Unregistered control %s\n", ct->name); | 236 | DBG("wf: Unregistered control %s\n", ct->name); |
| 191 | 237 | ||
| @@ -197,16 +243,16 @@ struct wf_control * wf_find_control(const char *name) | |||
| 197 | { | 243 | { |
| 198 | struct wf_control *ct; | 244 | struct wf_control *ct; |
| 199 | 245 | ||
| 200 | down(&wf_lock); | 246 | mutex_lock(&wf_lock); |
| 201 | list_for_each_entry(ct, &wf_controls, link) { | 247 | list_for_each_entry(ct, &wf_controls, link) { |
| 202 | if (!strcmp(ct->name, name)) { | 248 | if (!strcmp(ct->name, name)) { |
| 203 | if (wf_get_control(ct)) | 249 | if (wf_get_control(ct)) |
| 204 | ct = NULL; | 250 | ct = NULL; |
| 205 | up(&wf_lock); | 251 | mutex_unlock(&wf_lock); |
| 206 | return ct; | 252 | return ct; |
| 207 | } | 253 | } |
| 208 | } | 254 | } |
| 209 | up(&wf_lock); | 255 | mutex_unlock(&wf_lock); |
| 210 | return NULL; | 256 | return NULL; |
| 211 | } | 257 | } |
| 212 | EXPORT_SYMBOL_GPL(wf_find_control); | 258 | EXPORT_SYMBOL_GPL(wf_find_control); |
| @@ -246,26 +292,46 @@ static void wf_sensor_release(struct kref *kref) | |||
| 246 | kfree(sr); | 292 | kfree(sr); |
| 247 | } | 293 | } |
| 248 | 294 | ||
| 295 | static ssize_t wf_show_sensor(struct device *dev, | ||
| 296 | struct device_attribute *attr, char *buf) | ||
| 297 | { | ||
| 298 | struct wf_sensor *sens = container_of(attr, struct wf_sensor, attr); | ||
| 299 | s32 val = 0; | ||
| 300 | int err; | ||
| 301 | |||
| 302 | err = sens->ops->get_value(sens, &val); | ||
| 303 | if (err < 0) | ||
| 304 | return err; | ||
| 305 | return sprintf(buf, "%d.%03d\n", FIX32TOPRINT(val)); | ||
| 306 | } | ||
| 307 | |||
| 249 | int wf_register_sensor(struct wf_sensor *new_sr) | 308 | int wf_register_sensor(struct wf_sensor *new_sr) |
| 250 | { | 309 | { |
| 251 | struct wf_sensor *sr; | 310 | struct wf_sensor *sr; |
| 252 | 311 | ||
| 253 | down(&wf_lock); | 312 | mutex_lock(&wf_lock); |
| 254 | list_for_each_entry(sr, &wf_sensors, link) { | 313 | list_for_each_entry(sr, &wf_sensors, link) { |
| 255 | if (!strcmp(sr->name, new_sr->name)) { | 314 | if (!strcmp(sr->name, new_sr->name)) { |
| 256 | printk(KERN_WARNING "windfarm: trying to register" | 315 | printk(KERN_WARNING "windfarm: trying to register" |
| 257 | " duplicate sensor %s\n", sr->name); | 316 | " duplicate sensor %s\n", sr->name); |
| 258 | up(&wf_lock); | 317 | mutex_unlock(&wf_lock); |
| 259 | return -EEXIST; | 318 | return -EEXIST; |
| 260 | } | 319 | } |
| 261 | } | 320 | } |
| 262 | kref_init(&new_sr->ref); | 321 | kref_init(&new_sr->ref); |
| 263 | list_add(&new_sr->link, &wf_sensors); | 322 | list_add(&new_sr->link, &wf_sensors); |
| 264 | 323 | ||
| 324 | new_sr->attr.attr.name = new_sr->name; | ||
| 325 | new_sr->attr.attr.owner = THIS_MODULE; | ||
| 326 | new_sr->attr.attr.mode = 0444; | ||
| 327 | new_sr->attr.show = wf_show_sensor; | ||
| 328 | new_sr->attr.store = NULL; | ||
| 329 | device_create_file(&wf_platform_device.dev, &new_sr->attr); | ||
| 330 | |||
| 265 | DBG("wf: Registered sensor %s\n", new_sr->name); | 331 | DBG("wf: Registered sensor %s\n", new_sr->name); |
| 266 | 332 | ||
| 267 | wf_notify(WF_EVENT_NEW_SENSOR, new_sr); | 333 | wf_notify(WF_EVENT_NEW_SENSOR, new_sr); |
| 268 | up(&wf_lock); | 334 | mutex_unlock(&wf_lock); |
| 269 | 335 | ||
| 270 | return 0; | 336 | return 0; |
| 271 | } | 337 | } |
| @@ -273,9 +339,9 @@ EXPORT_SYMBOL_GPL(wf_register_sensor); | |||
| 273 | 339 | ||
| 274 | void wf_unregister_sensor(struct wf_sensor *sr) | 340 | void wf_unregister_sensor(struct wf_sensor *sr) |
| 275 | { | 341 | { |
| 276 | down(&wf_lock); | 342 | mutex_lock(&wf_lock); |
| 277 | list_del(&sr->link); | 343 | list_del(&sr->link); |
| 278 | up(&wf_lock); | 344 | mutex_unlock(&wf_lock); |
| 279 | 345 | ||
| 280 | DBG("wf: Unregistered sensor %s\n", sr->name); | 346 | DBG("wf: Unregistered sensor %s\n", sr->name); |
| 281 | 347 | ||
| @@ -287,16 +353,16 @@ struct wf_sensor * wf_find_sensor(const char *name) | |||
| 287 | { | 353 | { |
| 288 | struct wf_sensor *sr; | 354 | struct wf_sensor *sr; |
| 289 | 355 | ||
| 290 | down(&wf_lock); | 356 | mutex_lock(&wf_lock); |
| 291 | list_for_each_entry(sr, &wf_sensors, link) { | 357 | list_for_each_entry(sr, &wf_sensors, link) { |
| 292 | if (!strcmp(sr->name, name)) { | 358 | if (!strcmp(sr->name, name)) { |
| 293 | if (wf_get_sensor(sr)) | 359 | if (wf_get_sensor(sr)) |
| 294 | sr = NULL; | 360 | sr = NULL; |
| 295 | up(&wf_lock); | 361 | mutex_unlock(&wf_lock); |
| 296 | return sr; | 362 | return sr; |
| 297 | } | 363 | } |
| 298 | } | 364 | } |
| 299 | up(&wf_lock); | 365 | mutex_unlock(&wf_lock); |
| 300 | return NULL; | 366 | return NULL; |
| 301 | } | 367 | } |
| 302 | EXPORT_SYMBOL_GPL(wf_find_sensor); | 368 | EXPORT_SYMBOL_GPL(wf_find_sensor); |
| @@ -329,7 +395,7 @@ int wf_register_client(struct notifier_block *nb) | |||
| 329 | struct wf_control *ct; | 395 | struct wf_control *ct; |
| 330 | struct wf_sensor *sr; | 396 | struct wf_sensor *sr; |
| 331 | 397 | ||
| 332 | down(&wf_lock); | 398 | mutex_lock(&wf_lock); |
| 333 | rc = notifier_chain_register(&wf_client_list, nb); | 399 | rc = notifier_chain_register(&wf_client_list, nb); |
| 334 | if (rc != 0) | 400 | if (rc != 0) |
| 335 | goto bail; | 401 | goto bail; |
| @@ -341,19 +407,19 @@ int wf_register_client(struct notifier_block *nb) | |||
| 341 | if (wf_client_count == 1) | 407 | if (wf_client_count == 1) |
| 342 | wf_start_thread(); | 408 | wf_start_thread(); |
| 343 | bail: | 409 | bail: |
| 344 | up(&wf_lock); | 410 | mutex_unlock(&wf_lock); |
| 345 | return rc; | 411 | return rc; |
| 346 | } | 412 | } |
| 347 | EXPORT_SYMBOL_GPL(wf_register_client); | 413 | EXPORT_SYMBOL_GPL(wf_register_client); |
| 348 | 414 | ||
| 349 | int wf_unregister_client(struct notifier_block *nb) | 415 | int wf_unregister_client(struct notifier_block *nb) |
| 350 | { | 416 | { |
| 351 | down(&wf_lock); | 417 | mutex_lock(&wf_lock); |
| 352 | notifier_chain_unregister(&wf_client_list, nb); | 418 | notifier_chain_unregister(&wf_client_list, nb); |
| 353 | wf_client_count++; | 419 | wf_client_count++; |
| 354 | if (wf_client_count == 0) | 420 | if (wf_client_count == 0) |
| 355 | wf_stop_thread(); | 421 | wf_stop_thread(); |
| 356 | up(&wf_lock); | 422 | mutex_unlock(&wf_lock); |
| 357 | 423 | ||
| 358 | return 0; | 424 | return 0; |
| 359 | } | 425 | } |
| @@ -361,23 +427,23 @@ EXPORT_SYMBOL_GPL(wf_unregister_client); | |||
| 361 | 427 | ||
| 362 | void wf_set_overtemp(void) | 428 | void wf_set_overtemp(void) |
| 363 | { | 429 | { |
| 364 | down(&wf_lock); | 430 | mutex_lock(&wf_lock); |
| 365 | wf_overtemp++; | 431 | wf_overtemp++; |
| 366 | if (wf_overtemp == 1) { | 432 | if (wf_overtemp == 1) { |
| 367 | printk(KERN_WARNING "windfarm: Overtemp condition detected !\n"); | 433 | printk(KERN_WARNING "windfarm: Overtemp condition detected !\n"); |
| 368 | wf_overtemp_counter = 0; | 434 | wf_overtemp_counter = 0; |
| 369 | wf_notify(WF_EVENT_OVERTEMP, NULL); | 435 | wf_notify(WF_EVENT_OVERTEMP, NULL); |
| 370 | } | 436 | } |
| 371 | up(&wf_lock); | 437 | mutex_unlock(&wf_lock); |
| 372 | } | 438 | } |
| 373 | EXPORT_SYMBOL_GPL(wf_set_overtemp); | 439 | EXPORT_SYMBOL_GPL(wf_set_overtemp); |
| 374 | 440 | ||
| 375 | void wf_clear_overtemp(void) | 441 | void wf_clear_overtemp(void) |
| 376 | { | 442 | { |
| 377 | down(&wf_lock); | 443 | mutex_lock(&wf_lock); |
| 378 | WARN_ON(wf_overtemp == 0); | 444 | WARN_ON(wf_overtemp == 0); |
| 379 | if (wf_overtemp == 0) { | 445 | if (wf_overtemp == 0) { |
| 380 | up(&wf_lock); | 446 | mutex_unlock(&wf_lock); |
| 381 | return; | 447 | return; |
| 382 | } | 448 | } |
| 383 | wf_overtemp--; | 449 | wf_overtemp--; |
| @@ -385,7 +451,7 @@ void wf_clear_overtemp(void) | |||
| 385 | printk(KERN_WARNING "windfarm: Overtemp condition cleared !\n"); | 451 | printk(KERN_WARNING "windfarm: Overtemp condition cleared !\n"); |
| 386 | wf_notify(WF_EVENT_NORMALTEMP, NULL); | 452 | wf_notify(WF_EVENT_NORMALTEMP, NULL); |
| 387 | } | 453 | } |
| 388 | up(&wf_lock); | 454 | mutex_unlock(&wf_lock); |
| 389 | } | 455 | } |
| 390 | EXPORT_SYMBOL_GPL(wf_clear_overtemp); | 456 | EXPORT_SYMBOL_GPL(wf_clear_overtemp); |
| 391 | 457 | ||
| @@ -395,10 +461,6 @@ int wf_is_overtemp(void) | |||
| 395 | } | 461 | } |
| 396 | EXPORT_SYMBOL_GPL(wf_is_overtemp); | 462 | EXPORT_SYMBOL_GPL(wf_is_overtemp); |
| 397 | 463 | ||
| 398 | static struct platform_device wf_platform_device = { | ||
| 399 | .name = "windfarm", | ||
| 400 | }; | ||
| 401 | |||
| 402 | static int __init windfarm_core_init(void) | 464 | static int __init windfarm_core_init(void) |
| 403 | { | 465 | { |
| 404 | DBG("wf: core loaded\n"); | 466 | DBG("wf: core loaded\n"); |
diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c new file mode 100644 index 000000000000..5b9ad6ca7cba --- /dev/null +++ b/drivers/macintosh/windfarm_max6690_sensor.c | |||
| @@ -0,0 +1,169 @@ | |||
| 1 | /* | ||
| 2 | * Windfarm PowerMac thermal control. MAX6690 sensor. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org> | ||
| 5 | * | ||
| 6 | * Use and redistribute under the terms of the GNU GPL v2. | ||
| 7 | */ | ||
| 8 | #include <linux/types.h> | ||
| 9 | #include <linux/errno.h> | ||
| 10 | #include <linux/kernel.h> | ||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/slab.h> | ||
| 13 | #include <linux/i2c.h> | ||
| 14 | #include <linux/i2c-dev.h> | ||
| 15 | #include <asm/prom.h> | ||
| 16 | #include <asm/pmac_low_i2c.h> | ||
| 17 | |||
| 18 | #include "windfarm.h" | ||
| 19 | |||
| 20 | #define VERSION "0.1" | ||
| 21 | |||
| 22 | /* This currently only exports the external temperature sensor, | ||
| 23 | since that's all the control loops need. */ | ||
| 24 | |||
| 25 | /* Some MAX6690 register numbers */ | ||
| 26 | #define MAX6690_INTERNAL_TEMP 0 | ||
| 27 | #define MAX6690_EXTERNAL_TEMP 1 | ||
| 28 | |||
| 29 | struct wf_6690_sensor { | ||
| 30 | struct i2c_client i2c; | ||
| 31 | struct wf_sensor sens; | ||
| 32 | }; | ||
| 33 | |||
| 34 | #define wf_to_6690(x) container_of((x), struct wf_6690_sensor, sens) | ||
| 35 | #define i2c_to_6690(x) container_of((x), struct wf_6690_sensor, i2c) | ||
| 36 | |||
| 37 | static int wf_max6690_attach(struct i2c_adapter *adapter); | ||
| 38 | static int wf_max6690_detach(struct i2c_client *client); | ||
| 39 | |||
| 40 | static struct i2c_driver wf_max6690_driver = { | ||
| 41 | .driver = { | ||
| 42 | .name = "wf_max6690", | ||
| 43 | }, | ||
| 44 | .attach_adapter = wf_max6690_attach, | ||
| 45 | .detach_client = wf_max6690_detach, | ||
| 46 | }; | ||
| 47 | |||
| 48 | static int wf_max6690_get(struct wf_sensor *sr, s32 *value) | ||
| 49 | { | ||
| 50 | struct wf_6690_sensor *max = wf_to_6690(sr); | ||
| 51 | s32 data; | ||
| 52 | |||
| 53 | if (max->i2c.adapter == NULL) | ||
| 54 | return -ENODEV; | ||
| 55 | |||
| 56 | /* chip gets initialized by firmware */ | ||
| 57 | data = i2c_smbus_read_byte_data(&max->i2c, MAX6690_EXTERNAL_TEMP); | ||
| 58 | if (data < 0) | ||
| 59 | return data; | ||
| 60 | *value = data << 16; | ||
| 61 | return 0; | ||
| 62 | } | ||
| 63 | |||
| 64 | static void wf_max6690_release(struct wf_sensor *sr) | ||
| 65 | { | ||
| 66 | struct wf_6690_sensor *max = wf_to_6690(sr); | ||
| 67 | |||
| 68 | if (max->i2c.adapter) { | ||
| 69 | i2c_detach_client(&max->i2c); | ||
| 70 | max->i2c.adapter = NULL; | ||
| 71 | } | ||
| 72 | kfree(max); | ||
| 73 | } | ||
| 74 | |||
| 75 | static struct wf_sensor_ops wf_max6690_ops = { | ||
| 76 | .get_value = wf_max6690_get, | ||
| 77 | .release = wf_max6690_release, | ||
| 78 | .owner = THIS_MODULE, | ||
| 79 | }; | ||
| 80 | |||
| 81 | static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr) | ||
| 82 | { | ||
| 83 | struct wf_6690_sensor *max; | ||
| 84 | char *name = "u4-temp"; | ||
| 85 | |||
| 86 | max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL); | ||
| 87 | if (max == NULL) { | ||
| 88 | printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor %s: " | ||
| 89 | "no memory\n", name); | ||
| 90 | return; | ||
| 91 | } | ||
| 92 | |||
| 93 | max->sens.ops = &wf_max6690_ops; | ||
| 94 | max->sens.name = name; | ||
| 95 | max->i2c.addr = addr >> 1; | ||
| 96 | max->i2c.adapter = adapter; | ||
| 97 | max->i2c.driver = &wf_max6690_driver; | ||
| 98 | strncpy(max->i2c.name, name, I2C_NAME_SIZE-1); | ||
| 99 | |||
| 100 | if (i2c_attach_client(&max->i2c)) { | ||
| 101 | printk(KERN_ERR "windfarm: failed to attach MAX6690 sensor\n"); | ||
| 102 | goto fail; | ||
| 103 | } | ||
| 104 | |||
| 105 | if (wf_register_sensor(&max->sens)) { | ||
| 106 | i2c_detach_client(&max->i2c); | ||
| 107 | goto fail; | ||
| 108 | } | ||
| 109 | |||
| 110 | return; | ||
| 111 | |||
| 112 | fail: | ||
| 113 | kfree(max); | ||
| 114 | } | ||
| 115 | |||
| 116 | static int wf_max6690_attach(struct i2c_adapter *adapter) | ||
| 117 | { | ||
| 118 | struct device_node *busnode, *dev = NULL; | ||
| 119 | struct pmac_i2c_bus *bus; | ||
| 120 | const char *loc; | ||
| 121 | u32 *reg; | ||
| 122 | |||
| 123 | bus = pmac_i2c_adapter_to_bus(adapter); | ||
| 124 | if (bus == NULL) | ||
| 125 | return -ENODEV; | ||
| 126 | busnode = pmac_i2c_get_bus_node(bus); | ||
| 127 | |||
| 128 | while ((dev = of_get_next_child(busnode, dev)) != NULL) { | ||
| 129 | if (!device_is_compatible(dev, "max6690")) | ||
| 130 | continue; | ||
| 131 | loc = get_property(dev, "hwsensor-location", NULL); | ||
| 132 | reg = (u32 *) get_property(dev, "reg", NULL); | ||
| 133 | if (!loc || !reg) | ||
| 134 | continue; | ||
| 135 | printk("found max6690, loc=%s reg=%x\n", loc, *reg); | ||
| 136 | if (strcmp(loc, "BACKSIDE")) | ||
| 137 | continue; | ||
| 138 | wf_max6690_create(adapter, *reg); | ||
| 139 | } | ||
| 140 | |||
| 141 | return 0; | ||
| 142 | } | ||
| 143 | |||
| 144 | static int wf_max6690_detach(struct i2c_client *client) | ||
| 145 | { | ||
| 146 | struct wf_6690_sensor *max = i2c_to_6690(client); | ||
| 147 | |||
| 148 | max->i2c.adapter = NULL; | ||
| 149 | wf_unregister_sensor(&max->sens); | ||
| 150 | |||
| 151 | return 0; | ||
| 152 | } | ||
| 153 | |||
| 154 | static int __init wf_max6690_sensor_init(void) | ||
| 155 | { | ||
| 156 | return i2c_add_driver(&wf_max6690_driver); | ||
| 157 | } | ||
| 158 | |||
| 159 | static void __exit wf_max6690_sensor_exit(void) | ||
| 160 | { | ||
| 161 | i2c_del_driver(&wf_max6690_driver); | ||
| 162 | } | ||
| 163 | |||
| 164 | module_init(wf_max6690_sensor_init); | ||
| 165 | module_exit(wf_max6690_sensor_exit); | ||
| 166 | |||
| 167 | MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>"); | ||
| 168 | MODULE_DESCRIPTION("MAX6690 sensor objects for PowerMac thermal control"); | ||
| 169 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/macintosh/windfarm_pid.c b/drivers/macintosh/windfarm_pid.c index 2e803b368757..0842432e27ad 100644 --- a/drivers/macintosh/windfarm_pid.c +++ b/drivers/macintosh/windfarm_pid.c | |||
| @@ -88,8 +88,8 @@ EXPORT_SYMBOL_GPL(wf_cpu_pid_init); | |||
| 88 | 88 | ||
| 89 | s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp) | 89 | s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp) |
| 90 | { | 90 | { |
| 91 | s64 error, integ, deriv, prop; | 91 | s64 integ, deriv, prop; |
| 92 | s32 target, sval, adj; | 92 | s32 error, target, sval, adj; |
| 93 | int i, hlen = st->param.history_len; | 93 | int i, hlen = st->param.history_len; |
| 94 | 94 | ||
| 95 | /* Calculate error term */ | 95 | /* Calculate error term */ |
| @@ -117,7 +117,7 @@ s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp) | |||
| 117 | integ += st->errors[(st->index + hlen - i) % hlen]; | 117 | integ += st->errors[(st->index + hlen - i) % hlen]; |
| 118 | integ *= st->param.interval; | 118 | integ *= st->param.interval; |
| 119 | integ *= st->param.gr; | 119 | integ *= st->param.gr; |
| 120 | sval = st->param.tmax - ((integ >> 20) & 0xffffffff); | 120 | sval = st->param.tmax - (s32)(integ >> 20); |
| 121 | adj = min(st->param.ttarget, sval); | 121 | adj = min(st->param.ttarget, sval); |
| 122 | 122 | ||
| 123 | DBG("integ: %lx, sval: %lx, adj: %lx\n", integ, sval, adj); | 123 | DBG("integ: %lx, sval: %lx, adj: %lx\n", integ, sval, adj); |
| @@ -129,7 +129,7 @@ s32 wf_cpu_pid_run(struct wf_cpu_pid_state *st, s32 new_power, s32 new_temp) | |||
| 129 | deriv *= st->param.gd; | 129 | deriv *= st->param.gd; |
| 130 | 130 | ||
| 131 | /* Calculate proportional term */ | 131 | /* Calculate proportional term */ |
| 132 | prop = (new_temp - adj); | 132 | prop = st->last_delta = (new_temp - adj); |
| 133 | prop *= st->param.gp; | 133 | prop *= st->param.gp; |
| 134 | 134 | ||
| 135 | DBG("deriv: %lx, prop: %lx\n", deriv, prop); | 135 | DBG("deriv: %lx, prop: %lx\n", deriv, prop); |
diff --git a/drivers/macintosh/windfarm_pid.h b/drivers/macintosh/windfarm_pid.h index a364c2a2499c..bbccc22d42b8 100644 --- a/drivers/macintosh/windfarm_pid.h +++ b/drivers/macintosh/windfarm_pid.h | |||
| @@ -72,6 +72,7 @@ struct wf_cpu_pid_state { | |||
| 72 | int index; /* index of current power */ | 72 | int index; /* index of current power */ |
| 73 | int tindex; /* index of current temp */ | 73 | int tindex; /* index of current temp */ |
| 74 | s32 target; /* current target value */ | 74 | s32 target; /* current target value */ |
| 75 | s32 last_delta; /* last Tactual - Ttarget */ | ||
| 75 | s32 powers[WF_PID_MAX_HISTORY]; /* power history buffer */ | 76 | s32 powers[WF_PID_MAX_HISTORY]; /* power history buffer */ |
| 76 | s32 errors[WF_PID_MAX_HISTORY]; /* error history buffer */ | 77 | s32 errors[WF_PID_MAX_HISTORY]; /* error history buffer */ |
| 77 | s32 temps[2]; /* temp. history buffer */ | 78 | s32 temps[2]; /* temp. history buffer */ |
diff --git a/drivers/macintosh/windfarm_pm112.c b/drivers/macintosh/windfarm_pm112.c new file mode 100644 index 000000000000..c2a4e689c784 --- /dev/null +++ b/drivers/macintosh/windfarm_pm112.c | |||
| @@ -0,0 +1,698 @@ | |||
| 1 | /* | ||
| 2 | * Windfarm PowerMac thermal control. | ||
| 3 | * Control loops for machines with SMU and PPC970MP processors. | ||
| 4 | * | ||
| 5 | * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org> | ||
| 6 | * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp. | ||
| 7 | * | ||
| 8 | * Use and redistribute under the terms of the GNU GPL v2. | ||
| 9 | */ | ||
| 10 | #include <linux/types.h> | ||
| 11 | #include <linux/errno.h> | ||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/device.h> | ||
| 14 | #include <linux/platform_device.h> | ||
| 15 | #include <linux/reboot.h> | ||
| 16 | #include <asm/prom.h> | ||
| 17 | #include <asm/smu.h> | ||
| 18 | |||
| 19 | #include "windfarm.h" | ||
| 20 | #include "windfarm_pid.h" | ||
| 21 | |||
| 22 | #define VERSION "0.2" | ||
| 23 | |||
| 24 | #define DEBUG | ||
| 25 | #undef LOTSA_DEBUG | ||
| 26 | |||
| 27 | #ifdef DEBUG | ||
| 28 | #define DBG(args...) printk(args) | ||
| 29 | #else | ||
| 30 | #define DBG(args...) do { } while(0) | ||
| 31 | #endif | ||
| 32 | |||
| 33 | #ifdef LOTSA_DEBUG | ||
| 34 | #define DBG_LOTS(args...) printk(args) | ||
| 35 | #else | ||
| 36 | #define DBG_LOTS(args...) do { } while(0) | ||
| 37 | #endif | ||
| 38 | |||
| 39 | /* define this to force CPU overtemp to 60 degree, useful for testing | ||
| 40 | * the overtemp code | ||
| 41 | */ | ||
| 42 | #undef HACKED_OVERTEMP | ||
| 43 | |||
| 44 | /* We currently only handle 2 chips, 4 cores... */ | ||
| 45 | #define NR_CHIPS 2 | ||
| 46 | #define NR_CORES 4 | ||
| 47 | #define NR_CPU_FANS 3 * NR_CHIPS | ||
| 48 | |||
| 49 | /* Controls and sensors */ | ||
| 50 | static struct wf_sensor *sens_cpu_temp[NR_CORES]; | ||
| 51 | static struct wf_sensor *sens_cpu_power[NR_CORES]; | ||
| 52 | static struct wf_sensor *hd_temp; | ||
| 53 | static struct wf_sensor *slots_power; | ||
| 54 | static struct wf_sensor *u4_temp; | ||
| 55 | |||
| 56 | static struct wf_control *cpu_fans[NR_CPU_FANS]; | ||
| 57 | static char *cpu_fan_names[NR_CPU_FANS] = { | ||
| 58 | "cpu-rear-fan-0", | ||
| 59 | "cpu-rear-fan-1", | ||
| 60 | "cpu-front-fan-0", | ||
| 61 | "cpu-front-fan-1", | ||
| 62 | "cpu-pump-0", | ||
| 63 | "cpu-pump-1", | ||
| 64 | }; | ||
| 65 | static struct wf_control *cpufreq_clamp; | ||
| 66 | |||
| 67 | /* Second pump isn't required (and isn't actually present) */ | ||
| 68 | #define CPU_FANS_REQD (NR_CPU_FANS - 2) | ||
| 69 | #define FIRST_PUMP 4 | ||
| 70 | #define LAST_PUMP 5 | ||
| 71 | |||
| 72 | /* We keep a temperature history for average calculation of 180s */ | ||
| 73 | #define CPU_TEMP_HIST_SIZE 180 | ||
| 74 | |||
| 75 | /* Scale factor for fan speed, *100 */ | ||
| 76 | static int cpu_fan_scale[NR_CPU_FANS] = { | ||
| 77 | 100, | ||
| 78 | 100, | ||
| 79 | 97, /* inlet fans run at 97% of exhaust fan */ | ||
| 80 | 97, | ||
| 81 | 100, /* updated later */ | ||
| 82 | 100, /* updated later */ | ||
| 83 | }; | ||
| 84 | |||
| 85 | static struct wf_control *backside_fan; | ||
| 86 | static struct wf_control *slots_fan; | ||
| 87 | static struct wf_control *drive_bay_fan; | ||
| 88 | |||
| 89 | /* PID loop state */ | ||
| 90 | static struct wf_cpu_pid_state cpu_pid[NR_CORES]; | ||
| 91 | static u32 cpu_thist[CPU_TEMP_HIST_SIZE]; | ||
| 92 | static int cpu_thist_pt; | ||
| 93 | static s64 cpu_thist_total; | ||
| 94 | static s32 cpu_all_tmax = 100 << 16; | ||
| 95 | static int cpu_last_target; | ||
| 96 | static struct wf_pid_state backside_pid; | ||
| 97 | static int backside_tick; | ||
| 98 | static struct wf_pid_state slots_pid; | ||
| 99 | static int slots_started; | ||
| 100 | static struct wf_pid_state drive_bay_pid; | ||
| 101 | static int drive_bay_tick; | ||
| 102 | |||
| 103 | static int nr_cores; | ||
| 104 | static int have_all_controls; | ||
| 105 | static int have_all_sensors; | ||
| 106 | static int started; | ||
| 107 | |||
| 108 | static int failure_state; | ||
| 109 | #define FAILURE_SENSOR 1 | ||
| 110 | #define FAILURE_FAN 2 | ||
| 111 | #define FAILURE_PERM 4 | ||
| 112 | #define FAILURE_LOW_OVERTEMP 8 | ||
| 113 | #define FAILURE_HIGH_OVERTEMP 16 | ||
| 114 | |||
| 115 | /* Overtemp values */ | ||
| 116 | #define LOW_OVER_AVERAGE 0 | ||
| 117 | #define LOW_OVER_IMMEDIATE (10 << 16) | ||
| 118 | #define LOW_OVER_CLEAR ((-10) << 16) | ||
| 119 | #define HIGH_OVER_IMMEDIATE (14 << 16) | ||
| 120 | #define HIGH_OVER_AVERAGE (10 << 16) | ||
| 121 | #define HIGH_OVER_IMMEDIATE (14 << 16) | ||
| 122 | |||
| 123 | |||
| 124 | /* Implementation... */ | ||
| 125 | static int create_cpu_loop(int cpu) | ||
| 126 | { | ||
| 127 | int chip = cpu / 2; | ||
| 128 | int core = cpu & 1; | ||
| 129 | struct smu_sdbp_header *hdr; | ||
| 130 | struct smu_sdbp_cpupiddata *piddata; | ||
| 131 | struct wf_cpu_pid_param pid; | ||
| 132 | struct wf_control *main_fan = cpu_fans[0]; | ||
| 133 | s32 tmax; | ||
| 134 | int fmin; | ||
| 135 | |||
| 136 | /* Get PID params from the appropriate SAT */ | ||
| 137 | hdr = smu_sat_get_sdb_partition(chip, 0xC8 + core, NULL); | ||
| 138 | if (hdr == NULL) { | ||
| 139 | printk(KERN_WARNING"windfarm: can't get CPU PID fan config\n"); | ||
| 140 | return -EINVAL; | ||
| 141 | } | ||
| 142 | piddata = (struct smu_sdbp_cpupiddata *)&hdr[1]; | ||
| 143 | |||
| 144 | /* Get FVT params to get Tmax; if not found, assume default */ | ||
| 145 | hdr = smu_sat_get_sdb_partition(chip, 0xC4 + core, NULL); | ||
| 146 | if (hdr) { | ||
| 147 | struct smu_sdbp_fvt *fvt = (struct smu_sdbp_fvt *)&hdr[1]; | ||
| 148 | tmax = fvt->maxtemp << 16; | ||
| 149 | } else | ||
| 150 | tmax = 95 << 16; /* default to 95 degrees C */ | ||
| 151 | |||
| 152 | /* We keep a global tmax for overtemp calculations */ | ||
| 153 | if (tmax < cpu_all_tmax) | ||
| 154 | cpu_all_tmax = tmax; | ||
| 155 | |||
| 156 | /* | ||
| 157 | * Darwin has a minimum fan speed of 1000 rpm for the 4-way and | ||
| 158 | * 515 for the 2-way. That appears to be overkill, so for now, | ||
| 159 | * impose a minimum of 750 or 515. | ||
| 160 | */ | ||
| 161 | fmin = (nr_cores > 2) ? 750 : 515; | ||
| 162 | |||
| 163 | /* Initialize PID loop */ | ||
| 164 | pid.interval = 1; /* seconds */ | ||
| 165 | pid.history_len = piddata->history_len; | ||
| 166 | pid.gd = piddata->gd; | ||
| 167 | pid.gp = piddata->gp; | ||
| 168 | pid.gr = piddata->gr / piddata->history_len; | ||
| 169 | pid.pmaxadj = (piddata->max_power << 16) - (piddata->power_adj << 8); | ||
| 170 | pid.ttarget = tmax - (piddata->target_temp_delta << 16); | ||
| 171 | pid.tmax = tmax; | ||
| 172 | pid.min = main_fan->ops->get_min(main_fan); | ||
| 173 | pid.max = main_fan->ops->get_max(main_fan); | ||
| 174 | if (pid.min < fmin) | ||
| 175 | pid.min = fmin; | ||
| 176 | |||
| 177 | wf_cpu_pid_init(&cpu_pid[cpu], &pid); | ||
| 178 | return 0; | ||
| 179 | } | ||
| 180 | |||
| 181 | static void cpu_max_all_fans(void) | ||
| 182 | { | ||
| 183 | int i; | ||
| 184 | |||
| 185 | /* We max all CPU fans in case of a sensor error. We also do the | ||
| 186 | * cpufreq clamping now, even if it's supposedly done later by the | ||
| 187 | * generic code anyway, we do it earlier here to react faster | ||
| 188 | */ | ||
| 189 | if (cpufreq_clamp) | ||
| 190 | wf_control_set_max(cpufreq_clamp); | ||
| 191 | for (i = 0; i < NR_CPU_FANS; ++i) | ||
| 192 | if (cpu_fans[i]) | ||
| 193 | wf_control_set_max(cpu_fans[i]); | ||
| 194 | } | ||
| 195 | |||
| 196 | static int cpu_check_overtemp(s32 temp) | ||
| 197 | { | ||
| 198 | int new_state = 0; | ||
| 199 | s32 t_avg, t_old; | ||
| 200 | |||
| 201 | /* First check for immediate overtemps */ | ||
| 202 | if (temp >= (cpu_all_tmax + LOW_OVER_IMMEDIATE)) { | ||
| 203 | new_state |= FAILURE_LOW_OVERTEMP; | ||
| 204 | if ((failure_state & FAILURE_LOW_OVERTEMP) == 0) | ||
| 205 | printk(KERN_ERR "windfarm: Overtemp due to immediate CPU" | ||
| 206 | " temperature !\n"); | ||
| 207 | } | ||
| 208 | if (temp >= (cpu_all_tmax + HIGH_OVER_IMMEDIATE)) { | ||
| 209 | new_state |= FAILURE_HIGH_OVERTEMP; | ||
| 210 | if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0) | ||
| 211 | printk(KERN_ERR "windfarm: Critical overtemp due to" | ||
| 212 | " immediate CPU temperature !\n"); | ||
| 213 | } | ||
| 214 | |||
| 215 | /* We calculate a history of max temperatures and use that for the | ||
| 216 | * overtemp management | ||
| 217 | */ | ||
| 218 | t_old = cpu_thist[cpu_thist_pt]; | ||
| 219 | cpu_thist[cpu_thist_pt] = temp; | ||
| 220 | cpu_thist_pt = (cpu_thist_pt + 1) % CPU_TEMP_HIST_SIZE; | ||
| 221 | cpu_thist_total -= t_old; | ||
| 222 | cpu_thist_total += temp; | ||
| 223 | t_avg = cpu_thist_total / CPU_TEMP_HIST_SIZE; | ||
| 224 | |||
| 225 | DBG_LOTS("t_avg = %d.%03d (out: %d.%03d, in: %d.%03d)\n", | ||
| 226 | FIX32TOPRINT(t_avg), FIX32TOPRINT(t_old), FIX32TOPRINT(temp)); | ||
| 227 | |||
| 228 | /* Now check for average overtemps */ | ||
| 229 | if (t_avg >= (cpu_all_tmax + LOW_OVER_AVERAGE)) { | ||
| 230 | new_state |= FAILURE_LOW_OVERTEMP; | ||
| 231 | if ((failure_state & FAILURE_LOW_OVERTEMP) == 0) | ||
| 232 | printk(KERN_ERR "windfarm: Overtemp due to average CPU" | ||
| 233 | " temperature !\n"); | ||
| 234 | } | ||
| 235 | if (t_avg >= (cpu_all_tmax + HIGH_OVER_AVERAGE)) { | ||
| 236 | new_state |= FAILURE_HIGH_OVERTEMP; | ||
| 237 | if ((failure_state & FAILURE_HIGH_OVERTEMP) == 0) | ||
| 238 | printk(KERN_ERR "windfarm: Critical overtemp due to" | ||
| 239 | " average CPU temperature !\n"); | ||
| 240 | } | ||
| 241 | |||
| 242 | /* Now handle overtemp conditions. We don't currently use the windfarm | ||
| 243 | * overtemp handling core as it's not fully suited to the needs of those | ||
| 244 | * new machine. This will be fixed later. | ||
| 245 | */ | ||
| 246 | if (new_state) { | ||
| 247 | /* High overtemp -> immediate shutdown */ | ||
| 248 | if (new_state & FAILURE_HIGH_OVERTEMP) | ||
| 249 | machine_power_off(); | ||
| 250 | if ((failure_state & new_state) != new_state) | ||
| 251 | cpu_max_all_fans(); | ||
| 252 | failure_state |= new_state; | ||
| 253 | } else if ((failure_state & FAILURE_LOW_OVERTEMP) && | ||
| 254 | (temp < (cpu_all_tmax + LOW_OVER_CLEAR))) { | ||
| 255 | printk(KERN_ERR "windfarm: Overtemp condition cleared !\n"); | ||
| 256 | failure_state &= ~FAILURE_LOW_OVERTEMP; | ||
| 257 | } | ||
| 258 | |||
| 259 | return failure_state & (FAILURE_LOW_OVERTEMP | FAILURE_HIGH_OVERTEMP); | ||
| 260 | } | ||
| 261 | |||
| 262 | static void cpu_fans_tick(void) | ||
| 263 | { | ||
| 264 | int err, cpu; | ||
| 265 | s32 greatest_delta = 0; | ||
| 266 | s32 temp, power, t_max = 0; | ||
| 267 | int i, t, target = 0; | ||
| 268 | struct wf_sensor *sr; | ||
| 269 | struct wf_control *ct; | ||
| 270 | struct wf_cpu_pid_state *sp; | ||
| 271 | |||
| 272 | DBG_LOTS(KERN_DEBUG); | ||
| 273 | for (cpu = 0; cpu < nr_cores; ++cpu) { | ||
| 274 | /* Get CPU core temperature */ | ||
| 275 | sr = sens_cpu_temp[cpu]; | ||
| 276 | err = sr->ops->get_value(sr, &temp); | ||
| 277 | if (err) { | ||
| 278 | DBG("\n"); | ||
| 279 | printk(KERN_WARNING "windfarm: CPU %d temperature " | ||
| 280 | "sensor error %d\n", cpu, err); | ||
| 281 | failure_state |= FAILURE_SENSOR; | ||
| 282 | cpu_max_all_fans(); | ||
| 283 | return; | ||
| 284 | } | ||
| 285 | |||
| 286 | /* Keep track of highest temp */ | ||
| 287 | t_max = max(t_max, temp); | ||
| 288 | |||
| 289 | /* Get CPU power */ | ||
| 290 | sr = sens_cpu_power[cpu]; | ||
| 291 | err = sr->ops->get_value(sr, &power); | ||
| 292 | if (err) { | ||
| 293 | DBG("\n"); | ||
| 294 | printk(KERN_WARNING "windfarm: CPU %d power " | ||
| 295 | "sensor error %d\n", cpu, err); | ||
| 296 | failure_state |= FAILURE_SENSOR; | ||
| 297 | cpu_max_all_fans(); | ||
| 298 | return; | ||
| 299 | } | ||
| 300 | |||
| 301 | /* Run PID */ | ||
| 302 | sp = &cpu_pid[cpu]; | ||
| 303 | t = wf_cpu_pid_run(sp, power, temp); | ||
| 304 | |||
| 305 | if (cpu == 0 || sp->last_delta > greatest_delta) { | ||
| 306 | greatest_delta = sp->last_delta; | ||
| 307 | target = t; | ||
| 308 | } | ||
| 309 | DBG_LOTS("[%d] P=%d.%.3d T=%d.%.3d ", | ||
| 310 | cpu, FIX32TOPRINT(power), FIX32TOPRINT(temp)); | ||
| 311 | } | ||
| 312 | DBG_LOTS("fans = %d, t_max = %d.%03d\n", target, FIX32TOPRINT(t_max)); | ||
| 313 | |||
| 314 | /* Darwin limits decrease to 20 per iteration */ | ||
| 315 | if (target < (cpu_last_target - 20)) | ||
| 316 | target = cpu_last_target - 20; | ||
| 317 | cpu_last_target = target; | ||
| 318 | for (cpu = 0; cpu < nr_cores; ++cpu) | ||
| 319 | cpu_pid[cpu].target = target; | ||
| 320 | |||
| 321 | /* Handle possible overtemps */ | ||
| 322 | if (cpu_check_overtemp(t_max)) | ||
| 323 | return; | ||
| 324 | |||
| 325 | /* Set fans */ | ||
| 326 | for (i = 0; i < NR_CPU_FANS; ++i) { | ||
| 327 | ct = cpu_fans[i]; | ||
| 328 | if (ct == NULL) | ||
| 329 | continue; | ||
| 330 | err = ct->ops->set_value(ct, target * cpu_fan_scale[i] / 100); | ||
| 331 | if (err) { | ||
| 332 | printk(KERN_WARNING "windfarm: fan %s reports " | ||
| 333 | "error %d\n", ct->name, err); | ||
| 334 | failure_state |= FAILURE_FAN; | ||
| 335 | break; | ||
| 336 | } | ||
| 337 | } | ||
| 338 | } | ||
| 339 | |||
| 340 | /* Backside/U4 fan */ | ||
| 341 | static struct wf_pid_param backside_param = { | ||
| 342 | .interval = 5, | ||
| 343 | .history_len = 2, | ||
| 344 | .gd = 48 << 20, | ||
| 345 | .gp = 5 << 20, | ||
| 346 | .gr = 0, | ||
| 347 | .itarget = 64 << 16, | ||
| 348 | .additive = 1, | ||
| 349 | }; | ||
| 350 | |||
| 351 | static void backside_fan_tick(void) | ||
| 352 | { | ||
| 353 | s32 temp; | ||
| 354 | int speed; | ||
| 355 | int err; | ||
| 356 | |||
| 357 | if (!backside_fan || !u4_temp) | ||
| 358 | return; | ||
| 359 | if (!backside_tick) { | ||
| 360 | /* first time; initialize things */ | ||
| 361 | backside_param.min = backside_fan->ops->get_min(backside_fan); | ||
| 362 | backside_param.max = backside_fan->ops->get_max(backside_fan); | ||
| 363 | wf_pid_init(&backside_pid, &backside_param); | ||
| 364 | backside_tick = 1; | ||
| 365 | } | ||
| 366 | if (--backside_tick > 0) | ||
| 367 | return; | ||
| 368 | backside_tick = backside_pid.param.interval; | ||
| 369 | |||
| 370 | err = u4_temp->ops->get_value(u4_temp, &temp); | ||
| 371 | if (err) { | ||
| 372 | printk(KERN_WARNING "windfarm: U4 temp sensor error %d\n", | ||
| 373 | err); | ||
| 374 | failure_state |= FAILURE_SENSOR; | ||
| 375 | wf_control_set_max(backside_fan); | ||
| 376 | return; | ||
| 377 | } | ||
| 378 | speed = wf_pid_run(&backside_pid, temp); | ||
| 379 | DBG_LOTS("backside PID temp=%d.%.3d speed=%d\n", | ||
| 380 | FIX32TOPRINT(temp), speed); | ||
| 381 | |||
| 382 | err = backside_fan->ops->set_value(backside_fan, speed); | ||
| 383 | if (err) { | ||
| 384 | printk(KERN_WARNING "windfarm: backside fan error %d\n", err); | ||
| 385 | failure_state |= FAILURE_FAN; | ||
| 386 | } | ||
| 387 | } | ||
| 388 | |||
| 389 | /* Drive bay fan */ | ||
| 390 | static struct wf_pid_param drive_bay_prm = { | ||
| 391 | .interval = 5, | ||
| 392 | .history_len = 2, | ||
| 393 | .gd = 30 << 20, | ||
| 394 | .gp = 5 << 20, | ||
| 395 | .gr = 0, | ||
| 396 | .itarget = 40 << 16, | ||
| 397 | .additive = 1, | ||
| 398 | }; | ||
| 399 | |||
| 400 | static void drive_bay_fan_tick(void) | ||
| 401 | { | ||
| 402 | s32 temp; | ||
| 403 | int speed; | ||
| 404 | int err; | ||
| 405 | |||
| 406 | if (!drive_bay_fan || !hd_temp) | ||
| 407 | return; | ||
| 408 | if (!drive_bay_tick) { | ||
| 409 | /* first time; initialize things */ | ||
| 410 | drive_bay_prm.min = drive_bay_fan->ops->get_min(drive_bay_fan); | ||
| 411 | drive_bay_prm.max = drive_bay_fan->ops->get_max(drive_bay_fan); | ||
| 412 | wf_pid_init(&drive_bay_pid, &drive_bay_prm); | ||
| 413 | drive_bay_tick = 1; | ||
| 414 | } | ||
| 415 | if (--drive_bay_tick > 0) | ||
| 416 | return; | ||
| 417 | drive_bay_tick = drive_bay_pid.param.interval; | ||
| 418 | |||
| 419 | err = hd_temp->ops->get_value(hd_temp, &temp); | ||
| 420 | if (err) { | ||
| 421 | printk(KERN_WARNING "windfarm: drive bay temp sensor " | ||
| 422 | "error %d\n", err); | ||
| 423 | failure_state |= FAILURE_SENSOR; | ||
| 424 | wf_control_set_max(drive_bay_fan); | ||
| 425 | return; | ||
| 426 | } | ||
| 427 | speed = wf_pid_run(&drive_bay_pid, temp); | ||
| 428 | DBG_LOTS("drive_bay PID temp=%d.%.3d speed=%d\n", | ||
| 429 | FIX32TOPRINT(temp), speed); | ||
| 430 | |||
| 431 | err = drive_bay_fan->ops->set_value(drive_bay_fan, speed); | ||
| 432 | if (err) { | ||
| 433 | printk(KERN_WARNING "windfarm: drive bay fan error %d\n", err); | ||
| 434 | failure_state |= FAILURE_FAN; | ||
| 435 | } | ||
| 436 | } | ||
| 437 | |||
| 438 | /* PCI slots area fan */ | ||
| 439 | /* This makes the fan speed proportional to the power consumed */ | ||
| 440 | static struct wf_pid_param slots_param = { | ||
| 441 | .interval = 1, | ||
| 442 | .history_len = 2, | ||
| 443 | .gd = 0, | ||
| 444 | .gp = 0, | ||
| 445 | .gr = 0x1277952, | ||
| 446 | .itarget = 0, | ||
| 447 | .min = 1560, | ||
| 448 | .max = 3510, | ||
| 449 | }; | ||
| 450 | |||
| 451 | static void slots_fan_tick(void) | ||
| 452 | { | ||
| 453 | s32 power; | ||
| 454 | int speed; | ||
| 455 | int err; | ||
| 456 | |||
| 457 | if (!slots_fan || !slots_power) | ||
| 458 | return; | ||
| 459 | if (!slots_started) { | ||
| 460 | /* first time; initialize things */ | ||
| 461 | wf_pid_init(&slots_pid, &slots_param); | ||
| 462 | slots_started = 1; | ||
| 463 | } | ||
| 464 | |||
| 465 | err = slots_power->ops->get_value(slots_power, &power); | ||
| 466 | if (err) { | ||
| 467 | printk(KERN_WARNING "windfarm: slots power sensor error %d\n", | ||
| 468 | err); | ||
| 469 | failure_state |= FAILURE_SENSOR; | ||
| 470 | wf_control_set_max(slots_fan); | ||
| 471 | return; | ||
| 472 | } | ||
| 473 | speed = wf_pid_run(&slots_pid, power); | ||
| 474 | DBG_LOTS("slots PID power=%d.%.3d speed=%d\n", | ||
| 475 | FIX32TOPRINT(power), speed); | ||
| 476 | |||
| 477 | err = slots_fan->ops->set_value(slots_fan, speed); | ||
| 478 | if (err) { | ||
| 479 | printk(KERN_WARNING "windfarm: slots fan error %d\n", err); | ||
| 480 | failure_state |= FAILURE_FAN; | ||
| 481 | } | ||
| 482 | } | ||
| 483 | |||
| 484 | static void set_fail_state(void) | ||
| 485 | { | ||
| 486 | int i; | ||
| 487 | |||
| 488 | if (cpufreq_clamp) | ||
| 489 | wf_control_set_max(cpufreq_clamp); | ||
| 490 | for (i = 0; i < NR_CPU_FANS; ++i) | ||
| 491 | if (cpu_fans[i]) | ||
| 492 | wf_control_set_max(cpu_fans[i]); | ||
| 493 | if (backside_fan) | ||
| 494 | wf_control_set_max(backside_fan); | ||
| 495 | if (slots_fan) | ||
| 496 | wf_control_set_max(slots_fan); | ||
| 497 | if (drive_bay_fan) | ||
| 498 | wf_control_set_max(drive_bay_fan); | ||
| 499 | } | ||
| 500 | |||
| 501 | static void pm112_tick(void) | ||
| 502 | { | ||
| 503 | int i, last_failure; | ||
| 504 | |||
| 505 | if (!started) { | ||
| 506 | started = 1; | ||
| 507 | for (i = 0; i < nr_cores; ++i) { | ||
| 508 | if (create_cpu_loop(i) < 0) { | ||
| 509 | failure_state = FAILURE_PERM; | ||
| 510 | set_fail_state(); | ||
| 511 | break; | ||
| 512 | } | ||
| 513 | } | ||
| 514 | DBG_LOTS("cpu_all_tmax=%d.%03d\n", FIX32TOPRINT(cpu_all_tmax)); | ||
| 515 | |||
| 516 | #ifdef HACKED_OVERTEMP | ||
| 517 | cpu_all_tmax = 60 << 16; | ||
| 518 | #endif | ||
| 519 | } | ||
| 520 | |||
| 521 | /* Permanent failure, bail out */ | ||
| 522 | if (failure_state & FAILURE_PERM) | ||
| 523 | return; | ||
| 524 | /* Clear all failure bits except low overtemp which will be eventually | ||
| 525 | * cleared by the control loop itself | ||
| 526 | */ | ||
| 527 | last_failure = failure_state; | ||
| 528 | failure_state &= FAILURE_LOW_OVERTEMP; | ||
| 529 | cpu_fans_tick(); | ||
| 530 | backside_fan_tick(); | ||
| 531 | slots_fan_tick(); | ||
| 532 | drive_bay_fan_tick(); | ||
| 533 | |||
| 534 | DBG_LOTS("last_failure: 0x%x, failure_state: %x\n", | ||
| 535 | last_failure, failure_state); | ||
| 536 | |||
| 537 | /* Check for failures. Any failure causes cpufreq clamping */ | ||
| 538 | if (failure_state && last_failure == 0 && cpufreq_clamp) | ||
| 539 | wf_control_set_max(cpufreq_clamp); | ||
| 540 | if (failure_state == 0 && last_failure && cpufreq_clamp) | ||
| 541 | wf_control_set_min(cpufreq_clamp); | ||
| 542 | |||
| 543 | /* That's it for now, we might want to deal with other failures | ||
| 544 | * differently in the future though | ||
| 545 | */ | ||
| 546 | } | ||
| 547 | |||
| 548 | static void pm112_new_control(struct wf_control *ct) | ||
| 549 | { | ||
| 550 | int i, max_exhaust; | ||
| 551 | |||
| 552 | if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) { | ||
| 553 | if (wf_get_control(ct) == 0) | ||
| 554 | cpufreq_clamp = ct; | ||
| 555 | } | ||
| 556 | |||
| 557 | for (i = 0; i < NR_CPU_FANS; ++i) { | ||
| 558 | if (!strcmp(ct->name, cpu_fan_names[i])) { | ||
| 559 | if (cpu_fans[i] == NULL && wf_get_control(ct) == 0) | ||
| 560 | cpu_fans[i] = ct; | ||
| 561 | break; | ||
| 562 | } | ||
| 563 | } | ||
| 564 | if (i >= NR_CPU_FANS) { | ||
| 565 | /* not a CPU fan, try the others */ | ||
| 566 | if (!strcmp(ct->name, "backside-fan")) { | ||
| 567 | if (backside_fan == NULL && wf_get_control(ct) == 0) | ||
| 568 | backside_fan = ct; | ||
| 569 | } else if (!strcmp(ct->name, "slots-fan")) { | ||
| 570 | if (slots_fan == NULL && wf_get_control(ct) == 0) | ||
| 571 | slots_fan = ct; | ||
| 572 | } else if (!strcmp(ct->name, "drive-bay-fan")) { | ||
| 573 | if (drive_bay_fan == NULL && wf_get_control(ct) == 0) | ||
| 574 | drive_bay_fan = ct; | ||
| 575 | } | ||
| 576 | return; | ||
| 577 | } | ||
| 578 | |||
| 579 | for (i = 0; i < CPU_FANS_REQD; ++i) | ||
| 580 | if (cpu_fans[i] == NULL) | ||
| 581 | return; | ||
| 582 | |||
| 583 | /* work out pump scaling factors */ | ||
| 584 | max_exhaust = cpu_fans[0]->ops->get_max(cpu_fans[0]); | ||
| 585 | for (i = FIRST_PUMP; i <= LAST_PUMP; ++i) | ||
| 586 | if ((ct = cpu_fans[i]) != NULL) | ||
| 587 | cpu_fan_scale[i] = | ||
| 588 | ct->ops->get_max(ct) * 100 / max_exhaust; | ||
| 589 | |||
| 590 | have_all_controls = 1; | ||
| 591 | } | ||
| 592 | |||
| 593 | static void pm112_new_sensor(struct wf_sensor *sr) | ||
| 594 | { | ||
| 595 | unsigned int i; | ||
| 596 | |||
| 597 | if (have_all_sensors) | ||
| 598 | return; | ||
| 599 | if (!strncmp(sr->name, "cpu-temp-", 9)) { | ||
| 600 | i = sr->name[9] - '0'; | ||
| 601 | if (sr->name[10] == 0 && i < NR_CORES && | ||
| 602 | sens_cpu_temp[i] == NULL && wf_get_sensor(sr) == 0) | ||
| 603 | sens_cpu_temp[i] = sr; | ||
| 604 | |||
| 605 | } else if (!strncmp(sr->name, "cpu-power-", 10)) { | ||
| 606 | i = sr->name[10] - '0'; | ||
| 607 | if (sr->name[11] == 0 && i < NR_CORES && | ||
| 608 | sens_cpu_power[i] == NULL && wf_get_sensor(sr) == 0) | ||
| 609 | sens_cpu_power[i] = sr; | ||
| 610 | } else if (!strcmp(sr->name, "hd-temp")) { | ||
| 611 | if (hd_temp == NULL && wf_get_sensor(sr) == 0) | ||
| 612 | hd_temp = sr; | ||
| 613 | } else if (!strcmp(sr->name, "slots-power")) { | ||
| 614 | if (slots_power == NULL && wf_get_sensor(sr) == 0) | ||
| 615 | slots_power = sr; | ||
| 616 | } else if (!strcmp(sr->name, "u4-temp")) { | ||
| 617 | if (u4_temp == NULL && wf_get_sensor(sr) == 0) | ||
| 618 | u4_temp = sr; | ||
| 619 | } else | ||
| 620 | return; | ||
| 621 | |||
| 622 | /* check if we have all the sensors we need */ | ||
| 623 | for (i = 0; i < nr_cores; ++i) | ||
| 624 | if (sens_cpu_temp[i] == NULL || sens_cpu_power[i] == NULL) | ||
| 625 | return; | ||
| 626 | |||
| 627 | have_all_sensors = 1; | ||
| 628 | } | ||
| 629 | |||
| 630 | static int pm112_wf_notify(struct notifier_block *self, | ||
| 631 | unsigned long event, void *data) | ||
| 632 | { | ||
| 633 | switch (event) { | ||
| 634 | case WF_EVENT_NEW_SENSOR: | ||
| 635 | pm112_new_sensor(data); | ||
| 636 | break; | ||
| 637 | case WF_EVENT_NEW_CONTROL: | ||
| 638 | pm112_new_control(data); | ||
| 639 | break; | ||
| 640 | case WF_EVENT_TICK: | ||
| 641 | if (have_all_controls && have_all_sensors) | ||
| 642 | pm112_tick(); | ||
| 643 | } | ||
| 644 | return 0; | ||
| 645 | } | ||
| 646 | |||
| 647 | static struct notifier_block pm112_events = { | ||
| 648 | .notifier_call = pm112_wf_notify, | ||
| 649 | }; | ||
| 650 | |||
| 651 | static int wf_pm112_probe(struct device *dev) | ||
| 652 | { | ||
| 653 | wf_register_client(&pm112_events); | ||
| 654 | return 0; | ||
| 655 | } | ||
| 656 | |||
| 657 | static int wf_pm112_remove(struct device *dev) | ||
| 658 | { | ||
| 659 | wf_unregister_client(&pm112_events); | ||
| 660 | /* should release all sensors and controls */ | ||
| 661 | return 0; | ||
| 662 | } | ||
| 663 | |||
| 664 | static struct device_driver wf_pm112_driver = { | ||
| 665 | .name = "windfarm", | ||
| 666 | .bus = &platform_bus_type, | ||
| 667 | .probe = wf_pm112_probe, | ||
| 668 | .remove = wf_pm112_remove, | ||
| 669 | }; | ||
| 670 | |||
| 671 | static int __init wf_pm112_init(void) | ||
| 672 | { | ||
| 673 | struct device_node *cpu; | ||
| 674 | |||
| 675 | if (!machine_is_compatible("PowerMac11,2")) | ||
| 676 | return -ENODEV; | ||
| 677 | |||
| 678 | /* Count the number of CPU cores */ | ||
| 679 | nr_cores = 0; | ||
| 680 | for (cpu = NULL; (cpu = of_find_node_by_type(cpu, "cpu")) != NULL; ) | ||
| 681 | ++nr_cores; | ||
| 682 | |||
| 683 | printk(KERN_INFO "windfarm: initializing for dual-core desktop G5\n"); | ||
| 684 | driver_register(&wf_pm112_driver); | ||
| 685 | return 0; | ||
| 686 | } | ||
| 687 | |||
| 688 | static void __exit wf_pm112_exit(void) | ||
| 689 | { | ||
| 690 | driver_unregister(&wf_pm112_driver); | ||
| 691 | } | ||
| 692 | |||
| 693 | module_init(wf_pm112_init); | ||
| 694 | module_exit(wf_pm112_exit); | ||
| 695 | |||
| 696 | MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>"); | ||
| 697 | MODULE_DESCRIPTION("Thermal control for PowerMac11,2"); | ||
| 698 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/macintosh/windfarm_pm81.c b/drivers/macintosh/windfarm_pm81.c index eb69a601e765..f1df6efcbe68 100644 --- a/drivers/macintosh/windfarm_pm81.c +++ b/drivers/macintosh/windfarm_pm81.c | |||
| @@ -538,45 +538,6 @@ static void wf_smu_cpu_fans_tick(struct wf_smu_cpu_fans_state *st) | |||
| 538 | } | 538 | } |
| 539 | } | 539 | } |
| 540 | 540 | ||
| 541 | |||
| 542 | /* | ||
| 543 | * ****** Attributes ****** | ||
| 544 | * | ||
| 545 | */ | ||
| 546 | |||
| 547 | #define BUILD_SHOW_FUNC_FIX(name, data) \ | ||
| 548 | static ssize_t show_##name(struct device *dev, \ | ||
| 549 | struct device_attribute *attr, \ | ||
| 550 | char *buf) \ | ||
| 551 | { \ | ||
| 552 | ssize_t r; \ | ||
| 553 | s32 val = 0; \ | ||
| 554 | data->ops->get_value(data, &val); \ | ||
| 555 | r = sprintf(buf, "%d.%03d", FIX32TOPRINT(val)); \ | ||
| 556 | return r; \ | ||
| 557 | } \ | ||
| 558 | static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL); | ||
| 559 | |||
| 560 | |||
| 561 | #define BUILD_SHOW_FUNC_INT(name, data) \ | ||
| 562 | static ssize_t show_##name(struct device *dev, \ | ||
| 563 | struct device_attribute *attr, \ | ||
| 564 | char *buf) \ | ||
| 565 | { \ | ||
| 566 | s32 val = 0; \ | ||
| 567 | data->ops->get_value(data, &val); \ | ||
| 568 | return sprintf(buf, "%d", val); \ | ||
| 569 | } \ | ||
| 570 | static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL); | ||
| 571 | |||
| 572 | BUILD_SHOW_FUNC_INT(cpu_fan, fan_cpu_main); | ||
| 573 | BUILD_SHOW_FUNC_INT(sys_fan, fan_system); | ||
| 574 | BUILD_SHOW_FUNC_INT(hd_fan, fan_hd); | ||
| 575 | |||
| 576 | BUILD_SHOW_FUNC_FIX(cpu_temp, sensor_cpu_temp); | ||
| 577 | BUILD_SHOW_FUNC_FIX(cpu_power, sensor_cpu_power); | ||
| 578 | BUILD_SHOW_FUNC_FIX(hd_temp, sensor_hd_temp); | ||
| 579 | |||
| 580 | /* | 541 | /* |
| 581 | * ****** Setup / Init / Misc ... ****** | 542 | * ****** Setup / Init / Misc ... ****** |
| 582 | * | 543 | * |
| @@ -654,17 +615,13 @@ static void wf_smu_new_control(struct wf_control *ct) | |||
| 654 | return; | 615 | return; |
| 655 | 616 | ||
| 656 | if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-fan")) { | 617 | if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-fan")) { |
| 657 | if (wf_get_control(ct) == 0) { | 618 | if (wf_get_control(ct) == 0) |
| 658 | fan_cpu_main = ct; | 619 | fan_cpu_main = ct; |
| 659 | device_create_file(wf_smu_dev, &dev_attr_cpu_fan); | ||
| 660 | } | ||
| 661 | } | 620 | } |
| 662 | 621 | ||
| 663 | if (fan_system == NULL && !strcmp(ct->name, "system-fan")) { | 622 | if (fan_system == NULL && !strcmp(ct->name, "system-fan")) { |
| 664 | if (wf_get_control(ct) == 0) { | 623 | if (wf_get_control(ct) == 0) |
| 665 | fan_system = ct; | 624 | fan_system = ct; |
| 666 | device_create_file(wf_smu_dev, &dev_attr_sys_fan); | ||
| 667 | } | ||
| 668 | } | 625 | } |
| 669 | 626 | ||
| 670 | if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) { | 627 | if (cpufreq_clamp == NULL && !strcmp(ct->name, "cpufreq-clamp")) { |
| @@ -683,10 +640,8 @@ static void wf_smu_new_control(struct wf_control *ct) | |||
| 683 | } | 640 | } |
| 684 | 641 | ||
| 685 | if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) { | 642 | if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) { |
| 686 | if (wf_get_control(ct) == 0) { | 643 | if (wf_get_control(ct) == 0) |
| 687 | fan_hd = ct; | 644 | fan_hd = ct; |
| 688 | device_create_file(wf_smu_dev, &dev_attr_hd_fan); | ||
| 689 | } | ||
| 690 | } | 645 | } |
| 691 | 646 | ||
| 692 | if (fan_system && fan_hd && fan_cpu_main && cpufreq_clamp) | 647 | if (fan_system && fan_hd && fan_cpu_main && cpufreq_clamp) |
| @@ -699,24 +654,18 @@ static void wf_smu_new_sensor(struct wf_sensor *sr) | |||
| 699 | return; | 654 | return; |
| 700 | 655 | ||
| 701 | if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) { | 656 | if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) { |
| 702 | if (wf_get_sensor(sr) == 0) { | 657 | if (wf_get_sensor(sr) == 0) |
| 703 | sensor_cpu_power = sr; | 658 | sensor_cpu_power = sr; |
| 704 | device_create_file(wf_smu_dev, &dev_attr_cpu_power); | ||
| 705 | } | ||
| 706 | } | 659 | } |
| 707 | 660 | ||
| 708 | if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) { | 661 | if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) { |
| 709 | if (wf_get_sensor(sr) == 0) { | 662 | if (wf_get_sensor(sr) == 0) |
| 710 | sensor_cpu_temp = sr; | 663 | sensor_cpu_temp = sr; |
| 711 | device_create_file(wf_smu_dev, &dev_attr_cpu_temp); | ||
| 712 | } | ||
| 713 | } | 664 | } |
| 714 | 665 | ||
| 715 | if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) { | 666 | if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) { |
| 716 | if (wf_get_sensor(sr) == 0) { | 667 | if (wf_get_sensor(sr) == 0) |
| 717 | sensor_hd_temp = sr; | 668 | sensor_hd_temp = sr; |
| 718 | device_create_file(wf_smu_dev, &dev_attr_hd_temp); | ||
| 719 | } | ||
| 720 | } | 669 | } |
| 721 | 670 | ||
| 722 | if (sensor_cpu_power && sensor_cpu_temp && sensor_hd_temp) | 671 | if (sensor_cpu_power && sensor_cpu_temp && sensor_hd_temp) |
| @@ -794,32 +743,20 @@ static int wf_smu_remove(struct device *ddev) | |||
| 794 | * with that except by adding locks all over... I'll do that | 743 | * with that except by adding locks all over... I'll do that |
| 795 | * eventually but heh, who ever rmmod this module anyway ? | 744 | * eventually but heh, who ever rmmod this module anyway ? |
| 796 | */ | 745 | */ |
| 797 | if (sensor_cpu_power) { | 746 | if (sensor_cpu_power) |
| 798 | device_remove_file(wf_smu_dev, &dev_attr_cpu_power); | ||
| 799 | wf_put_sensor(sensor_cpu_power); | 747 | wf_put_sensor(sensor_cpu_power); |
| 800 | } | 748 | if (sensor_cpu_temp) |
| 801 | if (sensor_cpu_temp) { | ||
| 802 | device_remove_file(wf_smu_dev, &dev_attr_cpu_temp); | ||
| 803 | wf_put_sensor(sensor_cpu_temp); | 749 | wf_put_sensor(sensor_cpu_temp); |
| 804 | } | 750 | if (sensor_hd_temp) |
| 805 | if (sensor_hd_temp) { | ||
| 806 | device_remove_file(wf_smu_dev, &dev_attr_hd_temp); | ||
| 807 | wf_put_sensor(sensor_hd_temp); | 751 | wf_put_sensor(sensor_hd_temp); |
| 808 | } | ||
| 809 | 752 | ||
| 810 | /* Release all controls */ | 753 | /* Release all controls */ |
| 811 | if (fan_cpu_main) { | 754 | if (fan_cpu_main) |
| 812 | device_remove_file(wf_smu_dev, &dev_attr_cpu_fan); | ||
| 813 | wf_put_control(fan_cpu_main); | 755 | wf_put_control(fan_cpu_main); |
| 814 | } | 756 | if (fan_hd) |
| 815 | if (fan_hd) { | ||
| 816 | device_remove_file(wf_smu_dev, &dev_attr_hd_fan); | ||
| 817 | wf_put_control(fan_hd); | 757 | wf_put_control(fan_hd); |
| 818 | } | 758 | if (fan_system) |
| 819 | if (fan_system) { | ||
| 820 | device_remove_file(wf_smu_dev, &dev_attr_sys_fan); | ||
| 821 | wf_put_control(fan_system); | 759 | wf_put_control(fan_system); |
| 822 | } | ||
| 823 | if (cpufreq_clamp) | 760 | if (cpufreq_clamp) |
| 824 | wf_put_control(cpufreq_clamp); | 761 | wf_put_control(cpufreq_clamp); |
| 825 | 762 | ||
diff --git a/drivers/macintosh/windfarm_pm91.c b/drivers/macintosh/windfarm_pm91.c index 43243cf7410b..0d6372e96d32 100644 --- a/drivers/macintosh/windfarm_pm91.c +++ b/drivers/macintosh/windfarm_pm91.c | |||
| @@ -458,45 +458,6 @@ static void wf_smu_slots_fans_tick(struct wf_smu_slots_fans_state *st) | |||
| 458 | 458 | ||
| 459 | 459 | ||
| 460 | /* | 460 | /* |
| 461 | * ****** Attributes ****** | ||
| 462 | * | ||
| 463 | */ | ||
| 464 | |||
| 465 | #define BUILD_SHOW_FUNC_FIX(name, data) \ | ||
| 466 | static ssize_t show_##name(struct device *dev, \ | ||
| 467 | struct device_attribute *attr, \ | ||
| 468 | char *buf) \ | ||
| 469 | { \ | ||
| 470 | ssize_t r; \ | ||
| 471 | s32 val = 0; \ | ||
| 472 | data->ops->get_value(data, &val); \ | ||
| 473 | r = sprintf(buf, "%d.%03d", FIX32TOPRINT(val)); \ | ||
| 474 | return r; \ | ||
| 475 | } \ | ||
| 476 | static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL); | ||
| 477 | |||
| 478 | |||
| 479 | #define BUILD_SHOW_FUNC_INT(name, data) \ | ||
| 480 | static ssize_t show_##name(struct device *dev, \ | ||
| 481 | struct device_attribute *attr, \ | ||
| 482 | char *buf) \ | ||
| 483 | { \ | ||
| 484 | s32 val = 0; \ | ||
| 485 | data->ops->get_value(data, &val); \ | ||
| 486 | return sprintf(buf, "%d", val); \ | ||
| 487 | } \ | ||
| 488 | static DEVICE_ATTR(name,S_IRUGO,show_##name, NULL); | ||
| 489 | |||
| 490 | BUILD_SHOW_FUNC_INT(cpu_fan, fan_cpu_main); | ||
| 491 | BUILD_SHOW_FUNC_INT(hd_fan, fan_hd); | ||
| 492 | BUILD_SHOW_FUNC_INT(slots_fan, fan_slots); | ||
| 493 | |||
| 494 | BUILD_SHOW_FUNC_FIX(cpu_temp, sensor_cpu_temp); | ||
| 495 | BUILD_SHOW_FUNC_FIX(cpu_power, sensor_cpu_power); | ||
| 496 | BUILD_SHOW_FUNC_FIX(hd_temp, sensor_hd_temp); | ||
| 497 | BUILD_SHOW_FUNC_FIX(slots_power, sensor_slots_power); | ||
| 498 | |||
| 499 | /* | ||
| 500 | * ****** Setup / Init / Misc ... ****** | 461 | * ****** Setup / Init / Misc ... ****** |
| 501 | * | 462 | * |
| 502 | */ | 463 | */ |
| @@ -581,10 +542,8 @@ static void wf_smu_new_control(struct wf_control *ct) | |||
| 581 | return; | 542 | return; |
| 582 | 543 | ||
| 583 | if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-rear-fan-0")) { | 544 | if (fan_cpu_main == NULL && !strcmp(ct->name, "cpu-rear-fan-0")) { |
| 584 | if (wf_get_control(ct) == 0) { | 545 | if (wf_get_control(ct) == 0) |
| 585 | fan_cpu_main = ct; | 546 | fan_cpu_main = ct; |
| 586 | device_create_file(wf_smu_dev, &dev_attr_cpu_fan); | ||
| 587 | } | ||
| 588 | } | 547 | } |
| 589 | 548 | ||
| 590 | if (fan_cpu_second == NULL && !strcmp(ct->name, "cpu-rear-fan-1")) { | 549 | if (fan_cpu_second == NULL && !strcmp(ct->name, "cpu-rear-fan-1")) { |
| @@ -603,17 +562,13 @@ static void wf_smu_new_control(struct wf_control *ct) | |||
| 603 | } | 562 | } |
| 604 | 563 | ||
| 605 | if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) { | 564 | if (fan_hd == NULL && !strcmp(ct->name, "drive-bay-fan")) { |
| 606 | if (wf_get_control(ct) == 0) { | 565 | if (wf_get_control(ct) == 0) |
| 607 | fan_hd = ct; | 566 | fan_hd = ct; |
| 608 | device_create_file(wf_smu_dev, &dev_attr_hd_fan); | ||
| 609 | } | ||
| 610 | } | 567 | } |
| 611 | 568 | ||
| 612 | if (fan_slots == NULL && !strcmp(ct->name, "slots-fan")) { | 569 | if (fan_slots == NULL && !strcmp(ct->name, "slots-fan")) { |
| 613 | if (wf_get_control(ct) == 0) { | 570 | if (wf_get_control(ct) == 0) |
| 614 | fan_slots = ct; | 571 | fan_slots = ct; |
| 615 | device_create_file(wf_smu_dev, &dev_attr_slots_fan); | ||
| 616 | } | ||
| 617 | } | 572 | } |
| 618 | 573 | ||
| 619 | if (fan_cpu_main && (fan_cpu_second || fan_cpu_third) && fan_hd && | 574 | if (fan_cpu_main && (fan_cpu_second || fan_cpu_third) && fan_hd && |
| @@ -627,31 +582,23 @@ static void wf_smu_new_sensor(struct wf_sensor *sr) | |||
| 627 | return; | 582 | return; |
| 628 | 583 | ||
| 629 | if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) { | 584 | if (sensor_cpu_power == NULL && !strcmp(sr->name, "cpu-power")) { |
| 630 | if (wf_get_sensor(sr) == 0) { | 585 | if (wf_get_sensor(sr) == 0) |
| 631 | sensor_cpu_power = sr; | 586 | sensor_cpu_power = sr; |
| 632 | device_create_file(wf_smu_dev, &dev_attr_cpu_power); | ||
| 633 | } | ||
| 634 | } | 587 | } |
| 635 | 588 | ||
| 636 | if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) { | 589 | if (sensor_cpu_temp == NULL && !strcmp(sr->name, "cpu-temp")) { |
| 637 | if (wf_get_sensor(sr) == 0) { | 590 | if (wf_get_sensor(sr) == 0) |
| 638 | sensor_cpu_temp = sr; | 591 | sensor_cpu_temp = sr; |
| 639 | device_create_file(wf_smu_dev, &dev_attr_cpu_temp); | ||
| 640 | } | ||
| 641 | } | 592 | } |
| 642 | 593 | ||
| 643 | if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) { | 594 | if (sensor_hd_temp == NULL && !strcmp(sr->name, "hd-temp")) { |
| 644 | if (wf_get_sensor(sr) == 0) { | 595 | if (wf_get_sensor(sr) == 0) |
| 645 | sensor_hd_temp = sr; | 596 | sensor_hd_temp = sr; |
| 646 | device_create_file(wf_smu_dev, &dev_attr_hd_temp); | ||
| 647 | } | ||
| 648 | } | 597 | } |
| 649 | 598 | ||
| 650 | if (sensor_slots_power == NULL && !strcmp(sr->name, "slots-power")) { | 599 | if (sensor_slots_power == NULL && !strcmp(sr->name, "slots-power")) { |
| 651 | if (wf_get_sensor(sr) == 0) { | 600 | if (wf_get_sensor(sr) == 0) |
| 652 | sensor_slots_power = sr; | 601 | sensor_slots_power = sr; |
| 653 | device_create_file(wf_smu_dev, &dev_attr_slots_power); | ||
| 654 | } | ||
| 655 | } | 602 | } |
| 656 | 603 | ||
| 657 | if (sensor_cpu_power && sensor_cpu_temp && | 604 | if (sensor_cpu_power && sensor_cpu_temp && |
| @@ -720,40 +667,26 @@ static int wf_smu_remove(struct device *ddev) | |||
| 720 | * with that except by adding locks all over... I'll do that | 667 | * with that except by adding locks all over... I'll do that |
| 721 | * eventually but heh, who ever rmmod this module anyway ? | 668 | * eventually but heh, who ever rmmod this module anyway ? |
| 722 | */ | 669 | */ |
| 723 | if (sensor_cpu_power) { | 670 | if (sensor_cpu_power) |
| 724 | device_remove_file(wf_smu_dev, &dev_attr_cpu_power); | ||
| 725 | wf_put_sensor(sensor_cpu_power); | 671 | wf_put_sensor(sensor_cpu_power); |
| 726 | } | 672 | if (sensor_cpu_temp) |
| 727 | if (sensor_cpu_temp) { | ||
| 728 | device_remove_file(wf_smu_dev, &dev_attr_cpu_temp); | ||
| 729 | wf_put_sensor(sensor_cpu_temp); | 673 | wf_put_sensor(sensor_cpu_temp); |
| 730 | } | 674 | if (sensor_hd_temp) |
| 731 | if (sensor_hd_temp) { | ||
| 732 | device_remove_file(wf_smu_dev, &dev_attr_hd_temp); | ||
| 733 | wf_put_sensor(sensor_hd_temp); | 675 | wf_put_sensor(sensor_hd_temp); |
| 734 | } | 676 | if (sensor_slots_power) |
| 735 | if (sensor_slots_power) { | ||
| 736 | device_remove_file(wf_smu_dev, &dev_attr_slots_power); | ||
| 737 | wf_put_sensor(sensor_slots_power); | 677 | wf_put_sensor(sensor_slots_power); |
| 738 | } | ||
| 739 | 678 | ||
| 740 | /* Release all controls */ | 679 | /* Release all controls */ |
| 741 | if (fan_cpu_main) { | 680 | if (fan_cpu_main) |
| 742 | device_remove_file(wf_smu_dev, &dev_attr_cpu_fan); | ||
| 743 | wf_put_control(fan_cpu_main); | 681 | wf_put_control(fan_cpu_main); |
| 744 | } | ||
| 745 | if (fan_cpu_second) | 682 | if (fan_cpu_second) |
| 746 | wf_put_control(fan_cpu_second); | 683 | wf_put_control(fan_cpu_second); |
| 747 | if (fan_cpu_third) | 684 | if (fan_cpu_third) |
| 748 | wf_put_control(fan_cpu_third); | 685 | wf_put_control(fan_cpu_third); |
| 749 | if (fan_hd) { | 686 | if (fan_hd) |
| 750 | device_remove_file(wf_smu_dev, &dev_attr_hd_fan); | ||
| 751 | wf_put_control(fan_hd); | 687 | wf_put_control(fan_hd); |
| 752 | } | 688 | if (fan_slots) |
| 753 | if (fan_slots) { | ||
| 754 | device_remove_file(wf_smu_dev, &dev_attr_slots_fan); | ||
| 755 | wf_put_control(fan_slots); | 689 | wf_put_control(fan_slots); |
| 756 | } | ||
| 757 | if (cpufreq_clamp) | 690 | if (cpufreq_clamp) |
| 758 | wf_put_control(cpufreq_clamp); | 691 | wf_put_control(cpufreq_clamp); |
| 759 | 692 | ||
diff --git a/drivers/macintosh/windfarm_smu_controls.c b/drivers/macintosh/windfarm_smu_controls.c index 4d811600bdab..a9e88edc0c72 100644 --- a/drivers/macintosh/windfarm_smu_controls.c +++ b/drivers/macintosh/windfarm_smu_controls.c | |||
| @@ -24,7 +24,7 @@ | |||
| 24 | 24 | ||
| 25 | #include "windfarm.h" | 25 | #include "windfarm.h" |
| 26 | 26 | ||
| 27 | #define VERSION "0.3" | 27 | #define VERSION "0.4" |
| 28 | 28 | ||
| 29 | #undef DEBUG | 29 | #undef DEBUG |
| 30 | 30 | ||
| @@ -34,6 +34,8 @@ | |||
| 34 | #define DBG(args...) do { } while(0) | 34 | #define DBG(args...) do { } while(0) |
| 35 | #endif | 35 | #endif |
| 36 | 36 | ||
| 37 | static int smu_supports_new_fans_ops = 1; | ||
| 38 | |||
| 37 | /* | 39 | /* |
| 38 | * SMU fans control object | 40 | * SMU fans control object |
| 39 | */ | 41 | */ |
| @@ -59,23 +61,49 @@ static int smu_set_fan(int pwm, u8 id, u16 value) | |||
| 59 | 61 | ||
| 60 | /* Fill SMU command structure */ | 62 | /* Fill SMU command structure */ |
| 61 | cmd.cmd = SMU_CMD_FAN_COMMAND; | 63 | cmd.cmd = SMU_CMD_FAN_COMMAND; |
| 62 | cmd.data_len = 14; | 64 | |
| 65 | /* The SMU has an "old" and a "new" way of setting the fan speed | ||
| 66 | * Unfortunately, I found no reliable way to know which one works | ||
| 67 | * on a given machine model. After some investigations it appears | ||
| 68 | * that MacOS X just tries the new one, and if it fails fallbacks | ||
| 69 | * to the old ones ... Ugh. | ||
| 70 | */ | ||
| 71 | retry: | ||
| 72 | if (smu_supports_new_fans_ops) { | ||
| 73 | buffer[0] = 0x30; | ||
| 74 | buffer[1] = id; | ||
| 75 | *((u16 *)(&buffer[2])) = value; | ||
| 76 | cmd.data_len = 4; | ||
| 77 | } else { | ||
| 78 | if (id > 7) | ||
| 79 | return -EINVAL; | ||
| 80 | /* Fill argument buffer */ | ||
| 81 | memset(buffer, 0, 16); | ||
| 82 | buffer[0] = pwm ? 0x10 : 0x00; | ||
| 83 | buffer[1] = 0x01 << id; | ||
| 84 | *((u16 *)&buffer[2 + id * 2]) = value; | ||
| 85 | cmd.data_len = 14; | ||
| 86 | } | ||
| 87 | |||
| 63 | cmd.reply_len = 16; | 88 | cmd.reply_len = 16; |
| 64 | cmd.data_buf = cmd.reply_buf = buffer; | 89 | cmd.data_buf = cmd.reply_buf = buffer; |
| 65 | cmd.status = 0; | 90 | cmd.status = 0; |
| 66 | cmd.done = smu_done_complete; | 91 | cmd.done = smu_done_complete; |
| 67 | cmd.misc = ∁ | 92 | cmd.misc = ∁ |
| 68 | 93 | ||
| 69 | /* Fill argument buffer */ | ||
| 70 | memset(buffer, 0, 16); | ||
| 71 | buffer[0] = pwm ? 0x10 : 0x00; | ||
| 72 | buffer[1] = 0x01 << id; | ||
| 73 | *((u16 *)&buffer[2 + id * 2]) = value; | ||
| 74 | |||
| 75 | rc = smu_queue_cmd(&cmd); | 94 | rc = smu_queue_cmd(&cmd); |
| 76 | if (rc) | 95 | if (rc) |
| 77 | return rc; | 96 | return rc; |
| 78 | wait_for_completion(&comp); | 97 | wait_for_completion(&comp); |
| 98 | |||
| 99 | /* Handle fallback (see coment above) */ | ||
| 100 | if (cmd.status != 0 && smu_supports_new_fans_ops) { | ||
| 101 | printk(KERN_WARNING "windfarm: SMU failed new fan command " | ||
| 102 | "falling back to old method\n"); | ||
| 103 | smu_supports_new_fans_ops = 0; | ||
| 104 | goto retry; | ||
| 105 | } | ||
| 106 | |||
| 79 | return cmd.status; | 107 | return cmd.status; |
| 80 | } | 108 | } |
| 81 | 109 | ||
| @@ -158,19 +186,29 @@ static struct smu_fan_control *smu_fan_create(struct device_node *node, | |||
| 158 | 186 | ||
| 159 | /* Names used on desktop models */ | 187 | /* Names used on desktop models */ |
| 160 | if (!strcmp(l, "Rear Fan 0") || !strcmp(l, "Rear Fan") || | 188 | if (!strcmp(l, "Rear Fan 0") || !strcmp(l, "Rear Fan") || |
| 161 | !strcmp(l, "Rear fan 0") || !strcmp(l, "Rear fan")) | 189 | !strcmp(l, "Rear fan 0") || !strcmp(l, "Rear fan") || |
| 190 | !strcmp(l, "CPU A EXHAUST")) | ||
| 162 | fct->ctrl.name = "cpu-rear-fan-0"; | 191 | fct->ctrl.name = "cpu-rear-fan-0"; |
| 163 | else if (!strcmp(l, "Rear Fan 1") || !strcmp(l, "Rear fan 1")) | 192 | else if (!strcmp(l, "Rear Fan 1") || !strcmp(l, "Rear fan 1") || |
| 193 | !strcmp(l, "CPU B EXHAUST")) | ||
| 164 | fct->ctrl.name = "cpu-rear-fan-1"; | 194 | fct->ctrl.name = "cpu-rear-fan-1"; |
| 165 | else if (!strcmp(l, "Front Fan 0") || !strcmp(l, "Front Fan") || | 195 | else if (!strcmp(l, "Front Fan 0") || !strcmp(l, "Front Fan") || |
| 166 | !strcmp(l, "Front fan 0") || !strcmp(l, "Front fan")) | 196 | !strcmp(l, "Front fan 0") || !strcmp(l, "Front fan") || |
| 197 | !strcmp(l, "CPU A INTAKE")) | ||
| 167 | fct->ctrl.name = "cpu-front-fan-0"; | 198 | fct->ctrl.name = "cpu-front-fan-0"; |
| 168 | else if (!strcmp(l, "Front Fan 1") || !strcmp(l, "Front fan 1")) | 199 | else if (!strcmp(l, "Front Fan 1") || !strcmp(l, "Front fan 1") || |
| 200 | !strcmp(l, "CPU B INTAKE")) | ||
| 169 | fct->ctrl.name = "cpu-front-fan-1"; | 201 | fct->ctrl.name = "cpu-front-fan-1"; |
| 170 | else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan")) | 202 | else if (!strcmp(l, "CPU A PUMP")) |
| 203 | fct->ctrl.name = "cpu-pump-0"; | ||
| 204 | else if (!strcmp(l, "Slots Fan") || !strcmp(l, "Slots fan") || | ||
| 205 | !strcmp(l, "EXPANSION SLOTS INTAKE")) | ||
| 171 | fct->ctrl.name = "slots-fan"; | 206 | fct->ctrl.name = "slots-fan"; |
| 172 | else if (!strcmp(l, "Drive Bay") || !strcmp(l, "Drive bay")) | 207 | else if (!strcmp(l, "Drive Bay") || !strcmp(l, "Drive bay") || |
| 208 | !strcmp(l, "DRIVE BAY A INTAKE")) | ||
| 173 | fct->ctrl.name = "drive-bay-fan"; | 209 | fct->ctrl.name = "drive-bay-fan"; |
| 210 | else if (!strcmp(l, "BACKSIDE")) | ||
| 211 | fct->ctrl.name = "backside-fan"; | ||
| 174 | 212 | ||
| 175 | /* Names used on iMac models */ | 213 | /* Names used on iMac models */ |
| 176 | if (!strcmp(l, "System Fan") || !strcmp(l, "System fan")) | 214 | if (!strcmp(l, "System Fan") || !strcmp(l, "System fan")) |
| @@ -223,7 +261,8 @@ static int __init smu_controls_init(void) | |||
| 223 | 261 | ||
| 224 | /* Look for RPM fans */ | 262 | /* Look for RPM fans */ |
| 225 | for (fans = NULL; (fans = of_get_next_child(smu, fans)) != NULL;) | 263 | for (fans = NULL; (fans = of_get_next_child(smu, fans)) != NULL;) |
| 226 | if (!strcmp(fans->name, "rpm-fans")) | 264 | if (!strcmp(fans->name, "rpm-fans") || |
| 265 | device_is_compatible(fans, "smu-rpm-fans")) | ||
| 227 | break; | 266 | break; |
| 228 | for (fan = NULL; | 267 | for (fan = NULL; |
| 229 | fans && (fan = of_get_next_child(fans, fan)) != NULL;) { | 268 | fans && (fan = of_get_next_child(fans, fan)) != NULL;) { |
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c new file mode 100644 index 000000000000..3a32c59494f2 --- /dev/null +++ b/drivers/macintosh/windfarm_smu_sat.c | |||
| @@ -0,0 +1,418 @@ | |||
| 1 | /* | ||
| 2 | * Windfarm PowerMac thermal control. SMU "satellite" controller sensors. | ||
| 3 | * | ||
| 4 | * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org> | ||
| 5 | * | ||
| 6 | * Released under the terms of the GNU GPL v2. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/types.h> | ||
| 10 | #include <linux/errno.h> | ||
| 11 | #include <linux/kernel.h> | ||
| 12 | #include <linux/slab.h> | ||
| 13 | #include <linux/init.h> | ||
| 14 | #include <linux/wait.h> | ||
| 15 | #include <linux/i2c.h> | ||
| 16 | #include <linux/i2c-dev.h> | ||
| 17 | #include <asm/semaphore.h> | ||
| 18 | #include <asm/prom.h> | ||
| 19 | #include <asm/smu.h> | ||
| 20 | #include <asm/pmac_low_i2c.h> | ||
| 21 | |||
| 22 | #include "windfarm.h" | ||
| 23 | |||
| 24 | #define VERSION "0.2" | ||
| 25 | |||
| 26 | #define DEBUG | ||
| 27 | |||
| 28 | #ifdef DEBUG | ||
| 29 | #define DBG(args...) printk(args) | ||
| 30 | #else | ||
| 31 | #define DBG(args...) do { } while(0) | ||
| 32 | #endif | ||
| 33 | |||
| 34 | /* If the cache is older than 800ms we'll refetch it */ | ||
| 35 | #define MAX_AGE msecs_to_jiffies(800) | ||
| 36 | |||
| 37 | struct wf_sat { | ||
| 38 | int nr; | ||
| 39 | atomic_t refcnt; | ||
| 40 | struct semaphore mutex; | ||
| 41 | unsigned long last_read; /* jiffies when cache last updated */ | ||
| 42 | u8 cache[16]; | ||
| 43 | struct i2c_client i2c; | ||
| 44 | struct device_node *node; | ||
| 45 | }; | ||
| 46 | |||
| 47 | static struct wf_sat *sats[2]; | ||
| 48 | |||
| 49 | struct wf_sat_sensor { | ||
| 50 | int index; | ||
| 51 | int index2; /* used for power sensors */ | ||
| 52 | int shift; | ||
| 53 | struct wf_sat *sat; | ||
| 54 | struct wf_sensor sens; | ||
| 55 | }; | ||
| 56 | |||
| 57 | #define wf_to_sat(c) container_of(c, struct wf_sat_sensor, sens) | ||
| 58 | #define i2c_to_sat(c) container_of(c, struct wf_sat, i2c) | ||
| 59 | |||
| 60 | static int wf_sat_attach(struct i2c_adapter *adapter); | ||
| 61 | static int wf_sat_detach(struct i2c_client *client); | ||
| 62 | |||
| 63 | static struct i2c_driver wf_sat_driver = { | ||
| 64 | .driver = { | ||
| 65 | .name = "wf_smu_sat", | ||
| 66 | }, | ||
| 67 | .attach_adapter = wf_sat_attach, | ||
| 68 | .detach_client = wf_sat_detach, | ||
| 69 | }; | ||
| 70 | |||
| 71 | /* | ||
| 72 | * XXX i2c_smbus_read_i2c_block_data doesn't pass the requested | ||
| 73 | * length down to the low-level driver, so we use this, which | ||
| 74 | * works well enough with the SMU i2c driver code... | ||
| 75 | */ | ||
| 76 | static int sat_read_block(struct i2c_client *client, u8 command, | ||
| 77 | u8 *values, int len) | ||
| 78 | { | ||
| 79 | union i2c_smbus_data data; | ||
| 80 | int err; | ||
| 81 | |||
| 82 | data.block[0] = len; | ||
| 83 | err = i2c_smbus_xfer(client->adapter, client->addr, client->flags, | ||
| 84 | I2C_SMBUS_READ, command, I2C_SMBUS_I2C_BLOCK_DATA, | ||
| 85 | &data); | ||
| 86 | if (!err) | ||
| 87 | memcpy(values, data.block, len); | ||
| 88 | return err; | ||
| 89 | } | ||
| 90 | |||
| 91 | struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id, | ||
| 92 | unsigned int *size) | ||
| 93 | { | ||
| 94 | struct wf_sat *sat; | ||
| 95 | int err; | ||
| 96 | unsigned int i, len; | ||
| 97 | u8 *buf; | ||
| 98 | u8 data[4]; | ||
| 99 | |||
| 100 | /* TODO: Add the resulting partition to the device-tree */ | ||
| 101 | |||
| 102 | if (sat_id > 1 || (sat = sats[sat_id]) == NULL) | ||
| 103 | return NULL; | ||
| 104 | |||
| 105 | err = i2c_smbus_write_word_data(&sat->i2c, 8, id << 8); | ||
| 106 | if (err) { | ||
| 107 | printk(KERN_ERR "smu_sat_get_sdb_part wr error %d\n", err); | ||
| 108 | return NULL; | ||
| 109 | } | ||
| 110 | |||
| 111 | len = i2c_smbus_read_word_data(&sat->i2c, 9); | ||
| 112 | if (len < 0) { | ||
| 113 | printk(KERN_ERR "smu_sat_get_sdb_part rd len error\n"); | ||
| 114 | return NULL; | ||
| 115 | } | ||
| 116 | if (len == 0) { | ||
| 117 | printk(KERN_ERR "smu_sat_get_sdb_part no partition %x\n", id); | ||
| 118 | return NULL; | ||
| 119 | } | ||
| 120 | |||
| 121 | len = le16_to_cpu(len); | ||
| 122 | len = (len + 3) & ~3; | ||
| 123 | buf = kmalloc(len, GFP_KERNEL); | ||
| 124 | if (buf == NULL) | ||
| 125 | return NULL; | ||
| 126 | |||
| 127 | for (i = 0; i < len; i += 4) { | ||
| 128 | err = sat_read_block(&sat->i2c, 0xa, data, 4); | ||
| 129 | if (err) { | ||
| 130 | printk(KERN_ERR "smu_sat_get_sdb_part rd err %d\n", | ||
| 131 | err); | ||
| 132 | goto fail; | ||
| 133 | } | ||
| 134 | buf[i] = data[1]; | ||
| 135 | buf[i+1] = data[0]; | ||
| 136 | buf[i+2] = data[3]; | ||
| 137 | buf[i+3] = data[2]; | ||
| 138 | } | ||
| 139 | #ifdef DEBUG | ||
| 140 | DBG(KERN_DEBUG "sat %d partition %x:", sat_id, id); | ||
| 141 | for (i = 0; i < len; ++i) | ||
| 142 | DBG(" %x", buf[i]); | ||
| 143 | DBG("\n"); | ||
| 144 | #endif | ||
| 145 | |||
| 146 | if (size) | ||
| 147 | *size = len; | ||
| 148 | return (struct smu_sdbp_header *) buf; | ||
| 149 | |||
| 150 | fail: | ||
| 151 | kfree(buf); | ||
| 152 | return NULL; | ||
| 153 | } | ||
| 154 | |||
| 155 | /* refresh the cache */ | ||
| 156 | static int wf_sat_read_cache(struct wf_sat *sat) | ||
| 157 | { | ||
| 158 | int err; | ||
| 159 | |||
| 160 | err = sat_read_block(&sat->i2c, 0x3f, sat->cache, 16); | ||
| 161 | if (err) | ||
| 162 | return err; | ||
| 163 | sat->last_read = jiffies; | ||
| 164 | #ifdef LOTSA_DEBUG | ||
| 165 | { | ||
| 166 | int i; | ||
| 167 | DBG(KERN_DEBUG "wf_sat_get: data is"); | ||
| 168 | for (i = 0; i < 16; ++i) | ||
| 169 | DBG(" %.2x", sat->cache[i]); | ||
| 170 | DBG("\n"); | ||
| 171 | } | ||
| 172 | #endif | ||
| 173 | return 0; | ||
| 174 | } | ||
| 175 | |||
| 176 | static int wf_sat_get(struct wf_sensor *sr, s32 *value) | ||
| 177 | { | ||
| 178 | struct wf_sat_sensor *sens = wf_to_sat(sr); | ||
| 179 | struct wf_sat *sat = sens->sat; | ||
| 180 | int i, err; | ||
| 181 | s32 val; | ||
| 182 | |||
| 183 | if (sat->i2c.adapter == NULL) | ||
| 184 | return -ENODEV; | ||
| 185 | |||
| 186 | down(&sat->mutex); | ||
| 187 | if (time_after(jiffies, (sat->last_read + MAX_AGE))) { | ||
| 188 | err = wf_sat_read_cache(sat); | ||
| 189 | if (err) | ||
| 190 | goto fail; | ||
| 191 | } | ||
| 192 | |||
| 193 | i = sens->index * 2; | ||
| 194 | val = ((sat->cache[i] << 8) + sat->cache[i+1]) << sens->shift; | ||
| 195 | if (sens->index2 >= 0) { | ||
| 196 | i = sens->index2 * 2; | ||
| 197 | /* 4.12 * 8.8 -> 12.20; shift right 4 to get 16.16 */ | ||
| 198 | val = (val * ((sat->cache[i] << 8) + sat->cache[i+1])) >> 4; | ||
| 199 | } | ||
| 200 | |||
| 201 | *value = val; | ||
| 202 | err = 0; | ||
| 203 | |||
| 204 | fail: | ||
| 205 | up(&sat->mutex); | ||
| 206 | return err; | ||
| 207 | } | ||
| 208 | |||
| 209 | static void wf_sat_release(struct wf_sensor *sr) | ||
| 210 | { | ||
| 211 | struct wf_sat_sensor *sens = wf_to_sat(sr); | ||
| 212 | struct wf_sat *sat = sens->sat; | ||
| 213 | |||
| 214 | if (atomic_dec_and_test(&sat->refcnt)) { | ||
| 215 | if (sat->i2c.adapter) { | ||
| 216 | i2c_detach_client(&sat->i2c); | ||
| 217 | sat->i2c.adapter = NULL; | ||
| 218 | } | ||
| 219 | if (sat->nr >= 0) | ||
| 220 | sats[sat->nr] = NULL; | ||
| 221 | kfree(sat); | ||
| 222 | } | ||
| 223 | kfree(sens); | ||
| 224 | } | ||
| 225 | |||
| 226 | static struct wf_sensor_ops wf_sat_ops = { | ||
| 227 | .get_value = wf_sat_get, | ||
| 228 | .release = wf_sat_release, | ||
| 229 | .owner = THIS_MODULE, | ||
| 230 | }; | ||
| 231 | |||
| 232 | static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev) | ||
| 233 | { | ||
| 234 | struct wf_sat *sat; | ||
| 235 | struct wf_sat_sensor *sens; | ||
| 236 | u32 *reg; | ||
| 237 | char *loc, *type; | ||
| 238 | u8 addr, chip, core; | ||
| 239 | struct device_node *child; | ||
| 240 | int shift, cpu, index; | ||
| 241 | char *name; | ||
| 242 | int vsens[2], isens[2]; | ||
| 243 | |||
| 244 | reg = (u32 *) get_property(dev, "reg", NULL); | ||
| 245 | if (reg == NULL) | ||
| 246 | return; | ||
| 247 | addr = *reg; | ||
| 248 | DBG(KERN_DEBUG "wf_sat: creating sat at address %x\n", addr); | ||
| 249 | |||
| 250 | sat = kzalloc(sizeof(struct wf_sat), GFP_KERNEL); | ||
| 251 | if (sat == NULL) | ||
| 252 | return; | ||
| 253 | sat->nr = -1; | ||
| 254 | sat->node = of_node_get(dev); | ||
| 255 | atomic_set(&sat->refcnt, 0); | ||
| 256 | init_MUTEX(&sat->mutex); | ||
| 257 | sat->i2c.addr = (addr >> 1) & 0x7f; | ||
| 258 | sat->i2c.adapter = adapter; | ||
| 259 | sat->i2c.driver = &wf_sat_driver; | ||
| 260 | strncpy(sat->i2c.name, "smu-sat", I2C_NAME_SIZE-1); | ||
| 261 | |||
| 262 | if (i2c_attach_client(&sat->i2c)) { | ||
| 263 | printk(KERN_ERR "windfarm: failed to attach smu-sat to i2c\n"); | ||
| 264 | goto fail; | ||
| 265 | } | ||
| 266 | |||
| 267 | vsens[0] = vsens[1] = -1; | ||
| 268 | isens[0] = isens[1] = -1; | ||
| 269 | child = NULL; | ||
| 270 | while ((child = of_get_next_child(dev, child)) != NULL) { | ||
| 271 | reg = (u32 *) get_property(child, "reg", NULL); | ||
| 272 | type = get_property(child, "device_type", NULL); | ||
| 273 | loc = get_property(child, "location", NULL); | ||
| 274 | if (reg == NULL || loc == NULL) | ||
| 275 | continue; | ||
| 276 | |||
| 277 | /* the cooked sensors are between 0x30 and 0x37 */ | ||
| 278 | if (*reg < 0x30 || *reg > 0x37) | ||
| 279 | continue; | ||
| 280 | index = *reg - 0x30; | ||
| 281 | |||
| 282 | /* expect location to be CPU [AB][01] ... */ | ||
| 283 | if (strncmp(loc, "CPU ", 4) != 0) | ||
| 284 | continue; | ||
| 285 | chip = loc[4] - 'A'; | ||
| 286 | core = loc[5] - '0'; | ||
| 287 | if (chip > 1 || core > 1) { | ||
| 288 | printk(KERN_ERR "wf_sat_create: don't understand " | ||
| 289 | "location %s for %s\n", loc, child->full_name); | ||
| 290 | continue; | ||
| 291 | } | ||
| 292 | cpu = 2 * chip + core; | ||
| 293 | if (sat->nr < 0) | ||
| 294 | sat->nr = chip; | ||
| 295 | else if (sat->nr != chip) { | ||
| 296 | printk(KERN_ERR "wf_sat_create: can't cope with " | ||
| 297 | "multiple CPU chips on one SAT (%s)\n", loc); | ||
| 298 | continue; | ||
| 299 | } | ||
| 300 | |||
| 301 | if (strcmp(type, "voltage-sensor") == 0) { | ||
| 302 | name = "cpu-voltage"; | ||
| 303 | shift = 4; | ||
| 304 | vsens[core] = index; | ||
| 305 | } else if (strcmp(type, "current-sensor") == 0) { | ||
| 306 | name = "cpu-current"; | ||
| 307 | shift = 8; | ||
| 308 | isens[core] = index; | ||
| 309 | } else if (strcmp(type, "temp-sensor") == 0) { | ||
| 310 | name = "cpu-temp"; | ||
| 311 | shift = 10; | ||
| 312 | } else | ||
| 313 | continue; /* hmmm shouldn't happen */ | ||
| 314 | |||
| 315 | /* the +16 is enough for "cpu-voltage-n" */ | ||
| 316 | sens = kzalloc(sizeof(struct wf_sat_sensor) + 16, GFP_KERNEL); | ||
| 317 | if (sens == NULL) { | ||
| 318 | printk(KERN_ERR "wf_sat_create: couldn't create " | ||
| 319 | "%s sensor %d (no memory)\n", name, cpu); | ||
| 320 | continue; | ||
| 321 | } | ||
| 322 | sens->index = index; | ||
| 323 | sens->index2 = -1; | ||
| 324 | sens->shift = shift; | ||
| 325 | sens->sat = sat; | ||
| 326 | atomic_inc(&sat->refcnt); | ||
| 327 | sens->sens.ops = &wf_sat_ops; | ||
| 328 | sens->sens.name = (char *) (sens + 1); | ||
| 329 | snprintf(sens->sens.name, 16, "%s-%d", name, cpu); | ||
| 330 | |||
| 331 | if (wf_register_sensor(&sens->sens)) { | ||
| 332 | atomic_dec(&sat->refcnt); | ||
| 333 | kfree(sens); | ||
| 334 | } | ||
| 335 | } | ||
| 336 | |||
| 337 | /* make the power sensors */ | ||
| 338 | for (core = 0; core < 2; ++core) { | ||
| 339 | if (vsens[core] < 0 || isens[core] < 0) | ||
| 340 | continue; | ||
| 341 | cpu = 2 * sat->nr + core; | ||
| 342 | sens = kzalloc(sizeof(struct wf_sat_sensor) + 16, GFP_KERNEL); | ||
| 343 | if (sens == NULL) { | ||
| 344 | printk(KERN_ERR "wf_sat_create: couldn't create power " | ||
| 345 | "sensor %d (no memory)\n", cpu); | ||
| 346 | continue; | ||
| 347 | } | ||
| 348 | sens->index = vsens[core]; | ||
| 349 | sens->index2 = isens[core]; | ||
| 350 | sens->shift = 0; | ||
| 351 | sens->sat = sat; | ||
| 352 | atomic_inc(&sat->refcnt); | ||
| 353 | sens->sens.ops = &wf_sat_ops; | ||
| 354 | sens->sens.name = (char *) (sens + 1); | ||
| 355 | snprintf(sens->sens.name, 16, "cpu-power-%d", cpu); | ||
| 356 | |||
| 357 | if (wf_register_sensor(&sens->sens)) { | ||
| 358 | atomic_dec(&sat->refcnt); | ||
| 359 | kfree(sens); | ||
| 360 | } | ||
| 361 | } | ||
| 362 | |||
| 363 | if (sat->nr >= 0) | ||
| 364 | sats[sat->nr] = sat; | ||
| 365 | |||
| 366 | return; | ||
| 367 | |||
| 368 | fail: | ||
| 369 | kfree(sat); | ||
| 370 | } | ||
| 371 | |||
| 372 | static int wf_sat_attach(struct i2c_adapter *adapter) | ||
| 373 | { | ||
| 374 | struct device_node *busnode, *dev = NULL; | ||
| 375 | struct pmac_i2c_bus *bus; | ||
| 376 | |||
| 377 | bus = pmac_i2c_adapter_to_bus(adapter); | ||
| 378 | if (bus == NULL) | ||
| 379 | return -ENODEV; | ||
| 380 | busnode = pmac_i2c_get_bus_node(bus); | ||
| 381 | |||
| 382 | while ((dev = of_get_next_child(busnode, dev)) != NULL) | ||
| 383 | if (device_is_compatible(dev, "smu-sat")) | ||
| 384 | wf_sat_create(adapter, dev); | ||
| 385 | return 0; | ||
| 386 | } | ||
| 387 | |||
| 388 | static int wf_sat_detach(struct i2c_client *client) | ||
| 389 | { | ||
| 390 | struct wf_sat *sat = i2c_to_sat(client); | ||
| 391 | |||
| 392 | /* XXX TODO */ | ||
| 393 | |||
| 394 | sat->i2c.adapter = NULL; | ||
| 395 | return 0; | ||
| 396 | } | ||
| 397 | |||
| 398 | static int __init sat_sensors_init(void) | ||
| 399 | { | ||
| 400 | int err; | ||
| 401 | |||
| 402 | err = i2c_add_driver(&wf_sat_driver); | ||
| 403 | if (err < 0) | ||
| 404 | return err; | ||
| 405 | return 0; | ||
| 406 | } | ||
| 407 | |||
| 408 | static void __exit sat_sensors_exit(void) | ||
| 409 | { | ||
| 410 | i2c_del_driver(&wf_sat_driver); | ||
| 411 | } | ||
| 412 | |||
| 413 | module_init(sat_sensors_init); | ||
| 414 | /*module_exit(sat_sensors_exit); Uncomment when cleanup is implemented */ | ||
| 415 | |||
| 416 | MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>"); | ||
| 417 | MODULE_DESCRIPTION("SMU satellite sensors for PowerMac thermal control"); | ||
| 418 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/macintosh/windfarm_smu_sensors.c b/drivers/macintosh/windfarm_smu_sensors.c index 1a00d9c75a23..bed25dcf8a1e 100644 --- a/drivers/macintosh/windfarm_smu_sensors.c +++ b/drivers/macintosh/windfarm_smu_sensors.c | |||
| @@ -220,14 +220,29 @@ static struct smu_ad_sensor *smu_ads_create(struct device_node *node) | |||
| 220 | !strcmp(l, "CPU T-Diode")) { | 220 | !strcmp(l, "CPU T-Diode")) { |
| 221 | ads->sens.ops = &smu_cputemp_ops; | 221 | ads->sens.ops = &smu_cputemp_ops; |
| 222 | ads->sens.name = "cpu-temp"; | 222 | ads->sens.name = "cpu-temp"; |
| 223 | if (cpudiode == NULL) { | ||
| 224 | DBG("wf: cpudiode partition (%02x) not found\n", | ||
| 225 | SMU_SDB_CPUDIODE_ID); | ||
| 226 | goto fail; | ||
| 227 | } | ||
| 223 | } else if (!strcmp(c, "current-sensor") && | 228 | } else if (!strcmp(c, "current-sensor") && |
| 224 | !strcmp(l, "CPU Current")) { | 229 | !strcmp(l, "CPU Current")) { |
| 225 | ads->sens.ops = &smu_cpuamp_ops; | 230 | ads->sens.ops = &smu_cpuamp_ops; |
| 226 | ads->sens.name = "cpu-current"; | 231 | ads->sens.name = "cpu-current"; |
| 232 | if (cpuvcp == NULL) { | ||
| 233 | DBG("wf: cpuvcp partition (%02x) not found\n", | ||
| 234 | SMU_SDB_CPUVCP_ID); | ||
| 235 | goto fail; | ||
| 236 | } | ||
| 227 | } else if (!strcmp(c, "voltage-sensor") && | 237 | } else if (!strcmp(c, "voltage-sensor") && |
| 228 | !strcmp(l, "CPU Voltage")) { | 238 | !strcmp(l, "CPU Voltage")) { |
| 229 | ads->sens.ops = &smu_cpuvolt_ops; | 239 | ads->sens.ops = &smu_cpuvolt_ops; |
| 230 | ads->sens.name = "cpu-voltage"; | 240 | ads->sens.name = "cpu-voltage"; |
| 241 | if (cpuvcp == NULL) { | ||
| 242 | DBG("wf: cpuvcp partition (%02x) not found\n", | ||
| 243 | SMU_SDB_CPUVCP_ID); | ||
| 244 | goto fail; | ||
| 245 | } | ||
| 231 | } else if (!strcmp(c, "power-sensor") && | 246 | } else if (!strcmp(c, "power-sensor") && |
| 232 | !strcmp(l, "Slots Power")) { | 247 | !strcmp(l, "Slots Power")) { |
| 233 | ads->sens.ops = &smu_slotspow_ops; | 248 | ads->sens.ops = &smu_slotspow_ops; |
| @@ -365,29 +380,22 @@ smu_cpu_power_create(struct wf_sensor *volts, struct wf_sensor *amps) | |||
| 365 | return NULL; | 380 | return NULL; |
| 366 | } | 381 | } |
| 367 | 382 | ||
| 368 | static int smu_fetch_param_partitions(void) | 383 | static void smu_fetch_param_partitions(void) |
| 369 | { | 384 | { |
| 370 | struct smu_sdbp_header *hdr; | 385 | struct smu_sdbp_header *hdr; |
| 371 | 386 | ||
| 372 | /* Get CPU voltage/current/power calibration data */ | 387 | /* Get CPU voltage/current/power calibration data */ |
| 373 | hdr = smu_get_sdb_partition(SMU_SDB_CPUVCP_ID, NULL); | 388 | hdr = smu_get_sdb_partition(SMU_SDB_CPUVCP_ID, NULL); |
| 374 | if (hdr == NULL) { | 389 | if (hdr != NULL) { |
| 375 | DBG("wf: cpuvcp partition (%02x) not found\n", | 390 | cpuvcp = (struct smu_sdbp_cpuvcp *)&hdr[1]; |
| 376 | SMU_SDB_CPUVCP_ID); | 391 | /* Keep version around */ |
| 377 | return -ENODEV; | 392 | cpuvcp_version = hdr->version; |
| 378 | } | 393 | } |
| 379 | cpuvcp = (struct smu_sdbp_cpuvcp *)&hdr[1]; | ||
| 380 | /* Keep version around */ | ||
| 381 | cpuvcp_version = hdr->version; | ||
| 382 | 394 | ||
| 383 | /* Get CPU diode calibration data */ | 395 | /* Get CPU diode calibration data */ |
| 384 | hdr = smu_get_sdb_partition(SMU_SDB_CPUDIODE_ID, NULL); | 396 | hdr = smu_get_sdb_partition(SMU_SDB_CPUDIODE_ID, NULL); |
| 385 | if (hdr == NULL) { | 397 | if (hdr != NULL) |
| 386 | DBG("wf: cpudiode partition (%02x) not found\n", | 398 | cpudiode = (struct smu_sdbp_cpudiode *)&hdr[1]; |
| 387 | SMU_SDB_CPUDIODE_ID); | ||
| 388 | return -ENODEV; | ||
| 389 | } | ||
| 390 | cpudiode = (struct smu_sdbp_cpudiode *)&hdr[1]; | ||
| 391 | 399 | ||
| 392 | /* Get slots power calibration data if any */ | 400 | /* Get slots power calibration data if any */ |
| 393 | hdr = smu_get_sdb_partition(SMU_SDB_SLOTSPOW_ID, NULL); | 401 | hdr = smu_get_sdb_partition(SMU_SDB_SLOTSPOW_ID, NULL); |
| @@ -398,23 +406,18 @@ static int smu_fetch_param_partitions(void) | |||
| 398 | hdr = smu_get_sdb_partition(SMU_SDB_DEBUG_SWITCHES_ID, NULL); | 406 | hdr = smu_get_sdb_partition(SMU_SDB_DEBUG_SWITCHES_ID, NULL); |
| 399 | if (hdr != NULL) | 407 | if (hdr != NULL) |
| 400 | debugswitches = (u8 *)&hdr[1]; | 408 | debugswitches = (u8 *)&hdr[1]; |
| 401 | |||
| 402 | return 0; | ||
| 403 | } | 409 | } |
| 404 | 410 | ||
| 405 | static int __init smu_sensors_init(void) | 411 | static int __init smu_sensors_init(void) |
| 406 | { | 412 | { |
| 407 | struct device_node *smu, *sensors, *s; | 413 | struct device_node *smu, *sensors, *s; |
| 408 | struct smu_ad_sensor *volt_sensor = NULL, *curr_sensor = NULL; | 414 | struct smu_ad_sensor *volt_sensor = NULL, *curr_sensor = NULL; |
| 409 | int rc; | ||
| 410 | 415 | ||
| 411 | if (!smu_present()) | 416 | if (!smu_present()) |
| 412 | return -ENODEV; | 417 | return -ENODEV; |
| 413 | 418 | ||
| 414 | /* Get parameters partitions */ | 419 | /* Get parameters partitions */ |
| 415 | rc = smu_fetch_param_partitions(); | 420 | smu_fetch_param_partitions(); |
| 416 | if (rc) | ||
| 417 | return rc; | ||
| 418 | 421 | ||
| 419 | smu = of_find_node_by_type(NULL, "smu"); | 422 | smu = of_find_node_by_type(NULL, "smu"); |
| 420 | if (smu == NULL) | 423 | if (smu == NULL) |
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index 74039db846ba..d73779a42417 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c | |||
| @@ -545,7 +545,8 @@ static int core_get_resync_work(struct dirty_log *log, region_t *region) | |||
| 545 | return 0; | 545 | return 0; |
| 546 | 546 | ||
| 547 | do { | 547 | do { |
| 548 | *region = find_next_zero_bit((unsigned long *) lc->sync_bits, | 548 | *region = ext2_find_next_zero_bit( |
| 549 | (unsigned long *) lc->sync_bits, | ||
| 549 | lc->region_count, | 550 | lc->region_count, |
| 550 | lc->sync_search); | 551 | lc->sync_search); |
| 551 | lc->sync_search = *region + 1; | 552 | lc->sync_search = *region + 1; |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 7145cd150f7b..d05e3125d298 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -1024,7 +1024,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) | |||
| 1024 | rdev-> sb_size = (rdev->sb_size | bmask)+1; | 1024 | rdev-> sb_size = (rdev->sb_size | bmask)+1; |
| 1025 | 1025 | ||
| 1026 | if (refdev == 0) | 1026 | if (refdev == 0) |
| 1027 | return 1; | 1027 | ret = 1; |
| 1028 | else { | 1028 | else { |
| 1029 | __u64 ev1, ev2; | 1029 | __u64 ev1, ev2; |
| 1030 | struct mdp_superblock_1 *refsb = | 1030 | struct mdp_superblock_1 *refsb = |
| @@ -1044,7 +1044,9 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) | |||
| 1044 | ev2 = le64_to_cpu(refsb->events); | 1044 | ev2 = le64_to_cpu(refsb->events); |
| 1045 | 1045 | ||
| 1046 | if (ev1 > ev2) | 1046 | if (ev1 > ev2) |
| 1047 | return 1; | 1047 | ret = 1; |
| 1048 | else | ||
| 1049 | ret = 0; | ||
| 1048 | } | 1050 | } |
| 1049 | if (minor_version) | 1051 | if (minor_version) |
| 1050 | rdev->size = ((rdev->bdev->bd_inode->i_size>>9) - le64_to_cpu(sb->data_offset)) / 2; | 1052 | rdev->size = ((rdev->bdev->bd_inode->i_size>>9) - le64_to_cpu(sb->data_offset)) / 2; |
| @@ -1058,7 +1060,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version) | |||
| 1058 | 1060 | ||
| 1059 | if (le32_to_cpu(sb->size) > rdev->size*2) | 1061 | if (le32_to_cpu(sb->size) > rdev->size*2) |
| 1060 | return -EINVAL; | 1062 | return -EINVAL; |
| 1061 | return 0; | 1063 | return ret; |
| 1062 | } | 1064 | } |
| 1063 | 1065 | ||
| 1064 | static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) | 1066 | static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) |
| @@ -1081,7 +1083,7 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 1081 | mddev->size = le64_to_cpu(sb->size)/2; | 1083 | mddev->size = le64_to_cpu(sb->size)/2; |
| 1082 | mddev->events = le64_to_cpu(sb->events); | 1084 | mddev->events = le64_to_cpu(sb->events); |
| 1083 | mddev->bitmap_offset = 0; | 1085 | mddev->bitmap_offset = 0; |
| 1084 | mddev->default_bitmap_offset = 1024; | 1086 | mddev->default_bitmap_offset = 1024 >> 9; |
| 1085 | 1087 | ||
| 1086 | mddev->recovery_cp = le64_to_cpu(sb->resync_offset); | 1088 | mddev->recovery_cp = le64_to_cpu(sb->resync_offset); |
| 1087 | memcpy(mddev->uuid, sb->set_uuid, 16); | 1089 | memcpy(mddev->uuid, sb->set_uuid, 16); |
| @@ -1161,6 +1163,9 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 1161 | 1163 | ||
| 1162 | sb->cnt_corrected_read = atomic_read(&rdev->corrected_errors); | 1164 | sb->cnt_corrected_read = atomic_read(&rdev->corrected_errors); |
| 1163 | 1165 | ||
| 1166 | sb->raid_disks = cpu_to_le32(mddev->raid_disks); | ||
| 1167 | sb->size = cpu_to_le64(mddev->size<<1); | ||
| 1168 | |||
| 1164 | if (mddev->bitmap && mddev->bitmap_file == NULL) { | 1169 | if (mddev->bitmap && mddev->bitmap_file == NULL) { |
| 1165 | sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset); | 1170 | sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset); |
| 1166 | sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); | 1171 | sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); |
| @@ -2686,14 +2691,6 @@ static int do_md_stop(mddev_t * mddev, int ro) | |||
| 2686 | set_disk_ro(disk, 1); | 2691 | set_disk_ro(disk, 1); |
| 2687 | } | 2692 | } |
| 2688 | 2693 | ||
| 2689 | bitmap_destroy(mddev); | ||
| 2690 | if (mddev->bitmap_file) { | ||
| 2691 | atomic_set(&mddev->bitmap_file->f_dentry->d_inode->i_writecount, 1); | ||
| 2692 | fput(mddev->bitmap_file); | ||
| 2693 | mddev->bitmap_file = NULL; | ||
| 2694 | } | ||
| 2695 | mddev->bitmap_offset = 0; | ||
| 2696 | |||
| 2697 | /* | 2694 | /* |
| 2698 | * Free resources if final stop | 2695 | * Free resources if final stop |
| 2699 | */ | 2696 | */ |
| @@ -2703,6 +2700,14 @@ static int do_md_stop(mddev_t * mddev, int ro) | |||
| 2703 | struct gendisk *disk; | 2700 | struct gendisk *disk; |
| 2704 | printk(KERN_INFO "md: %s stopped.\n", mdname(mddev)); | 2701 | printk(KERN_INFO "md: %s stopped.\n", mdname(mddev)); |
| 2705 | 2702 | ||
| 2703 | bitmap_destroy(mddev); | ||
| 2704 | if (mddev->bitmap_file) { | ||
| 2705 | atomic_set(&mddev->bitmap_file->f_dentry->d_inode->i_writecount, 1); | ||
| 2706 | fput(mddev->bitmap_file); | ||
| 2707 | mddev->bitmap_file = NULL; | ||
| 2708 | } | ||
| 2709 | mddev->bitmap_offset = 0; | ||
| 2710 | |||
| 2706 | ITERATE_RDEV(mddev,rdev,tmp) | 2711 | ITERATE_RDEV(mddev,rdev,tmp) |
| 2707 | if (rdev->raid_disk >= 0) { | 2712 | if (rdev->raid_disk >= 0) { |
| 2708 | char nm[20]; | 2713 | char nm[20]; |
| @@ -2939,6 +2944,8 @@ static int get_array_info(mddev_t * mddev, void __user * arg) | |||
| 2939 | info.ctime = mddev->ctime; | 2944 | info.ctime = mddev->ctime; |
| 2940 | info.level = mddev->level; | 2945 | info.level = mddev->level; |
| 2941 | info.size = mddev->size; | 2946 | info.size = mddev->size; |
| 2947 | if (info.size != mddev->size) /* overflow */ | ||
| 2948 | info.size = -1; | ||
| 2942 | info.nr_disks = nr; | 2949 | info.nr_disks = nr; |
| 2943 | info.raid_disks = mddev->raid_disks; | 2950 | info.raid_disks = mddev->raid_disks; |
| 2944 | info.md_minor = mddev->md_minor; | 2951 | info.md_minor = mddev->md_minor; |
| @@ -3465,7 +3472,7 @@ static int update_size(mddev_t *mddev, unsigned long size) | |||
| 3465 | bdev = bdget_disk(mddev->gendisk, 0); | 3472 | bdev = bdget_disk(mddev->gendisk, 0); |
| 3466 | if (bdev) { | 3473 | if (bdev) { |
| 3467 | mutex_lock(&bdev->bd_inode->i_mutex); | 3474 | mutex_lock(&bdev->bd_inode->i_mutex); |
| 3468 | i_size_write(bdev->bd_inode, mddev->array_size << 10); | 3475 | i_size_write(bdev->bd_inode, (loff_t)mddev->array_size << 10); |
| 3469 | mutex_unlock(&bdev->bd_inode->i_mutex); | 3476 | mutex_unlock(&bdev->bd_inode->i_mutex); |
| 3470 | bdput(bdev); | 3477 | bdput(bdev); |
| 3471 | } | 3478 | } |
| @@ -3485,17 +3492,6 @@ static int update_raid_disks(mddev_t *mddev, int raid_disks) | |||
| 3485 | if (mddev->sync_thread) | 3492 | if (mddev->sync_thread) |
| 3486 | return -EBUSY; | 3493 | return -EBUSY; |
| 3487 | rv = mddev->pers->reshape(mddev, raid_disks); | 3494 | rv = mddev->pers->reshape(mddev, raid_disks); |
| 3488 | if (!rv) { | ||
| 3489 | struct block_device *bdev; | ||
| 3490 | |||
| 3491 | bdev = bdget_disk(mddev->gendisk, 0); | ||
| 3492 | if (bdev) { | ||
| 3493 | mutex_lock(&bdev->bd_inode->i_mutex); | ||
| 3494 | i_size_write(bdev->bd_inode, mddev->array_size << 10); | ||
| 3495 | mutex_unlock(&bdev->bd_inode->i_mutex); | ||
| 3496 | bdput(bdev); | ||
| 3497 | } | ||
| 3498 | } | ||
| 3499 | return rv; | 3495 | return rv; |
| 3500 | } | 3496 | } |
| 3501 | 3497 | ||
| @@ -3531,7 +3527,7 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info) | |||
| 3531 | ) | 3527 | ) |
| 3532 | return -EINVAL; | 3528 | return -EINVAL; |
| 3533 | /* Check there is only one change */ | 3529 | /* Check there is only one change */ |
| 3534 | if (mddev->size != info->size) cnt++; | 3530 | if (info->size >= 0 && mddev->size != info->size) cnt++; |
| 3535 | if (mddev->raid_disks != info->raid_disks) cnt++; | 3531 | if (mddev->raid_disks != info->raid_disks) cnt++; |
| 3536 | if (mddev->layout != info->layout) cnt++; | 3532 | if (mddev->layout != info->layout) cnt++; |
| 3537 | if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT)) cnt++; | 3533 | if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT)) cnt++; |
| @@ -3548,7 +3544,7 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info) | |||
| 3548 | else | 3544 | else |
| 3549 | return mddev->pers->reconfig(mddev, info->layout, -1); | 3545 | return mddev->pers->reconfig(mddev, info->layout, -1); |
| 3550 | } | 3546 | } |
| 3551 | if (mddev->size != info->size) | 3547 | if (info->size >= 0 && mddev->size != info->size) |
| 3552 | rv = update_size(mddev, info->size); | 3548 | rv = update_size(mddev, info->size); |
| 3553 | 3549 | ||
| 3554 | if (mddev->raid_disks != info->raid_disks) | 3550 | if (mddev->raid_disks != info->raid_disks) |
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index d03f99cf4b7d..678f4dbbea1d 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c | |||
| @@ -372,7 +372,7 @@ out_free_conf: | |||
| 372 | kfree(conf); | 372 | kfree(conf); |
| 373 | mddev->private = NULL; | 373 | mddev->private = NULL; |
| 374 | out: | 374 | out: |
| 375 | return 1; | 375 | return -ENOMEM; |
| 376 | } | 376 | } |
| 377 | 377 | ||
| 378 | static int raid0_stop (mddev_t *mddev) | 378 | static int raid0_stop (mddev_t *mddev) |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 9130d051b474..ab90a6d12020 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
| @@ -565,6 +565,8 @@ rb_out: | |||
| 565 | 565 | ||
| 566 | if (disk >= 0 && (rdev=rcu_dereference(conf->mirrors[disk].rdev))!= NULL) | 566 | if (disk >= 0 && (rdev=rcu_dereference(conf->mirrors[disk].rdev))!= NULL) |
| 567 | atomic_inc(&conf->mirrors[disk].rdev->nr_pending); | 567 | atomic_inc(&conf->mirrors[disk].rdev->nr_pending); |
| 568 | else | ||
| 569 | disk = -1; | ||
| 568 | rcu_read_unlock(); | 570 | rcu_read_unlock(); |
| 569 | 571 | ||
| 570 | return disk; | 572 | return disk; |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 25976bfb6f9c..2dba305daf3c 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
| @@ -350,7 +350,8 @@ static void shrink_stripes(raid5_conf_t *conf) | |||
| 350 | while (drop_one_stripe(conf)) | 350 | while (drop_one_stripe(conf)) |
| 351 | ; | 351 | ; |
| 352 | 352 | ||
| 353 | kmem_cache_destroy(conf->slab_cache); | 353 | if (conf->slab_cache) |
| 354 | kmem_cache_destroy(conf->slab_cache); | ||
| 354 | conf->slab_cache = NULL; | 355 | conf->slab_cache = NULL; |
| 355 | } | 356 | } |
| 356 | 357 | ||
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c index f618a53b98be..cd477ebf2ee4 100644 --- a/drivers/md/raid6main.c +++ b/drivers/md/raid6main.c | |||
| @@ -115,7 +115,7 @@ static void __release_stripe(raid6_conf_t *conf, struct stripe_head *sh) | |||
| 115 | list_add_tail(&sh->lru, &conf->inactive_list); | 115 | list_add_tail(&sh->lru, &conf->inactive_list); |
| 116 | atomic_dec(&conf->active_stripes); | 116 | atomic_dec(&conf->active_stripes); |
| 117 | if (!conf->inactive_blocked || | 117 | if (!conf->inactive_blocked || |
| 118 | atomic_read(&conf->active_stripes) < (NR_STRIPES*3/4)) | 118 | atomic_read(&conf->active_stripes) < (conf->max_nr_stripes*3/4)) |
| 119 | wake_up(&conf->wait_for_stripe); | 119 | wake_up(&conf->wait_for_stripe); |
| 120 | } | 120 | } |
| 121 | } | 121 | } |
| @@ -273,7 +273,8 @@ static struct stripe_head *get_active_stripe(raid6_conf_t *conf, sector_t sector | |||
| 273 | conf->inactive_blocked = 1; | 273 | conf->inactive_blocked = 1; |
| 274 | wait_event_lock_irq(conf->wait_for_stripe, | 274 | wait_event_lock_irq(conf->wait_for_stripe, |
| 275 | !list_empty(&conf->inactive_list) && | 275 | !list_empty(&conf->inactive_list) && |
| 276 | (atomic_read(&conf->active_stripes) < (NR_STRIPES *3/4) | 276 | (atomic_read(&conf->active_stripes) |
| 277 | < (conf->max_nr_stripes *3/4) | ||
| 277 | || !conf->inactive_blocked), | 278 | || !conf->inactive_blocked), |
| 278 | conf->device_lock, | 279 | conf->device_lock, |
| 279 | unplug_slaves(conf->mddev); | 280 | unplug_slaves(conf->mddev); |
| @@ -302,9 +303,31 @@ static struct stripe_head *get_active_stripe(raid6_conf_t *conf, sector_t sector | |||
| 302 | return sh; | 303 | return sh; |
| 303 | } | 304 | } |
| 304 | 305 | ||
| 305 | static int grow_stripes(raid6_conf_t *conf, int num) | 306 | static int grow_one_stripe(raid6_conf_t *conf) |
| 306 | { | 307 | { |
| 307 | struct stripe_head *sh; | 308 | struct stripe_head *sh; |
| 309 | sh = kmem_cache_alloc(conf->slab_cache, GFP_KERNEL); | ||
| 310 | if (!sh) | ||
| 311 | return 0; | ||
| 312 | memset(sh, 0, sizeof(*sh) + (conf->raid_disks-1)*sizeof(struct r5dev)); | ||
| 313 | sh->raid_conf = conf; | ||
| 314 | spin_lock_init(&sh->lock); | ||
| 315 | |||
| 316 | if (grow_buffers(sh, conf->raid_disks)) { | ||
| 317 | shrink_buffers(sh, conf->raid_disks); | ||
| 318 | kmem_cache_free(conf->slab_cache, sh); | ||
| 319 | return 0; | ||
| 320 | } | ||
| 321 | /* we just created an active stripe so... */ | ||
| 322 | atomic_set(&sh->count, 1); | ||
| 323 | atomic_inc(&conf->active_stripes); | ||
| 324 | INIT_LIST_HEAD(&sh->lru); | ||
| 325 | release_stripe(sh); | ||
| 326 | return 1; | ||
| 327 | } | ||
| 328 | |||
| 329 | static int grow_stripes(raid6_conf_t *conf, int num) | ||
| 330 | { | ||
| 308 | kmem_cache_t *sc; | 331 | kmem_cache_t *sc; |
| 309 | int devs = conf->raid_disks; | 332 | int devs = conf->raid_disks; |
| 310 | 333 | ||
| @@ -316,45 +339,35 @@ static int grow_stripes(raid6_conf_t *conf, int num) | |||
| 316 | if (!sc) | 339 | if (!sc) |
| 317 | return 1; | 340 | return 1; |
| 318 | conf->slab_cache = sc; | 341 | conf->slab_cache = sc; |
| 319 | while (num--) { | 342 | while (num--) |
| 320 | sh = kmem_cache_alloc(sc, GFP_KERNEL); | 343 | if (!grow_one_stripe(conf)) |
| 321 | if (!sh) | ||
| 322 | return 1; | ||
| 323 | memset(sh, 0, sizeof(*sh) + (devs-1)*sizeof(struct r5dev)); | ||
| 324 | sh->raid_conf = conf; | ||
| 325 | spin_lock_init(&sh->lock); | ||
| 326 | |||
| 327 | if (grow_buffers(sh, conf->raid_disks)) { | ||
| 328 | shrink_buffers(sh, conf->raid_disks); | ||
| 329 | kmem_cache_free(sc, sh); | ||
| 330 | return 1; | 344 | return 1; |
| 331 | } | ||
| 332 | /* we just created an active stripe so... */ | ||
| 333 | atomic_set(&sh->count, 1); | ||
| 334 | atomic_inc(&conf->active_stripes); | ||
| 335 | INIT_LIST_HEAD(&sh->lru); | ||
| 336 | release_stripe(sh); | ||
| 337 | } | ||
| 338 | return 0; | 345 | return 0; |
| 339 | } | 346 | } |
| 340 | 347 | ||
| 341 | static void shrink_stripes(raid6_conf_t *conf) | 348 | static int drop_one_stripe(raid6_conf_t *conf) |
| 342 | { | 349 | { |
| 343 | struct stripe_head *sh; | 350 | struct stripe_head *sh; |
| 351 | spin_lock_irq(&conf->device_lock); | ||
| 352 | sh = get_free_stripe(conf); | ||
| 353 | spin_unlock_irq(&conf->device_lock); | ||
| 354 | if (!sh) | ||
| 355 | return 0; | ||
| 356 | if (atomic_read(&sh->count)) | ||
| 357 | BUG(); | ||
| 358 | shrink_buffers(sh, conf->raid_disks); | ||
| 359 | kmem_cache_free(conf->slab_cache, sh); | ||
| 360 | atomic_dec(&conf->active_stripes); | ||
| 361 | return 1; | ||
| 362 | } | ||
| 344 | 363 | ||
| 345 | while (1) { | 364 | static void shrink_stripes(raid6_conf_t *conf) |
| 346 | spin_lock_irq(&conf->device_lock); | 365 | { |
| 347 | sh = get_free_stripe(conf); | 366 | while (drop_one_stripe(conf)) |
| 348 | spin_unlock_irq(&conf->device_lock); | 367 | ; |
| 349 | if (!sh) | 368 | |
| 350 | break; | 369 | if (conf->slab_cache) |
| 351 | if (atomic_read(&sh->count)) | 370 | kmem_cache_destroy(conf->slab_cache); |
| 352 | BUG(); | ||
| 353 | shrink_buffers(sh, conf->raid_disks); | ||
| 354 | kmem_cache_free(conf->slab_cache, sh); | ||
| 355 | atomic_dec(&conf->active_stripes); | ||
| 356 | } | ||
| 357 | kmem_cache_destroy(conf->slab_cache); | ||
| 358 | conf->slab_cache = NULL; | 371 | conf->slab_cache = NULL; |
| 359 | } | 372 | } |
| 360 | 373 | ||
| @@ -1912,6 +1925,74 @@ static void raid6d (mddev_t *mddev) | |||
| 1912 | PRINTK("--- raid6d inactive\n"); | 1925 | PRINTK("--- raid6d inactive\n"); |
| 1913 | } | 1926 | } |
| 1914 | 1927 | ||
| 1928 | static ssize_t | ||
| 1929 | raid6_show_stripe_cache_size(mddev_t *mddev, char *page) | ||
| 1930 | { | ||
| 1931 | raid6_conf_t *conf = mddev_to_conf(mddev); | ||
| 1932 | if (conf) | ||
| 1933 | return sprintf(page, "%d\n", conf->max_nr_stripes); | ||
| 1934 | else | ||
| 1935 | return 0; | ||
| 1936 | } | ||
| 1937 | |||
| 1938 | static ssize_t | ||
| 1939 | raid6_store_stripe_cache_size(mddev_t *mddev, const char *page, size_t len) | ||
| 1940 | { | ||
| 1941 | raid6_conf_t *conf = mddev_to_conf(mddev); | ||
| 1942 | char *end; | ||
| 1943 | int new; | ||
| 1944 | if (len >= PAGE_SIZE) | ||
| 1945 | return -EINVAL; | ||
| 1946 | if (!conf) | ||
| 1947 | return -ENODEV; | ||
| 1948 | |||
| 1949 | new = simple_strtoul(page, &end, 10); | ||
| 1950 | if (!*page || (*end && *end != '\n') ) | ||
| 1951 | return -EINVAL; | ||
| 1952 | if (new <= 16 || new > 32768) | ||
| 1953 | return -EINVAL; | ||
| 1954 | while (new < conf->max_nr_stripes) { | ||
| 1955 | if (drop_one_stripe(conf)) | ||
| 1956 | conf->max_nr_stripes--; | ||
| 1957 | else | ||
| 1958 | break; | ||
| 1959 | } | ||
| 1960 | while (new > conf->max_nr_stripes) { | ||
| 1961 | if (grow_one_stripe(conf)) | ||
| 1962 | conf->max_nr_stripes++; | ||
| 1963 | else break; | ||
| 1964 | } | ||
| 1965 | return len; | ||
| 1966 | } | ||
| 1967 | |||
| 1968 | static struct md_sysfs_entry | ||
| 1969 | raid6_stripecache_size = __ATTR(stripe_cache_size, S_IRUGO | S_IWUSR, | ||
| 1970 | raid6_show_stripe_cache_size, | ||
| 1971 | raid6_store_stripe_cache_size); | ||
| 1972 | |||
| 1973 | static ssize_t | ||
| 1974 | stripe_cache_active_show(mddev_t *mddev, char *page) | ||
| 1975 | { | ||
| 1976 | raid6_conf_t *conf = mddev_to_conf(mddev); | ||
| 1977 | if (conf) | ||
| 1978 | return sprintf(page, "%d\n", atomic_read(&conf->active_stripes)); | ||
| 1979 | else | ||
| 1980 | return 0; | ||
| 1981 | } | ||
| 1982 | |||
| 1983 | static struct md_sysfs_entry | ||
| 1984 | raid6_stripecache_active = __ATTR_RO(stripe_cache_active); | ||
| 1985 | |||
| 1986 | static struct attribute *raid6_attrs[] = { | ||
| 1987 | &raid6_stripecache_size.attr, | ||
| 1988 | &raid6_stripecache_active.attr, | ||
| 1989 | NULL, | ||
| 1990 | }; | ||
| 1991 | static struct attribute_group raid6_attrs_group = { | ||
| 1992 | .name = NULL, | ||
| 1993 | .attrs = raid6_attrs, | ||
| 1994 | }; | ||
| 1995 | |||
| 1915 | static int run(mddev_t *mddev) | 1996 | static int run(mddev_t *mddev) |
| 1916 | { | 1997 | { |
| 1917 | raid6_conf_t *conf; | 1998 | raid6_conf_t *conf; |
| @@ -2095,6 +2176,7 @@ static int stop (mddev_t *mddev) | |||
| 2095 | shrink_stripes(conf); | 2176 | shrink_stripes(conf); |
| 2096 | kfree(conf->stripe_hashtbl); | 2177 | kfree(conf->stripe_hashtbl); |
| 2097 | blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ | 2178 | blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ |
| 2179 | sysfs_remove_group(&mddev->kobj, &raid6_attrs_group); | ||
| 2098 | kfree(conf); | 2180 | kfree(conf); |
| 2099 | mddev->private = NULL; | 2181 | mddev->private = NULL; |
| 2100 | return 0; | 2182 | return 0; |
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig index 2583a865a58e..2963605c0ecc 100644 --- a/drivers/media/dvb/b2c2/Kconfig +++ b/drivers/media/dvb/b2c2/Kconfig | |||
| @@ -4,7 +4,7 @@ config DVB_B2C2_FLEXCOP | |||
| 4 | select DVB_STV0299 | 4 | select DVB_STV0299 |
| 5 | select DVB_MT352 | 5 | select DVB_MT352 |
| 6 | select DVB_MT312 | 6 | select DVB_MT312 |
| 7 | select DVB_NXT2002 | 7 | select DVB_NXT200X |
| 8 | select DVB_STV0297 | 8 | select DVB_STV0297 |
| 9 | select DVB_BCM3510 | 9 | select DVB_BCM3510 |
| 10 | select DVB_LGDT330X | 10 | select DVB_LGDT330X |
diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h index 344a3c898460..7d7e1613c5a7 100644 --- a/drivers/media/dvb/b2c2/flexcop-common.h +++ b/drivers/media/dvb/b2c2/flexcop-common.h | |||
| @@ -116,11 +116,9 @@ void flexcop_dma_free(struct flexcop_dma *dma); | |||
| 116 | 116 | ||
| 117 | int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff); | 117 | int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff); |
| 118 | int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff); | 118 | int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff); |
| 119 | int flexcop_dma_control_packet_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff); | ||
| 120 | int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx); | 119 | int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx); |
| 121 | int flexcop_dma_xfer_control(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index, int onoff); | 120 | int flexcop_dma_xfer_control(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index, int onoff); |
| 122 | int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles); | 121 | int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles); |
| 123 | int flexcop_dma_config_packet_count(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 packets); | ||
| 124 | 122 | ||
| 125 | /* from flexcop-eeprom.c */ | 123 | /* from flexcop-eeprom.c */ |
| 126 | /* the PCI part uses this call to get the MAC address, the USB part has its own */ | 124 | /* the PCI part uses this call to get the MAC address, the USB part has its own */ |
diff --git a/drivers/media/dvb/b2c2/flexcop-dma.c b/drivers/media/dvb/b2c2/flexcop-dma.c index cf4ed1df6086..6f592bc32d22 100644 --- a/drivers/media/dvb/b2c2/flexcop-dma.c +++ b/drivers/media/dvb/b2c2/flexcop-dma.c | |||
| @@ -169,38 +169,3 @@ int flexcop_dma_config_timer(struct flexcop_device *fc, | |||
| 169 | } | 169 | } |
| 170 | EXPORT_SYMBOL(flexcop_dma_config_timer); | 170 | EXPORT_SYMBOL(flexcop_dma_config_timer); |
| 171 | 171 | ||
| 172 | /* packet IRQ does not exist in FCII or FCIIb - according to data book and tests */ | ||
| 173 | int flexcop_dma_control_packet_irq(struct flexcop_device *fc, | ||
| 174 | flexcop_dma_index_t no, | ||
| 175 | int onoff) | ||
| 176 | { | ||
| 177 | flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208); | ||
| 178 | |||
| 179 | deb_rdump("reg: %03x: %x\n",ctrl_208,v.raw); | ||
| 180 | if (no & FC_DMA_1) | ||
| 181 | v.ctrl_208.DMA1_Size_IRQ_Enable_sig = onoff; | ||
| 182 | |||
| 183 | if (no & FC_DMA_2) | ||
| 184 | v.ctrl_208.DMA2_Size_IRQ_Enable_sig = onoff; | ||
| 185 | |||
| 186 | fc->write_ibi_reg(fc,ctrl_208,v); | ||
| 187 | deb_rdump("reg: %03x: %x\n",ctrl_208,v.raw); | ||
| 188 | |||
| 189 | return 0; | ||
| 190 | } | ||
| 191 | EXPORT_SYMBOL(flexcop_dma_control_packet_irq); | ||
| 192 | |||
| 193 | int flexcop_dma_config_packet_count(struct flexcop_device *fc, | ||
| 194 | flexcop_dma_index_t dma_idx, | ||
| 195 | u8 packets) | ||
| 196 | { | ||
| 197 | flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014; | ||
| 198 | flexcop_ibi_value v = fc->read_ibi_reg(fc,r); | ||
| 199 | |||
| 200 | flexcop_dma_remap(fc,dma_idx,1); | ||
| 201 | |||
| 202 | v.dma_0x4_remap.DMA_maxpackets = packets; | ||
| 203 | fc->write_ibi_reg(fc,r,v); | ||
| 204 | return 0; | ||
| 205 | } | ||
| 206 | EXPORT_SYMBOL(flexcop_dma_config_packet_count); | ||
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c index 0b940e152b79..390cc3a99ce6 100644 --- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c +++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | 9 | ||
| 10 | #include "stv0299.h" | 10 | #include "stv0299.h" |
| 11 | #include "mt352.h" | 11 | #include "mt352.h" |
| 12 | #include "nxt2002.h" | 12 | #include "nxt200x.h" |
| 13 | #include "bcm3510.h" | 13 | #include "bcm3510.h" |
| 14 | #include "stv0297.h" | 14 | #include "stv0297.h" |
| 15 | #include "mt312.h" | 15 | #include "mt312.h" |
| @@ -343,9 +343,10 @@ static struct lgdt330x_config air2pc_atsc_hd5000_config = { | |||
| 343 | .clock_polarity_flip = 1, | 343 | .clock_polarity_flip = 1, |
| 344 | }; | 344 | }; |
| 345 | 345 | ||
| 346 | static struct nxt2002_config samsung_tbmv_config = { | 346 | static struct nxt200x_config samsung_tbmv_config = { |
| 347 | .demod_address = 0x0a, | 347 | .demod_address = 0x0a, |
| 348 | .request_firmware = flexcop_fe_request_firmware, | 348 | .pll_address = 0xc2, |
| 349 | .pll_desc = &dvb_pll_samsung_tbmv, | ||
| 349 | }; | 350 | }; |
| 350 | 351 | ||
| 351 | static struct bcm3510_config air2pc_atsc_first_gen_config = { | 352 | static struct bcm3510_config air2pc_atsc_first_gen_config = { |
| @@ -505,7 +506,7 @@ int flexcop_frontend_init(struct flexcop_device *fc) | |||
| 505 | info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address); | 506 | info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address); |
| 506 | } else | 507 | } else |
| 507 | /* try the air atsc 2nd generation (nxt2002) */ | 508 | /* try the air atsc 2nd generation (nxt2002) */ |
| 508 | if ((fc->fe = nxt2002_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) { | 509 | if ((fc->fe = nxt200x_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) { |
| 509 | fc->dev_type = FC_AIR_ATSC2; | 510 | fc->dev_type = FC_AIR_ATSC2; |
| 510 | info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address); | 511 | info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address); |
| 511 | } else | 512 | } else |
diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c index 62282d8dbfa8..167583bf0621 100644 --- a/drivers/media/dvb/b2c2/flexcop-misc.c +++ b/drivers/media/dvb/b2c2/flexcop-misc.c | |||
| @@ -36,14 +36,14 @@ void flexcop_determine_revision(struct flexcop_device *fc) | |||
| 36 | /* bus parts have to decide if hw pid filtering is used or not. */ | 36 | /* bus parts have to decide if hw pid filtering is used or not. */ |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | const char *flexcop_revision_names[] = { | 39 | static const char *flexcop_revision_names[] = { |
| 40 | "Unkown chip", | 40 | "Unkown chip", |
| 41 | "FlexCopII", | 41 | "FlexCopII", |
| 42 | "FlexCopIIb", | 42 | "FlexCopIIb", |
| 43 | "FlexCopIII", | 43 | "FlexCopIII", |
| 44 | }; | 44 | }; |
| 45 | 45 | ||
| 46 | const char *flexcop_device_names[] = { | 46 | static const char *flexcop_device_names[] = { |
| 47 | "Unkown device", | 47 | "Unkown device", |
| 48 | "Air2PC/AirStar 2 DVB-T", | 48 | "Air2PC/AirStar 2 DVB-T", |
| 49 | "Air2PC/AirStar 2 ATSC 1st generation", | 49 | "Air2PC/AirStar 2 ATSC 1st generation", |
| @@ -54,7 +54,7 @@ const char *flexcop_device_names[] = { | |||
| 54 | "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)", | 54 | "Air2PC/AirStar 2 ATSC 3rd generation (HD5000)", |
| 55 | }; | 55 | }; |
| 56 | 56 | ||
| 57 | const char *flexcop_bus_names[] = { | 57 | static const char *flexcop_bus_names[] = { |
| 58 | "USB", | 58 | "USB", |
| 59 | "PCI", | 59 | "PCI", |
| 60 | }; | 60 | }; |
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c index 2f76eb3fea40..9bc40bdcc282 100644 --- a/drivers/media/dvb/b2c2/flexcop-pci.c +++ b/drivers/media/dvb/b2c2/flexcop-pci.c | |||
| @@ -161,8 +161,10 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
| 161 | fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2; | 161 | fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2; |
| 162 | u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0; | 162 | u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0; |
| 163 | 163 | ||
| 164 | deb_irq("%u irq: %08x cur_addr: %08x: cur_pos: %08x, last_cur_pos: %08x ", | 164 | deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, last_cur_pos: %08x ", |
| 165 | jiffies_to_usecs(jiffies - fc_pci->last_irq),v.raw,cur_addr,cur_pos,fc_pci->last_dma1_cur_pos); | 165 | jiffies_to_usecs(jiffies - fc_pci->last_irq), |
| 166 | v.raw, (unsigned long long)cur_addr, cur_pos, | ||
| 167 | fc_pci->last_dma1_cur_pos); | ||
| 166 | fc_pci->last_irq = jiffies; | 168 | fc_pci->last_irq = jiffies; |
| 167 | 169 | ||
| 168 | /* buffer end was reached, restarted from the beginning | 170 | /* buffer end was reached, restarted from the beginning |
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h index 3153f9513c63..491f9bd6e195 100644 --- a/drivers/media/dvb/b2c2/flexcop-reg.h +++ b/drivers/media/dvb/b2c2/flexcop-reg.h | |||
| @@ -16,8 +16,6 @@ typedef enum { | |||
| 16 | FLEXCOP_III, | 16 | FLEXCOP_III, |
| 17 | } flexcop_revision_t; | 17 | } flexcop_revision_t; |
| 18 | 18 | ||
| 19 | extern const char *flexcop_revision_names[]; | ||
| 20 | |||
| 21 | typedef enum { | 19 | typedef enum { |
| 22 | FC_UNK = 0, | 20 | FC_UNK = 0, |
| 23 | FC_AIR_DVB, | 21 | FC_AIR_DVB, |
| @@ -34,8 +32,6 @@ typedef enum { | |||
| 34 | FC_PCI, | 32 | FC_PCI, |
| 35 | } flexcop_bus_t; | 33 | } flexcop_bus_t; |
| 36 | 34 | ||
| 37 | extern const char *flexcop_device_names[]; | ||
| 38 | |||
| 39 | /* FlexCop IBI Registers */ | 35 | /* FlexCop IBI Registers */ |
| 40 | #if defined(__LITTLE_ENDIAN) | 36 | #if defined(__LITTLE_ENDIAN) |
| 41 | #include "flexcop_ibi_value_le.h" | 37 | #include "flexcop_ibi_value_le.h" |
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c index a04bb61f21f4..34c3189a1a33 100644 --- a/drivers/media/dvb/bt8xx/bt878.c +++ b/drivers/media/dvb/bt8xx/bt878.c | |||
| @@ -381,6 +381,23 @@ bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet * | |||
| 381 | 381 | ||
| 382 | EXPORT_SYMBOL(bt878_device_control); | 382 | EXPORT_SYMBOL(bt878_device_control); |
| 383 | 383 | ||
| 384 | |||
| 385 | struct cards card_list[] __devinitdata = { | ||
| 386 | |||
| 387 | { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" }, | ||
| 388 | { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" }, | ||
| 389 | { 0x001c11bd, BTTV_BOARD_PINNACLESAT, "Pinnacle PCTV Sat" }, | ||
| 390 | { 0x002611bd, BTTV_BOARD_TWINHAN_DST, "Pinnacle PCTV SAT CI" }, | ||
| 391 | { 0x00011822, BTTV_BOARD_TWINHAN_DST, "Twinhan VisionPlus DVB" }, | ||
| 392 | { 0xfc00270f, BTTV_BOARD_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" }, | ||
| 393 | { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" }, | ||
| 394 | { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" }, | ||
| 395 | { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" }, | ||
| 396 | { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV"}, | ||
| 397 | { 0, -1, NULL } | ||
| 398 | }; | ||
| 399 | |||
| 400 | |||
| 384 | /***********************/ | 401 | /***********************/ |
| 385 | /* PCI device handling */ | 402 | /* PCI device handling */ |
| 386 | /***********************/ | 403 | /***********************/ |
| @@ -388,18 +405,41 @@ EXPORT_SYMBOL(bt878_device_control); | |||
| 388 | static int __devinit bt878_probe(struct pci_dev *dev, | 405 | static int __devinit bt878_probe(struct pci_dev *dev, |
| 389 | const struct pci_device_id *pci_id) | 406 | const struct pci_device_id *pci_id) |
| 390 | { | 407 | { |
| 391 | int result; | 408 | int result = 0, has_dvb = 0, i; |
| 392 | unsigned char lat; | 409 | unsigned char lat; |
| 393 | struct bt878 *bt; | 410 | struct bt878 *bt; |
| 394 | #if defined(__powerpc__) | 411 | #if defined(__powerpc__) |
| 395 | unsigned int cmd; | 412 | unsigned int cmd; |
| 396 | #endif | 413 | #endif |
| 414 | unsigned int cardid; | ||
| 415 | unsigned short id; | ||
| 416 | struct cards *dvb_cards; | ||
| 397 | 417 | ||
| 398 | printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n", | 418 | printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n", |
| 399 | bt878_num); | 419 | bt878_num); |
| 400 | if (pci_enable_device(dev)) | 420 | if (pci_enable_device(dev)) |
| 401 | return -EIO; | 421 | return -EIO; |
| 402 | 422 | ||
| 423 | pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &id); | ||
| 424 | cardid = id << 16; | ||
| 425 | pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &id); | ||
| 426 | cardid |= id; | ||
| 427 | |||
| 428 | for (i = 0, dvb_cards = card_list; i < ARRAY_SIZE(card_list); i++, dvb_cards++) { | ||
| 429 | if (cardid == dvb_cards->pci_id) { | ||
| 430 | printk("%s: card id=[0x%x],[ %s ] has DVB functions.\n", | ||
| 431 | __func__, cardid, dvb_cards->name); | ||
| 432 | has_dvb = 1; | ||
| 433 | } | ||
| 434 | } | ||
| 435 | |||
| 436 | if (!has_dvb) { | ||
| 437 | printk("%s: card id=[0x%x], Unknown card.\nExiting..\n", __func__, cardid); | ||
| 438 | result = -EINVAL; | ||
| 439 | |||
| 440 | goto fail0; | ||
| 441 | } | ||
| 442 | |||
| 403 | bt = &bt878[bt878_num]; | 443 | bt = &bt878[bt878_num]; |
| 404 | bt->dev = dev; | 444 | bt->dev = dev; |
| 405 | bt->nr = bt878_num; | 445 | bt->nr = bt878_num; |
| @@ -416,6 +456,8 @@ static int __devinit bt878_probe(struct pci_dev *dev, | |||
| 416 | 456 | ||
| 417 | pci_read_config_byte(dev, PCI_CLASS_REVISION, &bt->revision); | 457 | pci_read_config_byte(dev, PCI_CLASS_REVISION, &bt->revision); |
| 418 | pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); | 458 | pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); |
| 459 | |||
| 460 | |||
| 419 | printk(KERN_INFO "bt878(%d): Bt%x (rev %d) at %02x:%02x.%x, ", | 461 | printk(KERN_INFO "bt878(%d): Bt%x (rev %d) at %02x:%02x.%x, ", |
| 420 | bt878_num, bt->id, bt->revision, dev->bus->number, | 462 | bt878_num, bt->id, bt->revision, dev->bus->number, |
| 421 | PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); | 463 | PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); |
diff --git a/drivers/media/dvb/bt8xx/bt878.h b/drivers/media/dvb/bt8xx/bt878.h index a73baf00ca39..9faf93770d08 100644 --- a/drivers/media/dvb/bt8xx/bt878.h +++ b/drivers/media/dvb/bt8xx/bt878.h | |||
| @@ -88,6 +88,23 @@ | |||
| 88 | 88 | ||
| 89 | #define BT878_RISC_SYNC_MASK (1 << 15) | 89 | #define BT878_RISC_SYNC_MASK (1 << 15) |
| 90 | 90 | ||
| 91 | |||
| 92 | #define BTTV_BOARD_UNKNOWN 0x00 | ||
| 93 | #define BTTV_BOARD_PINNACLESAT 0x5e | ||
| 94 | #define BTTV_BOARD_NEBULA_DIGITV 0x68 | ||
| 95 | #define BTTV_BOARD_PC_HDTV 0x70 | ||
| 96 | #define BTTV_BOARD_TWINHAN_DST 0x71 | ||
| 97 | #define BTTV_BOARD_AVDVBT_771 0x7b | ||
| 98 | #define BTTV_BOARD_AVDVBT_761 0x7c | ||
| 99 | #define BTTV_BOARD_DVICO_DVBT_LITE 0x80 | ||
| 100 | #define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87 | ||
| 101 | |||
| 102 | struct cards { | ||
| 103 | __u32 pci_id; | ||
| 104 | __u16 card_id; | ||
| 105 | char *name; | ||
| 106 | }; | ||
| 107 | |||
| 91 | extern int bt878_num; | 108 | extern int bt878_num; |
| 92 | 109 | ||
| 93 | struct bt878 { | 110 | struct bt878 { |
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 90a69d343b79..d3df12039b06 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig | |||
| @@ -83,12 +83,18 @@ config DVB_USB_UMT_010 | |||
| 83 | Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver. | 83 | Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver. |
| 84 | 84 | ||
| 85 | config DVB_USB_CXUSB | 85 | config DVB_USB_CXUSB |
| 86 | tristate "Medion MD95700 hybrid USB2.0 (Conexant) support" | 86 | tristate "Conexant USB2.0 hybrid reference design support" |
| 87 | depends on DVB_USB | 87 | depends on DVB_USB |
| 88 | select DVB_CX22702 | 88 | select DVB_CX22702 |
| 89 | select DVB_LGDT330X | ||
| 90 | select DVB_MT352 | ||
| 89 | help | 91 | help |
| 90 | Say Y here to support the Medion MD95700 hybrid USB2.0 device. Currently | 92 | Say Y here to support the Conexant USB2.0 hybrid reference design. |
| 91 | only the DVB-T part is supported. | 93 | Currently, only DVB and ATSC modes are supported, analog mode |
| 94 | shall be added in the future. Devices that require this module: | ||
| 95 | |||
| 96 | Medion MD95700 hybrid USB2.0 device. | ||
| 97 | DViCO FusionHDTV (Bluebird) USB2.0 devices | ||
| 92 | 98 | ||
| 93 | config DVB_USB_DIGITV | 99 | config DVB_USB_DIGITV |
| 94 | tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support" | 100 | tristate "Nebula Electronics uDigiTV DVB-T USB2.0 support" |
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index a7fb06f4cd34..f327fac1688e 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c | |||
| @@ -184,7 +184,7 @@ static int cxusb_rc_query(struct dvb_usb_device *d, u32 *event, int *state) | |||
| 184 | return 0; | 184 | return 0; |
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | struct dvb_usb_rc_key dvico_mce_rc_keys[] = { | 187 | static struct dvb_usb_rc_key dvico_mce_rc_keys[] = { |
| 188 | { 0xfe, 0x02, KEY_TV }, | 188 | { 0xfe, 0x02, KEY_TV }, |
| 189 | { 0xfe, 0x0e, KEY_MP3 }, | 189 | { 0xfe, 0x0e, KEY_MP3 }, |
| 190 | { 0xfe, 0x1a, KEY_DVD }, | 190 | { 0xfe, 0x1a, KEY_DVD }, |
| @@ -234,7 +234,7 @@ struct dvb_usb_rc_key dvico_mce_rc_keys[] = { | |||
| 234 | 234 | ||
| 235 | static int cxusb_dee1601_demod_init(struct dvb_frontend* fe) | 235 | static int cxusb_dee1601_demod_init(struct dvb_frontend* fe) |
| 236 | { | 236 | { |
| 237 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 }; | 237 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 }; |
| 238 | static u8 reset [] = { RESET, 0x80 }; | 238 | static u8 reset [] = { RESET, 0x80 }; |
| 239 | static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; | 239 | static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; |
| 240 | static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 }; | 240 | static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 }; |
| @@ -255,7 +255,7 @@ static int cxusb_dee1601_demod_init(struct dvb_frontend* fe) | |||
| 255 | 255 | ||
| 256 | static int cxusb_mt352_demod_init(struct dvb_frontend* fe) | 256 | static int cxusb_mt352_demod_init(struct dvb_frontend* fe) |
| 257 | { /* used in both lgz201 and th7579 */ | 257 | { /* used in both lgz201 and th7579 */ |
| 258 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 }; | 258 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x29 }; |
| 259 | static u8 reset [] = { RESET, 0x80 }; | 259 | static u8 reset [] = { RESET, 0x80 }; |
| 260 | static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; | 260 | static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; |
| 261 | static u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 }; | 261 | static u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 }; |
| @@ -273,7 +273,7 @@ static int cxusb_mt352_demod_init(struct dvb_frontend* fe) | |||
| 273 | return 0; | 273 | return 0; |
| 274 | } | 274 | } |
| 275 | 275 | ||
| 276 | struct cx22702_config cxusb_cx22702_config = { | 276 | static struct cx22702_config cxusb_cx22702_config = { |
| 277 | .demod_address = 0x63, | 277 | .demod_address = 0x63, |
| 278 | 278 | ||
| 279 | .output_mode = CX22702_PARALLEL_OUTPUT, | 279 | .output_mode = CX22702_PARALLEL_OUTPUT, |
| @@ -282,13 +282,13 @@ struct cx22702_config cxusb_cx22702_config = { | |||
| 282 | .pll_set = dvb_usb_pll_set_i2c, | 282 | .pll_set = dvb_usb_pll_set_i2c, |
| 283 | }; | 283 | }; |
| 284 | 284 | ||
| 285 | struct lgdt330x_config cxusb_lgdt330x_config = { | 285 | static struct lgdt330x_config cxusb_lgdt330x_config = { |
| 286 | .demod_address = 0x0e, | 286 | .demod_address = 0x0e, |
| 287 | .demod_chip = LGDT3303, | 287 | .demod_chip = LGDT3303, |
| 288 | .pll_set = dvb_usb_pll_set_i2c, | 288 | .pll_set = dvb_usb_pll_set_i2c, |
| 289 | }; | 289 | }; |
| 290 | 290 | ||
| 291 | struct mt352_config cxusb_dee1601_config = { | 291 | static struct mt352_config cxusb_dee1601_config = { |
| 292 | .demod_address = 0x0f, | 292 | .demod_address = 0x0f, |
| 293 | .demod_init = cxusb_dee1601_demod_init, | 293 | .demod_init = cxusb_dee1601_demod_init, |
| 294 | .pll_set = dvb_usb_pll_set, | 294 | .pll_set = dvb_usb_pll_set, |
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c index e6c55c9c9417..caa1346e3063 100644 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ b/drivers/media/dvb/dvb-usb/digitv.c | |||
| @@ -175,11 +175,13 @@ static int digitv_probe(struct usb_interface *intf, | |||
| 175 | if ((ret = dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE,&d)) == 0) { | 175 | if ((ret = dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE,&d)) == 0) { |
| 176 | u8 b[4] = { 0 }; | 176 | u8 b[4] = { 0 }; |
| 177 | 177 | ||
| 178 | b[0] = 1; | 178 | if (d != NULL) { /* do that only when the firmware is loaded */ |
| 179 | digitv_ctrl_msg(d,USB_WRITE_REMOTE_TYPE,0,b,4,NULL,0); | 179 | b[0] = 1; |
| 180 | digitv_ctrl_msg(d,USB_WRITE_REMOTE_TYPE,0,b,4,NULL,0); | ||
| 180 | 181 | ||
| 181 | b[0] = 0; | 182 | b[0] = 0; |
| 182 | digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0); | 183 | digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0); |
| 184 | } | ||
| 183 | } | 185 | } |
| 184 | return ret; | 186 | return ret; |
| 185 | } | 187 | } |
| @@ -194,7 +196,7 @@ static struct dvb_usb_properties digitv_properties = { | |||
| 194 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, | 196 | .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
| 195 | 197 | ||
| 196 | .usb_ctrl = CYPRESS_FX2, | 198 | .usb_ctrl = CYPRESS_FX2, |
| 197 | .firmware = "dvb-usb-digitv-01.fw", | 199 | .firmware = "dvb-usb-digitv-02.fw", |
| 198 | 200 | ||
| 199 | .size_of_priv = 0, | 201 | .size_of_priv = 0, |
| 200 | 202 | ||
| @@ -229,6 +231,7 @@ static struct dvb_usb_properties digitv_properties = { | |||
| 229 | { &digitv_table[0], NULL }, | 231 | { &digitv_table[0], NULL }, |
| 230 | { NULL }, | 232 | { NULL }, |
| 231 | }, | 233 | }, |
| 234 | { NULL }, | ||
| 232 | } | 235 | } |
| 233 | }; | 236 | }; |
| 234 | 237 | ||
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c index 130ea7f21f5e..12ebaf8bddca 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u.c +++ b/drivers/media/dvb/dvb-usb/dtt200u.c | |||
| @@ -151,7 +151,7 @@ static struct dvb_usb_properties dtt200u_properties = { | |||
| 151 | .cold_ids = { &dtt200u_usb_table[0], NULL }, | 151 | .cold_ids = { &dtt200u_usb_table[0], NULL }, |
| 152 | .warm_ids = { &dtt200u_usb_table[1], NULL }, | 152 | .warm_ids = { &dtt200u_usb_table[1], NULL }, |
| 153 | }, | 153 | }, |
| 154 | { 0 }, | 154 | { NULL }, |
| 155 | } | 155 | } |
| 156 | }; | 156 | }; |
| 157 | 157 | ||
| @@ -192,7 +192,7 @@ static struct dvb_usb_properties wt220u_properties = { | |||
| 192 | .cold_ids = { &dtt200u_usb_table[2], NULL }, | 192 | .cold_ids = { &dtt200u_usb_table[2], NULL }, |
| 193 | .warm_ids = { &dtt200u_usb_table[3], NULL }, | 193 | .warm_ids = { &dtt200u_usb_table[3], NULL }, |
| 194 | }, | 194 | }, |
| 195 | { 0 }, | 195 | { NULL }, |
| 196 | } | 196 | } |
| 197 | }; | 197 | }; |
| 198 | 198 | ||
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c index 8535895819fb..9222b0a81f74 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-firmware.c | |||
| @@ -24,6 +24,9 @@ static struct usb_cypress_controller cypress[] = { | |||
| 24 | { .id = CYPRESS_FX2, .name = "Cypress FX2", .cpu_cs_register = 0xe600 }, | 24 | { .id = CYPRESS_FX2, .name = "Cypress FX2", .cpu_cs_register = 0xe600 }, |
| 25 | }; | 25 | }; |
| 26 | 26 | ||
| 27 | static int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, | ||
| 28 | int *pos); | ||
| 29 | |||
| 27 | /* | 30 | /* |
| 28 | * load a firmware packet to the device | 31 | * load a firmware packet to the device |
| 29 | */ | 32 | */ |
| @@ -112,7 +115,8 @@ int dvb_usb_download_firmware(struct usb_device *udev, struct dvb_usb_properties | |||
| 112 | return ret; | 115 | return ret; |
| 113 | } | 116 | } |
| 114 | 117 | ||
| 115 | int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, int *pos) | 118 | static int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, |
| 119 | int *pos) | ||
| 116 | { | 120 | { |
| 117 | u8 *b = (u8 *) &fw->data[*pos]; | 121 | u8 *b = (u8 *) &fw->data[*pos]; |
| 118 | int data_offs = 4; | 122 | int data_offs = 4; |
| @@ -142,5 +146,3 @@ int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx, int *pos) | |||
| 142 | 146 | ||
| 143 | return *pos; | 147 | return *pos; |
| 144 | } | 148 | } |
| 145 | EXPORT_SYMBOL(dvb_usb_get_hexline); | ||
| 146 | |||
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h index dd568396e594..5e5d21ad93c9 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h | |||
| @@ -341,7 +341,6 @@ struct hexline { | |||
| 341 | u8 data[255]; | 341 | u8 data[255]; |
| 342 | u8 chk; | 342 | u8 chk; |
| 343 | }; | 343 | }; |
| 344 | extern int dvb_usb_get_hexline(const struct firmware *, struct hexline *, int *); | ||
| 345 | extern int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type); | 344 | extern int usb_cypress_load_firmware(struct usb_device *udev, const struct firmware *fw, int type); |
| 346 | 345 | ||
| 347 | #endif | 346 | #endif |
diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c index afa00fdb5ec0..4a95eca81c5c 100644 --- a/drivers/media/dvb/dvb-usb/vp702x.c +++ b/drivers/media/dvb/dvb-usb/vp702x.c | |||
| @@ -53,7 +53,8 @@ int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 | |||
| 53 | return ret; | 53 | return ret; |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen) | 56 | static int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, |
| 57 | u16 index, u8 *b, int blen) | ||
| 57 | { | 58 | { |
| 58 | deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index); | 59 | deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index); |
| 59 | debug_dump(b,blen,deb_xfer); | 60 | debug_dump(b,blen,deb_xfer); |
| @@ -88,7 +89,8 @@ unlock: | |||
| 88 | return ret; | 89 | return ret; |
| 89 | } | 90 | } |
| 90 | 91 | ||
| 91 | int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o, int olen, u8 *i, int ilen, int msec) | 92 | static int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o, |
| 93 | int olen, u8 *i, int ilen, int msec) | ||
| 92 | { | 94 | { |
| 93 | u8 bout[olen+2]; | 95 | u8 bout[olen+2]; |
| 94 | u8 bin[ilen+1]; | 96 | u8 bin[ilen+1]; |
diff --git a/drivers/media/dvb/dvb-usb/vp702x.h b/drivers/media/dvb/dvb-usb/vp702x.h index a808d48e7bf2..c2f97f96c21f 100644 --- a/drivers/media/dvb/dvb-usb/vp702x.h +++ b/drivers/media/dvb/dvb-usb/vp702x.h | |||
| @@ -101,8 +101,6 @@ extern int dvb_usb_vp702x_debug; | |||
| 101 | extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d); | 101 | extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d); |
| 102 | 102 | ||
| 103 | extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec); | 103 | extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec); |
| 104 | extern int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o, int olen, u8 *i, int ilen, int msec); | ||
| 105 | extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen); | 104 | extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen); |
| 106 | extern int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen); | ||
| 107 | 105 | ||
| 108 | #endif | 106 | #endif |
diff --git a/drivers/media/dvb/dvb-usb/vp7045-fe.c b/drivers/media/dvb/dvb-usb/vp7045-fe.c index 5242cca5db4a..9999336aeeb6 100644 --- a/drivers/media/dvb/dvb-usb/vp7045-fe.c +++ b/drivers/media/dvb/dvb-usb/vp7045-fe.c | |||
| @@ -23,10 +23,11 @@ | |||
| 23 | 23 | ||
| 24 | struct vp7045_fe_state { | 24 | struct vp7045_fe_state { |
| 25 | struct dvb_frontend fe; | 25 | struct dvb_frontend fe; |
| 26 | struct dvb_frontend_ops ops; | ||
| 27 | |||
| 26 | struct dvb_usb_device *d; | 28 | struct dvb_usb_device *d; |
| 27 | }; | 29 | }; |
| 28 | 30 | ||
| 29 | |||
| 30 | static int vp7045_fe_read_status(struct dvb_frontend* fe, fe_status_t *status) | 31 | static int vp7045_fe_read_status(struct dvb_frontend* fe, fe_status_t *status) |
| 31 | { | 32 | { |
| 32 | struct vp7045_fe_state *state = fe->demodulator_priv; | 33 | struct vp7045_fe_state *state = fe->demodulator_priv; |
| @@ -150,7 +151,8 @@ struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d) | |||
| 150 | goto error; | 151 | goto error; |
| 151 | 152 | ||
| 152 | s->d = d; | 153 | s->d = d; |
| 153 | s->fe.ops = &vp7045_fe_ops; | 154 | memcpy(&s->ops, &vp7045_fe_ops, sizeof(struct dvb_frontend_ops)); |
| 155 | s->fe.ops = &s->ops; | ||
| 154 | s->fe.demodulator_priv = s; | 156 | s->fe.demodulator_priv = s; |
| 155 | 157 | ||
| 156 | goto success; | 158 | goto success; |
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c index 028204956bb0..3835235b68df 100644 --- a/drivers/media/dvb/dvb-usb/vp7045.c +++ b/drivers/media/dvb/dvb-usb/vp7045.c | |||
| @@ -247,7 +247,7 @@ static struct dvb_usb_properties vp7045_properties = { | |||
| 247 | .cold_ids = { &vp7045_usb_table[2], NULL }, | 247 | .cold_ids = { &vp7045_usb_table[2], NULL }, |
| 248 | .warm_ids = { &vp7045_usb_table[3], NULL }, | 248 | .warm_ids = { &vp7045_usb_table[3], NULL }, |
| 249 | }, | 249 | }, |
| 250 | { 0 }, | 250 | { NULL }, |
| 251 | } | 251 | } |
| 252 | }; | 252 | }; |
| 253 | 253 | ||
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index db3a8b40031e..76b6a2aef32f 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig | |||
| @@ -28,12 +28,6 @@ config DVB_TDA8083 | |||
| 28 | help | 28 | help |
| 29 | A DVB-S tuner module. Say Y when you want to support this frontend. | 29 | A DVB-S tuner module. Say Y when you want to support this frontend. |
| 30 | 30 | ||
| 31 | config DVB_TDA80XX | ||
| 32 | tristate "Philips TDA8044 or TDA8083 based" | ||
| 33 | depends on DVB_CORE | ||
| 34 | help | ||
| 35 | A DVB-S tuner module. Say Y when you want to support this frontend. | ||
| 36 | |||
| 37 | config DVB_MT312 | 31 | config DVB_MT312 |
| 38 | tristate "Zarlink MT312 based" | 32 | tristate "Zarlink MT312 based" |
| 39 | depends on DVB_CORE | 33 | depends on DVB_CORE |
| @@ -139,12 +133,6 @@ config DVB_DIB3000MC | |||
| 139 | comment "DVB-C (cable) frontends" | 133 | comment "DVB-C (cable) frontends" |
| 140 | depends on DVB_CORE | 134 | depends on DVB_CORE |
| 141 | 135 | ||
| 142 | config DVB_ATMEL_AT76C651 | ||
| 143 | tristate "Atmel AT76C651 based" | ||
| 144 | depends on DVB_CORE | ||
| 145 | help | ||
| 146 | A DVB-C tuner module. Say Y when you want to support this frontend. | ||
| 147 | |||
| 148 | config DVB_VES1820 | 136 | config DVB_VES1820 |
| 149 | tristate "VLSI VES1820 based" | 137 | tristate "VLSI VES1820 based" |
| 150 | depends on DVB_CORE | 138 | depends on DVB_CORE |
| @@ -166,18 +154,6 @@ config DVB_STV0297 | |||
| 166 | comment "ATSC (North American/Korean Terresterial DTV) frontends" | 154 | comment "ATSC (North American/Korean Terresterial DTV) frontends" |
| 167 | depends on DVB_CORE | 155 | depends on DVB_CORE |
| 168 | 156 | ||
| 169 | config DVB_NXT2002 | ||
| 170 | tristate "Nxt2002 based" | ||
| 171 | depends on DVB_CORE | ||
| 172 | select FW_LOADER | ||
| 173 | help | ||
| 174 | An ATSC 8VSB tuner module. Say Y when you want to support this frontend. | ||
| 175 | |||
| 176 | This driver needs external firmware. Please use the command | ||
| 177 | "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to | ||
| 178 | download/extract it, and then copy it to /usr/lib/hotplug/firmware | ||
| 179 | or /lib/firmware (depending on configuration of firmware hotplug). | ||
| 180 | |||
| 181 | config DVB_NXT200X | 157 | config DVB_NXT200X |
| 182 | tristate "Nextwave NXT2002/NXT2004 based" | 158 | tristate "Nextwave NXT2002/NXT2004 based" |
| 183 | depends on DVB_CORE | 159 | depends on DVB_CORE |
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 615ec830e1c9..1af769cd90c0 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile | |||
| @@ -8,7 +8,6 @@ obj-$(CONFIG_DVB_CORE) += dvb-pll.o | |||
| 8 | obj-$(CONFIG_DVB_STV0299) += stv0299.o | 8 | obj-$(CONFIG_DVB_STV0299) += stv0299.o |
| 9 | obj-$(CONFIG_DVB_SP8870) += sp8870.o | 9 | obj-$(CONFIG_DVB_SP8870) += sp8870.o |
| 10 | obj-$(CONFIG_DVB_CX22700) += cx22700.o | 10 | obj-$(CONFIG_DVB_CX22700) += cx22700.o |
| 11 | obj-$(CONFIG_DVB_ATMEL_AT76C651) += at76c651.o | ||
| 12 | obj-$(CONFIG_DVB_CX24110) += cx24110.o | 11 | obj-$(CONFIG_DVB_CX24110) += cx24110.o |
| 13 | obj-$(CONFIG_DVB_TDA8083) += tda8083.o | 12 | obj-$(CONFIG_DVB_TDA8083) += tda8083.o |
| 14 | obj-$(CONFIG_DVB_L64781) += l64781.o | 13 | obj-$(CONFIG_DVB_L64781) += l64781.o |
| @@ -22,10 +21,8 @@ obj-$(CONFIG_DVB_SP887X) += sp887x.o | |||
| 22 | obj-$(CONFIG_DVB_NXT6000) += nxt6000.o | 21 | obj-$(CONFIG_DVB_NXT6000) += nxt6000.o |
| 23 | obj-$(CONFIG_DVB_MT352) += mt352.o | 22 | obj-$(CONFIG_DVB_MT352) += mt352.o |
| 24 | obj-$(CONFIG_DVB_CX22702) += cx22702.o | 23 | obj-$(CONFIG_DVB_CX22702) += cx22702.o |
| 25 | obj-$(CONFIG_DVB_TDA80XX) += tda80xx.o | ||
| 26 | obj-$(CONFIG_DVB_TDA10021) += tda10021.o | 24 | obj-$(CONFIG_DVB_TDA10021) += tda10021.o |
| 27 | obj-$(CONFIG_DVB_STV0297) += stv0297.o | 25 | obj-$(CONFIG_DVB_STV0297) += stv0297.o |
| 28 | obj-$(CONFIG_DVB_NXT2002) += nxt2002.o | ||
| 29 | obj-$(CONFIG_DVB_NXT200X) += nxt200x.o | 26 | obj-$(CONFIG_DVB_NXT200X) += nxt200x.o |
| 30 | obj-$(CONFIG_DVB_OR51211) += or51211.o | 27 | obj-$(CONFIG_DVB_OR51211) += or51211.o |
| 31 | obj-$(CONFIG_DVB_OR51132) += or51132.o | 28 | obj-$(CONFIG_DVB_OR51132) += or51132.o |
diff --git a/drivers/media/dvb/frontends/at76c651.c b/drivers/media/dvb/frontends/at76c651.c deleted file mode 100644 index 8e0f4b3a1417..000000000000 --- a/drivers/media/dvb/frontends/at76c651.c +++ /dev/null | |||
| @@ -1,450 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * at76c651.c | ||
| 3 | * | ||
| 4 | * Atmel DVB-C Frontend Driver (at76c651/tua6010xs) | ||
| 5 | * | ||
| 6 | * Copyright (C) 2001 fnbrd <fnbrd@gmx.de> | ||
| 7 | * & 2002-2004 Andreas Oberritter <obi@linuxtv.org> | ||
| 8 | * & 2003 Wolfram Joost <dbox2@frokaschwei.de> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 23 | * | ||
| 24 | * AT76C651 | ||
| 25 | * http://www.nalanda.nitc.ac.in/industry/datasheets/atmel/acrobat/doc1293.pdf | ||
| 26 | * http://www.atmel.com/atmel/acrobat/doc1320.pdf | ||
| 27 | */ | ||
| 28 | |||
| 29 | #include <linux/init.h> | ||
| 30 | #include <linux/module.h> | ||
| 31 | #include <linux/moduleparam.h> | ||
| 32 | #include <linux/kernel.h> | ||
| 33 | #include <linux/string.h> | ||
| 34 | #include <linux/slab.h> | ||
| 35 | #include <linux/bitops.h> | ||
| 36 | #include "dvb_frontend.h" | ||
| 37 | #include "at76c651.h" | ||
| 38 | |||
| 39 | |||
| 40 | struct at76c651_state { | ||
| 41 | |||
| 42 | struct i2c_adapter* i2c; | ||
| 43 | |||
| 44 | struct dvb_frontend_ops ops; | ||
| 45 | |||
| 46 | const struct at76c651_config* config; | ||
| 47 | |||
| 48 | struct dvb_frontend frontend; | ||
| 49 | |||
| 50 | /* revision of the chip */ | ||
| 51 | u8 revision; | ||
| 52 | |||
| 53 | /* last QAM value set */ | ||
| 54 | u8 qam; | ||
| 55 | }; | ||
| 56 | |||
| 57 | static int debug; | ||
| 58 | #define dprintk(args...) \ | ||
| 59 | do { \ | ||
| 60 | if (debug) printk(KERN_DEBUG "at76c651: " args); \ | ||
| 61 | } while (0) | ||
| 62 | |||
| 63 | |||
| 64 | #if ! defined(__powerpc__) | ||
| 65 | static __inline__ int __ilog2(unsigned long x) | ||
| 66 | { | ||
| 67 | int i; | ||
| 68 | |||
| 69 | if (x == 0) | ||
| 70 | return -1; | ||
| 71 | |||
| 72 | for (i = 0; x != 0; i++) | ||
| 73 | x >>= 1; | ||
| 74 | |||
| 75 | return i - 1; | ||
| 76 | } | ||
| 77 | #endif | ||
| 78 | |||
| 79 | static int at76c651_writereg(struct at76c651_state* state, u8 reg, u8 data) | ||
| 80 | { | ||
| 81 | int ret; | ||
| 82 | u8 buf[] = { reg, data }; | ||
| 83 | struct i2c_msg msg = | ||
| 84 | { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; | ||
| 85 | |||
| 86 | ret = i2c_transfer(state->i2c, &msg, 1); | ||
| 87 | |||
| 88 | if (ret != 1) | ||
| 89 | dprintk("%s: writereg error " | ||
| 90 | "(reg == 0x%02x, val == 0x%02x, ret == %i)\n", | ||
| 91 | __FUNCTION__, reg, data, ret); | ||
| 92 | |||
| 93 | msleep(10); | ||
| 94 | |||
| 95 | return (ret != 1) ? -EREMOTEIO : 0; | ||
| 96 | } | ||
| 97 | |||
| 98 | static u8 at76c651_readreg(struct at76c651_state* state, u8 reg) | ||
| 99 | { | ||
| 100 | int ret; | ||
| 101 | u8 val; | ||
| 102 | struct i2c_msg msg[] = { | ||
| 103 | { .addr = state->config->demod_address, .flags = 0, .buf = ®, .len = 1 }, | ||
| 104 | { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = &val, .len = 1 } | ||
| 105 | }; | ||
| 106 | |||
| 107 | ret = i2c_transfer(state->i2c, msg, 2); | ||
| 108 | |||
| 109 | if (ret != 2) | ||
| 110 | dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret); | ||
| 111 | |||
| 112 | return val; | ||
| 113 | } | ||
| 114 | |||
| 115 | static int at76c651_reset(struct at76c651_state* state) | ||
| 116 | { | ||
| 117 | return at76c651_writereg(state, 0x07, 0x01); | ||
| 118 | } | ||
| 119 | |||
| 120 | static void at76c651_disable_interrupts(struct at76c651_state* state) | ||
| 121 | { | ||
| 122 | at76c651_writereg(state, 0x0b, 0x00); | ||
| 123 | } | ||
| 124 | |||
| 125 | static int at76c651_set_auto_config(struct at76c651_state *state) | ||
| 126 | { | ||
| 127 | /* | ||
| 128 | * Autoconfig | ||
| 129 | */ | ||
| 130 | |||
| 131 | at76c651_writereg(state, 0x06, 0x01); | ||
| 132 | |||
| 133 | /* | ||
| 134 | * Performance optimizations, should be done after autoconfig | ||
| 135 | */ | ||
| 136 | |||
| 137 | at76c651_writereg(state, 0x10, 0x06); | ||
| 138 | at76c651_writereg(state, 0x11, ((state->qam == 5) || (state->qam == 7)) ? 0x12 : 0x10); | ||
| 139 | at76c651_writereg(state, 0x15, 0x28); | ||
| 140 | at76c651_writereg(state, 0x20, 0x09); | ||
| 141 | at76c651_writereg(state, 0x24, ((state->qam == 5) || (state->qam == 7)) ? 0xC0 : 0x90); | ||
| 142 | at76c651_writereg(state, 0x30, 0x90); | ||
| 143 | if (state->qam == 5) | ||
| 144 | at76c651_writereg(state, 0x35, 0x2A); | ||
| 145 | |||
| 146 | /* | ||
| 147 | * Initialize A/D-converter | ||
| 148 | */ | ||
| 149 | |||
| 150 | if (state->revision == 0x11) { | ||
| 151 | at76c651_writereg(state, 0x2E, 0x38); | ||
| 152 | at76c651_writereg(state, 0x2F, 0x13); | ||
| 153 | } | ||
| 154 | |||
| 155 | at76c651_disable_interrupts(state); | ||
| 156 | |||
| 157 | /* | ||
| 158 | * Restart operation | ||
| 159 | */ | ||
| 160 | |||
| 161 | at76c651_reset(state); | ||
| 162 | |||
| 163 | return 0; | ||
| 164 | } | ||
| 165 | |||
| 166 | static void at76c651_set_bbfreq(struct at76c651_state* state) | ||
| 167 | { | ||
| 168 | at76c651_writereg(state, 0x04, 0x3f); | ||
| 169 | at76c651_writereg(state, 0x05, 0xee); | ||
| 170 | } | ||
| 171 | |||
| 172 | static int at76c651_set_symbol_rate(struct at76c651_state* state, u32 symbol_rate) | ||
| 173 | { | ||
| 174 | u8 exponent; | ||
| 175 | u32 mantissa; | ||
| 176 | |||
| 177 | if (symbol_rate > 9360000) | ||
| 178 | return -EINVAL; | ||
| 179 | |||
| 180 | /* | ||
| 181 | * FREF = 57800 kHz | ||
| 182 | * exponent = 10 + floor (log2(symbol_rate / FREF)) | ||
| 183 | * mantissa = (symbol_rate / FREF) * (1 << (30 - exponent)) | ||
| 184 | */ | ||
| 185 | |||
| 186 | exponent = __ilog2((symbol_rate << 4) / 903125); | ||
| 187 | mantissa = ((symbol_rate / 3125) * (1 << (24 - exponent))) / 289; | ||
| 188 | |||
| 189 | at76c651_writereg(state, 0x00, mantissa >> 13); | ||
| 190 | at76c651_writereg(state, 0x01, mantissa >> 5); | ||
| 191 | at76c651_writereg(state, 0x02, (mantissa << 3) | exponent); | ||
| 192 | |||
| 193 | return 0; | ||
| 194 | } | ||
| 195 | |||
| 196 | static int at76c651_set_qam(struct at76c651_state *state, fe_modulation_t qam) | ||
| 197 | { | ||
| 198 | switch (qam) { | ||
| 199 | case QPSK: | ||
| 200 | state->qam = 0x02; | ||
| 201 | break; | ||
| 202 | case QAM_16: | ||
| 203 | state->qam = 0x04; | ||
| 204 | break; | ||
| 205 | case QAM_32: | ||
| 206 | state->qam = 0x05; | ||
| 207 | break; | ||
| 208 | case QAM_64: | ||
| 209 | state->qam = 0x06; | ||
| 210 | break; | ||
| 211 | case QAM_128: | ||
| 212 | state->qam = 0x07; | ||
| 213 | break; | ||
| 214 | case QAM_256: | ||
| 215 | state->qam = 0x08; | ||
| 216 | break; | ||
| 217 | #if 0 | ||
| 218 | case QAM_512: | ||
| 219 | state->qam = 0x09; | ||
| 220 | break; | ||
| 221 | case QAM_1024: | ||
| 222 | state->qam = 0x0A; | ||
| 223 | break; | ||
| 224 | #endif | ||
| 225 | default: | ||
| 226 | return -EINVAL; | ||
| 227 | |||
| 228 | } | ||
| 229 | |||
| 230 | return at76c651_writereg(state, 0x03, state->qam); | ||
| 231 | } | ||
| 232 | |||
| 233 | static int at76c651_set_inversion(struct at76c651_state* state, fe_spectral_inversion_t inversion) | ||
| 234 | { | ||
| 235 | u8 feciqinv = at76c651_readreg(state, 0x60); | ||
| 236 | |||
| 237 | switch (inversion) { | ||
| 238 | case INVERSION_OFF: | ||
| 239 | feciqinv |= 0x02; | ||
| 240 | feciqinv &= 0xFE; | ||
| 241 | break; | ||
| 242 | |||
| 243 | case INVERSION_ON: | ||
| 244 | feciqinv |= 0x03; | ||
| 245 | break; | ||
| 246 | |||
| 247 | case INVERSION_AUTO: | ||
| 248 | feciqinv &= 0xFC; | ||
| 249 | break; | ||
| 250 | |||
| 251 | default: | ||
| 252 | return -EINVAL; | ||
| 253 | } | ||
| 254 | |||
| 255 | return at76c651_writereg(state, 0x60, feciqinv); | ||
| 256 | } | ||
| 257 | |||
| 258 | static int at76c651_set_parameters(struct dvb_frontend* fe, | ||
| 259 | struct dvb_frontend_parameters *p) | ||
| 260 | { | ||
| 261 | int ret; | ||
| 262 | struct at76c651_state* state = fe->demodulator_priv; | ||
| 263 | |||
| 264 | at76c651_writereg(state, 0x0c, 0xc3); | ||
| 265 | state->config->pll_set(fe, p); | ||
| 266 | at76c651_writereg(state, 0x0c, 0xc2); | ||
| 267 | |||
| 268 | if ((ret = at76c651_set_symbol_rate(state, p->u.qam.symbol_rate))) | ||
| 269 | return ret; | ||
| 270 | |||
| 271 | if ((ret = at76c651_set_inversion(state, p->inversion))) | ||
| 272 | return ret; | ||
| 273 | |||
| 274 | return at76c651_set_auto_config(state); | ||
| 275 | } | ||
| 276 | |||
| 277 | static int at76c651_set_defaults(struct dvb_frontend* fe) | ||
| 278 | { | ||
| 279 | struct at76c651_state* state = fe->demodulator_priv; | ||
| 280 | |||
| 281 | at76c651_set_symbol_rate(state, 6900000); | ||
| 282 | at76c651_set_qam(state, QAM_64); | ||
| 283 | at76c651_set_bbfreq(state); | ||
| 284 | at76c651_set_auto_config(state); | ||
| 285 | |||
| 286 | if (state->config->pll_init) { | ||
| 287 | at76c651_writereg(state, 0x0c, 0xc3); | ||
| 288 | state->config->pll_init(fe); | ||
| 289 | at76c651_writereg(state, 0x0c, 0xc2); | ||
| 290 | } | ||
| 291 | |||
| 292 | return 0; | ||
| 293 | } | ||
| 294 | |||
| 295 | static int at76c651_read_status(struct dvb_frontend* fe, fe_status_t* status) | ||
| 296 | { | ||
| 297 | struct at76c651_state* state = fe->demodulator_priv; | ||
| 298 | u8 sync; | ||
| 299 | |||
| 300 | /* | ||
| 301 | * Bits: FEC, CAR, EQU, TIM, AGC2, AGC1, ADC, PLL (PLL=0) | ||
| 302 | */ | ||
| 303 | sync = at76c651_readreg(state, 0x80); | ||
| 304 | *status = 0; | ||
| 305 | |||
| 306 | if (sync & (0x04 | 0x10)) /* AGC1 || TIM */ | ||
| 307 | *status |= FE_HAS_SIGNAL; | ||
| 308 | if (sync & 0x10) /* TIM */ | ||
| 309 | *status |= FE_HAS_CARRIER; | ||
| 310 | if (sync & 0x80) /* FEC */ | ||
| 311 | *status |= FE_HAS_VITERBI; | ||
| 312 | if (sync & 0x40) /* CAR */ | ||
| 313 | *status |= FE_HAS_SYNC; | ||
| 314 | if ((sync & 0xF0) == 0xF0) /* TIM && EQU && CAR && FEC */ | ||
| 315 | *status |= FE_HAS_LOCK; | ||
| 316 | |||
| 317 | return 0; | ||
| 318 | } | ||
| 319 | |||
| 320 | static int at76c651_read_ber(struct dvb_frontend* fe, u32* ber) | ||
| 321 | { | ||
| 322 | struct at76c651_state* state = fe->demodulator_priv; | ||
| 323 | |||
| 324 | *ber = (at76c651_readreg(state, 0x81) & 0x0F) << 16; | ||
| 325 | *ber |= at76c651_readreg(state, 0x82) << 8; | ||
| 326 | *ber |= at76c651_readreg(state, 0x83); | ||
| 327 | *ber *= 10; | ||
| 328 | |||
| 329 | return 0; | ||
| 330 | } | ||
| 331 | |||
| 332 | static int at76c651_read_signal_strength(struct dvb_frontend* fe, u16* strength) | ||
| 333 | { | ||
| 334 | struct at76c651_state* state = fe->demodulator_priv; | ||
| 335 | |||
| 336 | u8 gain = ~at76c651_readreg(state, 0x91); | ||
| 337 | *strength = (gain << 8) | gain; | ||
| 338 | |||
| 339 | return 0; | ||
| 340 | } | ||
| 341 | |||
| 342 | static int at76c651_read_snr(struct dvb_frontend* fe, u16* snr) | ||
| 343 | { | ||
| 344 | struct at76c651_state* state = fe->demodulator_priv; | ||
| 345 | |||
| 346 | *snr = 0xFFFF - | ||
| 347 | ((at76c651_readreg(state, 0x8F) << 8) | | ||
| 348 | at76c651_readreg(state, 0x90)); | ||
| 349 | |||
| 350 | return 0; | ||
| 351 | } | ||
| 352 | |||
| 353 | static int at76c651_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | ||
| 354 | { | ||
| 355 | struct at76c651_state* state = fe->demodulator_priv; | ||
| 356 | |||
| 357 | *ucblocks = at76c651_readreg(state, 0x82); | ||
| 358 | |||
| 359 | return 0; | ||
| 360 | } | ||
| 361 | |||
| 362 | static int at76c651_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *fesettings) | ||
| 363 | { | ||
| 364 | fesettings->min_delay_ms = 50; | ||
| 365 | fesettings->step_size = 0; | ||
| 366 | fesettings->max_drift = 0; | ||
| 367 | return 0; | ||
| 368 | } | ||
| 369 | |||
| 370 | static void at76c651_release(struct dvb_frontend* fe) | ||
| 371 | { | ||
| 372 | struct at76c651_state* state = fe->demodulator_priv; | ||
| 373 | kfree(state); | ||
| 374 | } | ||
| 375 | |||
| 376 | static struct dvb_frontend_ops at76c651_ops; | ||
| 377 | |||
| 378 | struct dvb_frontend* at76c651_attach(const struct at76c651_config* config, | ||
| 379 | struct i2c_adapter* i2c) | ||
| 380 | { | ||
| 381 | struct at76c651_state* state = NULL; | ||
| 382 | |||
| 383 | /* allocate memory for the internal state */ | ||
| 384 | state = kmalloc(sizeof(struct at76c651_state), GFP_KERNEL); | ||
| 385 | if (state == NULL) goto error; | ||
| 386 | |||
| 387 | /* setup the state */ | ||
| 388 | state->config = config; | ||
| 389 | state->qam = 0; | ||
| 390 | |||
| 391 | /* check if the demod is there */ | ||
| 392 | if (at76c651_readreg(state, 0x0e) != 0x65) goto error; | ||
| 393 | |||
| 394 | /* finalise state setup */ | ||
| 395 | state->i2c = i2c; | ||
| 396 | state->revision = at76c651_readreg(state, 0x0f) & 0xfe; | ||
| 397 | memcpy(&state->ops, &at76c651_ops, sizeof(struct dvb_frontend_ops)); | ||
| 398 | |||
| 399 | /* create dvb_frontend */ | ||
| 400 | state->frontend.ops = &state->ops; | ||
| 401 | state->frontend.demodulator_priv = state; | ||
| 402 | return &state->frontend; | ||
| 403 | |||
| 404 | error: | ||
| 405 | kfree(state); | ||
| 406 | return NULL; | ||
| 407 | } | ||
| 408 | |||
| 409 | static struct dvb_frontend_ops at76c651_ops = { | ||
| 410 | |||
| 411 | .info = { | ||
| 412 | .name = "Atmel AT76C651B DVB-C", | ||
| 413 | .type = FE_QAM, | ||
| 414 | .frequency_min = 48250000, | ||
| 415 | .frequency_max = 863250000, | ||
| 416 | .frequency_stepsize = 62500, | ||
| 417 | /*.frequency_tolerance = */ /* FIXME: 12% of SR */ | ||
| 418 | .symbol_rate_min = 0, /* FIXME */ | ||
| 419 | .symbol_rate_max = 9360000, /* FIXME */ | ||
| 420 | .symbol_rate_tolerance = 4000, | ||
| 421 | .caps = FE_CAN_INVERSION_AUTO | | ||
| 422 | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | ||
| 423 | FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | | ||
| 424 | FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | | ||
| 425 | FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 | FE_CAN_QAM_128 | | ||
| 426 | FE_CAN_MUTE_TS | FE_CAN_QAM_256 | FE_CAN_RECOVER | ||
| 427 | }, | ||
| 428 | |||
| 429 | .release = at76c651_release, | ||
| 430 | |||
| 431 | .init = at76c651_set_defaults, | ||
| 432 | |||
| 433 | .set_frontend = at76c651_set_parameters, | ||
| 434 | .get_tune_settings = at76c651_get_tune_settings, | ||
| 435 | |||
| 436 | .read_status = at76c651_read_status, | ||
| 437 | .read_ber = at76c651_read_ber, | ||
| 438 | .read_signal_strength = at76c651_read_signal_strength, | ||
| 439 | .read_snr = at76c651_read_snr, | ||
| 440 | .read_ucblocks = at76c651_read_ucblocks, | ||
| 441 | }; | ||
| 442 | |||
| 443 | module_param(debug, int, 0644); | ||
| 444 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | ||
| 445 | |||
| 446 | MODULE_DESCRIPTION("Atmel AT76C651 DVB-C Demodulator Driver"); | ||
| 447 | MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>"); | ||
| 448 | MODULE_LICENSE("GPL"); | ||
| 449 | |||
| 450 | EXPORT_SYMBOL(at76c651_attach); | ||
diff --git a/drivers/media/dvb/frontends/at76c651.h b/drivers/media/dvb/frontends/at76c651.h deleted file mode 100644 index 34054df93608..000000000000 --- a/drivers/media/dvb/frontends/at76c651.h +++ /dev/null | |||
| @@ -1,47 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * at76c651.c | ||
| 3 | * | ||
| 4 | * Atmel DVB-C Frontend Driver (at76c651) | ||
| 5 | * | ||
| 6 | * Copyright (C) 2001 fnbrd <fnbrd@gmx.de> | ||
| 7 | * & 2002-2004 Andreas Oberritter <obi@linuxtv.org> | ||
| 8 | * & 2003 Wolfram Joost <dbox2@frokaschwei.de> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 23 | * | ||
| 24 | * AT76C651 | ||
| 25 | * http://www.nalanda.nitc.ac.in/industry/datasheets/atmel/acrobat/doc1293.pdf | ||
| 26 | * http://www.atmel.com/atmel/acrobat/doc1320.pdf | ||
| 27 | */ | ||
| 28 | |||
| 29 | #ifndef AT76C651_H | ||
| 30 | #define AT76C651_H | ||
| 31 | |||
| 32 | #include <linux/dvb/frontend.h> | ||
| 33 | |||
| 34 | struct at76c651_config | ||
| 35 | { | ||
| 36 | /* the demodulator's i2c address */ | ||
| 37 | u8 demod_address; | ||
| 38 | |||
| 39 | /* PLL maintenance */ | ||
| 40 | int (*pll_init)(struct dvb_frontend* fe); | ||
| 41 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
| 42 | }; | ||
| 43 | |||
| 44 | extern struct dvb_frontend* at76c651_attach(const struct at76c651_config* config, | ||
| 45 | struct i2c_adapter* i2c); | ||
| 46 | |||
| 47 | #endif // AT76C651_H | ||
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index 1b9934ea5b06..4dcb6050d4fa 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c | |||
| @@ -326,11 +326,11 @@ struct dvb_pll_desc dvb_pll_tuv1236d = { | |||
| 326 | }; | 326 | }; |
| 327 | EXPORT_SYMBOL(dvb_pll_tuv1236d); | 327 | EXPORT_SYMBOL(dvb_pll_tuv1236d); |
| 328 | 328 | ||
| 329 | /* Samsung TBMV30111IN | 329 | /* Samsung TBMV30111IN / TBMV30712IN1 |
| 330 | * used in Air2PC ATSC - 2nd generation (nxt2002) | 330 | * used in Air2PC ATSC - 2nd generation (nxt2002) |
| 331 | */ | 331 | */ |
| 332 | struct dvb_pll_desc dvb_pll_tbmv30111in = { | 332 | struct dvb_pll_desc dvb_pll_samsung_tbmv = { |
| 333 | .name = "Samsung TBMV30111IN", | 333 | .name = "Samsung TBMV30111IN / TBMV30712IN1", |
| 334 | .min = 54000000, | 334 | .min = 54000000, |
| 335 | .max = 860000000, | 335 | .max = 860000000, |
| 336 | .count = 6, | 336 | .count = 6, |
| @@ -343,7 +343,7 @@ struct dvb_pll_desc dvb_pll_tbmv30111in = { | |||
| 343 | { 999999999, 44000000, 166666, 0xfc, 0x02 }, | 343 | { 999999999, 44000000, 166666, 0xfc, 0x02 }, |
| 344 | } | 344 | } |
| 345 | }; | 345 | }; |
| 346 | EXPORT_SYMBOL(dvb_pll_tbmv30111in); | 346 | EXPORT_SYMBOL(dvb_pll_samsung_tbmv); |
| 347 | 347 | ||
| 348 | /* | 348 | /* |
| 349 | * Philips SD1878 Tuner. | 349 | * Philips SD1878 Tuner. |
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h index f682c09189b3..bb8d4b4eb183 100644 --- a/drivers/media/dvb/frontends/dvb-pll.h +++ b/drivers/media/dvb/frontends/dvb-pll.h | |||
| @@ -38,7 +38,7 @@ extern struct dvb_pll_desc dvb_pll_tded4; | |||
| 38 | 38 | ||
| 39 | extern struct dvb_pll_desc dvb_pll_tuv1236d; | 39 | extern struct dvb_pll_desc dvb_pll_tuv1236d; |
| 40 | extern struct dvb_pll_desc dvb_pll_tdhu2; | 40 | extern struct dvb_pll_desc dvb_pll_tdhu2; |
| 41 | extern struct dvb_pll_desc dvb_pll_tbmv30111in; | 41 | extern struct dvb_pll_desc dvb_pll_samsung_tbmv; |
| 42 | extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261; | 42 | extern struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261; |
| 43 | 43 | ||
| 44 | int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | 44 | int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, |
diff --git a/drivers/media/dvb/frontends/nxt2002.c b/drivers/media/dvb/frontends/nxt2002.c deleted file mode 100644 index 4f263e65ba14..000000000000 --- a/drivers/media/dvb/frontends/nxt2002.c +++ /dev/null | |||
| @@ -1,706 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Support for B2C2/BBTI Technisat Air2PC - ATSC | ||
| 3 | |||
| 4 | Copyright (C) 2004 Taylor Jacob <rtjacob@earthlink.net> | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; if not, write to the Free Software | ||
| 18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | |||
| 20 | */ | ||
| 21 | |||
| 22 | /* | ||
| 23 | * This driver needs external firmware. Please use the command | ||
| 24 | * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" to | ||
| 25 | * download/extract it, and then copy it to /usr/lib/hotplug/firmware | ||
| 26 | * or /lib/firmware (depending on configuration of firmware hotplug). | ||
| 27 | */ | ||
| 28 | #define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw" | ||
| 29 | #define CRC_CCIT_MASK 0x1021 | ||
| 30 | |||
| 31 | #include <linux/init.h> | ||
| 32 | #include <linux/module.h> | ||
| 33 | #include <linux/moduleparam.h> | ||
| 34 | #include <linux/device.h> | ||
| 35 | #include <linux/firmware.h> | ||
| 36 | #include <linux/string.h> | ||
| 37 | #include <linux/slab.h> | ||
| 38 | |||
| 39 | #include "dvb_frontend.h" | ||
| 40 | #include "nxt2002.h" | ||
| 41 | |||
| 42 | struct nxt2002_state { | ||
| 43 | |||
| 44 | struct i2c_adapter* i2c; | ||
| 45 | struct dvb_frontend_ops ops; | ||
| 46 | const struct nxt2002_config* config; | ||
| 47 | struct dvb_frontend frontend; | ||
| 48 | |||
| 49 | /* demodulator private data */ | ||
| 50 | u8 initialised:1; | ||
| 51 | }; | ||
| 52 | |||
| 53 | static int debug; | ||
| 54 | #define dprintk(args...) \ | ||
| 55 | do { \ | ||
| 56 | if (debug) printk(KERN_DEBUG "nxt2002: " args); \ | ||
| 57 | } while (0) | ||
| 58 | |||
| 59 | static int i2c_writebytes (struct nxt2002_state* state, u8 reg, u8 *buf, u8 len) | ||
| 60 | { | ||
| 61 | /* probbably a much better way or doing this */ | ||
| 62 | u8 buf2 [256],x; | ||
| 63 | int err; | ||
| 64 | struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf2, .len = len + 1 }; | ||
| 65 | |||
| 66 | buf2[0] = reg; | ||
| 67 | for (x = 0 ; x < len ; x++) | ||
| 68 | buf2[x+1] = buf[x]; | ||
| 69 | |||
| 70 | if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) { | ||
| 71 | printk ("%s: i2c write error (addr %02x, err == %i)\n", | ||
| 72 | __FUNCTION__, state->config->demod_address, err); | ||
| 73 | return -EREMOTEIO; | ||
| 74 | } | ||
| 75 | |||
| 76 | return 0; | ||
| 77 | } | ||
| 78 | |||
| 79 | static u8 i2c_readbytes (struct nxt2002_state* state, u8 reg, u8* buf, u8 len) | ||
| 80 | { | ||
| 81 | u8 reg2 [] = { reg }; | ||
| 82 | |||
| 83 | struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = reg2, .len = 1 }, | ||
| 84 | { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } }; | ||
| 85 | |||
| 86 | int err; | ||
| 87 | |||
| 88 | if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) { | ||
| 89 | printk ("%s: i2c read error (addr %02x, err == %i)\n", | ||
| 90 | __FUNCTION__, state->config->demod_address, err); | ||
| 91 | return -EREMOTEIO; | ||
| 92 | } | ||
| 93 | |||
| 94 | return 0; | ||
| 95 | } | ||
| 96 | |||
| 97 | static u16 nxt2002_crc(u16 crc, u8 c) | ||
| 98 | { | ||
| 99 | |||
| 100 | u8 i; | ||
| 101 | u16 input = (u16) c & 0xFF; | ||
| 102 | |||
| 103 | input<<=8; | ||
| 104 | for(i=0 ;i<8 ;i++) { | ||
| 105 | if((crc ^ input) & 0x8000) | ||
| 106 | crc=(crc<<1)^CRC_CCIT_MASK; | ||
| 107 | else | ||
| 108 | crc<<=1; | ||
| 109 | input<<=1; | ||
| 110 | } | ||
| 111 | return crc; | ||
| 112 | } | ||
| 113 | |||
| 114 | static int nxt2002_writereg_multibyte (struct nxt2002_state* state, u8 reg, u8* data, u8 len) | ||
| 115 | { | ||
| 116 | u8 buf; | ||
| 117 | dprintk("%s\n", __FUNCTION__); | ||
| 118 | |||
| 119 | /* set multi register length */ | ||
| 120 | i2c_writebytes(state,0x34,&len,1); | ||
| 121 | |||
| 122 | /* set mutli register register */ | ||
| 123 | i2c_writebytes(state,0x35,®,1); | ||
| 124 | |||
| 125 | /* send the actual data */ | ||
| 126 | i2c_writebytes(state,0x36,data,len); | ||
| 127 | |||
| 128 | /* toggle the multireg write bit*/ | ||
| 129 | buf = 0x02; | ||
| 130 | i2c_writebytes(state,0x21,&buf,1); | ||
| 131 | |||
| 132 | i2c_readbytes(state,0x21,&buf,1); | ||
| 133 | |||
| 134 | if ((buf & 0x02) == 0) | ||
| 135 | return 0; | ||
| 136 | |||
| 137 | dprintk("Error writing multireg register %02X\n",reg); | ||
| 138 | |||
| 139 | return 0; | ||
| 140 | } | ||
| 141 | |||
| 142 | static int nxt2002_readreg_multibyte (struct nxt2002_state* state, u8 reg, u8* data, u8 len) | ||
| 143 | { | ||
| 144 | u8 len2; | ||
| 145 | dprintk("%s\n", __FUNCTION__); | ||
| 146 | |||
| 147 | /* set multi register length */ | ||
| 148 | len2 = len & 0x80; | ||
| 149 | i2c_writebytes(state,0x34,&len2,1); | ||
| 150 | |||
| 151 | /* set mutli register register */ | ||
| 152 | i2c_writebytes(state,0x35,®,1); | ||
| 153 | |||
| 154 | /* send the actual data */ | ||
| 155 | i2c_readbytes(state,reg,data,len); | ||
| 156 | |||
| 157 | return 0; | ||
| 158 | } | ||
| 159 | |||
| 160 | static void nxt2002_microcontroller_stop (struct nxt2002_state* state) | ||
| 161 | { | ||
| 162 | u8 buf[2],counter = 0; | ||
| 163 | dprintk("%s\n", __FUNCTION__); | ||
| 164 | |||
| 165 | buf[0] = 0x80; | ||
| 166 | i2c_writebytes(state,0x22,buf,1); | ||
| 167 | |||
| 168 | while (counter < 20) { | ||
| 169 | i2c_readbytes(state,0x31,buf,1); | ||
| 170 | if (buf[0] & 0x40) | ||
| 171 | return; | ||
| 172 | msleep(10); | ||
| 173 | counter++; | ||
| 174 | } | ||
| 175 | |||
| 176 | dprintk("Timeout waiting for micro to stop.. This is ok after firmware upload\n"); | ||
| 177 | return; | ||
| 178 | } | ||
| 179 | |||
| 180 | static void nxt2002_microcontroller_start (struct nxt2002_state* state) | ||
| 181 | { | ||
| 182 | u8 buf; | ||
| 183 | dprintk("%s\n", __FUNCTION__); | ||
| 184 | |||
| 185 | buf = 0x00; | ||
| 186 | i2c_writebytes(state,0x22,&buf,1); | ||
| 187 | } | ||
| 188 | |||
| 189 | static int nxt2002_writetuner (struct nxt2002_state* state, u8* data) | ||
| 190 | { | ||
| 191 | u8 buf,count = 0; | ||
| 192 | |||
| 193 | dprintk("Tuner Bytes: %02X %02X %02X %02X\n",data[0],data[1],data[2],data[3]); | ||
| 194 | |||
| 195 | dprintk("%s\n", __FUNCTION__); | ||
| 196 | /* stop the micro first */ | ||
| 197 | nxt2002_microcontroller_stop(state); | ||
| 198 | |||
| 199 | /* set the i2c transfer speed to the tuner */ | ||
| 200 | buf = 0x03; | ||
| 201 | i2c_writebytes(state,0x20,&buf,1); | ||
| 202 | |||
| 203 | /* setup to transfer 4 bytes via i2c */ | ||
| 204 | buf = 0x04; | ||
| 205 | i2c_writebytes(state,0x34,&buf,1); | ||
| 206 | |||
| 207 | /* write actual tuner bytes */ | ||
| 208 | i2c_writebytes(state,0x36,data,4); | ||
| 209 | |||
| 210 | /* set tuner i2c address */ | ||
| 211 | buf = 0xC2; | ||
| 212 | i2c_writebytes(state,0x35,&buf,1); | ||
| 213 | |||
| 214 | /* write UC Opmode to begin transfer */ | ||
| 215 | buf = 0x80; | ||
| 216 | i2c_writebytes(state,0x21,&buf,1); | ||
| 217 | |||
| 218 | while (count < 20) { | ||
| 219 | i2c_readbytes(state,0x21,&buf,1); | ||
| 220 | if ((buf & 0x80)== 0x00) | ||
| 221 | return 0; | ||
| 222 | msleep(100); | ||
| 223 | count++; | ||
| 224 | } | ||
| 225 | |||
| 226 | printk("nxt2002: timeout error writing tuner\n"); | ||
| 227 | return 0; | ||
| 228 | } | ||
| 229 | |||
| 230 | static void nxt2002_agc_reset(struct nxt2002_state* state) | ||
| 231 | { | ||
| 232 | u8 buf; | ||
| 233 | dprintk("%s\n", __FUNCTION__); | ||
| 234 | |||
| 235 | buf = 0x08; | ||
| 236 | i2c_writebytes(state,0x08,&buf,1); | ||
| 237 | |||
| 238 | buf = 0x00; | ||
| 239 | i2c_writebytes(state,0x08,&buf,1); | ||
| 240 | |||
| 241 | return; | ||
| 242 | } | ||
| 243 | |||
| 244 | static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) | ||
| 245 | { | ||
| 246 | |||
| 247 | struct nxt2002_state* state = fe->demodulator_priv; | ||
| 248 | u8 buf[256],written = 0,chunkpos = 0; | ||
| 249 | u16 rambase,position,crc = 0; | ||
| 250 | |||
| 251 | dprintk("%s\n", __FUNCTION__); | ||
| 252 | dprintk("Firmware is %zu bytes\n",fw->size); | ||
| 253 | |||
| 254 | /* Get the RAM base for this nxt2002 */ | ||
| 255 | i2c_readbytes(state,0x10,buf,1); | ||
| 256 | |||
| 257 | if (buf[0] & 0x10) | ||
| 258 | rambase = 0x1000; | ||
| 259 | else | ||
| 260 | rambase = 0x0000; | ||
| 261 | |||
| 262 | dprintk("rambase on this nxt2002 is %04X\n",rambase); | ||
| 263 | |||
| 264 | /* Hold the micro in reset while loading firmware */ | ||
| 265 | buf[0] = 0x80; | ||
| 266 | i2c_writebytes(state,0x2B,buf,1); | ||
| 267 | |||
| 268 | for (position = 0; position < fw->size ; position++) { | ||
| 269 | if (written == 0) { | ||
| 270 | crc = 0; | ||
| 271 | chunkpos = 0x28; | ||
| 272 | buf[0] = ((rambase + position) >> 8); | ||
| 273 | buf[1] = (rambase + position) & 0xFF; | ||
| 274 | buf[2] = 0x81; | ||
| 275 | /* write starting address */ | ||
| 276 | i2c_writebytes(state,0x29,buf,3); | ||
| 277 | } | ||
| 278 | written++; | ||
| 279 | chunkpos++; | ||
| 280 | |||
| 281 | if ((written % 4) == 0) | ||
| 282 | i2c_writebytes(state,chunkpos,&fw->data[position-3],4); | ||
| 283 | |||
| 284 | crc = nxt2002_crc(crc,fw->data[position]); | ||
| 285 | |||
| 286 | if ((written == 255) || (position+1 == fw->size)) { | ||
| 287 | /* write remaining bytes of firmware */ | ||
| 288 | i2c_writebytes(state, chunkpos+4-(written %4), | ||
| 289 | &fw->data[position-(written %4) + 1], | ||
| 290 | written %4); | ||
| 291 | buf[0] = crc << 8; | ||
| 292 | buf[1] = crc & 0xFF; | ||
| 293 | |||
| 294 | /* write crc */ | ||
| 295 | i2c_writebytes(state,0x2C,buf,2); | ||
| 296 | |||
| 297 | /* do a read to stop things */ | ||
| 298 | i2c_readbytes(state,0x2A,buf,1); | ||
| 299 | |||
| 300 | /* set transfer mode to complete */ | ||
| 301 | buf[0] = 0x80; | ||
| 302 | i2c_writebytes(state,0x2B,buf,1); | ||
| 303 | |||
| 304 | written = 0; | ||
| 305 | } | ||
| 306 | } | ||
| 307 | |||
| 308 | printk ("done.\n"); | ||
| 309 | return 0; | ||
| 310 | }; | ||
| 311 | |||
| 312 | static int nxt2002_setup_frontend_parameters (struct dvb_frontend* fe, | ||
| 313 | struct dvb_frontend_parameters *p) | ||
| 314 | { | ||
| 315 | struct nxt2002_state* state = fe->demodulator_priv; | ||
| 316 | u32 freq = 0; | ||
| 317 | u16 tunerfreq = 0; | ||
| 318 | u8 buf[4]; | ||
| 319 | |||
| 320 | freq = 44000 + ( p->frequency / 1000 ); | ||
| 321 | |||
| 322 | dprintk("freq = %d p->frequency = %d\n",freq,p->frequency); | ||
| 323 | |||
| 324 | tunerfreq = freq * 24/4000; | ||
| 325 | |||
| 326 | buf[0] = (tunerfreq >> 8) & 0x7F; | ||
| 327 | buf[1] = (tunerfreq & 0xFF); | ||
| 328 | |||
| 329 | if (p->frequency <= 214000000) { | ||
| 330 | buf[2] = 0x84 + (0x06 << 3); | ||
| 331 | buf[3] = (p->frequency <= 172000000) ? 0x01 : 0x02; | ||
| 332 | } else if (p->frequency <= 721000000) { | ||
| 333 | buf[2] = 0x84 + (0x07 << 3); | ||
| 334 | buf[3] = (p->frequency <= 467000000) ? 0x02 : 0x08; | ||
| 335 | } else if (p->frequency <= 841000000) { | ||
| 336 | buf[2] = 0x84 + (0x0E << 3); | ||
| 337 | buf[3] = 0x08; | ||
| 338 | } else { | ||
| 339 | buf[2] = 0x84 + (0x0F << 3); | ||
| 340 | buf[3] = 0x02; | ||
| 341 | } | ||
| 342 | |||
| 343 | /* write frequency information */ | ||
| 344 | nxt2002_writetuner(state,buf); | ||
| 345 | |||
| 346 | /* reset the agc now that tuning has been completed */ | ||
| 347 | nxt2002_agc_reset(state); | ||
| 348 | |||
| 349 | /* set target power level */ | ||
| 350 | switch (p->u.vsb.modulation) { | ||
| 351 | case QAM_64: | ||
| 352 | case QAM_256: | ||
| 353 | buf[0] = 0x74; | ||
| 354 | break; | ||
| 355 | case VSB_8: | ||
| 356 | buf[0] = 0x70; | ||
| 357 | break; | ||
| 358 | default: | ||
| 359 | return -EINVAL; | ||
| 360 | break; | ||
| 361 | } | ||
| 362 | i2c_writebytes(state,0x42,buf,1); | ||
| 363 | |||
| 364 | /* configure sdm */ | ||
| 365 | buf[0] = 0x87; | ||
| 366 | i2c_writebytes(state,0x57,buf,1); | ||
| 367 | |||
| 368 | /* write sdm1 input */ | ||
| 369 | buf[0] = 0x10; | ||
| 370 | buf[1] = 0x00; | ||
| 371 | nxt2002_writereg_multibyte(state,0x58,buf,2); | ||
| 372 | |||
| 373 | /* write sdmx input */ | ||
| 374 | switch (p->u.vsb.modulation) { | ||
| 375 | case QAM_64: | ||
| 376 | buf[0] = 0x68; | ||
| 377 | break; | ||
| 378 | case QAM_256: | ||
| 379 | buf[0] = 0x64; | ||
| 380 | break; | ||
| 381 | case VSB_8: | ||
| 382 | buf[0] = 0x60; | ||
| 383 | break; | ||
| 384 | default: | ||
| 385 | return -EINVAL; | ||
| 386 | break; | ||
| 387 | } | ||
| 388 | buf[1] = 0x00; | ||
| 389 | nxt2002_writereg_multibyte(state,0x5C,buf,2); | ||
| 390 | |||
| 391 | /* write adc power lpf fc */ | ||
| 392 | buf[0] = 0x05; | ||
| 393 | i2c_writebytes(state,0x43,buf,1); | ||
| 394 | |||
| 395 | /* write adc power lpf fc */ | ||
| 396 | buf[0] = 0x05; | ||
| 397 | i2c_writebytes(state,0x43,buf,1); | ||
| 398 | |||
| 399 | /* write accumulator2 input */ | ||
| 400 | buf[0] = 0x80; | ||
| 401 | buf[1] = 0x00; | ||
| 402 | nxt2002_writereg_multibyte(state,0x4B,buf,2); | ||
| 403 | |||
| 404 | /* write kg1 */ | ||
| 405 | buf[0] = 0x00; | ||
| 406 | i2c_writebytes(state,0x4D,buf,1); | ||
| 407 | |||
| 408 | /* write sdm12 lpf fc */ | ||
| 409 | buf[0] = 0x44; | ||
| 410 | i2c_writebytes(state,0x55,buf,1); | ||
| 411 | |||
| 412 | /* write agc control reg */ | ||
| 413 | buf[0] = 0x04; | ||
| 414 | i2c_writebytes(state,0x41,buf,1); | ||
| 415 | |||
| 416 | /* write agc ucgp0 */ | ||
| 417 | switch (p->u.vsb.modulation) { | ||
| 418 | case QAM_64: | ||
| 419 | buf[0] = 0x02; | ||
| 420 | break; | ||
| 421 | case QAM_256: | ||
| 422 | buf[0] = 0x03; | ||
| 423 | break; | ||
| 424 | case VSB_8: | ||
| 425 | buf[0] = 0x00; | ||
| 426 | break; | ||
| 427 | default: | ||
| 428 | return -EINVAL; | ||
| 429 | break; | ||
| 430 | } | ||
| 431 | i2c_writebytes(state,0x30,buf,1); | ||
| 432 | |||
| 433 | /* write agc control reg */ | ||
| 434 | buf[0] = 0x00; | ||
| 435 | i2c_writebytes(state,0x41,buf,1); | ||
| 436 | |||
| 437 | /* write accumulator2 input */ | ||
| 438 | buf[0] = 0x80; | ||
| 439 | buf[1] = 0x00; | ||
| 440 | nxt2002_writereg_multibyte(state,0x49,buf,2); | ||
| 441 | nxt2002_writereg_multibyte(state,0x4B,buf,2); | ||
| 442 | |||
| 443 | /* write agc control reg */ | ||
| 444 | buf[0] = 0x04; | ||
| 445 | i2c_writebytes(state,0x41,buf,1); | ||
| 446 | |||
| 447 | nxt2002_microcontroller_start(state); | ||
| 448 | |||
| 449 | /* adjacent channel detection should be done here, but I don't | ||
| 450 | have any stations with this need so I cannot test it */ | ||
| 451 | |||
| 452 | return 0; | ||
| 453 | } | ||
| 454 | |||
| 455 | static int nxt2002_read_status(struct dvb_frontend* fe, fe_status_t* status) | ||
| 456 | { | ||
| 457 | struct nxt2002_state* state = fe->demodulator_priv; | ||
| 458 | u8 lock; | ||
| 459 | i2c_readbytes(state,0x31,&lock,1); | ||
| 460 | |||
| 461 | *status = 0; | ||
| 462 | if (lock & 0x20) { | ||
| 463 | *status |= FE_HAS_SIGNAL; | ||
| 464 | *status |= FE_HAS_CARRIER; | ||
| 465 | *status |= FE_HAS_VITERBI; | ||
| 466 | *status |= FE_HAS_SYNC; | ||
| 467 | *status |= FE_HAS_LOCK; | ||
| 468 | } | ||
| 469 | return 0; | ||
| 470 | } | ||
| 471 | |||
| 472 | static int nxt2002_read_ber(struct dvb_frontend* fe, u32* ber) | ||
| 473 | { | ||
| 474 | struct nxt2002_state* state = fe->demodulator_priv; | ||
| 475 | u8 b[3]; | ||
| 476 | |||
| 477 | nxt2002_readreg_multibyte(state,0xE6,b,3); | ||
| 478 | |||
| 479 | *ber = ((b[0] << 8) + b[1]) * 8; | ||
| 480 | |||
| 481 | return 0; | ||
| 482 | } | ||
| 483 | |||
| 484 | static int nxt2002_read_signal_strength(struct dvb_frontend* fe, u16* strength) | ||
| 485 | { | ||
| 486 | struct nxt2002_state* state = fe->demodulator_priv; | ||
| 487 | u8 b[2]; | ||
| 488 | u16 temp = 0; | ||
| 489 | |||
| 490 | /* setup to read cluster variance */ | ||
| 491 | b[0] = 0x00; | ||
| 492 | i2c_writebytes(state,0xA1,b,1); | ||
| 493 | |||
| 494 | /* get multreg val */ | ||
| 495 | nxt2002_readreg_multibyte(state,0xA6,b,2); | ||
| 496 | |||
| 497 | temp = (b[0] << 8) | b[1]; | ||
| 498 | *strength = ((0x7FFF - temp) & 0x0FFF) * 16; | ||
| 499 | |||
| 500 | return 0; | ||
| 501 | } | ||
| 502 | |||
| 503 | static int nxt2002_read_snr(struct dvb_frontend* fe, u16* snr) | ||
| 504 | { | ||
| 505 | |||
| 506 | struct nxt2002_state* state = fe->demodulator_priv; | ||
| 507 | u8 b[2]; | ||
| 508 | u16 temp = 0, temp2; | ||
| 509 | u32 snrdb = 0; | ||
| 510 | |||
| 511 | /* setup to read cluster variance */ | ||
| 512 | b[0] = 0x00; | ||
| 513 | i2c_writebytes(state,0xA1,b,1); | ||
| 514 | |||
| 515 | /* get multreg val from 0xA6 */ | ||
| 516 | nxt2002_readreg_multibyte(state,0xA6,b,2); | ||
| 517 | |||
| 518 | temp = (b[0] << 8) | b[1]; | ||
| 519 | temp2 = 0x7FFF - temp; | ||
| 520 | |||
| 521 | /* snr will be in db */ | ||
| 522 | if (temp2 > 0x7F00) | ||
| 523 | snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) ); | ||
| 524 | else if (temp2 > 0x7EC0) | ||
| 525 | snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) ); | ||
| 526 | else if (temp2 > 0x7C00) | ||
| 527 | snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) ); | ||
| 528 | else | ||
| 529 | snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) ); | ||
| 530 | |||
| 531 | /* the value reported back from the frontend will be FFFF=32db 0000=0db */ | ||
| 532 | |||
| 533 | *snr = snrdb * (0xFFFF/32000); | ||
| 534 | |||
| 535 | return 0; | ||
| 536 | } | ||
| 537 | |||
| 538 | static int nxt2002_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | ||
| 539 | { | ||
| 540 | struct nxt2002_state* state = fe->demodulator_priv; | ||
| 541 | u8 b[3]; | ||
| 542 | |||
| 543 | nxt2002_readreg_multibyte(state,0xE6,b,3); | ||
| 544 | *ucblocks = b[2]; | ||
| 545 | |||
| 546 | return 0; | ||
| 547 | } | ||
| 548 | |||
| 549 | static int nxt2002_sleep(struct dvb_frontend* fe) | ||
| 550 | { | ||
| 551 | return 0; | ||
| 552 | } | ||
| 553 | |||
| 554 | static int nxt2002_init(struct dvb_frontend* fe) | ||
| 555 | { | ||
| 556 | struct nxt2002_state* state = fe->demodulator_priv; | ||
| 557 | const struct firmware *fw; | ||
| 558 | int ret; | ||
| 559 | u8 buf[2]; | ||
| 560 | |||
| 561 | if (!state->initialised) { | ||
| 562 | /* request the firmware, this will block until someone uploads it */ | ||
| 563 | printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE); | ||
| 564 | ret = state->config->request_firmware(fe, &fw, NXT2002_DEFAULT_FIRMWARE); | ||
| 565 | printk("nxt2002: Waiting for firmware upload(2)...\n"); | ||
| 566 | if (ret) { | ||
| 567 | printk("nxt2002: no firmware upload (timeout or file not found?)\n"); | ||
| 568 | return ret; | ||
| 569 | } | ||
| 570 | |||
| 571 | ret = nxt2002_load_firmware(fe, fw); | ||
| 572 | if (ret) { | ||
| 573 | printk("nxt2002: writing firmware to device failed\n"); | ||
| 574 | release_firmware(fw); | ||
| 575 | return ret; | ||
| 576 | } | ||
| 577 | printk("nxt2002: firmware upload complete\n"); | ||
| 578 | |||
| 579 | /* Put the micro into reset */ | ||
| 580 | nxt2002_microcontroller_stop(state); | ||
| 581 | |||
| 582 | /* ensure transfer is complete */ | ||
| 583 | buf[0]=0; | ||
| 584 | i2c_writebytes(state,0x2B,buf,1); | ||
| 585 | |||
| 586 | /* Put the micro into reset for real this time */ | ||
| 587 | nxt2002_microcontroller_stop(state); | ||
| 588 | |||
| 589 | /* soft reset everything (agc,frontend,eq,fec)*/ | ||
| 590 | buf[0] = 0x0F; | ||
| 591 | i2c_writebytes(state,0x08,buf,1); | ||
| 592 | buf[0] = 0x00; | ||
| 593 | i2c_writebytes(state,0x08,buf,1); | ||
| 594 | |||
| 595 | /* write agc sdm configure */ | ||
| 596 | buf[0] = 0xF1; | ||
| 597 | i2c_writebytes(state,0x57,buf,1); | ||
| 598 | |||
| 599 | /* write mod output format */ | ||
| 600 | buf[0] = 0x20; | ||
| 601 | i2c_writebytes(state,0x09,buf,1); | ||
| 602 | |||
| 603 | /* write fec mpeg mode */ | ||
| 604 | buf[0] = 0x7E; | ||
| 605 | buf[1] = 0x00; | ||
| 606 | i2c_writebytes(state,0xE9,buf,2); | ||
| 607 | |||
| 608 | /* write mux selection */ | ||
| 609 | buf[0] = 0x00; | ||
| 610 | i2c_writebytes(state,0xCC,buf,1); | ||
| 611 | |||
| 612 | state->initialised = 1; | ||
| 613 | } | ||
| 614 | |||
| 615 | return 0; | ||
| 616 | } | ||
| 617 | |||
| 618 | static int nxt2002_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) | ||
| 619 | { | ||
| 620 | fesettings->min_delay_ms = 500; | ||
| 621 | fesettings->step_size = 0; | ||
| 622 | fesettings->max_drift = 0; | ||
| 623 | return 0; | ||
| 624 | } | ||
| 625 | |||
| 626 | static void nxt2002_release(struct dvb_frontend* fe) | ||
| 627 | { | ||
| 628 | struct nxt2002_state* state = fe->demodulator_priv; | ||
| 629 | kfree(state); | ||
| 630 | } | ||
| 631 | |||
| 632 | static struct dvb_frontend_ops nxt2002_ops; | ||
| 633 | |||
| 634 | struct dvb_frontend* nxt2002_attach(const struct nxt2002_config* config, | ||
| 635 | struct i2c_adapter* i2c) | ||
| 636 | { | ||
| 637 | struct nxt2002_state* state = NULL; | ||
| 638 | u8 buf [] = {0,0,0,0,0}; | ||
| 639 | |||
| 640 | /* allocate memory for the internal state */ | ||
| 641 | state = kmalloc(sizeof(struct nxt2002_state), GFP_KERNEL); | ||
| 642 | if (state == NULL) goto error; | ||
| 643 | |||
| 644 | /* setup the state */ | ||
| 645 | state->config = config; | ||
| 646 | state->i2c = i2c; | ||
| 647 | memcpy(&state->ops, &nxt2002_ops, sizeof(struct dvb_frontend_ops)); | ||
| 648 | state->initialised = 0; | ||
| 649 | |||
| 650 | /* Check the first 5 registers to ensure this a revision we can handle */ | ||
| 651 | |||
| 652 | i2c_readbytes(state, 0x00, buf, 5); | ||
| 653 | if (buf[0] != 0x04) goto error; /* device id */ | ||
| 654 | if (buf[1] != 0x02) goto error; /* fab id */ | ||
| 655 | if (buf[2] != 0x11) goto error; /* month */ | ||
| 656 | if (buf[3] != 0x20) goto error; /* year msb */ | ||
| 657 | if (buf[4] != 0x00) goto error; /* year lsb */ | ||
| 658 | |||
| 659 | /* create dvb_frontend */ | ||
| 660 | state->frontend.ops = &state->ops; | ||
| 661 | state->frontend.demodulator_priv = state; | ||
| 662 | return &state->frontend; | ||
| 663 | |||
| 664 | error: | ||
| 665 | kfree(state); | ||
| 666 | return NULL; | ||
| 667 | } | ||
| 668 | |||
| 669 | static struct dvb_frontend_ops nxt2002_ops = { | ||
| 670 | |||
| 671 | .info = { | ||
| 672 | .name = "Nextwave nxt2002 VSB/QAM frontend", | ||
| 673 | .type = FE_ATSC, | ||
| 674 | .frequency_min = 54000000, | ||
| 675 | .frequency_max = 860000000, | ||
| 676 | /* stepsize is just a guess */ | ||
| 677 | .frequency_stepsize = 166666, | ||
| 678 | .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | ||
| 679 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | | ||
| 680 | FE_CAN_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256 | ||
| 681 | }, | ||
| 682 | |||
| 683 | .release = nxt2002_release, | ||
| 684 | |||
| 685 | .init = nxt2002_init, | ||
| 686 | .sleep = nxt2002_sleep, | ||
| 687 | |||
| 688 | .set_frontend = nxt2002_setup_frontend_parameters, | ||
| 689 | .get_tune_settings = nxt2002_get_tune_settings, | ||
| 690 | |||
| 691 | .read_status = nxt2002_read_status, | ||
| 692 | .read_ber = nxt2002_read_ber, | ||
| 693 | .read_signal_strength = nxt2002_read_signal_strength, | ||
| 694 | .read_snr = nxt2002_read_snr, | ||
| 695 | .read_ucblocks = nxt2002_read_ucblocks, | ||
| 696 | |||
| 697 | }; | ||
| 698 | |||
| 699 | module_param(debug, int, 0644); | ||
| 700 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | ||
| 701 | |||
| 702 | MODULE_DESCRIPTION("NXT2002 ATSC (8VSB & ITU J83 AnnexB FEC QAM64/256) demodulator driver"); | ||
| 703 | MODULE_AUTHOR("Taylor Jacob"); | ||
| 704 | MODULE_LICENSE("GPL"); | ||
| 705 | |||
| 706 | EXPORT_SYMBOL(nxt2002_attach); | ||
diff --git a/drivers/media/dvb/frontends/nxt2002.h b/drivers/media/dvb/frontends/nxt2002.h deleted file mode 100644 index 462301f577ee..000000000000 --- a/drivers/media/dvb/frontends/nxt2002.h +++ /dev/null | |||
| @@ -1,23 +0,0 @@ | |||
| 1 | /* | ||
| 2 | Driver for the Nxt2002 demodulator | ||
| 3 | */ | ||
| 4 | |||
| 5 | #ifndef NXT2002_H | ||
| 6 | #define NXT2002_H | ||
| 7 | |||
| 8 | #include <linux/dvb/frontend.h> | ||
| 9 | #include <linux/firmware.h> | ||
| 10 | |||
| 11 | struct nxt2002_config | ||
| 12 | { | ||
| 13 | /* the demodulator's i2c address */ | ||
| 14 | u8 demod_address; | ||
| 15 | |||
| 16 | /* request firmware for device */ | ||
| 17 | int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); | ||
| 18 | }; | ||
| 19 | |||
| 20 | extern struct dvb_frontend* nxt2002_attach(const struct nxt2002_config* config, | ||
| 21 | struct i2c_adapter* i2c); | ||
| 22 | |||
| 23 | #endif // NXT2002_H | ||
diff --git a/drivers/media/dvb/frontends/nxt200x.c b/drivers/media/dvb/frontends/nxt200x.c index 78d2b93d35b9..9e3535394509 100644 --- a/drivers/media/dvb/frontends/nxt200x.c +++ b/drivers/media/dvb/frontends/nxt200x.c | |||
| @@ -1,9 +1,10 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Support for NXT2002 and NXT2004 - VSB/QAM | 2 | * Support for NXT2002 and NXT2004 - VSB/QAM |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2005 Kirk Lapray (kirk.lapray@gmail.com) | 4 | * Copyright (C) 2005 Kirk Lapray <kirk.lapray@gmail.com> |
| 5 | * Copyright (C) 2006 Michael Krufky <mkrufky@m1k.net> | ||
| 5 | * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net> | 6 | * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net> |
| 6 | * and nxt2004 by Jean-Francois Thibert (jeanfrancois@sagetv.com) | 7 | * and nxt2004 by Jean-Francois Thibert <jeanfrancois@sagetv.com> |
| 7 | * | 8 | * |
| 8 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
| 9 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
| @@ -614,7 +615,17 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, | |||
| 614 | /* write sdm1 input */ | 615 | /* write sdm1 input */ |
| 615 | buf[0] = 0x10; | 616 | buf[0] = 0x10; |
| 616 | buf[1] = 0x00; | 617 | buf[1] = 0x00; |
| 617 | nxt200x_writebytes(state, 0x58, buf, 2); | 618 | switch (state->demod_chip) { |
| 619 | case NXT2002: | ||
| 620 | nxt200x_writereg_multibyte(state, 0x58, buf, 2); | ||
| 621 | break; | ||
| 622 | case NXT2004: | ||
| 623 | nxt200x_writebytes(state, 0x58, buf, 2); | ||
| 624 | break; | ||
| 625 | default: | ||
| 626 | return -EINVAL; | ||
| 627 | break; | ||
| 628 | } | ||
| 618 | 629 | ||
| 619 | /* write sdmx input */ | 630 | /* write sdmx input */ |
| 620 | switch (p->u.vsb.modulation) { | 631 | switch (p->u.vsb.modulation) { |
| @@ -632,7 +643,17 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, | |||
| 632 | break; | 643 | break; |
| 633 | } | 644 | } |
| 634 | buf[1] = 0x00; | 645 | buf[1] = 0x00; |
| 635 | nxt200x_writebytes(state, 0x5C, buf, 2); | 646 | switch (state->demod_chip) { |
| 647 | case NXT2002: | ||
| 648 | nxt200x_writereg_multibyte(state, 0x5C, buf, 2); | ||
| 649 | break; | ||
| 650 | case NXT2004: | ||
| 651 | nxt200x_writebytes(state, 0x5C, buf, 2); | ||
| 652 | break; | ||
| 653 | default: | ||
| 654 | return -EINVAL; | ||
| 655 | break; | ||
| 656 | } | ||
| 636 | 657 | ||
| 637 | /* write adc power lpf fc */ | 658 | /* write adc power lpf fc */ |
| 638 | buf[0] = 0x05; | 659 | buf[0] = 0x05; |
| @@ -648,7 +669,17 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, | |||
| 648 | /* write accumulator2 input */ | 669 | /* write accumulator2 input */ |
| 649 | buf[0] = 0x80; | 670 | buf[0] = 0x80; |
| 650 | buf[1] = 0x00; | 671 | buf[1] = 0x00; |
| 651 | nxt200x_writebytes(state, 0x4B, buf, 2); | 672 | switch (state->demod_chip) { |
| 673 | case NXT2002: | ||
| 674 | nxt200x_writereg_multibyte(state, 0x4B, buf, 2); | ||
| 675 | break; | ||
| 676 | case NXT2004: | ||
| 677 | nxt200x_writebytes(state, 0x4B, buf, 2); | ||
| 678 | break; | ||
| 679 | default: | ||
| 680 | return -EINVAL; | ||
| 681 | break; | ||
| 682 | } | ||
| 652 | 683 | ||
| 653 | /* write kg1 */ | 684 | /* write kg1 */ |
| 654 | buf[0] = 0x00; | 685 | buf[0] = 0x00; |
| @@ -714,8 +745,19 @@ static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe, | |||
| 714 | /* write accumulator2 input */ | 745 | /* write accumulator2 input */ |
| 715 | buf[0] = 0x80; | 746 | buf[0] = 0x80; |
| 716 | buf[1] = 0x00; | 747 | buf[1] = 0x00; |
| 717 | nxt200x_writebytes(state, 0x49, buf,2); | 748 | switch (state->demod_chip) { |
| 718 | nxt200x_writebytes(state, 0x4B, buf,2); | 749 | case NXT2002: |
| 750 | nxt200x_writereg_multibyte(state, 0x49, buf, 2); | ||
| 751 | nxt200x_writereg_multibyte(state, 0x4B, buf, 2); | ||
| 752 | break; | ||
| 753 | case NXT2004: | ||
| 754 | nxt200x_writebytes(state, 0x49, buf, 2); | ||
| 755 | nxt200x_writebytes(state, 0x4B, buf, 2); | ||
| 756 | break; | ||
| 757 | default: | ||
| 758 | return -EINVAL; | ||
| 759 | break; | ||
| 760 | } | ||
| 719 | 761 | ||
| 720 | /* write agc control reg */ | 762 | /* write agc control reg */ |
| 721 | buf[0] = 0x04; | 763 | buf[0] = 0x04; |
| @@ -1199,7 +1241,7 @@ module_param(debug, int, 0644); | |||
| 1199 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | 1241 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); |
| 1200 | 1242 | ||
| 1201 | MODULE_DESCRIPTION("NXT200X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver"); | 1243 | MODULE_DESCRIPTION("NXT200X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver"); |
| 1202 | MODULE_AUTHOR("Kirk Lapray, Jean-Francois Thibert, and Taylor Jacob"); | 1244 | MODULE_AUTHOR("Kirk Lapray, Michael Krufky, Jean-Francois Thibert, and Taylor Jacob"); |
| 1203 | MODULE_LICENSE("GPL"); | 1245 | MODULE_LICENSE("GPL"); |
| 1204 | 1246 | ||
| 1205 | EXPORT_SYMBOL(nxt200x_attach); | 1247 | EXPORT_SYMBOL(nxt200x_attach); |
diff --git a/drivers/media/dvb/frontends/tda80xx.c b/drivers/media/dvb/frontends/tda80xx.c deleted file mode 100644 index d1cabb6a0a13..000000000000 --- a/drivers/media/dvb/frontends/tda80xx.c +++ /dev/null | |||
| @@ -1,734 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * tda80xx.c | ||
| 3 | * | ||
| 4 | * Philips TDA8044 / TDA8083 QPSK demodulator driver | ||
| 5 | * | ||
| 6 | * Copyright (C) 2001 Felix Domke <tmbinc@elitedvb.net> | ||
| 7 | * Copyright (C) 2002-2004 Andreas Oberritter <obi@linuxtv.org> | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License as published by | ||
| 11 | * the Free Software Foundation; either version 2 of the License, or | ||
| 12 | * (at your option) any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 22 | */ | ||
| 23 | |||
| 24 | #include <linux/config.h> | ||
| 25 | #include <linux/delay.h> | ||
| 26 | #include <linux/init.h> | ||
| 27 | #include <linux/spinlock.h> | ||
| 28 | #include <linux/threads.h> | ||
| 29 | #include <linux/interrupt.h> | ||
| 30 | #include <linux/kernel.h> | ||
| 31 | #include <linux/module.h> | ||
| 32 | #include <linux/slab.h> | ||
| 33 | #include <asm/irq.h> | ||
| 34 | #include <asm/div64.h> | ||
| 35 | |||
| 36 | #include "dvb_frontend.h" | ||
| 37 | #include "tda80xx.h" | ||
| 38 | |||
| 39 | enum { | ||
| 40 | ID_TDA8044 = 0x04, | ||
| 41 | ID_TDA8083 = 0x05, | ||
| 42 | }; | ||
| 43 | |||
| 44 | |||
| 45 | struct tda80xx_state { | ||
| 46 | |||
| 47 | struct i2c_adapter* i2c; | ||
| 48 | |||
| 49 | struct dvb_frontend_ops ops; | ||
| 50 | |||
| 51 | /* configuration settings */ | ||
| 52 | const struct tda80xx_config* config; | ||
| 53 | |||
| 54 | struct dvb_frontend frontend; | ||
| 55 | |||
| 56 | u32 clk; | ||
| 57 | int afc_loop; | ||
| 58 | struct work_struct worklet; | ||
| 59 | fe_code_rate_t code_rate; | ||
| 60 | fe_spectral_inversion_t spectral_inversion; | ||
| 61 | fe_status_t status; | ||
| 62 | u8 id; | ||
| 63 | }; | ||
| 64 | |||
| 65 | static int debug = 1; | ||
| 66 | #define dprintk if (debug) printk | ||
| 67 | |||
| 68 | static u8 tda8044_inittab_pre[] = { | ||
| 69 | 0x02, 0x00, 0x6f, 0xb5, 0x86, 0x22, 0x00, 0xea, | ||
| 70 | 0x30, 0x42, 0x98, 0x68, 0x70, 0x42, 0x99, 0x58, | ||
| 71 | 0x95, 0x10, 0xf5, 0xe7, 0x93, 0x0b, 0x15, 0x68, | ||
| 72 | 0x9a, 0x90, 0x61, 0x80, 0x00, 0xe0, 0x40, 0x00, | ||
| 73 | 0x0f, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 74 | 0x00, 0x00 | ||
| 75 | }; | ||
| 76 | |||
| 77 | static u8 tda8044_inittab_post[] = { | ||
| 78 | 0x04, 0x00, 0x6f, 0xb5, 0x86, 0x22, 0x00, 0xea, | ||
| 79 | 0x30, 0x42, 0x98, 0x68, 0x70, 0x42, 0x99, 0x50, | ||
| 80 | 0x95, 0x10, 0xf5, 0xe7, 0x93, 0x0b, 0x15, 0x68, | ||
| 81 | 0x9a, 0x90, 0x61, 0x80, 0x00, 0xe0, 0x40, 0x6c, | ||
| 82 | 0x0f, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 83 | 0x00, 0x00 | ||
| 84 | }; | ||
| 85 | |||
| 86 | static u8 tda8083_inittab[] = { | ||
| 87 | 0x04, 0x00, 0x4a, 0x79, 0x04, 0x00, 0xff, 0xea, | ||
| 88 | 0x48, 0x42, 0x79, 0x60, 0x70, 0x52, 0x9a, 0x10, | ||
| 89 | 0x0e, 0x10, 0xf2, 0xa7, 0x93, 0x0b, 0x05, 0xc8, | ||
| 90 | 0x9d, 0x00, 0x42, 0x80, 0x00, 0x60, 0x40, 0x00, | ||
| 91 | 0x00, 0x75, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, | ||
| 92 | 0x00, 0x00, 0x00, 0x00 | ||
| 93 | }; | ||
| 94 | |||
| 95 | static __inline__ u32 tda80xx_div(u32 a, u32 b) | ||
| 96 | { | ||
| 97 | return (a + (b / 2)) / b; | ||
| 98 | } | ||
| 99 | |||
| 100 | static __inline__ u32 tda80xx_gcd(u32 a, u32 b) | ||
| 101 | { | ||
| 102 | u32 r; | ||
| 103 | |||
| 104 | while ((r = a % b)) { | ||
| 105 | a = b; | ||
| 106 | b = r; | ||
| 107 | } | ||
| 108 | |||
| 109 | return b; | ||
| 110 | } | ||
| 111 | |||
| 112 | static int tda80xx_read(struct tda80xx_state* state, u8 reg, u8 *buf, u8 len) | ||
| 113 | { | ||
| 114 | int ret; | ||
| 115 | struct i2c_msg msg[] = { { .addr = state->config->demod_address, .flags = 0, .buf = ®, .len = 1 }, | ||
| 116 | { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } }; | ||
| 117 | |||
| 118 | ret = i2c_transfer(state->i2c, msg, 2); | ||
| 119 | |||
| 120 | if (ret != 2) | ||
| 121 | dprintk("%s: readreg error (reg %02x, ret == %i)\n", | ||
| 122 | __FUNCTION__, reg, ret); | ||
| 123 | |||
| 124 | mdelay(10); | ||
| 125 | |||
| 126 | return (ret == 2) ? 0 : -EREMOTEIO; | ||
| 127 | } | ||
| 128 | |||
| 129 | static int tda80xx_write(struct tda80xx_state* state, u8 reg, const u8 *buf, u8 len) | ||
| 130 | { | ||
| 131 | int ret; | ||
| 132 | u8 wbuf[len + 1]; | ||
| 133 | struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = wbuf, .len = len + 1 }; | ||
| 134 | |||
| 135 | wbuf[0] = reg; | ||
| 136 | memcpy(&wbuf[1], buf, len); | ||
| 137 | |||
| 138 | ret = i2c_transfer(state->i2c, &msg, 1); | ||
| 139 | |||
| 140 | if (ret != 1) | ||
| 141 | dprintk("%s: i2c xfer error (ret == %i)\n", __FUNCTION__, ret); | ||
| 142 | |||
| 143 | mdelay(10); | ||
| 144 | |||
| 145 | return (ret == 1) ? 0 : -EREMOTEIO; | ||
| 146 | } | ||
| 147 | |||
| 148 | static __inline__ u8 tda80xx_readreg(struct tda80xx_state* state, u8 reg) | ||
| 149 | { | ||
| 150 | u8 val; | ||
| 151 | |||
| 152 | tda80xx_read(state, reg, &val, 1); | ||
| 153 | |||
| 154 | return val; | ||
| 155 | } | ||
| 156 | |||
| 157 | static __inline__ int tda80xx_writereg(struct tda80xx_state* state, u8 reg, u8 data) | ||
| 158 | { | ||
| 159 | return tda80xx_write(state, reg, &data, 1); | ||
| 160 | } | ||
| 161 | |||
| 162 | static int tda80xx_set_parameters(struct tda80xx_state* state, | ||
| 163 | fe_spectral_inversion_t inversion, | ||
| 164 | u32 symbol_rate, | ||
| 165 | fe_code_rate_t fec_inner) | ||
| 166 | { | ||
| 167 | u8 buf[15]; | ||
| 168 | u64 ratio; | ||
| 169 | u32 clk; | ||
| 170 | u32 k; | ||
| 171 | u32 sr = symbol_rate; | ||
| 172 | u32 gcd; | ||
| 173 | u8 scd; | ||
| 174 | |||
| 175 | if (symbol_rate > (state->clk * 3) / 16) | ||
| 176 | scd = 0; | ||
| 177 | else if (symbol_rate > (state->clk * 3) / 32) | ||
| 178 | scd = 1; | ||
| 179 | else if (symbol_rate > (state->clk * 3) / 64) | ||
| 180 | scd = 2; | ||
| 181 | else | ||
| 182 | scd = 3; | ||
| 183 | |||
| 184 | clk = scd ? (state->clk / (scd * 2)) : state->clk; | ||
| 185 | |||
| 186 | /* | ||
| 187 | * Viterbi decoder: | ||
| 188 | * Differential decoding off | ||
| 189 | * Spectral inversion unknown | ||
| 190 | * QPSK modulation | ||
| 191 | */ | ||
| 192 | if (inversion == INVERSION_ON) | ||
| 193 | buf[0] = 0x60; | ||
| 194 | else if (inversion == INVERSION_OFF) | ||
| 195 | buf[0] = 0x20; | ||
| 196 | else | ||
| 197 | buf[0] = 0x00; | ||
| 198 | |||
| 199 | /* | ||
| 200 | * CLK ratio: | ||
| 201 | * system clock frequency is up to 64 or 96 MHz | ||
| 202 | * | ||
| 203 | * formula: | ||
| 204 | * r = k * clk / symbol_rate | ||
| 205 | * | ||
| 206 | * k: 2^21 for caa 0..3, | ||
| 207 | * 2^20 for caa 4..5, | ||
| 208 | * 2^19 for caa 6..7 | ||
| 209 | */ | ||
| 210 | if (symbol_rate <= (clk * 3) / 32) | ||
| 211 | k = (1 << 19); | ||
| 212 | else if (symbol_rate <= (clk * 3) / 16) | ||
| 213 | k = (1 << 20); | ||
| 214 | else | ||
| 215 | k = (1 << 21); | ||
| 216 | |||
| 217 | gcd = tda80xx_gcd(clk, sr); | ||
| 218 | clk /= gcd; | ||
| 219 | sr /= gcd; | ||
| 220 | |||
| 221 | gcd = tda80xx_gcd(k, sr); | ||
| 222 | k /= gcd; | ||
| 223 | sr /= gcd; | ||
| 224 | |||
| 225 | ratio = (u64)k * (u64)clk; | ||
| 226 | do_div(ratio, sr); | ||
| 227 | |||
| 228 | buf[1] = ratio >> 16; | ||
| 229 | buf[2] = ratio >> 8; | ||
| 230 | buf[3] = ratio; | ||
| 231 | |||
| 232 | /* nyquist filter roll-off factor 35% */ | ||
| 233 | buf[4] = 0x20; | ||
| 234 | |||
| 235 | clk = scd ? (state->clk / (scd * 2)) : state->clk; | ||
| 236 | |||
| 237 | /* Anti Alias Filter */ | ||
| 238 | if (symbol_rate < (clk * 3) / 64) | ||
| 239 | printk("tda80xx: unsupported symbol rate: %u\n", symbol_rate); | ||
| 240 | else if (symbol_rate <= clk / 16) | ||
| 241 | buf[4] |= 0x07; | ||
| 242 | else if (symbol_rate <= (clk * 3) / 32) | ||
| 243 | buf[4] |= 0x06; | ||
| 244 | else if (symbol_rate <= clk / 8) | ||
| 245 | buf[4] |= 0x05; | ||
| 246 | else if (symbol_rate <= (clk * 3) / 16) | ||
| 247 | buf[4] |= 0x04; | ||
| 248 | else if (symbol_rate <= clk / 4) | ||
| 249 | buf[4] |= 0x03; | ||
| 250 | else if (symbol_rate <= (clk * 3) / 8) | ||
| 251 | buf[4] |= 0x02; | ||
| 252 | else if (symbol_rate <= clk / 2) | ||
| 253 | buf[4] |= 0x01; | ||
| 254 | else | ||
| 255 | buf[4] |= 0x00; | ||
| 256 | |||
| 257 | /* Sigma Delta converter */ | ||
| 258 | buf[5] = 0x00; | ||
| 259 | |||
| 260 | /* FEC: Possible puncturing rates */ | ||
| 261 | if (fec_inner == FEC_NONE) | ||
| 262 | buf[6] = 0x00; | ||
| 263 | else if ((fec_inner >= FEC_1_2) && (fec_inner <= FEC_8_9)) | ||
| 264 | buf[6] = (1 << (8 - fec_inner)); | ||
| 265 | else if (fec_inner == FEC_AUTO) | ||
| 266 | buf[6] = 0xff; | ||
| 267 | else | ||
| 268 | return -EINVAL; | ||
| 269 | |||
| 270 | /* carrier lock detector threshold value */ | ||
| 271 | buf[7] = 0x30; | ||
| 272 | /* AFC1: proportional part settings */ | ||
| 273 | buf[8] = 0x42; | ||
| 274 | /* AFC1: integral part settings */ | ||
| 275 | buf[9] = 0x98; | ||
| 276 | /* PD: Leaky integrator SCPC mode */ | ||
| 277 | buf[10] = 0x28; | ||
| 278 | /* AFC2, AFC1 controls */ | ||
| 279 | buf[11] = 0x30; | ||
| 280 | /* PD: proportional part settings */ | ||
| 281 | buf[12] = 0x42; | ||
| 282 | /* PD: integral part settings */ | ||
| 283 | buf[13] = 0x99; | ||
| 284 | /* AGC */ | ||
| 285 | buf[14] = 0x50 | scd; | ||
| 286 | |||
| 287 | printk("symbol_rate=%u clk=%u\n", symbol_rate, clk); | ||
| 288 | |||
| 289 | return tda80xx_write(state, 0x01, buf, sizeof(buf)); | ||
| 290 | } | ||
| 291 | |||
| 292 | static int tda80xx_set_clk(struct tda80xx_state* state) | ||
| 293 | { | ||
| 294 | u8 buf[2]; | ||
| 295 | |||
| 296 | /* CLK proportional part */ | ||
| 297 | buf[0] = (0x06 << 5) | 0x08; /* CMP[2:0], CSP[4:0] */ | ||
| 298 | /* CLK integral part */ | ||
| 299 | buf[1] = (0x04 << 5) | 0x1a; /* CMI[2:0], CSI[4:0] */ | ||
| 300 | |||
| 301 | return tda80xx_write(state, 0x17, buf, sizeof(buf)); | ||
| 302 | } | ||
| 303 | |||
| 304 | #if 0 | ||
| 305 | static int tda80xx_set_scpc_freq_offset(struct tda80xx_state* state) | ||
| 306 | { | ||
| 307 | /* a constant value is nonsense here imho */ | ||
| 308 | return tda80xx_writereg(state, 0x22, 0xf9); | ||
| 309 | } | ||
| 310 | #endif | ||
| 311 | |||
| 312 | static int tda80xx_close_loop(struct tda80xx_state* state) | ||
| 313 | { | ||
| 314 | u8 buf[2]; | ||
| 315 | |||
| 316 | /* PD: Loop closed, LD: lock detect enable, SCPC: Sweep mode - AFC1 loop closed */ | ||
| 317 | buf[0] = 0x68; | ||
| 318 | /* AFC1: Loop closed, CAR Feedback: 8192 */ | ||
| 319 | buf[1] = 0x70; | ||
| 320 | |||
| 321 | return tda80xx_write(state, 0x0b, buf, sizeof(buf)); | ||
| 322 | } | ||
| 323 | |||
| 324 | static irqreturn_t tda80xx_irq(int irq, void *priv, struct pt_regs *pt) | ||
| 325 | { | ||
| 326 | schedule_work(priv); | ||
| 327 | |||
| 328 | return IRQ_HANDLED; | ||
| 329 | } | ||
| 330 | |||
| 331 | static void tda80xx_read_status_int(struct tda80xx_state* state) | ||
| 332 | { | ||
| 333 | u8 val; | ||
| 334 | |||
| 335 | static const fe_spectral_inversion_t inv_tab[] = { | ||
| 336 | INVERSION_OFF, INVERSION_ON | ||
| 337 | }; | ||
| 338 | |||
| 339 | static const fe_code_rate_t fec_tab[] = { | ||
| 340 | FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4, | ||
| 341 | FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8, | ||
| 342 | }; | ||
| 343 | |||
| 344 | val = tda80xx_readreg(state, 0x02); | ||
| 345 | |||
| 346 | state->status = 0; | ||
| 347 | |||
| 348 | if (val & 0x01) /* demodulator lock */ | ||
| 349 | state->status |= FE_HAS_SIGNAL; | ||
| 350 | if (val & 0x02) /* clock recovery lock */ | ||
| 351 | state->status |= FE_HAS_CARRIER; | ||
| 352 | if (val & 0x04) /* viterbi lock */ | ||
| 353 | state->status |= FE_HAS_VITERBI; | ||
| 354 | if (val & 0x08) /* deinterleaver lock (packet sync) */ | ||
| 355 | state->status |= FE_HAS_SYNC; | ||
| 356 | if (val & 0x10) /* derandomizer lock (frame sync) */ | ||
| 357 | state->status |= FE_HAS_LOCK; | ||
| 358 | if (val & 0x20) /* frontend can not lock */ | ||
| 359 | state->status |= FE_TIMEDOUT; | ||
| 360 | |||
| 361 | if ((state->status & (FE_HAS_CARRIER)) && (state->afc_loop)) { | ||
| 362 | printk("tda80xx: closing loop\n"); | ||
| 363 | tda80xx_close_loop(state); | ||
| 364 | state->afc_loop = 0; | ||
| 365 | } | ||
| 366 | |||
| 367 | if (state->status & (FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK)) { | ||
| 368 | val = tda80xx_readreg(state, 0x0e); | ||
| 369 | state->code_rate = fec_tab[val & 0x07]; | ||
| 370 | if (state->status & (FE_HAS_SYNC | FE_HAS_LOCK)) | ||
| 371 | state->spectral_inversion = inv_tab[(val >> 7) & 0x01]; | ||
| 372 | else | ||
| 373 | state->spectral_inversion = INVERSION_AUTO; | ||
| 374 | } | ||
| 375 | else { | ||
| 376 | state->code_rate = FEC_AUTO; | ||
| 377 | } | ||
| 378 | } | ||
| 379 | |||
| 380 | static void tda80xx_worklet(void *priv) | ||
| 381 | { | ||
| 382 | struct tda80xx_state *state = priv; | ||
| 383 | |||
| 384 | tda80xx_writereg(state, 0x00, 0x04); | ||
| 385 | enable_irq(state->config->irq); | ||
| 386 | |||
| 387 | tda80xx_read_status_int(state); | ||
| 388 | } | ||
| 389 | |||
| 390 | static void tda80xx_wait_diseqc_fifo(struct tda80xx_state* state) | ||
| 391 | { | ||
| 392 | size_t i; | ||
| 393 | |||
| 394 | for (i = 0; i < 100; i++) { | ||
| 395 | if (tda80xx_readreg(state, 0x02) & 0x80) | ||
| 396 | break; | ||
| 397 | msleep(10); | ||
| 398 | } | ||
| 399 | } | ||
| 400 | |||
| 401 | static int tda8044_init(struct dvb_frontend* fe) | ||
| 402 | { | ||
| 403 | struct tda80xx_state* state = fe->demodulator_priv; | ||
| 404 | int ret; | ||
| 405 | |||
| 406 | /* | ||
| 407 | * this function is a mess... | ||
| 408 | */ | ||
| 409 | |||
| 410 | if ((ret = tda80xx_write(state, 0x00, tda8044_inittab_pre, sizeof(tda8044_inittab_pre)))) | ||
| 411 | return ret; | ||
| 412 | |||
| 413 | tda80xx_writereg(state, 0x0f, 0x50); | ||
| 414 | #if 1 | ||
| 415 | tda80xx_writereg(state, 0x20, 0x8F); /* FIXME */ | ||
| 416 | tda80xx_writereg(state, 0x20, state->config->volt18setting); /* FIXME */ | ||
| 417 | //tda80xx_writereg(state, 0x00, 0x04); | ||
| 418 | tda80xx_writereg(state, 0x00, 0x0C); | ||
| 419 | #endif | ||
| 420 | //tda80xx_writereg(state, 0x00, 0x08); /* Reset AFC1 loop filter */ | ||
| 421 | |||
| 422 | tda80xx_write(state, 0x00, tda8044_inittab_post, sizeof(tda8044_inittab_post)); | ||
| 423 | |||
| 424 | if (state->config->pll_init) { | ||
| 425 | tda80xx_writereg(state, 0x1c, 0x80); | ||
| 426 | state->config->pll_init(fe); | ||
| 427 | tda80xx_writereg(state, 0x1c, 0x00); | ||
| 428 | } | ||
| 429 | |||
| 430 | return 0; | ||
| 431 | } | ||
| 432 | |||
| 433 | static int tda8083_init(struct dvb_frontend* fe) | ||
| 434 | { | ||
| 435 | struct tda80xx_state* state = fe->demodulator_priv; | ||
| 436 | |||
| 437 | tda80xx_write(state, 0x00, tda8083_inittab, sizeof(tda8083_inittab)); | ||
| 438 | |||
| 439 | if (state->config->pll_init) { | ||
| 440 | tda80xx_writereg(state, 0x1c, 0x80); | ||
| 441 | state->config->pll_init(fe); | ||
| 442 | tda80xx_writereg(state, 0x1c, 0x00); | ||
| 443 | } | ||
| 444 | |||
| 445 | return 0; | ||
| 446 | } | ||
| 447 | |||
| 448 | static int tda80xx_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | ||
| 449 | { | ||
| 450 | struct tda80xx_state* state = fe->demodulator_priv; | ||
| 451 | |||
| 452 | switch (voltage) { | ||
| 453 | case SEC_VOLTAGE_13: | ||
| 454 | return tda80xx_writereg(state, 0x20, state->config->volt13setting); | ||
| 455 | case SEC_VOLTAGE_18: | ||
| 456 | return tda80xx_writereg(state, 0x20, state->config->volt18setting); | ||
| 457 | case SEC_VOLTAGE_OFF: | ||
| 458 | return tda80xx_writereg(state, 0x20, 0); | ||
| 459 | default: | ||
| 460 | return -EINVAL; | ||
| 461 | } | ||
| 462 | } | ||
| 463 | |||
| 464 | static int tda80xx_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | ||
| 465 | { | ||
| 466 | struct tda80xx_state* state = fe->demodulator_priv; | ||
| 467 | |||
| 468 | switch (tone) { | ||
| 469 | case SEC_TONE_OFF: | ||
| 470 | return tda80xx_writereg(state, 0x29, 0x00); | ||
| 471 | case SEC_TONE_ON: | ||
| 472 | return tda80xx_writereg(state, 0x29, 0x80); | ||
| 473 | default: | ||
| 474 | return -EINVAL; | ||
| 475 | } | ||
| 476 | } | ||
| 477 | |||
| 478 | static int tda80xx_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd) | ||
| 479 | { | ||
| 480 | struct tda80xx_state* state = fe->demodulator_priv; | ||
| 481 | |||
| 482 | if (cmd->msg_len > 6) | ||
| 483 | return -EINVAL; | ||
| 484 | |||
| 485 | tda80xx_writereg(state, 0x29, 0x08 | (cmd->msg_len - 3)); | ||
| 486 | tda80xx_write(state, 0x23, cmd->msg, cmd->msg_len); | ||
| 487 | tda80xx_writereg(state, 0x29, 0x0c | (cmd->msg_len - 3)); | ||
| 488 | tda80xx_wait_diseqc_fifo(state); | ||
| 489 | |||
| 490 | return 0; | ||
| 491 | } | ||
| 492 | |||
| 493 | static int tda80xx_send_diseqc_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t cmd) | ||
| 494 | { | ||
| 495 | struct tda80xx_state* state = fe->demodulator_priv; | ||
| 496 | |||
| 497 | switch (cmd) { | ||
| 498 | case SEC_MINI_A: | ||
| 499 | tda80xx_writereg(state, 0x29, 0x14); | ||
| 500 | break; | ||
| 501 | case SEC_MINI_B: | ||
| 502 | tda80xx_writereg(state, 0x29, 0x1c); | ||
| 503 | break; | ||
| 504 | default: | ||
| 505 | return -EINVAL; | ||
| 506 | } | ||
| 507 | |||
| 508 | tda80xx_wait_diseqc_fifo(state); | ||
| 509 | |||
| 510 | return 0; | ||
| 511 | } | ||
| 512 | |||
| 513 | static int tda80xx_sleep(struct dvb_frontend* fe) | ||
| 514 | { | ||
| 515 | struct tda80xx_state* state = fe->demodulator_priv; | ||
| 516 | |||
| 517 | tda80xx_writereg(state, 0x00, 0x02); /* enter standby */ | ||
| 518 | |||
| 519 | return 0; | ||
| 520 | } | ||
| 521 | |||
| 522 | static int tda80xx_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | ||
| 523 | { | ||
| 524 | struct tda80xx_state* state = fe->demodulator_priv; | ||
| 525 | |||
| 526 | tda80xx_writereg(state, 0x1c, 0x80); | ||
| 527 | state->config->pll_set(fe, p); | ||
| 528 | tda80xx_writereg(state, 0x1c, 0x00); | ||
| 529 | |||
| 530 | tda80xx_set_parameters(state, p->inversion, p->u.qpsk.symbol_rate, p->u.qpsk.fec_inner); | ||
| 531 | tda80xx_set_clk(state); | ||
| 532 | //tda80xx_set_scpc_freq_offset(state); | ||
| 533 | state->afc_loop = 1; | ||
| 534 | |||
| 535 | return 0; | ||
| 536 | } | ||
| 537 | |||
| 538 | static int tda80xx_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | ||
| 539 | { | ||
| 540 | struct tda80xx_state* state = fe->demodulator_priv; | ||
| 541 | |||
| 542 | if (!state->config->irq) | ||
| 543 | tda80xx_read_status_int(state); | ||
| 544 | |||
| 545 | p->inversion = state->spectral_inversion; | ||
| 546 | p->u.qpsk.fec_inner = state->code_rate; | ||
| 547 | |||
| 548 | return 0; | ||
| 549 | } | ||
| 550 | |||
| 551 | static int tda80xx_read_status(struct dvb_frontend* fe, fe_status_t* status) | ||
| 552 | { | ||
| 553 | struct tda80xx_state* state = fe->demodulator_priv; | ||
| 554 | |||
| 555 | if (!state->config->irq) | ||
| 556 | tda80xx_read_status_int(state); | ||
| 557 | *status = state->status; | ||
| 558 | |||
| 559 | return 0; | ||
| 560 | } | ||
| 561 | |||
| 562 | static int tda80xx_read_ber(struct dvb_frontend* fe, u32* ber) | ||
| 563 | { | ||
| 564 | struct tda80xx_state* state = fe->demodulator_priv; | ||
| 565 | int ret; | ||
| 566 | u8 buf[3]; | ||
| 567 | |||
| 568 | if ((ret = tda80xx_read(state, 0x0b, buf, sizeof(buf)))) | ||
| 569 | return ret; | ||
| 570 | |||
| 571 | *ber = ((buf[0] & 0x1f) << 16) | (buf[1] << 8) | buf[2]; | ||
| 572 | |||
| 573 | return 0; | ||
| 574 | } | ||
| 575 | |||
| 576 | static int tda80xx_read_signal_strength(struct dvb_frontend* fe, u16* strength) | ||
| 577 | { | ||
| 578 | struct tda80xx_state* state = fe->demodulator_priv; | ||
| 579 | |||
| 580 | u8 gain = ~tda80xx_readreg(state, 0x01); | ||
| 581 | *strength = (gain << 8) | gain; | ||
| 582 | |||
| 583 | return 0; | ||
| 584 | } | ||
| 585 | |||
| 586 | static int tda80xx_read_snr(struct dvb_frontend* fe, u16* snr) | ||
| 587 | { | ||
| 588 | struct tda80xx_state* state = fe->demodulator_priv; | ||
| 589 | |||
| 590 | u8 quality = tda80xx_readreg(state, 0x08); | ||
| 591 | *snr = (quality << 8) | quality; | ||
| 592 | |||
| 593 | return 0; | ||
| 594 | } | ||
| 595 | |||
| 596 | static int tda80xx_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | ||
| 597 | { | ||
| 598 | struct tda80xx_state* state = fe->demodulator_priv; | ||
| 599 | |||
| 600 | *ucblocks = tda80xx_readreg(state, 0x0f); | ||
| 601 | if (*ucblocks == 0xff) | ||
| 602 | *ucblocks = 0xffffffff; | ||
| 603 | |||
| 604 | return 0; | ||
| 605 | } | ||
| 606 | |||
| 607 | static int tda80xx_init(struct dvb_frontend* fe) | ||
| 608 | { | ||
| 609 | struct tda80xx_state* state = fe->demodulator_priv; | ||
| 610 | |||
| 611 | switch(state->id) { | ||
| 612 | case ID_TDA8044: | ||
| 613 | return tda8044_init(fe); | ||
| 614 | |||
| 615 | case ID_TDA8083: | ||
| 616 | return tda8083_init(fe); | ||
| 617 | } | ||
| 618 | return 0; | ||
| 619 | } | ||
| 620 | |||
| 621 | static void tda80xx_release(struct dvb_frontend* fe) | ||
| 622 | { | ||
| 623 | struct tda80xx_state* state = fe->demodulator_priv; | ||
| 624 | |||
| 625 | if (state->config->irq) | ||
| 626 | free_irq(state->config->irq, &state->worklet); | ||
| 627 | |||
| 628 | kfree(state); | ||
| 629 | } | ||
| 630 | |||
| 631 | static struct dvb_frontend_ops tda80xx_ops; | ||
| 632 | |||
| 633 | struct dvb_frontend* tda80xx_attach(const struct tda80xx_config* config, | ||
| 634 | struct i2c_adapter* i2c) | ||
| 635 | { | ||
| 636 | struct tda80xx_state* state = NULL; | ||
| 637 | int ret; | ||
| 638 | |||
| 639 | /* allocate memory for the internal state */ | ||
| 640 | state = kmalloc(sizeof(struct tda80xx_state), GFP_KERNEL); | ||
| 641 | if (state == NULL) goto error; | ||
| 642 | |||
| 643 | /* setup the state */ | ||
| 644 | state->config = config; | ||
| 645 | state->i2c = i2c; | ||
| 646 | memcpy(&state->ops, &tda80xx_ops, sizeof(struct dvb_frontend_ops)); | ||
| 647 | state->spectral_inversion = INVERSION_AUTO; | ||
| 648 | state->code_rate = FEC_AUTO; | ||
| 649 | state->status = 0; | ||
| 650 | state->afc_loop = 0; | ||
| 651 | |||
| 652 | /* check if the demod is there */ | ||
| 653 | if (tda80xx_writereg(state, 0x89, 0x00) < 0) goto error; | ||
| 654 | state->id = tda80xx_readreg(state, 0x00); | ||
| 655 | |||
| 656 | switch (state->id) { | ||
| 657 | case ID_TDA8044: | ||
| 658 | state->clk = 96000000; | ||
| 659 | printk("tda80xx: Detected tda8044\n"); | ||
| 660 | break; | ||
| 661 | |||
| 662 | case ID_TDA8083: | ||
| 663 | state->clk = 64000000; | ||
| 664 | printk("tda80xx: Detected tda8083\n"); | ||
| 665 | break; | ||
| 666 | |||
| 667 | default: | ||
| 668 | goto error; | ||
| 669 | } | ||
| 670 | |||
| 671 | /* setup IRQ */ | ||
| 672 | if (state->config->irq) { | ||
| 673 | INIT_WORK(&state->worklet, tda80xx_worklet, state); | ||
| 674 | if ((ret = request_irq(state->config->irq, tda80xx_irq, SA_ONESHOT, "tda80xx", &state->worklet)) < 0) { | ||
| 675 | printk(KERN_ERR "tda80xx: request_irq failed (%d)\n", ret); | ||
| 676 | goto error; | ||
| 677 | } | ||
| 678 | } | ||
| 679 | |||
| 680 | /* create dvb_frontend */ | ||
| 681 | state->frontend.ops = &state->ops; | ||
| 682 | state->frontend.demodulator_priv = state; | ||
| 683 | return &state->frontend; | ||
| 684 | |||
| 685 | error: | ||
| 686 | kfree(state); | ||
| 687 | return NULL; | ||
| 688 | } | ||
| 689 | |||
| 690 | static struct dvb_frontend_ops tda80xx_ops = { | ||
| 691 | |||
| 692 | .info = { | ||
| 693 | .name = "Philips TDA80xx DVB-S", | ||
| 694 | .type = FE_QPSK, | ||
| 695 | .frequency_min = 500000, | ||
| 696 | .frequency_max = 2700000, | ||
| 697 | .frequency_stepsize = 125, | ||
| 698 | .symbol_rate_min = 4500000, | ||
| 699 | .symbol_rate_max = 45000000, | ||
| 700 | .caps = FE_CAN_INVERSION_AUTO | | ||
| 701 | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | | ||
| 702 | FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | | ||
| 703 | FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO | | ||
| 704 | FE_CAN_QPSK | | ||
| 705 | FE_CAN_MUTE_TS | ||
| 706 | }, | ||
| 707 | |||
| 708 | .release = tda80xx_release, | ||
| 709 | |||
| 710 | .init = tda80xx_init, | ||
| 711 | .sleep = tda80xx_sleep, | ||
| 712 | |||
| 713 | .set_frontend = tda80xx_set_frontend, | ||
| 714 | .get_frontend = tda80xx_get_frontend, | ||
| 715 | |||
| 716 | .read_status = tda80xx_read_status, | ||
| 717 | .read_ber = tda80xx_read_ber, | ||
| 718 | .read_signal_strength = tda80xx_read_signal_strength, | ||
| 719 | .read_snr = tda80xx_read_snr, | ||
| 720 | .read_ucblocks = tda80xx_read_ucblocks, | ||
| 721 | |||
| 722 | .diseqc_send_master_cmd = tda80xx_send_diseqc_msg, | ||
| 723 | .diseqc_send_burst = tda80xx_send_diseqc_burst, | ||
| 724 | .set_tone = tda80xx_set_tone, | ||
| 725 | .set_voltage = tda80xx_set_voltage, | ||
| 726 | }; | ||
| 727 | |||
| 728 | module_param(debug, int, 0644); | ||
| 729 | |||
| 730 | MODULE_DESCRIPTION("Philips TDA8044 / TDA8083 DVB-S Demodulator driver"); | ||
| 731 | MODULE_AUTHOR("Felix Domke, Andreas Oberritter"); | ||
| 732 | MODULE_LICENSE("GPL"); | ||
| 733 | |||
| 734 | EXPORT_SYMBOL(tda80xx_attach); | ||
diff --git a/drivers/media/dvb/frontends/tda80xx.h b/drivers/media/dvb/frontends/tda80xx.h deleted file mode 100644 index cd639a0aad55..000000000000 --- a/drivers/media/dvb/frontends/tda80xx.h +++ /dev/null | |||
| @@ -1,51 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * tda80xx.c | ||
| 3 | * | ||
| 4 | * Philips TDA8044 / TDA8083 QPSK demodulator driver | ||
| 5 | * | ||
| 6 | * Copyright (C) 2001 Felix Domke <tmbinc@elitedvb.net> | ||
| 7 | * Copyright (C) 2002-2004 Andreas Oberritter <obi@linuxtv.org> | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License as published by | ||
| 11 | * the Free Software Foundation; either version 2 of the License, or | ||
| 12 | * (at your option) any later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, | ||
| 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | * GNU General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License | ||
| 20 | * along with this program; if not, write to the Free Software | ||
| 21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 22 | */ | ||
| 23 | |||
| 24 | #ifndef TDA80XX_H | ||
| 25 | #define TDA80XX_H | ||
| 26 | |||
| 27 | #include <linux/dvb/frontend.h> | ||
| 28 | |||
| 29 | struct tda80xx_config | ||
| 30 | { | ||
| 31 | /* the demodulator's i2c address */ | ||
| 32 | u8 demod_address; | ||
| 33 | |||
| 34 | /* IRQ to use (0=>no IRQ used) */ | ||
| 35 | u32 irq; | ||
| 36 | |||
| 37 | /* Register setting to use for 13v */ | ||
| 38 | u8 volt13setting; | ||
| 39 | |||
| 40 | /* Register setting to use for 18v */ | ||
| 41 | u8 volt18setting; | ||
| 42 | |||
| 43 | /* PLL maintenance */ | ||
| 44 | int (*pll_init)(struct dvb_frontend* fe); | ||
| 45 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); | ||
| 46 | }; | ||
| 47 | |||
| 48 | extern struct dvb_frontend* tda80xx_attach(const struct tda80xx_config* config, | ||
| 49 | struct i2c_adapter* i2c); | ||
| 50 | |||
| 51 | #endif // TDA80XX_H | ||
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 27494901975f..d36369e9e88f 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
| @@ -2329,6 +2329,17 @@ static int frontend_init(struct av7110 *av7110) | |||
| 2329 | av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110)); | 2329 | av7110->fe = ves1820_attach(&alps_tdbe2_config, &av7110->i2c_adap, read_pwm(av7110)); |
| 2330 | break; | 2330 | break; |
| 2331 | 2331 | ||
| 2332 | case 0x0004: // Galaxis DVB-S rev1.3 | ||
| 2333 | /* ALPS BSRV2 */ | ||
| 2334 | av7110->fe = ves1x93_attach(&alps_bsrv2_config, &av7110->i2c_adap); | ||
| 2335 | if (av7110->fe) { | ||
| 2336 | av7110->fe->ops->diseqc_send_master_cmd = av7110_diseqc_send_master_cmd; | ||
| 2337 | av7110->fe->ops->diseqc_send_burst = av7110_diseqc_send_burst; | ||
| 2338 | av7110->fe->ops->set_tone = av7110_set_tone; | ||
| 2339 | av7110->recover = dvb_s_recover; | ||
| 2340 | } | ||
| 2341 | break; | ||
| 2342 | |||
| 2332 | case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */ | 2343 | case 0x0006: /* Fujitsu-Siemens DVB-S rev 1.6 */ |
| 2333 | /* Grundig 29504-451 */ | 2344 | /* Grundig 29504-451 */ |
| 2334 | av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); | 2345 | av7110->fe = tda8083_attach(&grundig_29504_451_config, &av7110->i2c_adap); |
| @@ -2930,6 +2941,7 @@ MAKE_AV7110_INFO(tts_1_3se, "Technotrend/Hauppauge WinTV DVB-S rev1.3 SE"); | |||
| 2930 | MAKE_AV7110_INFO(ttt, "Technotrend/Hauppauge DVB-T"); | 2941 | MAKE_AV7110_INFO(ttt, "Technotrend/Hauppauge DVB-T"); |
| 2931 | MAKE_AV7110_INFO(fsc, "Fujitsu Siemens DVB-C"); | 2942 | MAKE_AV7110_INFO(fsc, "Fujitsu Siemens DVB-C"); |
| 2932 | MAKE_AV7110_INFO(fss, "Fujitsu Siemens DVB-S rev1.6"); | 2943 | MAKE_AV7110_INFO(fss, "Fujitsu Siemens DVB-S rev1.6"); |
| 2944 | MAKE_AV7110_INFO(gxs_1_3, "Galaxis DVB-S rev1.3"); | ||
| 2933 | 2945 | ||
| 2934 | static struct pci_device_id pci_tbl[] = { | 2946 | static struct pci_device_id pci_tbl[] = { |
| 2935 | MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000), | 2947 | MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000), |
| @@ -2937,13 +2949,13 @@ static struct pci_device_id pci_tbl[] = { | |||
| 2937 | MAKE_EXTENSION_PCI(ttt_1_X, 0x13c2, 0x0001), | 2949 | MAKE_EXTENSION_PCI(ttt_1_X, 0x13c2, 0x0001), |
| 2938 | MAKE_EXTENSION_PCI(ttc_2_X, 0x13c2, 0x0002), | 2950 | MAKE_EXTENSION_PCI(ttc_2_X, 0x13c2, 0x0002), |
| 2939 | MAKE_EXTENSION_PCI(tts_2_X, 0x13c2, 0x0003), | 2951 | MAKE_EXTENSION_PCI(tts_2_X, 0x13c2, 0x0003), |
| 2952 | MAKE_EXTENSION_PCI(gxs_1_3, 0x13c2, 0x0004), | ||
| 2940 | MAKE_EXTENSION_PCI(fss, 0x13c2, 0x0006), | 2953 | MAKE_EXTENSION_PCI(fss, 0x13c2, 0x0006), |
| 2941 | MAKE_EXTENSION_PCI(ttt, 0x13c2, 0x0008), | 2954 | MAKE_EXTENSION_PCI(ttt, 0x13c2, 0x0008), |
| 2942 | MAKE_EXTENSION_PCI(ttc_1_X, 0x13c2, 0x000a), | 2955 | MAKE_EXTENSION_PCI(ttc_1_X, 0x13c2, 0x000a), |
| 2943 | MAKE_EXTENSION_PCI(tts_2_3, 0x13c2, 0x000e), | 2956 | MAKE_EXTENSION_PCI(tts_2_3, 0x13c2, 0x000e), |
| 2944 | MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002), | 2957 | MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002), |
| 2945 | 2958 | ||
| 2946 | /* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0004), UNDEFINED CARD */ // Galaxis DVB PC-Sat-Carte | ||
| 2947 | /* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1 | 2959 | /* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1 |
| 2948 | /* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v???? | 2960 | /* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0009), UNDEFINED CARD */ // TT/Hauppauge WinTV Nexus-CA v???? |
| 2949 | 2961 | ||
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h index 6ea30df2e823..fafd25fab835 100644 --- a/drivers/media/dvb/ttpci/av7110.h +++ b/drivers/media/dvb/ttpci/av7110.h | |||
| @@ -273,8 +273,6 @@ struct av7110 { | |||
| 273 | extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, | 273 | extern int ChangePIDs(struct av7110 *av7110, u16 vpid, u16 apid, u16 ttpid, |
| 274 | u16 subpid, u16 pcrpid); | 274 | u16 subpid, u16 pcrpid); |
| 275 | 275 | ||
| 276 | extern int av7110_setup_irc_config (struct av7110 *av7110, u32 ir_config); | ||
| 277 | |||
| 278 | extern int av7110_ir_init(struct av7110 *av7110); | 276 | extern int av7110_ir_init(struct av7110 *av7110); |
| 279 | extern void av7110_ir_exit(struct av7110 *av7110); | 277 | extern void av7110_ir_exit(struct av7110 *av7110); |
| 280 | 278 | ||
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c index 9138132ad25f..617e4f6c0ed7 100644 --- a/drivers/media/dvb/ttpci/av7110_ir.c +++ b/drivers/media/dvb/ttpci/av7110_ir.c | |||
| @@ -155,6 +155,19 @@ static void input_repeat_key(unsigned long data) | |||
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | 157 | ||
| 158 | static int av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config) | ||
| 159 | { | ||
| 160 | int ret = 0; | ||
| 161 | |||
| 162 | dprintk(4, "%p\n", av7110); | ||
| 163 | if (av7110) { | ||
| 164 | ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config); | ||
| 165 | av7110->ir_config = ir_config; | ||
| 166 | } | ||
| 167 | return ret; | ||
| 168 | } | ||
| 169 | |||
| 170 | |||
| 158 | static int av7110_ir_write_proc(struct file *file, const char __user *buffer, | 171 | static int av7110_ir_write_proc(struct file *file, const char __user *buffer, |
| 159 | unsigned long count, void *data) | 172 | unsigned long count, void *data) |
| 160 | { | 173 | { |
| @@ -187,19 +200,6 @@ static int av7110_ir_write_proc(struct file *file, const char __user *buffer, | |||
| 187 | } | 200 | } |
| 188 | 201 | ||
| 189 | 202 | ||
| 190 | int av7110_setup_irc_config(struct av7110 *av7110, u32 ir_config) | ||
| 191 | { | ||
| 192 | int ret = 0; | ||
| 193 | |||
| 194 | dprintk(4, "%p\n", av7110); | ||
| 195 | if (av7110) { | ||
| 196 | ret = av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, ir_config); | ||
| 197 | av7110->ir_config = ir_config; | ||
| 198 | } | ||
| 199 | return ret; | ||
| 200 | } | ||
| 201 | |||
| 202 | |||
| 203 | static void ir_handler(struct av7110 *av7110, u32 ircom) | 203 | static void ir_handler(struct av7110 *av7110, u32 ircom) |
| 204 | { | 204 | { |
| 205 | dprintk(4, "ircommand = %08x\n", ircom); | 205 | dprintk(4, "ircommand = %08x\n", ircom); |
diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c index aa4c4c521880..578b20085082 100644 --- a/drivers/media/video/bttv-driver.c +++ b/drivers/media/video/bttv-driver.c | |||
| @@ -214,7 +214,7 @@ const struct bttv_tvnorm bttv_tvnorms[] = { | |||
| 214 | we can capture, of the first and second field. */ | 214 | we can capture, of the first and second field. */ |
| 215 | .vbistart = { 7,320 }, | 215 | .vbistart = { 7,320 }, |
| 216 | },{ | 216 | },{ |
| 217 | .v4l2_id = V4L2_STD_NTSC_M, | 217 | .v4l2_id = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR, |
| 218 | .name = "NTSC", | 218 | .name = "NTSC", |
| 219 | .Fsc = 28636363, | 219 | .Fsc = 28636363, |
| 220 | .swidth = 768, | 220 | .swidth = 768, |
diff --git a/drivers/media/video/compat_ioctl32.c b/drivers/media/video/compat_ioctl32.c index 297c32ab51e3..840fe0177121 100644 --- a/drivers/media/video/compat_ioctl32.c +++ b/drivers/media/video/compat_ioctl32.c | |||
| @@ -167,29 +167,32 @@ static int get_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user | |||
| 167 | if (kp->clipcount > 2048) | 167 | if (kp->clipcount > 2048) |
| 168 | return -EINVAL; | 168 | return -EINVAL; |
| 169 | if (kp->clipcount) { | 169 | if (kp->clipcount) { |
| 170 | struct v4l2_clip32 *uclips = compat_ptr(up->clips); | 170 | struct v4l2_clip32 __user *uclips; |
| 171 | struct v4l2_clip *kclips; | 171 | struct v4l2_clip __user *kclips; |
| 172 | int n = kp->clipcount; | 172 | int n = kp->clipcount; |
| 173 | compat_caddr_t p; | ||
| 173 | 174 | ||
| 175 | if (get_user(p, &up->clips)) | ||
| 176 | return -EFAULT; | ||
| 177 | uclips = compat_ptr(p); | ||
| 174 | kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip)); | 178 | kclips = compat_alloc_user_space(n * sizeof(struct v4l2_clip)); |
| 175 | kp->clips = kclips; | 179 | kp->clips = kclips; |
| 176 | while (--n >= 0) { | 180 | while (--n >= 0) { |
| 177 | if (!access_ok(VERIFY_READ, &uclips->c, sizeof(uclips->c)) || | 181 | if (copy_in_user(&kclips->c, &uclips->c, sizeof(uclips->c))) |
| 178 | copy_from_user(&kclips->c, &uclips->c, sizeof(uclips->c))) | 182 | return -EFAULT; |
| 183 | if (put_user(n ? kclips + 1 : NULL, &kclips->next)) | ||
| 179 | return -EFAULT; | 184 | return -EFAULT; |
| 180 | kclips->next = n ? kclips + 1 : 0; | ||
| 181 | uclips += 1; | 185 | uclips += 1; |
| 182 | kclips += 1; | 186 | kclips += 1; |
| 183 | } | 187 | } |
| 184 | } else | 188 | } else |
| 185 | kp->clips = 0; | 189 | kp->clips = NULL; |
| 186 | return 0; | 190 | return 0; |
| 187 | } | 191 | } |
| 188 | 192 | ||
| 189 | static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up) | 193 | static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user *up) |
| 190 | { | 194 | { |
| 191 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_window32)) || | 195 | if (copy_to_user(&up->w, &kp->w, sizeof(up->w)) || |
| 192 | copy_to_user(&up->w, &kp->w, sizeof(up->w)) || | ||
| 193 | put_user(kp->field, &up->field) || | 196 | put_user(kp->field, &up->field) || |
| 194 | put_user(kp->chromakey, &up->chromakey) || | 197 | put_user(kp->chromakey, &up->chromakey) || |
| 195 | put_user(kp->clipcount, &up->clipcount)) | 198 | put_user(kp->clipcount, &up->clipcount)) |
| @@ -199,33 +202,29 @@ static int put_v4l2_window32(struct v4l2_window *kp, struct v4l2_window32 __user | |||
| 199 | 202 | ||
| 200 | static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) | 203 | static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) |
| 201 | { | 204 | { |
| 202 | if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_pix_format)) || | 205 | if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format))) |
| 203 | copy_from_user(kp, up, sizeof(struct v4l2_pix_format))) | 206 | return -EFAULT; |
| 204 | return -EFAULT; | ||
| 205 | return 0; | 207 | return 0; |
| 206 | } | 208 | } |
| 207 | 209 | ||
| 208 | static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) | 210 | static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) |
| 209 | { | 211 | { |
| 210 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_pix_format)) || | 212 | if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format))) |
| 211 | copy_to_user(up, kp, sizeof(struct v4l2_pix_format))) | 213 | return -EFAULT; |
| 212 | return -EFAULT; | ||
| 213 | return 0; | 214 | return 0; |
| 214 | } | 215 | } |
| 215 | 216 | ||
| 216 | static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) | 217 | static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) |
| 217 | { | 218 | { |
| 218 | if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_vbi_format)) || | 219 | if (copy_from_user(kp, up, sizeof(struct v4l2_vbi_format))) |
| 219 | copy_from_user(kp, up, sizeof(struct v4l2_vbi_format))) | 220 | return -EFAULT; |
| 220 | return -EFAULT; | ||
| 221 | return 0; | 221 | return 0; |
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) | 224 | static inline int put_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) |
| 225 | { | 225 | { |
| 226 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_vbi_format)) || | 226 | if (copy_to_user(up, kp, sizeof(struct v4l2_vbi_format))) |
| 227 | copy_to_user(up, kp, sizeof(struct v4l2_vbi_format))) | 227 | return -EFAULT; |
| 228 | return -EFAULT; | ||
| 229 | return 0; | 228 | return 0; |
| 230 | } | 229 | } |
| 231 | 230 | ||
| @@ -279,18 +278,16 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user | |||
| 279 | 278 | ||
| 280 | static inline int get_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up) | 279 | static inline int get_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up) |
| 281 | { | 280 | { |
| 282 | if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_standard)) || | 281 | if (copy_from_user(kp, up, sizeof(struct v4l2_standard))) |
| 283 | copy_from_user(kp, up, sizeof(struct v4l2_standard))) | 282 | return -EFAULT; |
| 284 | return -EFAULT; | ||
| 285 | return 0; | 283 | return 0; |
| 286 | 284 | ||
| 287 | } | 285 | } |
| 288 | 286 | ||
| 289 | static inline int put_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up) | 287 | static inline int put_v4l2_standard(struct v4l2_standard *kp, struct v4l2_standard __user *up) |
| 290 | { | 288 | { |
| 291 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_standard)) || | 289 | if (copy_to_user(up, kp, sizeof(struct v4l2_standard))) |
| 292 | copy_to_user(up, kp, sizeof(struct v4l2_standard))) | 290 | return -EFAULT; |
| 293 | return -EFAULT; | ||
| 294 | return 0; | 291 | return 0; |
| 295 | } | 292 | } |
| 296 | 293 | ||
| @@ -328,18 +325,16 @@ static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32 | |||
| 328 | 325 | ||
| 329 | static inline int get_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up) | 326 | static inline int get_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up) |
| 330 | { | 327 | { |
| 331 | if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_tuner)) || | 328 | if (copy_from_user(kp, up, sizeof(struct v4l2_tuner))) |
| 332 | copy_from_user(kp, up, sizeof(struct v4l2_tuner))) | 329 | return -EFAULT; |
| 333 | return -EFAULT; | ||
| 334 | return 0; | 330 | return 0; |
| 335 | 331 | ||
| 336 | } | 332 | } |
| 337 | 333 | ||
| 338 | static inline int put_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up) | 334 | static inline int put_v4l2_tuner(struct v4l2_tuner *kp, struct v4l2_tuner __user *up) |
| 339 | { | 335 | { |
| 340 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_tuner)) || | 336 | if (copy_to_user(up, kp, sizeof(struct v4l2_tuner))) |
| 341 | copy_to_user(up, kp, sizeof(struct v4l2_tuner))) | 337 | return -EFAULT; |
| 342 | return -EFAULT; | ||
| 343 | return 0; | 338 | return 0; |
| 344 | } | 339 | } |
| 345 | 340 | ||
| @@ -380,11 +375,13 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user | |||
| 380 | break; | 375 | break; |
| 381 | case V4L2_MEMORY_USERPTR: | 376 | case V4L2_MEMORY_USERPTR: |
| 382 | { | 377 | { |
| 383 | unsigned long tmp = (unsigned long)compat_ptr(up->m.userptr); | 378 | compat_long_t tmp; |
| 384 | 379 | ||
| 385 | if(get_user(kp->length, &up->length) || | 380 | if (get_user(kp->length, &up->length) || |
| 386 | get_user(kp->m.userptr, &tmp)) | 381 | get_user(tmp, &up->m.userptr)) |
| 387 | return -EFAULT; | 382 | return -EFAULT; |
| 383 | |||
| 384 | kp->m.userptr = (unsigned long)compat_ptr(tmp); | ||
| 388 | } | 385 | } |
| 389 | break; | 386 | break; |
| 390 | case V4L2_MEMORY_OVERLAY: | 387 | case V4L2_MEMORY_OVERLAY: |
| @@ -468,33 +465,29 @@ static int put_v4l2_framebuffer32(struct v4l2_framebuffer *kp, struct v4l2_frame | |||
| 468 | 465 | ||
| 469 | static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up) | 466 | static inline int get_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up) |
| 470 | { | 467 | { |
| 471 | if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_input) - 4) || | 468 | if (copy_from_user(kp, up, sizeof(struct v4l2_input) - 4)) |
| 472 | copy_from_user(kp, up, sizeof(struct v4l2_input) - 4)) | 469 | return -EFAULT; |
| 473 | return -EFAULT; | ||
| 474 | return 0; | 470 | return 0; |
| 475 | } | 471 | } |
| 476 | 472 | ||
| 477 | static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up) | 473 | static inline int put_v4l2_input32(struct v4l2_input *kp, struct v4l2_input __user *up) |
| 478 | { | 474 | { |
| 479 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_input) - 4) || | 475 | if (copy_to_user(up, kp, sizeof(struct v4l2_input) - 4)) |
| 480 | copy_to_user(up, kp, sizeof(struct v4l2_input) - 4)) | 476 | return -EFAULT; |
| 481 | return -EFAULT; | ||
| 482 | return 0; | 477 | return 0; |
| 483 | } | 478 | } |
| 484 | 479 | ||
| 485 | static inline int get_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up) | 480 | static inline int get_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up) |
| 486 | { | 481 | { |
| 487 | if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_input)) || | 482 | if (copy_from_user(kp, up, sizeof(struct v4l2_input))) |
| 488 | copy_from_user(kp, up, sizeof(struct v4l2_input))) | 483 | return -EFAULT; |
| 489 | return -EFAULT; | ||
| 490 | return 0; | 484 | return 0; |
| 491 | } | 485 | } |
| 492 | 486 | ||
| 493 | static inline int put_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up) | 487 | static inline int put_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user *up) |
| 494 | { | 488 | { |
| 495 | if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_input)) || | 489 | if (copy_to_user(up, kp, sizeof(struct v4l2_input))) |
| 496 | copy_to_user(up, kp, sizeof(struct v4l2_input))) | 490 | return -EFAULT; |
| 497 | return -EFAULT; | ||
| 498 | return 0; | 491 | return 0; |
| 499 | } | 492 | } |
| 500 | 493 | ||
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index c66c2c1f4809..08ffd1f325fc 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c | |||
| @@ -220,33 +220,23 @@ static void input_change(struct i2c_client *client) | |||
| 220 | cx25840_write(client, 0x808, 0xff); | 220 | cx25840_write(client, 0x808, 0xff); |
| 221 | cx25840_write(client, 0x80b, 0x10); | 221 | cx25840_write(client, 0x80b, 0x10); |
| 222 | } else if (std & V4L2_STD_NTSC) { | 222 | } else if (std & V4L2_STD_NTSC) { |
| 223 | /* NTSC */ | 223 | /* Certain Hauppauge PVR150 models have a hardware bug |
| 224 | if (state->pvr150_workaround) { | 224 | that causes audio to drop out. For these models the |
| 225 | /* Certain Hauppauge PVR150 models have a hardware bug | 225 | audio standard must be set explicitly. |
| 226 | that causes audio to drop out. For these models the | 226 | To be precise: it affects cards with tuner models |
| 227 | audio standard must be set explicitly. | 227 | 85, 99 and 112 (model numbers from tveeprom). */ |
| 228 | To be precise: it affects cards with tuner models | 228 | int hw_fix = state->pvr150_workaround; |
| 229 | 85, 99 and 112 (model numbers from tveeprom). */ | 229 | |
| 230 | if (std == V4L2_STD_NTSC_M_JP) { | 230 | if (std == V4L2_STD_NTSC_M_JP) { |
| 231 | /* Japan uses EIAJ audio standard */ | ||
| 232 | cx25840_write(client, 0x808, 0x2f); | ||
| 233 | } else { | ||
| 234 | /* Others use the BTSC audio standard */ | ||
| 235 | cx25840_write(client, 0x808, 0x1f); | ||
| 236 | } | ||
| 237 | /* South Korea uses the A2-M (aka Zweiton M) audio | ||
| 238 | standard, and should set 0x808 to 0x3f, but I don't | ||
| 239 | know how to detect this. */ | ||
| 240 | } else if (std == V4L2_STD_NTSC_M_JP) { | ||
| 241 | /* Japan uses EIAJ audio standard */ | 231 | /* Japan uses EIAJ audio standard */ |
| 242 | cx25840_write(client, 0x808, 0xf7); | 232 | cx25840_write(client, 0x808, hw_fix ? 0x2f : 0xf7); |
| 233 | } else if (std == V4L2_STD_NTSC_M_KR) { | ||
| 234 | /* South Korea uses A2 audio standard */ | ||
| 235 | cx25840_write(client, 0x808, hw_fix ? 0x3f : 0xf8); | ||
| 243 | } else { | 236 | } else { |
| 244 | /* Others use the BTSC audio standard */ | 237 | /* Others use the BTSC audio standard */ |
| 245 | cx25840_write(client, 0x808, 0xf6); | 238 | cx25840_write(client, 0x808, hw_fix ? 0x1f : 0xf6); |
| 246 | } | 239 | } |
| 247 | /* South Korea uses the A2-M (aka Zweiton M) audio standard, | ||
| 248 | and should set 0x808 to 0xf8, but I don't know how to | ||
| 249 | detect this. */ | ||
| 250 | cx25840_write(client, 0x80b, 0x00); | 240 | cx25840_write(client, 0x80b, 0x00); |
| 251 | } | 241 | } |
| 252 | 242 | ||
| @@ -330,17 +320,17 @@ static int set_v4lstd(struct i2c_client *client, v4l2_std_id std) | |||
| 330 | u8 fmt=0; /* zero is autodetect */ | 320 | u8 fmt=0; /* zero is autodetect */ |
| 331 | 321 | ||
| 332 | /* First tests should be against specific std */ | 322 | /* First tests should be against specific std */ |
| 333 | if (std & V4L2_STD_NTSC_M_JP) { | 323 | if (std == V4L2_STD_NTSC_M_JP) { |
| 334 | fmt=0x2; | 324 | fmt=0x2; |
| 335 | } else if (std & V4L2_STD_NTSC_443) { | 325 | } else if (std == V4L2_STD_NTSC_443) { |
| 336 | fmt=0x3; | 326 | fmt=0x3; |
| 337 | } else if (std & V4L2_STD_PAL_M) { | 327 | } else if (std == V4L2_STD_PAL_M) { |
| 338 | fmt=0x5; | 328 | fmt=0x5; |
| 339 | } else if (std & V4L2_STD_PAL_N) { | 329 | } else if (std == V4L2_STD_PAL_N) { |
| 340 | fmt=0x6; | 330 | fmt=0x6; |
| 341 | } else if (std & V4L2_STD_PAL_Nc) { | 331 | } else if (std == V4L2_STD_PAL_Nc) { |
| 342 | fmt=0x7; | 332 | fmt=0x7; |
| 343 | } else if (std & V4L2_STD_PAL_60) { | 333 | } else if (std == V4L2_STD_PAL_60) { |
| 344 | fmt=0x8; | 334 | fmt=0x8; |
| 345 | } else { | 335 | } else { |
| 346 | /* Then, test against generic ones */ | 336 | /* Then, test against generic ones */ |
| @@ -369,7 +359,7 @@ v4l2_std_id cx25840_get_v4lstd(struct i2c_client * client) | |||
| 369 | } | 359 | } |
| 370 | 360 | ||
| 371 | switch (fmt) { | 361 | switch (fmt) { |
| 372 | case 0x1: return V4L2_STD_NTSC_M; | 362 | case 0x1: return V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR; |
| 373 | case 0x2: return V4L2_STD_NTSC_M_JP; | 363 | case 0x2: return V4L2_STD_NTSC_M_JP; |
| 374 | case 0x3: return V4L2_STD_NTSC_443; | 364 | case 0x3: return V4L2_STD_NTSC_443; |
| 375 | case 0x4: return V4L2_STD_PAL; | 365 | case 0x4: return V4L2_STD_PAL; |
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig index 53308911ae6e..e99dfbbf3e95 100644 --- a/drivers/media/video/cx88/Kconfig +++ b/drivers/media/video/cx88/Kconfig | |||
| @@ -32,6 +32,7 @@ config VIDEO_CX88_DVB | |||
| 32 | config VIDEO_CX88_ALSA | 32 | config VIDEO_CX88_ALSA |
| 33 | tristate "ALSA DMA audio support" | 33 | tristate "ALSA DMA audio support" |
| 34 | depends on VIDEO_CX88 && SND && EXPERIMENTAL | 34 | depends on VIDEO_CX88 && SND && EXPERIMENTAL |
| 35 | select SND_PCM | ||
| 35 | ---help--- | 36 | ---help--- |
| 36 | This is a video4linux driver for direct (DMA) audio on | 37 | This is a video4linux driver for direct (DMA) audio on |
| 37 | Conexant 2388x based TV cards. | 38 | Conexant 2388x based TV cards. |
| @@ -48,6 +49,7 @@ config VIDEO_CX88_DVB_ALL_FRONTENDS | |||
| 48 | default y | 49 | default y |
| 49 | depends on VIDEO_CX88_DVB | 50 | depends on VIDEO_CX88_DVB |
| 50 | select DVB_MT352 | 51 | select DVB_MT352 |
| 52 | select VIDEO_CX88_VP3054 | ||
| 51 | select DVB_OR51132 | 53 | select DVB_OR51132 |
| 52 | select DVB_CX22702 | 54 | select DVB_CX22702 |
| 53 | select DVB_LGDT330X | 55 | select DVB_LGDT330X |
| @@ -69,6 +71,16 @@ config VIDEO_CX88_DVB_MT352 | |||
| 69 | This adds DVB-T support for cards based on the | 71 | This adds DVB-T support for cards based on the |
| 70 | Connexant 2388x chip and the MT352 demodulator. | 72 | Connexant 2388x chip and the MT352 demodulator. |
| 71 | 73 | ||
| 74 | config VIDEO_CX88_VP3054 | ||
| 75 | tristate "VP-3054 Secondary I2C Bus Support" | ||
| 76 | default m | ||
| 77 | depends on DVB_MT352 | ||
| 78 | ---help--- | ||
| 79 | This adds DVB-T support for cards based on the | ||
| 80 | Connexant 2388x chip and the MT352 demodulator, | ||
| 81 | which also require support for the VP-3054 | ||
| 82 | Secondary I2C bus, such at DNTV Live! DVB-T Pro. | ||
| 83 | |||
| 72 | config VIDEO_CX88_DVB_OR51132 | 84 | config VIDEO_CX88_DVB_OR51132 |
| 73 | bool "OR51132 ATSC Support" | 85 | bool "OR51132 ATSC Support" |
| 74 | default y | 86 | default y |
diff --git a/drivers/media/video/cx88/Makefile b/drivers/media/video/cx88/Makefile index 6e5eaa22619e..2b902784facc 100644 --- a/drivers/media/video/cx88/Makefile +++ b/drivers/media/video/cx88/Makefile | |||
| @@ -4,8 +4,9 @@ cx8800-objs := cx88-video.o cx88-vbi.o | |||
| 4 | cx8802-objs := cx88-mpeg.o | 4 | cx8802-objs := cx88-mpeg.o |
| 5 | 5 | ||
| 6 | obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o cx8802.o cx88-blackbird.o | 6 | obj-$(CONFIG_VIDEO_CX88) += cx88xx.o cx8800.o cx8802.o cx88-blackbird.o |
| 7 | obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o cx88-vp3054-i2c.o | 7 | obj-$(CONFIG_VIDEO_CX88_DVB) += cx88-dvb.o |
| 8 | obj-$(CONFIG_VIDEO_CX88_ALSA) += cx88-alsa.o | 8 | obj-$(CONFIG_VIDEO_CX88_ALSA) += cx88-alsa.o |
| 9 | obj-$(CONFIG_VIDEO_CX88_VP3054) += cx88-vp3054-i2c.o | ||
| 9 | 10 | ||
| 10 | EXTRA_CFLAGS += -I$(src)/.. | 11 | EXTRA_CFLAGS += -I$(src)/.. |
| 11 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core | 12 | EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core |
| @@ -18,6 +19,6 @@ extra-cflags-$(CONFIG_DVB_LGDT330X) += -DHAVE_LGDT330X=1 | |||
| 18 | extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1 | 19 | extra-cflags-$(CONFIG_DVB_MT352) += -DHAVE_MT352=1 |
| 19 | extra-cflags-$(CONFIG_DVB_NXT200X) += -DHAVE_NXT200X=1 | 20 | extra-cflags-$(CONFIG_DVB_NXT200X) += -DHAVE_NXT200X=1 |
| 20 | extra-cflags-$(CONFIG_DVB_CX24123) += -DHAVE_CX24123=1 | 21 | extra-cflags-$(CONFIG_DVB_CX24123) += -DHAVE_CX24123=1 |
| 21 | extra-cflags-$(CONFIG_VIDEO_CX88_DVB)+= -DHAVE_VP3054_I2C=1 | 22 | extra-cflags-$(CONFIG_VIDEO_CX88_VP3054)+= -DHAVE_VP3054_I2C=1 |
| 22 | 23 | ||
| 23 | EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) | 24 | EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) |
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c index a2e36a1e5f59..2acccd6d49bc 100644 --- a/drivers/media/video/cx88/cx88-alsa.c +++ b/drivers/media/video/cx88/cx88-alsa.c | |||
| @@ -128,7 +128,7 @@ MODULE_PARM_DESC(debug,"enable debug messages"); | |||
| 128 | * BOARD Specific: Sets audio DMA | 128 | * BOARD Specific: Sets audio DMA |
| 129 | */ | 129 | */ |
| 130 | 130 | ||
| 131 | int _cx88_start_audio_dma(snd_cx88_card_t *chip) | 131 | static int _cx88_start_audio_dma(snd_cx88_card_t *chip) |
| 132 | { | 132 | { |
| 133 | struct cx88_buffer *buf = chip->buf; | 133 | struct cx88_buffer *buf = chip->buf; |
| 134 | struct cx88_core *core=chip->core; | 134 | struct cx88_core *core=chip->core; |
| @@ -173,7 +173,7 @@ int _cx88_start_audio_dma(snd_cx88_card_t *chip) | |||
| 173 | /* | 173 | /* |
| 174 | * BOARD Specific: Resets audio DMA | 174 | * BOARD Specific: Resets audio DMA |
| 175 | */ | 175 | */ |
| 176 | int _cx88_stop_audio_dma(snd_cx88_card_t *chip) | 176 | static int _cx88_stop_audio_dma(snd_cx88_card_t *chip) |
| 177 | { | 177 | { |
| 178 | struct cx88_core *core=chip->core; | 178 | struct cx88_core *core=chip->core; |
| 179 | dprintk(1, "Stopping audio DMA\n"); | 179 | dprintk(1, "Stopping audio DMA\n"); |
| @@ -613,7 +613,7 @@ static snd_kcontrol_new_t snd_cx88_capture_volume = { | |||
| 613 | * Only boards with eeprom and byte 1 at eeprom=1 have it | 613 | * Only boards with eeprom and byte 1 at eeprom=1 have it |
| 614 | */ | 614 | */ |
| 615 | 615 | ||
| 616 | struct pci_device_id cx88_audio_pci_tbl[] = { | 616 | static struct pci_device_id cx88_audio_pci_tbl[] = { |
| 617 | {0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, | 617 | {0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, |
| 618 | {0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, | 618 | {0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0}, |
| 619 | {0, } | 619 | {0, } |
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index ad2f565f522c..1bc999247fdc 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c | |||
| @@ -1246,6 +1246,11 @@ struct cx88_subid cx88_subids[] = { | |||
| 1246 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL, | 1246 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL, |
| 1247 | },{ | 1247 | },{ |
| 1248 | .subvendor = 0x18ac, | 1248 | .subvendor = 0x18ac, |
| 1249 | .subdevice = 0xdb54, | ||
| 1250 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL, | ||
| 1251 | /* Re-branded DViCO: DigitalNow DVB-T Dual */ | ||
| 1252 | },{ | ||
| 1253 | .subvendor = 0x18ac, | ||
| 1249 | .subdevice = 0xdb11, | 1254 | .subdevice = 0xdb11, |
| 1250 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS, | 1255 | .card = CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS, |
| 1251 | /* Re-branded DViCO: UltraView DVB-T Plus */ | 1256 | /* Re-branded DViCO: UltraView DVB-T Plus */ |
| @@ -1293,6 +1298,7 @@ static void hauppauge_eeprom(struct cx88_core *core, u8 *eeprom_data) | |||
| 1293 | switch (tv.model) | 1298 | switch (tv.model) |
| 1294 | { | 1299 | { |
| 1295 | case 28552: /* WinTV-PVR 'Roslyn' (No IR) */ | 1300 | case 28552: /* WinTV-PVR 'Roslyn' (No IR) */ |
| 1301 | case 34519: /* WinTV-PCI-FM */ | ||
| 1296 | case 90002: /* Nova-T-PCI (9002) */ | 1302 | case 90002: /* Nova-T-PCI (9002) */ |
| 1297 | case 92001: /* Nova-S-Plus (Video and IR) */ | 1303 | case 92001: /* Nova-S-Plus (Video and IR) */ |
| 1298 | case 92002: /* Nova-S-Plus (Video and IR) */ | 1304 | case 92002: /* Nova-S-Plus (Video and IR) */ |
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c index 8d6d6a6cf785..3720f24a25cf 100644 --- a/drivers/media/video/cx88/cx88-core.c +++ b/drivers/media/video/cx88/cx88-core.c | |||
| @@ -787,12 +787,14 @@ static int set_pll(struct cx88_core *core, int prescale, u32 ofreq) | |||
| 787 | 787 | ||
| 788 | int cx88_start_audio_dma(struct cx88_core *core) | 788 | int cx88_start_audio_dma(struct cx88_core *core) |
| 789 | { | 789 | { |
| 790 | /* constant 128 made buzz in analog Nicam-stereo for bigger fifo_size */ | ||
| 791 | int bpl = cx88_sram_channels[SRAM_CH25].fifo_size/4; | ||
| 790 | /* setup fifo + format */ | 792 | /* setup fifo + format */ |
| 791 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], 128, 0); | 793 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH25], bpl, 0); |
| 792 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], 128, 0); | 794 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH26], bpl, 0); |
| 793 | 795 | ||
| 794 | cx_write(MO_AUDD_LNGTH, 128); /* fifo bpl size */ | 796 | cx_write(MO_AUDD_LNGTH, bpl); /* fifo bpl size */ |
| 795 | cx_write(MO_AUDR_LNGTH, 128); /* fifo bpl size */ | 797 | cx_write(MO_AUDR_LNGTH, bpl); /* fifo bpl size */ |
| 796 | 798 | ||
| 797 | /* start dma */ | 799 | /* start dma */ |
| 798 | cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */ | 800 | cx_write(MO_AUD_DMACNTRL, 0x0003); /* Up and Down fifo enable */ |
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index da2ad5c4b553..165d948624a3 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c | |||
| @@ -482,6 +482,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
| 482 | switch (core->board) { | 482 | switch (core->board) { |
| 483 | case CX88_BOARD_DNTV_LIVE_DVB_T: | 483 | case CX88_BOARD_DNTV_LIVE_DVB_T: |
| 484 | case CX88_BOARD_KWORLD_DVB_T: | 484 | case CX88_BOARD_KWORLD_DVB_T: |
| 485 | case CX88_BOARD_KWORLD_DVB_T_CX22702: | ||
| 485 | ir_codes = ir_codes_dntv_live_dvb_t; | 486 | ir_codes = ir_codes_dntv_live_dvb_t; |
| 486 | ir->gpio_addr = MO_GP1_IO; | 487 | ir->gpio_addr = MO_GP1_IO; |
| 487 | ir->mask_keycode = 0x1f; | 488 | ir->mask_keycode = 0x1f; |
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index dff3893f32fd..e5ee8bceb210 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
| @@ -139,6 +139,9 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, | |||
| 139 | { | 139 | { |
| 140 | int ret, byte; | 140 | int ret, byte; |
| 141 | 141 | ||
| 142 | if (dev->state & DEV_DISCONNECTED) | ||
| 143 | return(-ENODEV); | ||
| 144 | |||
| 142 | em28xx_regdbg("req=%02x, reg=%02x ", req, reg); | 145 | em28xx_regdbg("req=%02x, reg=%02x ", req, reg); |
| 143 | 146 | ||
| 144 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, | 147 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, |
| @@ -165,6 +168,9 @@ int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg) | |||
| 165 | u8 val; | 168 | u8 val; |
| 166 | int ret; | 169 | int ret; |
| 167 | 170 | ||
| 171 | if (dev->state & DEV_DISCONNECTED) | ||
| 172 | return(-ENODEV); | ||
| 173 | |||
| 168 | em28xx_regdbg("req=%02x, reg=%02x:", req, reg); | 174 | em28xx_regdbg("req=%02x, reg=%02x:", req, reg); |
| 169 | 175 | ||
| 170 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, | 176 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, |
| @@ -195,7 +201,12 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | |||
| 195 | int ret; | 201 | int ret; |
| 196 | 202 | ||
| 197 | /*usb_control_msg seems to expect a kmalloced buffer */ | 203 | /*usb_control_msg seems to expect a kmalloced buffer */ |
| 198 | unsigned char *bufs = kmalloc(len, GFP_KERNEL); | 204 | unsigned char *bufs; |
| 205 | |||
| 206 | if (dev->state & DEV_DISCONNECTED) | ||
| 207 | return(-ENODEV); | ||
| 208 | |||
| 209 | bufs = kmalloc(len, GFP_KERNEL); | ||
| 199 | 210 | ||
| 200 | em28xx_regdbg("req=%02x reg=%02x:", req, reg); | 211 | em28xx_regdbg("req=%02x reg=%02x:", req, reg); |
| 201 | 212 | ||
| @@ -212,7 +223,7 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | |||
| 212 | ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req, | 223 | ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req, |
| 213 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 224 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
| 214 | 0x0000, reg, bufs, len, HZ); | 225 | 0x0000, reg, bufs, len, HZ); |
| 215 | mdelay(5); /* FIXME: magic number */ | 226 | msleep(5); /* FIXME: magic number */ |
| 216 | kfree(bufs); | 227 | kfree(bufs); |
| 217 | return ret; | 228 | return ret; |
| 218 | } | 229 | } |
| @@ -253,7 +264,7 @@ int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 * val) | |||
| 253 | if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0) | 264 | if ((ret = em28xx_read_reg(dev, AC97BUSY_REG)) < 0) |
| 254 | return ret; | 265 | return ret; |
| 255 | else if (((u8) ret) & 0x01) { | 266 | else if (((u8) ret) & 0x01) { |
| 256 | em28xx_warn ("AC97 command still being exectuted: not handled properly!\n"); | 267 | em28xx_warn ("AC97 command still being executed: not handled properly!\n"); |
| 257 | } | 268 | } |
| 258 | return 0; | 269 | return 0; |
| 259 | } | 270 | } |
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c index 0591a705b7a1..6ca8631bc36d 100644 --- a/drivers/media/video/em28xx/em28xx-i2c.c +++ b/drivers/media/video/em28xx/em28xx-i2c.c | |||
| @@ -78,7 +78,7 @@ static int em2800_i2c_send_max4(struct em28xx *dev, unsigned char addr, | |||
| 78 | ret = dev->em28xx_read_reg(dev, 0x05); | 78 | ret = dev->em28xx_read_reg(dev, 0x05); |
| 79 | if (ret == 0x80 + len - 1) | 79 | if (ret == 0x80 + len - 1) |
| 80 | return len; | 80 | return len; |
| 81 | mdelay(5); | 81 | msleep(5); |
| 82 | } | 82 | } |
| 83 | em28xx_warn("i2c write timed out\n"); | 83 | em28xx_warn("i2c write timed out\n"); |
| 84 | return -EIO; | 84 | return -EIO; |
| @@ -138,7 +138,7 @@ static int em2800_i2c_check_for_device(struct em28xx *dev, unsigned char addr) | |||
| 138 | return -ENODEV; | 138 | return -ENODEV; |
| 139 | else if (msg == 0x84) | 139 | else if (msg == 0x84) |
| 140 | return 0; | 140 | return 0; |
| 141 | mdelay(5); | 141 | msleep(5); |
| 142 | } | 142 | } |
| 143 | return -ENODEV; | 143 | return -ENODEV; |
| 144 | } | 144 | } |
| @@ -278,9 +278,9 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
| 278 | msgs[i].buf, | 278 | msgs[i].buf, |
| 279 | msgs[i].len, | 279 | msgs[i].len, |
| 280 | i == num - 1); | 280 | i == num - 1); |
| 281 | if (rc < 0) | ||
| 282 | goto err; | ||
| 283 | } | 281 | } |
| 282 | if (rc < 0) | ||
| 283 | goto err; | ||
| 284 | if (i2c_debug>=2) | 284 | if (i2c_debug>=2) |
| 285 | printk("\n"); | 285 | printk("\n"); |
| 286 | } | 286 | } |
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index eea304f75176..94a14a2bb6d6 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
| @@ -6,6 +6,9 @@ | |||
| 6 | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | 6 | Mauro Carvalho Chehab <mchehab@brturbo.com.br> |
| 7 | Sascha Sommer <saschasommer@freenet.de> | 7 | Sascha Sommer <saschasommer@freenet.de> |
| 8 | 8 | ||
| 9 | Some parts based on SN9C10x PC Camera Controllers GPL driver made | ||
| 10 | by Luca Risolia <luca.risolia@studio.unibo.it> | ||
| 11 | |||
| 9 | This program is free software; you can redistribute it and/or modify | 12 | This program is free software; you can redistribute it and/or modify |
| 10 | it under the terms of the GNU General Public License as published by | 13 | it under the terms of the GNU General Public License as published by |
| 11 | the Free Software Foundation; either version 2 of the License, or | 14 | the Free Software Foundation; either version 2 of the License, or |
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index c64718aec9cb..5a35d3b6550d 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c | |||
| @@ -136,7 +136,7 @@ struct saa7134_board saa7134_boards[] = { | |||
| 136 | }, | 136 | }, |
| 137 | [SAA7134_BOARD_FLYVIDEO2000] = { | 137 | [SAA7134_BOARD_FLYVIDEO2000] = { |
| 138 | /* "TC Wan" <tcwan@cs.usm.my> */ | 138 | /* "TC Wan" <tcwan@cs.usm.my> */ |
| 139 | .name = "LifeView FlyVIDEO2000", | 139 | .name = "LifeView/Typhoon FlyVIDEO2000", |
| 140 | .audio_clock = 0x00200000, | 140 | .audio_clock = 0x00200000, |
| 141 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | 141 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, |
| 142 | .radio_type = UNSET, | 142 | .radio_type = UNSET, |
| @@ -1884,44 +1884,38 @@ struct saa7134_board saa7134_boards[] = { | |||
| 1884 | .gpio = 0x000, | 1884 | .gpio = 0x000, |
| 1885 | }, | 1885 | }, |
| 1886 | }, | 1886 | }, |
| 1887 | [SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS] = { | 1887 | [SAA7134_BOARD_FLYDVBT_DUO_CARDBUS] = { |
| 1888 | .name = "Typhoon DVB-T Duo Digital/Analog Cardbus", | 1888 | .name = "LifeView/Typhoon FlyDVB-T Duo Cardbus", |
| 1889 | .audio_clock = 0x00200000, | 1889 | .audio_clock = 0x00200000, |
| 1890 | .tuner_type = TUNER_PHILIPS_TDA8290, | 1890 | .tuner_type = TUNER_PHILIPS_TDA8290, |
| 1891 | .radio_type = UNSET, | 1891 | .radio_type = UNSET, |
| 1892 | .tuner_addr = ADDR_UNSET, | 1892 | .tuner_addr = ADDR_UNSET, |
| 1893 | .radio_addr = ADDR_UNSET, | 1893 | .radio_addr = ADDR_UNSET, |
| 1894 | .mpeg = SAA7134_MPEG_DVB, | 1894 | .mpeg = SAA7134_MPEG_DVB, |
| 1895 | /* .gpiomask = 0xe000, */ | 1895 | .gpiomask = 0x00200000, |
| 1896 | .inputs = {{ | 1896 | .inputs = {{ |
| 1897 | .name = name_tv, | 1897 | .name = name_tv, |
| 1898 | .vmux = 1, | 1898 | .vmux = 1, |
| 1899 | .amux = TV, | 1899 | .amux = TV, |
| 1900 | /* .gpio = 0x0000, */ | 1900 | .gpio = 0x200000, /* GPIO21=High for TV input */ |
| 1901 | .tv = 1, | 1901 | .tv = 1, |
| 1902 | },{ | 1902 | },{ |
| 1903 | .name = name_svideo, /* S-Video signal on S-Video input */ | ||
| 1904 | .vmux = 8, | ||
| 1905 | .amux = LINE2, | ||
| 1906 | },{ | ||
| 1903 | .name = name_comp1, /* Composite signal on S-Video input */ | 1907 | .name = name_comp1, /* Composite signal on S-Video input */ |
| 1904 | .vmux = 0, | 1908 | .vmux = 0, |
| 1905 | .amux = LINE2, | 1909 | .amux = LINE2, |
| 1906 | /* .gpio = 0x4000, */ | ||
| 1907 | },{ | 1910 | },{ |
| 1908 | .name = name_comp2, /* Composite input */ | 1911 | .name = name_comp2, /* Composite input */ |
| 1909 | .vmux = 3, | 1912 | .vmux = 3, |
| 1910 | .amux = LINE2, | 1913 | .amux = LINE2, |
| 1911 | /* .gpio = 0x4000, */ | ||
| 1912 | },{ | ||
| 1913 | .name = name_svideo, /* S-Video signal on S-Video input */ | ||
| 1914 | .vmux = 8, | ||
| 1915 | .amux = LINE2, | ||
| 1916 | /* .gpio = 0x4000, */ | ||
| 1917 | }}, | 1914 | }}, |
| 1918 | .radio = { | 1915 | .radio = { |
| 1919 | .name = name_radio, | 1916 | .name = name_radio, |
| 1920 | .amux = LINE2, | 1917 | .amux = TV, |
| 1921 | }, | 1918 | .gpio = 0x000000, /* GPIO21=Low for FM radio antenna */ |
| 1922 | .mute = { | ||
| 1923 | .name = name_mute, | ||
| 1924 | .amux = LINE1, | ||
| 1925 | }, | 1919 | }, |
| 1926 | }, | 1920 | }, |
| 1927 | [SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII] = { | 1921 | [SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII] = { |
| @@ -2701,6 +2695,12 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
| 2701 | .driver_data = SAA7134_BOARD_FLYVIDEO2000, | 2695 | .driver_data = SAA7134_BOARD_FLYVIDEO2000, |
| 2702 | },{ | 2696 | },{ |
| 2703 | .vendor = PCI_VENDOR_ID_PHILIPS, | 2697 | .vendor = PCI_VENDOR_ID_PHILIPS, |
| 2698 | .device = PCI_DEVICE_ID_PHILIPS_SAA7130, | ||
| 2699 | .subvendor = 0x4e42, /* Typhoon */ | ||
| 2700 | .subdevice = 0x0138, /* LifeView FlyTV Prime30 OEM */ | ||
| 2701 | .driver_data = SAA7134_BOARD_FLYVIDEO2000, | ||
| 2702 | },{ | ||
| 2703 | .vendor = PCI_VENDOR_ID_PHILIPS, | ||
| 2704 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 2704 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
| 2705 | .subvendor = 0x5168, | 2705 | .subvendor = 0x5168, |
| 2706 | .subdevice = 0x0212, /* minipci, LR212 */ | 2706 | .subdevice = 0x0212, /* minipci, LR212 */ |
| @@ -2935,7 +2935,7 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
| 2935 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 2935 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
| 2936 | .subvendor = 0x5168, | 2936 | .subvendor = 0x5168, |
| 2937 | .subdevice = 0x0502, /* Cardbus version */ | 2937 | .subdevice = 0x0502, /* Cardbus version */ |
| 2938 | .driver_data = SAA7134_BOARD_FLYDVBTDUO, | 2938 | .driver_data = SAA7134_BOARD_FLYDVBT_DUO_CARDBUS, |
| 2939 | },{ | 2939 | },{ |
| 2940 | .vendor = PCI_VENDOR_ID_PHILIPS, | 2940 | .vendor = PCI_VENDOR_ID_PHILIPS, |
| 2941 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 2941 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
| @@ -2980,12 +2980,12 @@ struct pci_device_id saa7134_pci_tbl[] = { | |||
| 2980 | .subdevice = 0x1370, /* cardbus version */ | 2980 | .subdevice = 0x1370, /* cardbus version */ |
| 2981 | .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, | 2981 | .driver_data = SAA7134_BOARD_ADS_INSTANT_TV, |
| 2982 | 2982 | ||
| 2983 | },{ /* Typhoon DVB-T Duo Digital/Analog Cardbus */ | 2983 | },{ |
| 2984 | .vendor = PCI_VENDOR_ID_PHILIPS, | 2984 | .vendor = PCI_VENDOR_ID_PHILIPS, |
| 2985 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 2985 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
| 2986 | .subvendor = 0x4e42, | 2986 | .subvendor = 0x4e42, /* Typhoon */ |
| 2987 | .subdevice = 0x0502, | 2987 | .subdevice = 0x0502, /* LifeView LR502 OEM */ |
| 2988 | .driver_data = SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS, | 2988 | .driver_data = SAA7134_BOARD_FLYDVBT_DUO_CARDBUS, |
| 2989 | },{ | 2989 | },{ |
| 2990 | .vendor = PCI_VENDOR_ID_PHILIPS, | 2990 | .vendor = PCI_VENDOR_ID_PHILIPS, |
| 2991 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, | 2991 | .device = PCI_DEVICE_ID_PHILIPS_SAA7133, |
| @@ -3206,8 +3206,7 @@ int saa7134_board_init1(struct saa7134_dev *dev) | |||
| 3206 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000); | 3206 | saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00040000, 0x00040000); |
| 3207 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000004); | 3207 | saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00040000, 0x00000004); |
| 3208 | break; | 3208 | break; |
| 3209 | case SAA7134_BOARD_FLYDVBTDUO: | 3209 | case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS: |
| 3210 | case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS: | ||
| 3211 | /* turn the fan on */ | 3210 | /* turn the fan on */ |
| 3212 | saa_writeb(SAA7134_GPIO_GPMODE3, 0x08); | 3211 | saa_writeb(SAA7134_GPIO_GPMODE3, 0x08); |
| 3213 | saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06); | 3212 | saa_writeb(SAA7134_GPIO_GPSTATUS3, 0x06); |
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c index 399f9952596c..1a536e865277 100644 --- a/drivers/media/video/saa7134/saa7134-dvb.c +++ b/drivers/media/video/saa7134/saa7134-dvb.c | |||
| @@ -861,7 +861,7 @@ static int dvb_init(struct saa7134_dev *dev) | |||
| 861 | dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, | 861 | dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, |
| 862 | &dev->i2c_adap); | 862 | &dev->i2c_adap); |
| 863 | break; | 863 | break; |
| 864 | case SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS: | 864 | case SAA7134_BOARD_FLYDVBT_DUO_CARDBUS: |
| 865 | dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, | 865 | dev->dvb.frontend = tda10046_attach(&tda827x_lifeview_config, |
| 866 | &dev->i2c_adap); | 866 | &dev->i2c_adap); |
| 867 | break; | 867 | break; |
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h index e70eae8d29bb..3261d8bebdd1 100644 --- a/drivers/media/video/saa7134/saa7134.h +++ b/drivers/media/video/saa7134/saa7134.h | |||
| @@ -185,7 +185,7 @@ struct saa7134_format { | |||
| 185 | #define SAA7134_BOARD_AVERMEDIA_GO_007_FM 57 | 185 | #define SAA7134_BOARD_AVERMEDIA_GO_007_FM 57 |
| 186 | #define SAA7134_BOARD_ADS_INSTANT_TV 58 | 186 | #define SAA7134_BOARD_ADS_INSTANT_TV 58 |
| 187 | #define SAA7134_BOARD_KWORLD_VSTREAM_XPERT 59 | 187 | #define SAA7134_BOARD_KWORLD_VSTREAM_XPERT 59 |
| 188 | #define SAA7134_BOARD_THYPHOON_DVBT_DUO_CARDBUS 60 | 188 | #define SAA7134_BOARD_FLYDVBT_DUO_CARDBUS 60 |
| 189 | #define SAA7134_BOARD_PHILIPS_TOUGH 61 | 189 | #define SAA7134_BOARD_PHILIPS_TOUGH 61 |
| 190 | #define SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII 62 | 190 | #define SAA7134_BOARD_VIDEOMATE_TV_GOLD_PLUSII 62 |
| 191 | #define SAA7134_BOARD_KWORLD_XPERT 63 | 191 | #define SAA7134_BOARD_KWORLD_XPERT 63 |
diff --git a/drivers/media/video/stradis.c b/drivers/media/video/stradis.c index 54fc33011ffb..9d769264a329 100644 --- a/drivers/media/video/stradis.c +++ b/drivers/media/video/stradis.c | |||
| @@ -2012,7 +2012,6 @@ static int __devinit init_saa7146(struct pci_dev *pdev) | |||
| 2012 | { | 2012 | { |
| 2013 | struct saa7146 *saa = pci_get_drvdata(pdev); | 2013 | struct saa7146 *saa = pci_get_drvdata(pdev); |
| 2014 | 2014 | ||
| 2015 | memset(saa, 0, sizeof(*saa)); | ||
| 2016 | saa->user = 0; | 2015 | saa->user = 0; |
| 2017 | /* reset the saa7146 */ | 2016 | /* reset the saa7146 */ |
| 2018 | saawrite(0xffff0000, SAA7146_MC1); | 2017 | saawrite(0xffff0000, SAA7146_MC1); |
| @@ -2062,16 +2061,16 @@ static int __devinit init_saa7146(struct pci_dev *pdev) | |||
| 2062 | } | 2061 | } |
| 2063 | if (saa->audbuf == NULL && (saa->audbuf = vmalloc(65536)) == NULL) { | 2062 | if (saa->audbuf == NULL && (saa->audbuf = vmalloc(65536)) == NULL) { |
| 2064 | dev_err(&pdev->dev, "%d: malloc failed\n", saa->nr); | 2063 | dev_err(&pdev->dev, "%d: malloc failed\n", saa->nr); |
| 2065 | goto errvid; | 2064 | goto errfree; |
| 2066 | } | 2065 | } |
| 2067 | if (saa->osdbuf == NULL && (saa->osdbuf = vmalloc(131072)) == NULL) { | 2066 | if (saa->osdbuf == NULL && (saa->osdbuf = vmalloc(131072)) == NULL) { |
| 2068 | dev_err(&pdev->dev, "%d: malloc failed\n", saa->nr); | 2067 | dev_err(&pdev->dev, "%d: malloc failed\n", saa->nr); |
| 2069 | goto erraud; | 2068 | goto errfree; |
| 2070 | } | 2069 | } |
| 2071 | /* allocate 81920 byte buffer for clipping */ | 2070 | /* allocate 81920 byte buffer for clipping */ |
| 2072 | if ((saa->dmavid2 = kzalloc(VIDEO_CLIPMAP_SIZE, GFP_KERNEL)) == NULL) { | 2071 | if ((saa->dmavid2 = kzalloc(VIDEO_CLIPMAP_SIZE, GFP_KERNEL)) == NULL) { |
| 2073 | dev_err(&pdev->dev, "%d: clip kmalloc failed\n", saa->nr); | 2072 | dev_err(&pdev->dev, "%d: clip kmalloc failed\n", saa->nr); |
| 2074 | goto errosd; | 2073 | goto errfree; |
| 2075 | } | 2074 | } |
| 2076 | /* setup clipping registers */ | 2075 | /* setup clipping registers */ |
| 2077 | saawrite(virt_to_bus(saa->dmavid2), SAA7146_BASE_EVEN2); | 2076 | saawrite(virt_to_bus(saa->dmavid2), SAA7146_BASE_EVEN2); |
| @@ -2085,15 +2084,11 @@ static int __devinit init_saa7146(struct pci_dev *pdev) | |||
| 2085 | I2CBusScan(saa); | 2084 | I2CBusScan(saa); |
| 2086 | 2085 | ||
| 2087 | return 0; | 2086 | return 0; |
| 2088 | errosd: | 2087 | errfree: |
| 2089 | vfree(saa->osdbuf); | 2088 | vfree(saa->osdbuf); |
| 2090 | saa->osdbuf = NULL; | ||
| 2091 | erraud: | ||
| 2092 | vfree(saa->audbuf); | 2089 | vfree(saa->audbuf); |
| 2093 | saa->audbuf = NULL; | ||
| 2094 | errvid: | ||
| 2095 | vfree(saa->vidbuf); | 2090 | vfree(saa->vidbuf); |
| 2096 | saa->vidbuf = NULL; | 2091 | saa->audbuf = saa->osdbuf = saa->vidbuf = NULL; |
| 2097 | err: | 2092 | err: |
| 2098 | return -ENOMEM; | 2093 | return -ENOMEM; |
| 2099 | } | 2094 | } |
diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index 5815649bdc78..0d54f6c1982b 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c | |||
| @@ -231,7 +231,7 @@ static struct tvnorm tvnorms[] = { | |||
| 231 | cAudioIF_6_5 | | 231 | cAudioIF_6_5 | |
| 232 | cVideoIF_38_90 ), | 232 | cVideoIF_38_90 ), |
| 233 | },{ | 233 | },{ |
| 234 | .std = V4L2_STD_NTSC_M, | 234 | .std = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR, |
| 235 | .name = "NTSC-M", | 235 | .name = "NTSC-M", |
| 236 | .b = ( cNegativeFmTV | | 236 | .b = ( cNegativeFmTV | |
| 237 | cQSS ), | 237 | cQSS ), |
| @@ -619,6 +619,11 @@ static int tda9887_fixup_std(struct tda9887 *t) | |||
| 619 | tda9887_dbg("insmod fixup: NTSC => NTSC_M_JP\n"); | 619 | tda9887_dbg("insmod fixup: NTSC => NTSC_M_JP\n"); |
| 620 | t->std = V4L2_STD_NTSC_M_JP; | 620 | t->std = V4L2_STD_NTSC_M_JP; |
| 621 | break; | 621 | break; |
| 622 | case 'k': | ||
| 623 | case 'K': | ||
| 624 | tda9887_dbg("insmod fixup: NTSC => NTSC_M_KR\n"); | ||
| 625 | t->std = V4L2_STD_NTSC_M_KR; | ||
| 626 | break; | ||
| 622 | case '-': | 627 | case '-': |
| 623 | /* default parameter, do nothing */ | 628 | /* default parameter, do nothing */ |
| 624 | break; | 629 | break; |
| @@ -876,7 +881,7 @@ static int tda9887_resume(struct device * dev) | |||
| 876 | /* ----------------------------------------------------------------------- */ | 881 | /* ----------------------------------------------------------------------- */ |
| 877 | 882 | ||
| 878 | static struct i2c_driver driver = { | 883 | static struct i2c_driver driver = { |
| 879 | .id = -1, /* FIXME */ | 884 | .id = I2C_DRIVERID_TDA9887, |
| 880 | .attach_adapter = tda9887_probe, | 885 | .attach_adapter = tda9887_probe, |
| 881 | .detach_client = tda9887_detach, | 886 | .detach_client = tda9887_detach, |
| 882 | .command = tda9887_command, | 887 | .command = tda9887_command, |
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 2995b22acb43..e7ee619d62c5 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
| @@ -216,6 +216,7 @@ static void set_type(struct i2c_client *c, unsigned int type, | |||
| 216 | buffer[3] = 0xa4; | 216 | buffer[3] = 0xa4; |
| 217 | i2c_master_send(c,buffer,4); | 217 | i2c_master_send(c,buffer,4); |
| 218 | default_tuner_init(c); | 218 | default_tuner_init(c); |
| 219 | break; | ||
| 219 | default: | 220 | default: |
| 220 | default_tuner_init(c); | 221 | default_tuner_init(c); |
| 221 | break; | 222 | break; |
| @@ -365,6 +366,11 @@ static int tuner_fixup_std(struct tuner *t) | |||
| 365 | tuner_dbg("insmod fixup: NTSC => NTSC_M_JP\n"); | 366 | tuner_dbg("insmod fixup: NTSC => NTSC_M_JP\n"); |
| 366 | t->std = V4L2_STD_NTSC_M_JP; | 367 | t->std = V4L2_STD_NTSC_M_JP; |
| 367 | break; | 368 | break; |
| 369 | case 'k': | ||
| 370 | case 'K': | ||
| 371 | tuner_dbg("insmod fixup: NTSC => NTSC_M_KR\n"); | ||
| 372 | t->std = V4L2_STD_NTSC_M_KR; | ||
| 373 | break; | ||
| 368 | case '-': | 374 | case '-': |
| 369 | /* default parameter, do nothing */ | 375 | /* default parameter, do nothing */ |
| 370 | break; | 376 | break; |
| @@ -448,7 +454,7 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) | |||
| 448 | printk("%02x ",buffer[i]); | 454 | printk("%02x ",buffer[i]); |
| 449 | printk("\n"); | 455 | printk("\n"); |
| 450 | } | 456 | } |
| 451 | /* TEA5767 autodetection code - only for addr = 0xc0 */ | 457 | /* autodetection code based on the i2c addr */ |
| 452 | if (!no_autodetect) { | 458 | if (!no_autodetect) { |
| 453 | switch (addr) { | 459 | switch (addr) { |
| 454 | case 0x42: | 460 | case 0x42: |
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index 6d03b9b05c6e..c8e5ad0e8185 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c | |||
| @@ -390,6 +390,14 @@ static void tda9840_setmode(struct CHIPSTATE *chip, int mode) | |||
| 390 | chip_write(chip, TDA9840_SW, t); | 390 | chip_write(chip, TDA9840_SW, t); |
| 391 | } | 391 | } |
| 392 | 392 | ||
| 393 | static int tda9840_checkit(struct CHIPSTATE *chip) | ||
| 394 | { | ||
| 395 | int rc; | ||
| 396 | rc = chip_read(chip); | ||
| 397 | /* lower 5 bits should be 0 */ | ||
| 398 | return ((rc & 0x1f) == 0) ? 1 : 0; | ||
| 399 | } | ||
| 400 | |||
| 393 | /* ---------------------------------------------------------------------- */ | 401 | /* ---------------------------------------------------------------------- */ |
| 394 | /* audio chip descriptions - defines+functions for tda985x */ | 402 | /* audio chip descriptions - defines+functions for tda985x */ |
| 395 | 403 | ||
| @@ -1264,6 +1272,7 @@ static struct CHIPDESC chiplist[] = { | |||
| 1264 | .addr_hi = I2C_TDA9840 >> 1, | 1272 | .addr_hi = I2C_TDA9840 >> 1, |
| 1265 | .registers = 5, | 1273 | .registers = 5, |
| 1266 | 1274 | ||
| 1275 | .checkit = tda9840_checkit, | ||
| 1267 | .getmode = tda9840_getmode, | 1276 | .getmode = tda9840_getmode, |
| 1268 | .setmode = tda9840_setmode, | 1277 | .setmode = tda9840_setmode, |
| 1269 | .checkmode = generic_checkmode, | 1278 | .checkmode = generic_checkmode, |
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c index fad9ea0ae4f2..1864423b3046 100644 --- a/drivers/media/video/tvp5150.c +++ b/drivers/media/video/tvp5150.c | |||
| @@ -746,24 +746,27 @@ static int tvp5150_set_std(struct i2c_client *c, v4l2_std_id std) | |||
| 746 | 746 | ||
| 747 | static inline void tvp5150_reset(struct i2c_client *c) | 747 | static inline void tvp5150_reset(struct i2c_client *c) |
| 748 | { | 748 | { |
| 749 | u8 type, ver_656, msb_id, lsb_id, msb_rom, lsb_rom; | 749 | u8 msb_id, lsb_id, msb_rom, lsb_rom; |
| 750 | struct tvp5150 *decoder = i2c_get_clientdata(c); | 750 | struct tvp5150 *decoder = i2c_get_clientdata(c); |
| 751 | 751 | ||
| 752 | type=tvp5150_read(c,TVP5150_AUTOSW_MSK); | ||
| 753 | msb_id=tvp5150_read(c,TVP5150_MSB_DEV_ID); | 752 | msb_id=tvp5150_read(c,TVP5150_MSB_DEV_ID); |
| 754 | lsb_id=tvp5150_read(c,TVP5150_LSB_DEV_ID); | 753 | lsb_id=tvp5150_read(c,TVP5150_LSB_DEV_ID); |
| 755 | msb_rom=tvp5150_read(c,TVP5150_ROM_MAJOR_VER); | 754 | msb_rom=tvp5150_read(c,TVP5150_ROM_MAJOR_VER); |
| 756 | lsb_rom=tvp5150_read(c,TVP5150_ROM_MINOR_VER); | 755 | lsb_rom=tvp5150_read(c,TVP5150_ROM_MINOR_VER); |
| 757 | 756 | ||
| 758 | if (type==0xdc) { | 757 | if ((msb_rom==4)&&(lsb_rom==0)) { /* Is TVP5150AM1 */ |
| 759 | ver_656=tvp5150_read(c,TVP5150_REV_SELECT); | 758 | tvp5150_info("tvp%02x%02xam1 detected.\n",msb_id, lsb_id); |
| 760 | tvp5150_info("tvp%02x%02xam1 detected 656 version is %d.\n",msb_id, lsb_id,ver_656); | 759 | |
| 761 | } else if (type==0xfc) { | 760 | /* ITU-T BT.656.4 timing */ |
| 762 | tvp5150_info("tvp%02x%02xa detected.\n",msb_id, lsb_id); | 761 | tvp5150_write(c,TVP5150_REV_SELECT,0); |
| 763 | } else { | 762 | } else { |
| 764 | tvp5150_info("unknown tvp%02x%02x chip detected(%d).\n",msb_id,lsb_id,type); | 763 | if ((msb_rom==3)||(lsb_rom==0x21)) { /* Is TVP5150A */ |
| 764 | tvp5150_info("tvp%02x%02xa detected.\n",msb_id, lsb_id); | ||
| 765 | } else { | ||
| 766 | tvp5150_info("*** unknown tvp%02x%02x chip detected.\n",msb_id,lsb_id); | ||
| 767 | tvp5150_info("*** Rom ver is %d.%d\n",msb_rom,lsb_rom); | ||
| 768 | } | ||
| 765 | } | 769 | } |
| 766 | tvp5150_info("Rom ver is %d.%d\n",msb_rom,lsb_rom); | ||
| 767 | 770 | ||
| 768 | /* Initializes TVP5150 to its default values */ | 771 | /* Initializes TVP5150 to its default values */ |
| 769 | tvp5150_write_inittab(c, tvp5150_init_default); | 772 | tvp5150_write_inittab(c, tvp5150_init_default); |
| @@ -893,6 +896,17 @@ static int tvp5150_command(struct i2c_client *c, | |||
| 893 | } | 896 | } |
| 894 | case DECODER_GET_STATUS: | 897 | case DECODER_GET_STATUS: |
| 895 | { | 898 | { |
| 899 | int *iarg = arg; | ||
| 900 | int status; | ||
| 901 | int res=0; | ||
| 902 | status = tvp5150_read(c, 0x88); | ||
| 903 | if(status&0x08){ | ||
| 904 | res |= DECODER_STATUS_COLOR; | ||
| 905 | } | ||
| 906 | if(status&0x04 && status&0x02){ | ||
| 907 | res |= DECODER_STATUS_GOOD; | ||
| 908 | } | ||
| 909 | *iarg=res; | ||
| 896 | break; | 910 | break; |
| 897 | } | 911 | } |
| 898 | 912 | ||
diff --git a/drivers/message/i2o/core.h b/drivers/message/i2o/core.h index 90628562851e..184974cc734d 100644 --- a/drivers/message/i2o/core.h +++ b/drivers/message/i2o/core.h | |||
| @@ -60,4 +60,7 @@ extern void i2o_iop_remove(struct i2o_controller *); | |||
| 60 | #define I2O_IN_PORT 0x40 | 60 | #define I2O_IN_PORT 0x40 |
| 61 | #define I2O_OUT_PORT 0x44 | 61 | #define I2O_OUT_PORT 0x44 |
| 62 | 62 | ||
| 63 | /* Motorola/Freescale specific register offset */ | ||
| 64 | #define I2O_MOTOROLA_PORT_OFFSET 0x10400 | ||
| 65 | |||
| 63 | #define I2O_IRQ_OUTBOUND_POST 0x00000008 | 66 | #define I2O_IRQ_OUTBOUND_POST 0x00000008 |
diff --git a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c index f9e5a23697a1..c08ddac3717d 100644 --- a/drivers/message/i2o/i2o_scsi.c +++ b/drivers/message/i2o/i2o_scsi.c | |||
| @@ -732,7 +732,7 @@ static int i2o_scsi_abort(struct scsi_cmnd *SCpnt) | |||
| 732 | cpu_to_le32(I2O_CMD_SCSI_ABORT << 24 | HOST_TID << 12 | tid); | 732 | cpu_to_le32(I2O_CMD_SCSI_ABORT << 24 | HOST_TID << 12 | tid); |
| 733 | msg->body[0] = cpu_to_le32(i2o_cntxt_list_get_ptr(c, SCpnt)); | 733 | msg->body[0] = cpu_to_le32(i2o_cntxt_list_get_ptr(c, SCpnt)); |
| 734 | 734 | ||
| 735 | if (i2o_msg_post_wait(c, msg, I2O_TIMEOUT_SCSI_SCB_ABORT)) | 735 | if (!i2o_msg_post_wait(c, msg, I2O_TIMEOUT_SCSI_SCB_ABORT)) |
| 736 | status = SUCCESS; | 736 | status = SUCCESS; |
| 737 | 737 | ||
| 738 | return status; | 738 | return status; |
diff --git a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c index d698d7709c31..4f1515cae5dc 100644 --- a/drivers/message/i2o/pci.c +++ b/drivers/message/i2o/pci.c | |||
| @@ -88,6 +88,11 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c) | |||
| 88 | struct device *dev = &pdev->dev; | 88 | struct device *dev = &pdev->dev; |
| 89 | int i; | 89 | int i; |
| 90 | 90 | ||
| 91 | if (pci_request_regions(pdev, OSM_DESCRIPTION)) { | ||
| 92 | printk(KERN_ERR "%s: device already claimed\n", c->name); | ||
| 93 | return -ENODEV; | ||
| 94 | } | ||
| 95 | |||
| 91 | for (i = 0; i < 6; i++) { | 96 | for (i = 0; i < 6; i++) { |
| 92 | /* Skip I/O spaces */ | 97 | /* Skip I/O spaces */ |
| 93 | if (!(pci_resource_flags(pdev, i) & IORESOURCE_IO)) { | 98 | if (!(pci_resource_flags(pdev, i) & IORESOURCE_IO)) { |
| @@ -163,6 +168,24 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c) | |||
| 163 | c->in_port = c->base.virt + I2O_IN_PORT; | 168 | c->in_port = c->base.virt + I2O_IN_PORT; |
| 164 | c->out_port = c->base.virt + I2O_OUT_PORT; | 169 | c->out_port = c->base.virt + I2O_OUT_PORT; |
| 165 | 170 | ||
| 171 | /* Motorola/Freescale chip does not follow spec */ | ||
| 172 | if (pdev->vendor == PCI_VENDOR_ID_MOTOROLA && pdev->device == 0x18c0) { | ||
| 173 | /* Check if CPU is enabled */ | ||
| 174 | if (be32_to_cpu(readl(c->base.virt + 0x10000)) & 0x10000000) { | ||
| 175 | printk(KERN_INFO "%s: MPC82XX needs CPU running to " | ||
| 176 | "service I2O.\n", c->name); | ||
| 177 | i2o_pci_free(c); | ||
| 178 | return -ENODEV; | ||
| 179 | } else { | ||
| 180 | c->irq_status += I2O_MOTOROLA_PORT_OFFSET; | ||
| 181 | c->irq_mask += I2O_MOTOROLA_PORT_OFFSET; | ||
| 182 | c->in_port += I2O_MOTOROLA_PORT_OFFSET; | ||
| 183 | c->out_port += I2O_MOTOROLA_PORT_OFFSET; | ||
| 184 | printk(KERN_INFO "%s: MPC82XX workarounds activated.\n", | ||
| 185 | c->name); | ||
| 186 | } | ||
| 187 | } | ||
| 188 | |||
| 166 | if (i2o_dma_alloc(dev, &c->status, 8, GFP_KERNEL)) { | 189 | if (i2o_dma_alloc(dev, &c->status, 8, GFP_KERNEL)) { |
| 167 | i2o_pci_free(c); | 190 | i2o_pci_free(c); |
| 168 | return -ENOMEM; | 191 | return -ENOMEM; |
| @@ -298,7 +321,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, | |||
| 298 | struct i2o_controller *c; | 321 | struct i2o_controller *c; |
| 299 | int rc; | 322 | int rc; |
| 300 | struct pci_dev *i960 = NULL; | 323 | struct pci_dev *i960 = NULL; |
| 301 | int pci_dev_busy = 0; | 324 | int enabled = pdev->is_enabled; |
| 302 | 325 | ||
| 303 | printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n"); | 326 | printk(KERN_INFO "i2o: Checking for PCI I2O controllers...\n"); |
| 304 | 327 | ||
| @@ -308,16 +331,12 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, | |||
| 308 | return -ENODEV; | 331 | return -ENODEV; |
| 309 | } | 332 | } |
| 310 | 333 | ||
| 311 | if ((rc = pci_enable_device(pdev))) { | 334 | if (!enabled) |
| 312 | printk(KERN_WARNING "i2o: couldn't enable device %s\n", | 335 | if ((rc = pci_enable_device(pdev))) { |
| 313 | pci_name(pdev)); | 336 | printk(KERN_WARNING "i2o: couldn't enable device %s\n", |
| 314 | return rc; | 337 | pci_name(pdev)); |
| 315 | } | 338 | return rc; |
| 316 | 339 | } | |
| 317 | if (pci_request_regions(pdev, OSM_DESCRIPTION)) { | ||
| 318 | printk(KERN_ERR "i2o: device already claimed\n"); | ||
| 319 | return -ENODEV; | ||
| 320 | } | ||
| 321 | 340 | ||
| 322 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { | 341 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { |
| 323 | printk(KERN_WARNING "i2o: no suitable DMA found for %s\n", | 342 | printk(KERN_WARNING "i2o: no suitable DMA found for %s\n", |
| @@ -395,9 +414,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, | |||
| 395 | 414 | ||
| 396 | if ((rc = i2o_pci_alloc(c))) { | 415 | if ((rc = i2o_pci_alloc(c))) { |
| 397 | printk(KERN_ERR "%s: DMA / IO allocation for I2O controller " | 416 | printk(KERN_ERR "%s: DMA / IO allocation for I2O controller " |
| 398 | " failed\n", c->name); | 417 | "failed\n", c->name); |
| 399 | if (rc == -ENODEV) | ||
| 400 | pci_dev_busy = 1; | ||
| 401 | goto free_controller; | 418 | goto free_controller; |
| 402 | } | 419 | } |
| 403 | 420 | ||
| @@ -425,7 +442,7 @@ static int __devinit i2o_pci_probe(struct pci_dev *pdev, | |||
| 425 | i2o_iop_free(c); | 442 | i2o_iop_free(c); |
| 426 | 443 | ||
| 427 | disable: | 444 | disable: |
| 428 | if (!pci_dev_busy) | 445 | if (!enabled) |
| 429 | pci_disable_device(pdev); | 446 | pci_disable_device(pdev); |
| 430 | 447 | ||
| 431 | return rc; | 448 | return rc; |
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index c483a863b116..5d397b7a5497 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig | |||
| @@ -65,7 +65,7 @@ config MMC_AU1X | |||
| 65 | depends on SOC_AU1X00 && MMC | 65 | depends on SOC_AU1X00 && MMC |
| 66 | help | 66 | help |
| 67 | This selects the AMD Alchemy(R) Multimedia card interface. | 67 | This selects the AMD Alchemy(R) Multimedia card interface. |
| 68 | iIf you have a Alchemy platform with a MMC slot, say Y or M here. | 68 | If you have a Alchemy platform with a MMC slot, say Y or M here. |
| 69 | 69 | ||
| 70 | If unsure, say N. | 70 | If unsure, say N. |
| 71 | 71 | ||
diff --git a/drivers/mmc/au1xmmc.c b/drivers/mmc/au1xmmc.c index aaf04638054e..227c39a7c1b4 100644 --- a/drivers/mmc/au1xmmc.c +++ b/drivers/mmc/au1xmmc.c | |||
| @@ -194,7 +194,7 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait, | |||
| 194 | 194 | ||
| 195 | u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT); | 195 | u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT); |
| 196 | 196 | ||
| 197 | switch(cmd->flags) { | 197 | switch (mmc_rsp_type(cmd->flags)) { |
| 198 | case MMC_RSP_R1: | 198 | case MMC_RSP_R1: |
| 199 | mmccmd |= SD_CMD_RT_1; | 199 | mmccmd |= SD_CMD_RT_1; |
| 200 | break; | 200 | break; |
| @@ -483,34 +483,35 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status) | |||
| 483 | cmd = mrq->cmd; | 483 | cmd = mrq->cmd; |
| 484 | cmd->error = MMC_ERR_NONE; | 484 | cmd->error = MMC_ERR_NONE; |
| 485 | 485 | ||
| 486 | if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_SHORT) { | 486 | if (cmd->flags & MMC_RSP_PRESENT) { |
| 487 | 487 | if (cmd->flags & MMC_RSP_136) { | |
| 488 | /* Techincally, we should be getting all 48 bits of the response | 488 | u32 r[4]; |
| 489 | * (SD_RESP1 + SD_RESP2), but because our response omits the CRC, | 489 | int i; |
| 490 | * our data ends up being shifted 8 bits to the right. In this case, | 490 | |
| 491 | * that means that the OSR data starts at bit 31, so we can just | 491 | r[0] = au_readl(host->iobase + SD_RESP3); |
| 492 | * read RESP0 and return that | 492 | r[1] = au_readl(host->iobase + SD_RESP2); |
| 493 | */ | 493 | r[2] = au_readl(host->iobase + SD_RESP1); |
| 494 | 494 | r[3] = au_readl(host->iobase + SD_RESP0); | |
| 495 | cmd->resp[0] = au_readl(host->iobase + SD_RESP0); | 495 | |
| 496 | } | 496 | /* The CRC is omitted from the response, so really |
| 497 | else if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_LONG) { | 497 | * we only got 120 bytes, but the engine expects |
| 498 | u32 r[4]; | 498 | * 128 bits, so we have to shift things up |
| 499 | int i; | 499 | */ |
| 500 | 500 | ||
| 501 | r[0] = au_readl(host->iobase + SD_RESP3); | 501 | for(i = 0; i < 4; i++) { |
| 502 | r[1] = au_readl(host->iobase + SD_RESP2); | 502 | cmd->resp[i] = (r[i] & 0x00FFFFFF) << 8; |
| 503 | r[2] = au_readl(host->iobase + SD_RESP1); | 503 | if (i != 3) |
| 504 | r[3] = au_readl(host->iobase + SD_RESP0); | 504 | cmd->resp[i] |= (r[i + 1] & 0xFF000000) >> 24; |
| 505 | 505 | } | |
| 506 | /* The CRC is omitted from the response, so really we only got | 506 | } else { |
| 507 | * 120 bytes, but the engine expects 128 bits, so we have to shift | 507 | /* Techincally, we should be getting all 48 bits of |
| 508 | * things up | 508 | * the response (SD_RESP1 + SD_RESP2), but because |
| 509 | */ | 509 | * our response omits the CRC, our data ends up |
| 510 | 510 | * being shifted 8 bits to the right. In this case, | |
| 511 | for(i = 0; i < 4; i++) { | 511 | * that means that the OSR data starts at bit 31, |
| 512 | cmd->resp[i] = (r[i] & 0x00FFFFFF) << 8; | 512 | * so we can just read RESP0 and return that |
| 513 | if (i != 3) cmd->resp[i] |= (r[i + 1] & 0xFF000000) >> 24; | 513 | */ |
| 514 | cmd->resp[0] = au_readl(host->iobase + SD_RESP0); | ||
| 514 | } | 515 | } |
| 515 | } | 516 | } |
| 516 | 517 | ||
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index bfca5c176e88..1888060c5e0c 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c | |||
| @@ -211,7 +211,7 @@ int mmc_wait_for_app_cmd(struct mmc_host *host, unsigned int rca, | |||
| 211 | 211 | ||
| 212 | appcmd.opcode = MMC_APP_CMD; | 212 | appcmd.opcode = MMC_APP_CMD; |
| 213 | appcmd.arg = rca << 16; | 213 | appcmd.arg = rca << 16; |
| 214 | appcmd.flags = MMC_RSP_R1; | 214 | appcmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
| 215 | appcmd.retries = 0; | 215 | appcmd.retries = 0; |
| 216 | memset(appcmd.resp, 0, sizeof(appcmd.resp)); | 216 | memset(appcmd.resp, 0, sizeof(appcmd.resp)); |
| 217 | appcmd.data = NULL; | 217 | appcmd.data = NULL; |
| @@ -331,7 +331,7 @@ static int mmc_select_card(struct mmc_host *host, struct mmc_card *card) | |||
| 331 | 331 | ||
| 332 | cmd.opcode = MMC_SELECT_CARD; | 332 | cmd.opcode = MMC_SELECT_CARD; |
| 333 | cmd.arg = card->rca << 16; | 333 | cmd.arg = card->rca << 16; |
| 334 | cmd.flags = MMC_RSP_R1; | 334 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
| 335 | 335 | ||
| 336 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | 336 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); |
| 337 | if (err != MMC_ERR_NONE) | 337 | if (err != MMC_ERR_NONE) |
| @@ -358,7 +358,7 @@ static int mmc_select_card(struct mmc_host *host, struct mmc_card *card) | |||
| 358 | struct mmc_command cmd; | 358 | struct mmc_command cmd; |
| 359 | cmd.opcode = SD_APP_SET_BUS_WIDTH; | 359 | cmd.opcode = SD_APP_SET_BUS_WIDTH; |
| 360 | cmd.arg = SD_BUS_WIDTH_4; | 360 | cmd.arg = SD_BUS_WIDTH_4; |
| 361 | cmd.flags = MMC_RSP_R1; | 361 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
| 362 | 362 | ||
| 363 | err = mmc_wait_for_app_cmd(host, card->rca, &cmd, | 363 | err = mmc_wait_for_app_cmd(host, card->rca, &cmd, |
| 364 | CMD_RETRIES); | 364 | CMD_RETRIES); |
| @@ -386,7 +386,7 @@ static void mmc_deselect_cards(struct mmc_host *host) | |||
| 386 | 386 | ||
| 387 | cmd.opcode = MMC_SELECT_CARD; | 387 | cmd.opcode = MMC_SELECT_CARD; |
| 388 | cmd.arg = 0; | 388 | cmd.arg = 0; |
| 389 | cmd.flags = MMC_RSP_NONE; | 389 | cmd.flags = MMC_RSP_NONE | MMC_CMD_AC; |
| 390 | 390 | ||
| 391 | mmc_wait_for_cmd(host, &cmd, 0); | 391 | mmc_wait_for_cmd(host, &cmd, 0); |
| 392 | } | 392 | } |
| @@ -677,7 +677,7 @@ static void mmc_idle_cards(struct mmc_host *host) | |||
| 677 | 677 | ||
| 678 | cmd.opcode = MMC_GO_IDLE_STATE; | 678 | cmd.opcode = MMC_GO_IDLE_STATE; |
| 679 | cmd.arg = 0; | 679 | cmd.arg = 0; |
| 680 | cmd.flags = MMC_RSP_NONE; | 680 | cmd.flags = MMC_RSP_NONE | MMC_CMD_BC; |
| 681 | 681 | ||
| 682 | mmc_wait_for_cmd(host, &cmd, 0); | 682 | mmc_wait_for_cmd(host, &cmd, 0); |
| 683 | 683 | ||
| @@ -738,7 +738,7 @@ static int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | |||
| 738 | 738 | ||
| 739 | cmd.opcode = MMC_SEND_OP_COND; | 739 | cmd.opcode = MMC_SEND_OP_COND; |
| 740 | cmd.arg = ocr; | 740 | cmd.arg = ocr; |
| 741 | cmd.flags = MMC_RSP_R3; | 741 | cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; |
| 742 | 742 | ||
| 743 | for (i = 100; i; i--) { | 743 | for (i = 100; i; i--) { |
| 744 | err = mmc_wait_for_cmd(host, &cmd, 0); | 744 | err = mmc_wait_for_cmd(host, &cmd, 0); |
| @@ -766,7 +766,7 @@ static int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr) | |||
| 766 | 766 | ||
| 767 | cmd.opcode = SD_APP_OP_COND; | 767 | cmd.opcode = SD_APP_OP_COND; |
| 768 | cmd.arg = ocr; | 768 | cmd.arg = ocr; |
| 769 | cmd.flags = MMC_RSP_R3; | 769 | cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; |
| 770 | 770 | ||
| 771 | for (i = 100; i; i--) { | 771 | for (i = 100; i; i--) { |
| 772 | err = mmc_wait_for_app_cmd(host, 0, &cmd, CMD_RETRIES); | 772 | err = mmc_wait_for_app_cmd(host, 0, &cmd, CMD_RETRIES); |
| @@ -805,7 +805,7 @@ static void mmc_discover_cards(struct mmc_host *host) | |||
| 805 | 805 | ||
| 806 | cmd.opcode = MMC_ALL_SEND_CID; | 806 | cmd.opcode = MMC_ALL_SEND_CID; |
| 807 | cmd.arg = 0; | 807 | cmd.arg = 0; |
| 808 | cmd.flags = MMC_RSP_R2; | 808 | cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR; |
| 809 | 809 | ||
| 810 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | 810 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); |
| 811 | if (err == MMC_ERR_TIMEOUT) { | 811 | if (err == MMC_ERR_TIMEOUT) { |
| @@ -835,7 +835,7 @@ static void mmc_discover_cards(struct mmc_host *host) | |||
| 835 | 835 | ||
| 836 | cmd.opcode = SD_SEND_RELATIVE_ADDR; | 836 | cmd.opcode = SD_SEND_RELATIVE_ADDR; |
| 837 | cmd.arg = 0; | 837 | cmd.arg = 0; |
| 838 | cmd.flags = MMC_RSP_R6; | 838 | cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR; |
| 839 | 839 | ||
| 840 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | 840 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); |
| 841 | if (err != MMC_ERR_NONE) | 841 | if (err != MMC_ERR_NONE) |
| @@ -856,7 +856,7 @@ static void mmc_discover_cards(struct mmc_host *host) | |||
| 856 | } else { | 856 | } else { |
| 857 | cmd.opcode = MMC_SET_RELATIVE_ADDR; | 857 | cmd.opcode = MMC_SET_RELATIVE_ADDR; |
| 858 | cmd.arg = card->rca << 16; | 858 | cmd.arg = card->rca << 16; |
| 859 | cmd.flags = MMC_RSP_R1; | 859 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
| 860 | 860 | ||
| 861 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | 861 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); |
| 862 | if (err != MMC_ERR_NONE) | 862 | if (err != MMC_ERR_NONE) |
| @@ -878,7 +878,7 @@ static void mmc_read_csds(struct mmc_host *host) | |||
| 878 | 878 | ||
| 879 | cmd.opcode = MMC_SEND_CSD; | 879 | cmd.opcode = MMC_SEND_CSD; |
| 880 | cmd.arg = card->rca << 16; | 880 | cmd.arg = card->rca << 16; |
| 881 | cmd.flags = MMC_RSP_R2; | 881 | cmd.flags = MMC_RSP_R2 | MMC_CMD_AC; |
| 882 | 882 | ||
| 883 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | 883 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); |
| 884 | if (err != MMC_ERR_NONE) { | 884 | if (err != MMC_ERR_NONE) { |
| @@ -920,7 +920,7 @@ static void mmc_read_scrs(struct mmc_host *host) | |||
| 920 | 920 | ||
| 921 | cmd.opcode = MMC_APP_CMD; | 921 | cmd.opcode = MMC_APP_CMD; |
| 922 | cmd.arg = card->rca << 16; | 922 | cmd.arg = card->rca << 16; |
| 923 | cmd.flags = MMC_RSP_R1; | 923 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
| 924 | 924 | ||
| 925 | err = mmc_wait_for_cmd(host, &cmd, 0); | 925 | err = mmc_wait_for_cmd(host, &cmd, 0); |
| 926 | if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD)) { | 926 | if ((err != MMC_ERR_NONE) || !(cmd.resp[0] & R1_APP_CMD)) { |
| @@ -932,7 +932,7 @@ static void mmc_read_scrs(struct mmc_host *host) | |||
| 932 | 932 | ||
| 933 | cmd.opcode = SD_APP_SEND_SCR; | 933 | cmd.opcode = SD_APP_SEND_SCR; |
| 934 | cmd.arg = 0; | 934 | cmd.arg = 0; |
| 935 | cmd.flags = MMC_RSP_R1; | 935 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; |
| 936 | 936 | ||
| 937 | memset(&data, 0, sizeof(struct mmc_data)); | 937 | memset(&data, 0, sizeof(struct mmc_data)); |
| 938 | 938 | ||
| @@ -1003,7 +1003,7 @@ static void mmc_check_cards(struct mmc_host *host) | |||
| 1003 | 1003 | ||
| 1004 | cmd.opcode = MMC_SEND_STATUS; | 1004 | cmd.opcode = MMC_SEND_STATUS; |
| 1005 | cmd.arg = card->rca << 16; | 1005 | cmd.arg = card->rca << 16; |
| 1006 | cmd.flags = MMC_RSP_R1; | 1006 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
| 1007 | 1007 | ||
| 1008 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); | 1008 | err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES); |
| 1009 | if (err == MMC_ERR_NONE) | 1009 | if (err == MMC_ERR_NONE) |
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c index 5b014c370e80..8eb2a2ede64b 100644 --- a/drivers/mmc/mmc_block.c +++ b/drivers/mmc/mmc_block.c | |||
| @@ -171,14 +171,14 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
| 171 | brq.mrq.data = &brq.data; | 171 | brq.mrq.data = &brq.data; |
| 172 | 172 | ||
| 173 | brq.cmd.arg = req->sector << 9; | 173 | brq.cmd.arg = req->sector << 9; |
| 174 | brq.cmd.flags = MMC_RSP_R1; | 174 | brq.cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; |
| 175 | brq.data.timeout_ns = card->csd.tacc_ns * 10; | 175 | brq.data.timeout_ns = card->csd.tacc_ns * 10; |
| 176 | brq.data.timeout_clks = card->csd.tacc_clks * 10; | 176 | brq.data.timeout_clks = card->csd.tacc_clks * 10; |
| 177 | brq.data.blksz_bits = md->block_bits; | 177 | brq.data.blksz_bits = md->block_bits; |
| 178 | brq.data.blocks = req->nr_sectors >> (md->block_bits - 9); | 178 | brq.data.blocks = req->nr_sectors >> (md->block_bits - 9); |
| 179 | brq.stop.opcode = MMC_STOP_TRANSMISSION; | 179 | brq.stop.opcode = MMC_STOP_TRANSMISSION; |
| 180 | brq.stop.arg = 0; | 180 | brq.stop.arg = 0; |
| 181 | brq.stop.flags = MMC_RSP_R1B; | 181 | brq.stop.flags = MMC_RSP_R1B | MMC_CMD_AC; |
| 182 | 182 | ||
| 183 | if (rq_data_dir(req) == READ) { | 183 | if (rq_data_dir(req) == READ) { |
| 184 | brq.cmd.opcode = brq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK; | 184 | brq.cmd.opcode = brq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK; |
| @@ -223,7 +223,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req) | |||
| 223 | 223 | ||
| 224 | cmd.opcode = MMC_SEND_STATUS; | 224 | cmd.opcode = MMC_SEND_STATUS; |
| 225 | cmd.arg = card->rca << 16; | 225 | cmd.arg = card->rca << 16; |
| 226 | cmd.flags = MMC_RSP_R1; | 226 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
| 227 | err = mmc_wait_for_cmd(card->host, &cmd, 5); | 227 | err = mmc_wait_for_cmd(card->host, &cmd, 5); |
| 228 | if (err) { | 228 | if (err) { |
| 229 | printk(KERN_ERR "%s: error %d requesting status\n", | 229 | printk(KERN_ERR "%s: error %d requesting status\n", |
| @@ -430,7 +430,7 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) | |||
| 430 | mmc_card_claim_host(card); | 430 | mmc_card_claim_host(card); |
| 431 | cmd.opcode = MMC_SET_BLOCKLEN; | 431 | cmd.opcode = MMC_SET_BLOCKLEN; |
| 432 | cmd.arg = 1 << md->block_bits; | 432 | cmd.arg = 1 << md->block_bits; |
| 433 | cmd.flags = MMC_RSP_R1; | 433 | cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; |
| 434 | err = mmc_wait_for_cmd(card->host, &cmd, 5); | 434 | err = mmc_wait_for_cmd(card->host, &cmd, 5); |
| 435 | mmc_card_release_host(card); | 435 | mmc_card_release_host(card); |
| 436 | 436 | ||
diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c index 634ef53e85a5..37ee7f8dc82f 100644 --- a/drivers/mmc/mmci.c +++ b/drivers/mmc/mmci.c | |||
| @@ -124,15 +124,10 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c) | |||
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | c |= cmd->opcode | MCI_CPSM_ENABLE; | 126 | c |= cmd->opcode | MCI_CPSM_ENABLE; |
| 127 | switch (cmd->flags & MMC_RSP_MASK) { | 127 | if (cmd->flags & MMC_RSP_PRESENT) { |
| 128 | case MMC_RSP_NONE: | 128 | if (cmd->flags & MMC_RSP_136) |
| 129 | default: | 129 | c |= MCI_CPSM_LONGRSP; |
| 130 | break; | ||
| 131 | case MMC_RSP_LONG: | ||
| 132 | c |= MCI_CPSM_LONGRSP; | ||
| 133 | case MMC_RSP_SHORT: | ||
| 134 | c |= MCI_CPSM_RESPONSE; | 130 | c |= MCI_CPSM_RESPONSE; |
| 135 | break; | ||
| 136 | } | 131 | } |
| 137 | if (/*interrupt*/0) | 132 | if (/*interrupt*/0) |
| 138 | c |= MCI_CPSM_INTERRUPT; | 133 | c |= MCI_CPSM_INTERRUPT; |
diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c index ee8f8a0420d1..285d7d068097 100644 --- a/drivers/mmc/pxamci.c +++ b/drivers/mmc/pxamci.c | |||
| @@ -178,14 +178,15 @@ static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, | |||
| 178 | if (cmd->flags & MMC_RSP_BUSY) | 178 | if (cmd->flags & MMC_RSP_BUSY) |
| 179 | cmdat |= CMDAT_BUSY; | 179 | cmdat |= CMDAT_BUSY; |
| 180 | 180 | ||
| 181 | switch (cmd->flags & (MMC_RSP_MASK | MMC_RSP_CRC)) { | 181 | #define RSP_TYPE(x) ((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE)) |
| 182 | case MMC_RSP_SHORT | MMC_RSP_CRC: | 182 | switch (RSP_TYPE(mmc_resp_type(cmd))) { |
| 183 | case RSP_TYPE(MMC_RSP_R1): /* r1, r1b, r6 */ | ||
| 183 | cmdat |= CMDAT_RESP_SHORT; | 184 | cmdat |= CMDAT_RESP_SHORT; |
| 184 | break; | 185 | break; |
| 185 | case MMC_RSP_SHORT: | 186 | case RSP_TYPE(MMC_RSP_R3): |
| 186 | cmdat |= CMDAT_RESP_R3; | 187 | cmdat |= CMDAT_RESP_R3; |
| 187 | break; | 188 | break; |
| 188 | case MMC_RSP_LONG | MMC_RSP_CRC: | 189 | case RSP_TYPE(MMC_RSP_R2): |
| 189 | cmdat |= CMDAT_RESP_R2; | 190 | cmdat |= CMDAT_RESP_R2; |
| 190 | break; | 191 | break; |
| 191 | default: | 192 | default: |
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index f25757625361..3be397d436fa 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c | |||
| @@ -459,7 +459,7 @@ static void wbsd_send_command(struct wbsd_host *host, struct mmc_command *cmd) | |||
| 459 | /* | 459 | /* |
| 460 | * Do we expect a reply? | 460 | * Do we expect a reply? |
| 461 | */ | 461 | */ |
| 462 | if ((cmd->flags & MMC_RSP_MASK) != MMC_RSP_NONE) { | 462 | if (cmd->flags & MMC_RSP_PRESENT) { |
| 463 | /* | 463 | /* |
| 464 | * Read back status. | 464 | * Read back status. |
| 465 | */ | 465 | */ |
| @@ -476,10 +476,10 @@ static void wbsd_send_command(struct wbsd_host *host, struct mmc_command *cmd) | |||
| 476 | cmd->error = MMC_ERR_BADCRC; | 476 | cmd->error = MMC_ERR_BADCRC; |
| 477 | /* All ok */ | 477 | /* All ok */ |
| 478 | else { | 478 | else { |
| 479 | if ((cmd->flags & MMC_RSP_MASK) == MMC_RSP_SHORT) | 479 | if (cmd->flags & MMC_RSP_136) |
| 480 | wbsd_get_short_reply(host, cmd); | ||
| 481 | else | ||
| 482 | wbsd_get_long_reply(host, cmd); | 480 | wbsd_get_long_reply(host, cmd); |
| 481 | else | ||
| 482 | wbsd_get_short_reply(host, cmd); | ||
| 483 | } | 483 | } |
| 484 | } | 484 | } |
| 485 | 485 | ||
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig index effa0d7a73ac..205bb7083335 100644 --- a/drivers/mtd/chips/Kconfig +++ b/drivers/mtd/chips/Kconfig | |||
| @@ -301,7 +301,7 @@ config MTD_JEDEC | |||
| 301 | 301 | ||
| 302 | config MTD_XIP | 302 | config MTD_XIP |
| 303 | bool "XIP aware MTD support" | 303 | bool "XIP aware MTD support" |
| 304 | depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL && ARM | 304 | depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL && ARCH_MTD_XIP |
| 305 | default y if XIP_KERNEL | 305 | default y if XIP_KERNEL |
| 306 | help | 306 | help |
| 307 | This allows MTD support to work with flash memory which is also | 307 | This allows MTD support to work with flash memory which is also |
diff --git a/drivers/mtd/maps/dc21285.c b/drivers/mtd/maps/dc21285.c index 701620b6baed..8b3784e2de89 100644 --- a/drivers/mtd/maps/dc21285.c +++ b/drivers/mtd/maps/dc21285.c | |||
| @@ -110,8 +110,9 @@ static void dc21285_copy_to_32(struct map_info *map, unsigned long to, const voi | |||
| 110 | { | 110 | { |
| 111 | while (len > 0) { | 111 | while (len > 0) { |
| 112 | map_word d; | 112 | map_word d; |
| 113 | d.x[0] = *((uint32_t*)from)++; | 113 | d.x[0] = *((uint32_t*)from); |
| 114 | dc21285_write32(map, d, to); | 114 | dc21285_write32(map, d, to); |
| 115 | from += 4; | ||
| 115 | to += 4; | 116 | to += 4; |
| 116 | len -= 4; | 117 | len -= 4; |
| 117 | } | 118 | } |
| @@ -121,8 +122,9 @@ static void dc21285_copy_to_16(struct map_info *map, unsigned long to, const voi | |||
| 121 | { | 122 | { |
| 122 | while (len > 0) { | 123 | while (len > 0) { |
| 123 | map_word d; | 124 | map_word d; |
| 124 | d.x[0] = *((uint16_t*)from)++; | 125 | d.x[0] = *((uint16_t*)from); |
| 125 | dc21285_write16(map, d, to); | 126 | dc21285_write16(map, d, to); |
| 127 | from += 2; | ||
| 126 | to += 2; | 128 | to += 2; |
| 127 | len -= 2; | 129 | len -= 2; |
| 128 | } | 130 | } |
| @@ -131,8 +133,9 @@ static void dc21285_copy_to_16(struct map_info *map, unsigned long to, const voi | |||
| 131 | static void dc21285_copy_to_8(struct map_info *map, unsigned long to, const void *from, ssize_t len) | 133 | static void dc21285_copy_to_8(struct map_info *map, unsigned long to, const void *from, ssize_t len) |
| 132 | { | 134 | { |
| 133 | map_word d; | 135 | map_word d; |
| 134 | d.x[0] = *((uint8_t*)from)++; | 136 | d.x[0] = *((uint8_t*)from); |
| 135 | dc21285_write8(map, d, to); | 137 | dc21285_write8(map, d, to); |
| 138 | from++; | ||
| 136 | to++; | 139 | to++; |
| 137 | len--; | 140 | len--; |
| 138 | } | 141 | } |
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 7488ee7f7caf..7f47124f118d 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c | |||
| @@ -753,9 +753,11 @@ enum tx_desc_status { | |||
| 753 | enum ChipCaps { CapBusMaster=0x20, CapPwrMgmt=0x2000 }; | 753 | enum ChipCaps { CapBusMaster=0x20, CapPwrMgmt=0x2000 }; |
| 754 | 754 | ||
| 755 | struct vortex_extra_stats { | 755 | struct vortex_extra_stats { |
| 756 | unsigned long tx_deferred; | 756 | unsigned long tx_deferred; |
| 757 | unsigned long tx_multiple_collisions; | 757 | unsigned long tx_max_collisions; |
| 758 | unsigned long rx_bad_ssd; | 758 | unsigned long tx_multiple_collisions; |
| 759 | unsigned long tx_single_collisions; | ||
| 760 | unsigned long rx_bad_ssd; | ||
| 759 | }; | 761 | }; |
| 760 | 762 | ||
| 761 | struct vortex_private { | 763 | struct vortex_private { |
| @@ -863,12 +865,14 @@ static struct { | |||
| 863 | const char str[ETH_GSTRING_LEN]; | 865 | const char str[ETH_GSTRING_LEN]; |
| 864 | } ethtool_stats_keys[] = { | 866 | } ethtool_stats_keys[] = { |
| 865 | { "tx_deferred" }, | 867 | { "tx_deferred" }, |
| 868 | { "tx_max_collisions" }, | ||
| 866 | { "tx_multiple_collisions" }, | 869 | { "tx_multiple_collisions" }, |
| 870 | { "tx_single_collisions" }, | ||
| 867 | { "rx_bad_ssd" }, | 871 | { "rx_bad_ssd" }, |
| 868 | }; | 872 | }; |
| 869 | 873 | ||
| 870 | /* number of ETHTOOL_GSTATS u64's */ | 874 | /* number of ETHTOOL_GSTATS u64's */ |
| 871 | #define VORTEX_NUM_STATS 3 | 875 | #define VORTEX_NUM_STATS 5 |
| 872 | 876 | ||
| 873 | static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq, | 877 | static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq, |
| 874 | int chip_idx, int card_idx); | 878 | int chip_idx, int card_idx); |
| @@ -2108,9 +2112,12 @@ vortex_error(struct net_device *dev, int status) | |||
| 2108 | iowrite8(0, ioaddr + TxStatus); | 2112 | iowrite8(0, ioaddr + TxStatus); |
| 2109 | if (tx_status & 0x30) { /* txJabber or txUnderrun */ | 2113 | if (tx_status & 0x30) { /* txJabber or txUnderrun */ |
| 2110 | do_tx_reset = 1; | 2114 | do_tx_reset = 1; |
| 2111 | } else if ((tx_status & 0x08) && (vp->drv_flags & MAX_COLLISION_RESET)) { /* maxCollisions */ | 2115 | } else if (tx_status & 0x08) { /* maxCollisions */ |
| 2112 | do_tx_reset = 1; | 2116 | vp->xstats.tx_max_collisions++; |
| 2113 | reset_mask = 0x0108; /* Reset interface logic, but not download logic */ | 2117 | if (vp->drv_flags & MAX_COLLISION_RESET) { |
| 2118 | do_tx_reset = 1; | ||
| 2119 | reset_mask = 0x0108; /* Reset interface logic, but not download logic */ | ||
| 2120 | } | ||
| 2114 | } else { /* Merely re-enable the transmitter. */ | 2121 | } else { /* Merely re-enable the transmitter. */ |
| 2115 | iowrite16(TxEnable, ioaddr + EL3_CMD); | 2122 | iowrite16(TxEnable, ioaddr + EL3_CMD); |
| 2116 | } | 2123 | } |
| @@ -2926,7 +2933,6 @@ static void update_stats(void __iomem *ioaddr, struct net_device *dev) | |||
| 2926 | EL3WINDOW(6); | 2933 | EL3WINDOW(6); |
| 2927 | vp->stats.tx_carrier_errors += ioread8(ioaddr + 0); | 2934 | vp->stats.tx_carrier_errors += ioread8(ioaddr + 0); |
| 2928 | vp->stats.tx_heartbeat_errors += ioread8(ioaddr + 1); | 2935 | vp->stats.tx_heartbeat_errors += ioread8(ioaddr + 1); |
| 2929 | vp->stats.collisions += ioread8(ioaddr + 3); | ||
| 2930 | vp->stats.tx_window_errors += ioread8(ioaddr + 4); | 2936 | vp->stats.tx_window_errors += ioread8(ioaddr + 4); |
| 2931 | vp->stats.rx_fifo_errors += ioread8(ioaddr + 5); | 2937 | vp->stats.rx_fifo_errors += ioread8(ioaddr + 5); |
| 2932 | vp->stats.tx_packets += ioread8(ioaddr + 6); | 2938 | vp->stats.tx_packets += ioread8(ioaddr + 6); |
| @@ -2939,10 +2945,15 @@ static void update_stats(void __iomem *ioaddr, struct net_device *dev) | |||
| 2939 | vp->stats.tx_bytes += ioread16(ioaddr + 12); | 2945 | vp->stats.tx_bytes += ioread16(ioaddr + 12); |
| 2940 | /* Extra stats for get_ethtool_stats() */ | 2946 | /* Extra stats for get_ethtool_stats() */ |
| 2941 | vp->xstats.tx_multiple_collisions += ioread8(ioaddr + 2); | 2947 | vp->xstats.tx_multiple_collisions += ioread8(ioaddr + 2); |
| 2948 | vp->xstats.tx_single_collisions += ioread8(ioaddr + 3); | ||
| 2942 | vp->xstats.tx_deferred += ioread8(ioaddr + 8); | 2949 | vp->xstats.tx_deferred += ioread8(ioaddr + 8); |
| 2943 | EL3WINDOW(4); | 2950 | EL3WINDOW(4); |
| 2944 | vp->xstats.rx_bad_ssd += ioread8(ioaddr + 12); | 2951 | vp->xstats.rx_bad_ssd += ioread8(ioaddr + 12); |
| 2945 | 2952 | ||
| 2953 | vp->stats.collisions = vp->xstats.tx_multiple_collisions | ||
| 2954 | + vp->xstats.tx_single_collisions | ||
| 2955 | + vp->xstats.tx_max_collisions; | ||
| 2956 | |||
| 2946 | { | 2957 | { |
| 2947 | u8 up = ioread8(ioaddr + 13); | 2958 | u8 up = ioread8(ioaddr + 13); |
| 2948 | vp->stats.rx_bytes += (up & 0x0f) << 16; | 2959 | vp->stats.rx_bytes += (up & 0x0f) << 16; |
| @@ -3036,8 +3047,10 @@ static void vortex_get_ethtool_stats(struct net_device *dev, | |||
| 3036 | spin_unlock_irqrestore(&vp->lock, flags); | 3047 | spin_unlock_irqrestore(&vp->lock, flags); |
| 3037 | 3048 | ||
| 3038 | data[0] = vp->xstats.tx_deferred; | 3049 | data[0] = vp->xstats.tx_deferred; |
| 3039 | data[1] = vp->xstats.tx_multiple_collisions; | 3050 | data[1] = vp->xstats.tx_max_collisions; |
| 3040 | data[2] = vp->xstats.rx_bad_ssd; | 3051 | data[2] = vp->xstats.tx_multiple_collisions; |
| 3052 | data[3] = vp->xstats.tx_single_collisions; | ||
| 3053 | data[4] = vp->xstats.rx_bad_ssd; | ||
| 3041 | } | 3054 | } |
| 3042 | 3055 | ||
| 3043 | 3056 | ||
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index adfba44dac5a..2beac55b57d6 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c | |||
| @@ -586,6 +586,7 @@ struct rtl8139_private { | |||
| 586 | dma_addr_t tx_bufs_dma; | 586 | dma_addr_t tx_bufs_dma; |
| 587 | signed char phys[4]; /* MII device addresses. */ | 587 | signed char phys[4]; /* MII device addresses. */ |
| 588 | char twistie, twist_row, twist_col; /* Twister tune state. */ | 588 | char twistie, twist_row, twist_col; /* Twister tune state. */ |
| 589 | unsigned int watchdog_fired : 1; | ||
| 589 | unsigned int default_port : 4; /* Last dev->if_port value. */ | 590 | unsigned int default_port : 4; /* Last dev->if_port value. */ |
| 590 | unsigned int have_thread : 1; | 591 | unsigned int have_thread : 1; |
| 591 | spinlock_t lock; | 592 | spinlock_t lock; |
| @@ -638,6 +639,7 @@ static void rtl8139_set_rx_mode (struct net_device *dev); | |||
| 638 | static void __set_rx_mode (struct net_device *dev); | 639 | static void __set_rx_mode (struct net_device *dev); |
| 639 | static void rtl8139_hw_start (struct net_device *dev); | 640 | static void rtl8139_hw_start (struct net_device *dev); |
| 640 | static void rtl8139_thread (void *_data); | 641 | static void rtl8139_thread (void *_data); |
| 642 | static void rtl8139_tx_timeout_task(void *_data); | ||
| 641 | static struct ethtool_ops rtl8139_ethtool_ops; | 643 | static struct ethtool_ops rtl8139_ethtool_ops; |
| 642 | 644 | ||
| 643 | /* write MMIO register, with flush */ | 645 | /* write MMIO register, with flush */ |
| @@ -1598,13 +1600,14 @@ static void rtl8139_thread (void *_data) | |||
| 1598 | { | 1600 | { |
| 1599 | struct net_device *dev = _data; | 1601 | struct net_device *dev = _data; |
| 1600 | struct rtl8139_private *tp = netdev_priv(dev); | 1602 | struct rtl8139_private *tp = netdev_priv(dev); |
| 1601 | unsigned long thr_delay; | 1603 | unsigned long thr_delay = next_tick; |
| 1602 | 1604 | ||
| 1603 | if (rtnl_shlock_nowait() == 0) { | 1605 | if (tp->watchdog_fired) { |
| 1606 | tp->watchdog_fired = 0; | ||
| 1607 | rtl8139_tx_timeout_task(_data); | ||
| 1608 | } else if (rtnl_shlock_nowait() == 0) { | ||
| 1604 | rtl8139_thread_iter (dev, tp, tp->mmio_addr); | 1609 | rtl8139_thread_iter (dev, tp, tp->mmio_addr); |
| 1605 | rtnl_unlock (); | 1610 | rtnl_unlock (); |
| 1606 | |||
| 1607 | thr_delay = next_tick; | ||
| 1608 | } else { | 1611 | } else { |
| 1609 | /* unlikely race. mitigate with fast poll. */ | 1612 | /* unlikely race. mitigate with fast poll. */ |
| 1610 | thr_delay = HZ / 2; | 1613 | thr_delay = HZ / 2; |
| @@ -1631,7 +1634,8 @@ static void rtl8139_stop_thread(struct rtl8139_private *tp) | |||
| 1631 | if (tp->have_thread) { | 1634 | if (tp->have_thread) { |
| 1632 | cancel_rearming_delayed_work(&tp->thread); | 1635 | cancel_rearming_delayed_work(&tp->thread); |
| 1633 | tp->have_thread = 0; | 1636 | tp->have_thread = 0; |
| 1634 | } | 1637 | } else |
| 1638 | flush_scheduled_work(); | ||
| 1635 | } | 1639 | } |
| 1636 | 1640 | ||
| 1637 | static inline void rtl8139_tx_clear (struct rtl8139_private *tp) | 1641 | static inline void rtl8139_tx_clear (struct rtl8139_private *tp) |
| @@ -1642,14 +1646,13 @@ static inline void rtl8139_tx_clear (struct rtl8139_private *tp) | |||
| 1642 | /* XXX account for unsent Tx packets in tp->stats.tx_dropped */ | 1646 | /* XXX account for unsent Tx packets in tp->stats.tx_dropped */ |
| 1643 | } | 1647 | } |
| 1644 | 1648 | ||
| 1645 | 1649 | static void rtl8139_tx_timeout_task (void *_data) | |
| 1646 | static void rtl8139_tx_timeout (struct net_device *dev) | ||
| 1647 | { | 1650 | { |
| 1651 | struct net_device *dev = _data; | ||
| 1648 | struct rtl8139_private *tp = netdev_priv(dev); | 1652 | struct rtl8139_private *tp = netdev_priv(dev); |
| 1649 | void __iomem *ioaddr = tp->mmio_addr; | 1653 | void __iomem *ioaddr = tp->mmio_addr; |
| 1650 | int i; | 1654 | int i; |
| 1651 | u8 tmp8; | 1655 | u8 tmp8; |
| 1652 | unsigned long flags; | ||
| 1653 | 1656 | ||
| 1654 | printk (KERN_DEBUG "%s: Transmit timeout, status %2.2x %4.4x %4.4x " | 1657 | printk (KERN_DEBUG "%s: Transmit timeout, status %2.2x %4.4x %4.4x " |
| 1655 | "media %2.2x.\n", dev->name, RTL_R8 (ChipCmd), | 1658 | "media %2.2x.\n", dev->name, RTL_R8 (ChipCmd), |
| @@ -1670,23 +1673,34 @@ static void rtl8139_tx_timeout (struct net_device *dev) | |||
| 1670 | if (tmp8 & CmdTxEnb) | 1673 | if (tmp8 & CmdTxEnb) |
| 1671 | RTL_W8 (ChipCmd, CmdRxEnb); | 1674 | RTL_W8 (ChipCmd, CmdRxEnb); |
| 1672 | 1675 | ||
| 1673 | spin_lock(&tp->rx_lock); | 1676 | spin_lock_bh(&tp->rx_lock); |
| 1674 | /* Disable interrupts by clearing the interrupt mask. */ | 1677 | /* Disable interrupts by clearing the interrupt mask. */ |
| 1675 | RTL_W16 (IntrMask, 0x0000); | 1678 | RTL_W16 (IntrMask, 0x0000); |
| 1676 | 1679 | ||
| 1677 | /* Stop a shared interrupt from scavenging while we are. */ | 1680 | /* Stop a shared interrupt from scavenging while we are. */ |
| 1678 | spin_lock_irqsave (&tp->lock, flags); | 1681 | spin_lock_irq(&tp->lock); |
| 1679 | rtl8139_tx_clear (tp); | 1682 | rtl8139_tx_clear (tp); |
| 1680 | spin_unlock_irqrestore (&tp->lock, flags); | 1683 | spin_unlock_irq(&tp->lock); |
| 1681 | 1684 | ||
| 1682 | /* ...and finally, reset everything */ | 1685 | /* ...and finally, reset everything */ |
| 1683 | if (netif_running(dev)) { | 1686 | if (netif_running(dev)) { |
| 1684 | rtl8139_hw_start (dev); | 1687 | rtl8139_hw_start (dev); |
| 1685 | netif_wake_queue (dev); | 1688 | netif_wake_queue (dev); |
| 1686 | } | 1689 | } |
| 1687 | spin_unlock(&tp->rx_lock); | 1690 | spin_unlock_bh(&tp->rx_lock); |
| 1688 | } | 1691 | } |
| 1689 | 1692 | ||
| 1693 | static void rtl8139_tx_timeout (struct net_device *dev) | ||
| 1694 | { | ||
| 1695 | struct rtl8139_private *tp = netdev_priv(dev); | ||
| 1696 | |||
| 1697 | if (!tp->have_thread) { | ||
| 1698 | INIT_WORK(&tp->thread, rtl8139_tx_timeout_task, dev); | ||
| 1699 | schedule_delayed_work(&tp->thread, next_tick); | ||
| 1700 | } else | ||
| 1701 | tp->watchdog_fired = 1; | ||
| 1702 | |||
| 1703 | } | ||
| 1690 | 1704 | ||
| 1691 | static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev) | 1705 | static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev) |
| 1692 | { | 1706 | { |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 6a6a08441804..47c72a63dfe1 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
| @@ -4,9 +4,9 @@ | |||
| 4 | # | 4 | # |
| 5 | 5 | ||
| 6 | menu "Network device support" | 6 | menu "Network device support" |
| 7 | depends on NET | ||
| 7 | 8 | ||
| 8 | config NETDEVICES | 9 | config NETDEVICES |
| 9 | depends on NET | ||
| 10 | default y if UML | 10 | default y if UML |
| 11 | bool "Network device support" | 11 | bool "Network device support" |
| 12 | ---help--- | 12 | ---help--- |
| @@ -24,9 +24,6 @@ config NETDEVICES | |||
| 24 | 24 | ||
| 25 | If unsure, say Y. | 25 | If unsure, say Y. |
| 26 | 26 | ||
| 27 | # All the following symbols are dependent on NETDEVICES - do not repeat | ||
| 28 | # that for each of the symbols. | ||
| 29 | if NETDEVICES | ||
| 30 | 27 | ||
| 31 | config IFB | 28 | config IFB |
| 32 | tristate "Intermediate Functional Block support" | 29 | tristate "Intermediate Functional Block support" |
| @@ -2718,8 +2715,6 @@ config NETCONSOLE | |||
| 2718 | If you want to log kernel messages over the network, enable this. | 2715 | If you want to log kernel messages over the network, enable this. |
| 2719 | See <file:Documentation/networking/netconsole.txt> for details. | 2716 | See <file:Documentation/networking/netconsole.txt> for details. |
| 2720 | 2717 | ||
| 2721 | endif #NETDEVICES | ||
| 2722 | |||
| 2723 | config NETPOLL | 2718 | config NETPOLL |
| 2724 | def_bool NETCONSOLE | 2719 | def_bool NETCONSOLE |
| 2725 | 2720 | ||
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 4ff006c37626..e0f51afec778 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
| @@ -1145,7 +1145,8 @@ int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1145 | } | 1145 | } |
| 1146 | 1146 | ||
| 1147 | #define BOND_INTERSECT_FEATURES \ | 1147 | #define BOND_INTERSECT_FEATURES \ |
| 1148 | (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM) | 1148 | (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM|\ |
| 1149 | NETIF_F_TSO|NETIF_F_UFO) | ||
| 1149 | 1150 | ||
| 1150 | /* | 1151 | /* |
| 1151 | * Compute the common dev->feature set available to all slaves. Some | 1152 | * Compute the common dev->feature set available to all slaves. Some |
| @@ -1168,6 +1169,16 @@ static int bond_compute_features(struct bonding *bond) | |||
| 1168 | NETIF_F_HW_CSUM))) | 1169 | NETIF_F_HW_CSUM))) |
| 1169 | features &= ~NETIF_F_SG; | 1170 | features &= ~NETIF_F_SG; |
| 1170 | 1171 | ||
| 1172 | /* | ||
| 1173 | * features will include NETIF_F_TSO (NETIF_F_UFO) iff all | ||
| 1174 | * slave devices support NETIF_F_TSO (NETIF_F_UFO), which | ||
| 1175 | * implies that all slaves also support scatter-gather | ||
| 1176 | * (NETIF_F_SG), which implies that features also includes | ||
| 1177 | * NETIF_F_SG. So no need to check whether we have an | ||
| 1178 | * illegal combination of NETIF_F_{TSO,UFO} and | ||
| 1179 | * !NETIF_F_SG | ||
| 1180 | */ | ||
| 1181 | |||
| 1171 | features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES); | 1182 | features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES); |
| 1172 | bond_dev->features = features; | 1183 | bond_dev->features = features; |
| 1173 | 1184 | ||
| @@ -4080,6 +4091,8 @@ static void bond_ethtool_get_drvinfo(struct net_device *bond_dev, | |||
| 4080 | 4091 | ||
| 4081 | static struct ethtool_ops bond_ethtool_ops = { | 4092 | static struct ethtool_ops bond_ethtool_ops = { |
| 4082 | .get_tx_csum = ethtool_op_get_tx_csum, | 4093 | .get_tx_csum = ethtool_op_get_tx_csum, |
| 4094 | .get_tso = ethtool_op_get_tso, | ||
| 4095 | .get_ufo = ethtool_op_get_ufo, | ||
| 4083 | .get_sg = ethtool_op_get_sg, | 4096 | .get_sg = ethtool_op_get_sg, |
| 4084 | .get_drvinfo = bond_ethtool_get_drvinfo, | 4097 | .get_drvinfo = bond_ethtool_get_drvinfo, |
| 4085 | }; | 4098 | }; |
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 32d13da43a0b..041bcc583557 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
| @@ -260,7 +260,7 @@ static ssize_t bonding_store_slaves(struct class_device *cd, const char *buffer, | |||
| 260 | char *ifname; | 260 | char *ifname; |
| 261 | int i, res, found, ret = count; | 261 | int i, res, found, ret = count; |
| 262 | struct slave *slave; | 262 | struct slave *slave; |
| 263 | struct net_device *dev = 0; | 263 | struct net_device *dev = NULL; |
| 264 | struct bonding *bond = to_bond(cd); | 264 | struct bonding *bond = to_bond(cd); |
| 265 | 265 | ||
| 266 | /* Quick sanity check -- is the bond interface up? */ | 266 | /* Quick sanity check -- is the bond interface up? */ |
| @@ -995,7 +995,7 @@ static ssize_t bonding_store_primary(struct class_device *cd, const char *buf, s | |||
| 995 | printk(KERN_INFO DRV_NAME | 995 | printk(KERN_INFO DRV_NAME |
| 996 | ": %s: Setting primary slave to None.\n", | 996 | ": %s: Setting primary slave to None.\n", |
| 997 | bond->dev->name); | 997 | bond->dev->name); |
| 998 | bond->primary_slave = 0; | 998 | bond->primary_slave = NULL; |
| 999 | bond_select_active_slave(bond); | 999 | bond_select_active_slave(bond); |
| 1000 | } else { | 1000 | } else { |
| 1001 | printk(KERN_INFO DRV_NAME | 1001 | printk(KERN_INFO DRV_NAME |
| @@ -1123,7 +1123,7 @@ static ssize_t bonding_store_active_slave(struct class_device *cd, const char *b | |||
| 1123 | printk(KERN_INFO DRV_NAME | 1123 | printk(KERN_INFO DRV_NAME |
| 1124 | ": %s: Setting active slave to None.\n", | 1124 | ": %s: Setting active slave to None.\n", |
| 1125 | bond->dev->name); | 1125 | bond->dev->name); |
| 1126 | bond->primary_slave = 0; | 1126 | bond->primary_slave = NULL; |
| 1127 | bond_select_active_slave(bond); | 1127 | bond_select_active_slave(bond); |
| 1128 | } else { | 1128 | } else { |
| 1129 | printk(KERN_INFO DRV_NAME | 1129 | printk(KERN_INFO DRV_NAME |
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index bf1fd2b98bf8..24253c807e55 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
| @@ -2752,8 +2752,6 @@ static int e100_resume(struct pci_dev *pdev) | |||
| 2752 | retval = pci_enable_wake(pdev, 0, 0); | 2752 | retval = pci_enable_wake(pdev, 0, 0); |
| 2753 | if (retval) | 2753 | if (retval) |
| 2754 | DPRINTK(PROBE,ERR, "Error clearing wake events\n"); | 2754 | DPRINTK(PROBE,ERR, "Error clearing wake events\n"); |
| 2755 | if(e100_hw_init(nic)) | ||
| 2756 | DPRINTK(HW, ERR, "e100_hw_init failed\n"); | ||
| 2757 | 2755 | ||
| 2758 | netif_device_attach(netdev); | 2756 | netif_device_attach(netdev); |
| 2759 | if(netif_running(netdev)) | 2757 | if(netif_running(netdev)) |
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 0c18dbd67d3b..0e8e3fcde9ff 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
| @@ -199,8 +199,7 @@ static int gfar_probe(struct platform_device *pdev) | |||
| 199 | 199 | ||
| 200 | /* get a pointer to the register memory */ | 200 | /* get a pointer to the register memory */ |
| 201 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 201 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 202 | priv->regs = (struct gfar *) | 202 | priv->regs = ioremap(r->start, sizeof (struct gfar)); |
| 203 | ioremap(r->start, sizeof (struct gfar)); | ||
| 204 | 203 | ||
| 205 | if (NULL == priv->regs) { | 204 | if (NULL == priv->regs) { |
| 206 | err = -ENOMEM; | 205 | err = -ENOMEM; |
| @@ -369,7 +368,7 @@ static int gfar_probe(struct platform_device *pdev) | |||
| 369 | return 0; | 368 | return 0; |
| 370 | 369 | ||
| 371 | register_fail: | 370 | register_fail: |
| 372 | iounmap((void *) priv->regs); | 371 | iounmap(priv->regs); |
| 373 | regs_fail: | 372 | regs_fail: |
| 374 | free_netdev(dev); | 373 | free_netdev(dev); |
| 375 | return err; | 374 | return err; |
| @@ -382,7 +381,7 @@ static int gfar_remove(struct platform_device *pdev) | |||
| 382 | 381 | ||
| 383 | platform_set_drvdata(pdev, NULL); | 382 | platform_set_drvdata(pdev, NULL); |
| 384 | 383 | ||
| 385 | iounmap((void *) priv->regs); | 384 | iounmap(priv->regs); |
| 386 | free_netdev(dev); | 385 | free_netdev(dev); |
| 387 | 386 | ||
| 388 | return 0; | 387 | return 0; |
| @@ -454,8 +453,7 @@ static void init_registers(struct net_device *dev) | |||
| 454 | 453 | ||
| 455 | /* Zero out the rmon mib registers if it has them */ | 454 | /* Zero out the rmon mib registers if it has them */ |
| 456 | if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) { | 455 | if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) { |
| 457 | memset((void *) &(priv->regs->rmon), 0, | 456 | memset_io(&(priv->regs->rmon), 0, sizeof (struct rmon_mib)); |
| 458 | sizeof (struct rmon_mib)); | ||
| 459 | 457 | ||
| 460 | /* Mask off the CAM interrupts */ | 458 | /* Mask off the CAM interrupts */ |
| 461 | gfar_write(&priv->regs->rmon.cam1, 0xffffffff); | 459 | gfar_write(&priv->regs->rmon.cam1, 0xffffffff); |
| @@ -477,7 +475,7 @@ static void init_registers(struct net_device *dev) | |||
| 477 | void gfar_halt(struct net_device *dev) | 475 | void gfar_halt(struct net_device *dev) |
| 478 | { | 476 | { |
| 479 | struct gfar_private *priv = netdev_priv(dev); | 477 | struct gfar_private *priv = netdev_priv(dev); |
| 480 | struct gfar *regs = priv->regs; | 478 | struct gfar __iomem *regs = priv->regs; |
| 481 | u32 tempval; | 479 | u32 tempval; |
| 482 | 480 | ||
| 483 | /* Mask all interrupts */ | 481 | /* Mask all interrupts */ |
| @@ -507,7 +505,7 @@ void gfar_halt(struct net_device *dev) | |||
| 507 | void stop_gfar(struct net_device *dev) | 505 | void stop_gfar(struct net_device *dev) |
| 508 | { | 506 | { |
| 509 | struct gfar_private *priv = netdev_priv(dev); | 507 | struct gfar_private *priv = netdev_priv(dev); |
| 510 | struct gfar *regs = priv->regs; | 508 | struct gfar __iomem *regs = priv->regs; |
| 511 | unsigned long flags; | 509 | unsigned long flags; |
| 512 | 510 | ||
| 513 | phy_stop(priv->phydev); | 511 | phy_stop(priv->phydev); |
| @@ -590,7 +588,7 @@ static void free_skb_resources(struct gfar_private *priv) | |||
| 590 | void gfar_start(struct net_device *dev) | 588 | void gfar_start(struct net_device *dev) |
| 591 | { | 589 | { |
| 592 | struct gfar_private *priv = netdev_priv(dev); | 590 | struct gfar_private *priv = netdev_priv(dev); |
| 593 | struct gfar *regs = priv->regs; | 591 | struct gfar __iomem *regs = priv->regs; |
| 594 | u32 tempval; | 592 | u32 tempval; |
| 595 | 593 | ||
| 596 | /* Enable Rx and Tx in MACCFG1 */ | 594 | /* Enable Rx and Tx in MACCFG1 */ |
| @@ -624,7 +622,7 @@ int startup_gfar(struct net_device *dev) | |||
| 624 | unsigned long vaddr; | 622 | unsigned long vaddr; |
| 625 | int i; | 623 | int i; |
| 626 | struct gfar_private *priv = netdev_priv(dev); | 624 | struct gfar_private *priv = netdev_priv(dev); |
| 627 | struct gfar *regs = priv->regs; | 625 | struct gfar __iomem *regs = priv->regs; |
| 628 | int err = 0; | 626 | int err = 0; |
| 629 | u32 rctrl = 0; | 627 | u32 rctrl = 0; |
| 630 | u32 attrs = 0; | 628 | u32 attrs = 0; |
| @@ -1622,7 +1620,7 @@ static irqreturn_t gfar_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
| 1622 | static void adjust_link(struct net_device *dev) | 1620 | static void adjust_link(struct net_device *dev) |
| 1623 | { | 1621 | { |
| 1624 | struct gfar_private *priv = netdev_priv(dev); | 1622 | struct gfar_private *priv = netdev_priv(dev); |
| 1625 | struct gfar *regs = priv->regs; | 1623 | struct gfar __iomem *regs = priv->regs; |
| 1626 | unsigned long flags; | 1624 | unsigned long flags; |
| 1627 | struct phy_device *phydev = priv->phydev; | 1625 | struct phy_device *phydev = priv->phydev; |
| 1628 | int new_state = 0; | 1626 | int new_state = 0; |
| @@ -1703,7 +1701,7 @@ static void gfar_set_multi(struct net_device *dev) | |||
| 1703 | { | 1701 | { |
| 1704 | struct dev_mc_list *mc_ptr; | 1702 | struct dev_mc_list *mc_ptr; |
| 1705 | struct gfar_private *priv = netdev_priv(dev); | 1703 | struct gfar_private *priv = netdev_priv(dev); |
| 1706 | struct gfar *regs = priv->regs; | 1704 | struct gfar __iomem *regs = priv->regs; |
| 1707 | u32 tempval; | 1705 | u32 tempval; |
| 1708 | 1706 | ||
| 1709 | if(dev->flags & IFF_PROMISC) { | 1707 | if(dev->flags & IFF_PROMISC) { |
| @@ -1842,7 +1840,7 @@ static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr) | |||
| 1842 | int idx; | 1840 | int idx; |
| 1843 | char tmpbuf[MAC_ADDR_LEN]; | 1841 | char tmpbuf[MAC_ADDR_LEN]; |
| 1844 | u32 tempval; | 1842 | u32 tempval; |
| 1845 | u32 *macptr = &priv->regs->macstnaddr1; | 1843 | u32 __iomem *macptr = &priv->regs->macstnaddr1; |
| 1846 | 1844 | ||
| 1847 | macptr += num*2; | 1845 | macptr += num*2; |
| 1848 | 1846 | ||
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index cb9d66ac3ab9..d37d5401be6e 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h | |||
| @@ -682,8 +682,8 @@ struct gfar_private { | |||
| 682 | struct rxbd8 *cur_rx; /* Next free rx ring entry */ | 682 | struct rxbd8 *cur_rx; /* Next free rx ring entry */ |
| 683 | struct txbd8 *cur_tx; /* Next free ring entry */ | 683 | struct txbd8 *cur_tx; /* Next free ring entry */ |
| 684 | struct txbd8 *dirty_tx; /* The Ring entry to be freed. */ | 684 | struct txbd8 *dirty_tx; /* The Ring entry to be freed. */ |
| 685 | struct gfar *regs; /* Pointer to the GFAR memory mapped Registers */ | 685 | struct gfar __iomem *regs; /* Pointer to the GFAR memory mapped Registers */ |
| 686 | u32 *hash_regs[16]; | 686 | u32 __iomem *hash_regs[16]; |
| 687 | int hash_width; | 687 | int hash_width; |
| 688 | struct net_device_stats stats; /* linux network statistics */ | 688 | struct net_device_stats stats; /* linux network statistics */ |
| 689 | struct gfar_extra_stats extra_stats; | 689 | struct gfar_extra_stats extra_stats; |
| @@ -718,14 +718,14 @@ struct gfar_private { | |||
| 718 | uint32_t msg_enable; | 718 | uint32_t msg_enable; |
| 719 | }; | 719 | }; |
| 720 | 720 | ||
| 721 | static inline u32 gfar_read(volatile unsigned *addr) | 721 | static inline u32 gfar_read(volatile unsigned __iomem *addr) |
| 722 | { | 722 | { |
| 723 | u32 val; | 723 | u32 val; |
| 724 | val = in_be32(addr); | 724 | val = in_be32(addr); |
| 725 | return val; | 725 | return val; |
| 726 | } | 726 | } |
| 727 | 727 | ||
| 728 | static inline void gfar_write(volatile unsigned *addr, u32 val) | 728 | static inline void gfar_write(volatile unsigned __iomem *addr, u32 val) |
| 729 | { | 729 | { |
| 730 | out_be32(addr, val); | 730 | out_be32(addr, val); |
| 731 | } | 731 | } |
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c index 765e810620fe..5de7b2e259dc 100644 --- a/drivers/net/gianfar_ethtool.c +++ b/drivers/net/gianfar_ethtool.c | |||
| @@ -144,11 +144,11 @@ static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy, | |||
| 144 | u64 *extra = (u64 *) & priv->extra_stats; | 144 | u64 *extra = (u64 *) & priv->extra_stats; |
| 145 | 145 | ||
| 146 | if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) { | 146 | if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_RMON) { |
| 147 | u32 *rmon = (u32 *) & priv->regs->rmon; | 147 | u32 __iomem *rmon = (u32 __iomem *) & priv->regs->rmon; |
| 148 | struct gfar_stats *stats = (struct gfar_stats *) buf; | 148 | struct gfar_stats *stats = (struct gfar_stats *) buf; |
| 149 | 149 | ||
| 150 | for (i = 0; i < GFAR_RMON_LEN; i++) | 150 | for (i = 0; i < GFAR_RMON_LEN; i++) |
| 151 | stats->rmon[i] = (u64) (rmon[i]); | 151 | stats->rmon[i] = (u64) gfar_read(&rmon[i]); |
| 152 | 152 | ||
| 153 | for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++) | 153 | for (i = 0; i < GFAR_EXTRA_STATS_LEN; i++) |
| 154 | stats->extra[i] = extra[i]; | 154 | stats->extra[i] = extra[i]; |
| @@ -221,11 +221,11 @@ static void gfar_get_regs(struct net_device *dev, struct ethtool_regs *regs, voi | |||
| 221 | { | 221 | { |
| 222 | int i; | 222 | int i; |
| 223 | struct gfar_private *priv = netdev_priv(dev); | 223 | struct gfar_private *priv = netdev_priv(dev); |
| 224 | u32 *theregs = (u32 *) priv->regs; | 224 | u32 __iomem *theregs = (u32 __iomem *) priv->regs; |
| 225 | u32 *buf = (u32 *) regbuf; | 225 | u32 *buf = (u32 *) regbuf; |
| 226 | 226 | ||
| 227 | for (i = 0; i < sizeof (struct gfar) / sizeof (u32); i++) | 227 | for (i = 0; i < sizeof (struct gfar) / sizeof (u32); i++) |
| 228 | buf[i] = theregs[i]; | 228 | buf[i] = gfar_read(&theregs[i]); |
| 229 | } | 229 | } |
| 230 | 230 | ||
| 231 | /* Convert microseconds to ethernet clock ticks, which changes | 231 | /* Convert microseconds to ethernet clock ticks, which changes |
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c index 74e52fcbf806..c6b725529af5 100644 --- a/drivers/net/gianfar_mii.c +++ b/drivers/net/gianfar_mii.c | |||
| @@ -50,7 +50,7 @@ | |||
| 50 | * All PHY configuration is done through the TSEC1 MIIM regs */ | 50 | * All PHY configuration is done through the TSEC1 MIIM regs */ |
| 51 | int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value) | 51 | int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value) |
| 52 | { | 52 | { |
| 53 | struct gfar_mii *regs = bus->priv; | 53 | struct gfar_mii __iomem *regs = (void __iomem *)bus->priv; |
| 54 | 54 | ||
| 55 | /* Set the PHY address and the register address we want to write */ | 55 | /* Set the PHY address and the register address we want to write */ |
| 56 | gfar_write(®s->miimadd, (mii_id << 8) | regnum); | 56 | gfar_write(®s->miimadd, (mii_id << 8) | regnum); |
| @@ -70,7 +70,7 @@ int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value) | |||
| 70 | * configuration has to be done through the TSEC1 MIIM regs */ | 70 | * configuration has to be done through the TSEC1 MIIM regs */ |
| 71 | int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum) | 71 | int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum) |
| 72 | { | 72 | { |
| 73 | struct gfar_mii *regs = bus->priv; | 73 | struct gfar_mii __iomem *regs = (void __iomem *)bus->priv; |
| 74 | u16 value; | 74 | u16 value; |
| 75 | 75 | ||
| 76 | /* Set the PHY address and the register address we want to read */ | 76 | /* Set the PHY address and the register address we want to read */ |
| @@ -94,7 +94,7 @@ int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum) | |||
| 94 | /* Reset the MIIM registers, and wait for the bus to free */ | 94 | /* Reset the MIIM registers, and wait for the bus to free */ |
| 95 | int gfar_mdio_reset(struct mii_bus *bus) | 95 | int gfar_mdio_reset(struct mii_bus *bus) |
| 96 | { | 96 | { |
| 97 | struct gfar_mii *regs = bus->priv; | 97 | struct gfar_mii __iomem *regs = (void __iomem *)bus->priv; |
| 98 | unsigned int timeout = PHY_INIT_TIMEOUT; | 98 | unsigned int timeout = PHY_INIT_TIMEOUT; |
| 99 | 99 | ||
| 100 | spin_lock_bh(&bus->mdio_lock); | 100 | spin_lock_bh(&bus->mdio_lock); |
| @@ -126,7 +126,7 @@ int gfar_mdio_probe(struct device *dev) | |||
| 126 | { | 126 | { |
| 127 | struct platform_device *pdev = to_platform_device(dev); | 127 | struct platform_device *pdev = to_platform_device(dev); |
| 128 | struct gianfar_mdio_data *pdata; | 128 | struct gianfar_mdio_data *pdata; |
| 129 | struct gfar_mii *regs; | 129 | struct gfar_mii __iomem *regs; |
| 130 | struct mii_bus *new_bus; | 130 | struct mii_bus *new_bus; |
| 131 | struct resource *r; | 131 | struct resource *r; |
| 132 | int err = 0; | 132 | int err = 0; |
| @@ -155,15 +155,14 @@ int gfar_mdio_probe(struct device *dev) | |||
| 155 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 155 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 156 | 156 | ||
| 157 | /* Set the PHY base address */ | 157 | /* Set the PHY base address */ |
| 158 | regs = (struct gfar_mii *) ioremap(r->start, | 158 | regs = ioremap(r->start, sizeof (struct gfar_mii)); |
| 159 | sizeof (struct gfar_mii)); | ||
| 160 | 159 | ||
| 161 | if (NULL == regs) { | 160 | if (NULL == regs) { |
| 162 | err = -ENOMEM; | 161 | err = -ENOMEM; |
| 163 | goto reg_map_fail; | 162 | goto reg_map_fail; |
| 164 | } | 163 | } |
| 165 | 164 | ||
| 166 | new_bus->priv = regs; | 165 | new_bus->priv = (void __force *)regs; |
| 167 | 166 | ||
| 168 | new_bus->irq = pdata->irq; | 167 | new_bus->irq = pdata->irq; |
| 169 | 168 | ||
| @@ -181,7 +180,7 @@ int gfar_mdio_probe(struct device *dev) | |||
| 181 | return 0; | 180 | return 0; |
| 182 | 181 | ||
| 183 | bus_register_fail: | 182 | bus_register_fail: |
| 184 | iounmap((void *) regs); | 183 | iounmap(regs); |
| 185 | reg_map_fail: | 184 | reg_map_fail: |
| 186 | kfree(new_bus); | 185 | kfree(new_bus); |
| 187 | 186 | ||
| @@ -197,7 +196,7 @@ int gfar_mdio_remove(struct device *dev) | |||
| 197 | 196 | ||
| 198 | dev_set_drvdata(dev, NULL); | 197 | dev_set_drvdata(dev, NULL); |
| 199 | 198 | ||
| 200 | iounmap((void *) (&bus->priv)); | 199 | iounmap((void __iomem *)bus->priv); |
| 201 | bus->priv = NULL; | 200 | bus->priv = NULL; |
| 202 | kfree(bus); | 201 | kfree(bus); |
| 203 | 202 | ||
diff --git a/drivers/net/hamradio/baycom_par.c b/drivers/net/hamradio/baycom_par.c index 3b1bef1ee215..77411a00d1ee 100644 --- a/drivers/net/hamradio/baycom_par.c +++ b/drivers/net/hamradio/baycom_par.c | |||
| @@ -86,7 +86,6 @@ | |||
| 86 | #include <linux/bitops.h> | 86 | #include <linux/bitops.h> |
| 87 | #include <linux/jiffies.h> | 87 | #include <linux/jiffies.h> |
| 88 | 88 | ||
| 89 | #include <asm/bug.h> | ||
| 90 | #include <asm/system.h> | 89 | #include <asm/system.h> |
| 91 | #include <asm/uaccess.h> | 90 | #include <asm/uaccess.h> |
| 92 | 91 | ||
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 7ef4b0434a3f..c0998ef938e0 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
| @@ -32,6 +32,8 @@ | |||
| 32 | */ | 32 | */ |
| 33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
| 34 | #include <linux/dma-mapping.h> | 34 | #include <linux/dma-mapping.h> |
| 35 | #include <linux/in.h> | ||
| 36 | #include <linux/ip.h> | ||
| 35 | #include <linux/tcp.h> | 37 | #include <linux/tcp.h> |
| 36 | #include <linux/udp.h> | 38 | #include <linux/udp.h> |
| 37 | #include <linux/etherdevice.h> | 39 | #include <linux/etherdevice.h> |
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 1c6d328165bb..0245e40b51a1 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c | |||
| @@ -1610,6 +1610,8 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) | |||
| 1610 | } | 1610 | } |
| 1611 | else if (!pskb_may_pull(skb, skb->len)) | 1611 | else if (!pskb_may_pull(skb, skb->len)) |
| 1612 | goto err; | 1612 | goto err; |
| 1613 | else | ||
| 1614 | skb->ip_summed = CHECKSUM_NONE; | ||
| 1613 | 1615 | ||
| 1614 | len = slhc_uncompress(ppp->vj, skb->data + 2, skb->len - 2); | 1616 | len = slhc_uncompress(ppp->vj, skb->data + 2, skb->len - 2); |
| 1615 | if (len <= 0) { | 1617 | if (len <= 0) { |
| @@ -1690,6 +1692,7 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb) | |||
| 1690 | kfree_skb(skb); | 1692 | kfree_skb(skb); |
| 1691 | } else { | 1693 | } else { |
| 1692 | skb_pull(skb, 2); /* chop off protocol */ | 1694 | skb_pull(skb, 2); /* chop off protocol */ |
| 1695 | skb_postpull_rcsum(skb, skb->data - 2, 2); | ||
| 1693 | skb->dev = ppp->dev; | 1696 | skb->dev = ppp->dev; |
| 1694 | skb->protocol = htons(npindex_to_ethertype[npi]); | 1697 | skb->protocol = htons(npindex_to_ethertype[npi]); |
| 1695 | skb->mac.raw = skb->data; | 1698 | skb->mac.raw = skb->data; |
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 2e1bed153c39..6e1018448eea 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
| @@ -484,13 +484,12 @@ static void mdio_write(void __iomem *ioaddr, int RegAddr, int value) | |||
| 484 | int i; | 484 | int i; |
| 485 | 485 | ||
| 486 | RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value); | 486 | RTL_W32(PHYAR, 0x80000000 | (RegAddr & 0xFF) << 16 | value); |
| 487 | udelay(1000); | ||
| 488 | 487 | ||
| 489 | for (i = 2000; i > 0; i--) { | 488 | for (i = 20; i > 0; i--) { |
| 490 | /* Check if the RTL8169 has completed writing to the specified MII register */ | 489 | /* Check if the RTL8169 has completed writing to the specified MII register */ |
| 491 | if (!(RTL_R32(PHYAR) & 0x80000000)) | 490 | if (!(RTL_R32(PHYAR) & 0x80000000)) |
| 492 | break; | 491 | break; |
| 493 | udelay(100); | 492 | udelay(25); |
| 494 | } | 493 | } |
| 495 | } | 494 | } |
| 496 | 495 | ||
| @@ -499,15 +498,14 @@ static int mdio_read(void __iomem *ioaddr, int RegAddr) | |||
| 499 | int i, value = -1; | 498 | int i, value = -1; |
| 500 | 499 | ||
| 501 | RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16); | 500 | RTL_W32(PHYAR, 0x0 | (RegAddr & 0xFF) << 16); |
| 502 | udelay(1000); | ||
| 503 | 501 | ||
| 504 | for (i = 2000; i > 0; i--) { | 502 | for (i = 20; i > 0; i--) { |
| 505 | /* Check if the RTL8169 has completed retrieving data from the specified MII register */ | 503 | /* Check if the RTL8169 has completed retrieving data from the specified MII register */ |
| 506 | if (RTL_R32(PHYAR) & 0x80000000) { | 504 | if (RTL_R32(PHYAR) & 0x80000000) { |
| 507 | value = (int) (RTL_R32(PHYAR) & 0xFFFF); | 505 | value = (int) (RTL_R32(PHYAR) & 0xFFFF); |
| 508 | break; | 506 | break; |
| 509 | } | 507 | } |
| 510 | udelay(100); | 508 | udelay(25); |
| 511 | } | 509 | } |
| 512 | return value; | 510 | return value; |
| 513 | } | 511 | } |
| @@ -677,6 +675,9 @@ static int rtl8169_set_speed_xmii(struct net_device *dev, | |||
| 677 | 675 | ||
| 678 | if (duplex == DUPLEX_HALF) | 676 | if (duplex == DUPLEX_HALF) |
| 679 | auto_nego &= ~(PHY_Cap_10_Full | PHY_Cap_100_Full); | 677 | auto_nego &= ~(PHY_Cap_10_Full | PHY_Cap_100_Full); |
| 678 | |||
| 679 | if (duplex == DUPLEX_FULL) | ||
| 680 | auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_100_Half); | ||
| 680 | } | 681 | } |
| 681 | 682 | ||
| 682 | tp->phy_auto_nego_reg = auto_nego; | 683 | tp->phy_auto_nego_reg = auto_nego; |
diff --git a/drivers/net/sis900.h b/drivers/net/sis900.h index 4233ea55670f..50323941e3c0 100644 --- a/drivers/net/sis900.h +++ b/drivers/net/sis900.h | |||
| @@ -33,7 +33,6 @@ enum sis900_registers { | |||
| 33 | rxcfg=0x34, //Receive Configuration Register | 33 | rxcfg=0x34, //Receive Configuration Register |
| 34 | flctrl=0x38, //Flow Control Register | 34 | flctrl=0x38, //Flow Control Register |
| 35 | rxlen=0x3c, //Receive Packet Length Register | 35 | rxlen=0x3c, //Receive Packet Length Register |
| 36 | cfgpmcsr=0x44, //Configuration Power Management Control/Status Register | ||
| 37 | rfcr=0x48, //Receive Filter Control Register | 36 | rfcr=0x48, //Receive Filter Control Register |
| 38 | rfdr=0x4C, //Receive Filter Data Register | 37 | rfdr=0x4C, //Receive Filter Data Register |
| 39 | pmctrl=0xB0, //Power Management Control Register | 38 | pmctrl=0xB0, //Power Management Control Register |
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index f8b973a04b65..cae2edf23004 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
| @@ -23,12 +23,6 @@ | |||
| 23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 24 | */ | 24 | */ |
| 25 | 25 | ||
| 26 | /* | ||
| 27 | * TOTEST | ||
| 28 | * - speed setting | ||
| 29 | * - suspend/resume | ||
| 30 | */ | ||
| 31 | |||
| 32 | #include <linux/config.h> | 26 | #include <linux/config.h> |
| 33 | #include <linux/crc32.h> | 27 | #include <linux/crc32.h> |
| 34 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
| @@ -57,7 +51,7 @@ | |||
| 57 | #include "sky2.h" | 51 | #include "sky2.h" |
| 58 | 52 | ||
| 59 | #define DRV_NAME "sky2" | 53 | #define DRV_NAME "sky2" |
| 60 | #define DRV_VERSION "0.13" | 54 | #define DRV_VERSION "0.15" |
| 61 | #define PFX DRV_NAME " " | 55 | #define PFX DRV_NAME " " |
| 62 | 56 | ||
| 63 | /* | 57 | /* |
| @@ -102,6 +96,10 @@ static int copybreak __read_mostly = 256; | |||
| 102 | module_param(copybreak, int, 0); | 96 | module_param(copybreak, int, 0); |
| 103 | MODULE_PARM_DESC(copybreak, "Receive copy threshold"); | 97 | MODULE_PARM_DESC(copybreak, "Receive copy threshold"); |
| 104 | 98 | ||
| 99 | static int disable_msi = 0; | ||
| 100 | module_param(disable_msi, int, 0); | ||
| 101 | MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); | ||
| 102 | |||
| 105 | static const struct pci_device_id sky2_id_table[] = { | 103 | static const struct pci_device_id sky2_id_table[] = { |
| 106 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, | 104 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, |
| 107 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, | 105 | { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, |
| @@ -198,7 +196,7 @@ static int sky2_set_power_state(struct sky2_hw *hw, pci_power_t state) | |||
| 198 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); | 196 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
| 199 | 197 | ||
| 200 | pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_PMC, &power_control); | 198 | pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_PMC, &power_control); |
| 201 | vaux = (sky2_read8(hw, B0_CTST) & Y2_VAUX_AVAIL) && | 199 | vaux = (sky2_read16(hw, B0_CTST) & Y2_VAUX_AVAIL) && |
| 202 | (power_control & PCI_PM_CAP_PME_D3cold); | 200 | (power_control & PCI_PM_CAP_PME_D3cold); |
| 203 | 201 | ||
| 204 | pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_CTRL, &power_control); | 202 | pci_read_config_word(hw->pdev, hw->pm_cap + PCI_PM_CTRL, &power_control); |
| @@ -1834,6 +1832,8 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
| 1834 | u16 hwidx; | 1832 | u16 hwidx; |
| 1835 | u16 tx_done[2] = { TX_NO_STATUS, TX_NO_STATUS }; | 1833 | u16 tx_done[2] = { TX_NO_STATUS, TX_NO_STATUS }; |
| 1836 | 1834 | ||
| 1835 | sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); | ||
| 1836 | |||
| 1837 | hwidx = sky2_read16(hw, STAT_PUT_IDX); | 1837 | hwidx = sky2_read16(hw, STAT_PUT_IDX); |
| 1838 | BUG_ON(hwidx >= STATUS_RING_SIZE); | 1838 | BUG_ON(hwidx >= STATUS_RING_SIZE); |
| 1839 | rmb(); | 1839 | rmb(); |
| @@ -1913,12 +1913,10 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
| 1913 | } | 1913 | } |
| 1914 | 1914 | ||
| 1915 | exit_loop: | 1915 | exit_loop: |
| 1916 | sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); | ||
| 1917 | |||
| 1918 | sky2_tx_check(hw, 0, tx_done[0]); | 1916 | sky2_tx_check(hw, 0, tx_done[0]); |
| 1919 | sky2_tx_check(hw, 1, tx_done[1]); | 1917 | sky2_tx_check(hw, 1, tx_done[1]); |
| 1920 | 1918 | ||
| 1921 | if (sky2_read16(hw, STAT_PUT_IDX) == hw->st_idx) { | 1919 | if (likely(work_done < to_do)) { |
| 1922 | /* need to restart TX timer */ | 1920 | /* need to restart TX timer */ |
| 1923 | if (is_ec_a1(hw)) { | 1921 | if (is_ec_a1(hw)) { |
| 1924 | sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP); | 1922 | sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP); |
| @@ -2141,14 +2139,12 @@ static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk) | |||
| 2141 | 2139 | ||
| 2142 | static int sky2_reset(struct sky2_hw *hw) | 2140 | static int sky2_reset(struct sky2_hw *hw) |
| 2143 | { | 2141 | { |
| 2144 | u32 ctst; | ||
| 2145 | u16 status; | 2142 | u16 status; |
| 2146 | u8 t8, pmd_type; | 2143 | u8 t8, pmd_type; |
| 2147 | int i; | 2144 | int i, err; |
| 2148 | |||
| 2149 | ctst = sky2_read32(hw, B0_CTST); | ||
| 2150 | 2145 | ||
| 2151 | sky2_write8(hw, B0_CTST, CS_RST_CLR); | 2146 | sky2_write8(hw, B0_CTST, CS_RST_CLR); |
| 2147 | |||
| 2152 | hw->chip_id = sky2_read8(hw, B2_CHIP_ID); | 2148 | hw->chip_id = sky2_read8(hw, B2_CHIP_ID); |
| 2153 | if (hw->chip_id < CHIP_ID_YUKON_XL || hw->chip_id > CHIP_ID_YUKON_FE) { | 2149 | if (hw->chip_id < CHIP_ID_YUKON_XL || hw->chip_id > CHIP_ID_YUKON_FE) { |
| 2154 | printk(KERN_ERR PFX "%s: unsupported chip type 0x%x\n", | 2150 | printk(KERN_ERR PFX "%s: unsupported chip type 0x%x\n", |
| @@ -2156,12 +2152,6 @@ static int sky2_reset(struct sky2_hw *hw) | |||
| 2156 | return -EOPNOTSUPP; | 2152 | return -EOPNOTSUPP; |
| 2157 | } | 2153 | } |
| 2158 | 2154 | ||
| 2159 | /* ring for status responses */ | ||
| 2160 | hw->st_le = pci_alloc_consistent(hw->pdev, STATUS_LE_BYTES, | ||
| 2161 | &hw->st_dma); | ||
| 2162 | if (!hw->st_le) | ||
| 2163 | return -ENOMEM; | ||
| 2164 | |||
| 2165 | /* disable ASF */ | 2155 | /* disable ASF */ |
| 2166 | if (hw->chip_id <= CHIP_ID_YUKON_EC) { | 2156 | if (hw->chip_id <= CHIP_ID_YUKON_EC) { |
| 2167 | sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); | 2157 | sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_RESET); |
| @@ -2173,19 +2163,24 @@ static int sky2_reset(struct sky2_hw *hw) | |||
| 2173 | sky2_write8(hw, B0_CTST, CS_RST_CLR); | 2163 | sky2_write8(hw, B0_CTST, CS_RST_CLR); |
| 2174 | 2164 | ||
| 2175 | /* clear PCI errors, if any */ | 2165 | /* clear PCI errors, if any */ |
| 2176 | pci_read_config_word(hw->pdev, PCI_STATUS, &status); | 2166 | err = pci_read_config_word(hw->pdev, PCI_STATUS, &status); |
| 2167 | if (err) | ||
| 2168 | goto pci_err; | ||
| 2169 | |||
| 2177 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); | 2170 | sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); |
| 2178 | pci_write_config_word(hw->pdev, PCI_STATUS, | 2171 | err = pci_write_config_word(hw->pdev, PCI_STATUS, |
| 2179 | status | PCI_STATUS_ERROR_BITS); | 2172 | status | PCI_STATUS_ERROR_BITS); |
| 2173 | if (err) | ||
| 2174 | goto pci_err; | ||
| 2180 | 2175 | ||
| 2181 | sky2_write8(hw, B0_CTST, CS_MRST_CLR); | 2176 | sky2_write8(hw, B0_CTST, CS_MRST_CLR); |
| 2182 | 2177 | ||
| 2183 | /* clear any PEX errors */ | 2178 | /* clear any PEX errors */ |
| 2184 | if (is_pciex(hw)) { | 2179 | if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP)) { |
| 2185 | u16 lstat; | 2180 | err = pci_write_config_dword(hw->pdev, PEX_UNC_ERR_STAT, |
| 2186 | pci_write_config_dword(hw->pdev, PEX_UNC_ERR_STAT, | 2181 | 0xffffffffUL); |
| 2187 | 0xffffffffUL); | 2182 | if (err) |
| 2188 | pci_read_config_word(hw->pdev, PEX_LNK_STAT, &lstat); | 2183 | goto pci_err; |
| 2189 | } | 2184 | } |
| 2190 | 2185 | ||
| 2191 | pmd_type = sky2_read8(hw, B2_PMD_TYP); | 2186 | pmd_type = sky2_read8(hw, B2_PMD_TYP); |
| @@ -2297,6 +2292,14 @@ static int sky2_reset(struct sky2_hw *hw) | |||
| 2297 | sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START); | 2292 | sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START); |
| 2298 | 2293 | ||
| 2299 | return 0; | 2294 | return 0; |
| 2295 | |||
| 2296 | pci_err: | ||
| 2297 | /* This is to catch a BIOS bug workaround where | ||
| 2298 | * mmconfig table doesn't have other buses. | ||
| 2299 | */ | ||
| 2300 | printk(KERN_ERR PFX "%s: can't access PCI config space\n", | ||
| 2301 | pci_name(hw->pdev)); | ||
| 2302 | return err; | ||
| 2300 | } | 2303 | } |
| 2301 | 2304 | ||
| 2302 | static u32 sky2_supported_modes(const struct sky2_hw *hw) | 2305 | static u32 sky2_supported_modes(const struct sky2_hw *hw) |
| @@ -2551,19 +2554,24 @@ static struct net_device_stats *sky2_get_stats(struct net_device *dev) | |||
| 2551 | static int sky2_set_mac_address(struct net_device *dev, void *p) | 2554 | static int sky2_set_mac_address(struct net_device *dev, void *p) |
| 2552 | { | 2555 | { |
| 2553 | struct sky2_port *sky2 = netdev_priv(dev); | 2556 | struct sky2_port *sky2 = netdev_priv(dev); |
| 2554 | struct sockaddr *addr = p; | 2557 | struct sky2_hw *hw = sky2->hw; |
| 2558 | unsigned port = sky2->port; | ||
| 2559 | const struct sockaddr *addr = p; | ||
| 2555 | 2560 | ||
| 2556 | if (!is_valid_ether_addr(addr->sa_data)) | 2561 | if (!is_valid_ether_addr(addr->sa_data)) |
| 2557 | return -EADDRNOTAVAIL; | 2562 | return -EADDRNOTAVAIL; |
| 2558 | 2563 | ||
| 2559 | memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); | 2564 | memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); |
| 2560 | memcpy_toio(sky2->hw->regs + B2_MAC_1 + sky2->port * 8, | 2565 | memcpy_toio(hw->regs + B2_MAC_1 + port * 8, |
| 2561 | dev->dev_addr, ETH_ALEN); | 2566 | dev->dev_addr, ETH_ALEN); |
| 2562 | memcpy_toio(sky2->hw->regs + B2_MAC_2 + sky2->port * 8, | 2567 | memcpy_toio(hw->regs + B2_MAC_2 + port * 8, |
| 2563 | dev->dev_addr, ETH_ALEN); | 2568 | dev->dev_addr, ETH_ALEN); |
| 2564 | 2569 | ||
| 2565 | if (netif_running(dev)) | 2570 | /* virtual address for data */ |
| 2566 | sky2_phy_reinit(sky2); | 2571 | gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr); |
| 2572 | |||
| 2573 | /* physical address: used for pause frames */ | ||
| 2574 | gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr); | ||
| 2567 | 2575 | ||
| 2568 | return 0; | 2576 | return 0; |
| 2569 | } | 2577 | } |
| @@ -2843,7 +2851,7 @@ static int sky2_set_coalesce(struct net_device *dev, | |||
| 2843 | if (ecmd->rx_coalesce_usecs_irq == 0) | 2851 | if (ecmd->rx_coalesce_usecs_irq == 0) |
| 2844 | sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_STOP); | 2852 | sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_STOP); |
| 2845 | else { | 2853 | else { |
| 2846 | sky2_write32(hw, STAT_TX_TIMER_INI, | 2854 | sky2_write32(hw, STAT_ISR_TIMER_INI, |
| 2847 | sky2_us2clk(hw, ecmd->rx_coalesce_usecs_irq)); | 2855 | sky2_us2clk(hw, ecmd->rx_coalesce_usecs_irq)); |
| 2848 | sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START); | 2856 | sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START); |
| 2849 | } | 2857 | } |
| @@ -3055,6 +3063,61 @@ static void __devinit sky2_show_addr(struct net_device *dev) | |||
| 3055 | dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); | 3063 | dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]); |
| 3056 | } | 3064 | } |
| 3057 | 3065 | ||
| 3066 | /* Handle software interrupt used during MSI test */ | ||
| 3067 | static irqreturn_t __devinit sky2_test_intr(int irq, void *dev_id, | ||
| 3068 | struct pt_regs *regs) | ||
| 3069 | { | ||
| 3070 | struct sky2_hw *hw = dev_id; | ||
| 3071 | u32 status = sky2_read32(hw, B0_Y2_SP_ISRC2); | ||
| 3072 | |||
| 3073 | if (status == 0) | ||
| 3074 | return IRQ_NONE; | ||
| 3075 | |||
| 3076 | if (status & Y2_IS_IRQ_SW) { | ||
| 3077 | sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ); | ||
| 3078 | hw->msi = 1; | ||
| 3079 | } | ||
| 3080 | sky2_write32(hw, B0_Y2_SP_ICR, 2); | ||
| 3081 | |||
| 3082 | sky2_read32(hw, B0_IMSK); | ||
| 3083 | return IRQ_HANDLED; | ||
| 3084 | } | ||
| 3085 | |||
| 3086 | /* Test interrupt path by forcing a a software IRQ */ | ||
| 3087 | static int __devinit sky2_test_msi(struct sky2_hw *hw) | ||
| 3088 | { | ||
| 3089 | struct pci_dev *pdev = hw->pdev; | ||
| 3090 | int i, err; | ||
| 3091 | |||
| 3092 | sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW); | ||
| 3093 | |||
| 3094 | err = request_irq(pdev->irq, sky2_test_intr, SA_SHIRQ, DRV_NAME, hw); | ||
| 3095 | if (err) { | ||
| 3096 | printk(KERN_ERR PFX "%s: cannot assign irq %d\n", | ||
| 3097 | pci_name(pdev), pdev->irq); | ||
| 3098 | return err; | ||
| 3099 | } | ||
| 3100 | |||
| 3101 | sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ); | ||
| 3102 | wmb(); | ||
| 3103 | |||
| 3104 | for (i = 0; i < 10; i++) { | ||
| 3105 | barrier(); | ||
| 3106 | if (hw->msi) | ||
| 3107 | goto found; | ||
| 3108 | mdelay(1); | ||
| 3109 | } | ||
| 3110 | |||
| 3111 | err = -EOPNOTSUPP; | ||
| 3112 | sky2_write8(hw, B0_CTST, CS_CL_SW_IRQ); | ||
| 3113 | found: | ||
| 3114 | sky2_write32(hw, B0_IMSK, 0); | ||
| 3115 | |||
| 3116 | free_irq(pdev->irq, hw); | ||
| 3117 | |||
| 3118 | return err; | ||
| 3119 | } | ||
| 3120 | |||
| 3058 | static int __devinit sky2_probe(struct pci_dev *pdev, | 3121 | static int __devinit sky2_probe(struct pci_dev *pdev, |
| 3059 | const struct pci_device_id *ent) | 3122 | const struct pci_device_id *ent) |
| 3060 | { | 3123 | { |
| @@ -3135,6 +3198,12 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
| 3135 | } | 3198 | } |
| 3136 | hw->pm_cap = pm_cap; | 3199 | hw->pm_cap = pm_cap; |
| 3137 | 3200 | ||
| 3201 | /* ring for status responses */ | ||
| 3202 | hw->st_le = pci_alloc_consistent(hw->pdev, STATUS_LE_BYTES, | ||
| 3203 | &hw->st_dma); | ||
| 3204 | if (!hw->st_le) | ||
| 3205 | goto err_out_iounmap; | ||
| 3206 | |||
| 3138 | err = sky2_reset(hw); | 3207 | err = sky2_reset(hw); |
| 3139 | if (err) | 3208 | if (err) |
| 3140 | goto err_out_iounmap; | 3209 | goto err_out_iounmap; |
| @@ -3169,7 +3238,22 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
| 3169 | } | 3238 | } |
| 3170 | } | 3239 | } |
| 3171 | 3240 | ||
| 3172 | err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ, DRV_NAME, hw); | 3241 | if (!disable_msi && pci_enable_msi(pdev) == 0) { |
| 3242 | err = sky2_test_msi(hw); | ||
| 3243 | if (err == -EOPNOTSUPP) { | ||
| 3244 | /* MSI test failed, go back to INTx mode */ | ||
| 3245 | printk(KERN_WARNING PFX "%s: No interrupt was generated using MSI, " | ||
| 3246 | "switching to INTx mode. Please report this failure to " | ||
| 3247 | "the PCI maintainer and include system chipset information.\n", | ||
| 3248 | pci_name(pdev)); | ||
| 3249 | pci_disable_msi(pdev); | ||
| 3250 | } | ||
| 3251 | else if (err) | ||
| 3252 | goto err_out_unregister; | ||
| 3253 | } | ||
| 3254 | |||
| 3255 | err = request_irq(pdev->irq, sky2_intr, SA_SHIRQ | SA_SAMPLE_RANDOM, | ||
| 3256 | DRV_NAME, hw); | ||
| 3173 | if (err) { | 3257 | if (err) { |
| 3174 | printk(KERN_ERR PFX "%s: cannot assign irq %d\n", | 3258 | printk(KERN_ERR PFX "%s: cannot assign irq %d\n", |
| 3175 | pci_name(pdev), pdev->irq); | 3259 | pci_name(pdev), pdev->irq); |
| @@ -3184,6 +3268,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
| 3184 | return 0; | 3268 | return 0; |
| 3185 | 3269 | ||
| 3186 | err_out_unregister: | 3270 | err_out_unregister: |
| 3271 | if (hw->msi) | ||
| 3272 | pci_disable_msi(pdev); | ||
| 3187 | if (dev1) { | 3273 | if (dev1) { |
| 3188 | unregister_netdev(dev1); | 3274 | unregister_netdev(dev1); |
| 3189 | free_netdev(dev1); | 3275 | free_netdev(dev1); |
| @@ -3226,6 +3312,8 @@ static void __devexit sky2_remove(struct pci_dev *pdev) | |||
| 3226 | sky2_read8(hw, B0_CTST); | 3312 | sky2_read8(hw, B0_CTST); |
| 3227 | 3313 | ||
| 3228 | free_irq(pdev->irq, hw); | 3314 | free_irq(pdev->irq, hw); |
| 3315 | if (hw->msi) | ||
| 3316 | pci_disable_msi(pdev); | ||
| 3229 | pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma); | 3317 | pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma); |
| 3230 | pci_release_regions(pdev); | 3318 | pci_release_regions(pdev); |
| 3231 | pci_disable_device(pdev); | 3319 | pci_disable_device(pdev); |
| @@ -3263,25 +3351,33 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) | |||
| 3263 | static int sky2_resume(struct pci_dev *pdev) | 3351 | static int sky2_resume(struct pci_dev *pdev) |
| 3264 | { | 3352 | { |
| 3265 | struct sky2_hw *hw = pci_get_drvdata(pdev); | 3353 | struct sky2_hw *hw = pci_get_drvdata(pdev); |
| 3266 | int i; | 3354 | int i, err; |
| 3267 | 3355 | ||
| 3268 | pci_restore_state(pdev); | 3356 | pci_restore_state(pdev); |
| 3269 | pci_enable_wake(pdev, PCI_D0, 0); | 3357 | pci_enable_wake(pdev, PCI_D0, 0); |
| 3270 | sky2_set_power_state(hw, PCI_D0); | 3358 | err = sky2_set_power_state(hw, PCI_D0); |
| 3359 | if (err) | ||
| 3360 | goto out; | ||
| 3271 | 3361 | ||
| 3272 | sky2_reset(hw); | 3362 | err = sky2_reset(hw); |
| 3363 | if (err) | ||
| 3364 | goto out; | ||
| 3273 | 3365 | ||
| 3274 | for (i = 0; i < 2; i++) { | 3366 | for (i = 0; i < 2; i++) { |
| 3275 | struct net_device *dev = hw->dev[i]; | 3367 | struct net_device *dev = hw->dev[i]; |
| 3276 | if (dev) { | 3368 | if (dev && netif_running(dev)) { |
| 3277 | if (netif_running(dev)) { | 3369 | netif_device_attach(dev); |
| 3278 | netif_device_attach(dev); | 3370 | err = sky2_up(dev); |
| 3279 | if (sky2_up(dev)) | 3371 | if (err) { |
| 3280 | dev_close(dev); | 3372 | printk(KERN_ERR PFX "%s: could not up: %d\n", |
| 3373 | dev->name, err); | ||
| 3374 | dev_close(dev); | ||
| 3375 | break; | ||
| 3281 | } | 3376 | } |
| 3282 | } | 3377 | } |
| 3283 | } | 3378 | } |
| 3284 | return 0; | 3379 | out: |
| 3380 | return err; | ||
| 3285 | } | 3381 | } |
| 3286 | #endif | 3382 | #endif |
| 3287 | 3383 | ||
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 95518921001c..fd12c289a238 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h | |||
| @@ -1841,6 +1841,7 @@ struct sky2_hw { | |||
| 1841 | struct net_device *dev[2]; | 1841 | struct net_device *dev[2]; |
| 1842 | 1842 | ||
| 1843 | int pm_cap; | 1843 | int pm_cap; |
| 1844 | int msi; | ||
| 1844 | u8 chip_id; | 1845 | u8 chip_id; |
| 1845 | u8 chip_rev; | 1846 | u8 chip_rev; |
| 1846 | u8 copper; | 1847 | u8 copper; |
| @@ -1867,14 +1868,6 @@ static inline u8 sky2_read8(const struct sky2_hw *hw, unsigned reg) | |||
| 1867 | return readb(hw->regs + reg); | 1868 | return readb(hw->regs + reg); |
| 1868 | } | 1869 | } |
| 1869 | 1870 | ||
| 1870 | /* This should probably go away, bus based tweeks suck */ | ||
| 1871 | static inline int is_pciex(const struct sky2_hw *hw) | ||
| 1872 | { | ||
| 1873 | u32 status; | ||
| 1874 | pci_read_config_dword(hw->pdev, PCI_DEV_STATUS, &status); | ||
| 1875 | return (status & PCI_OS_PCI_X) == 0; | ||
| 1876 | } | ||
| 1877 | |||
| 1878 | static inline void sky2_write32(const struct sky2_hw *hw, unsigned reg, u32 val) | 1871 | static inline void sky2_write32(const struct sky2_hw *hw, unsigned reg, u32 val) |
| 1879 | { | 1872 | { |
| 1880 | writel(val, hw->regs + reg); | 1873 | writel(val, hw->regs + reg); |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index f2d1dafde087..e7dc653d5bd6 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
| @@ -69,8 +69,8 @@ | |||
| 69 | 69 | ||
| 70 | #define DRV_MODULE_NAME "tg3" | 70 | #define DRV_MODULE_NAME "tg3" |
| 71 | #define PFX DRV_MODULE_NAME ": " | 71 | #define PFX DRV_MODULE_NAME ": " |
| 72 | #define DRV_MODULE_VERSION "3.48" | 72 | #define DRV_MODULE_VERSION "3.49" |
| 73 | #define DRV_MODULE_RELDATE "Jan 16, 2006" | 73 | #define DRV_MODULE_RELDATE "Feb 2, 2006" |
| 74 | 74 | ||
| 75 | #define TG3_DEF_MAC_MODE 0 | 75 | #define TG3_DEF_MAC_MODE 0 |
| 76 | #define TG3_DEF_RX_MODE 0 | 76 | #define TG3_DEF_RX_MODE 0 |
| @@ -3482,6 +3482,17 @@ static void tg3_reset_task(void *_data) | |||
| 3482 | struct tg3 *tp = _data; | 3482 | struct tg3 *tp = _data; |
| 3483 | unsigned int restart_timer; | 3483 | unsigned int restart_timer; |
| 3484 | 3484 | ||
| 3485 | tg3_full_lock(tp, 0); | ||
| 3486 | tp->tg3_flags |= TG3_FLAG_IN_RESET_TASK; | ||
| 3487 | |||
| 3488 | if (!netif_running(tp->dev)) { | ||
| 3489 | tp->tg3_flags &= ~TG3_FLAG_IN_RESET_TASK; | ||
| 3490 | tg3_full_unlock(tp); | ||
| 3491 | return; | ||
| 3492 | } | ||
| 3493 | |||
| 3494 | tg3_full_unlock(tp); | ||
| 3495 | |||
| 3485 | tg3_netif_stop(tp); | 3496 | tg3_netif_stop(tp); |
| 3486 | 3497 | ||
| 3487 | tg3_full_lock(tp, 1); | 3498 | tg3_full_lock(tp, 1); |
| @@ -3494,10 +3505,12 @@ static void tg3_reset_task(void *_data) | |||
| 3494 | 3505 | ||
| 3495 | tg3_netif_start(tp); | 3506 | tg3_netif_start(tp); |
| 3496 | 3507 | ||
| 3497 | tg3_full_unlock(tp); | ||
| 3498 | |||
| 3499 | if (restart_timer) | 3508 | if (restart_timer) |
| 3500 | mod_timer(&tp->timer, jiffies + 1); | 3509 | mod_timer(&tp->timer, jiffies + 1); |
| 3510 | |||
| 3511 | tp->tg3_flags &= ~TG3_FLAG_IN_RESET_TASK; | ||
| 3512 | |||
| 3513 | tg3_full_unlock(tp); | ||
| 3501 | } | 3514 | } |
| 3502 | 3515 | ||
| 3503 | static void tg3_tx_timeout(struct net_device *dev) | 3516 | static void tg3_tx_timeout(struct net_device *dev) |
| @@ -6786,6 +6799,13 @@ static int tg3_close(struct net_device *dev) | |||
| 6786 | { | 6799 | { |
| 6787 | struct tg3 *tp = netdev_priv(dev); | 6800 | struct tg3 *tp = netdev_priv(dev); |
| 6788 | 6801 | ||
| 6802 | /* Calling flush_scheduled_work() may deadlock because | ||
| 6803 | * linkwatch_event() may be on the workqueue and it will try to get | ||
| 6804 | * the rtnl_lock which we are holding. | ||
| 6805 | */ | ||
| 6806 | while (tp->tg3_flags & TG3_FLAG_IN_RESET_TASK) | ||
| 6807 | msleep(1); | ||
| 6808 | |||
| 6789 | netif_stop_queue(dev); | 6809 | netif_stop_queue(dev); |
| 6790 | 6810 | ||
| 6791 | del_timer_sync(&tp->timer); | 6811 | del_timer_sync(&tp->timer); |
| @@ -10880,6 +10900,7 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev) | |||
| 10880 | if (dev) { | 10900 | if (dev) { |
| 10881 | struct tg3 *tp = netdev_priv(dev); | 10901 | struct tg3 *tp = netdev_priv(dev); |
| 10882 | 10902 | ||
| 10903 | flush_scheduled_work(); | ||
| 10883 | unregister_netdev(dev); | 10904 | unregister_netdev(dev); |
| 10884 | if (tp->regs) { | 10905 | if (tp->regs) { |
| 10885 | iounmap(tp->regs); | 10906 | iounmap(tp->regs); |
| @@ -10901,6 +10922,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) | |||
| 10901 | if (!netif_running(dev)) | 10922 | if (!netif_running(dev)) |
| 10902 | return 0; | 10923 | return 0; |
| 10903 | 10924 | ||
| 10925 | flush_scheduled_work(); | ||
| 10904 | tg3_netif_stop(tp); | 10926 | tg3_netif_stop(tp); |
| 10905 | 10927 | ||
| 10906 | del_timer_sync(&tp->timer); | 10928 | del_timer_sync(&tp->timer); |
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index e8243305f0e8..7f4b7f6ac40d 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h | |||
| @@ -2162,6 +2162,7 @@ struct tg3 { | |||
| 2162 | #define TG3_FLAG_JUMBO_RING_ENABLE 0x00800000 | 2162 | #define TG3_FLAG_JUMBO_RING_ENABLE 0x00800000 |
| 2163 | #define TG3_FLAG_10_100_ONLY 0x01000000 | 2163 | #define TG3_FLAG_10_100_ONLY 0x01000000 |
| 2164 | #define TG3_FLAG_PAUSE_AUTONEG 0x02000000 | 2164 | #define TG3_FLAG_PAUSE_AUTONEG 0x02000000 |
| 2165 | #define TG3_FLAG_IN_RESET_TASK 0x04000000 | ||
| 2165 | #define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000 | 2166 | #define TG3_FLAG_BROKEN_CHECKSUMS 0x10000000 |
| 2166 | #define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000 | 2167 | #define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000 |
| 2167 | #define TG3_FLAG_SPLIT_MODE 0x40000000 | 2168 | #define TG3_FLAG_SPLIT_MODE 0x40000000 |
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c index 983981666800..238e9c72cb3a 100644 --- a/drivers/net/tulip/uli526x.c +++ b/drivers/net/tulip/uli526x.c | |||
| @@ -214,7 +214,7 @@ static u32 uli526x_cr6_user_set; | |||
| 214 | /* For module input parameter */ | 214 | /* For module input parameter */ |
| 215 | static int debug; | 215 | static int debug; |
| 216 | static u32 cr6set; | 216 | static u32 cr6set; |
| 217 | static unsigned char mode = 8; | 217 | static int mode = 8; |
| 218 | 218 | ||
| 219 | /* function declaration ------------------------------------- */ | 219 | /* function declaration ------------------------------------- */ |
| 220 | static int uli526x_open(struct net_device *); | 220 | static int uli526x_open(struct net_device *); |
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c index 2f61a47b4716..1ff5de076d21 100644 --- a/drivers/net/wan/dscc4.c +++ b/drivers/net/wan/dscc4.c | |||
| @@ -1943,7 +1943,7 @@ static int dscc4_init_ring(struct net_device *dev) | |||
| 1943 | (++i%TX_RING_SIZE)*sizeof(*tx_fd)); | 1943 | (++i%TX_RING_SIZE)*sizeof(*tx_fd)); |
| 1944 | } while (i < TX_RING_SIZE); | 1944 | } while (i < TX_RING_SIZE); |
| 1945 | 1945 | ||
| 1946 | if (dscc4_init_dummy_skb(dpriv) < 0) | 1946 | if (!dscc4_init_dummy_skb(dpriv)) |
| 1947 | goto err_free_dma_tx; | 1947 | goto err_free_dma_tx; |
| 1948 | 1948 | ||
| 1949 | memset(dpriv->rx_skbuff, 0, sizeof(struct sk_buff *)*RX_RING_SIZE); | 1949 | memset(dpriv->rx_skbuff, 0, sizeof(struct sk_buff *)*RX_RING_SIZE); |
diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c index 8dea07b47999..eba8e5cfacc2 100644 --- a/drivers/net/wan/pci200syn.c +++ b/drivers/net/wan/pci200syn.c | |||
| @@ -29,7 +29,7 @@ | |||
| 29 | #include <linux/netdevice.h> | 29 | #include <linux/netdevice.h> |
| 30 | #include <linux/hdlc.h> | 30 | #include <linux/hdlc.h> |
| 31 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
| 32 | #include <asm/delay.h> | 32 | #include <linux/delay.h> |
| 33 | #include <asm/io.h> | 33 | #include <asm/io.h> |
| 34 | 34 | ||
| 35 | #include "hd64572.h" | 35 | #include "hd64572.h" |
diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c index 9c1e10602f2b..9d3b51c3ef54 100644 --- a/drivers/net/wan/wanxl.c +++ b/drivers/net/wan/wanxl.c | |||
| @@ -27,8 +27,8 @@ | |||
| 27 | #include <linux/hdlc.h> | 27 | #include <linux/hdlc.h> |
| 28 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
| 29 | #include <linux/dma-mapping.h> | 29 | #include <linux/dma-mapping.h> |
| 30 | #include <linux/delay.h> | ||
| 30 | #include <asm/io.h> | 31 | #include <asm/io.h> |
| 31 | #include <asm/delay.h> | ||
| 32 | 32 | ||
| 33 | #include "wanxl.h" | 33 | #include "wanxl.h" |
| 34 | 34 | ||
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index c5cd61c7f927..e5bb9f5ae429 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c | |||
| @@ -748,7 +748,7 @@ prism54_get_essid(struct net_device *ndev, struct iw_request_info *info, | |||
| 748 | if (essid->length) { | 748 | if (essid->length) { |
| 749 | dwrq->flags = 1; /* set ESSID to ON for Wireless Extensions */ | 749 | dwrq->flags = 1; /* set ESSID to ON for Wireless Extensions */ |
| 750 | /* if it is to big, trunk it */ | 750 | /* if it is to big, trunk it */ |
| 751 | dwrq->length = min(IW_ESSID_MAX_SIZE, essid->length); | 751 | dwrq->length = min((u8)IW_ESSID_MAX_SIZE, essid->length); |
| 752 | } else { | 752 | } else { |
| 753 | dwrq->flags = 0; | 753 | dwrq->flags = 0; |
| 754 | dwrq->length = 0; | 754 | dwrq->length = 0; |
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c index 9e0229f7e25f..f46e8438e0d2 100644 --- a/drivers/parisc/ccio-dma.c +++ b/drivers/parisc/ccio-dma.c | |||
| @@ -1423,7 +1423,7 @@ static void __init ccio_init_resources(struct ioc *ioc) | |||
| 1423 | struct resource *res = ioc->mmio_region; | 1423 | struct resource *res = ioc->mmio_region; |
| 1424 | char *name = kmalloc(14, GFP_KERNEL); | 1424 | char *name = kmalloc(14, GFP_KERNEL); |
| 1425 | 1425 | ||
| 1426 | sprintf(name, "GSC Bus [%d/]", ioc->hw_path); | 1426 | snprintf(name, 14, "GSC Bus [%d/]", ioc->hw_path); |
| 1427 | 1427 | ||
| 1428 | ccio_init_resource(res, name, &ioc->ioc_regs->io_io_low); | 1428 | ccio_init_resource(res, name, &ioc->ioc_regs->io_io_low); |
| 1429 | ccio_init_resource(res + 1, name, &ioc->ioc_regs->io_io_low_hv); | 1429 | ccio_init_resource(res + 1, name, &ioc->ioc_regs->io_io_low_hv); |
| @@ -1557,12 +1557,11 @@ static int ccio_probe(struct parisc_device *dev) | |||
| 1557 | int i; | 1557 | int i; |
| 1558 | struct ioc *ioc, **ioc_p = &ioc_list; | 1558 | struct ioc *ioc, **ioc_p = &ioc_list; |
| 1559 | 1559 | ||
| 1560 | ioc = kmalloc(sizeof(struct ioc), GFP_KERNEL); | 1560 | ioc = kzalloc(sizeof(struct ioc), GFP_KERNEL); |
| 1561 | if (ioc == NULL) { | 1561 | if (ioc == NULL) { |
| 1562 | printk(KERN_ERR MODULE_NAME ": memory allocation failure\n"); | 1562 | printk(KERN_ERR MODULE_NAME ": memory allocation failure\n"); |
| 1563 | return 1; | 1563 | return 1; |
| 1564 | } | 1564 | } |
| 1565 | memset(ioc, 0, sizeof(struct ioc)); | ||
| 1566 | 1565 | ||
| 1567 | ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn"; | 1566 | ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn"; |
| 1568 | 1567 | ||
| @@ -1578,7 +1577,7 @@ static int ccio_probe(struct parisc_device *dev) | |||
| 1578 | ccio_ioc_init(ioc); | 1577 | ccio_ioc_init(ioc); |
| 1579 | ccio_init_resources(ioc); | 1578 | ccio_init_resources(ioc); |
| 1580 | hppa_dma_ops = &ccio_ops; | 1579 | hppa_dma_ops = &ccio_ops; |
| 1581 | dev->dev.platform_data = kmalloc(sizeof(struct pci_hba_data), GFP_KERNEL); | 1580 | dev->dev.platform_data = kzalloc(sizeof(struct pci_hba_data), GFP_KERNEL); |
| 1582 | 1581 | ||
| 1583 | /* if this fails, no I/O cards will work, so may as well bug */ | 1582 | /* if this fails, no I/O cards will work, so may as well bug */ |
| 1584 | BUG_ON(dev->dev.platform_data == NULL); | 1583 | BUG_ON(dev->dev.platform_data == NULL); |
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index 216d1d859326..3d1a7f98c676 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c | |||
| @@ -989,14 +989,12 @@ static int __init dino_probe(struct parisc_device *dev) | |||
| 989 | */ | 989 | */ |
| 990 | } | 990 | } |
| 991 | 991 | ||
| 992 | dino_dev = kmalloc(sizeof(struct dino_device), GFP_KERNEL); | 992 | dino_dev = kzalloc(sizeof(struct dino_device), GFP_KERNEL); |
| 993 | if (!dino_dev) { | 993 | if (!dino_dev) { |
| 994 | printk("dino_init_chip - couldn't alloc dino_device\n"); | 994 | printk("dino_init_chip - couldn't alloc dino_device\n"); |
| 995 | return 1; | 995 | return 1; |
| 996 | } | 996 | } |
| 997 | 997 | ||
| 998 | memset(dino_dev, 0, sizeof(struct dino_device)); | ||
| 999 | |||
| 1000 | dino_dev->hba.dev = dev; | 998 | dino_dev->hba.dev = dev; |
| 1001 | dino_dev->hba.base_addr = ioremap(hpa, 4096); | 999 | dino_dev->hba.base_addr = ioremap(hpa, 4096); |
| 1002 | dino_dev->hba.lmmio_space_offset = 0; /* CPU addrs == bus addrs */ | 1000 | dino_dev->hba.lmmio_space_offset = 0; /* CPU addrs == bus addrs */ |
diff --git a/drivers/parisc/hppb.c b/drivers/parisc/hppb.c index 5edf93f80757..07dc2b6d4e93 100644 --- a/drivers/parisc/hppb.c +++ b/drivers/parisc/hppb.c | |||
| @@ -60,12 +60,11 @@ static int hppb_probe(struct parisc_device *dev) | |||
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | if(card->hpa) { | 62 | if(card->hpa) { |
| 63 | card->next = kmalloc(sizeof(struct hppb_card), GFP_KERNEL); | 63 | card->next = kzalloc(sizeof(struct hppb_card), GFP_KERNEL); |
| 64 | if(!card->next) { | 64 | if(!card->next) { |
| 65 | printk(KERN_ERR "HP-PB: Unable to allocate memory.\n"); | 65 | printk(KERN_ERR "HP-PB: Unable to allocate memory.\n"); |
| 66 | return 1; | 66 | return 1; |
| 67 | } | 67 | } |
| 68 | memset(card->next, '\0', sizeof(struct hppb_card)); | ||
| 69 | card = card->next; | 68 | card = card->next; |
| 70 | } | 69 | } |
| 71 | printk(KERN_INFO "Found GeckoBoa at 0x%lx\n", dev->hpa.start); | 70 | printk(KERN_INFO "Found GeckoBoa at 0x%lx\n", dev->hpa.start); |
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c index 19657efa8dc3..8d7a36392eb8 100644 --- a/drivers/parisc/iosapic.c +++ b/drivers/parisc/iosapic.c | |||
| @@ -873,28 +873,24 @@ void *iosapic_register(unsigned long hpa) | |||
| 873 | return NULL; | 873 | return NULL; |
| 874 | } | 874 | } |
| 875 | 875 | ||
| 876 | isi = (struct iosapic_info *)kmalloc(sizeof(struct iosapic_info), GFP_KERNEL); | 876 | isi = (struct iosapic_info *)kzalloc(sizeof(struct iosapic_info), GFP_KERNEL); |
| 877 | if (!isi) { | 877 | if (!isi) { |
| 878 | BUG(); | 878 | BUG(); |
| 879 | return NULL; | 879 | return NULL; |
| 880 | } | 880 | } |
| 881 | 881 | ||
| 882 | memset(isi, 0, sizeof(struct iosapic_info)); | ||
| 883 | |||
| 884 | isi->addr = ioremap(hpa, 4096); | 882 | isi->addr = ioremap(hpa, 4096); |
| 885 | isi->isi_hpa = hpa; | 883 | isi->isi_hpa = hpa; |
| 886 | isi->isi_version = iosapic_rd_version(isi); | 884 | isi->isi_version = iosapic_rd_version(isi); |
| 887 | isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1; | 885 | isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1; |
| 888 | 886 | ||
| 889 | vip = isi->isi_vector = (struct vector_info *) | 887 | vip = isi->isi_vector = (struct vector_info *) |
| 890 | kmalloc(sizeof(struct vector_info) * isi->isi_num_vectors, GFP_KERNEL); | 888 | kzalloc(sizeof(struct vector_info) * isi->isi_num_vectors, GFP_KERNEL); |
| 891 | if (vip == NULL) { | 889 | if (vip == NULL) { |
| 892 | kfree(isi); | 890 | kfree(isi); |
| 893 | return NULL; | 891 | return NULL; |
| 894 | } | 892 | } |
| 895 | 893 | ||
| 896 | memset(vip, 0, sizeof(struct vector_info) * isi->isi_num_vectors); | ||
| 897 | |||
| 898 | for (cnt=0; cnt < isi->isi_num_vectors; cnt++, vip++) { | 894 | for (cnt=0; cnt < isi->isi_num_vectors; cnt++, vip++) { |
| 899 | vip->irqline = (unsigned char) cnt; | 895 | vip->irqline = (unsigned char) cnt; |
| 900 | vip->iosapic = isi; | 896 | vip->iosapic = isi; |
diff --git a/drivers/parisc/lasi.c b/drivers/parisc/lasi.c index 2b3ba1dcf332..cb3d28176129 100644 --- a/drivers/parisc/lasi.c +++ b/drivers/parisc/lasi.c | |||
| @@ -166,11 +166,12 @@ static void lasi_power_off(void) | |||
| 166 | int __init | 166 | int __init |
| 167 | lasi_init_chip(struct parisc_device *dev) | 167 | lasi_init_chip(struct parisc_device *dev) |
| 168 | { | 168 | { |
| 169 | extern void (*chassis_power_off)(void); | ||
| 169 | struct gsc_asic *lasi; | 170 | struct gsc_asic *lasi; |
| 170 | struct gsc_irq gsc_irq; | 171 | struct gsc_irq gsc_irq; |
| 171 | int ret; | 172 | int ret; |
| 172 | 173 | ||
| 173 | lasi = kmalloc(sizeof(*lasi), GFP_KERNEL); | 174 | lasi = kzalloc(sizeof(*lasi), GFP_KERNEL); |
| 174 | if (!lasi) | 175 | if (!lasi) |
| 175 | return -ENOMEM; | 176 | return -ENOMEM; |
| 176 | 177 | ||
| @@ -222,7 +223,7 @@ lasi_init_chip(struct parisc_device *dev) | |||
| 222 | * ensure that only the first LASI (the one controlling the power off) | 223 | * ensure that only the first LASI (the one controlling the power off) |
| 223 | * should set the HPA here */ | 224 | * should set the HPA here */ |
| 224 | lasi_power_off_hpa = lasi->hpa; | 225 | lasi_power_off_hpa = lasi->hpa; |
| 225 | pm_power_off = lasi_power_off; | 226 | chassis_power_off = lasi_power_off; |
| 226 | 227 | ||
| 227 | return ret; | 228 | return ret; |
| 228 | } | 229 | } |
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index cbae8c8963fa..e8a2a4a852f5 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c | |||
| @@ -1565,7 +1565,7 @@ lba_driver_probe(struct parisc_device *dev) | |||
| 1565 | } else if (IS_MERCURY(dev) || IS_QUICKSILVER(dev)) { | 1565 | } else if (IS_MERCURY(dev) || IS_QUICKSILVER(dev)) { |
| 1566 | func_class &= 0xff; | 1566 | func_class &= 0xff; |
| 1567 | version = kmalloc(6, GFP_KERNEL); | 1567 | version = kmalloc(6, GFP_KERNEL); |
| 1568 | sprintf(version,"TR%d.%d",(func_class >> 4),(func_class & 0xf)); | 1568 | snprintf(version, 6, "TR%d.%d",(func_class >> 4),(func_class & 0xf)); |
| 1569 | /* We could use one printk for both Elroy and Mercury, | 1569 | /* We could use one printk for both Elroy and Mercury, |
| 1570 | * but for the mask for func_class. | 1570 | * but for the mask for func_class. |
| 1571 | */ | 1571 | */ |
| @@ -1586,14 +1586,12 @@ lba_driver_probe(struct parisc_device *dev) | |||
| 1586 | ** have an IRT entry will get NULL back from iosapic code. | 1586 | ** have an IRT entry will get NULL back from iosapic code. |
| 1587 | */ | 1587 | */ |
| 1588 | 1588 | ||
| 1589 | lba_dev = kmalloc(sizeof(struct lba_device), GFP_KERNEL); | 1589 | lba_dev = kzalloc(sizeof(struct lba_device), GFP_KERNEL); |
| 1590 | if (!lba_dev) { | 1590 | if (!lba_dev) { |
| 1591 | printk(KERN_ERR "lba_init_chip - couldn't alloc lba_device\n"); | 1591 | printk(KERN_ERR "lba_init_chip - couldn't alloc lba_device\n"); |
| 1592 | return(1); | 1592 | return(1); |
| 1593 | } | 1593 | } |
| 1594 | 1594 | ||
| 1595 | memset(lba_dev, 0, sizeof(struct lba_device)); | ||
| 1596 | |||
| 1597 | 1595 | ||
| 1598 | /* ---------- First : initialize data we already have --------- */ | 1596 | /* ---------- First : initialize data we already have --------- */ |
| 1599 | 1597 | ||
diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c index 42a3c54e8e6c..a28e17898fbd 100644 --- a/drivers/parisc/pdc_stable.c +++ b/drivers/parisc/pdc_stable.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Interfaces to retrieve and set PDC Stable options (firmware) | 2 | * Interfaces to retrieve and set PDC Stable options (firmware) |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org> | 4 | * Copyright (C) 2005-2006 Thibaut VARENE <varenet@parisc-linux.org> |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
| @@ -26,11 +26,19 @@ | |||
| 26 | * | 26 | * |
| 27 | * Since locations between 96 and 192 are the various paths, most (if not | 27 | * Since locations between 96 and 192 are the various paths, most (if not |
| 28 | * all) PA-RISC machines should have them. Anyway, for safety reasons, the | 28 | * all) PA-RISC machines should have them. Anyway, for safety reasons, the |
| 29 | * following code can deal with only 96 bytes of Stable Storage, and all | 29 | * following code can deal with just 96 bytes of Stable Storage, and all |
| 30 | * sizes between 96 and 192 bytes (provided they are multiple of struct | 30 | * sizes between 96 and 192 bytes (provided they are multiple of struct |
| 31 | * device_path size, eg: 128, 160 and 192) to provide full information. | 31 | * device_path size, eg: 128, 160 and 192) to provide full information. |
| 32 | * The code makes no use of data above 192 bytes. One last word: there's one | 32 | * The code makes no use of data above 192 bytes. One last word: there's one |
| 33 | * path we can always count on: the primary path. | 33 | * path we can always count on: the primary path. |
| 34 | * | ||
| 35 | * The current policy wrt file permissions is: | ||
| 36 | * - write: root only | ||
| 37 | * - read: (reading triggers PDC calls) ? root only : everyone | ||
| 38 | * The rationale is that PDC calls could hog (DoS) the machine. | ||
| 39 | * | ||
| 40 | * TODO: | ||
| 41 | * - timer/fastsize write calls | ||
| 34 | */ | 42 | */ |
| 35 | 43 | ||
| 36 | #undef PDCS_DEBUG | 44 | #undef PDCS_DEBUG |
| @@ -50,13 +58,15 @@ | |||
| 50 | #include <linux/kobject.h> | 58 | #include <linux/kobject.h> |
| 51 | #include <linux/device.h> | 59 | #include <linux/device.h> |
| 52 | #include <linux/errno.h> | 60 | #include <linux/errno.h> |
| 61 | #include <linux/spinlock.h> | ||
| 53 | 62 | ||
| 54 | #include <asm/pdc.h> | 63 | #include <asm/pdc.h> |
| 55 | #include <asm/page.h> | 64 | #include <asm/page.h> |
| 56 | #include <asm/uaccess.h> | 65 | #include <asm/uaccess.h> |
| 57 | #include <asm/hardware.h> | 66 | #include <asm/hardware.h> |
| 58 | 67 | ||
| 59 | #define PDCS_VERSION "0.10" | 68 | #define PDCS_VERSION "0.22" |
| 69 | #define PDCS_PREFIX "PDC Stable Storage" | ||
| 60 | 70 | ||
| 61 | #define PDCS_ADDR_PPRI 0x00 | 71 | #define PDCS_ADDR_PPRI 0x00 |
| 62 | #define PDCS_ADDR_OSID 0x40 | 72 | #define PDCS_ADDR_OSID 0x40 |
| @@ -70,10 +80,12 @@ MODULE_DESCRIPTION("sysfs interface to HP PDC Stable Storage data"); | |||
| 70 | MODULE_LICENSE("GPL"); | 80 | MODULE_LICENSE("GPL"); |
| 71 | MODULE_VERSION(PDCS_VERSION); | 81 | MODULE_VERSION(PDCS_VERSION); |
| 72 | 82 | ||
| 83 | /* holds Stable Storage size. Initialized once and for all, no lock needed */ | ||
| 73 | static unsigned long pdcs_size __read_mostly; | 84 | static unsigned long pdcs_size __read_mostly; |
| 74 | 85 | ||
| 75 | /* This struct defines what we need to deal with a parisc pdc path entry */ | 86 | /* This struct defines what we need to deal with a parisc pdc path entry */ |
| 76 | struct pdcspath_entry { | 87 | struct pdcspath_entry { |
| 88 | rwlock_t rw_lock; /* to protect path entry access */ | ||
| 77 | short ready; /* entry record is valid if != 0 */ | 89 | short ready; /* entry record is valid if != 0 */ |
| 78 | unsigned long addr; /* entry address in stable storage */ | 90 | unsigned long addr; /* entry address in stable storage */ |
| 79 | char *name; /* entry name */ | 91 | char *name; /* entry name */ |
| @@ -121,6 +133,8 @@ struct pdcspath_attribute paths_attr_##_name = { \ | |||
| 121 | * content of the stable storage WRT various paths in these structs. We read | 133 | * content of the stable storage WRT various paths in these structs. We read |
| 122 | * these structs when reading the files, and we will write to these structs when | 134 | * these structs when reading the files, and we will write to these structs when |
| 123 | * writing to the files, and only then write them back to the Stable Storage. | 135 | * writing to the files, and only then write them back to the Stable Storage. |
| 136 | * | ||
| 137 | * This function expects to be called with @entry->rw_lock write-hold. | ||
| 124 | */ | 138 | */ |
| 125 | static int | 139 | static int |
| 126 | pdcspath_fetch(struct pdcspath_entry *entry) | 140 | pdcspath_fetch(struct pdcspath_entry *entry) |
| @@ -160,14 +174,15 @@ pdcspath_fetch(struct pdcspath_entry *entry) | |||
| 160 | * pointer, from which it'll find out the corresponding hardware path. | 174 | * pointer, from which it'll find out the corresponding hardware path. |
| 161 | * For now we do not handle the case where there's an error in writing to the | 175 | * For now we do not handle the case where there's an error in writing to the |
| 162 | * Stable Storage area, so you'd better not mess up the data :P | 176 | * Stable Storage area, so you'd better not mess up the data :P |
| 177 | * | ||
| 178 | * This function expects to be called with @entry->rw_lock write-hold. | ||
| 163 | */ | 179 | */ |
| 164 | static int | 180 | static void |
| 165 | pdcspath_store(struct pdcspath_entry *entry) | 181 | pdcspath_store(struct pdcspath_entry *entry) |
| 166 | { | 182 | { |
| 167 | struct device_path *devpath; | 183 | struct device_path *devpath; |
| 168 | 184 | ||
| 169 | if (!entry) | 185 | BUG_ON(!entry); |
| 170 | return -EINVAL; | ||
| 171 | 186 | ||
| 172 | devpath = &entry->devpath; | 187 | devpath = &entry->devpath; |
| 173 | 188 | ||
| @@ -176,10 +191,8 @@ pdcspath_store(struct pdcspath_entry *entry) | |||
| 176 | First case, we don't have a preset hwpath... */ | 191 | First case, we don't have a preset hwpath... */ |
| 177 | if (!entry->ready) { | 192 | if (!entry->ready) { |
| 178 | /* ...but we have a device, map it */ | 193 | /* ...but we have a device, map it */ |
| 179 | if (entry->dev) | 194 | BUG_ON(!entry->dev); |
| 180 | device_to_hwpath(entry->dev, (struct hardware_path *)devpath); | 195 | device_to_hwpath(entry->dev, (struct hardware_path *)devpath); |
| 181 | else | ||
| 182 | return -EINVAL; | ||
| 183 | } | 196 | } |
| 184 | /* else, we expect the provided hwpath to be valid. */ | 197 | /* else, we expect the provided hwpath to be valid. */ |
| 185 | 198 | ||
| @@ -191,15 +204,13 @@ pdcspath_store(struct pdcspath_entry *entry) | |||
| 191 | printk(KERN_ERR "%s: an error occured when writing to PDC.\n" | 204 | printk(KERN_ERR "%s: an error occured when writing to PDC.\n" |
| 192 | "It is likely that the Stable Storage data has been corrupted.\n" | 205 | "It is likely that the Stable Storage data has been corrupted.\n" |
| 193 | "Please check it carefully upon next reboot.\n", __func__); | 206 | "Please check it carefully upon next reboot.\n", __func__); |
| 194 | return -EIO; | 207 | WARN_ON(1); |
| 195 | } | 208 | } |
| 196 | 209 | ||
| 197 | /* kobject is already registered */ | 210 | /* kobject is already registered */ |
| 198 | entry->ready = 2; | 211 | entry->ready = 2; |
| 199 | 212 | ||
| 200 | DPRINTK("%s: device: 0x%p\n", __func__, entry->dev); | 213 | DPRINTK("%s: device: 0x%p\n", __func__, entry->dev); |
| 201 | |||
| 202 | return 0; | ||
| 203 | } | 214 | } |
| 204 | 215 | ||
| 205 | /** | 216 | /** |
| @@ -214,14 +225,17 @@ pdcspath_hwpath_read(struct pdcspath_entry *entry, char *buf) | |||
| 214 | { | 225 | { |
| 215 | char *out = buf; | 226 | char *out = buf; |
| 216 | struct device_path *devpath; | 227 | struct device_path *devpath; |
| 217 | unsigned short i; | 228 | short i; |
| 218 | 229 | ||
| 219 | if (!entry || !buf) | 230 | if (!entry || !buf) |
| 220 | return -EINVAL; | 231 | return -EINVAL; |
| 221 | 232 | ||
| 233 | read_lock(&entry->rw_lock); | ||
| 222 | devpath = &entry->devpath; | 234 | devpath = &entry->devpath; |
| 235 | i = entry->ready; | ||
| 236 | read_unlock(&entry->rw_lock); | ||
| 223 | 237 | ||
| 224 | if (!entry->ready) | 238 | if (!i) /* entry is not ready */ |
| 225 | return -ENODATA; | 239 | return -ENODATA; |
| 226 | 240 | ||
| 227 | for (i = 0; i < 6; i++) { | 241 | for (i = 0; i < 6; i++) { |
| @@ -242,7 +256,7 @@ pdcspath_hwpath_read(struct pdcspath_entry *entry, char *buf) | |||
| 242 | * | 256 | * |
| 243 | * We will call this function to change the current hardware path. | 257 | * We will call this function to change the current hardware path. |
| 244 | * Hardware paths are to be given '/'-delimited, without brackets. | 258 | * Hardware paths are to be given '/'-delimited, without brackets. |
| 245 | * We take care to make sure that the provided path actually maps to an existing | 259 | * We make sure that the provided path actually maps to an existing |
| 246 | * device, BUT nothing would prevent some foolish user to set the path to some | 260 | * device, BUT nothing would prevent some foolish user to set the path to some |
| 247 | * PCI bridge or even a CPU... | 261 | * PCI bridge or even a CPU... |
| 248 | * A better work around would be to make sure we are at the end of a device tree | 262 | * A better work around would be to make sure we are at the end of a device tree |
| @@ -298,17 +312,19 @@ pdcspath_hwpath_write(struct pdcspath_entry *entry, const char *buf, size_t coun | |||
| 298 | } | 312 | } |
| 299 | 313 | ||
| 300 | /* So far so good, let's get in deep */ | 314 | /* So far so good, let's get in deep */ |
| 315 | write_lock(&entry->rw_lock); | ||
| 301 | entry->ready = 0; | 316 | entry->ready = 0; |
| 302 | entry->dev = dev; | 317 | entry->dev = dev; |
| 303 | 318 | ||
| 304 | /* Now, dive in. Write back to the hardware */ | 319 | /* Now, dive in. Write back to the hardware */ |
| 305 | WARN_ON(pdcspath_store(entry)); /* this warn should *NEVER* happen */ | 320 | pdcspath_store(entry); |
| 306 | 321 | ||
| 307 | /* Update the symlink to the real device */ | 322 | /* Update the symlink to the real device */ |
| 308 | sysfs_remove_link(&entry->kobj, "device"); | 323 | sysfs_remove_link(&entry->kobj, "device"); |
| 309 | sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device"); | 324 | sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device"); |
| 325 | write_unlock(&entry->rw_lock); | ||
| 310 | 326 | ||
| 311 | printk(KERN_INFO "PDC Stable Storage: changed \"%s\" path to \"%s\"\n", | 327 | printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" path to \"%s\"\n", |
| 312 | entry->name, buf); | 328 | entry->name, buf); |
| 313 | 329 | ||
| 314 | return count; | 330 | return count; |
| @@ -326,14 +342,17 @@ pdcspath_layer_read(struct pdcspath_entry *entry, char *buf) | |||
| 326 | { | 342 | { |
| 327 | char *out = buf; | 343 | char *out = buf; |
| 328 | struct device_path *devpath; | 344 | struct device_path *devpath; |
| 329 | unsigned short i; | 345 | short i; |
| 330 | 346 | ||
| 331 | if (!entry || !buf) | 347 | if (!entry || !buf) |
| 332 | return -EINVAL; | 348 | return -EINVAL; |
| 333 | 349 | ||
| 350 | read_lock(&entry->rw_lock); | ||
| 334 | devpath = &entry->devpath; | 351 | devpath = &entry->devpath; |
| 352 | i = entry->ready; | ||
| 353 | read_unlock(&entry->rw_lock); | ||
| 335 | 354 | ||
| 336 | if (!entry->ready) | 355 | if (!i) /* entry is not ready */ |
| 337 | return -ENODATA; | 356 | return -ENODATA; |
| 338 | 357 | ||
| 339 | for (i = 0; devpath->layers[i] && (likely(i < 6)); i++) | 358 | for (i = 0; devpath->layers[i] && (likely(i < 6)); i++) |
| @@ -388,15 +407,17 @@ pdcspath_layer_write(struct pdcspath_entry *entry, const char *buf, size_t count | |||
| 388 | } | 407 | } |
| 389 | 408 | ||
| 390 | /* So far so good, let's get in deep */ | 409 | /* So far so good, let's get in deep */ |
| 410 | write_lock(&entry->rw_lock); | ||
| 391 | 411 | ||
| 392 | /* First, overwrite the current layers with the new ones, not touching | 412 | /* First, overwrite the current layers with the new ones, not touching |
| 393 | the hardware path. */ | 413 | the hardware path. */ |
| 394 | memcpy(&entry->devpath.layers, &layers, sizeof(layers)); | 414 | memcpy(&entry->devpath.layers, &layers, sizeof(layers)); |
| 395 | 415 | ||
| 396 | /* Now, dive in. Write back to the hardware */ | 416 | /* Now, dive in. Write back to the hardware */ |
| 397 | WARN_ON(pdcspath_store(entry)); /* this warn should *NEVER* happen */ | 417 | pdcspath_store(entry); |
| 418 | write_unlock(&entry->rw_lock); | ||
| 398 | 419 | ||
| 399 | printk(KERN_INFO "PDC Stable Storage: changed \"%s\" layers to \"%s\"\n", | 420 | printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" layers to \"%s\"\n", |
| 400 | entry->name, buf); | 421 | entry->name, buf); |
| 401 | 422 | ||
| 402 | return count; | 423 | return count; |
| @@ -415,9 +436,6 @@ pdcspath_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) | |||
| 415 | struct pdcspath_attribute *pdcs_attr = to_pdcspath_attribute(attr); | 436 | struct pdcspath_attribute *pdcs_attr = to_pdcspath_attribute(attr); |
| 416 | ssize_t ret = 0; | 437 | ssize_t ret = 0; |
| 417 | 438 | ||
| 418 | if (!capable(CAP_SYS_ADMIN)) | ||
| 419 | return -EACCES; | ||
| 420 | |||
| 421 | if (pdcs_attr->show) | 439 | if (pdcs_attr->show) |
| 422 | ret = pdcs_attr->show(entry, buf); | 440 | ret = pdcs_attr->show(entry, buf); |
| 423 | 441 | ||
| @@ -454,8 +472,8 @@ static struct sysfs_ops pdcspath_attr_ops = { | |||
| 454 | }; | 472 | }; |
| 455 | 473 | ||
| 456 | /* These are the two attributes of any PDC path. */ | 474 | /* These are the two attributes of any PDC path. */ |
| 457 | static PATHS_ATTR(hwpath, 0600, pdcspath_hwpath_read, pdcspath_hwpath_write); | 475 | static PATHS_ATTR(hwpath, 0644, pdcspath_hwpath_read, pdcspath_hwpath_write); |
| 458 | static PATHS_ATTR(layer, 0600, pdcspath_layer_read, pdcspath_layer_write); | 476 | static PATHS_ATTR(layer, 0644, pdcspath_layer_read, pdcspath_layer_write); |
| 459 | 477 | ||
| 460 | static struct attribute *paths_subsys_attrs[] = { | 478 | static struct attribute *paths_subsys_attrs[] = { |
| 461 | &paths_attr_hwpath.attr, | 479 | &paths_attr_hwpath.attr, |
| @@ -484,36 +502,119 @@ static struct pdcspath_entry *pdcspath_entries[] = { | |||
| 484 | NULL, | 502 | NULL, |
| 485 | }; | 503 | }; |
| 486 | 504 | ||
| 505 | |||
| 506 | /* For more insight of what's going on here, refer to PDC Procedures doc, | ||
| 507 | * Section PDC_STABLE */ | ||
| 508 | |||
| 487 | /** | 509 | /** |
| 488 | * pdcs_info_read - Pretty printing of the remaining useful data. | 510 | * pdcs_size_read - Stable Storage size output. |
| 489 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | 511 | * @entry: An allocated and populated subsytem struct. We don't use it tho. |
| 490 | * @buf: The output buffer to write to. | 512 | * @buf: The output buffer to write to. |
| 491 | * | ||
| 492 | * We will call this function to format the output of the 'info' attribute file. | ||
| 493 | * Please refer to PDC Procedures documentation, section PDC_STABLE to get a | ||
| 494 | * better insight of what we're doing here. | ||
| 495 | */ | 513 | */ |
| 496 | static ssize_t | 514 | static ssize_t |
| 497 | pdcs_info_read(struct subsystem *entry, char *buf) | 515 | pdcs_size_read(struct subsystem *entry, char *buf) |
| 498 | { | 516 | { |
| 499 | char *out = buf; | 517 | char *out = buf; |
| 500 | __u32 result; | ||
| 501 | struct device_path devpath; | ||
| 502 | char *tmpstr = NULL; | ||
| 503 | 518 | ||
| 504 | if (!entry || !buf) | 519 | if (!entry || !buf) |
| 505 | return -EINVAL; | 520 | return -EINVAL; |
| 506 | 521 | ||
| 507 | /* show the size of the stable storage */ | 522 | /* show the size of the stable storage */ |
| 508 | out += sprintf(out, "Stable Storage size: %ld bytes\n", pdcs_size); | 523 | out += sprintf(out, "%ld\n", pdcs_size); |
| 509 | 524 | ||
| 510 | /* deal with flags */ | 525 | return out - buf; |
| 511 | if (pdc_stable_read(PDCS_ADDR_PPRI, &devpath, sizeof(devpath)) != PDC_OK) | 526 | } |
| 512 | return -EIO; | 527 | |
| 528 | /** | ||
| 529 | * pdcs_auto_read - Stable Storage autoboot/search flag output. | ||
| 530 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
| 531 | * @buf: The output buffer to write to. | ||
| 532 | * @knob: The PF_AUTOBOOT or PF_AUTOSEARCH flag | ||
| 533 | */ | ||
| 534 | static ssize_t | ||
| 535 | pdcs_auto_read(struct subsystem *entry, char *buf, int knob) | ||
| 536 | { | ||
| 537 | char *out = buf; | ||
| 538 | struct pdcspath_entry *pathentry; | ||
| 513 | 539 | ||
| 514 | out += sprintf(out, "Autoboot: %s\n", (devpath.flags & PF_AUTOBOOT) ? "On" : "Off"); | 540 | if (!entry || !buf) |
| 515 | out += sprintf(out, "Autosearch: %s\n", (devpath.flags & PF_AUTOSEARCH) ? "On" : "Off"); | 541 | return -EINVAL; |
| 516 | out += sprintf(out, "Timer: %u s\n", (devpath.flags & PF_TIMER) ? (1 << (devpath.flags & PF_TIMER)) : 0); | 542 | |
| 543 | /* Current flags are stored in primary boot path entry */ | ||
| 544 | pathentry = &pdcspath_entry_primary; | ||
| 545 | |||
| 546 | read_lock(&pathentry->rw_lock); | ||
| 547 | out += sprintf(out, "%s\n", (pathentry->devpath.flags & knob) ? | ||
| 548 | "On" : "Off"); | ||
| 549 | read_unlock(&pathentry->rw_lock); | ||
| 550 | |||
| 551 | return out - buf; | ||
| 552 | } | ||
| 553 | |||
| 554 | /** | ||
| 555 | * pdcs_autoboot_read - Stable Storage autoboot flag output. | ||
| 556 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
| 557 | * @buf: The output buffer to write to. | ||
| 558 | */ | ||
| 559 | static inline ssize_t | ||
| 560 | pdcs_autoboot_read(struct subsystem *entry, char *buf) | ||
| 561 | { | ||
| 562 | return pdcs_auto_read(entry, buf, PF_AUTOBOOT); | ||
| 563 | } | ||
| 564 | |||
| 565 | /** | ||
| 566 | * pdcs_autosearch_read - Stable Storage autoboot flag output. | ||
| 567 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
| 568 | * @buf: The output buffer to write to. | ||
| 569 | */ | ||
| 570 | static inline ssize_t | ||
| 571 | pdcs_autosearch_read(struct subsystem *entry, char *buf) | ||
| 572 | { | ||
| 573 | return pdcs_auto_read(entry, buf, PF_AUTOSEARCH); | ||
| 574 | } | ||
| 575 | |||
| 576 | /** | ||
| 577 | * pdcs_timer_read - Stable Storage timer count output (in seconds). | ||
| 578 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
| 579 | * @buf: The output buffer to write to. | ||
| 580 | * | ||
| 581 | * The value of the timer field correponds to a number of seconds in powers of 2. | ||
| 582 | */ | ||
| 583 | static ssize_t | ||
| 584 | pdcs_timer_read(struct subsystem *entry, char *buf) | ||
| 585 | { | ||
| 586 | char *out = buf; | ||
| 587 | struct pdcspath_entry *pathentry; | ||
| 588 | |||
| 589 | if (!entry || !buf) | ||
| 590 | return -EINVAL; | ||
| 591 | |||
| 592 | /* Current flags are stored in primary boot path entry */ | ||
| 593 | pathentry = &pdcspath_entry_primary; | ||
| 594 | |||
| 595 | /* print the timer value in seconds */ | ||
| 596 | read_lock(&pathentry->rw_lock); | ||
| 597 | out += sprintf(out, "%u\n", (pathentry->devpath.flags & PF_TIMER) ? | ||
| 598 | (1 << (pathentry->devpath.flags & PF_TIMER)) : 0); | ||
| 599 | read_unlock(&pathentry->rw_lock); | ||
| 600 | |||
| 601 | return out - buf; | ||
| 602 | } | ||
| 603 | |||
| 604 | /** | ||
| 605 | * pdcs_osid_read - Stable Storage OS ID register output. | ||
| 606 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
| 607 | * @buf: The output buffer to write to. | ||
| 608 | */ | ||
| 609 | static ssize_t | ||
| 610 | pdcs_osid_read(struct subsystem *entry, char *buf) | ||
| 611 | { | ||
| 612 | char *out = buf; | ||
| 613 | __u32 result; | ||
| 614 | char *tmpstr = NULL; | ||
| 615 | |||
| 616 | if (!entry || !buf) | ||
| 617 | return -EINVAL; | ||
| 517 | 618 | ||
| 518 | /* get OSID */ | 619 | /* get OSID */ |
| 519 | if (pdc_stable_read(PDCS_ADDR_OSID, &result, sizeof(result)) != PDC_OK) | 620 | if (pdc_stable_read(PDCS_ADDR_OSID, &result, sizeof(result)) != PDC_OK) |
| @@ -529,13 +630,31 @@ pdcs_info_read(struct subsystem *entry, char *buf) | |||
| 529 | case 0x0005: tmpstr = "Novell Netware dependent data"; break; | 630 | case 0x0005: tmpstr = "Novell Netware dependent data"; break; |
| 530 | default: tmpstr = "Unknown"; break; | 631 | default: tmpstr = "Unknown"; break; |
| 531 | } | 632 | } |
| 532 | out += sprintf(out, "OS ID: %s (0x%.4x)\n", tmpstr, (result >> 16)); | 633 | out += sprintf(out, "%s (0x%.4x)\n", tmpstr, (result >> 16)); |
| 634 | |||
| 635 | return out - buf; | ||
| 636 | } | ||
| 637 | |||
| 638 | /** | ||
| 639 | * pdcs_fastsize_read - Stable Storage FastSize register output. | ||
| 640 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
| 641 | * @buf: The output buffer to write to. | ||
| 642 | * | ||
| 643 | * This register holds the amount of system RAM to be tested during boot sequence. | ||
| 644 | */ | ||
| 645 | static ssize_t | ||
| 646 | pdcs_fastsize_read(struct subsystem *entry, char *buf) | ||
| 647 | { | ||
| 648 | char *out = buf; | ||
| 649 | __u32 result; | ||
| 650 | |||
| 651 | if (!entry || !buf) | ||
| 652 | return -EINVAL; | ||
| 533 | 653 | ||
| 534 | /* get fast-size */ | 654 | /* get fast-size */ |
| 535 | if (pdc_stable_read(PDCS_ADDR_FSIZ, &result, sizeof(result)) != PDC_OK) | 655 | if (pdc_stable_read(PDCS_ADDR_FSIZ, &result, sizeof(result)) != PDC_OK) |
| 536 | return -EIO; | 656 | return -EIO; |
| 537 | 657 | ||
| 538 | out += sprintf(out, "Memory tested: "); | ||
| 539 | if ((result & 0x0F) < 0x0E) | 658 | if ((result & 0x0F) < 0x0E) |
| 540 | out += sprintf(out, "%d kB", (1<<(result & 0x0F))*256); | 659 | out += sprintf(out, "%d kB", (1<<(result & 0x0F))*256); |
| 541 | else | 660 | else |
| @@ -546,22 +665,18 @@ pdcs_info_read(struct subsystem *entry, char *buf) | |||
| 546 | } | 665 | } |
| 547 | 666 | ||
| 548 | /** | 667 | /** |
| 549 | * pdcs_info_write - This function handles boot flag modifying. | 668 | * pdcs_auto_write - This function handles autoboot/search flag modifying. |
| 550 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | 669 | * @entry: An allocated and populated subsytem struct. We don't use it tho. |
| 551 | * @buf: The input buffer to read from. | 670 | * @buf: The input buffer to read from. |
| 552 | * @count: The number of bytes to be read. | 671 | * @count: The number of bytes to be read. |
| 672 | * @knob: The PF_AUTOBOOT or PF_AUTOSEARCH flag | ||
| 553 | * | 673 | * |
| 554 | * We will call this function to change the current boot flags. | 674 | * We will call this function to change the current autoboot flag. |
| 555 | * We expect a precise syntax: | 675 | * We expect a precise syntax: |
| 556 | * \"n n\" (n == 0 or 1) to toggle respectively AutoBoot and AutoSearch | 676 | * \"n\" (n == 0 or 1) to toggle AutoBoot Off or On |
| 557 | * | ||
| 558 | * As of now there is no incentive on my side to provide more "knobs" to that | ||
| 559 | * interface, since modifying the rest of the data is pretty meaningless when | ||
| 560 | * the machine is running and for the expected use of that facility, such as | ||
| 561 | * PALO setting up the boot disk when installing a Linux distribution... | ||
| 562 | */ | 677 | */ |
| 563 | static ssize_t | 678 | static ssize_t |
| 564 | pdcs_info_write(struct subsystem *entry, const char *buf, size_t count) | 679 | pdcs_auto_write(struct subsystem *entry, const char *buf, size_t count, int knob) |
| 565 | { | 680 | { |
| 566 | struct pdcspath_entry *pathentry; | 681 | struct pdcspath_entry *pathentry; |
| 567 | unsigned char flags; | 682 | unsigned char flags; |
| @@ -582,7 +697,9 @@ pdcs_info_write(struct subsystem *entry, const char *buf, size_t count) | |||
| 582 | pathentry = &pdcspath_entry_primary; | 697 | pathentry = &pdcspath_entry_primary; |
| 583 | 698 | ||
| 584 | /* Be nice to the existing flag record */ | 699 | /* Be nice to the existing flag record */ |
| 700 | read_lock(&pathentry->rw_lock); | ||
| 585 | flags = pathentry->devpath.flags; | 701 | flags = pathentry->devpath.flags; |
| 702 | read_unlock(&pathentry->rw_lock); | ||
| 586 | 703 | ||
| 587 | DPRINTK("%s: flags before: 0x%X\n", __func__, flags); | 704 | DPRINTK("%s: flags before: 0x%X\n", __func__, flags); |
| 588 | 705 | ||
| @@ -595,50 +712,85 @@ pdcs_info_write(struct subsystem *entry, const char *buf, size_t count) | |||
| 595 | if ((c != 0) && (c != 1)) | 712 | if ((c != 0) && (c != 1)) |
| 596 | goto parse_error; | 713 | goto parse_error; |
| 597 | if (c == 0) | 714 | if (c == 0) |
| 598 | flags &= ~PF_AUTOBOOT; | 715 | flags &= ~knob; |
| 599 | else | 716 | else |
| 600 | flags |= PF_AUTOBOOT; | 717 | flags |= knob; |
| 601 | |||
| 602 | if (*temp++ != ' ') | ||
| 603 | goto parse_error; | ||
| 604 | |||
| 605 | c = *temp++ - '0'; | ||
| 606 | if ((c != 0) && (c != 1)) | ||
| 607 | goto parse_error; | ||
| 608 | if (c == 0) | ||
| 609 | flags &= ~PF_AUTOSEARCH; | ||
| 610 | else | ||
| 611 | flags |= PF_AUTOSEARCH; | ||
| 612 | 718 | ||
| 613 | DPRINTK("%s: flags after: 0x%X\n", __func__, flags); | 719 | DPRINTK("%s: flags after: 0x%X\n", __func__, flags); |
| 614 | 720 | ||
| 615 | /* So far so good, let's get in deep */ | 721 | /* So far so good, let's get in deep */ |
| 722 | write_lock(&pathentry->rw_lock); | ||
| 616 | 723 | ||
| 617 | /* Change the path entry flags first */ | 724 | /* Change the path entry flags first */ |
| 618 | pathentry->devpath.flags = flags; | 725 | pathentry->devpath.flags = flags; |
| 619 | 726 | ||
| 620 | /* Now, dive in. Write back to the hardware */ | 727 | /* Now, dive in. Write back to the hardware */ |
| 621 | WARN_ON(pdcspath_store(pathentry)); /* this warn should *NEVER* happen */ | 728 | pdcspath_store(pathentry); |
| 729 | write_unlock(&pathentry->rw_lock); | ||
| 622 | 730 | ||
| 623 | printk(KERN_INFO "PDC Stable Storage: changed flags to \"%s\"\n", buf); | 731 | printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" to \"%s\"\n", |
| 732 | (knob & PF_AUTOBOOT) ? "autoboot" : "autosearch", | ||
| 733 | (flags & knob) ? "On" : "Off"); | ||
| 624 | 734 | ||
| 625 | return count; | 735 | return count; |
| 626 | 736 | ||
| 627 | parse_error: | 737 | parse_error: |
| 628 | printk(KERN_WARNING "%s: Parse error: expect \"n n\" (n == 0 or 1) for AB and AS\n", __func__); | 738 | printk(KERN_WARNING "%s: Parse error: expect \"n\" (n == 0 or 1)\n", __func__); |
| 629 | return -EINVAL; | 739 | return -EINVAL; |
| 630 | } | 740 | } |
| 631 | 741 | ||
| 632 | /* The last attribute (the 'root' one actually) with all remaining data. */ | 742 | /** |
| 633 | static PDCS_ATTR(info, 0600, pdcs_info_read, pdcs_info_write); | 743 | * pdcs_autoboot_write - This function handles autoboot flag modifying. |
| 744 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
| 745 | * @buf: The input buffer to read from. | ||
| 746 | * @count: The number of bytes to be read. | ||
| 747 | * | ||
| 748 | * We will call this function to change the current boot flags. | ||
| 749 | * We expect a precise syntax: | ||
| 750 | * \"n\" (n == 0 or 1) to toggle AutoSearch Off or On | ||
| 751 | */ | ||
| 752 | static inline ssize_t | ||
| 753 | pdcs_autoboot_write(struct subsystem *entry, const char *buf, size_t count) | ||
| 754 | { | ||
| 755 | return pdcs_auto_write(entry, buf, count, PF_AUTOBOOT); | ||
| 756 | } | ||
| 757 | |||
| 758 | /** | ||
| 759 | * pdcs_autosearch_write - This function handles autosearch flag modifying. | ||
| 760 | * @entry: An allocated and populated subsytem struct. We don't use it tho. | ||
| 761 | * @buf: The input buffer to read from. | ||
| 762 | * @count: The number of bytes to be read. | ||
| 763 | * | ||
| 764 | * We will call this function to change the current boot flags. | ||
| 765 | * We expect a precise syntax: | ||
| 766 | * \"n\" (n == 0 or 1) to toggle AutoSearch Off or On | ||
| 767 | */ | ||
| 768 | static inline ssize_t | ||
| 769 | pdcs_autosearch_write(struct subsystem *entry, const char *buf, size_t count) | ||
| 770 | { | ||
| 771 | return pdcs_auto_write(entry, buf, count, PF_AUTOSEARCH); | ||
| 772 | } | ||
| 773 | |||
| 774 | /* The remaining attributes. */ | ||
| 775 | static PDCS_ATTR(size, 0444, pdcs_size_read, NULL); | ||
| 776 | static PDCS_ATTR(autoboot, 0644, pdcs_autoboot_read, pdcs_autoboot_write); | ||
| 777 | static PDCS_ATTR(autosearch, 0644, pdcs_autosearch_read, pdcs_autosearch_write); | ||
| 778 | static PDCS_ATTR(timer, 0444, pdcs_timer_read, NULL); | ||
| 779 | static PDCS_ATTR(osid, 0400, pdcs_osid_read, NULL); | ||
| 780 | static PDCS_ATTR(fastsize, 0400, pdcs_fastsize_read, NULL); | ||
| 634 | 781 | ||
| 635 | static struct subsys_attribute *pdcs_subsys_attrs[] = { | 782 | static struct subsys_attribute *pdcs_subsys_attrs[] = { |
| 636 | &pdcs_attr_info, | 783 | &pdcs_attr_size, |
| 637 | NULL, /* maybe more in the future? */ | 784 | &pdcs_attr_autoboot, |
| 785 | &pdcs_attr_autosearch, | ||
| 786 | &pdcs_attr_timer, | ||
| 787 | &pdcs_attr_osid, | ||
| 788 | &pdcs_attr_fastsize, | ||
| 789 | NULL, | ||
| 638 | }; | 790 | }; |
| 639 | 791 | ||
| 640 | static decl_subsys(paths, &ktype_pdcspath, NULL); | 792 | static decl_subsys(paths, &ktype_pdcspath, NULL); |
| 641 | static decl_subsys(pdc, NULL, NULL); | 793 | static decl_subsys(stable, NULL, NULL); |
| 642 | 794 | ||
| 643 | /** | 795 | /** |
| 644 | * pdcs_register_pathentries - Prepares path entries kobjects for sysfs usage. | 796 | * pdcs_register_pathentries - Prepares path entries kobjects for sysfs usage. |
| @@ -656,8 +808,16 @@ pdcs_register_pathentries(void) | |||
| 656 | struct pdcspath_entry *entry; | 808 | struct pdcspath_entry *entry; |
| 657 | int err; | 809 | int err; |
| 658 | 810 | ||
| 811 | /* Initialize the entries rw_lock before anything else */ | ||
| 812 | for (i = 0; (entry = pdcspath_entries[i]); i++) | ||
| 813 | rwlock_init(&entry->rw_lock); | ||
| 814 | |||
| 659 | for (i = 0; (entry = pdcspath_entries[i]); i++) { | 815 | for (i = 0; (entry = pdcspath_entries[i]); i++) { |
| 660 | if (pdcspath_fetch(entry) < 0) | 816 | write_lock(&entry->rw_lock); |
| 817 | err = pdcspath_fetch(entry); | ||
| 818 | write_unlock(&entry->rw_lock); | ||
| 819 | |||
| 820 | if (err < 0) | ||
| 661 | continue; | 821 | continue; |
| 662 | 822 | ||
| 663 | if ((err = kobject_set_name(&entry->kobj, "%s", entry->name))) | 823 | if ((err = kobject_set_name(&entry->kobj, "%s", entry->name))) |
| @@ -667,13 +827,14 @@ pdcs_register_pathentries(void) | |||
| 667 | return err; | 827 | return err; |
| 668 | 828 | ||
| 669 | /* kobject is now registered */ | 829 | /* kobject is now registered */ |
| 830 | write_lock(&entry->rw_lock); | ||
| 670 | entry->ready = 2; | 831 | entry->ready = 2; |
| 671 | 832 | ||
| 672 | if (!entry->dev) | ||
| 673 | continue; | ||
| 674 | |||
| 675 | /* Add a nice symlink to the real device */ | 833 | /* Add a nice symlink to the real device */ |
| 676 | sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device"); | 834 | if (entry->dev) |
| 835 | sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device"); | ||
| 836 | |||
| 837 | write_unlock(&entry->rw_lock); | ||
| 677 | } | 838 | } |
| 678 | 839 | ||
| 679 | return 0; | 840 | return 0; |
| @@ -688,14 +849,17 @@ pdcs_unregister_pathentries(void) | |||
| 688 | unsigned short i; | 849 | unsigned short i; |
| 689 | struct pdcspath_entry *entry; | 850 | struct pdcspath_entry *entry; |
| 690 | 851 | ||
| 691 | for (i = 0; (entry = pdcspath_entries[i]); i++) | 852 | for (i = 0; (entry = pdcspath_entries[i]); i++) { |
| 853 | read_lock(&entry->rw_lock); | ||
| 692 | if (entry->ready >= 2) | 854 | if (entry->ready >= 2) |
| 693 | kobject_unregister(&entry->kobj); | 855 | kobject_unregister(&entry->kobj); |
| 856 | read_unlock(&entry->rw_lock); | ||
| 857 | } | ||
| 694 | } | 858 | } |
| 695 | 859 | ||
| 696 | /* | 860 | /* |
| 697 | * For now we register the pdc subsystem with the firmware subsystem | 861 | * For now we register the stable subsystem with the firmware subsystem |
| 698 | * and the paths subsystem with the pdc subsystem | 862 | * and the paths subsystem with the stable subsystem |
| 699 | */ | 863 | */ |
| 700 | static int __init | 864 | static int __init |
| 701 | pdc_stable_init(void) | 865 | pdc_stable_init(void) |
| @@ -707,19 +871,23 @@ pdc_stable_init(void) | |||
| 707 | if (pdc_stable_get_size(&pdcs_size) != PDC_OK) | 871 | if (pdc_stable_get_size(&pdcs_size) != PDC_OK) |
| 708 | return -ENODEV; | 872 | return -ENODEV; |
| 709 | 873 | ||
| 710 | printk(KERN_INFO "PDC Stable Storage facility v%s\n", PDCS_VERSION); | 874 | /* make sure we have enough data */ |
| 875 | if (pdcs_size < 96) | ||
| 876 | return -ENODATA; | ||
| 877 | |||
| 878 | printk(KERN_INFO PDCS_PREFIX " facility v%s\n", PDCS_VERSION); | ||
| 711 | 879 | ||
| 712 | /* For now we'll register the pdc subsys within this driver */ | 880 | /* For now we'll register the stable subsys within this driver */ |
| 713 | if ((rc = firmware_register(&pdc_subsys))) | 881 | if ((rc = firmware_register(&stable_subsys))) |
| 714 | goto fail_firmreg; | 882 | goto fail_firmreg; |
| 715 | 883 | ||
| 716 | /* Don't forget the info entry */ | 884 | /* Don't forget the root entries */ |
| 717 | for (i = 0; (attr = pdcs_subsys_attrs[i]) && !error; i++) | 885 | for (i = 0; (attr = pdcs_subsys_attrs[i]) && !error; i++) |
| 718 | if (attr->show) | 886 | if (attr->show) |
| 719 | error = subsys_create_file(&pdc_subsys, attr); | 887 | error = subsys_create_file(&stable_subsys, attr); |
| 720 | 888 | ||
| 721 | /* register the paths subsys as a subsystem of pdc subsys */ | 889 | /* register the paths subsys as a subsystem of stable subsys */ |
| 722 | kset_set_kset_s(&paths_subsys, pdc_subsys); | 890 | kset_set_kset_s(&paths_subsys, stable_subsys); |
| 723 | if ((rc= subsystem_register(&paths_subsys))) | 891 | if ((rc= subsystem_register(&paths_subsys))) |
| 724 | goto fail_subsysreg; | 892 | goto fail_subsysreg; |
| 725 | 893 | ||
| @@ -734,10 +902,10 @@ fail_pdcsreg: | |||
| 734 | subsystem_unregister(&paths_subsys); | 902 | subsystem_unregister(&paths_subsys); |
| 735 | 903 | ||
| 736 | fail_subsysreg: | 904 | fail_subsysreg: |
| 737 | firmware_unregister(&pdc_subsys); | 905 | firmware_unregister(&stable_subsys); |
| 738 | 906 | ||
| 739 | fail_firmreg: | 907 | fail_firmreg: |
| 740 | printk(KERN_INFO "PDC Stable Storage bailing out\n"); | 908 | printk(KERN_INFO PDCS_PREFIX " bailing out\n"); |
| 741 | return rc; | 909 | return rc; |
| 742 | } | 910 | } |
| 743 | 911 | ||
| @@ -747,7 +915,7 @@ pdc_stable_exit(void) | |||
| 747 | pdcs_unregister_pathentries(); | 915 | pdcs_unregister_pathentries(); |
| 748 | subsystem_unregister(&paths_subsys); | 916 | subsystem_unregister(&paths_subsys); |
| 749 | 917 | ||
| 750 | firmware_unregister(&pdc_subsys); | 918 | firmware_unregister(&stable_subsys); |
| 751 | } | 919 | } |
| 752 | 920 | ||
| 753 | 921 | ||
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index c85653f315aa..52f265e97729 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c | |||
| @@ -2064,14 +2064,13 @@ sba_driver_callback(struct parisc_device *dev) | |||
| 2064 | printk(KERN_INFO "%s found %s at 0x%lx\n", | 2064 | printk(KERN_INFO "%s found %s at 0x%lx\n", |
| 2065 | MODULE_NAME, version, dev->hpa.start); | 2065 | MODULE_NAME, version, dev->hpa.start); |
| 2066 | 2066 | ||
| 2067 | sba_dev = kmalloc(sizeof(struct sba_device), GFP_KERNEL); | 2067 | sba_dev = kzalloc(sizeof(struct sba_device), GFP_KERNEL); |
| 2068 | if (!sba_dev) { | 2068 | if (!sba_dev) { |
| 2069 | printk(KERN_ERR MODULE_NAME " - couldn't alloc sba_device\n"); | 2069 | printk(KERN_ERR MODULE_NAME " - couldn't alloc sba_device\n"); |
| 2070 | return -ENOMEM; | 2070 | return -ENOMEM; |
| 2071 | } | 2071 | } |
| 2072 | 2072 | ||
| 2073 | parisc_set_drvdata(dev, sba_dev); | 2073 | parisc_set_drvdata(dev, sba_dev); |
| 2074 | memset(sba_dev, 0, sizeof(struct sba_device)); | ||
| 2075 | 2074 | ||
| 2076 | for(i=0; i<MAX_IOC; i++) | 2075 | for(i=0; i<MAX_IOC; i++) |
| 2077 | spin_lock_init(&(sba_dev->ioc[i].res_lock)); | 2076 | spin_lock_init(&(sba_dev->ioc[i].res_lock)); |
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c index d14888e149bb..ba971fecd0d8 100644 --- a/drivers/parisc/superio.c +++ b/drivers/parisc/superio.c | |||
| @@ -89,6 +89,9 @@ static struct superio_device sio_dev; | |||
| 89 | #define DBG_INIT(x...) | 89 | #define DBG_INIT(x...) |
| 90 | #endif | 90 | #endif |
| 91 | 91 | ||
| 92 | #define SUPERIO "SuperIO" | ||
| 93 | #define PFX SUPERIO ": " | ||
| 94 | |||
| 92 | static irqreturn_t | 95 | static irqreturn_t |
| 93 | superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs) | 96 | superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs) |
| 94 | { | 97 | { |
| @@ -117,7 +120,7 @@ superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs) | |||
| 117 | local_irq = results & 0x0f; | 120 | local_irq = results & 0x0f; |
| 118 | 121 | ||
| 119 | if (local_irq == 2 || local_irq > 7) { | 122 | if (local_irq == 2 || local_irq > 7) { |
| 120 | printk(KERN_ERR "SuperIO: slave interrupted!\n"); | 123 | printk(KERN_ERR PFX "slave interrupted!\n"); |
| 121 | return IRQ_HANDLED; | 124 | return IRQ_HANDLED; |
| 122 | } | 125 | } |
| 123 | 126 | ||
| @@ -128,7 +131,7 @@ superio_interrupt(int parent_irq, void *devp, struct pt_regs *regs) | |||
| 128 | outb(OCW3_ISR,IC_PIC1+0); | 131 | outb(OCW3_ISR,IC_PIC1+0); |
| 129 | results = inb(IC_PIC1+0); | 132 | results = inb(IC_PIC1+0); |
| 130 | if ((results & 0x80) == 0) { /* if ISR7 not set: spurious */ | 133 | if ((results & 0x80) == 0) { /* if ISR7 not set: spurious */ |
| 131 | printk(KERN_WARNING "SuperIO: spurious interrupt!\n"); | 134 | printk(KERN_WARNING PFX "spurious interrupt!\n"); |
| 132 | return IRQ_HANDLED; | 135 | return IRQ_HANDLED; |
| 133 | } | 136 | } |
| 134 | } | 137 | } |
| @@ -163,27 +166,27 @@ superio_init(struct pci_dev *pcidev) | |||
| 163 | /* ...then properly fixup the USB to point at suckyio PIC */ | 166 | /* ...then properly fixup the USB to point at suckyio PIC */ |
| 164 | sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev); | 167 | sio->usb_pdev->irq = superio_fixup_irq(sio->usb_pdev); |
| 165 | 168 | ||
| 166 | printk(KERN_INFO "SuperIO: Found NS87560 Legacy I/O device at %s (IRQ %i) \n", | 169 | printk(KERN_INFO PFX "Found NS87560 Legacy I/O device at %s (IRQ %i) \n", |
| 167 | pci_name(pdev), pdev->irq); | 170 | pci_name(pdev), pdev->irq); |
| 168 | 171 | ||
| 169 | pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base); | 172 | pci_read_config_dword (pdev, SIO_SP1BAR, &sio->sp1_base); |
| 170 | sio->sp1_base &= ~1; | 173 | sio->sp1_base &= ~1; |
| 171 | printk (KERN_INFO "SuperIO: Serial port 1 at 0x%x\n", sio->sp1_base); | 174 | printk(KERN_INFO PFX "Serial port 1 at 0x%x\n", sio->sp1_base); |
| 172 | 175 | ||
| 173 | pci_read_config_dword (pdev, SIO_SP2BAR, &sio->sp2_base); | 176 | pci_read_config_dword (pdev, SIO_SP2BAR, &sio->sp2_base); |
| 174 | sio->sp2_base &= ~1; | 177 | sio->sp2_base &= ~1; |
| 175 | printk (KERN_INFO "SuperIO: Serial port 2 at 0x%x\n", sio->sp2_base); | 178 | printk(KERN_INFO PFX "Serial port 2 at 0x%x\n", sio->sp2_base); |
| 176 | 179 | ||
| 177 | pci_read_config_dword (pdev, SIO_PPBAR, &sio->pp_base); | 180 | pci_read_config_dword (pdev, SIO_PPBAR, &sio->pp_base); |
| 178 | sio->pp_base &= ~1; | 181 | sio->pp_base &= ~1; |
| 179 | printk (KERN_INFO "SuperIO: Parallel port at 0x%x\n", sio->pp_base); | 182 | printk(KERN_INFO PFX "Parallel port at 0x%x\n", sio->pp_base); |
| 180 | 183 | ||
| 181 | pci_read_config_dword (pdev, SIO_FDCBAR, &sio->fdc_base); | 184 | pci_read_config_dword (pdev, SIO_FDCBAR, &sio->fdc_base); |
| 182 | sio->fdc_base &= ~1; | 185 | sio->fdc_base &= ~1; |
| 183 | printk (KERN_INFO "SuperIO: Floppy controller at 0x%x\n", sio->fdc_base); | 186 | printk(KERN_INFO PFX "Floppy controller at 0x%x\n", sio->fdc_base); |
| 184 | pci_read_config_dword (pdev, SIO_ACPIBAR, &sio->acpi_base); | 187 | pci_read_config_dword (pdev, SIO_ACPIBAR, &sio->acpi_base); |
| 185 | sio->acpi_base &= ~1; | 188 | sio->acpi_base &= ~1; |
| 186 | printk (KERN_INFO "SuperIO: ACPI at 0x%x\n", sio->acpi_base); | 189 | printk(KERN_INFO PFX "ACPI at 0x%x\n", sio->acpi_base); |
| 187 | 190 | ||
| 188 | request_region (IC_PIC1, 0x1f, "pic1"); | 191 | request_region (IC_PIC1, 0x1f, "pic1"); |
| 189 | request_region (IC_PIC2, 0x1f, "pic2"); | 192 | request_region (IC_PIC2, 0x1f, "pic2"); |
| @@ -263,14 +266,14 @@ superio_init(struct pci_dev *pcidev) | |||
| 263 | /* Setup USB power regulation */ | 266 | /* Setup USB power regulation */ |
| 264 | outb(1, sio->acpi_base + USB_REG_CR); | 267 | outb(1, sio->acpi_base + USB_REG_CR); |
| 265 | if (inb(sio->acpi_base + USB_REG_CR) & 1) | 268 | if (inb(sio->acpi_base + USB_REG_CR) & 1) |
| 266 | printk(KERN_INFO "SuperIO: USB regulator enabled\n"); | 269 | printk(KERN_INFO PFX "USB regulator enabled\n"); |
| 267 | else | 270 | else |
| 268 | printk(KERN_ERR "USB regulator not initialized!\n"); | 271 | printk(KERN_ERR PFX "USB regulator not initialized!\n"); |
| 269 | 272 | ||
| 270 | if (request_irq(pdev->irq, superio_interrupt, SA_INTERRUPT, | 273 | if (request_irq(pdev->irq, superio_interrupt, SA_INTERRUPT, |
| 271 | "SuperIO", (void *)sio)) { | 274 | SUPERIO, (void *)sio)) { |
| 272 | 275 | ||
| 273 | printk(KERN_ERR "SuperIO: could not get irq\n"); | 276 | printk(KERN_ERR PFX "could not get irq\n"); |
| 274 | BUG(); | 277 | BUG(); |
| 275 | return; | 278 | return; |
| 276 | } | 279 | } |
| @@ -284,7 +287,7 @@ static void superio_disable_irq(unsigned int irq) | |||
| 284 | u8 r8; | 287 | u8 r8; |
| 285 | 288 | ||
| 286 | if ((irq < 1) || (irq == 2) || (irq > 7)) { | 289 | if ((irq < 1) || (irq == 2) || (irq > 7)) { |
| 287 | printk(KERN_ERR "SuperIO: Illegal irq number.\n"); | 290 | printk(KERN_ERR PFX "Illegal irq number.\n"); |
| 288 | BUG(); | 291 | BUG(); |
| 289 | return; | 292 | return; |
| 290 | } | 293 | } |
| @@ -301,7 +304,7 @@ static void superio_enable_irq(unsigned int irq) | |||
| 301 | u8 r8; | 304 | u8 r8; |
| 302 | 305 | ||
| 303 | if ((irq < 1) || (irq == 2) || (irq > 7)) { | 306 | if ((irq < 1) || (irq == 2) || (irq > 7)) { |
| 304 | printk(KERN_ERR "SuperIO: Illegal irq number (%d).\n", irq); | 307 | printk(KERN_ERR PFX "Illegal irq number (%d).\n", irq); |
| 305 | BUG(); | 308 | BUG(); |
| 306 | return; | 309 | return; |
| 307 | } | 310 | } |
| @@ -319,7 +322,7 @@ static unsigned int superio_startup_irq(unsigned int irq) | |||
| 319 | } | 322 | } |
| 320 | 323 | ||
| 321 | static struct hw_interrupt_type superio_interrupt_type = { | 324 | static struct hw_interrupt_type superio_interrupt_type = { |
| 322 | .typename = "SuperIO", | 325 | .typename = SUPERIO, |
| 323 | .startup = superio_startup_irq, | 326 | .startup = superio_startup_irq, |
| 324 | .shutdown = superio_disable_irq, | 327 | .shutdown = superio_disable_irq, |
| 325 | .enable = superio_enable_irq, | 328 | .enable = superio_enable_irq, |
| @@ -413,7 +416,7 @@ static void __devinit superio_serial_init(void) | |||
| 413 | 416 | ||
| 414 | retval = early_serial_setup(&serial[0]); | 417 | retval = early_serial_setup(&serial[0]); |
| 415 | if (retval < 0) { | 418 | if (retval < 0) { |
| 416 | printk(KERN_WARNING "SuperIO: Register Serial #0 failed.\n"); | 419 | printk(KERN_WARNING PFX "Register Serial #0 failed.\n"); |
| 417 | return; | 420 | return; |
| 418 | } | 421 | } |
| 419 | 422 | ||
| @@ -423,7 +426,7 @@ static void __devinit superio_serial_init(void) | |||
| 423 | retval = early_serial_setup(&serial[1]); | 426 | retval = early_serial_setup(&serial[1]); |
| 424 | 427 | ||
| 425 | if (retval < 0) | 428 | if (retval < 0) |
| 426 | printk(KERN_WARNING "SuperIO: Register Serial #1 failed.\n"); | 429 | printk(KERN_WARNING PFX "Register Serial #1 failed.\n"); |
| 427 | #endif /* CONFIG_SERIAL_8250 */ | 430 | #endif /* CONFIG_SERIAL_8250 */ |
| 428 | } | 431 | } |
| 429 | 432 | ||
| @@ -437,7 +440,7 @@ static void __devinit superio_parport_init(void) | |||
| 437 | PARPORT_DMA_NONE /* dma */, | 440 | PARPORT_DMA_NONE /* dma */, |
| 438 | NULL /*struct pci_dev* */) ) | 441 | NULL /*struct pci_dev* */) ) |
| 439 | 442 | ||
| 440 | printk(KERN_WARNING "SuperIO: Probing parallel port failed.\n"); | 443 | printk(KERN_WARNING PFX "Probing parallel port failed.\n"); |
| 441 | #endif /* CONFIG_PARPORT_PC */ | 444 | #endif /* CONFIG_PARPORT_PC */ |
| 442 | } | 445 | } |
| 443 | 446 | ||
| @@ -499,7 +502,7 @@ static struct pci_device_id superio_tbl[] = { | |||
| 499 | }; | 502 | }; |
| 500 | 503 | ||
| 501 | static struct pci_driver superio_driver = { | 504 | static struct pci_driver superio_driver = { |
| 502 | .name = "SuperIO", | 505 | .name = SUPERIO, |
| 503 | .id_table = superio_tbl, | 506 | .id_table = superio_tbl, |
| 504 | .probe = superio_probe, | 507 | .probe = superio_probe, |
| 505 | }; | 508 | }; |
diff --git a/drivers/parisc/wax.c b/drivers/parisc/wax.c index 17dce2adf7fe..813c2c24ab1e 100644 --- a/drivers/parisc/wax.c +++ b/drivers/parisc/wax.c | |||
| @@ -76,7 +76,7 @@ wax_init_chip(struct parisc_device *dev) | |||
| 76 | struct gsc_irq gsc_irq; | 76 | struct gsc_irq gsc_irq; |
| 77 | int ret; | 77 | int ret; |
| 78 | 78 | ||
| 79 | wax = kmalloc(sizeof(*wax), GFP_KERNEL); | 79 | wax = kzalloc(sizeof(*wax), GFP_KERNEL); |
| 80 | if (!wax) | 80 | if (!wax) |
| 81 | return -ENOMEM; | 81 | return -ENOMEM; |
| 82 | 82 | ||
diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig index f605dea57224..f63c387976cf 100644 --- a/drivers/parport/Kconfig +++ b/drivers/parport/Kconfig | |||
| @@ -90,6 +90,15 @@ config PARPORT_ARC | |||
| 90 | depends on ARM && PARPORT | 90 | depends on ARM && PARPORT |
| 91 | select PARPORT_NOT_PC | 91 | select PARPORT_NOT_PC |
| 92 | 92 | ||
| 93 | config PARPORT_IP32 | ||
| 94 | tristate "SGI IP32 builtin port (EXPERIMENTAL)" | ||
| 95 | depends on SGI_IP32 && PARPORT && EXPERIMENTAL | ||
| 96 | select PARPORT_NOT_PC | ||
| 97 | help | ||
| 98 | Say Y here if you need support for the parallel port on | ||
| 99 | SGI O2 machines. This code is also available as a module (say M), | ||
| 100 | called parport_ip32. If in doubt, saying N is the safe plan. | ||
| 101 | |||
| 93 | config PARPORT_AMIGA | 102 | config PARPORT_AMIGA |
| 94 | tristate "Amiga builtin port" | 103 | tristate "Amiga builtin port" |
| 95 | depends on AMIGA && PARPORT | 104 | depends on AMIGA && PARPORT |
diff --git a/drivers/parport/Makefile b/drivers/parport/Makefile index 5372212bb9d9..a19de35f8de2 100644 --- a/drivers/parport/Makefile +++ b/drivers/parport/Makefile | |||
| @@ -17,3 +17,4 @@ obj-$(CONFIG_PARPORT_MFC3) += parport_mfc3.o | |||
| 17 | obj-$(CONFIG_PARPORT_ATARI) += parport_atari.o | 17 | obj-$(CONFIG_PARPORT_ATARI) += parport_atari.o |
| 18 | obj-$(CONFIG_PARPORT_SUNBPP) += parport_sunbpp.o | 18 | obj-$(CONFIG_PARPORT_SUNBPP) += parport_sunbpp.o |
| 19 | obj-$(CONFIG_PARPORT_GSC) += parport_gsc.o | 19 | obj-$(CONFIG_PARPORT_GSC) += parport_gsc.o |
| 20 | obj-$(CONFIG_PARPORT_IP32) += parport_ip32.o | ||
diff --git a/drivers/parport/ieee1284.c b/drivers/parport/ieee1284.c index 5b887ba5aaf9..690b239ad3a7 100644 --- a/drivers/parport/ieee1284.c +++ b/drivers/parport/ieee1284.c | |||
| @@ -61,10 +61,10 @@ static void timeout_waiting_on_port (unsigned long cookie) | |||
| 61 | * set to zero, it returns immediately. | 61 | * set to zero, it returns immediately. |
| 62 | * | 62 | * |
| 63 | * If an interrupt occurs before the timeout period elapses, this | 63 | * If an interrupt occurs before the timeout period elapses, this |
| 64 | * function returns one immediately. If it times out, it returns | 64 | * function returns zero immediately. If it times out, it returns |
| 65 | * a value greater than zero. An error code less than zero | 65 | * one. An error code less than zero indicates an error (most |
| 66 | * indicates an error (most likely a pending signal), and the | 66 | * likely a pending signal), and the calling code should finish |
| 67 | * calling code should finish what it's doing as soon as it can. | 67 | * what it's doing as soon as it can. |
| 68 | */ | 68 | */ |
| 69 | 69 | ||
| 70 | int parport_wait_event (struct parport *port, signed long timeout) | 70 | int parport_wait_event (struct parport *port, signed long timeout) |
| @@ -110,7 +110,7 @@ int parport_wait_event (struct parport *port, signed long timeout) | |||
| 110 | * | 110 | * |
| 111 | * If the status lines take on the desired values before the | 111 | * If the status lines take on the desired values before the |
| 112 | * timeout period elapses, parport_poll_peripheral() returns zero | 112 | * timeout period elapses, parport_poll_peripheral() returns zero |
| 113 | * immediately. A zero return value greater than zero indicates | 113 | * immediately. A return value greater than zero indicates |
| 114 | * a timeout. An error code (less than zero) indicates an error, | 114 | * a timeout. An error code (less than zero) indicates an error, |
| 115 | * most likely a signal that arrived, and the caller should | 115 | * most likely a signal that arrived, and the caller should |
| 116 | * finish what it is doing as soon as possible. | 116 | * finish what it is doing as soon as possible. |
diff --git a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c index fde29a75f888..1de52d9febf9 100644 --- a/drivers/parport/parport_gsc.c +++ b/drivers/parport/parport_gsc.c | |||
| @@ -249,7 +249,7 @@ struct parport *__devinit parport_gsc_probe_port (unsigned long base, | |||
| 249 | struct parport tmp; | 249 | struct parport tmp; |
| 250 | struct parport *p = &tmp; | 250 | struct parport *p = &tmp; |
| 251 | 251 | ||
| 252 | priv = kmalloc (sizeof (struct parport_gsc_private), GFP_KERNEL); | 252 | priv = kzalloc (sizeof (struct parport_gsc_private), GFP_KERNEL); |
| 253 | if (!priv) { | 253 | if (!priv) { |
| 254 | printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base); | 254 | printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base); |
| 255 | return NULL; | 255 | return NULL; |
diff --git a/drivers/parport/parport_ip32.c b/drivers/parport/parport_ip32.c new file mode 100644 index 000000000000..46e06e596d73 --- /dev/null +++ b/drivers/parport/parport_ip32.c | |||
| @@ -0,0 +1,2253 @@ | |||
| 1 | /* Low-level parallel port routines for built-in port on SGI IP32 | ||
| 2 | * | ||
| 3 | * Author: Arnaud Giersch <arnaud.giersch@free.fr> | ||
| 4 | * | ||
| 5 | * Based on parport_pc.c by | ||
| 6 | * Phil Blundell, Tim Waugh, Jose Renau, David Campbell, | ||
| 7 | * Andrea Arcangeli, et al. | ||
| 8 | * | ||
| 9 | * Thanks to Ilya A. Volynets-Evenbakh for his help. | ||
| 10 | * | ||
| 11 | * Copyright (C) 2005, 2006 Arnaud Giersch. | ||
| 12 | * | ||
| 13 | * This program is free software; you can redistribute it and/or modify it | ||
| 14 | * under the terms of the GNU General Public License as published by the Free | ||
| 15 | * Software Foundation; either version 2 of the License, or (at your option) | ||
| 16 | * any later version. | ||
| 17 | * | ||
| 18 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
| 19 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 20 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 21 | * more details. | ||
| 22 | * | ||
| 23 | * You should have received a copy of the GNU General Public License along | ||
| 24 | * with this program; if not, write to the Free Software Foundation, Inc., 59 | ||
| 25 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
| 26 | */ | ||
| 27 | |||
| 28 | /* Current status: | ||
| 29 | * | ||
| 30 | * Basic SPP and PS2 modes are supported. | ||
| 31 | * Support for parallel port IRQ is present. | ||
| 32 | * Hardware SPP (a.k.a. compatibility), EPP, and ECP modes are | ||
| 33 | * supported. | ||
| 34 | * SPP/ECP FIFO can be driven in PIO or DMA mode. PIO mode can work with | ||
| 35 | * or without interrupt support. | ||
| 36 | * | ||
| 37 | * Hardware ECP mode is not fully implemented (ecp_read_data and | ||
| 38 | * ecp_write_addr are actually missing). | ||
| 39 | * | ||
| 40 | * To do: | ||
| 41 | * | ||
| 42 | * Fully implement ECP mode. | ||
| 43 | * EPP and ECP mode need to be tested. I currently do not own any | ||
| 44 | * peripheral supporting these extended mode, and cannot test them. | ||
| 45 | * If DMA mode works well, decide if support for PIO FIFO modes should be | ||
| 46 | * dropped. | ||
| 47 | * Use the io{read,write} family functions when they become available in | ||
| 48 | * the linux-mips.org tree. Note: the MIPS specific functions readsb() | ||
| 49 | * and writesb() are to be translated by ioread8_rep() and iowrite8_rep() | ||
| 50 | * respectively. | ||
| 51 | */ | ||
| 52 | |||
| 53 | /* The built-in parallel port on the SGI 02 workstation (a.k.a. IP32) is an | ||
| 54 | * IEEE 1284 parallel port driven by a Texas Instrument TL16PIR552PH chip[1]. | ||
| 55 | * This chip supports SPP, bidirectional, EPP and ECP modes. It has a 16 byte | ||
| 56 | * FIFO buffer and supports DMA transfers. | ||
| 57 | * | ||
| 58 | * [1] http://focus.ti.com/docs/prod/folders/print/tl16pir552.html | ||
| 59 | * | ||
| 60 | * Theoretically, we could simply use the parport_pc module. It is however | ||
| 61 | * not so simple. The parport_pc code assumes that the parallel port | ||
| 62 | * registers are port-mapped. On the O2, they are memory-mapped. | ||
| 63 | * Furthermore, each register is replicated on 256 consecutive addresses (as | ||
| 64 | * it is for the built-in serial ports on the same chip). | ||
| 65 | */ | ||
| 66 | |||
| 67 | /*--- Some configuration defines ---------------------------------------*/ | ||
| 68 | |||
| 69 | /* DEBUG_PARPORT_IP32 | ||
| 70 | * 0 disable debug | ||
| 71 | * 1 standard level: pr_debug1 is enabled | ||
| 72 | * 2 parport_ip32_dump_state is enabled | ||
| 73 | * >=3 verbose level: pr_debug is enabled | ||
| 74 | */ | ||
| 75 | #if !defined(DEBUG_PARPORT_IP32) | ||
| 76 | # define DEBUG_PARPORT_IP32 0 /* 0 (disabled) for production */ | ||
| 77 | #endif | ||
| 78 | |||
| 79 | /*----------------------------------------------------------------------*/ | ||
| 80 | |||
| 81 | /* Setup DEBUG macros. This is done before any includes, just in case we | ||
| 82 | * activate pr_debug() with DEBUG_PARPORT_IP32 >= 3. | ||
| 83 | */ | ||
| 84 | #if DEBUG_PARPORT_IP32 == 1 | ||
| 85 | # warning DEBUG_PARPORT_IP32 == 1 | ||
| 86 | #elif DEBUG_PARPORT_IP32 == 2 | ||
| 87 | # warning DEBUG_PARPORT_IP32 == 2 | ||
| 88 | #elif DEBUG_PARPORT_IP32 >= 3 | ||
| 89 | # warning DEBUG_PARPORT_IP32 >= 3 | ||
| 90 | # if !defined(DEBUG) | ||
| 91 | # define DEBUG /* enable pr_debug() in kernel.h */ | ||
| 92 | # endif | ||
| 93 | #endif | ||
| 94 | |||
| 95 | #include <linux/completion.h> | ||
| 96 | #include <linux/delay.h> | ||
| 97 | #include <linux/dma-mapping.h> | ||
| 98 | #include <linux/err.h> | ||
| 99 | #include <linux/init.h> | ||
| 100 | #include <linux/interrupt.h> | ||
| 101 | #include <linux/jiffies.h> | ||
| 102 | #include <linux/kernel.h> | ||
| 103 | #include <linux/module.h> | ||
| 104 | #include <linux/parport.h> | ||
| 105 | #include <linux/sched.h> | ||
| 106 | #include <linux/spinlock.h> | ||
| 107 | #include <linux/stddef.h> | ||
| 108 | #include <linux/types.h> | ||
| 109 | #include <asm/io.h> | ||
| 110 | #include <asm/ip32/ip32_ints.h> | ||
| 111 | #include <asm/ip32/mace.h> | ||
| 112 | |||
| 113 | /*--- Global variables -------------------------------------------------*/ | ||
| 114 | |||
| 115 | /* Verbose probing on by default for debugging. */ | ||
| 116 | #if DEBUG_PARPORT_IP32 >= 1 | ||
| 117 | # define DEFAULT_VERBOSE_PROBING 1 | ||
| 118 | #else | ||
| 119 | # define DEFAULT_VERBOSE_PROBING 0 | ||
| 120 | #endif | ||
| 121 | |||
| 122 | /* Default prefix for printk */ | ||
| 123 | #define PPIP32 "parport_ip32: " | ||
| 124 | |||
| 125 | /* | ||
| 126 | * These are the module parameters: | ||
| 127 | * @features: bit mask of features to enable/disable | ||
| 128 | * (all enabled by default) | ||
| 129 | * @verbose_probing: log chit-chat during initialization | ||
| 130 | */ | ||
| 131 | #define PARPORT_IP32_ENABLE_IRQ (1U << 0) | ||
| 132 | #define PARPORT_IP32_ENABLE_DMA (1U << 1) | ||
| 133 | #define PARPORT_IP32_ENABLE_SPP (1U << 2) | ||
| 134 | #define PARPORT_IP32_ENABLE_EPP (1U << 3) | ||
| 135 | #define PARPORT_IP32_ENABLE_ECP (1U << 4) | ||
| 136 | static unsigned int features = ~0U; | ||
| 137 | static int verbose_probing = DEFAULT_VERBOSE_PROBING; | ||
| 138 | |||
| 139 | /* We do not support more than one port. */ | ||
| 140 | static struct parport *this_port = NULL; | ||
| 141 | |||
| 142 | /* Timing constants for FIFO modes. */ | ||
| 143 | #define FIFO_NFAULT_TIMEOUT 100 /* milliseconds */ | ||
| 144 | #define FIFO_POLLING_INTERVAL 50 /* microseconds */ | ||
| 145 | |||
| 146 | /*--- I/O register definitions -----------------------------------------*/ | ||
| 147 | |||
| 148 | /** | ||
| 149 | * struct parport_ip32_regs - virtual addresses of parallel port registers | ||
| 150 | * @data: Data Register | ||
| 151 | * @dsr: Device Status Register | ||
| 152 | * @dcr: Device Control Register | ||
| 153 | * @eppAddr: EPP Address Register | ||
| 154 | * @eppData0: EPP Data Register 0 | ||
| 155 | * @eppData1: EPP Data Register 1 | ||
| 156 | * @eppData2: EPP Data Register 2 | ||
| 157 | * @eppData3: EPP Data Register 3 | ||
| 158 | * @ecpAFifo: ECP Address FIFO | ||
| 159 | * @fifo: General FIFO register. The same address is used for: | ||
| 160 | * - cFifo, the Parallel Port DATA FIFO | ||
| 161 | * - ecpDFifo, the ECP Data FIFO | ||
| 162 | * - tFifo, the ECP Test FIFO | ||
| 163 | * @cnfgA: Configuration Register A | ||
| 164 | * @cnfgB: Configuration Register B | ||
| 165 | * @ecr: Extended Control Register | ||
| 166 | */ | ||
| 167 | struct parport_ip32_regs { | ||
| 168 | void __iomem *data; | ||
| 169 | void __iomem *dsr; | ||
| 170 | void __iomem *dcr; | ||
| 171 | void __iomem *eppAddr; | ||
| 172 | void __iomem *eppData0; | ||
| 173 | void __iomem *eppData1; | ||
| 174 | void __iomem *eppData2; | ||
| 175 | void __iomem *eppData3; | ||
| 176 | void __iomem *ecpAFifo; | ||
| 177 | void __iomem *fifo; | ||
| 178 | void __iomem *cnfgA; | ||
| 179 | void __iomem *cnfgB; | ||
| 180 | void __iomem *ecr; | ||
| 181 | }; | ||
| 182 | |||
| 183 | /* Device Status Register */ | ||
| 184 | #define DSR_nBUSY (1U << 7) /* PARPORT_STATUS_BUSY */ | ||
| 185 | #define DSR_nACK (1U << 6) /* PARPORT_STATUS_ACK */ | ||
| 186 | #define DSR_PERROR (1U << 5) /* PARPORT_STATUS_PAPEROUT */ | ||
| 187 | #define DSR_SELECT (1U << 4) /* PARPORT_STATUS_SELECT */ | ||
| 188 | #define DSR_nFAULT (1U << 3) /* PARPORT_STATUS_ERROR */ | ||
| 189 | #define DSR_nPRINT (1U << 2) /* specific to TL16PIR552 */ | ||
| 190 | /* #define DSR_reserved (1U << 1) */ | ||
| 191 | #define DSR_TIMEOUT (1U << 0) /* EPP timeout */ | ||
| 192 | |||
| 193 | /* Device Control Register */ | ||
| 194 | /* #define DCR_reserved (1U << 7) | (1U << 6) */ | ||
| 195 | #define DCR_DIR (1U << 5) /* direction */ | ||
| 196 | #define DCR_IRQ (1U << 4) /* interrupt on nAck */ | ||
| 197 | #define DCR_SELECT (1U << 3) /* PARPORT_CONTROL_SELECT */ | ||
| 198 | #define DCR_nINIT (1U << 2) /* PARPORT_CONTROL_INIT */ | ||
| 199 | #define DCR_AUTOFD (1U << 1) /* PARPORT_CONTROL_AUTOFD */ | ||
| 200 | #define DCR_STROBE (1U << 0) /* PARPORT_CONTROL_STROBE */ | ||
| 201 | |||
| 202 | /* ECP Configuration Register A */ | ||
| 203 | #define CNFGA_IRQ (1U << 7) | ||
| 204 | #define CNFGA_ID_MASK ((1U << 6) | (1U << 5) | (1U << 4)) | ||
| 205 | #define CNFGA_ID_SHIFT 4 | ||
| 206 | #define CNFGA_ID_16 (00U << CNFGA_ID_SHIFT) | ||
| 207 | #define CNFGA_ID_8 (01U << CNFGA_ID_SHIFT) | ||
| 208 | #define CNFGA_ID_32 (02U << CNFGA_ID_SHIFT) | ||
| 209 | /* #define CNFGA_reserved (1U << 3) */ | ||
| 210 | #define CNFGA_nBYTEINTRANS (1U << 2) | ||
| 211 | #define CNFGA_PWORDLEFT ((1U << 1) | (1U << 0)) | ||
| 212 | |||
| 213 | /* ECP Configuration Register B */ | ||
| 214 | #define CNFGB_COMPRESS (1U << 7) | ||
| 215 | #define CNFGB_INTRVAL (1U << 6) | ||
| 216 | #define CNFGB_IRQ_MASK ((1U << 5) | (1U << 4) | (1U << 3)) | ||
| 217 | #define CNFGB_IRQ_SHIFT 3 | ||
| 218 | #define CNFGB_DMA_MASK ((1U << 2) | (1U << 1) | (1U << 0)) | ||
| 219 | #define CNFGB_DMA_SHIFT 0 | ||
| 220 | |||
| 221 | /* Extended Control Register */ | ||
| 222 | #define ECR_MODE_MASK ((1U << 7) | (1U << 6) | (1U << 5)) | ||
| 223 | #define ECR_MODE_SHIFT 5 | ||
| 224 | #define ECR_MODE_SPP (00U << ECR_MODE_SHIFT) | ||
| 225 | #define ECR_MODE_PS2 (01U << ECR_MODE_SHIFT) | ||
| 226 | #define ECR_MODE_PPF (02U << ECR_MODE_SHIFT) | ||
| 227 | #define ECR_MODE_ECP (03U << ECR_MODE_SHIFT) | ||
| 228 | #define ECR_MODE_EPP (04U << ECR_MODE_SHIFT) | ||
| 229 | /* #define ECR_MODE_reserved (05U << ECR_MODE_SHIFT) */ | ||
| 230 | #define ECR_MODE_TST (06U << ECR_MODE_SHIFT) | ||
| 231 | #define ECR_MODE_CFG (07U << ECR_MODE_SHIFT) | ||
| 232 | #define ECR_nERRINTR (1U << 4) | ||
| 233 | #define ECR_DMAEN (1U << 3) | ||
| 234 | #define ECR_SERVINTR (1U << 2) | ||
| 235 | #define ECR_F_FULL (1U << 1) | ||
| 236 | #define ECR_F_EMPTY (1U << 0) | ||
| 237 | |||
| 238 | /*--- Private data -----------------------------------------------------*/ | ||
| 239 | |||
| 240 | /** | ||
| 241 | * enum parport_ip32_irq_mode - operation mode of interrupt handler | ||
| 242 | * @PARPORT_IP32_IRQ_FWD: forward interrupt to the upper parport layer | ||
| 243 | * @PARPORT_IP32_IRQ_HERE: interrupt is handled locally | ||
| 244 | */ | ||
| 245 | enum parport_ip32_irq_mode { PARPORT_IP32_IRQ_FWD, PARPORT_IP32_IRQ_HERE }; | ||
| 246 | |||
| 247 | /** | ||
| 248 | * struct parport_ip32_private - private stuff for &struct parport | ||
| 249 | * @regs: register addresses | ||
| 250 | * @dcr_cache: cached contents of DCR | ||
| 251 | * @dcr_writable: bit mask of writable DCR bits | ||
| 252 | * @pword: number of bytes per PWord | ||
| 253 | * @fifo_depth: number of PWords that FIFO will hold | ||
| 254 | * @readIntrThreshold: minimum number of PWords we can read | ||
| 255 | * if we get an interrupt | ||
| 256 | * @writeIntrThreshold: minimum number of PWords we can write | ||
| 257 | * if we get an interrupt | ||
| 258 | * @irq_mode: operation mode of interrupt handler for this port | ||
| 259 | * @irq_complete: mutex used to wait for an interrupt to occur | ||
| 260 | */ | ||
| 261 | struct parport_ip32_private { | ||
| 262 | struct parport_ip32_regs regs; | ||
| 263 | unsigned int dcr_cache; | ||
| 264 | unsigned int dcr_writable; | ||
| 265 | unsigned int pword; | ||
| 266 | unsigned int fifo_depth; | ||
| 267 | unsigned int readIntrThreshold; | ||
| 268 | unsigned int writeIntrThreshold; | ||
| 269 | enum parport_ip32_irq_mode irq_mode; | ||
| 270 | struct completion irq_complete; | ||
| 271 | }; | ||
| 272 | |||
| 273 | /*--- Debug code -------------------------------------------------------*/ | ||
| 274 | |||
| 275 | /* | ||
| 276 | * pr_debug1 - print debug messages | ||
| 277 | * | ||
| 278 | * This is like pr_debug(), but is defined for %DEBUG_PARPORT_IP32 >= 1 | ||
| 279 | */ | ||
| 280 | #if DEBUG_PARPORT_IP32 >= 1 | ||
| 281 | # define pr_debug1(...) printk(KERN_DEBUG __VA_ARGS__) | ||
| 282 | #else /* DEBUG_PARPORT_IP32 < 1 */ | ||
| 283 | # define pr_debug1(...) do { } while (0) | ||
| 284 | #endif | ||
| 285 | |||
| 286 | /* | ||
| 287 | * pr_trace, pr_trace1 - trace function calls | ||
| 288 | * @p: pointer to &struct parport | ||
| 289 | * @fmt: printk format string | ||
| 290 | * @...: parameters for format string | ||
| 291 | * | ||
| 292 | * Macros used to trace function calls. The given string is formatted after | ||
| 293 | * function name. pr_trace() uses pr_debug(), and pr_trace1() uses | ||
| 294 | * pr_debug1(). __pr_trace() is the low-level macro and is not to be used | ||
| 295 | * directly. | ||
| 296 | */ | ||
| 297 | #define __pr_trace(pr, p, fmt, ...) \ | ||
| 298 | pr("%s: %s" fmt "\n", \ | ||
| 299 | ({ const struct parport *__p = (p); \ | ||
| 300 | __p ? __p->name : "parport_ip32"; }), \ | ||
| 301 | __func__ , ##__VA_ARGS__) | ||
| 302 | #define pr_trace(p, fmt, ...) __pr_trace(pr_debug, p, fmt , ##__VA_ARGS__) | ||
| 303 | #define pr_trace1(p, fmt, ...) __pr_trace(pr_debug1, p, fmt , ##__VA_ARGS__) | ||
| 304 | |||
| 305 | /* | ||
| 306 | * __pr_probe, pr_probe - print message if @verbose_probing is true | ||
| 307 | * @p: pointer to &struct parport | ||
| 308 | * @fmt: printk format string | ||
| 309 | * @...: parameters for format string | ||
| 310 | * | ||
| 311 | * For new lines, use pr_probe(). Use __pr_probe() for continued lines. | ||
| 312 | */ | ||
| 313 | #define __pr_probe(...) \ | ||
| 314 | do { if (verbose_probing) printk(__VA_ARGS__); } while (0) | ||
| 315 | #define pr_probe(p, fmt, ...) \ | ||
| 316 | __pr_probe(KERN_INFO PPIP32 "0x%lx: " fmt, (p)->base , ##__VA_ARGS__) | ||
| 317 | |||
| 318 | /* | ||
| 319 | * parport_ip32_dump_state - print register status of parport | ||
| 320 | * @p: pointer to &struct parport | ||
| 321 | * @str: string to add in message | ||
| 322 | * @show_ecp_config: shall we dump ECP configuration registers too? | ||
| 323 | * | ||
| 324 | * This function is only here for debugging purpose, and should be used with | ||
| 325 | * care. Reading the parallel port registers may have undesired side effects. | ||
| 326 | * Especially if @show_ecp_config is true, the parallel port is resetted. | ||
| 327 | * This function is only defined if %DEBUG_PARPORT_IP32 >= 2. | ||
| 328 | */ | ||
| 329 | #if DEBUG_PARPORT_IP32 >= 2 | ||
| 330 | static void parport_ip32_dump_state(struct parport *p, char *str, | ||
| 331 | unsigned int show_ecp_config) | ||
| 332 | { | ||
| 333 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 334 | unsigned int i; | ||
| 335 | |||
| 336 | printk(KERN_DEBUG PPIP32 "%s: state (%s):\n", p->name, str); | ||
| 337 | { | ||
| 338 | static const char ecr_modes[8][4] = {"SPP", "PS2", "PPF", | ||
| 339 | "ECP", "EPP", "???", | ||
| 340 | "TST", "CFG"}; | ||
| 341 | unsigned int ecr = readb(priv->regs.ecr); | ||
| 342 | printk(KERN_DEBUG PPIP32 " ecr=0x%02x", ecr); | ||
| 343 | printk(" %s", | ||
| 344 | ecr_modes[(ecr & ECR_MODE_MASK) >> ECR_MODE_SHIFT]); | ||
| 345 | if (ecr & ECR_nERRINTR) | ||
| 346 | printk(",nErrIntrEn"); | ||
| 347 | if (ecr & ECR_DMAEN) | ||
| 348 | printk(",dmaEn"); | ||
| 349 | if (ecr & ECR_SERVINTR) | ||
| 350 | printk(",serviceIntr"); | ||
| 351 | if (ecr & ECR_F_FULL) | ||
| 352 | printk(",f_full"); | ||
| 353 | if (ecr & ECR_F_EMPTY) | ||
| 354 | printk(",f_empty"); | ||
| 355 | printk("\n"); | ||
| 356 | } | ||
| 357 | if (show_ecp_config) { | ||
| 358 | unsigned int oecr, cnfgA, cnfgB; | ||
| 359 | oecr = readb(priv->regs.ecr); | ||
| 360 | writeb(ECR_MODE_PS2, priv->regs.ecr); | ||
| 361 | writeb(ECR_MODE_CFG, priv->regs.ecr); | ||
| 362 | cnfgA = readb(priv->regs.cnfgA); | ||
| 363 | cnfgB = readb(priv->regs.cnfgB); | ||
| 364 | writeb(ECR_MODE_PS2, priv->regs.ecr); | ||
| 365 | writeb(oecr, priv->regs.ecr); | ||
| 366 | printk(KERN_DEBUG PPIP32 " cnfgA=0x%02x", cnfgA); | ||
| 367 | printk(" ISA-%s", (cnfgA & CNFGA_IRQ) ? "Level" : "Pulses"); | ||
| 368 | switch (cnfgA & CNFGA_ID_MASK) { | ||
| 369 | case CNFGA_ID_8: | ||
| 370 | printk(",8 bits"); | ||
| 371 | break; | ||
| 372 | case CNFGA_ID_16: | ||
| 373 | printk(",16 bits"); | ||
| 374 | break; | ||
| 375 | case CNFGA_ID_32: | ||
| 376 | printk(",32 bits"); | ||
| 377 | break; | ||
| 378 | default: | ||
| 379 | printk(",unknown ID"); | ||
| 380 | break; | ||
| 381 | } | ||
| 382 | if (!(cnfgA & CNFGA_nBYTEINTRANS)) | ||
| 383 | printk(",ByteInTrans"); | ||
| 384 | if ((cnfgA & CNFGA_ID_MASK) != CNFGA_ID_8) | ||
| 385 | printk(",%d byte%s left", cnfgA & CNFGA_PWORDLEFT, | ||
| 386 | ((cnfgA & CNFGA_PWORDLEFT) > 1) ? "s" : ""); | ||
| 387 | printk("\n"); | ||
| 388 | printk(KERN_DEBUG PPIP32 " cnfgB=0x%02x", cnfgB); | ||
| 389 | printk(" irq=%u,dma=%u", | ||
| 390 | (cnfgB & CNFGB_IRQ_MASK) >> CNFGB_IRQ_SHIFT, | ||
| 391 | (cnfgB & CNFGB_DMA_MASK) >> CNFGB_DMA_SHIFT); | ||
| 392 | printk(",intrValue=%d", !!(cnfgB & CNFGB_INTRVAL)); | ||
| 393 | if (cnfgB & CNFGB_COMPRESS) | ||
| 394 | printk(",compress"); | ||
| 395 | printk("\n"); | ||
| 396 | } | ||
| 397 | for (i = 0; i < 2; i++) { | ||
| 398 | unsigned int dcr = i ? priv->dcr_cache : readb(priv->regs.dcr); | ||
| 399 | printk(KERN_DEBUG PPIP32 " dcr(%s)=0x%02x", | ||
| 400 | i ? "soft" : "hard", dcr); | ||
| 401 | printk(" %s", (dcr & DCR_DIR) ? "rev" : "fwd"); | ||
| 402 | if (dcr & DCR_IRQ) | ||
| 403 | printk(",ackIntEn"); | ||
| 404 | if (!(dcr & DCR_SELECT)) | ||
| 405 | printk(",nSelectIn"); | ||
| 406 | if (dcr & DCR_nINIT) | ||
| 407 | printk(",nInit"); | ||
| 408 | if (!(dcr & DCR_AUTOFD)) | ||
| 409 | printk(",nAutoFD"); | ||
| 410 | if (!(dcr & DCR_STROBE)) | ||
| 411 | printk(",nStrobe"); | ||
| 412 | printk("\n"); | ||
| 413 | } | ||
| 414 | #define sep (f++ ? ',' : ' ') | ||
| 415 | { | ||
| 416 | unsigned int f = 0; | ||
| 417 | unsigned int dsr = readb(priv->regs.dsr); | ||
| 418 | printk(KERN_DEBUG PPIP32 " dsr=0x%02x", dsr); | ||
| 419 | if (!(dsr & DSR_nBUSY)) | ||
| 420 | printk("%cBusy", sep); | ||
| 421 | if (dsr & DSR_nACK) | ||
| 422 | printk("%cnAck", sep); | ||
| 423 | if (dsr & DSR_PERROR) | ||
| 424 | printk("%cPError", sep); | ||
| 425 | if (dsr & DSR_SELECT) | ||
| 426 | printk("%cSelect", sep); | ||
| 427 | if (dsr & DSR_nFAULT) | ||
| 428 | printk("%cnFault", sep); | ||
| 429 | if (!(dsr & DSR_nPRINT)) | ||
| 430 | printk("%c(Print)", sep); | ||
| 431 | if (dsr & DSR_TIMEOUT) | ||
| 432 | printk("%cTimeout", sep); | ||
| 433 | printk("\n"); | ||
| 434 | } | ||
| 435 | #undef sep | ||
| 436 | } | ||
| 437 | #else /* DEBUG_PARPORT_IP32 < 2 */ | ||
| 438 | #define parport_ip32_dump_state(...) do { } while (0) | ||
| 439 | #endif | ||
| 440 | |||
| 441 | /* | ||
| 442 | * CHECK_EXTRA_BITS - track and log extra bits | ||
| 443 | * @p: pointer to &struct parport | ||
| 444 | * @b: byte to inspect | ||
| 445 | * @m: bit mask of authorized bits | ||
| 446 | * | ||
| 447 | * This is used to track and log extra bits that should not be there in | ||
| 448 | * parport_ip32_write_control() and parport_ip32_frob_control(). It is only | ||
| 449 | * defined if %DEBUG_PARPORT_IP32 >= 1. | ||
| 450 | */ | ||
| 451 | #if DEBUG_PARPORT_IP32 >= 1 | ||
| 452 | #define CHECK_EXTRA_BITS(p, b, m) \ | ||
| 453 | do { \ | ||
| 454 | unsigned int __b = (b), __m = (m); \ | ||
| 455 | if (__b & ~__m) \ | ||
| 456 | pr_debug1(PPIP32 "%s: extra bits in %s(%s): " \ | ||
| 457 | "0x%02x/0x%02x\n", \ | ||
| 458 | (p)->name, __func__, #b, __b, __m); \ | ||
| 459 | } while (0) | ||
| 460 | #else /* DEBUG_PARPORT_IP32 < 1 */ | ||
| 461 | #define CHECK_EXTRA_BITS(...) do { } while (0) | ||
| 462 | #endif | ||
| 463 | |||
| 464 | /*--- IP32 parallel port DMA operations --------------------------------*/ | ||
| 465 | |||
| 466 | /** | ||
| 467 | * struct parport_ip32_dma_data - private data needed for DMA operation | ||
| 468 | * @dir: DMA direction (from or to device) | ||
| 469 | * @buf: buffer physical address | ||
| 470 | * @len: buffer length | ||
| 471 | * @next: address of next bytes to DMA transfer | ||
| 472 | * @left: number of bytes remaining | ||
| 473 | * @ctx: next context to write (0: context_a; 1: context_b) | ||
| 474 | * @irq_on: are the DMA IRQs currently enabled? | ||
| 475 | * @lock: spinlock to protect access to the structure | ||
| 476 | */ | ||
| 477 | struct parport_ip32_dma_data { | ||
| 478 | enum dma_data_direction dir; | ||
| 479 | dma_addr_t buf; | ||
| 480 | dma_addr_t next; | ||
| 481 | size_t len; | ||
| 482 | size_t left; | ||
| 483 | unsigned int ctx; | ||
| 484 | unsigned int irq_on; | ||
| 485 | spinlock_t lock; | ||
| 486 | }; | ||
| 487 | static struct parport_ip32_dma_data parport_ip32_dma; | ||
| 488 | |||
| 489 | /** | ||
| 490 | * parport_ip32_dma_setup_context - setup next DMA context | ||
| 491 | * @limit: maximum data size for the context | ||
| 492 | * | ||
| 493 | * The alignment constraints must be verified in caller function, and the | ||
| 494 | * parameter @limit must be set accordingly. | ||
| 495 | */ | ||
| 496 | static void parport_ip32_dma_setup_context(unsigned int limit) | ||
| 497 | { | ||
| 498 | unsigned long flags; | ||
| 499 | |||
| 500 | spin_lock_irqsave(&parport_ip32_dma.lock, flags); | ||
| 501 | if (parport_ip32_dma.left > 0) { | ||
| 502 | /* Note: ctxreg is "volatile" here only because | ||
| 503 | * mace->perif.ctrl.parport.context_a and context_b are | ||
| 504 | * "volatile". */ | ||
| 505 | volatile u64 __iomem *ctxreg = (parport_ip32_dma.ctx == 0) ? | ||
| 506 | &mace->perif.ctrl.parport.context_a : | ||
| 507 | &mace->perif.ctrl.parport.context_b; | ||
| 508 | u64 count; | ||
| 509 | u64 ctxval; | ||
| 510 | if (parport_ip32_dma.left <= limit) { | ||
| 511 | count = parport_ip32_dma.left; | ||
| 512 | ctxval = MACEPAR_CONTEXT_LASTFLAG; | ||
| 513 | } else { | ||
| 514 | count = limit; | ||
| 515 | ctxval = 0; | ||
| 516 | } | ||
| 517 | |||
| 518 | pr_trace(NULL, | ||
| 519 | "(%u): 0x%04x:0x%04x, %u -> %u%s", | ||
| 520 | limit, | ||
| 521 | (unsigned int)parport_ip32_dma.buf, | ||
| 522 | (unsigned int)parport_ip32_dma.next, | ||
| 523 | (unsigned int)count, | ||
| 524 | parport_ip32_dma.ctx, ctxval ? "*" : ""); | ||
| 525 | |||
| 526 | ctxval |= parport_ip32_dma.next & | ||
| 527 | MACEPAR_CONTEXT_BASEADDR_MASK; | ||
| 528 | ctxval |= ((count - 1) << MACEPAR_CONTEXT_DATALEN_SHIFT) & | ||
| 529 | MACEPAR_CONTEXT_DATALEN_MASK; | ||
| 530 | writeq(ctxval, ctxreg); | ||
| 531 | parport_ip32_dma.next += count; | ||
| 532 | parport_ip32_dma.left -= count; | ||
| 533 | parport_ip32_dma.ctx ^= 1U; | ||
| 534 | } | ||
| 535 | /* If there is nothing more to send, disable IRQs to avoid to | ||
| 536 | * face an IRQ storm which can lock the machine. Disable them | ||
| 537 | * only once. */ | ||
| 538 | if (parport_ip32_dma.left == 0 && parport_ip32_dma.irq_on) { | ||
| 539 | pr_debug(PPIP32 "IRQ off (ctx)\n"); | ||
| 540 | disable_irq_nosync(MACEISA_PAR_CTXA_IRQ); | ||
| 541 | disable_irq_nosync(MACEISA_PAR_CTXB_IRQ); | ||
| 542 | parport_ip32_dma.irq_on = 0; | ||
| 543 | } | ||
| 544 | spin_unlock_irqrestore(&parport_ip32_dma.lock, flags); | ||
| 545 | } | ||
| 546 | |||
| 547 | /** | ||
| 548 | * parport_ip32_dma_interrupt - DMA interrupt handler | ||
| 549 | * @irq: interrupt number | ||
| 550 | * @dev_id: unused | ||
| 551 | * @regs: pointer to &struct pt_regs | ||
| 552 | */ | ||
| 553 | static irqreturn_t parport_ip32_dma_interrupt(int irq, void *dev_id, | ||
| 554 | struct pt_regs *regs) | ||
| 555 | { | ||
| 556 | if (parport_ip32_dma.left) | ||
| 557 | pr_trace(NULL, "(%d): ctx=%d", irq, parport_ip32_dma.ctx); | ||
| 558 | parport_ip32_dma_setup_context(MACEPAR_CONTEXT_DATA_BOUND); | ||
| 559 | return IRQ_HANDLED; | ||
| 560 | } | ||
| 561 | |||
| 562 | #if DEBUG_PARPORT_IP32 | ||
| 563 | static irqreturn_t parport_ip32_merr_interrupt(int irq, void *dev_id, | ||
| 564 | struct pt_regs *regs) | ||
| 565 | { | ||
| 566 | pr_trace1(NULL, "(%d)", irq); | ||
| 567 | return IRQ_HANDLED; | ||
| 568 | } | ||
| 569 | #endif | ||
| 570 | |||
| 571 | /** | ||
| 572 | * parport_ip32_dma_start - begins a DMA transfer | ||
| 573 | * @dir: DMA direction: DMA_TO_DEVICE or DMA_FROM_DEVICE | ||
| 574 | * @addr: pointer to data buffer | ||
| 575 | * @count: buffer size | ||
| 576 | * | ||
| 577 | * Calls to parport_ip32_dma_start() and parport_ip32_dma_stop() must be | ||
| 578 | * correctly balanced. | ||
| 579 | */ | ||
| 580 | static int parport_ip32_dma_start(enum dma_data_direction dir, | ||
| 581 | void *addr, size_t count) | ||
| 582 | { | ||
| 583 | unsigned int limit; | ||
| 584 | u64 ctrl; | ||
| 585 | |||
| 586 | pr_trace(NULL, "(%d, %lu)", dir, (unsigned long)count); | ||
| 587 | |||
| 588 | /* FIXME - add support for DMA_FROM_DEVICE. In this case, buffer must | ||
| 589 | * be 64 bytes aligned. */ | ||
| 590 | BUG_ON(dir != DMA_TO_DEVICE); | ||
| 591 | |||
| 592 | /* Reset DMA controller */ | ||
| 593 | ctrl = MACEPAR_CTLSTAT_RESET; | ||
| 594 | writeq(ctrl, &mace->perif.ctrl.parport.cntlstat); | ||
| 595 | |||
| 596 | /* DMA IRQs should normally be enabled */ | ||
| 597 | if (!parport_ip32_dma.irq_on) { | ||
| 598 | WARN_ON(1); | ||
| 599 | enable_irq(MACEISA_PAR_CTXA_IRQ); | ||
| 600 | enable_irq(MACEISA_PAR_CTXB_IRQ); | ||
| 601 | parport_ip32_dma.irq_on = 1; | ||
| 602 | } | ||
| 603 | |||
| 604 | /* Prepare DMA pointers */ | ||
| 605 | parport_ip32_dma.dir = dir; | ||
| 606 | parport_ip32_dma.buf = dma_map_single(NULL, addr, count, dir); | ||
| 607 | parport_ip32_dma.len = count; | ||
| 608 | parport_ip32_dma.next = parport_ip32_dma.buf; | ||
| 609 | parport_ip32_dma.left = parport_ip32_dma.len; | ||
| 610 | parport_ip32_dma.ctx = 0; | ||
| 611 | |||
| 612 | /* Setup DMA direction and first two contexts */ | ||
| 613 | ctrl = (dir == DMA_TO_DEVICE) ? 0 : MACEPAR_CTLSTAT_DIRECTION; | ||
| 614 | writeq(ctrl, &mace->perif.ctrl.parport.cntlstat); | ||
| 615 | /* Single transfer should not cross a 4K page boundary */ | ||
| 616 | limit = MACEPAR_CONTEXT_DATA_BOUND - | ||
| 617 | (parport_ip32_dma.next & (MACEPAR_CONTEXT_DATA_BOUND - 1)); | ||
| 618 | parport_ip32_dma_setup_context(limit); | ||
| 619 | parport_ip32_dma_setup_context(MACEPAR_CONTEXT_DATA_BOUND); | ||
| 620 | |||
| 621 | /* Real start of DMA transfer */ | ||
| 622 | ctrl |= MACEPAR_CTLSTAT_ENABLE; | ||
| 623 | writeq(ctrl, &mace->perif.ctrl.parport.cntlstat); | ||
| 624 | |||
| 625 | return 0; | ||
| 626 | } | ||
| 627 | |||
| 628 | /** | ||
| 629 | * parport_ip32_dma_stop - ends a running DMA transfer | ||
| 630 | * | ||
| 631 | * Calls to parport_ip32_dma_start() and parport_ip32_dma_stop() must be | ||
| 632 | * correctly balanced. | ||
| 633 | */ | ||
| 634 | static void parport_ip32_dma_stop(void) | ||
| 635 | { | ||
| 636 | u64 ctx_a; | ||
| 637 | u64 ctx_b; | ||
| 638 | u64 ctrl; | ||
| 639 | u64 diag; | ||
| 640 | size_t res[2]; /* {[0] = res_a, [1] = res_b} */ | ||
| 641 | |||
| 642 | pr_trace(NULL, "()"); | ||
| 643 | |||
| 644 | /* Disable IRQs */ | ||
| 645 | spin_lock_irq(&parport_ip32_dma.lock); | ||
| 646 | if (parport_ip32_dma.irq_on) { | ||
| 647 | pr_debug(PPIP32 "IRQ off (stop)\n"); | ||
| 648 | disable_irq_nosync(MACEISA_PAR_CTXA_IRQ); | ||
| 649 | disable_irq_nosync(MACEISA_PAR_CTXB_IRQ); | ||
| 650 | parport_ip32_dma.irq_on = 0; | ||
| 651 | } | ||
| 652 | spin_unlock_irq(&parport_ip32_dma.lock); | ||
| 653 | /* Force IRQ synchronization, even if the IRQs were disabled | ||
| 654 | * elsewhere. */ | ||
| 655 | synchronize_irq(MACEISA_PAR_CTXA_IRQ); | ||
| 656 | synchronize_irq(MACEISA_PAR_CTXB_IRQ); | ||
| 657 | |||
| 658 | /* Stop DMA transfer */ | ||
| 659 | ctrl = readq(&mace->perif.ctrl.parport.cntlstat); | ||
| 660 | ctrl &= ~MACEPAR_CTLSTAT_ENABLE; | ||
| 661 | writeq(ctrl, &mace->perif.ctrl.parport.cntlstat); | ||
| 662 | |||
| 663 | /* Adjust residue (parport_ip32_dma.left) */ | ||
| 664 | ctx_a = readq(&mace->perif.ctrl.parport.context_a); | ||
| 665 | ctx_b = readq(&mace->perif.ctrl.parport.context_b); | ||
| 666 | ctrl = readq(&mace->perif.ctrl.parport.cntlstat); | ||
| 667 | diag = readq(&mace->perif.ctrl.parport.diagnostic); | ||
| 668 | res[0] = (ctrl & MACEPAR_CTLSTAT_CTXA_VALID) ? | ||
| 669 | 1 + ((ctx_a & MACEPAR_CONTEXT_DATALEN_MASK) >> | ||
| 670 | MACEPAR_CONTEXT_DATALEN_SHIFT) : | ||
| 671 | 0; | ||
| 672 | res[1] = (ctrl & MACEPAR_CTLSTAT_CTXB_VALID) ? | ||
| 673 | 1 + ((ctx_b & MACEPAR_CONTEXT_DATALEN_MASK) >> | ||
| 674 | MACEPAR_CONTEXT_DATALEN_SHIFT) : | ||
| 675 | 0; | ||
| 676 | if (diag & MACEPAR_DIAG_DMACTIVE) | ||
| 677 | res[(diag & MACEPAR_DIAG_CTXINUSE) != 0] = | ||
| 678 | 1 + ((diag & MACEPAR_DIAG_CTRMASK) >> | ||
| 679 | MACEPAR_DIAG_CTRSHIFT); | ||
| 680 | parport_ip32_dma.left += res[0] + res[1]; | ||
| 681 | |||
| 682 | /* Reset DMA controller, and re-enable IRQs */ | ||
| 683 | ctrl = MACEPAR_CTLSTAT_RESET; | ||
| 684 | writeq(ctrl, &mace->perif.ctrl.parport.cntlstat); | ||
| 685 | pr_debug(PPIP32 "IRQ on (stop)\n"); | ||
| 686 | enable_irq(MACEISA_PAR_CTXA_IRQ); | ||
| 687 | enable_irq(MACEISA_PAR_CTXB_IRQ); | ||
| 688 | parport_ip32_dma.irq_on = 1; | ||
| 689 | |||
| 690 | dma_unmap_single(NULL, parport_ip32_dma.buf, parport_ip32_dma.len, | ||
| 691 | parport_ip32_dma.dir); | ||
| 692 | } | ||
| 693 | |||
| 694 | /** | ||
| 695 | * parport_ip32_dma_get_residue - get residue from last DMA transfer | ||
| 696 | * | ||
| 697 | * Returns the number of bytes remaining from last DMA transfer. | ||
| 698 | */ | ||
| 699 | static inline size_t parport_ip32_dma_get_residue(void) | ||
| 700 | { | ||
| 701 | return parport_ip32_dma.left; | ||
| 702 | } | ||
| 703 | |||
| 704 | /** | ||
| 705 | * parport_ip32_dma_register - initialize DMA engine | ||
| 706 | * | ||
| 707 | * Returns zero for success. | ||
| 708 | */ | ||
| 709 | static int parport_ip32_dma_register(void) | ||
| 710 | { | ||
| 711 | int err; | ||
| 712 | |||
| 713 | spin_lock_init(&parport_ip32_dma.lock); | ||
| 714 | parport_ip32_dma.irq_on = 1; | ||
| 715 | |||
| 716 | /* Reset DMA controller */ | ||
| 717 | writeq(MACEPAR_CTLSTAT_RESET, &mace->perif.ctrl.parport.cntlstat); | ||
| 718 | |||
| 719 | /* Request IRQs */ | ||
| 720 | err = request_irq(MACEISA_PAR_CTXA_IRQ, parport_ip32_dma_interrupt, | ||
| 721 | 0, "parport_ip32", NULL); | ||
| 722 | if (err) | ||
| 723 | goto fail_a; | ||
| 724 | err = request_irq(MACEISA_PAR_CTXB_IRQ, parport_ip32_dma_interrupt, | ||
| 725 | 0, "parport_ip32", NULL); | ||
| 726 | if (err) | ||
| 727 | goto fail_b; | ||
| 728 | #if DEBUG_PARPORT_IP32 | ||
| 729 | /* FIXME - what is this IRQ for? */ | ||
| 730 | err = request_irq(MACEISA_PAR_MERR_IRQ, parport_ip32_merr_interrupt, | ||
| 731 | 0, "parport_ip32", NULL); | ||
| 732 | if (err) | ||
| 733 | goto fail_merr; | ||
| 734 | #endif | ||
| 735 | return 0; | ||
| 736 | |||
| 737 | #if DEBUG_PARPORT_IP32 | ||
| 738 | fail_merr: | ||
| 739 | free_irq(MACEISA_PAR_CTXB_IRQ, NULL); | ||
| 740 | #endif | ||
| 741 | fail_b: | ||
| 742 | free_irq(MACEISA_PAR_CTXA_IRQ, NULL); | ||
| 743 | fail_a: | ||
| 744 | return err; | ||
| 745 | } | ||
| 746 | |||
| 747 | /** | ||
| 748 | * parport_ip32_dma_unregister - release and free resources for DMA engine | ||
| 749 | */ | ||
| 750 | static void parport_ip32_dma_unregister(void) | ||
| 751 | { | ||
| 752 | #if DEBUG_PARPORT_IP32 | ||
| 753 | free_irq(MACEISA_PAR_MERR_IRQ, NULL); | ||
| 754 | #endif | ||
| 755 | free_irq(MACEISA_PAR_CTXB_IRQ, NULL); | ||
| 756 | free_irq(MACEISA_PAR_CTXA_IRQ, NULL); | ||
| 757 | } | ||
| 758 | |||
| 759 | /*--- Interrupt handlers and associates --------------------------------*/ | ||
| 760 | |||
| 761 | /** | ||
| 762 | * parport_ip32_wakeup - wakes up code waiting for an interrupt | ||
| 763 | * @p: pointer to &struct parport | ||
| 764 | */ | ||
| 765 | static inline void parport_ip32_wakeup(struct parport *p) | ||
| 766 | { | ||
| 767 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 768 | complete(&priv->irq_complete); | ||
| 769 | } | ||
| 770 | |||
| 771 | /** | ||
| 772 | * parport_ip32_interrupt - interrupt handler | ||
| 773 | * @irq: interrupt number | ||
| 774 | * @dev_id: pointer to &struct parport | ||
| 775 | * @regs: pointer to &struct pt_regs | ||
| 776 | * | ||
| 777 | * Caught interrupts are forwarded to the upper parport layer if IRQ_mode is | ||
| 778 | * %PARPORT_IP32_IRQ_FWD. | ||
| 779 | */ | ||
| 780 | static irqreturn_t parport_ip32_interrupt(int irq, void *dev_id, | ||
| 781 | struct pt_regs *regs) | ||
| 782 | { | ||
| 783 | struct parport * const p = dev_id; | ||
| 784 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 785 | enum parport_ip32_irq_mode irq_mode = priv->irq_mode; | ||
| 786 | switch (irq_mode) { | ||
| 787 | case PARPORT_IP32_IRQ_FWD: | ||
| 788 | parport_generic_irq(irq, p, regs); | ||
| 789 | break; | ||
| 790 | case PARPORT_IP32_IRQ_HERE: | ||
| 791 | parport_ip32_wakeup(p); | ||
| 792 | break; | ||
| 793 | } | ||
| 794 | return IRQ_HANDLED; | ||
| 795 | } | ||
| 796 | |||
| 797 | /*--- Some utility function to manipulate ECR register -----------------*/ | ||
| 798 | |||
| 799 | /** | ||
| 800 | * parport_ip32_read_econtrol - read contents of the ECR register | ||
| 801 | * @p: pointer to &struct parport | ||
| 802 | */ | ||
| 803 | static inline unsigned int parport_ip32_read_econtrol(struct parport *p) | ||
| 804 | { | ||
| 805 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 806 | return readb(priv->regs.ecr); | ||
| 807 | } | ||
| 808 | |||
| 809 | /** | ||
| 810 | * parport_ip32_write_econtrol - write new contents to the ECR register | ||
| 811 | * @p: pointer to &struct parport | ||
| 812 | * @c: new value to write | ||
| 813 | */ | ||
| 814 | static inline void parport_ip32_write_econtrol(struct parport *p, | ||
| 815 | unsigned int c) | ||
| 816 | { | ||
| 817 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 818 | writeb(c, priv->regs.ecr); | ||
| 819 | } | ||
| 820 | |||
| 821 | /** | ||
| 822 | * parport_ip32_frob_econtrol - change bits from the ECR register | ||
| 823 | * @p: pointer to &struct parport | ||
| 824 | * @mask: bit mask of bits to change | ||
| 825 | * @val: new value for changed bits | ||
| 826 | * | ||
| 827 | * Read from the ECR, mask out the bits in @mask, exclusive-or with the bits | ||
| 828 | * in @val, and write the result to the ECR. | ||
| 829 | */ | ||
| 830 | static inline void parport_ip32_frob_econtrol(struct parport *p, | ||
| 831 | unsigned int mask, | ||
| 832 | unsigned int val) | ||
| 833 | { | ||
| 834 | unsigned int c; | ||
| 835 | c = (parport_ip32_read_econtrol(p) & ~mask) ^ val; | ||
| 836 | parport_ip32_write_econtrol(p, c); | ||
| 837 | } | ||
| 838 | |||
| 839 | /** | ||
| 840 | * parport_ip32_set_mode - change mode of ECP port | ||
| 841 | * @p: pointer to &struct parport | ||
| 842 | * @mode: new mode to write in ECR | ||
| 843 | * | ||
| 844 | * ECR is reset in a sane state (interrupts and DMA disabled), and placed in | ||
| 845 | * mode @mode. Go through PS2 mode if needed. | ||
| 846 | */ | ||
| 847 | static void parport_ip32_set_mode(struct parport *p, unsigned int mode) | ||
| 848 | { | ||
| 849 | unsigned int omode; | ||
| 850 | |||
| 851 | mode &= ECR_MODE_MASK; | ||
| 852 | omode = parport_ip32_read_econtrol(p) & ECR_MODE_MASK; | ||
| 853 | |||
| 854 | if (!(mode == ECR_MODE_SPP || mode == ECR_MODE_PS2 | ||
| 855 | || omode == ECR_MODE_SPP || omode == ECR_MODE_PS2)) { | ||
| 856 | /* We have to go through PS2 mode */ | ||
| 857 | unsigned int ecr = ECR_MODE_PS2 | ECR_nERRINTR | ECR_SERVINTR; | ||
| 858 | parport_ip32_write_econtrol(p, ecr); | ||
| 859 | } | ||
| 860 | parport_ip32_write_econtrol(p, mode | ECR_nERRINTR | ECR_SERVINTR); | ||
| 861 | } | ||
| 862 | |||
| 863 | /*--- Basic functions needed for parport -------------------------------*/ | ||
| 864 | |||
| 865 | /** | ||
| 866 | * parport_ip32_read_data - return current contents of the DATA register | ||
| 867 | * @p: pointer to &struct parport | ||
| 868 | */ | ||
| 869 | static inline unsigned char parport_ip32_read_data(struct parport *p) | ||
| 870 | { | ||
| 871 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 872 | return readb(priv->regs.data); | ||
| 873 | } | ||
| 874 | |||
| 875 | /** | ||
| 876 | * parport_ip32_write_data - set new contents for the DATA register | ||
| 877 | * @p: pointer to &struct parport | ||
| 878 | * @d: new value to write | ||
| 879 | */ | ||
| 880 | static inline void parport_ip32_write_data(struct parport *p, unsigned char d) | ||
| 881 | { | ||
| 882 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 883 | writeb(d, priv->regs.data); | ||
| 884 | } | ||
| 885 | |||
| 886 | /** | ||
| 887 | * parport_ip32_read_status - return current contents of the DSR register | ||
| 888 | * @p: pointer to &struct parport | ||
| 889 | */ | ||
| 890 | static inline unsigned char parport_ip32_read_status(struct parport *p) | ||
| 891 | { | ||
| 892 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 893 | return readb(priv->regs.dsr); | ||
| 894 | } | ||
| 895 | |||
| 896 | /** | ||
| 897 | * __parport_ip32_read_control - return cached contents of the DCR register | ||
| 898 | * @p: pointer to &struct parport | ||
| 899 | */ | ||
| 900 | static inline unsigned int __parport_ip32_read_control(struct parport *p) | ||
| 901 | { | ||
| 902 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 903 | return priv->dcr_cache; /* use soft copy */ | ||
| 904 | } | ||
| 905 | |||
| 906 | /** | ||
| 907 | * __parport_ip32_write_control - set new contents for the DCR register | ||
| 908 | * @p: pointer to &struct parport | ||
| 909 | * @c: new value to write | ||
| 910 | */ | ||
| 911 | static inline void __parport_ip32_write_control(struct parport *p, | ||
| 912 | unsigned int c) | ||
| 913 | { | ||
| 914 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 915 | CHECK_EXTRA_BITS(p, c, priv->dcr_writable); | ||
| 916 | c &= priv->dcr_writable; /* only writable bits */ | ||
| 917 | writeb(c, priv->regs.dcr); | ||
| 918 | priv->dcr_cache = c; /* update soft copy */ | ||
| 919 | } | ||
| 920 | |||
| 921 | /** | ||
| 922 | * __parport_ip32_frob_control - change bits from the DCR register | ||
| 923 | * @p: pointer to &struct parport | ||
| 924 | * @mask: bit mask of bits to change | ||
| 925 | * @val: new value for changed bits | ||
| 926 | * | ||
| 927 | * This is equivalent to read from the DCR, mask out the bits in @mask, | ||
| 928 | * exclusive-or with the bits in @val, and write the result to the DCR. | ||
| 929 | * Actually, the cached contents of the DCR is used. | ||
| 930 | */ | ||
| 931 | static inline void __parport_ip32_frob_control(struct parport *p, | ||
| 932 | unsigned int mask, | ||
| 933 | unsigned int val) | ||
| 934 | { | ||
| 935 | unsigned int c; | ||
| 936 | c = (__parport_ip32_read_control(p) & ~mask) ^ val; | ||
| 937 | __parport_ip32_write_control(p, c); | ||
| 938 | } | ||
| 939 | |||
| 940 | /** | ||
| 941 | * parport_ip32_read_control - return cached contents of the DCR register | ||
| 942 | * @p: pointer to &struct parport | ||
| 943 | * | ||
| 944 | * The return value is masked so as to only return the value of %DCR_STROBE, | ||
| 945 | * %DCR_AUTOFD, %DCR_nINIT, and %DCR_SELECT. | ||
| 946 | */ | ||
| 947 | static inline unsigned char parport_ip32_read_control(struct parport *p) | ||
| 948 | { | ||
| 949 | const unsigned int rm = | ||
| 950 | DCR_STROBE | DCR_AUTOFD | DCR_nINIT | DCR_SELECT; | ||
| 951 | return __parport_ip32_read_control(p) & rm; | ||
| 952 | } | ||
| 953 | |||
| 954 | /** | ||
| 955 | * parport_ip32_write_control - set new contents for the DCR register | ||
| 956 | * @p: pointer to &struct parport | ||
| 957 | * @c: new value to write | ||
| 958 | * | ||
| 959 | * The value is masked so as to only change the value of %DCR_STROBE, | ||
| 960 | * %DCR_AUTOFD, %DCR_nINIT, and %DCR_SELECT. | ||
| 961 | */ | ||
| 962 | static inline void parport_ip32_write_control(struct parport *p, | ||
| 963 | unsigned char c) | ||
| 964 | { | ||
| 965 | const unsigned int wm = | ||
| 966 | DCR_STROBE | DCR_AUTOFD | DCR_nINIT | DCR_SELECT; | ||
| 967 | CHECK_EXTRA_BITS(p, c, wm); | ||
| 968 | __parport_ip32_frob_control(p, wm, c & wm); | ||
| 969 | } | ||
| 970 | |||
| 971 | /** | ||
| 972 | * parport_ip32_frob_control - change bits from the DCR register | ||
| 973 | * @p: pointer to &struct parport | ||
| 974 | * @mask: bit mask of bits to change | ||
| 975 | * @val: new value for changed bits | ||
| 976 | * | ||
| 977 | * This differs from __parport_ip32_frob_control() in that it only allows to | ||
| 978 | * change the value of %DCR_STROBE, %DCR_AUTOFD, %DCR_nINIT, and %DCR_SELECT. | ||
| 979 | */ | ||
| 980 | static inline unsigned char parport_ip32_frob_control(struct parport *p, | ||
| 981 | unsigned char mask, | ||
| 982 | unsigned char val) | ||
| 983 | { | ||
| 984 | const unsigned int wm = | ||
| 985 | DCR_STROBE | DCR_AUTOFD | DCR_nINIT | DCR_SELECT; | ||
| 986 | CHECK_EXTRA_BITS(p, mask, wm); | ||
| 987 | CHECK_EXTRA_BITS(p, val, wm); | ||
| 988 | __parport_ip32_frob_control(p, mask & wm, val & wm); | ||
| 989 | return parport_ip32_read_control(p); | ||
| 990 | } | ||
| 991 | |||
| 992 | /** | ||
| 993 | * parport_ip32_disable_irq - disable interrupts on the rising edge of nACK | ||
| 994 | * @p: pointer to &struct parport | ||
| 995 | */ | ||
| 996 | static inline void parport_ip32_disable_irq(struct parport *p) | ||
| 997 | { | ||
| 998 | __parport_ip32_frob_control(p, DCR_IRQ, 0); | ||
| 999 | } | ||
| 1000 | |||
| 1001 | /** | ||
| 1002 | * parport_ip32_enable_irq - enable interrupts on the rising edge of nACK | ||
| 1003 | * @p: pointer to &struct parport | ||
| 1004 | */ | ||
| 1005 | static inline void parport_ip32_enable_irq(struct parport *p) | ||
| 1006 | { | ||
| 1007 | __parport_ip32_frob_control(p, DCR_IRQ, DCR_IRQ); | ||
| 1008 | } | ||
| 1009 | |||
| 1010 | /** | ||
| 1011 | * parport_ip32_data_forward - enable host-to-peripheral communications | ||
| 1012 | * @p: pointer to &struct parport | ||
| 1013 | * | ||
| 1014 | * Enable the data line drivers, for 8-bit host-to-peripheral communications. | ||
| 1015 | */ | ||
| 1016 | static inline void parport_ip32_data_forward(struct parport *p) | ||
| 1017 | { | ||
| 1018 | __parport_ip32_frob_control(p, DCR_DIR, 0); | ||
| 1019 | } | ||
| 1020 | |||
| 1021 | /** | ||
| 1022 | * parport_ip32_data_reverse - enable peripheral-to-host communications | ||
| 1023 | * @p: pointer to &struct parport | ||
| 1024 | * | ||
| 1025 | * Place the data bus in a high impedance state, if @p->modes has the | ||
| 1026 | * PARPORT_MODE_TRISTATE bit set. | ||
| 1027 | */ | ||
| 1028 | static inline void parport_ip32_data_reverse(struct parport *p) | ||
| 1029 | { | ||
| 1030 | __parport_ip32_frob_control(p, DCR_DIR, DCR_DIR); | ||
| 1031 | } | ||
| 1032 | |||
| 1033 | /** | ||
| 1034 | * parport_ip32_init_state - for core parport code | ||
| 1035 | * @dev: pointer to &struct pardevice | ||
| 1036 | * @s: pointer to &struct parport_state to initialize | ||
| 1037 | */ | ||
| 1038 | static void parport_ip32_init_state(struct pardevice *dev, | ||
| 1039 | struct parport_state *s) | ||
| 1040 | { | ||
| 1041 | s->u.ip32.dcr = DCR_SELECT | DCR_nINIT; | ||
| 1042 | s->u.ip32.ecr = ECR_MODE_PS2 | ECR_nERRINTR | ECR_SERVINTR; | ||
| 1043 | } | ||
| 1044 | |||
| 1045 | /** | ||
| 1046 | * parport_ip32_save_state - for core parport code | ||
| 1047 | * @p: pointer to &struct parport | ||
| 1048 | * @s: pointer to &struct parport_state to save state to | ||
| 1049 | */ | ||
| 1050 | static void parport_ip32_save_state(struct parport *p, | ||
| 1051 | struct parport_state *s) | ||
| 1052 | { | ||
| 1053 | s->u.ip32.dcr = __parport_ip32_read_control(p); | ||
| 1054 | s->u.ip32.ecr = parport_ip32_read_econtrol(p); | ||
| 1055 | } | ||
| 1056 | |||
| 1057 | /** | ||
| 1058 | * parport_ip32_restore_state - for core parport code | ||
| 1059 | * @p: pointer to &struct parport | ||
| 1060 | * @s: pointer to &struct parport_state to restore state from | ||
| 1061 | */ | ||
| 1062 | static void parport_ip32_restore_state(struct parport *p, | ||
| 1063 | struct parport_state *s) | ||
| 1064 | { | ||
| 1065 | parport_ip32_set_mode(p, s->u.ip32.ecr & ECR_MODE_MASK); | ||
| 1066 | parport_ip32_write_econtrol(p, s->u.ip32.ecr); | ||
| 1067 | __parport_ip32_write_control(p, s->u.ip32.dcr); | ||
| 1068 | } | ||
| 1069 | |||
| 1070 | /*--- EPP mode functions -----------------------------------------------*/ | ||
| 1071 | |||
| 1072 | /** | ||
| 1073 | * parport_ip32_clear_epp_timeout - clear Timeout bit in EPP mode | ||
| 1074 | * @p: pointer to &struct parport | ||
| 1075 | * | ||
| 1076 | * Returns 1 if the Timeout bit is clear, and 0 otherwise. | ||
| 1077 | */ | ||
| 1078 | static unsigned int parport_ip32_clear_epp_timeout(struct parport *p) | ||
| 1079 | { | ||
| 1080 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 1081 | unsigned int cleared; | ||
| 1082 | |||
| 1083 | if (!(parport_ip32_read_status(p) & DSR_TIMEOUT)) | ||
| 1084 | cleared = 1; | ||
| 1085 | else { | ||
| 1086 | unsigned int r; | ||
| 1087 | /* To clear timeout some chips require double read */ | ||
| 1088 | parport_ip32_read_status(p); | ||
| 1089 | r = parport_ip32_read_status(p); | ||
| 1090 | /* Some reset by writing 1 */ | ||
| 1091 | writeb(r | DSR_TIMEOUT, priv->regs.dsr); | ||
| 1092 | /* Others by writing 0 */ | ||
| 1093 | writeb(r & ~DSR_TIMEOUT, priv->regs.dsr); | ||
| 1094 | |||
| 1095 | r = parport_ip32_read_status(p); | ||
| 1096 | cleared = !(r & DSR_TIMEOUT); | ||
| 1097 | } | ||
| 1098 | |||
| 1099 | pr_trace(p, "(): %s", cleared ? "cleared" : "failed"); | ||
| 1100 | return cleared; | ||
| 1101 | } | ||
| 1102 | |||
| 1103 | /** | ||
| 1104 | * parport_ip32_epp_read - generic EPP read function | ||
| 1105 | * @eppreg: I/O register to read from | ||
| 1106 | * @p: pointer to &struct parport | ||
| 1107 | * @buf: buffer to store read data | ||
| 1108 | * @len: length of buffer @buf | ||
| 1109 | * @flags: may be PARPORT_EPP_FAST | ||
| 1110 | */ | ||
| 1111 | static size_t parport_ip32_epp_read(void __iomem *eppreg, | ||
| 1112 | struct parport *p, void *buf, | ||
| 1113 | size_t len, int flags) | ||
| 1114 | { | ||
| 1115 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 1116 | size_t got; | ||
| 1117 | parport_ip32_set_mode(p, ECR_MODE_EPP); | ||
| 1118 | parport_ip32_data_reverse(p); | ||
| 1119 | parport_ip32_write_control(p, DCR_nINIT); | ||
| 1120 | if ((flags & PARPORT_EPP_FAST) && (len > 1)) { | ||
| 1121 | readsb(eppreg, buf, len); | ||
| 1122 | if (readb(priv->regs.dsr) & DSR_TIMEOUT) { | ||
| 1123 | parport_ip32_clear_epp_timeout(p); | ||
| 1124 | return -EIO; | ||
| 1125 | } | ||
| 1126 | got = len; | ||
| 1127 | } else { | ||
| 1128 | u8 *bufp = buf; | ||
| 1129 | for (got = 0; got < len; got++) { | ||
| 1130 | *bufp++ = readb(eppreg); | ||
| 1131 | if (readb(priv->regs.dsr) & DSR_TIMEOUT) { | ||
| 1132 | parport_ip32_clear_epp_timeout(p); | ||
| 1133 | break; | ||
| 1134 | } | ||
| 1135 | } | ||
| 1136 | } | ||
| 1137 | parport_ip32_data_forward(p); | ||
| 1138 | parport_ip32_set_mode(p, ECR_MODE_PS2); | ||
| 1139 | return got; | ||
| 1140 | } | ||
| 1141 | |||
| 1142 | /** | ||
| 1143 | * parport_ip32_epp_write - generic EPP write function | ||
| 1144 | * @eppreg: I/O register to write to | ||
| 1145 | * @p: pointer to &struct parport | ||
| 1146 | * @buf: buffer of data to write | ||
| 1147 | * @len: length of buffer @buf | ||
| 1148 | * @flags: may be PARPORT_EPP_FAST | ||
| 1149 | */ | ||
| 1150 | static size_t parport_ip32_epp_write(void __iomem *eppreg, | ||
| 1151 | struct parport *p, const void *buf, | ||
| 1152 | size_t len, int flags) | ||
| 1153 | { | ||
| 1154 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 1155 | size_t written; | ||
| 1156 | parport_ip32_set_mode(p, ECR_MODE_EPP); | ||
| 1157 | parport_ip32_data_forward(p); | ||
| 1158 | parport_ip32_write_control(p, DCR_nINIT); | ||
| 1159 | if ((flags & PARPORT_EPP_FAST) && (len > 1)) { | ||
| 1160 | writesb(eppreg, buf, len); | ||
| 1161 | if (readb(priv->regs.dsr) & DSR_TIMEOUT) { | ||
| 1162 | parport_ip32_clear_epp_timeout(p); | ||
| 1163 | return -EIO; | ||
| 1164 | } | ||
| 1165 | written = len; | ||
| 1166 | } else { | ||
| 1167 | const u8 *bufp = buf; | ||
| 1168 | for (written = 0; written < len; written++) { | ||
| 1169 | writeb(*bufp++, eppreg); | ||
| 1170 | if (readb(priv->regs.dsr) & DSR_TIMEOUT) { | ||
| 1171 | parport_ip32_clear_epp_timeout(p); | ||
| 1172 | break; | ||
| 1173 | } | ||
| 1174 | } | ||
| 1175 | } | ||
| 1176 | parport_ip32_set_mode(p, ECR_MODE_PS2); | ||
| 1177 | return written; | ||
| 1178 | } | ||
| 1179 | |||
| 1180 | /** | ||
| 1181 | * parport_ip32_epp_read_data - read a block of data in EPP mode | ||
| 1182 | * @p: pointer to &struct parport | ||
| 1183 | * @buf: buffer to store read data | ||
| 1184 | * @len: length of buffer @buf | ||
| 1185 | * @flags: may be PARPORT_EPP_FAST | ||
| 1186 | */ | ||
| 1187 | static size_t parport_ip32_epp_read_data(struct parport *p, void *buf, | ||
| 1188 | size_t len, int flags) | ||
| 1189 | { | ||
| 1190 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 1191 | return parport_ip32_epp_read(priv->regs.eppData0, p, buf, len, flags); | ||
| 1192 | } | ||
| 1193 | |||
| 1194 | /** | ||
| 1195 | * parport_ip32_epp_write_data - write a block of data in EPP mode | ||
| 1196 | * @p: pointer to &struct parport | ||
| 1197 | * @buf: buffer of data to write | ||
| 1198 | * @len: length of buffer @buf | ||
| 1199 | * @flags: may be PARPORT_EPP_FAST | ||
| 1200 | */ | ||
| 1201 | static size_t parport_ip32_epp_write_data(struct parport *p, const void *buf, | ||
| 1202 | size_t len, int flags) | ||
| 1203 | { | ||
| 1204 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 1205 | return parport_ip32_epp_write(priv->regs.eppData0, p, buf, len, flags); | ||
| 1206 | } | ||
| 1207 | |||
| 1208 | /** | ||
| 1209 | * parport_ip32_epp_read_addr - read a block of addresses in EPP mode | ||
| 1210 | * @p: pointer to &struct parport | ||
| 1211 | * @buf: buffer to store read data | ||
| 1212 | * @len: length of buffer @buf | ||
| 1213 | * @flags: may be PARPORT_EPP_FAST | ||
| 1214 | */ | ||
| 1215 | static size_t parport_ip32_epp_read_addr(struct parport *p, void *buf, | ||
| 1216 | size_t len, int flags) | ||
| 1217 | { | ||
| 1218 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 1219 | return parport_ip32_epp_read(priv->regs.eppAddr, p, buf, len, flags); | ||
| 1220 | } | ||
| 1221 | |||
| 1222 | /** | ||
| 1223 | * parport_ip32_epp_write_addr - write a block of addresses in EPP mode | ||
| 1224 | * @p: pointer to &struct parport | ||
| 1225 | * @buf: buffer of data to write | ||
| 1226 | * @len: length of buffer @buf | ||
| 1227 | * @flags: may be PARPORT_EPP_FAST | ||
| 1228 | */ | ||
| 1229 | static size_t parport_ip32_epp_write_addr(struct parport *p, const void *buf, | ||
| 1230 | size_t len, int flags) | ||
| 1231 | { | ||
| 1232 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 1233 | return parport_ip32_epp_write(priv->regs.eppAddr, p, buf, len, flags); | ||
| 1234 | } | ||
| 1235 | |||
| 1236 | /*--- ECP mode functions (FIFO) ----------------------------------------*/ | ||
| 1237 | |||
| 1238 | /** | ||
| 1239 | * parport_ip32_fifo_wait_break - check if the waiting function should return | ||
| 1240 | * @p: pointer to &struct parport | ||
| 1241 | * @expire: timeout expiring date, in jiffies | ||
| 1242 | * | ||
| 1243 | * parport_ip32_fifo_wait_break() checks if the waiting function should return | ||
| 1244 | * immediately or not. The break conditions are: | ||
| 1245 | * - expired timeout; | ||
| 1246 | * - a pending signal; | ||
| 1247 | * - nFault asserted low. | ||
| 1248 | * This function also calls cond_resched(). | ||
| 1249 | */ | ||
| 1250 | static unsigned int parport_ip32_fifo_wait_break(struct parport *p, | ||
| 1251 | unsigned long expire) | ||
| 1252 | { | ||
| 1253 | cond_resched(); | ||
| 1254 | if (time_after(jiffies, expire)) { | ||
| 1255 | pr_debug1(PPIP32 "%s: FIFO write timed out\n", p->name); | ||
| 1256 | return 1; | ||
| 1257 | } | ||
| 1258 | if (signal_pending(current)) { | ||
| 1259 | pr_debug1(PPIP32 "%s: Signal pending\n", p->name); | ||
| 1260 | return 1; | ||
| 1261 | } | ||
| 1262 | if (!(parport_ip32_read_status(p) & DSR_nFAULT)) { | ||
| 1263 | pr_debug1(PPIP32 "%s: nFault asserted low\n", p->name); | ||
| 1264 | return 1; | ||
| 1265 | } | ||
| 1266 | return 0; | ||
| 1267 | } | ||
| 1268 | |||
| 1269 | /** | ||
| 1270 | * parport_ip32_fwp_wait_polling - wait for FIFO to empty (polling) | ||
| 1271 | * @p: pointer to &struct parport | ||
| 1272 | * | ||
| 1273 | * Returns the number of bytes that can safely be written in the FIFO. A | ||
| 1274 | * return value of zero means that the calling function should terminate as | ||
| 1275 | * fast as possible. | ||
| 1276 | */ | ||
| 1277 | static unsigned int parport_ip32_fwp_wait_polling(struct parport *p) | ||
| 1278 | { | ||
| 1279 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 1280 | struct parport * const physport = p->physport; | ||
| 1281 | unsigned long expire; | ||
| 1282 | unsigned int count; | ||
| 1283 | unsigned int ecr; | ||
| 1284 | |||
| 1285 | expire = jiffies + physport->cad->timeout; | ||
| 1286 | count = 0; | ||
| 1287 | while (1) { | ||
| 1288 | if (parport_ip32_fifo_wait_break(p, expire)) | ||
| 1289 | break; | ||
| 1290 | |||
| 1291 | /* Check FIFO state. We do nothing when the FIFO is nor full, | ||
| 1292 | * nor empty. It appears that the FIFO full bit is not always | ||
| 1293 | * reliable, the FIFO state is sometimes wrongly reported, and | ||
| 1294 | * the chip gets confused if we give it another byte. */ | ||
| 1295 | ecr = parport_ip32_read_econtrol(p); | ||
| 1296 | if (ecr & ECR_F_EMPTY) { | ||
| 1297 | /* FIFO is empty, fill it up */ | ||
| 1298 | count = priv->fifo_depth; | ||
| 1299 | break; | ||
| 1300 | } | ||
| 1301 | |||
| 1302 | /* Wait a moment... */ | ||
| 1303 | udelay(FIFO_POLLING_INTERVAL); | ||
| 1304 | } /* while (1) */ | ||
| 1305 | |||
| 1306 | return count; | ||
| 1307 | } | ||
| 1308 | |||
| 1309 | /** | ||
| 1310 | * parport_ip32_fwp_wait_interrupt - wait for FIFO to empty (interrupt-driven) | ||
| 1311 | * @p: pointer to &struct parport | ||
| 1312 | * | ||
| 1313 | * Returns the number of bytes that can safely be written in the FIFO. A | ||
| 1314 | * return value of zero means that the calling function should terminate as | ||
| 1315 | * fast as possible. | ||
| 1316 | */ | ||
| 1317 | static unsigned int parport_ip32_fwp_wait_interrupt(struct parport *p) | ||
| 1318 | { | ||
| 1319 | static unsigned int lost_interrupt = 0; | ||
| 1320 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 1321 | struct parport * const physport = p->physport; | ||
| 1322 | unsigned long nfault_timeout; | ||
| 1323 | unsigned long expire; | ||
| 1324 | unsigned int count; | ||
| 1325 | unsigned int ecr; | ||
| 1326 | |||
| 1327 | nfault_timeout = min((unsigned long)physport->cad->timeout, | ||
| 1328 | msecs_to_jiffies(FIFO_NFAULT_TIMEOUT)); | ||
| 1329 | expire = jiffies + physport->cad->timeout; | ||
| 1330 | count = 0; | ||
| 1331 | while (1) { | ||
| 1332 | if (parport_ip32_fifo_wait_break(p, expire)) | ||
| 1333 | break; | ||
| 1334 | |||
| 1335 | /* Initialize mutex used to take interrupts into account */ | ||
| 1336 | INIT_COMPLETION(priv->irq_complete); | ||
| 1337 | |||
| 1338 | /* Enable serviceIntr */ | ||
| 1339 | parport_ip32_frob_econtrol(p, ECR_SERVINTR, 0); | ||
| 1340 | |||
| 1341 | /* Enabling serviceIntr while the FIFO is empty does not | ||
| 1342 | * always generate an interrupt, so check for emptiness | ||
| 1343 | * now. */ | ||
| 1344 | ecr = parport_ip32_read_econtrol(p); | ||
| 1345 | if (!(ecr & ECR_F_EMPTY)) { | ||
| 1346 | /* FIFO is not empty: wait for an interrupt or a | ||
| 1347 | * timeout to occur */ | ||
| 1348 | wait_for_completion_interruptible_timeout( | ||
| 1349 | &priv->irq_complete, nfault_timeout); | ||
| 1350 | ecr = parport_ip32_read_econtrol(p); | ||
| 1351 | if ((ecr & ECR_F_EMPTY) && !(ecr & ECR_SERVINTR) | ||
| 1352 | && !lost_interrupt) { | ||
| 1353 | printk(KERN_WARNING PPIP32 | ||
| 1354 | "%s: lost interrupt in %s\n", | ||
| 1355 | p->name, __func__); | ||
| 1356 | lost_interrupt = 1; | ||
| 1357 | } | ||
| 1358 | } | ||
| 1359 | |||
| 1360 | /* Disable serviceIntr */ | ||
| 1361 | parport_ip32_frob_econtrol(p, ECR_SERVINTR, ECR_SERVINTR); | ||
| 1362 | |||
| 1363 | /* Check FIFO state */ | ||
| 1364 | if (ecr & ECR_F_EMPTY) { | ||
| 1365 | /* FIFO is empty, fill it up */ | ||
| 1366 | count = priv->fifo_depth; | ||
| 1367 | break; | ||
| 1368 | } else if (ecr & ECR_SERVINTR) { | ||
| 1369 | /* FIFO is not empty, but we know that can safely push | ||
| 1370 | * writeIntrThreshold bytes into it */ | ||
| 1371 | count = priv->writeIntrThreshold; | ||
| 1372 | break; | ||
| 1373 | } | ||
| 1374 | /* FIFO is not empty, and we did not get any interrupt. | ||
| 1375 | * Either it's time to check for nFault, or a signal is | ||
| 1376 | * pending. This is verified in | ||
| 1377 | * parport_ip32_fifo_wait_break(), so we continue the loop. */ | ||
| 1378 | } /* while (1) */ | ||
| 1379 | |||
| 1380 | return count; | ||
| 1381 | } | ||
| 1382 | |||
| 1383 | /** | ||
| 1384 | * parport_ip32_fifo_write_block_pio - write a block of data (PIO mode) | ||
| 1385 | * @p: pointer to &struct parport | ||
| 1386 | * @buf: buffer of data to write | ||
| 1387 | * @len: length of buffer @buf | ||
| 1388 | * | ||
| 1389 | * Uses PIO to write the contents of the buffer @buf into the parallel port | ||
| 1390 | * FIFO. Returns the number of bytes that were actually written. It can work | ||
| 1391 | * with or without the help of interrupts. The parallel port must be | ||
| 1392 | * correctly initialized before calling parport_ip32_fifo_write_block_pio(). | ||
| 1393 | */ | ||
| 1394 | static size_t parport_ip32_fifo_write_block_pio(struct parport *p, | ||
| 1395 | const void *buf, size_t len) | ||
| 1396 | { | ||
| 1397 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 1398 | const u8 *bufp = buf; | ||
| 1399 | size_t left = len; | ||
| 1400 | |||
| 1401 | priv->irq_mode = PARPORT_IP32_IRQ_HERE; | ||
| 1402 | |||
| 1403 | while (left > 0) { | ||
| 1404 | unsigned int count; | ||
| 1405 | |||
| 1406 | count = (p->irq == PARPORT_IRQ_NONE) ? | ||
| 1407 | parport_ip32_fwp_wait_polling(p) : | ||
| 1408 | parport_ip32_fwp_wait_interrupt(p); | ||
| 1409 | if (count == 0) | ||
| 1410 | break; /* Transmission should be stopped */ | ||
| 1411 | if (count > left) | ||
| 1412 | count = left; | ||
| 1413 | if (count == 1) { | ||
| 1414 | writeb(*bufp, priv->regs.fifo); | ||
| 1415 | bufp++, left--; | ||
| 1416 | } else { | ||
| 1417 | writesb(priv->regs.fifo, bufp, count); | ||
| 1418 | bufp += count, left -= count; | ||
| 1419 | } | ||
| 1420 | } | ||
| 1421 | |||
| 1422 | priv->irq_mode = PARPORT_IP32_IRQ_FWD; | ||
| 1423 | |||
| 1424 | return len - left; | ||
| 1425 | } | ||
| 1426 | |||
| 1427 | /** | ||
| 1428 | * parport_ip32_fifo_write_block_dma - write a block of data (DMA mode) | ||
| 1429 | * @p: pointer to &struct parport | ||
| 1430 | * @buf: buffer of data to write | ||
| 1431 | * @len: length of buffer @buf | ||
| 1432 | * | ||
| 1433 | * Uses DMA to write the contents of the buffer @buf into the parallel port | ||
| 1434 | * FIFO. Returns the number of bytes that were actually written. The | ||
| 1435 | * parallel port must be correctly initialized before calling | ||
| 1436 | * parport_ip32_fifo_write_block_dma(). | ||
| 1437 | */ | ||
| 1438 | static size_t parport_ip32_fifo_write_block_dma(struct parport *p, | ||
| 1439 | const void *buf, size_t len) | ||
| 1440 | { | ||
| 1441 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 1442 | struct parport * const physport = p->physport; | ||
| 1443 | unsigned long nfault_timeout; | ||
| 1444 | unsigned long expire; | ||
| 1445 | size_t written; | ||
| 1446 | unsigned int ecr; | ||
| 1447 | |||
| 1448 | priv->irq_mode = PARPORT_IP32_IRQ_HERE; | ||
| 1449 | |||
| 1450 | parport_ip32_dma_start(DMA_TO_DEVICE, (void *)buf, len); | ||
| 1451 | INIT_COMPLETION(priv->irq_complete); | ||
| 1452 | parport_ip32_frob_econtrol(p, ECR_DMAEN | ECR_SERVINTR, ECR_DMAEN); | ||
| 1453 | |||
| 1454 | nfault_timeout = min((unsigned long)physport->cad->timeout, | ||
| 1455 | msecs_to_jiffies(FIFO_NFAULT_TIMEOUT)); | ||
| 1456 | expire = jiffies + physport->cad->timeout; | ||
| 1457 | while (1) { | ||
| 1458 | if (parport_ip32_fifo_wait_break(p, expire)) | ||
| 1459 | break; | ||
| 1460 | wait_for_completion_interruptible_timeout(&priv->irq_complete, | ||
| 1461 | nfault_timeout); | ||
| 1462 | ecr = parport_ip32_read_econtrol(p); | ||
| 1463 | if (ecr & ECR_SERVINTR) | ||
| 1464 | break; /* DMA transfer just finished */ | ||
| 1465 | } | ||
| 1466 | parport_ip32_dma_stop(); | ||
| 1467 | written = len - parport_ip32_dma_get_residue(); | ||
| 1468 | |||
| 1469 | priv->irq_mode = PARPORT_IP32_IRQ_FWD; | ||
| 1470 | |||
| 1471 | return written; | ||
| 1472 | } | ||
| 1473 | |||
| 1474 | /** | ||
| 1475 | * parport_ip32_fifo_write_block - write a block of data | ||
| 1476 | * @p: pointer to &struct parport | ||
| 1477 | * @buf: buffer of data to write | ||
| 1478 | * @len: length of buffer @buf | ||
| 1479 | * | ||
| 1480 | * Uses PIO or DMA to write the contents of the buffer @buf into the parallel | ||
| 1481 | * p FIFO. Returns the number of bytes that were actually written. | ||
| 1482 | */ | ||
| 1483 | static size_t parport_ip32_fifo_write_block(struct parport *p, | ||
| 1484 | const void *buf, size_t len) | ||
| 1485 | { | ||
| 1486 | size_t written = 0; | ||
| 1487 | if (len) | ||
| 1488 | /* FIXME - Maybe some threshold value should be set for @len | ||
| 1489 | * under which we revert to PIO mode? */ | ||
| 1490 | written = (p->modes & PARPORT_MODE_DMA) ? | ||
| 1491 | parport_ip32_fifo_write_block_dma(p, buf, len) : | ||
| 1492 | parport_ip32_fifo_write_block_pio(p, buf, len); | ||
| 1493 | return written; | ||
| 1494 | } | ||
| 1495 | |||
| 1496 | /** | ||
| 1497 | * parport_ip32_drain_fifo - wait for FIFO to empty | ||
| 1498 | * @p: pointer to &struct parport | ||
| 1499 | * @timeout: timeout, in jiffies | ||
| 1500 | * | ||
| 1501 | * This function waits for FIFO to empty. It returns 1 when FIFO is empty, or | ||
| 1502 | * 0 if the timeout @timeout is reached before, or if a signal is pending. | ||
| 1503 | */ | ||
| 1504 | static unsigned int parport_ip32_drain_fifo(struct parport *p, | ||
| 1505 | unsigned long timeout) | ||
| 1506 | { | ||
| 1507 | unsigned long expire = jiffies + timeout; | ||
| 1508 | unsigned int polling_interval; | ||
| 1509 | unsigned int counter; | ||
| 1510 | |||
| 1511 | /* Busy wait for approx. 200us */ | ||
| 1512 | for (counter = 0; counter < 40; counter++) { | ||
| 1513 | if (parport_ip32_read_econtrol(p) & ECR_F_EMPTY) | ||
| 1514 | break; | ||
| 1515 | if (time_after(jiffies, expire)) | ||
| 1516 | break; | ||
| 1517 | if (signal_pending(current)) | ||
| 1518 | break; | ||
| 1519 | udelay(5); | ||
| 1520 | } | ||
| 1521 | /* Poll slowly. Polling interval starts with 1 millisecond, and is | ||
| 1522 | * increased exponentially until 128. */ | ||
| 1523 | polling_interval = 1; /* msecs */ | ||
| 1524 | while (!(parport_ip32_read_econtrol(p) & ECR_F_EMPTY)) { | ||
| 1525 | if (time_after_eq(jiffies, expire)) | ||
| 1526 | break; | ||
| 1527 | msleep_interruptible(polling_interval); | ||
| 1528 | if (signal_pending(current)) | ||
| 1529 | break; | ||
| 1530 | if (polling_interval < 128) | ||
| 1531 | polling_interval *= 2; | ||
| 1532 | } | ||
| 1533 | |||
| 1534 | return !!(parport_ip32_read_econtrol(p) & ECR_F_EMPTY); | ||
| 1535 | } | ||
| 1536 | |||
| 1537 | /** | ||
| 1538 | * parport_ip32_get_fifo_residue - reset FIFO | ||
| 1539 | * @p: pointer to &struct parport | ||
| 1540 | * @mode: current operation mode (ECR_MODE_PPF or ECR_MODE_ECP) | ||
| 1541 | * | ||
| 1542 | * This function resets FIFO, and returns the number of bytes remaining in it. | ||
| 1543 | */ | ||
| 1544 | static unsigned int parport_ip32_get_fifo_residue(struct parport *p, | ||
| 1545 | unsigned int mode) | ||
| 1546 | { | ||
| 1547 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 1548 | unsigned int residue; | ||
| 1549 | unsigned int cnfga; | ||
| 1550 | |||
| 1551 | /* FIXME - We are missing one byte if the printer is off-line. I | ||
| 1552 | * don't know how to detect this. It looks that the full bit is not | ||
| 1553 | * always reliable. For the moment, the problem is avoided in most | ||
| 1554 | * cases by testing for BUSY in parport_ip32_compat_write_data(). | ||
| 1555 | */ | ||
| 1556 | if (parport_ip32_read_econtrol(p) & ECR_F_EMPTY) | ||
| 1557 | residue = 0; | ||
| 1558 | else { | ||
| 1559 | pr_debug1(PPIP32 "%s: FIFO is stuck\n", p->name); | ||
| 1560 | |||
| 1561 | /* Stop all transfers. | ||
| 1562 | * | ||
| 1563 | * Microsoft's document instructs to drive DCR_STROBE to 0, | ||
| 1564 | * but it doesn't work (at least in Compatibility mode, not | ||
| 1565 | * tested in ECP mode). Switching directly to Test mode (as | ||
| 1566 | * in parport_pc) is not an option: it does confuse the port, | ||
| 1567 | * ECP service interrupts are no more working after that. A | ||
| 1568 | * hard reset is then needed to revert to a sane state. | ||
| 1569 | * | ||
| 1570 | * Let's hope that the FIFO is really stuck and that the | ||
| 1571 | * peripheral doesn't wake up now. | ||
| 1572 | */ | ||
| 1573 | parport_ip32_frob_control(p, DCR_STROBE, 0); | ||
| 1574 | |||
| 1575 | /* Fill up FIFO */ | ||
| 1576 | for (residue = priv->fifo_depth; residue > 0; residue--) { | ||
| 1577 | if (parport_ip32_read_econtrol(p) & ECR_F_FULL) | ||
| 1578 | break; | ||
| 1579 | writeb(0x00, priv->regs.fifo); | ||
| 1580 | } | ||
| 1581 | } | ||
| 1582 | if (residue) | ||
| 1583 | pr_debug1(PPIP32 "%s: %d PWord%s left in FIFO\n", | ||
| 1584 | p->name, residue, | ||
| 1585 | (residue == 1) ? " was" : "s were"); | ||
| 1586 | |||
| 1587 | /* Now reset the FIFO */ | ||
| 1588 | parport_ip32_set_mode(p, ECR_MODE_PS2); | ||
| 1589 | |||
| 1590 | /* Host recovery for ECP mode */ | ||
| 1591 | if (mode == ECR_MODE_ECP) { | ||
| 1592 | parport_ip32_data_reverse(p); | ||
| 1593 | parport_ip32_frob_control(p, DCR_nINIT, 0); | ||
| 1594 | if (parport_wait_peripheral(p, DSR_PERROR, 0)) | ||
| 1595 | pr_debug1(PPIP32 "%s: PEerror timeout 1 in %s\n", | ||
| 1596 | p->name, __func__); | ||
| 1597 | parport_ip32_frob_control(p, DCR_STROBE, DCR_STROBE); | ||
| 1598 | parport_ip32_frob_control(p, DCR_nINIT, DCR_nINIT); | ||
| 1599 | if (parport_wait_peripheral(p, DSR_PERROR, DSR_PERROR)) | ||
| 1600 | pr_debug1(PPIP32 "%s: PEerror timeout 2 in %s\n", | ||
| 1601 | p->name, __func__); | ||
| 1602 | } | ||
| 1603 | |||
| 1604 | /* Adjust residue if needed */ | ||
| 1605 | parport_ip32_set_mode(p, ECR_MODE_CFG); | ||
| 1606 | cnfga = readb(priv->regs.cnfgA); | ||
| 1607 | if (!(cnfga & CNFGA_nBYTEINTRANS)) { | ||
| 1608 | pr_debug1(PPIP32 "%s: cnfgA contains 0x%02x\n", | ||
| 1609 | p->name, cnfga); | ||
| 1610 | pr_debug1(PPIP32 "%s: Accounting for extra byte\n", | ||
| 1611 | p->name); | ||
| 1612 | residue++; | ||
| 1613 | } | ||
| 1614 | |||
| 1615 | /* Don't care about partial PWords since we do not support | ||
| 1616 | * PWord != 1 byte. */ | ||
| 1617 | |||
| 1618 | /* Back to forward PS2 mode. */ | ||
| 1619 | parport_ip32_set_mode(p, ECR_MODE_PS2); | ||
| 1620 | parport_ip32_data_forward(p); | ||
| 1621 | |||
| 1622 | return residue; | ||
| 1623 | } | ||
| 1624 | |||
| 1625 | /** | ||
| 1626 | * parport_ip32_compat_write_data - write a block of data in SPP mode | ||
| 1627 | * @p: pointer to &struct parport | ||
| 1628 | * @buf: buffer of data to write | ||
| 1629 | * @len: length of buffer @buf | ||
| 1630 | * @flags: ignored | ||
| 1631 | */ | ||
| 1632 | static size_t parport_ip32_compat_write_data(struct parport *p, | ||
| 1633 | const void *buf, size_t len, | ||
| 1634 | int flags) | ||
| 1635 | { | ||
| 1636 | static unsigned int ready_before = 1; | ||
| 1637 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 1638 | struct parport * const physport = p->physport; | ||
| 1639 | size_t written = 0; | ||
| 1640 | |||
| 1641 | /* Special case: a timeout of zero means we cannot call schedule(). | ||
| 1642 | * Also if O_NONBLOCK is set then use the default implementation. */ | ||
| 1643 | if (physport->cad->timeout <= PARPORT_INACTIVITY_O_NONBLOCK) | ||
| 1644 | return parport_ieee1284_write_compat(p, buf, len, flags); | ||
| 1645 | |||
| 1646 | /* Reset FIFO, go in forward mode, and disable ackIntEn */ | ||
| 1647 | parport_ip32_set_mode(p, ECR_MODE_PS2); | ||
| 1648 | parport_ip32_write_control(p, DCR_SELECT | DCR_nINIT); | ||
| 1649 | parport_ip32_data_forward(p); | ||
| 1650 | parport_ip32_disable_irq(p); | ||
| 1651 | parport_ip32_set_mode(p, ECR_MODE_PPF); | ||
| 1652 | physport->ieee1284.phase = IEEE1284_PH_FWD_DATA; | ||
| 1653 | |||
| 1654 | /* Wait for peripheral to become ready */ | ||
| 1655 | if (parport_wait_peripheral(p, DSR_nBUSY | DSR_nFAULT, | ||
| 1656 | DSR_nBUSY | DSR_nFAULT)) { | ||
| 1657 | /* Avoid to flood the logs */ | ||
| 1658 | if (ready_before) | ||
| 1659 | printk(KERN_INFO PPIP32 "%s: not ready in %s\n", | ||
| 1660 | p->name, __func__); | ||
| 1661 | ready_before = 0; | ||
| 1662 | goto stop; | ||
| 1663 | } | ||
| 1664 | ready_before = 1; | ||
| 1665 | |||
| 1666 | written = parport_ip32_fifo_write_block(p, buf, len); | ||
| 1667 | |||
| 1668 | /* Wait FIFO to empty. Timeout is proportional to FIFO_depth. */ | ||
| 1669 | parport_ip32_drain_fifo(p, physport->cad->timeout * priv->fifo_depth); | ||
| 1670 | |||
| 1671 | /* Check for a potential residue */ | ||
| 1672 | written -= parport_ip32_get_fifo_residue(p, ECR_MODE_PPF); | ||
| 1673 | |||
| 1674 | /* Then, wait for BUSY to get low. */ | ||
| 1675 | if (parport_wait_peripheral(p, DSR_nBUSY, DSR_nBUSY)) | ||
| 1676 | printk(KERN_DEBUG PPIP32 "%s: BUSY timeout in %s\n", | ||
| 1677 | p->name, __func__); | ||
| 1678 | |||
| 1679 | stop: | ||
| 1680 | /* Reset FIFO */ | ||
| 1681 | parport_ip32_set_mode(p, ECR_MODE_PS2); | ||
| 1682 | physport->ieee1284.phase = IEEE1284_PH_FWD_IDLE; | ||
| 1683 | |||
| 1684 | return written; | ||
| 1685 | } | ||
| 1686 | |||
| 1687 | /* | ||
| 1688 | * FIXME - Insert here parport_ip32_ecp_read_data(). | ||
| 1689 | */ | ||
| 1690 | |||
| 1691 | /** | ||
| 1692 | * parport_ip32_ecp_write_data - write a block of data in ECP mode | ||
| 1693 | * @p: pointer to &struct parport | ||
| 1694 | * @buf: buffer of data to write | ||
| 1695 | * @len: length of buffer @buf | ||
| 1696 | * @flags: ignored | ||
| 1697 | */ | ||
| 1698 | static size_t parport_ip32_ecp_write_data(struct parport *p, | ||
| 1699 | const void *buf, size_t len, | ||
| 1700 | int flags) | ||
| 1701 | { | ||
| 1702 | static unsigned int ready_before = 1; | ||
| 1703 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 1704 | struct parport * const physport = p->physport; | ||
| 1705 | size_t written = 0; | ||
| 1706 | |||
| 1707 | /* Special case: a timeout of zero means we cannot call schedule(). | ||
| 1708 | * Also if O_NONBLOCK is set then use the default implementation. */ | ||
| 1709 | if (physport->cad->timeout <= PARPORT_INACTIVITY_O_NONBLOCK) | ||
| 1710 | return parport_ieee1284_ecp_write_data(p, buf, len, flags); | ||
| 1711 | |||
| 1712 | /* Negotiate to forward mode if necessary. */ | ||
| 1713 | if (physport->ieee1284.phase != IEEE1284_PH_FWD_IDLE) { | ||
| 1714 | /* Event 47: Set nInit high. */ | ||
| 1715 | parport_ip32_frob_control(p, DCR_nINIT | DCR_AUTOFD, | ||
| 1716 | DCR_nINIT | DCR_AUTOFD); | ||
| 1717 | |||
| 1718 | /* Event 49: PError goes high. */ | ||
| 1719 | if (parport_wait_peripheral(p, DSR_PERROR, DSR_PERROR)) { | ||
| 1720 | printk(KERN_DEBUG PPIP32 "%s: PError timeout in %s", | ||
| 1721 | p->name, __func__); | ||
| 1722 | physport->ieee1284.phase = IEEE1284_PH_ECP_DIR_UNKNOWN; | ||
| 1723 | return 0; | ||
| 1724 | } | ||
| 1725 | } | ||
| 1726 | |||
| 1727 | /* Reset FIFO, go in forward mode, and disable ackIntEn */ | ||
| 1728 | parport_ip32_set_mode(p, ECR_MODE_PS2); | ||
| 1729 | parport_ip32_write_control(p, DCR_SELECT | DCR_nINIT); | ||
| 1730 | parport_ip32_data_forward(p); | ||
| 1731 | parport_ip32_disable_irq(p); | ||
| 1732 | parport_ip32_set_mode(p, ECR_MODE_ECP); | ||
| 1733 | physport->ieee1284.phase = IEEE1284_PH_FWD_DATA; | ||
| 1734 | |||
| 1735 | /* Wait for peripheral to become ready */ | ||
| 1736 | if (parport_wait_peripheral(p, DSR_nBUSY | DSR_nFAULT, | ||
| 1737 | DSR_nBUSY | DSR_nFAULT)) { | ||
| 1738 | /* Avoid to flood the logs */ | ||
| 1739 | if (ready_before) | ||
| 1740 | printk(KERN_INFO PPIP32 "%s: not ready in %s\n", | ||
| 1741 | p->name, __func__); | ||
| 1742 | ready_before = 0; | ||
| 1743 | goto stop; | ||
| 1744 | } | ||
| 1745 | ready_before = 1; | ||
| 1746 | |||
| 1747 | written = parport_ip32_fifo_write_block(p, buf, len); | ||
| 1748 | |||
| 1749 | /* Wait FIFO to empty. Timeout is proportional to FIFO_depth. */ | ||
| 1750 | parport_ip32_drain_fifo(p, physport->cad->timeout * priv->fifo_depth); | ||
| 1751 | |||
| 1752 | /* Check for a potential residue */ | ||
| 1753 | written -= parport_ip32_get_fifo_residue(p, ECR_MODE_ECP); | ||
| 1754 | |||
| 1755 | /* Then, wait for BUSY to get low. */ | ||
| 1756 | if (parport_wait_peripheral(p, DSR_nBUSY, DSR_nBUSY)) | ||
| 1757 | printk(KERN_DEBUG PPIP32 "%s: BUSY timeout in %s\n", | ||
| 1758 | p->name, __func__); | ||
| 1759 | |||
| 1760 | stop: | ||
| 1761 | /* Reset FIFO */ | ||
| 1762 | parport_ip32_set_mode(p, ECR_MODE_PS2); | ||
| 1763 | physport->ieee1284.phase = IEEE1284_PH_FWD_IDLE; | ||
| 1764 | |||
| 1765 | return written; | ||
| 1766 | } | ||
| 1767 | |||
| 1768 | /* | ||
| 1769 | * FIXME - Insert here parport_ip32_ecp_write_addr(). | ||
| 1770 | */ | ||
| 1771 | |||
| 1772 | /*--- Default parport operations ---------------------------------------*/ | ||
| 1773 | |||
| 1774 | static __initdata struct parport_operations parport_ip32_ops = { | ||
| 1775 | .write_data = parport_ip32_write_data, | ||
| 1776 | .read_data = parport_ip32_read_data, | ||
| 1777 | |||
| 1778 | .write_control = parport_ip32_write_control, | ||
| 1779 | .read_control = parport_ip32_read_control, | ||
| 1780 | .frob_control = parport_ip32_frob_control, | ||
| 1781 | |||
| 1782 | .read_status = parport_ip32_read_status, | ||
| 1783 | |||
| 1784 | .enable_irq = parport_ip32_enable_irq, | ||
| 1785 | .disable_irq = parport_ip32_disable_irq, | ||
| 1786 | |||
| 1787 | .data_forward = parport_ip32_data_forward, | ||
| 1788 | .data_reverse = parport_ip32_data_reverse, | ||
| 1789 | |||
| 1790 | .init_state = parport_ip32_init_state, | ||
| 1791 | .save_state = parport_ip32_save_state, | ||
| 1792 | .restore_state = parport_ip32_restore_state, | ||
| 1793 | |||
| 1794 | .epp_write_data = parport_ieee1284_epp_write_data, | ||
| 1795 | .epp_read_data = parport_ieee1284_epp_read_data, | ||
| 1796 | .epp_write_addr = parport_ieee1284_epp_write_addr, | ||
| 1797 | .epp_read_addr = parport_ieee1284_epp_read_addr, | ||
| 1798 | |||
| 1799 | .ecp_write_data = parport_ieee1284_ecp_write_data, | ||
| 1800 | .ecp_read_data = parport_ieee1284_ecp_read_data, | ||
| 1801 | .ecp_write_addr = parport_ieee1284_ecp_write_addr, | ||
| 1802 | |||
| 1803 | .compat_write_data = parport_ieee1284_write_compat, | ||
| 1804 | .nibble_read_data = parport_ieee1284_read_nibble, | ||
| 1805 | .byte_read_data = parport_ieee1284_read_byte, | ||
| 1806 | |||
| 1807 | .owner = THIS_MODULE, | ||
| 1808 | }; | ||
| 1809 | |||
| 1810 | /*--- Device detection -------------------------------------------------*/ | ||
| 1811 | |||
| 1812 | /** | ||
| 1813 | * parport_ip32_ecp_supported - check for an ECP port | ||
| 1814 | * @p: pointer to the &parport structure | ||
| 1815 | * | ||
| 1816 | * Returns 1 if an ECP port is found, and 0 otherwise. This function actually | ||
| 1817 | * checks if an Extended Control Register seems to be present. On successful | ||
| 1818 | * return, the port is placed in SPP mode. | ||
| 1819 | */ | ||
| 1820 | static __init unsigned int parport_ip32_ecp_supported(struct parport *p) | ||
| 1821 | { | ||
| 1822 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 1823 | unsigned int ecr; | ||
| 1824 | |||
| 1825 | ecr = ECR_MODE_PS2 | ECR_nERRINTR | ECR_SERVINTR; | ||
| 1826 | writeb(ecr, priv->regs.ecr); | ||
| 1827 | if (readb(priv->regs.ecr) != (ecr | ECR_F_EMPTY)) | ||
| 1828 | goto fail; | ||
| 1829 | |||
| 1830 | pr_probe(p, "Found working ECR register\n"); | ||
| 1831 | parport_ip32_set_mode(p, ECR_MODE_SPP); | ||
| 1832 | parport_ip32_write_control(p, DCR_SELECT | DCR_nINIT); | ||
| 1833 | return 1; | ||
| 1834 | |||
| 1835 | fail: | ||
| 1836 | pr_probe(p, "ECR register not found\n"); | ||
| 1837 | return 0; | ||
| 1838 | } | ||
| 1839 | |||
| 1840 | /** | ||
| 1841 | * parport_ip32_fifo_supported - check for FIFO parameters | ||
| 1842 | * @p: pointer to the &parport structure | ||
| 1843 | * | ||
| 1844 | * Check for FIFO parameters of an Extended Capabilities Port. Returns 1 on | ||
| 1845 | * success, and 0 otherwise. Adjust FIFO parameters in the parport structure. | ||
| 1846 | * On return, the port is placed in SPP mode. | ||
| 1847 | */ | ||
| 1848 | static __init unsigned int parport_ip32_fifo_supported(struct parport *p) | ||
| 1849 | { | ||
| 1850 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 1851 | unsigned int configa, configb; | ||
| 1852 | unsigned int pword; | ||
| 1853 | unsigned int i; | ||
| 1854 | |||
| 1855 | /* Configuration mode */ | ||
| 1856 | parport_ip32_set_mode(p, ECR_MODE_CFG); | ||
| 1857 | configa = readb(priv->regs.cnfgA); | ||
| 1858 | configb = readb(priv->regs.cnfgB); | ||
| 1859 | |||
| 1860 | /* Find out PWord size */ | ||
| 1861 | switch (configa & CNFGA_ID_MASK) { | ||
| 1862 | case CNFGA_ID_8: | ||
| 1863 | pword = 1; | ||
| 1864 | break; | ||
| 1865 | case CNFGA_ID_16: | ||
| 1866 | pword = 2; | ||
| 1867 | break; | ||
| 1868 | case CNFGA_ID_32: | ||
| 1869 | pword = 4; | ||
| 1870 | break; | ||
| 1871 | default: | ||
| 1872 | pr_probe(p, "Unknown implementation ID: 0x%0x\n", | ||
| 1873 | (configa & CNFGA_ID_MASK) >> CNFGA_ID_SHIFT); | ||
| 1874 | goto fail; | ||
| 1875 | break; | ||
| 1876 | } | ||
| 1877 | if (pword != 1) { | ||
| 1878 | pr_probe(p, "Unsupported PWord size: %u\n", pword); | ||
| 1879 | goto fail; | ||
| 1880 | } | ||
| 1881 | priv->pword = pword; | ||
| 1882 | pr_probe(p, "PWord is %u bits\n", 8 * priv->pword); | ||
| 1883 | |||
| 1884 | /* Check for compression support */ | ||
| 1885 | writeb(configb | CNFGB_COMPRESS, priv->regs.cnfgB); | ||
| 1886 | if (readb(priv->regs.cnfgB) & CNFGB_COMPRESS) | ||
| 1887 | pr_probe(p, "Hardware compression detected (unsupported)\n"); | ||
| 1888 | writeb(configb & ~CNFGB_COMPRESS, priv->regs.cnfgB); | ||
| 1889 | |||
| 1890 | /* Reset FIFO and go in test mode (no interrupt, no DMA) */ | ||
| 1891 | parport_ip32_set_mode(p, ECR_MODE_TST); | ||
| 1892 | |||
| 1893 | /* FIFO must be empty now */ | ||
| 1894 | if (!(readb(priv->regs.ecr) & ECR_F_EMPTY)) { | ||
| 1895 | pr_probe(p, "FIFO not reset\n"); | ||
| 1896 | goto fail; | ||
| 1897 | } | ||
| 1898 | |||
| 1899 | /* Find out FIFO depth. */ | ||
| 1900 | priv->fifo_depth = 0; | ||
| 1901 | for (i = 0; i < 1024; i++) { | ||
| 1902 | if (readb(priv->regs.ecr) & ECR_F_FULL) { | ||
| 1903 | /* FIFO full */ | ||
| 1904 | priv->fifo_depth = i; | ||
| 1905 | break; | ||
| 1906 | } | ||
| 1907 | writeb((u8)i, priv->regs.fifo); | ||
| 1908 | } | ||
| 1909 | if (i >= 1024) { | ||
| 1910 | pr_probe(p, "Can't fill FIFO\n"); | ||
| 1911 | goto fail; | ||
| 1912 | } | ||
| 1913 | if (!priv->fifo_depth) { | ||
| 1914 | pr_probe(p, "Can't get FIFO depth\n"); | ||
| 1915 | goto fail; | ||
| 1916 | } | ||
| 1917 | pr_probe(p, "FIFO is %u PWords deep\n", priv->fifo_depth); | ||
| 1918 | |||
| 1919 | /* Enable interrupts */ | ||
| 1920 | parport_ip32_frob_econtrol(p, ECR_SERVINTR, 0); | ||
| 1921 | |||
| 1922 | /* Find out writeIntrThreshold: number of PWords we know we can write | ||
| 1923 | * if we get an interrupt. */ | ||
| 1924 | priv->writeIntrThreshold = 0; | ||
| 1925 | for (i = 0; i < priv->fifo_depth; i++) { | ||
| 1926 | if (readb(priv->regs.fifo) != (u8)i) { | ||
| 1927 | pr_probe(p, "Invalid data in FIFO\n"); | ||
| 1928 | goto fail; | ||
| 1929 | } | ||
| 1930 | if (!priv->writeIntrThreshold | ||
| 1931 | && readb(priv->regs.ecr) & ECR_SERVINTR) | ||
| 1932 | /* writeIntrThreshold reached */ | ||
| 1933 | priv->writeIntrThreshold = i + 1; | ||
| 1934 | if (i + 1 < priv->fifo_depth | ||
| 1935 | && readb(priv->regs.ecr) & ECR_F_EMPTY) { | ||
| 1936 | /* FIFO empty before the last byte? */ | ||
| 1937 | pr_probe(p, "Data lost in FIFO\n"); | ||
| 1938 | goto fail; | ||
| 1939 | } | ||
| 1940 | } | ||
| 1941 | if (!priv->writeIntrThreshold) { | ||
| 1942 | pr_probe(p, "Can't get writeIntrThreshold\n"); | ||
| 1943 | goto fail; | ||
| 1944 | } | ||
| 1945 | pr_probe(p, "writeIntrThreshold is %u\n", priv->writeIntrThreshold); | ||
| 1946 | |||
| 1947 | /* FIFO must be empty now */ | ||
| 1948 | if (!(readb(priv->regs.ecr) & ECR_F_EMPTY)) { | ||
| 1949 | pr_probe(p, "Can't empty FIFO\n"); | ||
| 1950 | goto fail; | ||
| 1951 | } | ||
| 1952 | |||
| 1953 | /* Reset FIFO */ | ||
| 1954 | parport_ip32_set_mode(p, ECR_MODE_PS2); | ||
| 1955 | /* Set reverse direction (must be in PS2 mode) */ | ||
| 1956 | parport_ip32_data_reverse(p); | ||
| 1957 | /* Test FIFO, no interrupt, no DMA */ | ||
| 1958 | parport_ip32_set_mode(p, ECR_MODE_TST); | ||
| 1959 | /* Enable interrupts */ | ||
| 1960 | parport_ip32_frob_econtrol(p, ECR_SERVINTR, 0); | ||
| 1961 | |||
| 1962 | /* Find out readIntrThreshold: number of PWords we can read if we get | ||
| 1963 | * an interrupt. */ | ||
| 1964 | priv->readIntrThreshold = 0; | ||
| 1965 | for (i = 0; i < priv->fifo_depth; i++) { | ||
| 1966 | writeb(0xaa, priv->regs.fifo); | ||
| 1967 | if (readb(priv->regs.ecr) & ECR_SERVINTR) { | ||
| 1968 | /* readIntrThreshold reached */ | ||
| 1969 | priv->readIntrThreshold = i + 1; | ||
| 1970 | break; | ||
| 1971 | } | ||
| 1972 | } | ||
| 1973 | if (!priv->readIntrThreshold) { | ||
| 1974 | pr_probe(p, "Can't get readIntrThreshold\n"); | ||
| 1975 | goto fail; | ||
| 1976 | } | ||
| 1977 | pr_probe(p, "readIntrThreshold is %u\n", priv->readIntrThreshold); | ||
| 1978 | |||
| 1979 | /* Reset ECR */ | ||
| 1980 | parport_ip32_set_mode(p, ECR_MODE_PS2); | ||
| 1981 | parport_ip32_data_forward(p); | ||
| 1982 | parport_ip32_set_mode(p, ECR_MODE_SPP); | ||
| 1983 | return 1; | ||
| 1984 | |||
| 1985 | fail: | ||
| 1986 | priv->fifo_depth = 0; | ||
| 1987 | parport_ip32_set_mode(p, ECR_MODE_SPP); | ||
| 1988 | return 0; | ||
| 1989 | } | ||
| 1990 | |||
| 1991 | /*--- Initialization code ----------------------------------------------*/ | ||
| 1992 | |||
| 1993 | /** | ||
| 1994 | * parport_ip32_make_isa_registers - compute (ISA) register addresses | ||
| 1995 | * @regs: pointer to &struct parport_ip32_regs to fill | ||
| 1996 | * @base: base address of standard and EPP registers | ||
| 1997 | * @base_hi: base address of ECP registers | ||
| 1998 | * @regshift: how much to shift register offset by | ||
| 1999 | * | ||
| 2000 | * Compute register addresses, according to the ISA standard. The addresses | ||
| 2001 | * of the standard and EPP registers are computed from address @base. The | ||
| 2002 | * addresses of the ECP registers are computed from address @base_hi. | ||
| 2003 | */ | ||
| 2004 | static void __init | ||
| 2005 | parport_ip32_make_isa_registers(struct parport_ip32_regs *regs, | ||
| 2006 | void __iomem *base, void __iomem *base_hi, | ||
| 2007 | unsigned int regshift) | ||
| 2008 | { | ||
| 2009 | #define r_base(offset) ((u8 __iomem *)base + ((offset) << regshift)) | ||
| 2010 | #define r_base_hi(offset) ((u8 __iomem *)base_hi + ((offset) << regshift)) | ||
| 2011 | *regs = (struct parport_ip32_regs){ | ||
| 2012 | .data = r_base(0), | ||
| 2013 | .dsr = r_base(1), | ||
| 2014 | .dcr = r_base(2), | ||
| 2015 | .eppAddr = r_base(3), | ||
| 2016 | .eppData0 = r_base(4), | ||
| 2017 | .eppData1 = r_base(5), | ||
| 2018 | .eppData2 = r_base(6), | ||
| 2019 | .eppData3 = r_base(7), | ||
| 2020 | .ecpAFifo = r_base(0), | ||
| 2021 | .fifo = r_base_hi(0), | ||
| 2022 | .cnfgA = r_base_hi(0), | ||
| 2023 | .cnfgB = r_base_hi(1), | ||
| 2024 | .ecr = r_base_hi(2) | ||
| 2025 | }; | ||
| 2026 | #undef r_base_hi | ||
| 2027 | #undef r_base | ||
| 2028 | } | ||
| 2029 | |||
| 2030 | /** | ||
| 2031 | * parport_ip32_probe_port - probe and register IP32 built-in parallel port | ||
| 2032 | * | ||
| 2033 | * Returns the new allocated &parport structure. On error, an error code is | ||
| 2034 | * encoded in return value with the ERR_PTR function. | ||
| 2035 | */ | ||
| 2036 | static __init struct parport *parport_ip32_probe_port(void) | ||
| 2037 | { | ||
| 2038 | struct parport_ip32_regs regs; | ||
| 2039 | struct parport_ip32_private *priv = NULL; | ||
| 2040 | struct parport_operations *ops = NULL; | ||
| 2041 | struct parport *p = NULL; | ||
| 2042 | int err; | ||
| 2043 | |||
| 2044 | parport_ip32_make_isa_registers(®s, &mace->isa.parallel, | ||
| 2045 | &mace->isa.ecp1284, 8 /* regshift */); | ||
| 2046 | |||
| 2047 | ops = kmalloc(sizeof(struct parport_operations), GFP_KERNEL); | ||
| 2048 | priv = kmalloc(sizeof(struct parport_ip32_private), GFP_KERNEL); | ||
| 2049 | p = parport_register_port(0, PARPORT_IRQ_NONE, PARPORT_DMA_NONE, ops); | ||
| 2050 | if (ops == NULL || priv == NULL || p == NULL) { | ||
| 2051 | err = -ENOMEM; | ||
| 2052 | goto fail; | ||
| 2053 | } | ||
| 2054 | p->base = MACE_BASE + offsetof(struct sgi_mace, isa.parallel); | ||
| 2055 | p->base_hi = MACE_BASE + offsetof(struct sgi_mace, isa.ecp1284); | ||
| 2056 | p->private_data = priv; | ||
| 2057 | |||
| 2058 | *ops = parport_ip32_ops; | ||
| 2059 | *priv = (struct parport_ip32_private){ | ||
| 2060 | .regs = regs, | ||
| 2061 | .dcr_writable = DCR_DIR | DCR_SELECT | DCR_nINIT | | ||
| 2062 | DCR_AUTOFD | DCR_STROBE, | ||
| 2063 | .irq_mode = PARPORT_IP32_IRQ_FWD, | ||
| 2064 | }; | ||
| 2065 | init_completion(&priv->irq_complete); | ||
| 2066 | |||
| 2067 | /* Probe port. */ | ||
| 2068 | if (!parport_ip32_ecp_supported(p)) { | ||
| 2069 | err = -ENODEV; | ||
| 2070 | goto fail; | ||
| 2071 | } | ||
| 2072 | parport_ip32_dump_state(p, "begin init", 0); | ||
| 2073 | |||
| 2074 | /* We found what looks like a working ECR register. Simply assume | ||
| 2075 | * that all modes are correctly supported. Enable basic modes. */ | ||
| 2076 | p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT; | ||
| 2077 | p->modes |= PARPORT_MODE_TRISTATE; | ||
| 2078 | |||
| 2079 | if (!parport_ip32_fifo_supported(p)) { | ||
| 2080 | printk(KERN_WARNING PPIP32 | ||
| 2081 | "%s: error: FIFO disabled\n", p->name); | ||
| 2082 | /* Disable hardware modes depending on a working FIFO. */ | ||
| 2083 | features &= ~PARPORT_IP32_ENABLE_SPP; | ||
| 2084 | features &= ~PARPORT_IP32_ENABLE_ECP; | ||
| 2085 | /* DMA is not needed if FIFO is not supported. */ | ||
| 2086 | features &= ~PARPORT_IP32_ENABLE_DMA; | ||
| 2087 | } | ||
| 2088 | |||
| 2089 | /* Request IRQ */ | ||
| 2090 | if (features & PARPORT_IP32_ENABLE_IRQ) { | ||
| 2091 | int irq = MACEISA_PARALLEL_IRQ; | ||
| 2092 | if (request_irq(irq, parport_ip32_interrupt, 0, p->name, p)) { | ||
| 2093 | printk(KERN_WARNING PPIP32 | ||
| 2094 | "%s: error: IRQ disabled\n", p->name); | ||
| 2095 | /* DMA cannot work without interrupts. */ | ||
| 2096 | features &= ~PARPORT_IP32_ENABLE_DMA; | ||
| 2097 | } else { | ||
| 2098 | pr_probe(p, "Interrupt support enabled\n"); | ||
| 2099 | p->irq = irq; | ||
| 2100 | priv->dcr_writable |= DCR_IRQ; | ||
| 2101 | } | ||
| 2102 | } | ||
| 2103 | |||
| 2104 | /* Allocate DMA resources */ | ||
| 2105 | if (features & PARPORT_IP32_ENABLE_DMA) { | ||
| 2106 | if (parport_ip32_dma_register()) | ||
| 2107 | printk(KERN_WARNING PPIP32 | ||
| 2108 | "%s: error: DMA disabled\n", p->name); | ||
| 2109 | else { | ||
| 2110 | pr_probe(p, "DMA support enabled\n"); | ||
| 2111 | p->dma = 0; /* arbitrary value != PARPORT_DMA_NONE */ | ||
| 2112 | p->modes |= PARPORT_MODE_DMA; | ||
| 2113 | } | ||
| 2114 | } | ||
| 2115 | |||
| 2116 | if (features & PARPORT_IP32_ENABLE_SPP) { | ||
| 2117 | /* Enable compatibility FIFO mode */ | ||
| 2118 | p->ops->compat_write_data = parport_ip32_compat_write_data; | ||
| 2119 | p->modes |= PARPORT_MODE_COMPAT; | ||
| 2120 | pr_probe(p, "Hardware support for SPP mode enabled\n"); | ||
| 2121 | } | ||
| 2122 | if (features & PARPORT_IP32_ENABLE_EPP) { | ||
| 2123 | /* Set up access functions to use EPP hardware. */ | ||
| 2124 | p->ops->epp_read_data = parport_ip32_epp_read_data; | ||
| 2125 | p->ops->epp_write_data = parport_ip32_epp_write_data; | ||
| 2126 | p->ops->epp_read_addr = parport_ip32_epp_read_addr; | ||
| 2127 | p->ops->epp_write_addr = parport_ip32_epp_write_addr; | ||
| 2128 | p->modes |= PARPORT_MODE_EPP; | ||
| 2129 | pr_probe(p, "Hardware support for EPP mode enabled\n"); | ||
| 2130 | } | ||
| 2131 | if (features & PARPORT_IP32_ENABLE_ECP) { | ||
| 2132 | /* Enable ECP FIFO mode */ | ||
| 2133 | p->ops->ecp_write_data = parport_ip32_ecp_write_data; | ||
| 2134 | /* FIXME - not implemented */ | ||
| 2135 | /* p->ops->ecp_read_data = parport_ip32_ecp_read_data; */ | ||
| 2136 | /* p->ops->ecp_write_addr = parport_ip32_ecp_write_addr; */ | ||
| 2137 | p->modes |= PARPORT_MODE_ECP; | ||
| 2138 | pr_probe(p, "Hardware support for ECP mode enabled\n"); | ||
| 2139 | } | ||
| 2140 | |||
| 2141 | /* Initialize the port with sensible values */ | ||
| 2142 | parport_ip32_set_mode(p, ECR_MODE_PS2); | ||
| 2143 | parport_ip32_write_control(p, DCR_SELECT | DCR_nINIT); | ||
| 2144 | parport_ip32_data_forward(p); | ||
| 2145 | parport_ip32_disable_irq(p); | ||
| 2146 | parport_ip32_write_data(p, 0x00); | ||
| 2147 | parport_ip32_dump_state(p, "end init", 0); | ||
| 2148 | |||
| 2149 | /* Print out what we found */ | ||
| 2150 | printk(KERN_INFO "%s: SGI IP32 at 0x%lx (0x%lx)", | ||
| 2151 | p->name, p->base, p->base_hi); | ||
| 2152 | if (p->irq != PARPORT_IRQ_NONE) | ||
| 2153 | printk(", irq %d", p->irq); | ||
| 2154 | printk(" ["); | ||
| 2155 | #define printmode(x) if (p->modes & PARPORT_MODE_##x) \ | ||
| 2156 | printk("%s%s", f++ ? "," : "", #x) | ||
| 2157 | { | ||
| 2158 | unsigned int f = 0; | ||
| 2159 | printmode(PCSPP); | ||
| 2160 | printmode(TRISTATE); | ||
| 2161 | printmode(COMPAT); | ||
| 2162 | printmode(EPP); | ||
| 2163 | printmode(ECP); | ||
| 2164 | printmode(DMA); | ||
| 2165 | } | ||
| 2166 | #undef printmode | ||
| 2167 | printk("]\n"); | ||
| 2168 | |||
| 2169 | parport_announce_port(p); | ||
| 2170 | return p; | ||
| 2171 | |||
| 2172 | fail: | ||
| 2173 | if (p) | ||
| 2174 | parport_put_port(p); | ||
| 2175 | kfree(priv); | ||
| 2176 | kfree(ops); | ||
| 2177 | return ERR_PTR(err); | ||
| 2178 | } | ||
| 2179 | |||
| 2180 | /** | ||
| 2181 | * parport_ip32_unregister_port - unregister a parallel port | ||
| 2182 | * @p: pointer to the &struct parport | ||
| 2183 | * | ||
| 2184 | * Unregisters a parallel port and free previously allocated resources | ||
| 2185 | * (memory, IRQ, ...). | ||
| 2186 | */ | ||
| 2187 | static __exit void parport_ip32_unregister_port(struct parport *p) | ||
| 2188 | { | ||
| 2189 | struct parport_ip32_private * const priv = p->physport->private_data; | ||
| 2190 | struct parport_operations *ops = p->ops; | ||
| 2191 | |||
| 2192 | parport_remove_port(p); | ||
| 2193 | if (p->modes & PARPORT_MODE_DMA) | ||
| 2194 | parport_ip32_dma_unregister(); | ||
| 2195 | if (p->irq != PARPORT_IRQ_NONE) | ||
| 2196 | free_irq(p->irq, p); | ||
| 2197 | parport_put_port(p); | ||
| 2198 | kfree(priv); | ||
| 2199 | kfree(ops); | ||
| 2200 | } | ||
| 2201 | |||
| 2202 | /** | ||
| 2203 | * parport_ip32_init - module initialization function | ||
| 2204 | */ | ||
| 2205 | static int __init parport_ip32_init(void) | ||
| 2206 | { | ||
| 2207 | pr_info(PPIP32 "SGI IP32 built-in parallel port driver v0.6\n"); | ||
| 2208 | pr_debug1(PPIP32 "Compiled on %s, %s\n", __DATE__, __TIME__); | ||
| 2209 | this_port = parport_ip32_probe_port(); | ||
| 2210 | return IS_ERR(this_port) ? PTR_ERR(this_port) : 0; | ||
| 2211 | } | ||
| 2212 | |||
| 2213 | /** | ||
| 2214 | * parport_ip32_exit - module termination function | ||
| 2215 | */ | ||
| 2216 | static void __exit parport_ip32_exit(void) | ||
| 2217 | { | ||
| 2218 | parport_ip32_unregister_port(this_port); | ||
| 2219 | } | ||
| 2220 | |||
| 2221 | /*--- Module stuff -----------------------------------------------------*/ | ||
| 2222 | |||
| 2223 | MODULE_AUTHOR("Arnaud Giersch <arnaud.giersch@free.fr>"); | ||
| 2224 | MODULE_DESCRIPTION("SGI IP32 built-in parallel port driver"); | ||
| 2225 | MODULE_LICENSE("GPL"); | ||
| 2226 | MODULE_VERSION("0.6"); /* update in parport_ip32_init() too */ | ||
| 2227 | |||
| 2228 | module_init(parport_ip32_init); | ||
| 2229 | module_exit(parport_ip32_exit); | ||
| 2230 | |||
| 2231 | module_param(verbose_probing, bool, S_IRUGO); | ||
| 2232 | MODULE_PARM_DESC(verbose_probing, "Log chit-chat during initialization"); | ||
| 2233 | |||
| 2234 | module_param(features, uint, S_IRUGO); | ||
| 2235 | MODULE_PARM_DESC(features, | ||
| 2236 | "Bit mask of features to enable" | ||
| 2237 | ", bit 0: IRQ support" | ||
| 2238 | ", bit 1: DMA support" | ||
| 2239 | ", bit 2: hardware SPP mode" | ||
| 2240 | ", bit 3: hardware EPP mode" | ||
| 2241 | ", bit 4: hardware ECP mode"); | ||
| 2242 | |||
| 2243 | /*--- Inform (X)Emacs about preferred coding style ---------------------*/ | ||
| 2244 | /* | ||
| 2245 | * Local Variables: | ||
| 2246 | * mode: c | ||
| 2247 | * c-file-style: "linux" | ||
| 2248 | * indent-tabs-mode: t | ||
| 2249 | * tab-width: 8 | ||
| 2250 | * fill-column: 78 | ||
| 2251 | * ispell-local-dictionary: "american" | ||
| 2252 | * End: | ||
| 2253 | */ | ||
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index 76dd077e3184..166de3507780 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c | |||
| @@ -329,9 +329,9 @@ static int __devinit parport_register (struct pci_dev *dev, | |||
| 329 | 329 | ||
| 330 | if (priv->num_par == ARRAY_SIZE (priv->port)) { | 330 | if (priv->num_par == ARRAY_SIZE (priv->port)) { |
| 331 | printk (KERN_WARNING | 331 | printk (KERN_WARNING |
| 332 | "parport_serial: %s: only %u parallel ports " | 332 | "parport_serial: %s: only %zu parallel ports " |
| 333 | "supported (%d reported)\n", pci_name (dev), | 333 | "supported (%d reported)\n", pci_name (dev), |
| 334 | ARRAY_SIZE (priv->port), card->numports); | 334 | ARRAY_SIZE(priv->port), card->numports); |
| 335 | break; | 335 | break; |
| 336 | } | 336 | } |
| 337 | 337 | ||
diff --git a/drivers/parport/probe.c b/drivers/parport/probe.c index b62aee8de3cb..ea83b70e0de2 100644 --- a/drivers/parport/probe.c +++ b/drivers/parport/probe.c | |||
| @@ -199,7 +199,7 @@ static ssize_t parport_read_device_id (struct parport *port, char *buffer, | |||
| 199 | 199 | ||
| 200 | if (port->physport->ieee1284.phase != IEEE1284_PH_HBUSY_DAVAIL) { | 200 | if (port->physport->ieee1284.phase != IEEE1284_PH_HBUSY_DAVAIL) { |
| 201 | if (belen != len) { | 201 | if (belen != len) { |
| 202 | printk (KERN_DEBUG "%s: Device ID was %d bytes" | 202 | printk (KERN_DEBUG "%s: Device ID was %zd bytes" |
| 203 | " while device told it would be %d" | 203 | " while device told it would be %d" |
| 204 | " bytes\n", | 204 | " bytes\n", |
| 205 | port->name, len, belen); | 205 | port->name, len, belen); |
| @@ -214,7 +214,7 @@ static ssize_t parport_read_device_id (struct parport *port, char *buffer, | |||
| 214 | if (buffer[len-1] == ';') { | 214 | if (buffer[len-1] == ';') { |
| 215 | printk (KERN_DEBUG "%s: Device ID reading stopped" | 215 | printk (KERN_DEBUG "%s: Device ID reading stopped" |
| 216 | " before device told data not available. " | 216 | " before device told data not available. " |
| 217 | "Current idlen %d of %d, len bytes %02X %02X\n", | 217 | "Current idlen %u of %u, len bytes %02X %02X\n", |
| 218 | port->name, current_idlen, numidlens, | 218 | port->name, current_idlen, numidlens, |
| 219 | length[0], length[1]); | 219 | length[0], length[1]); |
| 220 | goto done; | 220 | goto done; |
diff --git a/drivers/s390/block/Kconfig b/drivers/s390/block/Kconfig index 6f50cc9323d9..6912399d0937 100644 --- a/drivers/s390/block/Kconfig +++ b/drivers/s390/block/Kconfig | |||
| @@ -55,13 +55,21 @@ config DASD_DIAG | |||
| 55 | Disks under VM. If you are not running under VM or unsure what it is, | 55 | Disks under VM. If you are not running under VM or unsure what it is, |
| 56 | say "N". | 56 | say "N". |
| 57 | 57 | ||
| 58 | config DASD_EER | ||
| 59 | tristate "Extended error reporting (EER)" | ||
| 60 | depends on DASD | ||
| 61 | help | ||
| 62 | This driver provides a character device interface to the | ||
| 63 | DASD extended error reporting. This is only needed if you want to | ||
| 64 | use applications written for the EER facility. | ||
| 65 | |||
| 58 | config DASD_CMB | 66 | config DASD_CMB |
| 59 | tristate "Compatibility interface for DASD channel measurement blocks" | 67 | tristate "Compatibility interface for DASD channel measurement blocks" |
| 60 | depends on DASD | 68 | depends on DASD |
| 61 | help | 69 | help |
| 62 | This driver provides an additional interface to the channel measurement | 70 | This driver provides an additional interface to the channel |
| 63 | facility, which is normally accessed though sysfs, with a set of | 71 | measurement facility, which is normally accessed though sysfs, with |
| 64 | ioctl functions specific to the dasd driver. | 72 | a set of ioctl functions specific to the dasd driver. |
| 65 | This is only needed if you want to use applications written for | 73 | This is only needed if you want to use applications written for |
| 66 | linux-2.4 dasd channel measurement facility interface. | 74 | linux-2.4 dasd channel measurement facility interface. |
| 67 | 75 | ||
diff --git a/drivers/s390/block/Makefile b/drivers/s390/block/Makefile index 58c6780134f7..0c0d871e8f51 100644 --- a/drivers/s390/block/Makefile +++ b/drivers/s390/block/Makefile | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | dasd_eckd_mod-objs := dasd_eckd.o dasd_3990_erp.o dasd_9343_erp.o | 5 | dasd_eckd_mod-objs := dasd_eckd.o dasd_3990_erp.o dasd_9343_erp.o |
| 6 | dasd_fba_mod-objs := dasd_fba.o dasd_3370_erp.o dasd_9336_erp.o | 6 | dasd_fba_mod-objs := dasd_fba.o dasd_3370_erp.o dasd_9336_erp.o |
| 7 | dasd_diag_mod-objs := dasd_diag.o | 7 | dasd_diag_mod-objs := dasd_diag.o |
| 8 | dasd_eer_mod-objs := dasd_eer.o | ||
| 8 | dasd_mod-objs := dasd.o dasd_ioctl.o dasd_proc.o dasd_devmap.o \ | 9 | dasd_mod-objs := dasd.o dasd_ioctl.o dasd_proc.o dasd_devmap.o \ |
| 9 | dasd_genhd.o dasd_erp.o | 10 | dasd_genhd.o dasd_erp.o |
| 10 | 11 | ||
| @@ -13,5 +14,6 @@ obj-$(CONFIG_DASD_DIAG) += dasd_diag_mod.o | |||
| 13 | obj-$(CONFIG_DASD_ECKD) += dasd_eckd_mod.o | 14 | obj-$(CONFIG_DASD_ECKD) += dasd_eckd_mod.o |
| 14 | obj-$(CONFIG_DASD_FBA) += dasd_fba_mod.o | 15 | obj-$(CONFIG_DASD_FBA) += dasd_fba_mod.o |
| 15 | obj-$(CONFIG_DASD_CMB) += dasd_cmb.o | 16 | obj-$(CONFIG_DASD_CMB) += dasd_cmb.o |
| 17 | obj-$(CONFIG_DASD_EER) += dasd_eer.o | ||
| 16 | obj-$(CONFIG_BLK_DEV_XPRAM) += xpram.o | 18 | obj-$(CONFIG_BLK_DEV_XPRAM) += xpram.o |
| 17 | obj-$(CONFIG_DCSSBLK) += dcssblk.o | 19 | obj-$(CONFIG_DCSSBLK) += dcssblk.o |
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index abdf1ee633e7..08c88fcd8963 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
| 19 | #include <linux/buffer_head.h> | 19 | #include <linux/buffer_head.h> |
| 20 | #include <linux/hdreg.h> | 20 | #include <linux/hdreg.h> |
| 21 | #include <linux/notifier.h> | ||
| 21 | 22 | ||
| 22 | #include <asm/ccwdev.h> | 23 | #include <asm/ccwdev.h> |
| 23 | #include <asm/ebcdic.h> | 24 | #include <asm/ebcdic.h> |
| @@ -57,6 +58,7 @@ static void dasd_int_handler(struct ccw_device *, unsigned long, struct irb *); | |||
| 57 | static void dasd_flush_ccw_queue(struct dasd_device *, int); | 58 | static void dasd_flush_ccw_queue(struct dasd_device *, int); |
| 58 | static void dasd_tasklet(struct dasd_device *); | 59 | static void dasd_tasklet(struct dasd_device *); |
| 59 | static void do_kick_device(void *data); | 60 | static void do_kick_device(void *data); |
| 61 | static void dasd_disable_eer(struct dasd_device *device); | ||
| 60 | 62 | ||
| 61 | /* | 63 | /* |
| 62 | * SECTION: Operations on the device structure. | 64 | * SECTION: Operations on the device structure. |
| @@ -151,6 +153,8 @@ dasd_state_new_to_known(struct dasd_device *device) | |||
| 151 | static inline void | 153 | static inline void |
| 152 | dasd_state_known_to_new(struct dasd_device * device) | 154 | dasd_state_known_to_new(struct dasd_device * device) |
| 153 | { | 155 | { |
| 156 | /* disable extended error reporting for this device */ | ||
| 157 | dasd_disable_eer(device); | ||
| 154 | /* Forget the discipline information. */ | 158 | /* Forget the discipline information. */ |
| 155 | device->discipline = NULL; | 159 | device->discipline = NULL; |
| 156 | device->state = DASD_STATE_NEW; | 160 | device->state = DASD_STATE_NEW; |
| @@ -867,6 +871,9 @@ dasd_handle_state_change_pending(struct dasd_device *device) | |||
| 867 | struct dasd_ccw_req *cqr; | 871 | struct dasd_ccw_req *cqr; |
| 868 | struct list_head *l, *n; | 872 | struct list_head *l, *n; |
| 869 | 873 | ||
| 874 | /* first of all call extended error reporting */ | ||
| 875 | dasd_write_eer_trigger(DASD_EER_STATECHANGE, device, NULL); | ||
| 876 | |||
| 870 | device->stopped &= ~DASD_STOPPED_PENDING; | 877 | device->stopped &= ~DASD_STOPPED_PENDING; |
| 871 | 878 | ||
| 872 | /* restart all 'running' IO on queue */ | 879 | /* restart all 'running' IO on queue */ |
| @@ -1086,6 +1093,19 @@ restart: | |||
| 1086 | } | 1093 | } |
| 1087 | goto restart; | 1094 | goto restart; |
| 1088 | } | 1095 | } |
| 1096 | |||
| 1097 | /* first of all call extended error reporting */ | ||
| 1098 | if (device->eer && cqr->status == DASD_CQR_FAILED) { | ||
| 1099 | dasd_write_eer_trigger(DASD_EER_FATALERROR, | ||
| 1100 | device, cqr); | ||
| 1101 | |||
| 1102 | /* restart request */ | ||
| 1103 | cqr->status = DASD_CQR_QUEUED; | ||
| 1104 | cqr->retries = 255; | ||
| 1105 | device->stopped |= DASD_STOPPED_QUIESCE; | ||
| 1106 | goto restart; | ||
| 1107 | } | ||
| 1108 | |||
| 1089 | /* Process finished ERP request. */ | 1109 | /* Process finished ERP request. */ |
| 1090 | if (cqr->refers) { | 1110 | if (cqr->refers) { |
| 1091 | __dasd_process_erp(device, cqr); | 1111 | __dasd_process_erp(device, cqr); |
| @@ -1223,7 +1243,8 @@ __dasd_start_head(struct dasd_device * device) | |||
| 1223 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list); | 1243 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list); |
| 1224 | /* check FAILFAST */ | 1244 | /* check FAILFAST */ |
| 1225 | if (device->stopped & ~DASD_STOPPED_PENDING && | 1245 | if (device->stopped & ~DASD_STOPPED_PENDING && |
| 1226 | test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags)) { | 1246 | test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) && |
| 1247 | (!device->eer)) { | ||
| 1227 | cqr->status = DASD_CQR_FAILED; | 1248 | cqr->status = DASD_CQR_FAILED; |
| 1228 | dasd_schedule_bh(device); | 1249 | dasd_schedule_bh(device); |
| 1229 | } | 1250 | } |
| @@ -1965,6 +1986,9 @@ dasd_generic_notify(struct ccw_device *cdev, int event) | |||
| 1965 | switch (event) { | 1986 | switch (event) { |
| 1966 | case CIO_GONE: | 1987 | case CIO_GONE: |
| 1967 | case CIO_NO_PATH: | 1988 | case CIO_NO_PATH: |
| 1989 | /* first of all call extended error reporting */ | ||
| 1990 | dasd_write_eer_trigger(DASD_EER_NOPATH, device, NULL); | ||
| 1991 | |||
| 1968 | if (device->state < DASD_STATE_BASIC) | 1992 | if (device->state < DASD_STATE_BASIC) |
| 1969 | break; | 1993 | break; |
| 1970 | /* Device is active. We want to keep it. */ | 1994 | /* Device is active. We want to keep it. */ |
| @@ -2022,6 +2046,51 @@ dasd_generic_auto_online (struct ccw_driver *dasd_discipline_driver) | |||
| 2022 | put_driver(drv); | 2046 | put_driver(drv); |
| 2023 | } | 2047 | } |
| 2024 | 2048 | ||
| 2049 | /* | ||
| 2050 | * notifications for extended error reports | ||
| 2051 | */ | ||
| 2052 | static struct notifier_block *dasd_eer_chain; | ||
| 2053 | |||
| 2054 | int | ||
| 2055 | dasd_register_eer_notifier(struct notifier_block *nb) | ||
| 2056 | { | ||
| 2057 | return notifier_chain_register(&dasd_eer_chain, nb); | ||
| 2058 | } | ||
| 2059 | |||
| 2060 | int | ||
| 2061 | dasd_unregister_eer_notifier(struct notifier_block *nb) | ||
| 2062 | { | ||
| 2063 | return notifier_chain_unregister(&dasd_eer_chain, nb); | ||
| 2064 | } | ||
| 2065 | |||
| 2066 | /* | ||
| 2067 | * Notify the registered error reporting module of a problem | ||
| 2068 | */ | ||
| 2069 | void | ||
| 2070 | dasd_write_eer_trigger(unsigned int id, struct dasd_device *device, | ||
| 2071 | struct dasd_ccw_req *cqr) | ||
| 2072 | { | ||
| 2073 | if (device->eer) { | ||
| 2074 | struct dasd_eer_trigger temp; | ||
| 2075 | temp.id = id; | ||
| 2076 | temp.device = device; | ||
| 2077 | temp.cqr = cqr; | ||
| 2078 | notifier_call_chain(&dasd_eer_chain, DASD_EER_TRIGGER, | ||
| 2079 | (void *)&temp); | ||
| 2080 | } | ||
| 2081 | } | ||
| 2082 | |||
| 2083 | /* | ||
| 2084 | * Tell the registered error reporting module to disable error reporting for | ||
| 2085 | * a given device and to cleanup any private data structures on that device. | ||
| 2086 | */ | ||
| 2087 | static void | ||
| 2088 | dasd_disable_eer(struct dasd_device *device) | ||
| 2089 | { | ||
| 2090 | notifier_call_chain(&dasd_eer_chain, DASD_EER_DISABLE, (void *)device); | ||
| 2091 | } | ||
| 2092 | |||
| 2093 | |||
| 2025 | static int __init | 2094 | static int __init |
| 2026 | dasd_init(void) | 2095 | dasd_init(void) |
| 2027 | { | 2096 | { |
| @@ -2103,6 +2172,11 @@ EXPORT_SYMBOL_GPL(dasd_generic_set_online); | |||
| 2103 | EXPORT_SYMBOL_GPL(dasd_generic_set_offline); | 2172 | EXPORT_SYMBOL_GPL(dasd_generic_set_offline); |
| 2104 | EXPORT_SYMBOL_GPL(dasd_generic_auto_online); | 2173 | EXPORT_SYMBOL_GPL(dasd_generic_auto_online); |
| 2105 | 2174 | ||
| 2175 | EXPORT_SYMBOL(dasd_register_eer_notifier); | ||
| 2176 | EXPORT_SYMBOL(dasd_unregister_eer_notifier); | ||
| 2177 | EXPORT_SYMBOL(dasd_write_eer_trigger); | ||
| 2178 | |||
| 2179 | |||
| 2106 | /* | 2180 | /* |
| 2107 | * Overrides for Emacs so that we follow Linus's tabbing style. | 2181 | * Overrides for Emacs so that we follow Linus's tabbing style. |
| 2108 | * Emacs will notice this stuff at the end of the file and automatically | 2182 | * Emacs will notice this stuff at the end of the file and automatically |
diff --git a/drivers/s390/block/dasd_3990_erp.c b/drivers/s390/block/dasd_3990_erp.c index 4ee0f934e325..c811380b9079 100644 --- a/drivers/s390/block/dasd_3990_erp.c +++ b/drivers/s390/block/dasd_3990_erp.c | |||
| @@ -1108,6 +1108,9 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense) | |||
| 1108 | case 0x0B: | 1108 | case 0x0B: |
| 1109 | DEV_MESSAGE(KERN_WARNING, device, "%s", | 1109 | DEV_MESSAGE(KERN_WARNING, device, "%s", |
| 1110 | "FORMAT F - Volume is suspended duplex"); | 1110 | "FORMAT F - Volume is suspended duplex"); |
| 1111 | /* call extended error reporting (EER) */ | ||
| 1112 | dasd_write_eer_trigger(DASD_EER_PPRCSUSPEND, device, | ||
| 1113 | erp->refers); | ||
| 1111 | break; | 1114 | break; |
| 1112 | case 0x0C: | 1115 | case 0x0C: |
| 1113 | DEV_MESSAGE(KERN_WARNING, device, "%s", | 1116 | DEV_MESSAGE(KERN_WARNING, device, "%s", |
diff --git a/drivers/s390/block/dasd_eckd.h b/drivers/s390/block/dasd_eckd.h index bc3823d35223..e15dd7978050 100644 --- a/drivers/s390/block/dasd_eckd.h +++ b/drivers/s390/block/dasd_eckd.h | |||
| @@ -29,6 +29,7 @@ | |||
| 29 | #define DASD_ECKD_CCW_PSF 0x27 | 29 | #define DASD_ECKD_CCW_PSF 0x27 |
| 30 | #define DASD_ECKD_CCW_RSSD 0x3e | 30 | #define DASD_ECKD_CCW_RSSD 0x3e |
| 31 | #define DASD_ECKD_CCW_LOCATE_RECORD 0x47 | 31 | #define DASD_ECKD_CCW_LOCATE_RECORD 0x47 |
| 32 | #define DASD_ECKD_CCW_SNSS 0x54 | ||
| 32 | #define DASD_ECKD_CCW_DEFINE_EXTENT 0x63 | 33 | #define DASD_ECKD_CCW_DEFINE_EXTENT 0x63 |
| 33 | #define DASD_ECKD_CCW_WRITE_MT 0x85 | 34 | #define DASD_ECKD_CCW_WRITE_MT 0x85 |
| 34 | #define DASD_ECKD_CCW_READ_MT 0x86 | 35 | #define DASD_ECKD_CCW_READ_MT 0x86 |
diff --git a/drivers/s390/block/dasd_eer.c b/drivers/s390/block/dasd_eer.c new file mode 100644 index 000000000000..f70cd7716b24 --- /dev/null +++ b/drivers/s390/block/dasd_eer.c | |||
| @@ -0,0 +1,1090 @@ | |||
| 1 | /* | ||
| 2 | * character device driver for extended error reporting | ||
| 3 | * | ||
| 4 | * | ||
| 5 | * Copyright (C) 2005 IBM Corporation | ||
| 6 | * extended error reporting for DASD ECKD devices | ||
| 7 | * Author(s): Stefan Weinhuber <wein@de.ibm.com> | ||
| 8 | * | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/fs.h> | ||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/miscdevice.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/moduleparam.h> | ||
| 17 | #include <linux/device.h> | ||
| 18 | #include <linux/workqueue.h> | ||
| 19 | #include <linux/poll.h> | ||
| 20 | #include <linux/notifier.h> | ||
| 21 | |||
| 22 | #include <asm/uaccess.h> | ||
| 23 | #include <asm/semaphore.h> | ||
| 24 | #include <asm/atomic.h> | ||
| 25 | #include <asm/ebcdic.h> | ||
| 26 | |||
| 27 | #include "dasd_int.h" | ||
| 28 | #include "dasd_eckd.h" | ||
| 29 | |||
| 30 | |||
| 31 | MODULE_LICENSE("GPL"); | ||
| 32 | |||
| 33 | MODULE_AUTHOR("Stefan Weinhuber <wein@de.ibm.com>"); | ||
| 34 | MODULE_DESCRIPTION("DASD extended error reporting module"); | ||
| 35 | |||
| 36 | |||
| 37 | #ifdef PRINTK_HEADER | ||
| 38 | #undef PRINTK_HEADER | ||
| 39 | #endif /* PRINTK_HEADER */ | ||
| 40 | #define PRINTK_HEADER "dasd(eer):" | ||
| 41 | |||
| 42 | |||
| 43 | |||
| 44 | |||
| 45 | |||
| 46 | /*****************************************************************************/ | ||
| 47 | /* the internal buffer */ | ||
| 48 | /*****************************************************************************/ | ||
| 49 | |||
| 50 | /* | ||
| 51 | * The internal buffer is meant to store obaque blobs of data, so it doesn't | ||
| 52 | * know of higher level concepts like triggers. | ||
| 53 | * It consists of a number of pages that are used as a ringbuffer. Each data | ||
| 54 | * blob is stored in a simple record that consists of an integer, which | ||
| 55 | * contains the size of the following data, and the data bytes themselfes. | ||
| 56 | * | ||
| 57 | * To allow for multiple independent readers we create one internal buffer | ||
| 58 | * each time the device is opened and destroy the buffer when the file is | ||
| 59 | * closed again. | ||
| 60 | * | ||
| 61 | * One record can be written to a buffer by using the functions | ||
| 62 | * - dasd_eer_start_record (one time per record to write the size to the buffer | ||
| 63 | * and reserve the space for the data) | ||
| 64 | * - dasd_eer_write_buffer (one or more times per record to write the data) | ||
| 65 | * The data can be written in several steps but you will have to compute | ||
| 66 | * the total size up front for the invocation of dasd_eer_start_record. | ||
| 67 | * If the ringbuffer is full, dasd_eer_start_record will remove the required | ||
| 68 | * number of old records. | ||
| 69 | * | ||
| 70 | * A record is typically read in two steps, first read the integer that | ||
| 71 | * specifies the size of the following data, then read the data. | ||
| 72 | * Both can be done by | ||
| 73 | * - dasd_eer_read_buffer | ||
| 74 | * | ||
| 75 | * For all mentioned functions you need to get the bufferlock first and keep it | ||
| 76 | * until a complete record is written or read. | ||
| 77 | */ | ||
| 78 | |||
| 79 | |||
| 80 | /* | ||
| 81 | * Alle information necessary to keep track of an internal buffer is kept in | ||
| 82 | * a struct eerbuffer. The buffer specific to a file pointer is strored in | ||
| 83 | * the private_data field of that file. To be able to write data to all | ||
| 84 | * existing buffers, each buffer is also added to the bufferlist. | ||
| 85 | * If the user doesn't want to read a complete record in one go, we have to | ||
| 86 | * keep track of the rest of the record. residual stores the number of bytes | ||
| 87 | * that are still to deliver. If the rest of the record is invalidated between | ||
| 88 | * two reads then residual will be set to -1 so that the next read will fail. | ||
| 89 | * All entries in the eerbuffer structure are protected with the bufferlock. | ||
| 90 | * To avoid races between writing to a buffer on the one side and creating | ||
| 91 | * and destroying buffers on the other side, the bufferlock must also be used | ||
| 92 | * to protect the bufferlist. | ||
| 93 | */ | ||
| 94 | |||
| 95 | struct eerbuffer { | ||
| 96 | struct list_head list; | ||
| 97 | char **buffer; | ||
| 98 | int buffersize; | ||
| 99 | int buffer_page_count; | ||
| 100 | int head; | ||
| 101 | int tail; | ||
| 102 | int residual; | ||
| 103 | }; | ||
| 104 | |||
| 105 | LIST_HEAD(bufferlist); | ||
| 106 | |||
| 107 | static spinlock_t bufferlock = SPIN_LOCK_UNLOCKED; | ||
| 108 | |||
| 109 | DECLARE_WAIT_QUEUE_HEAD(dasd_eer_read_wait_queue); | ||
| 110 | |||
| 111 | /* | ||
| 112 | * How many free bytes are available on the buffer. | ||
| 113 | * needs to be called with bufferlock held | ||
| 114 | */ | ||
| 115 | static int | ||
| 116 | dasd_eer_get_free_bytes(struct eerbuffer *eerb) | ||
| 117 | { | ||
| 118 | if (eerb->head < eerb->tail) { | ||
| 119 | return eerb->tail - eerb->head - 1; | ||
| 120 | } else | ||
| 121 | return eerb->buffersize - eerb->head + eerb->tail -1; | ||
| 122 | } | ||
| 123 | |||
| 124 | /* | ||
| 125 | * How many bytes of buffer space are used. | ||
| 126 | * needs to be called with bufferlock held | ||
| 127 | */ | ||
| 128 | static int | ||
| 129 | dasd_eer_get_filled_bytes(struct eerbuffer *eerb) | ||
| 130 | { | ||
| 131 | |||
| 132 | if (eerb->head >= eerb->tail) { | ||
| 133 | return eerb->head - eerb->tail; | ||
| 134 | } else | ||
| 135 | return eerb->buffersize - eerb->tail + eerb->head; | ||
| 136 | } | ||
| 137 | |||
| 138 | /* | ||
| 139 | * The dasd_eer_write_buffer function just copies count bytes of data | ||
| 140 | * to the buffer. Make sure to call dasd_eer_start_record first, to | ||
| 141 | * make sure that enough free space is available. | ||
| 142 | * needs to be called with bufferlock held | ||
| 143 | */ | ||
| 144 | static void | ||
| 145 | dasd_eer_write_buffer(struct eerbuffer *eerb, int count, char *data) | ||
| 146 | { | ||
| 147 | |||
| 148 | unsigned long headindex,localhead; | ||
| 149 | unsigned long rest, len; | ||
| 150 | char *nextdata; | ||
| 151 | |||
| 152 | nextdata = data; | ||
| 153 | rest = count; | ||
| 154 | while (rest > 0) { | ||
| 155 | headindex = eerb->head / PAGE_SIZE; | ||
| 156 | localhead = eerb->head % PAGE_SIZE; | ||
| 157 | len = min(rest, (PAGE_SIZE - localhead)); | ||
| 158 | memcpy(eerb->buffer[headindex]+localhead, nextdata, len); | ||
| 159 | nextdata += len; | ||
| 160 | rest -= len; | ||
| 161 | eerb->head += len; | ||
| 162 | if ( eerb->head == eerb->buffersize ) | ||
| 163 | eerb->head = 0; /* wrap around */ | ||
| 164 | if (eerb->head > eerb->buffersize) { | ||
| 165 | MESSAGE(KERN_ERR, "%s", "runaway buffer head."); | ||
| 166 | BUG(); | ||
| 167 | } | ||
| 168 | } | ||
| 169 | } | ||
| 170 | |||
| 171 | /* | ||
| 172 | * needs to be called with bufferlock held | ||
| 173 | */ | ||
| 174 | static int | ||
| 175 | dasd_eer_read_buffer(struct eerbuffer *eerb, int count, char *data) | ||
| 176 | { | ||
| 177 | |||
| 178 | unsigned long tailindex,localtail; | ||
| 179 | unsigned long rest, len, finalcount; | ||
| 180 | char *nextdata; | ||
| 181 | |||
| 182 | finalcount = min(count, dasd_eer_get_filled_bytes(eerb)); | ||
| 183 | nextdata = data; | ||
| 184 | rest = finalcount; | ||
| 185 | while (rest > 0) { | ||
| 186 | tailindex = eerb->tail / PAGE_SIZE; | ||
| 187 | localtail = eerb->tail % PAGE_SIZE; | ||
| 188 | len = min(rest, (PAGE_SIZE - localtail)); | ||
| 189 | memcpy(nextdata, eerb->buffer[tailindex]+localtail, len); | ||
| 190 | nextdata += len; | ||
| 191 | rest -= len; | ||
| 192 | eerb->tail += len; | ||
| 193 | if ( eerb->tail == eerb->buffersize ) | ||
| 194 | eerb->tail = 0; /* wrap around */ | ||
| 195 | if (eerb->tail > eerb->buffersize) { | ||
| 196 | MESSAGE(KERN_ERR, "%s", "runaway buffer tail."); | ||
| 197 | BUG(); | ||
| 198 | } | ||
| 199 | } | ||
| 200 | return finalcount; | ||
| 201 | } | ||
| 202 | |||
| 203 | /* | ||
| 204 | * Whenever you want to write a blob of data to the internal buffer you | ||
| 205 | * have to start by using this function first. It will write the number | ||
| 206 | * of bytes that will be written to the buffer. If necessary it will remove | ||
| 207 | * old records to make room for the new one. | ||
| 208 | * needs to be called with bufferlock held | ||
| 209 | */ | ||
| 210 | static int | ||
| 211 | dasd_eer_start_record(struct eerbuffer *eerb, int count) | ||
| 212 | { | ||
| 213 | int tailcount; | ||
| 214 | if (count + sizeof(count) > eerb->buffersize) | ||
| 215 | return -ENOMEM; | ||
| 216 | while (dasd_eer_get_free_bytes(eerb) < count + sizeof(count)) { | ||
| 217 | if (eerb->residual > 0) { | ||
| 218 | eerb->tail += eerb->residual; | ||
| 219 | if (eerb->tail >= eerb->buffersize) | ||
| 220 | eerb->tail -= eerb->buffersize; | ||
| 221 | eerb->residual = -1; | ||
| 222 | } | ||
| 223 | dasd_eer_read_buffer(eerb, sizeof(tailcount), | ||
| 224 | (char*)(&tailcount)); | ||
| 225 | eerb->tail += tailcount; | ||
| 226 | if (eerb->tail >= eerb->buffersize) | ||
| 227 | eerb->tail -= eerb->buffersize; | ||
| 228 | } | ||
| 229 | dasd_eer_write_buffer(eerb, sizeof(count), (char*)(&count)); | ||
| 230 | |||
| 231 | return 0; | ||
| 232 | }; | ||
| 233 | |||
| 234 | /* | ||
| 235 | * release pages that are not used anymore | ||
| 236 | */ | ||
| 237 | static void | ||
| 238 | dasd_eer_free_buffer_pages(char **buf, int no_pages) | ||
| 239 | { | ||
| 240 | int i; | ||
| 241 | |||
| 242 | for (i = 0; i < no_pages; ++i) { | ||
| 243 | free_page((unsigned long)buf[i]); | ||
| 244 | } | ||
| 245 | } | ||
| 246 | |||
| 247 | /* | ||
| 248 | * allocate a new set of memory pages | ||
| 249 | */ | ||
| 250 | static int | ||
| 251 | dasd_eer_allocate_buffer_pages(char **buf, int no_pages) | ||
| 252 | { | ||
| 253 | int i; | ||
| 254 | |||
| 255 | for (i = 0; i < no_pages; ++i) { | ||
| 256 | buf[i] = (char *) get_zeroed_page(GFP_KERNEL); | ||
| 257 | if (!buf[i]) { | ||
| 258 | dasd_eer_free_buffer_pages(buf, i); | ||
| 259 | return -ENOMEM; | ||
| 260 | } | ||
| 261 | } | ||
| 262 | return 0; | ||
| 263 | } | ||
| 264 | |||
| 265 | /* | ||
| 266 | * empty the buffer by resetting head and tail | ||
| 267 | * In case there is a half read data blob in the buffer, we set residual | ||
| 268 | * to -1 to indicate that the remainder of the blob is lost. | ||
| 269 | */ | ||
| 270 | static void | ||
| 271 | dasd_eer_purge_buffer(struct eerbuffer *eerb) | ||
| 272 | { | ||
| 273 | unsigned long flags; | ||
| 274 | |||
| 275 | spin_lock_irqsave(&bufferlock, flags); | ||
| 276 | if (eerb->residual > 0) | ||
| 277 | eerb->residual = -1; | ||
| 278 | eerb->tail=0; | ||
| 279 | eerb->head=0; | ||
| 280 | spin_unlock_irqrestore(&bufferlock, flags); | ||
| 281 | } | ||
| 282 | |||
| 283 | /* | ||
| 284 | * set the size of the buffer, newsize is the new number of pages to be used | ||
| 285 | * we don't try to copy any data back an forth, so any resize will also purge | ||
| 286 | * the buffer | ||
| 287 | */ | ||
| 288 | static int | ||
| 289 | dasd_eer_resize_buffer(struct eerbuffer *eerb, int newsize) | ||
| 290 | { | ||
| 291 | int i, oldcount, reuse; | ||
| 292 | char **new; | ||
| 293 | char **old; | ||
| 294 | unsigned long flags; | ||
| 295 | |||
| 296 | if (newsize < 1) | ||
| 297 | return -EINVAL; | ||
| 298 | if (eerb->buffer_page_count == newsize) { | ||
| 299 | /* documented behaviour is that any successfull invocation | ||
| 300 | * will purge all records */ | ||
| 301 | dasd_eer_purge_buffer(eerb); | ||
| 302 | return 0; | ||
| 303 | } | ||
| 304 | new = kmalloc(newsize*sizeof(char*), GFP_KERNEL); | ||
| 305 | if (!new) | ||
| 306 | return -ENOMEM; | ||
| 307 | |||
| 308 | reuse=min(eerb->buffer_page_count, newsize); | ||
| 309 | for (i = 0; i < reuse; ++i) { | ||
| 310 | new[i] = eerb->buffer[i]; | ||
| 311 | } | ||
| 312 | if (eerb->buffer_page_count < newsize) { | ||
| 313 | if (dasd_eer_allocate_buffer_pages( | ||
| 314 | &new[eerb->buffer_page_count], | ||
| 315 | newsize - eerb->buffer_page_count)) { | ||
| 316 | kfree(new); | ||
| 317 | return -ENOMEM; | ||
| 318 | } | ||
| 319 | } | ||
| 320 | |||
| 321 | spin_lock_irqsave(&bufferlock, flags); | ||
| 322 | old = eerb->buffer; | ||
| 323 | eerb->buffer = new; | ||
| 324 | if (eerb->residual > 0) | ||
| 325 | eerb->residual = -1; | ||
| 326 | eerb->tail = 0; | ||
| 327 | eerb->head = 0; | ||
| 328 | oldcount = eerb->buffer_page_count; | ||
| 329 | eerb->buffer_page_count = newsize; | ||
| 330 | spin_unlock_irqrestore(&bufferlock, flags); | ||
| 331 | |||
| 332 | if (oldcount > newsize) { | ||
| 333 | for (i = newsize; i < oldcount; ++i) { | ||
| 334 | free_page((unsigned long)old[i]); | ||
| 335 | } | ||
| 336 | } | ||
| 337 | kfree(old); | ||
| 338 | |||
| 339 | return 0; | ||
| 340 | } | ||
| 341 | |||
| 342 | |||
| 343 | /*****************************************************************************/ | ||
| 344 | /* The extended error reporting functionality */ | ||
| 345 | /*****************************************************************************/ | ||
| 346 | |||
| 347 | /* | ||
| 348 | * When a DASD device driver wants to report an error, it calls the | ||
| 349 | * function dasd_eer_write_trigger (via a notifier mechanism) and gives the | ||
| 350 | * respective trigger ID as parameter. | ||
| 351 | * Currently there are four kinds of triggers: | ||
| 352 | * | ||
| 353 | * DASD_EER_FATALERROR: all kinds of unrecoverable I/O problems | ||
| 354 | * DASD_EER_PPRCSUSPEND: PPRC was suspended | ||
| 355 | * DASD_EER_NOPATH: There is no path to the device left. | ||
| 356 | * DASD_EER_STATECHANGE: The state of the device has changed. | ||
| 357 | * | ||
| 358 | * For the first three triggers all required information can be supplied by | ||
| 359 | * the caller. For these triggers a record is written by the function | ||
| 360 | * dasd_eer_write_standard_trigger. | ||
| 361 | * | ||
| 362 | * When dasd_eer_write_trigger is called to write a DASD_EER_STATECHANGE | ||
| 363 | * trigger, we have to gather the necessary sense data first. We cannot queue | ||
| 364 | * the necessary SNSS (sense subsystem status) request immediatly, since we | ||
| 365 | * are likely to run in a deadlock situation. Instead, we schedule a | ||
| 366 | * work_struct that calls the function dasd_eer_sense_subsystem_status to | ||
| 367 | * create and start an SNSS request asynchronously. | ||
| 368 | * | ||
| 369 | * To avoid memory allocations at runtime, the necessary memory is allocated | ||
| 370 | * when the extended error reporting is enabled for a device (by | ||
| 371 | * dasd_eer_probe). There is one private eer data structure for each eer | ||
| 372 | * enabled DASD device. It contains memory for the work_struct, one SNSS cqr | ||
| 373 | * and a flags field that is used to coordinate the use of the cqr. The call | ||
| 374 | * to write a state change trigger can come in at any time, so we have one flag | ||
| 375 | * CQR_IN_USE that protects the cqr itself. When this flag indicates that the | ||
| 376 | * cqr is currently in use, dasd_eer_sense_subsystem_status cannot start a | ||
| 377 | * second request but sets the SNSS_REQUESTED flag instead. | ||
| 378 | * | ||
| 379 | * When the request is finished, the callback function dasd_eer_SNSS_cb | ||
| 380 | * is called. This function will invoke the function | ||
| 381 | * dasd_eer_write_SNSS_trigger to finally write the trigger. It will also | ||
| 382 | * check the SNSS_REQUESTED flag and if it is set it will call | ||
| 383 | * dasd_eer_sense_subsystem_status again. | ||
| 384 | * | ||
| 385 | * To avoid race conditions during the handling of the lock, the flags must | ||
| 386 | * be protected by the snsslock. | ||
| 387 | */ | ||
| 388 | |||
| 389 | struct dasd_eer_private { | ||
| 390 | struct dasd_ccw_req *cqr; | ||
| 391 | unsigned long flags; | ||
| 392 | struct work_struct worker; | ||
| 393 | }; | ||
| 394 | |||
| 395 | static void dasd_eer_destroy(struct dasd_device *device, | ||
| 396 | struct dasd_eer_private *eer); | ||
| 397 | static int | ||
| 398 | dasd_eer_write_trigger(struct dasd_eer_trigger *trigger); | ||
| 399 | static void dasd_eer_sense_subsystem_status(void *data); | ||
| 400 | static int dasd_eer_notify(struct notifier_block *self, | ||
| 401 | unsigned long action, void *data); | ||
| 402 | |||
| 403 | struct workqueue_struct *dasd_eer_workqueue; | ||
| 404 | |||
| 405 | #define SNSS_DATA_SIZE 44 | ||
| 406 | static spinlock_t snsslock = SPIN_LOCK_UNLOCKED; | ||
| 407 | |||
| 408 | #define DASD_EER_BUSID_SIZE 10 | ||
| 409 | struct dasd_eer_header { | ||
| 410 | __u32 total_size; | ||
| 411 | __u32 trigger; | ||
| 412 | __u64 tv_sec; | ||
| 413 | __u64 tv_usec; | ||
| 414 | char busid[DASD_EER_BUSID_SIZE]; | ||
| 415 | } __attribute__ ((packed)); | ||
| 416 | |||
| 417 | static struct notifier_block dasd_eer_nb = { | ||
| 418 | .notifier_call = dasd_eer_notify, | ||
| 419 | }; | ||
| 420 | |||
| 421 | /* | ||
| 422 | * flags for use with dasd_eer_private | ||
| 423 | */ | ||
| 424 | #define CQR_IN_USE 0 | ||
| 425 | #define SNSS_REQUESTED 1 | ||
| 426 | |||
| 427 | /* | ||
| 428 | * This function checks if extended error reporting is available for a given | ||
| 429 | * dasd_device. If yes, then it creates and returns a struct dasd_eer, | ||
| 430 | * otherwise it returns an -EPERM error pointer. | ||
| 431 | */ | ||
| 432 | struct dasd_eer_private * | ||
| 433 | dasd_eer_probe(struct dasd_device *device) | ||
| 434 | { | ||
| 435 | struct dasd_eer_private *private; | ||
| 436 | |||
| 437 | if (!(device && device->discipline | ||
| 438 | && !strcmp(device->discipline->name, "ECKD"))) { | ||
| 439 | return ERR_PTR(-EPERM); | ||
| 440 | } | ||
| 441 | /* allocate the private data structure */ | ||
| 442 | private = (struct dasd_eer_private *)kmalloc( | ||
| 443 | sizeof(struct dasd_eer_private), GFP_KERNEL); | ||
| 444 | if (!private) { | ||
| 445 | return ERR_PTR(-ENOMEM); | ||
| 446 | } | ||
| 447 | INIT_WORK(&private->worker, dasd_eer_sense_subsystem_status, | ||
| 448 | (void *)device); | ||
| 449 | private->cqr = dasd_kmalloc_request("ECKD", | ||
| 450 | 1 /* SNSS */ , | ||
| 451 | SNSS_DATA_SIZE , | ||
| 452 | device); | ||
| 453 | if (!private->cqr) { | ||
| 454 | kfree(private); | ||
| 455 | return ERR_PTR(-ENOMEM); | ||
| 456 | } | ||
| 457 | private->flags = 0; | ||
| 458 | return private; | ||
| 459 | }; | ||
| 460 | |||
| 461 | /* | ||
| 462 | * If our private SNSS request is queued, remove it from the | ||
| 463 | * dasd ccw queue so we can free the requests memory. | ||
| 464 | */ | ||
| 465 | static void | ||
| 466 | dasd_eer_dequeue_SNSS_request(struct dasd_device *device, | ||
| 467 | struct dasd_eer_private *eer) | ||
| 468 | { | ||
| 469 | struct list_head *lst, *nxt; | ||
| 470 | struct dasd_ccw_req *cqr, *erpcqr; | ||
| 471 | dasd_erp_fn_t erp_fn; | ||
| 472 | |||
| 473 | spin_lock_irq(get_ccwdev_lock(device->cdev)); | ||
| 474 | list_for_each_safe(lst, nxt, &device->ccw_queue) { | ||
| 475 | cqr = list_entry(lst, struct dasd_ccw_req, list); | ||
| 476 | /* we are looking for two kinds or requests */ | ||
| 477 | /* first kind: our SNSS request: */ | ||
| 478 | if (cqr == eer->cqr) { | ||
| 479 | if (cqr->status == DASD_CQR_IN_IO) | ||
| 480 | device->discipline->term_IO(cqr); | ||
| 481 | list_del(&cqr->list); | ||
| 482 | break; | ||
| 483 | } | ||
| 484 | /* second kind: ERP requests for our SNSS request */ | ||
| 485 | if (cqr->refers) { | ||
| 486 | /* If this erp request chain ends in our cqr, then */ | ||
| 487 | /* cal the erp_postaction to clean it up */ | ||
| 488 | erpcqr = cqr; | ||
| 489 | while (erpcqr->refers) { | ||
| 490 | erpcqr = erpcqr->refers; | ||
| 491 | } | ||
| 492 | if (erpcqr == eer->cqr) { | ||
| 493 | erp_fn = device->discipline->erp_postaction( | ||
| 494 | cqr); | ||
| 495 | erp_fn(cqr); | ||
| 496 | } | ||
| 497 | continue; | ||
| 498 | } | ||
| 499 | } | ||
| 500 | spin_unlock_irq(get_ccwdev_lock(device->cdev)); | ||
| 501 | } | ||
| 502 | |||
| 503 | /* | ||
| 504 | * This function dismantles a struct dasd_eer that was created by | ||
| 505 | * dasd_eer_probe. Since we want to free our private data structure, | ||
| 506 | * we must make sure that the memory is not in use anymore. | ||
| 507 | * We have to flush the work queue and remove a possible SNSS request | ||
| 508 | * from the dasd queue. | ||
| 509 | */ | ||
| 510 | static void | ||
| 511 | dasd_eer_destroy(struct dasd_device *device, struct dasd_eer_private *eer) | ||
| 512 | { | ||
| 513 | flush_workqueue(dasd_eer_workqueue); | ||
| 514 | dasd_eer_dequeue_SNSS_request(device, eer); | ||
| 515 | dasd_kfree_request(eer->cqr, device); | ||
| 516 | kfree(eer); | ||
| 517 | }; | ||
| 518 | |||
| 519 | /* | ||
| 520 | * enable the extended error reporting for a particular device | ||
| 521 | */ | ||
| 522 | static int | ||
| 523 | dasd_eer_enable_on_device(struct dasd_device *device) | ||
| 524 | { | ||
| 525 | void *eer; | ||
| 526 | if (!device) | ||
| 527 | return -ENODEV; | ||
| 528 | if (device->eer) | ||
| 529 | return 0; | ||
| 530 | if (!try_module_get(THIS_MODULE)) { | ||
| 531 | return -EINVAL; | ||
| 532 | } | ||
| 533 | eer = (void *)dasd_eer_probe(device); | ||
| 534 | if (IS_ERR(eer)) { | ||
| 535 | module_put(THIS_MODULE); | ||
| 536 | return PTR_ERR(eer); | ||
| 537 | } | ||
| 538 | device->eer = eer; | ||
| 539 | return 0; | ||
| 540 | } | ||
| 541 | |||
| 542 | /* | ||
| 543 | * enable the extended error reporting for a particular device | ||
| 544 | */ | ||
| 545 | static int | ||
| 546 | dasd_eer_disable_on_device(struct dasd_device *device) | ||
| 547 | { | ||
| 548 | struct dasd_eer_private *eer = device->eer; | ||
| 549 | |||
| 550 | if (!device) | ||
| 551 | return -ENODEV; | ||
| 552 | if (!device->eer) | ||
| 553 | return 0; | ||
| 554 | device->eer = NULL; | ||
| 555 | dasd_eer_destroy(device,eer); | ||
| 556 | module_put(THIS_MODULE); | ||
| 557 | |||
| 558 | return 0; | ||
| 559 | } | ||
| 560 | |||
| 561 | /* | ||
| 562 | * Set extended error reporting (eer) | ||
| 563 | * Note: This will be registered as a DASD ioctl, to be called on DASD devices. | ||
| 564 | */ | ||
| 565 | static int | ||
| 566 | dasd_ioctl_set_eer(struct block_device *bdev, int no, long args) | ||
| 567 | { | ||
| 568 | struct dasd_device *device; | ||
| 569 | int intval; | ||
| 570 | |||
| 571 | if (!capable(CAP_SYS_ADMIN)) | ||
| 572 | return -EACCES; | ||
| 573 | if (bdev != bdev->bd_contains) | ||
| 574 | /* Error-reporting is not allowed for partitions */ | ||
| 575 | return -EINVAL; | ||
| 576 | if (get_user(intval, (int __user *) args)) | ||
| 577 | return -EFAULT; | ||
| 578 | device = bdev->bd_disk->private_data; | ||
| 579 | if (device == NULL) | ||
| 580 | return -ENODEV; | ||
| 581 | |||
| 582 | intval = (intval != 0); | ||
| 583 | DEV_MESSAGE (KERN_DEBUG, device, | ||
| 584 | "set eer on device to %d", intval); | ||
| 585 | if (intval) | ||
| 586 | return dasd_eer_enable_on_device(device); | ||
| 587 | else | ||
| 588 | return dasd_eer_disable_on_device(device); | ||
| 589 | } | ||
| 590 | |||
| 591 | /* | ||
| 592 | * Get value of extended error reporting. | ||
| 593 | * Note: This will be registered as a DASD ioctl, to be called on DASD devices. | ||
| 594 | */ | ||
| 595 | static int | ||
| 596 | dasd_ioctl_get_eer(struct block_device *bdev, int no, long args) | ||
| 597 | { | ||
| 598 | struct dasd_device *device; | ||
| 599 | |||
| 600 | device = bdev->bd_disk->private_data; | ||
| 601 | if (device == NULL) | ||
| 602 | return -ENODEV; | ||
| 603 | return put_user((device->eer != NULL), (int __user *) args); | ||
| 604 | } | ||
| 605 | |||
| 606 | /* | ||
| 607 | * The following function can be used for those triggers that have | ||
| 608 | * all necessary data available when the function is called. | ||
| 609 | * If the parameter cqr is not NULL, the chain of requests will be searched | ||
| 610 | * for valid sense data, and all valid sense data sets will be added to | ||
| 611 | * the triggers data. | ||
| 612 | */ | ||
| 613 | static int | ||
| 614 | dasd_eer_write_standard_trigger(int trigger, struct dasd_device *device, | ||
| 615 | struct dasd_ccw_req *cqr) | ||
| 616 | { | ||
| 617 | struct dasd_ccw_req *temp_cqr; | ||
| 618 | int data_size; | ||
| 619 | struct timeval tv; | ||
| 620 | struct dasd_eer_header header; | ||
| 621 | unsigned long flags; | ||
| 622 | struct eerbuffer *eerb; | ||
| 623 | |||
| 624 | /* go through cqr chain and count the valid sense data sets */ | ||
| 625 | temp_cqr = cqr; | ||
| 626 | data_size = 0; | ||
| 627 | while (temp_cqr) { | ||
| 628 | if (temp_cqr->irb.esw.esw0.erw.cons) | ||
| 629 | data_size += 32; | ||
| 630 | temp_cqr = temp_cqr->refers; | ||
| 631 | } | ||
| 632 | |||
| 633 | header.total_size = sizeof(header) + data_size + 4; /* "EOR" */ | ||
| 634 | header.trigger = trigger; | ||
| 635 | do_gettimeofday(&tv); | ||
| 636 | header.tv_sec = tv.tv_sec; | ||
| 637 | header.tv_usec = tv.tv_usec; | ||
| 638 | strncpy(header.busid, device->cdev->dev.bus_id, DASD_EER_BUSID_SIZE); | ||
| 639 | |||
| 640 | spin_lock_irqsave(&bufferlock, flags); | ||
| 641 | list_for_each_entry(eerb, &bufferlist, list) { | ||
| 642 | dasd_eer_start_record(eerb, header.total_size); | ||
| 643 | dasd_eer_write_buffer(eerb, sizeof(header), (char*)(&header)); | ||
| 644 | temp_cqr = cqr; | ||
| 645 | while (temp_cqr) { | ||
| 646 | if (temp_cqr->irb.esw.esw0.erw.cons) | ||
| 647 | dasd_eer_write_buffer(eerb, 32, cqr->irb.ecw); | ||
| 648 | temp_cqr = temp_cqr->refers; | ||
| 649 | } | ||
| 650 | dasd_eer_write_buffer(eerb, 4,"EOR"); | ||
| 651 | } | ||
| 652 | spin_unlock_irqrestore(&bufferlock, flags); | ||
| 653 | |||
| 654 | wake_up_interruptible(&dasd_eer_read_wait_queue); | ||
| 655 | |||
| 656 | return 0; | ||
| 657 | } | ||
| 658 | |||
| 659 | /* | ||
| 660 | * This function writes a DASD_EER_STATECHANGE trigger. | ||
| 661 | */ | ||
| 662 | static void | ||
| 663 | dasd_eer_write_SNSS_trigger(struct dasd_device *device, | ||
| 664 | struct dasd_ccw_req *cqr) | ||
| 665 | { | ||
| 666 | int data_size; | ||
| 667 | int snss_rc; | ||
| 668 | struct timeval tv; | ||
| 669 | struct dasd_eer_header header; | ||
| 670 | unsigned long flags; | ||
| 671 | struct eerbuffer *eerb; | ||
| 672 | |||
| 673 | snss_rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0; | ||
| 674 | if (snss_rc) | ||
| 675 | data_size = 0; | ||
| 676 | else | ||
| 677 | data_size = SNSS_DATA_SIZE; | ||
| 678 | |||
| 679 | header.total_size = sizeof(header) + data_size + 4; /* "EOR" */ | ||
| 680 | header.trigger = DASD_EER_STATECHANGE; | ||
| 681 | do_gettimeofday(&tv); | ||
| 682 | header.tv_sec = tv.tv_sec; | ||
| 683 | header.tv_usec = tv.tv_usec; | ||
| 684 | strncpy(header.busid, device->cdev->dev.bus_id, DASD_EER_BUSID_SIZE); | ||
| 685 | |||
| 686 | spin_lock_irqsave(&bufferlock, flags); | ||
| 687 | list_for_each_entry(eerb, &bufferlist, list) { | ||
| 688 | dasd_eer_start_record(eerb, header.total_size); | ||
| 689 | dasd_eer_write_buffer(eerb, sizeof(header),(char*)(&header)); | ||
| 690 | if (!snss_rc) | ||
| 691 | dasd_eer_write_buffer(eerb, SNSS_DATA_SIZE, cqr->data); | ||
| 692 | dasd_eer_write_buffer(eerb, 4,"EOR"); | ||
| 693 | } | ||
| 694 | spin_unlock_irqrestore(&bufferlock, flags); | ||
| 695 | |||
| 696 | wake_up_interruptible(&dasd_eer_read_wait_queue); | ||
| 697 | } | ||
| 698 | |||
| 699 | /* | ||
| 700 | * callback function for use with SNSS request | ||
| 701 | */ | ||
| 702 | static void | ||
| 703 | dasd_eer_SNSS_cb(struct dasd_ccw_req *cqr, void *data) | ||
| 704 | { | ||
| 705 | struct dasd_device *device; | ||
| 706 | struct dasd_eer_private *private; | ||
| 707 | unsigned long irqflags; | ||
| 708 | |||
| 709 | device = (struct dasd_device *)data; | ||
| 710 | private = (struct dasd_eer_private *)device->eer; | ||
| 711 | dasd_eer_write_SNSS_trigger(device, cqr); | ||
| 712 | spin_lock_irqsave(&snsslock, irqflags); | ||
| 713 | if(!test_and_clear_bit(SNSS_REQUESTED, &private->flags)) { | ||
| 714 | clear_bit(CQR_IN_USE, &private->flags); | ||
| 715 | spin_unlock_irqrestore(&snsslock, irqflags); | ||
| 716 | return; | ||
| 717 | }; | ||
| 718 | clear_bit(CQR_IN_USE, &private->flags); | ||
| 719 | spin_unlock_irqrestore(&snsslock, irqflags); | ||
| 720 | dasd_eer_sense_subsystem_status(device); | ||
| 721 | return; | ||
| 722 | } | ||
| 723 | |||
| 724 | /* | ||
| 725 | * clean a used cqr before using it again | ||
| 726 | */ | ||
| 727 | static void | ||
| 728 | dasd_eer_clean_SNSS_request(struct dasd_ccw_req *cqr) | ||
| 729 | { | ||
| 730 | struct ccw1 *cpaddr = cqr->cpaddr; | ||
| 731 | void *data = cqr->data; | ||
| 732 | |||
| 733 | memset(cqr, 0, sizeof(struct dasd_ccw_req)); | ||
| 734 | memset(cpaddr, 0, sizeof(struct ccw1)); | ||
| 735 | memset(data, 0, SNSS_DATA_SIZE); | ||
| 736 | cqr->cpaddr = cpaddr; | ||
| 737 | cqr->data = data; | ||
| 738 | strncpy((char *) &cqr->magic, "ECKD", 4); | ||
| 739 | ASCEBC((char *) &cqr->magic, 4); | ||
| 740 | set_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); | ||
| 741 | } | ||
| 742 | |||
| 743 | /* | ||
| 744 | * build and start an SNSS request | ||
| 745 | * This function is called from a work queue so we have to | ||
| 746 | * pass the dasd_device pointer as a void pointer. | ||
| 747 | */ | ||
| 748 | static void | ||
| 749 | dasd_eer_sense_subsystem_status(void *data) | ||
| 750 | { | ||
| 751 | struct dasd_device *device; | ||
| 752 | struct dasd_eer_private *private; | ||
| 753 | struct dasd_ccw_req *cqr; | ||
| 754 | struct ccw1 *ccw; | ||
| 755 | unsigned long irqflags; | ||
| 756 | |||
| 757 | device = (struct dasd_device *)data; | ||
| 758 | private = (struct dasd_eer_private *)device->eer; | ||
| 759 | if (!private) /* device not eer enabled any more */ | ||
| 760 | return; | ||
| 761 | cqr = private->cqr; | ||
| 762 | spin_lock_irqsave(&snsslock, irqflags); | ||
| 763 | if(test_and_set_bit(CQR_IN_USE, &private->flags)) { | ||
| 764 | set_bit(SNSS_REQUESTED, &private->flags); | ||
| 765 | spin_unlock_irqrestore(&snsslock, irqflags); | ||
| 766 | return; | ||
| 767 | }; | ||
| 768 | spin_unlock_irqrestore(&snsslock, irqflags); | ||
| 769 | dasd_eer_clean_SNSS_request(cqr); | ||
| 770 | cqr->device = device; | ||
| 771 | cqr->retries = 255; | ||
| 772 | cqr->expires = 10 * HZ; | ||
| 773 | |||
| 774 | ccw = cqr->cpaddr; | ||
| 775 | ccw->cmd_code = DASD_ECKD_CCW_SNSS; | ||
| 776 | ccw->count = SNSS_DATA_SIZE; | ||
| 777 | ccw->flags = 0; | ||
| 778 | ccw->cda = (__u32)(addr_t)cqr->data; | ||
| 779 | |||
| 780 | cqr->buildclk = get_clock(); | ||
| 781 | cqr->status = DASD_CQR_FILLED; | ||
| 782 | cqr->callback = dasd_eer_SNSS_cb; | ||
| 783 | cqr->callback_data = (void *)device; | ||
| 784 | dasd_add_request_head(cqr); | ||
| 785 | |||
| 786 | return; | ||
| 787 | } | ||
| 788 | |||
| 789 | /* | ||
| 790 | * This function is called for all triggers. It calls the appropriate | ||
| 791 | * function that writes the actual trigger records. | ||
| 792 | */ | ||
| 793 | static int | ||
| 794 | dasd_eer_write_trigger(struct dasd_eer_trigger *trigger) | ||
| 795 | { | ||
| 796 | int rc; | ||
| 797 | struct dasd_eer_private *private = trigger->device->eer; | ||
| 798 | |||
| 799 | switch (trigger->id) { | ||
| 800 | case DASD_EER_FATALERROR: | ||
| 801 | case DASD_EER_PPRCSUSPEND: | ||
| 802 | rc = dasd_eer_write_standard_trigger( | ||
| 803 | trigger->id, trigger->device, trigger->cqr); | ||
| 804 | break; | ||
| 805 | case DASD_EER_NOPATH: | ||
| 806 | rc = dasd_eer_write_standard_trigger( | ||
| 807 | trigger->id, trigger->device, NULL); | ||
| 808 | break; | ||
| 809 | case DASD_EER_STATECHANGE: | ||
| 810 | if (queue_work(dasd_eer_workqueue, &private->worker)) { | ||
| 811 | rc=0; | ||
| 812 | } else { | ||
| 813 | /* If the work_struct was already queued, it can't | ||
| 814 | * be queued again. But this is OK since we don't | ||
| 815 | * need to have it queued twice. | ||
| 816 | */ | ||
| 817 | rc = -EBUSY; | ||
| 818 | } | ||
| 819 | break; | ||
| 820 | default: /* unknown trigger, so we write it without any sense data */ | ||
| 821 | rc = dasd_eer_write_standard_trigger( | ||
| 822 | trigger->id, trigger->device, NULL); | ||
| 823 | break; | ||
| 824 | } | ||
| 825 | return rc; | ||
| 826 | } | ||
| 827 | |||
| 828 | /* | ||
| 829 | * This function is registered with the dasd device driver and gets called | ||
| 830 | * for all dasd eer notifications. | ||
| 831 | */ | ||
| 832 | static int dasd_eer_notify(struct notifier_block *self, | ||
| 833 | unsigned long action, void *data) | ||
| 834 | { | ||
| 835 | switch (action) { | ||
| 836 | case DASD_EER_DISABLE: | ||
| 837 | dasd_eer_disable_on_device((struct dasd_device *)data); | ||
| 838 | break; | ||
| 839 | case DASD_EER_TRIGGER: | ||
| 840 | dasd_eer_write_trigger((struct dasd_eer_trigger *)data); | ||
| 841 | break; | ||
| 842 | } | ||
| 843 | return NOTIFY_OK; | ||
| 844 | } | ||
| 845 | |||
| 846 | |||
| 847 | /*****************************************************************************/ | ||
| 848 | /* the device operations */ | ||
| 849 | /*****************************************************************************/ | ||
| 850 | |||
| 851 | /* | ||
| 852 | * On the one side we need a lock to access our internal buffer, on the | ||
| 853 | * other side a copy_to_user can sleep. So we need to copy the data we have | ||
| 854 | * to transfer in a readbuffer, which is protected by the readbuffer_mutex. | ||
| 855 | */ | ||
| 856 | static char readbuffer[PAGE_SIZE]; | ||
| 857 | DECLARE_MUTEX(readbuffer_mutex); | ||
| 858 | |||
| 859 | |||
| 860 | static int | ||
| 861 | dasd_eer_open(struct inode *inp, struct file *filp) | ||
| 862 | { | ||
| 863 | struct eerbuffer *eerb; | ||
| 864 | unsigned long flags; | ||
| 865 | |||
| 866 | eerb = kmalloc(sizeof(struct eerbuffer), GFP_KERNEL); | ||
| 867 | eerb->head = 0; | ||
| 868 | eerb->tail = 0; | ||
| 869 | eerb->residual = 0; | ||
| 870 | eerb->buffer_page_count = 1; | ||
| 871 | eerb->buffersize = eerb->buffer_page_count * PAGE_SIZE; | ||
| 872 | eerb->buffer = kmalloc(eerb->buffer_page_count*sizeof(char*), | ||
| 873 | GFP_KERNEL); | ||
| 874 | if (!eerb->buffer) | ||
| 875 | return -ENOMEM; | ||
| 876 | if (dasd_eer_allocate_buffer_pages(eerb->buffer, | ||
| 877 | eerb->buffer_page_count)) { | ||
| 878 | kfree(eerb->buffer); | ||
| 879 | return -ENOMEM; | ||
| 880 | } | ||
| 881 | filp->private_data = eerb; | ||
| 882 | spin_lock_irqsave(&bufferlock, flags); | ||
| 883 | list_add(&eerb->list, &bufferlist); | ||
| 884 | spin_unlock_irqrestore(&bufferlock, flags); | ||
| 885 | |||
| 886 | return nonseekable_open(inp,filp); | ||
| 887 | } | ||
| 888 | |||
| 889 | static int | ||
| 890 | dasd_eer_close(struct inode *inp, struct file *filp) | ||
| 891 | { | ||
| 892 | struct eerbuffer *eerb; | ||
| 893 | unsigned long flags; | ||
| 894 | |||
| 895 | eerb = (struct eerbuffer *)filp->private_data; | ||
| 896 | spin_lock_irqsave(&bufferlock, flags); | ||
| 897 | list_del(&eerb->list); | ||
| 898 | spin_unlock_irqrestore(&bufferlock, flags); | ||
| 899 | dasd_eer_free_buffer_pages(eerb->buffer, eerb->buffer_page_count); | ||
| 900 | kfree(eerb->buffer); | ||
| 901 | kfree(eerb); | ||
| 902 | |||
| 903 | return 0; | ||
| 904 | } | ||
| 905 | |||
| 906 | static long | ||
| 907 | dasd_eer_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | ||
| 908 | { | ||
| 909 | int intval; | ||
| 910 | struct eerbuffer *eerb; | ||
| 911 | |||
| 912 | eerb = (struct eerbuffer *)filp->private_data; | ||
| 913 | switch (cmd) { | ||
| 914 | case DASD_EER_PURGE: | ||
| 915 | dasd_eer_purge_buffer(eerb); | ||
| 916 | return 0; | ||
| 917 | case DASD_EER_SETBUFSIZE: | ||
| 918 | if (get_user(intval, (int __user *)arg)) | ||
| 919 | return -EFAULT; | ||
| 920 | return dasd_eer_resize_buffer(eerb, intval); | ||
| 921 | default: | ||
| 922 | return -ENOIOCTLCMD; | ||
| 923 | } | ||
| 924 | } | ||
| 925 | |||
| 926 | static ssize_t | ||
| 927 | dasd_eer_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) | ||
| 928 | { | ||
| 929 | int tc,rc; | ||
| 930 | int tailcount,effective_count; | ||
| 931 | unsigned long flags; | ||
| 932 | struct eerbuffer *eerb; | ||
| 933 | |||
| 934 | eerb = (struct eerbuffer *)filp->private_data; | ||
| 935 | if(down_interruptible(&readbuffer_mutex)) | ||
| 936 | return -ERESTARTSYS; | ||
| 937 | |||
| 938 | spin_lock_irqsave(&bufferlock, flags); | ||
| 939 | |||
| 940 | if (eerb->residual < 0) { /* the remainder of this record */ | ||
| 941 | /* has been deleted */ | ||
| 942 | eerb->residual = 0; | ||
| 943 | spin_unlock_irqrestore(&bufferlock, flags); | ||
| 944 | up(&readbuffer_mutex); | ||
| 945 | return -EIO; | ||
| 946 | } else if (eerb->residual > 0) { | ||
| 947 | /* OK we still have a second half of a record to deliver */ | ||
| 948 | effective_count = min(eerb->residual, (int)count); | ||
| 949 | eerb->residual -= effective_count; | ||
| 950 | } else { | ||
| 951 | tc = 0; | ||
| 952 | while (!tc) { | ||
| 953 | tc = dasd_eer_read_buffer(eerb, | ||
| 954 | sizeof(tailcount), (char*)(&tailcount)); | ||
| 955 | if (!tc) { | ||
| 956 | /* no data available */ | ||
| 957 | spin_unlock_irqrestore(&bufferlock, flags); | ||
| 958 | up(&readbuffer_mutex); | ||
| 959 | if (filp->f_flags & O_NONBLOCK) | ||
| 960 | return -EAGAIN; | ||
| 961 | rc = wait_event_interruptible( | ||
| 962 | dasd_eer_read_wait_queue, | ||
| 963 | eerb->head != eerb->tail); | ||
| 964 | if (rc) { | ||
| 965 | return rc; | ||
| 966 | } | ||
| 967 | if(down_interruptible(&readbuffer_mutex)) | ||
| 968 | return -ERESTARTSYS; | ||
| 969 | spin_lock_irqsave(&bufferlock, flags); | ||
| 970 | } | ||
| 971 | } | ||
| 972 | WARN_ON(tc != sizeof(tailcount)); | ||
| 973 | effective_count = min(tailcount,(int)count); | ||
| 974 | eerb->residual = tailcount - effective_count; | ||
| 975 | } | ||
| 976 | |||
| 977 | tc = dasd_eer_read_buffer(eerb, effective_count, readbuffer); | ||
| 978 | WARN_ON(tc != effective_count); | ||
| 979 | |||
| 980 | spin_unlock_irqrestore(&bufferlock, flags); | ||
| 981 | |||
| 982 | if (copy_to_user(buf, readbuffer, effective_count)) { | ||
| 983 | up(&readbuffer_mutex); | ||
| 984 | return -EFAULT; | ||
| 985 | } | ||
| 986 | |||
| 987 | up(&readbuffer_mutex); | ||
| 988 | return effective_count; | ||
| 989 | } | ||
| 990 | |||
| 991 | static unsigned int | ||
| 992 | dasd_eer_poll (struct file *filp, poll_table *ptable) | ||
| 993 | { | ||
| 994 | unsigned int mask; | ||
| 995 | unsigned long flags; | ||
| 996 | struct eerbuffer *eerb; | ||
| 997 | |||
| 998 | eerb = (struct eerbuffer *)filp->private_data; | ||
| 999 | poll_wait(filp, &dasd_eer_read_wait_queue, ptable); | ||
| 1000 | spin_lock_irqsave(&bufferlock, flags); | ||
| 1001 | if (eerb->head != eerb->tail) | ||
| 1002 | mask = POLLIN | POLLRDNORM ; | ||
| 1003 | else | ||
| 1004 | mask = 0; | ||
| 1005 | spin_unlock_irqrestore(&bufferlock, flags); | ||
| 1006 | return mask; | ||
| 1007 | } | ||
| 1008 | |||
| 1009 | static struct file_operations dasd_eer_fops = { | ||
| 1010 | .open = &dasd_eer_open, | ||
| 1011 | .release = &dasd_eer_close, | ||
| 1012 | .unlocked_ioctl = &dasd_eer_ioctl, | ||
| 1013 | .compat_ioctl = &dasd_eer_ioctl, | ||
| 1014 | .read = &dasd_eer_read, | ||
| 1015 | .poll = &dasd_eer_poll, | ||
| 1016 | .owner = THIS_MODULE, | ||
| 1017 | }; | ||
| 1018 | |||
| 1019 | static struct miscdevice dasd_eer_dev = { | ||
| 1020 | .minor = MISC_DYNAMIC_MINOR, | ||
| 1021 | .name = "dasd_eer", | ||
| 1022 | .fops = &dasd_eer_fops, | ||
| 1023 | }; | ||
| 1024 | |||
| 1025 | |||
| 1026 | /*****************************************************************************/ | ||
| 1027 | /* Init and exit */ | ||
| 1028 | /*****************************************************************************/ | ||
| 1029 | |||
| 1030 | static int | ||
| 1031 | __init dasd_eer_init(void) | ||
| 1032 | { | ||
| 1033 | int rc; | ||
| 1034 | |||
| 1035 | dasd_eer_workqueue = create_singlethread_workqueue("dasd_eer"); | ||
| 1036 | if (!dasd_eer_workqueue) { | ||
| 1037 | MESSAGE(KERN_ERR , "%s", "dasd_eer_init could not " | ||
| 1038 | "create workqueue \n"); | ||
| 1039 | rc = -ENOMEM; | ||
| 1040 | goto out; | ||
| 1041 | } | ||
| 1042 | |||
| 1043 | rc = dasd_register_eer_notifier(&dasd_eer_nb); | ||
| 1044 | if (rc) { | ||
| 1045 | MESSAGE(KERN_ERR, "%s", "dasd_eer_init could not " | ||
| 1046 | "register error reporting"); | ||
| 1047 | goto queue; | ||
| 1048 | } | ||
| 1049 | |||
| 1050 | dasd_ioctl_no_register(THIS_MODULE, BIODASDEERSET, dasd_ioctl_set_eer); | ||
| 1051 | dasd_ioctl_no_register(THIS_MODULE, BIODASDEERGET, dasd_ioctl_get_eer); | ||
| 1052 | |||
| 1053 | /* we don't need our own character device, | ||
| 1054 | * so we just register as misc device */ | ||
| 1055 | rc = misc_register(&dasd_eer_dev); | ||
| 1056 | if (rc) { | ||
| 1057 | MESSAGE(KERN_ERR, "%s", "dasd_eer_init could not " | ||
| 1058 | "register misc device"); | ||
| 1059 | goto unregister; | ||
| 1060 | } | ||
| 1061 | |||
| 1062 | return 0; | ||
| 1063 | |||
| 1064 | unregister: | ||
| 1065 | dasd_unregister_eer_notifier(&dasd_eer_nb); | ||
| 1066 | dasd_ioctl_no_unregister(THIS_MODULE, BIODASDEERSET, | ||
| 1067 | dasd_ioctl_set_eer); | ||
| 1068 | dasd_ioctl_no_unregister(THIS_MODULE, BIODASDEERGET, | ||
| 1069 | dasd_ioctl_get_eer); | ||
| 1070 | queue: | ||
| 1071 | destroy_workqueue(dasd_eer_workqueue); | ||
| 1072 | out: | ||
| 1073 | return rc; | ||
| 1074 | |||
| 1075 | } | ||
| 1076 | module_init(dasd_eer_init); | ||
| 1077 | |||
| 1078 | static void | ||
| 1079 | __exit dasd_eer_exit(void) | ||
| 1080 | { | ||
| 1081 | dasd_unregister_eer_notifier(&dasd_eer_nb); | ||
| 1082 | dasd_ioctl_no_unregister(THIS_MODULE, BIODASDEERSET, | ||
| 1083 | dasd_ioctl_set_eer); | ||
| 1084 | dasd_ioctl_no_unregister(THIS_MODULE, BIODASDEERGET, | ||
| 1085 | dasd_ioctl_get_eer); | ||
| 1086 | destroy_workqueue(dasd_eer_workqueue); | ||
| 1087 | |||
| 1088 | WARN_ON(misc_deregister(&dasd_eer_dev) != 0); | ||
| 1089 | } | ||
| 1090 | module_exit(dasd_eer_exit); | ||
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index c20af9874500..d1b08fa13fd2 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
| @@ -275,6 +275,34 @@ struct dasd_discipline { | |||
| 275 | 275 | ||
| 276 | extern struct dasd_discipline *dasd_diag_discipline_pointer; | 276 | extern struct dasd_discipline *dasd_diag_discipline_pointer; |
| 277 | 277 | ||
| 278 | |||
| 279 | /* | ||
| 280 | * Notification numbers for extended error reporting notifications: | ||
| 281 | * The DASD_EER_DISABLE notification is sent before a dasd_device (and it's | ||
| 282 | * eer pointer) is freed. The error reporting module needs to do all necessary | ||
| 283 | * cleanup steps. | ||
| 284 | * The DASD_EER_TRIGGER notification sends the actual error reports (triggers). | ||
| 285 | */ | ||
| 286 | #define DASD_EER_DISABLE 0 | ||
| 287 | #define DASD_EER_TRIGGER 1 | ||
| 288 | |||
| 289 | /* Trigger IDs for extended error reporting DASD_EER_TRIGGER notification */ | ||
| 290 | #define DASD_EER_FATALERROR 1 | ||
| 291 | #define DASD_EER_NOPATH 2 | ||
| 292 | #define DASD_EER_STATECHANGE 3 | ||
| 293 | #define DASD_EER_PPRCSUSPEND 4 | ||
| 294 | |||
| 295 | /* | ||
| 296 | * The dasd_eer_trigger structure contains all data that we need to send | ||
| 297 | * along with an DASD_EER_TRIGGER notification. | ||
| 298 | */ | ||
| 299 | struct dasd_eer_trigger { | ||
| 300 | unsigned int id; | ||
| 301 | struct dasd_device *device; | ||
| 302 | struct dasd_ccw_req *cqr; | ||
| 303 | }; | ||
| 304 | |||
| 305 | |||
| 278 | struct dasd_device { | 306 | struct dasd_device { |
| 279 | /* Block device stuff. */ | 307 | /* Block device stuff. */ |
| 280 | struct gendisk *gdp; | 308 | struct gendisk *gdp; |
| @@ -288,6 +316,9 @@ struct dasd_device { | |||
| 288 | unsigned long flags; /* per device flags */ | 316 | unsigned long flags; /* per device flags */ |
| 289 | unsigned short features; /* copy of devmap-features (read-only!) */ | 317 | unsigned short features; /* copy of devmap-features (read-only!) */ |
| 290 | 318 | ||
| 319 | /* extended error reporting stuff (eer) */ | ||
| 320 | void *eer; | ||
| 321 | |||
| 291 | /* Device discipline stuff. */ | 322 | /* Device discipline stuff. */ |
| 292 | struct dasd_discipline *discipline; | 323 | struct dasd_discipline *discipline; |
| 293 | char *private; | 324 | char *private; |
| @@ -488,6 +519,12 @@ int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *); | |||
| 488 | int dasd_generic_set_offline (struct ccw_device *cdev); | 519 | int dasd_generic_set_offline (struct ccw_device *cdev); |
| 489 | int dasd_generic_notify(struct ccw_device *, int); | 520 | int dasd_generic_notify(struct ccw_device *, int); |
| 490 | void dasd_generic_auto_online (struct ccw_driver *); | 521 | void dasd_generic_auto_online (struct ccw_driver *); |
| 522 | int dasd_register_eer_notifier(struct notifier_block *); | ||
| 523 | int dasd_unregister_eer_notifier(struct notifier_block *); | ||
| 524 | void dasd_write_eer_trigger(unsigned int , struct dasd_device *, | ||
| 525 | struct dasd_ccw_req *); | ||
| 526 | |||
| 527 | |||
| 491 | 528 | ||
| 492 | /* externals in dasd_devmap.c */ | 529 | /* externals in dasd_devmap.c */ |
| 493 | extern int dasd_max_devindex; | 530 | extern int dasd_max_devindex; |
diff --git a/drivers/s390/cio/chsc.h b/drivers/s390/cio/chsc.h index 44e4b4bb1c5a..3e75095f35d0 100644 --- a/drivers/s390/cio/chsc.h +++ b/drivers/s390/cio/chsc.h | |||
| @@ -68,6 +68,6 @@ extern void *chsc_get_chp_desc(struct subchannel*, int); | |||
| 68 | 68 | ||
| 69 | extern int chsc_enable_facility(int); | 69 | extern int chsc_enable_facility(int); |
| 70 | 70 | ||
| 71 | #define to_channelpath(dev) container_of(dev, struct channel_path, dev) | 71 | #define to_channelpath(device) container_of(device, struct channel_path, dev) |
| 72 | 72 | ||
| 73 | #endif | 73 | #endif |
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 38d6d00fb0fc..014cc8d54a9f 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
| @@ -38,10 +38,10 @@ | |||
| 38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
| 39 | #include <linux/completion.h> | 39 | #include <linux/completion.h> |
| 40 | #include <linux/blkdev.h> | 40 | #include <linux/blkdev.h> |
| 41 | #include <linux/delay.h> | ||
| 41 | #include <scsi/scsi_host.h> | 42 | #include <scsi/scsi_host.h> |
| 42 | #include <scsi/scsi_device.h> | 43 | #include <scsi/scsi_device.h> |
| 43 | #include <asm/semaphore.h> | 44 | #include <asm/semaphore.h> |
| 44 | #include <asm/delay.h> | ||
| 45 | 45 | ||
| 46 | #include "aacraid.h" | 46 | #include "aacraid.h" |
| 47 | 47 | ||
diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c index 311a4122bd70..93edaa8696cf 100644 --- a/drivers/scsi/mac53c94.c +++ b/drivers/scsi/mac53c94.c | |||
| @@ -537,9 +537,9 @@ static int mac53c94_remove(struct macio_dev *mdev) | |||
| 537 | free_irq(fp->intr, fp); | 537 | free_irq(fp->intr, fp); |
| 538 | 538 | ||
| 539 | if (fp->regs) | 539 | if (fp->regs) |
| 540 | iounmap((void *) fp->regs); | 540 | iounmap(fp->regs); |
| 541 | if (fp->dma) | 541 | if (fp->dma) |
| 542 | iounmap((void *) fp->dma); | 542 | iounmap(fp->dma); |
| 543 | kfree(fp->dma_cmd_space); | 543 | kfree(fp->dma_cmd_space); |
| 544 | 544 | ||
| 545 | scsi_host_put(host); | 545 | scsi_host_put(host); |
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 245ca99a641e..c551bb84dbfb 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
| @@ -1245,7 +1245,7 @@ static int __init init_scsi(void) | |||
| 1245 | if (error) | 1245 | if (error) |
| 1246 | goto cleanup_sysctl; | 1246 | goto cleanup_sysctl; |
| 1247 | 1247 | ||
| 1248 | for (i = 0; i < NR_CPUS; i++) | 1248 | for_each_cpu(i) |
| 1249 | INIT_LIST_HEAD(&per_cpu(scsi_done_q, i)); | 1249 | INIT_LIST_HEAD(&per_cpu(scsi_done_q, i)); |
| 1250 | 1250 | ||
| 1251 | devfs_mk_dir("scsi"); | 1251 | devfs_mk_dir("scsi"); |
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 59a1c9d9d3bd..723f7acbeb12 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c | |||
| @@ -463,7 +463,7 @@ static inline struct list_head *skb_to_lh(struct sk_buff *skb) | |||
| 463 | } | 463 | } |
| 464 | 464 | ||
| 465 | static void* | 465 | static void* |
| 466 | mempool_zone_alloc_skb(unsigned int gfp_mask, void *pool_data) | 466 | mempool_zone_alloc_skb(gfp_t gfp_mask, void *pool_data) |
| 467 | { | 467 | { |
| 468 | struct mempool_zone *zone = pool_data; | 468 | struct mempool_zone *zone = pool_data; |
| 469 | 469 | ||
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 7d0700091f3d..2a547538d444 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
| @@ -1679,7 +1679,7 @@ static int | |||
| 1679 | sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp, int tablesize) | 1679 | sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp, int tablesize) |
| 1680 | { | 1680 | { |
| 1681 | int sg_bufflen = tablesize * sizeof(struct scatterlist); | 1681 | int sg_bufflen = tablesize * sizeof(struct scatterlist); |
| 1682 | unsigned int gfp_flags = GFP_ATOMIC | __GFP_NOWARN; | 1682 | gfp_t gfp_flags = GFP_ATOMIC | __GFP_NOWARN; |
| 1683 | 1683 | ||
| 1684 | /* | 1684 | /* |
| 1685 | * TODO: test without low_dma, we should not need it since | 1685 | * TODO: test without low_dma, we should not need it since |
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c index 7aef7518b0d1..8c5c276c5577 100644 --- a/drivers/serial/21285.c +++ b/drivers/serial/21285.c | |||
| @@ -362,7 +362,7 @@ static struct uart_ops serial21285_ops = { | |||
| 362 | 362 | ||
| 363 | static struct uart_port serial21285_port = { | 363 | static struct uart_port serial21285_port = { |
| 364 | .mapbase = 0x42000160, | 364 | .mapbase = 0x42000160, |
| 365 | .iotype = SERIAL_IO_MEM, | 365 | .iotype = UPIO_MEM, |
| 366 | .irq = NO_IRQ, | 366 | .irq = NO_IRQ, |
| 367 | .fifosize = 16, | 367 | .fifosize = 16, |
| 368 | .ops = &serial21285_ops, | 368 | .ops = &serial21285_ops, |
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index 8cbf0fc5a225..7f0f35a05dca 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c | |||
| @@ -332,7 +332,7 @@ static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *reg | |||
| 332 | * Make sure that we do not overflow the buffer | 332 | * Make sure that we do not overflow the buffer |
| 333 | */ | 333 | */ |
| 334 | if (tty_request_buffer_room(tty, 1) == 0) { | 334 | if (tty_request_buffer_room(tty, 1) == 0) { |
| 335 | schedule_work(&tty->flip.work); | 335 | tty_schedule_flip(tty); |
| 336 | return; | 336 | return; |
| 337 | } | 337 | } |
| 338 | 338 | ||
| @@ -353,7 +353,7 @@ static _INLINE_ void receive_chars(struct m68k_serial *info, struct pt_regs *reg | |||
| 353 | } while((rx = uart->urx.w) & URX_DATA_READY); | 353 | } while((rx = uart->urx.w) & URX_DATA_READY); |
| 354 | #endif | 354 | #endif |
| 355 | 355 | ||
| 356 | schedule_work(&tty->flip.work); | 356 | tty_schedule_flip(tty); |
| 357 | 357 | ||
| 358 | clear_and_exit: | 358 | clear_and_exit: |
| 359 | return; | 359 | return; |
diff --git a/drivers/serial/68360serial.c b/drivers/serial/68360serial.c index 60f5a5dc17f1..9843ae3d420e 100644 --- a/drivers/serial/68360serial.c +++ b/drivers/serial/68360serial.c | |||
| @@ -509,7 +509,7 @@ static _INLINE_ void receive_chars(ser_info_t *info) | |||
| 509 | 509 | ||
| 510 | info->rx_cur = (QUICC_BD *)bdp; | 510 | info->rx_cur = (QUICC_BD *)bdp; |
| 511 | 511 | ||
| 512 | schedule_work(&tty->flip.work); | 512 | tty_schedule_flip(tty); |
| 513 | } | 513 | } |
| 514 | 514 | ||
| 515 | static _INLINE_ void receive_break(ser_info_t *info) | 515 | static _INLINE_ void receive_break(ser_info_t *info) |
| @@ -521,7 +521,7 @@ static _INLINE_ void receive_break(ser_info_t *info) | |||
| 521 | * the break. If not, we exit now, losing the break. FIXME | 521 | * the break. If not, we exit now, losing the break. FIXME |
| 522 | */ | 522 | */ |
| 523 | tty_insert_flip_char(tty, 0, TTY_BREAK); | 523 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
| 524 | schedule_work(&tty->flip.work); | 524 | tty_schedule_flip(tty); |
| 525 | } | 525 | } |
| 526 | 526 | ||
| 527 | static _INLINE_ void transmit_chars(ser_info_t *info) | 527 | static _INLINE_ void transmit_chars(ser_info_t *info) |
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 179c1f065e60..b1fc97d5f643 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
| @@ -2229,6 +2229,7 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) | |||
| 2229 | * and restore the IER | 2229 | * and restore the IER |
| 2230 | */ | 2230 | */ |
| 2231 | wait_for_xmitr(up, BOTH_EMPTY); | 2231 | wait_for_xmitr(up, BOTH_EMPTY); |
| 2232 | up->ier |= UART_IER_THRI; | ||
| 2232 | serial_out(up, UART_IER, ier | UART_IER_THRI); | 2233 | serial_out(up, UART_IER, ier | UART_IER_THRI); |
| 2233 | } | 2234 | } |
| 2234 | 2235 | ||
diff --git a/drivers/serial/8250_au1x00.c b/drivers/serial/8250_au1x00.c index 06ae8fbcc947..8d8d7a70d03e 100644 --- a/drivers/serial/8250_au1x00.c +++ b/drivers/serial/8250_au1x00.c | |||
| @@ -56,7 +56,6 @@ static struct plat_serial8250_port au1x00_data[] = { | |||
| 56 | #elif defined(CONFIG_SOC_AU1550) | 56 | #elif defined(CONFIG_SOC_AU1550) |
| 57 | PORT(UART0_ADDR, AU1550_UART0_INT), | 57 | PORT(UART0_ADDR, AU1550_UART0_INT), |
| 58 | PORT(UART1_ADDR, AU1550_UART1_INT), | 58 | PORT(UART1_ADDR, AU1550_UART1_INT), |
| 59 | PORT(UART2_ADDR, AU1550_UART2_INT), | ||
| 60 | PORT(UART3_ADDR, AU1550_UART3_INT), | 59 | PORT(UART3_ADDR, AU1550_UART3_INT), |
| 61 | #elif defined(CONFIG_SOC_AU1200) | 60 | #elif defined(CONFIG_SOC_AU1200) |
| 62 | PORT(UART0_ADDR, AU1200_UART0_INT), | 61 | PORT(UART0_ADDR, AU1200_UART0_INT), |
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index 2a912153321e..94886c000d2a 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c | |||
| @@ -439,6 +439,20 @@ static int pci_siig_init(struct pci_dev *dev) | |||
| 439 | return -ENODEV; | 439 | return -ENODEV; |
| 440 | } | 440 | } |
| 441 | 441 | ||
| 442 | static int pci_siig_setup(struct serial_private *priv, | ||
| 443 | struct pciserial_board *board, | ||
| 444 | struct uart_port *port, int idx) | ||
| 445 | { | ||
| 446 | unsigned int bar = FL_GET_BASE(board->flags) + idx, offset = 0; | ||
| 447 | |||
| 448 | if (idx > 3) { | ||
| 449 | bar = 4; | ||
| 450 | offset = (idx - 4) * 8; | ||
| 451 | } | ||
| 452 | |||
| 453 | return setup_port(priv, port, bar, offset, 0); | ||
| 454 | } | ||
| 455 | |||
| 442 | /* | 456 | /* |
| 443 | * Timedia has an explosion of boards, and to avoid the PCI table from | 457 | * Timedia has an explosion of boards, and to avoid the PCI table from |
| 444 | * growing *huge*, we use this function to collapse some 70 entries | 458 | * growing *huge*, we use this function to collapse some 70 entries |
| @@ -748,7 +762,7 @@ static struct pci_serial_quirk pci_serial_quirks[] = { | |||
| 748 | .subvendor = PCI_ANY_ID, | 762 | .subvendor = PCI_ANY_ID, |
| 749 | .subdevice = PCI_ANY_ID, | 763 | .subdevice = PCI_ANY_ID, |
| 750 | .init = pci_siig_init, | 764 | .init = pci_siig_init, |
| 751 | .setup = pci_default_setup, | 765 | .setup = pci_siig_setup, |
| 752 | }, | 766 | }, |
| 753 | /* | 767 | /* |
| 754 | * Titan cards | 768 | * Titan cards |
| @@ -1868,6 +1882,10 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
| 1868 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 1882 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
| 1869 | PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_4, 0, 0, | 1883 | PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_4, 0, 0, |
| 1870 | pbn_b0_4_1843200 }, | 1884 | pbn_b0_4_1843200 }, |
| 1885 | { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954, | ||
| 1886 | PCI_VENDOR_ID_AFAVLAB, | ||
| 1887 | PCI_SUBDEVICE_ID_AFAVLAB_P061, 0, 0, | ||
| 1888 | pbn_b0_4_1152000 }, | ||
| 1871 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, | 1889 | { PCI_VENDOR_ID_EXAR, PCI_DEVICE_ID_EXAR_XR17C152, |
| 1872 | PCI_SUBVENDOR_ID_CONNECT_TECH, | 1890 | PCI_SUBVENDOR_ID_CONNECT_TECH, |
| 1873 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_232, 0, 0, | 1891 | PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_232, 0, 0, |
| @@ -2141,6 +2159,15 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
| 2141 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_850, | 2159 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_850, |
| 2142 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 2160 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
| 2143 | pbn_b0_bt_4_921600 }, | 2161 | pbn_b0_bt_4_921600 }, |
| 2162 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_550, | ||
| 2163 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
| 2164 | pbn_b0_bt_8_921600 }, | ||
| 2165 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_650, | ||
| 2166 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
| 2167 | pbn_b0_bt_8_921600 }, | ||
| 2168 | { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_8S_20x_850, | ||
| 2169 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
| 2170 | pbn_b0_bt_8_921600 }, | ||
| 2144 | 2171 | ||
| 2145 | /* | 2172 | /* |
| 2146 | * Computone devices submitted by Doug McNash dmcnash@computone.com | 2173 | * Computone devices submitted by Doug McNash dmcnash@computone.com |
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 0d38f0f2ae29..0f4361c8466b 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
| @@ -98,6 +98,7 @@ config SERIAL_8250_NR_UARTS | |||
| 98 | config SERIAL_8250_RUNTIME_UARTS | 98 | config SERIAL_8250_RUNTIME_UARTS |
| 99 | int "Number of 8250/16550 serial ports to register at runtime" | 99 | int "Number of 8250/16550 serial ports to register at runtime" |
| 100 | depends on SERIAL_8250 | 100 | depends on SERIAL_8250 |
| 101 | range 0 SERIAL_8250_NR_UARTS | ||
| 101 | default "4" | 102 | default "4" |
| 102 | help | 103 | help |
| 103 | Set this to the maximum number of serial ports you want | 104 | Set this to the maximum number of serial ports you want |
| @@ -892,20 +893,20 @@ config SERIAL_VR41XX_CONSOLE | |||
| 892 | a console on a serial port, say Y. Otherwise, say N. | 893 | a console on a serial port, say Y. Otherwise, say N. |
| 893 | 894 | ||
| 894 | config SERIAL_JSM | 895 | config SERIAL_JSM |
| 895 | tristate "Digi International NEO PCI Support" | 896 | tristate "Digi International NEO PCI Support" |
| 896 | depends on PCI && BROKEN | 897 | depends on PCI |
| 897 | select SERIAL_CORE | 898 | select SERIAL_CORE |
| 898 | help | 899 | help |
| 899 | This is a driver for Digi International's Neo series | 900 | This is a driver for Digi International's Neo series |
| 900 | of cards which provide multiple serial ports. You would need | 901 | of cards which provide multiple serial ports. You would need |
| 901 | something like this to connect more than two modems to your Linux | 902 | something like this to connect more than two modems to your Linux |
| 902 | box, for instance in order to become a dial-in server. This driver | 903 | box, for instance in order to become a dial-in server. This driver |
| 903 | supports PCI boards only. | 904 | supports PCI boards only. |
| 904 | If you have a card like this, say Y here and read the file | 905 | If you have a card like this, say Y here and read the file |
| 905 | <file:Documentation/jsm.txt>. | 906 | <file:Documentation/jsm.txt>. |
| 906 | 907 | ||
| 907 | To compile this driver as a module, choose M here: the | 908 | To compile this driver as a module, choose M here: the |
| 908 | module will be called jsm. | 909 | module will be called jsm. |
| 909 | 910 | ||
| 910 | config SERIAL_SGI_IOC4 | 911 | config SERIAL_SGI_IOC4 |
| 911 | tristate "SGI IOC4 controller serial support" | 912 | tristate "SGI IOC4 controller serial support" |
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index 429de2723a1c..321a3b3a5728 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c | |||
| @@ -561,7 +561,7 @@ static struct uart_amba_port amba_ports[UART_NR] = { | |||
| 561 | .port = { | 561 | .port = { |
| 562 | .membase = (void *)IO_ADDRESS(INTEGRATOR_UART0_BASE), | 562 | .membase = (void *)IO_ADDRESS(INTEGRATOR_UART0_BASE), |
| 563 | .mapbase = INTEGRATOR_UART0_BASE, | 563 | .mapbase = INTEGRATOR_UART0_BASE, |
| 564 | .iotype = SERIAL_IO_MEM, | 564 | .iotype = UPIO_MEM, |
| 565 | .irq = IRQ_UARTINT0, | 565 | .irq = IRQ_UARTINT0, |
| 566 | .uartclk = 14745600, | 566 | .uartclk = 14745600, |
| 567 | .fifosize = 16, | 567 | .fifosize = 16, |
| @@ -576,7 +576,7 @@ static struct uart_amba_port amba_ports[UART_NR] = { | |||
| 576 | .port = { | 576 | .port = { |
| 577 | .membase = (void *)IO_ADDRESS(INTEGRATOR_UART1_BASE), | 577 | .membase = (void *)IO_ADDRESS(INTEGRATOR_UART1_BASE), |
| 578 | .mapbase = INTEGRATOR_UART1_BASE, | 578 | .mapbase = INTEGRATOR_UART1_BASE, |
| 579 | .iotype = SERIAL_IO_MEM, | 579 | .iotype = UPIO_MEM, |
| 580 | .irq = IRQ_UARTINT1, | 580 | .irq = IRQ_UARTINT1, |
| 581 | .uartclk = 14745600, | 581 | .uartclk = 14745600, |
| 582 | .fifosize = 16, | 582 | .fifosize = 16, |
diff --git a/drivers/serial/au1x00_uart.c b/drivers/serial/au1x00_uart.c index ceb5d7f37bbd..344022fe53ef 100644 --- a/drivers/serial/au1x00_uart.c +++ b/drivers/serial/au1x00_uart.c | |||
| @@ -892,7 +892,7 @@ serial8250_request_std_resource(struct uart_8250_port *up, struct resource **res | |||
| 892 | int ret = 0; | 892 | int ret = 0; |
| 893 | 893 | ||
| 894 | switch (up->port.iotype) { | 894 | switch (up->port.iotype) { |
| 895 | case SERIAL_IO_MEM: | 895 | case UPIO_MEM: |
| 896 | if (up->port.mapbase) { | 896 | if (up->port.mapbase) { |
| 897 | *res = request_mem_region(up->port.mapbase, size, "serial"); | 897 | *res = request_mem_region(up->port.mapbase, size, "serial"); |
| 898 | if (!*res) | 898 | if (!*res) |
| @@ -900,8 +900,8 @@ serial8250_request_std_resource(struct uart_8250_port *up, struct resource **res | |||
| 900 | } | 900 | } |
| 901 | break; | 901 | break; |
| 902 | 902 | ||
| 903 | case SERIAL_IO_HUB6: | 903 | case UPIO_HUB6: |
| 904 | case SERIAL_IO_PORT: | 904 | case UPIO_PORT: |
| 905 | *res = request_region(up->port.iobase, size, "serial"); | 905 | *res = request_region(up->port.iobase, size, "serial"); |
| 906 | if (!*res) | 906 | if (!*res) |
| 907 | ret = -EBUSY; | 907 | ret = -EBUSY; |
| @@ -919,7 +919,7 @@ static void serial8250_release_port(struct uart_port *port) | |||
| 919 | size <<= up->port.regshift; | 919 | size <<= up->port.regshift; |
| 920 | 920 | ||
| 921 | switch (up->port.iotype) { | 921 | switch (up->port.iotype) { |
| 922 | case SERIAL_IO_MEM: | 922 | case UPIO_MEM: |
| 923 | if (up->port.mapbase) { | 923 | if (up->port.mapbase) { |
| 924 | /* | 924 | /* |
| 925 | * Unmap the area. | 925 | * Unmap the area. |
| @@ -935,8 +935,8 @@ static void serial8250_release_port(struct uart_port *port) | |||
| 935 | } | 935 | } |
| 936 | break; | 936 | break; |
| 937 | 937 | ||
| 938 | case SERIAL_IO_HUB6: | 938 | case UPIO_HUB6: |
| 939 | case SERIAL_IO_PORT: | 939 | case UPIO_PORT: |
| 940 | start = up->port.iobase; | 940 | start = up->port.iobase; |
| 941 | 941 | ||
| 942 | if (size) | 942 | if (size) |
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 16af5626c243..b7bf4c698a47 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c | |||
| @@ -252,12 +252,9 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs) | |||
| 252 | /* If we have not enough room in tty flip buffer, then we try | 252 | /* If we have not enough room in tty flip buffer, then we try |
| 253 | * later, which will be the next rx-interrupt or a timeout | 253 | * later, which will be the next rx-interrupt or a timeout |
| 254 | */ | 254 | */ |
| 255 | if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) { | 255 | if(tty_buffer_request_room(tty, i) < i) { |
| 256 | tty->flip.work.func((void *)tty); | 256 | printk(KERN_WARNING "No room in flip buffer\n"); |
| 257 | if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) { | 257 | return; |
| 258 | printk(KERN_WARNING "TTY_DONT_FLIP set\n"); | ||
| 259 | return; | ||
| 260 | } | ||
| 261 | } | 258 | } |
| 262 | 259 | ||
| 263 | /* get pointer */ | 260 | /* get pointer */ |
| @@ -276,9 +273,7 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs) | |||
| 276 | continue; | 273 | continue; |
| 277 | 274 | ||
| 278 | error_return: | 275 | error_return: |
| 279 | *tty->flip.char_buf_ptr++ = ch; | 276 | tty_insert_flip_char(tty, ch, flg); |
| 280 | *tty->flip.flag_buf_ptr++ = flg; | ||
| 281 | tty->flip.count++; | ||
| 282 | 277 | ||
| 283 | } /* End while (i--) */ | 278 | } /* End while (i--) */ |
| 284 | 279 | ||
| @@ -908,7 +903,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
| 908 | .port = { | 903 | .port = { |
| 909 | .irq = SMC1_IRQ, | 904 | .irq = SMC1_IRQ, |
| 910 | .ops = &cpm_uart_pops, | 905 | .ops = &cpm_uart_pops, |
| 911 | .iotype = SERIAL_IO_MEM, | 906 | .iotype = UPIO_MEM, |
| 912 | .lock = SPIN_LOCK_UNLOCKED, | 907 | .lock = SPIN_LOCK_UNLOCKED, |
| 913 | }, | 908 | }, |
| 914 | .flags = FLAG_SMC, | 909 | .flags = FLAG_SMC, |
| @@ -922,7 +917,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
| 922 | .port = { | 917 | .port = { |
| 923 | .irq = SMC2_IRQ, | 918 | .irq = SMC2_IRQ, |
| 924 | .ops = &cpm_uart_pops, | 919 | .ops = &cpm_uart_pops, |
| 925 | .iotype = SERIAL_IO_MEM, | 920 | .iotype = UPIO_MEM, |
| 926 | .lock = SPIN_LOCK_UNLOCKED, | 921 | .lock = SPIN_LOCK_UNLOCKED, |
| 927 | }, | 922 | }, |
| 928 | .flags = FLAG_SMC, | 923 | .flags = FLAG_SMC, |
| @@ -939,7 +934,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
| 939 | .port = { | 934 | .port = { |
| 940 | .irq = SCC1_IRQ, | 935 | .irq = SCC1_IRQ, |
| 941 | .ops = &cpm_uart_pops, | 936 | .ops = &cpm_uart_pops, |
| 942 | .iotype = SERIAL_IO_MEM, | 937 | .iotype = UPIO_MEM, |
| 943 | .lock = SPIN_LOCK_UNLOCKED, | 938 | .lock = SPIN_LOCK_UNLOCKED, |
| 944 | }, | 939 | }, |
| 945 | .tx_nrfifos = TX_NUM_FIFO, | 940 | .tx_nrfifos = TX_NUM_FIFO, |
| @@ -953,7 +948,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
| 953 | .port = { | 948 | .port = { |
| 954 | .irq = SCC2_IRQ, | 949 | .irq = SCC2_IRQ, |
| 955 | .ops = &cpm_uart_pops, | 950 | .ops = &cpm_uart_pops, |
| 956 | .iotype = SERIAL_IO_MEM, | 951 | .iotype = UPIO_MEM, |
| 957 | .lock = SPIN_LOCK_UNLOCKED, | 952 | .lock = SPIN_LOCK_UNLOCKED, |
| 958 | }, | 953 | }, |
| 959 | .tx_nrfifos = TX_NUM_FIFO, | 954 | .tx_nrfifos = TX_NUM_FIFO, |
| @@ -967,7 +962,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
| 967 | .port = { | 962 | .port = { |
| 968 | .irq = SCC3_IRQ, | 963 | .irq = SCC3_IRQ, |
| 969 | .ops = &cpm_uart_pops, | 964 | .ops = &cpm_uart_pops, |
| 970 | .iotype = SERIAL_IO_MEM, | 965 | .iotype = UPIO_MEM, |
| 971 | .lock = SPIN_LOCK_UNLOCKED, | 966 | .lock = SPIN_LOCK_UNLOCKED, |
| 972 | }, | 967 | }, |
| 973 | .tx_nrfifos = TX_NUM_FIFO, | 968 | .tx_nrfifos = TX_NUM_FIFO, |
| @@ -981,7 +976,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
| 981 | .port = { | 976 | .port = { |
| 982 | .irq = SCC4_IRQ, | 977 | .irq = SCC4_IRQ, |
| 983 | .ops = &cpm_uart_pops, | 978 | .ops = &cpm_uart_pops, |
| 984 | .iotype = SERIAL_IO_MEM, | 979 | .iotype = UPIO_MEM, |
| 985 | .lock = SPIN_LOCK_UNLOCKED, | 980 | .lock = SPIN_LOCK_UNLOCKED, |
| 986 | }, | 981 | }, |
| 987 | .tx_nrfifos = TX_NUM_FIFO, | 982 | .tx_nrfifos = TX_NUM_FIFO, |
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c index a64ba26a94e8..ba5541de673b 100644 --- a/drivers/serial/dz.c +++ b/drivers/serial/dz.c | |||
| @@ -262,6 +262,7 @@ static inline void dz_receive_chars(struct dz_port *dport) | |||
| 262 | } | 262 | } |
| 263 | tty_insert_flip_char(tty, ch, flag); | 263 | tty_insert_flip_char(tty, ch, flag); |
| 264 | ignore_char: | 264 | ignore_char: |
| 265 | ; | ||
| 265 | } while (status & DZ_DVAL); | 266 | } while (status & DZ_DVAL); |
| 266 | 267 | ||
| 267 | if (tty) | 268 | if (tty) |
| @@ -650,7 +651,7 @@ static void __init dz_init_ports(void) | |||
| 650 | for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) { | 651 | for (i = 0, dport = dz_ports; i < DZ_NB_PORT; i++, dport++) { |
| 651 | spin_lock_init(&dport->port.lock); | 652 | spin_lock_init(&dport->port.lock); |
| 652 | dport->port.membase = (char *) base; | 653 | dport->port.membase = (char *) base; |
| 653 | dport->port.iotype = SERIAL_IO_PORT; | 654 | dport->port.iotype = UPIO_PORT; |
| 654 | dport->port.irq = dec_interrupt[DEC_IRQ_DZ11]; | 655 | dport->port.irq = dec_interrupt[DEC_IRQ_DZ11]; |
| 655 | dport->port.line = i; | 656 | dport->port.line = i; |
| 656 | dport->port.fifosize = 1; | 657 | dport->port.fifosize = 1; |
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 858048efe1ed..4d53fb5ca87b 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c | |||
| @@ -668,7 +668,7 @@ static struct imx_port imx_ports[] = { | |||
| 668 | .rtsirq = UART1_MINT_RTS, | 668 | .rtsirq = UART1_MINT_RTS, |
| 669 | .port = { | 669 | .port = { |
| 670 | .type = PORT_IMX, | 670 | .type = PORT_IMX, |
| 671 | .iotype = SERIAL_IO_MEM, | 671 | .iotype = UPIO_MEM, |
| 672 | .membase = (void *)IMX_UART1_BASE, | 672 | .membase = (void *)IMX_UART1_BASE, |
| 673 | .mapbase = IMX_UART1_BASE, /* FIXME */ | 673 | .mapbase = IMX_UART1_BASE, /* FIXME */ |
| 674 | .irq = UART1_MINT_RX, | 674 | .irq = UART1_MINT_RX, |
| @@ -684,7 +684,7 @@ static struct imx_port imx_ports[] = { | |||
| 684 | .rtsirq = UART2_MINT_RTS, | 684 | .rtsirq = UART2_MINT_RTS, |
| 685 | .port = { | 685 | .port = { |
| 686 | .type = PORT_IMX, | 686 | .type = PORT_IMX, |
| 687 | .iotype = SERIAL_IO_MEM, | 687 | .iotype = UPIO_MEM, |
| 688 | .membase = (void *)IMX_UART2_BASE, | 688 | .membase = (void *)IMX_UART2_BASE, |
| 689 | .mapbase = IMX_UART2_BASE, /* FIXME */ | 689 | .mapbase = IMX_UART2_BASE, /* FIXME */ |
| 690 | .irq = UART2_MINT_RX, | 690 | .irq = UART2_MINT_RX, |
diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c index 66f117d15065..419dd3cd7862 100644 --- a/drivers/serial/ip22zilog.c +++ b/drivers/serial/ip22zilog.c | |||
| @@ -215,7 +215,7 @@ static void __load_zsregs(struct zilog_channel *channel, unsigned char *regs) | |||
| 215 | /* Lower and upper byte of baud rate generator divisor. */ | 215 | /* Lower and upper byte of baud rate generator divisor. */ |
| 216 | write_zsreg(channel, R12, regs[R12]); | 216 | write_zsreg(channel, R12, regs[R12]); |
| 217 | write_zsreg(channel, R13, regs[R13]); | 217 | write_zsreg(channel, R13, regs[R13]); |
| 218 | 218 | ||
| 219 | /* Now rewrite R14, with BRENAB (if set). */ | 219 | /* Now rewrite R14, with BRENAB (if set). */ |
| 220 | write_zsreg(channel, R14, regs[R14]); | 220 | write_zsreg(channel, R14, regs[R14]); |
| 221 | 221 | ||
| @@ -571,7 +571,7 @@ static void ip22zilog_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
| 571 | else | 571 | else |
| 572 | clear_bits |= DTR; | 572 | clear_bits |= DTR; |
| 573 | 573 | ||
| 574 | /* NOTE: Not subject to 'transmitter active' rule. */ | 574 | /* NOTE: Not subject to 'transmitter active' rule. */ |
| 575 | up->curregs[R5] |= set_bits; | 575 | up->curregs[R5] |= set_bits; |
| 576 | up->curregs[R5] &= ~clear_bits; | 576 | up->curregs[R5] &= ~clear_bits; |
| 577 | write_zsreg(channel, R5, up->curregs[R5]); | 577 | write_zsreg(channel, R5, up->curregs[R5]); |
| @@ -654,7 +654,7 @@ static void ip22zilog_enable_ms(struct uart_port *port) | |||
| 654 | if (new_reg != up->curregs[R15]) { | 654 | if (new_reg != up->curregs[R15]) { |
| 655 | up->curregs[R15] = new_reg; | 655 | up->curregs[R15] = new_reg; |
| 656 | 656 | ||
| 657 | /* NOTE: Not subject to 'transmitter active' rule. */ | 657 | /* NOTE: Not subject to 'transmitter active' rule. */ |
| 658 | write_zsreg(channel, R15, up->curregs[R15]); | 658 | write_zsreg(channel, R15, up->curregs[R15]); |
| 659 | } | 659 | } |
| 660 | } | 660 | } |
| @@ -680,7 +680,7 @@ static void ip22zilog_break_ctl(struct uart_port *port, int break_state) | |||
| 680 | if (new_reg != up->curregs[R5]) { | 680 | if (new_reg != up->curregs[R5]) { |
| 681 | up->curregs[R5] = new_reg; | 681 | up->curregs[R5] = new_reg; |
| 682 | 682 | ||
| 683 | /* NOTE: Not subject to 'transmitter active' rule. */ | 683 | /* NOTE: Not subject to 'transmitter active' rule. */ |
| 684 | write_zsreg(channel, R5, up->curregs[R5]); | 684 | write_zsreg(channel, R5, up->curregs[R5]); |
| 685 | } | 685 | } |
| 686 | 686 | ||
diff --git a/drivers/serial/jsm/jsm.h b/drivers/serial/jsm/jsm.h index 18753193f59b..dfc1e86d3aa1 100644 --- a/drivers/serial/jsm/jsm.h +++ b/drivers/serial/jsm/jsm.h | |||
| @@ -380,7 +380,6 @@ struct neo_uart_struct { | |||
| 380 | extern struct uart_driver jsm_uart_driver; | 380 | extern struct uart_driver jsm_uart_driver; |
| 381 | extern struct board_ops jsm_neo_ops; | 381 | extern struct board_ops jsm_neo_ops; |
| 382 | extern int jsm_debug; | 382 | extern int jsm_debug; |
| 383 | extern int jsm_rawreadok; | ||
| 384 | 383 | ||
| 385 | /************************************************************************* | 384 | /************************************************************************* |
| 386 | * | 385 | * |
diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c index 7e56c7824194..b1b66e71d281 100644 --- a/drivers/serial/jsm/jsm_driver.c +++ b/drivers/serial/jsm/jsm_driver.c | |||
| @@ -49,11 +49,8 @@ struct uart_driver jsm_uart_driver = { | |||
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| 51 | int jsm_debug; | 51 | int jsm_debug; |
| 52 | int jsm_rawreadok; | ||
| 53 | module_param(jsm_debug, int, 0); | 52 | module_param(jsm_debug, int, 0); |
| 54 | module_param(jsm_rawreadok, int, 0); | ||
| 55 | MODULE_PARM_DESC(jsm_debug, "Driver debugging level"); | 53 | MODULE_PARM_DESC(jsm_debug, "Driver debugging level"); |
| 56 | MODULE_PARM_DESC(jsm_rawreadok, "Bypass flip buffers on input"); | ||
| 57 | 54 | ||
| 58 | static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 55 | static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
| 59 | { | 56 | { |
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c index 6fa0d62d6f68..4d48b625cd3d 100644 --- a/drivers/serial/jsm/jsm_tty.c +++ b/drivers/serial/jsm/jsm_tty.c | |||
| @@ -20,8 +20,10 @@ | |||
| 20 | * | 20 | * |
| 21 | * Contact Information: | 21 | * Contact Information: |
| 22 | * Scott H Kilau <Scott_Kilau@digi.com> | 22 | * Scott H Kilau <Scott_Kilau@digi.com> |
| 23 | * Wendy Xiong <wendyx@us.ltcfwd.linux.ibm.com> | 23 | * Ananda Venkatarman <mansarov@us.ibm.com> |
| 24 | * | 24 | * Modifications: |
| 25 | * 01/19/06: changed jsm_input routine to use the dynamically allocated | ||
| 26 | * tty_buffer changes. Contributors: Scott Kilau and Ananda V. | ||
| 25 | ***********************************************************************/ | 27 | ***********************************************************************/ |
| 26 | #include <linux/tty.h> | 28 | #include <linux/tty.h> |
| 27 | #include <linux/tty_flip.h> | 29 | #include <linux/tty_flip.h> |
| @@ -497,16 +499,15 @@ void jsm_input(struct jsm_channel *ch) | |||
| 497 | { | 499 | { |
| 498 | struct jsm_board *bd; | 500 | struct jsm_board *bd; |
| 499 | struct tty_struct *tp; | 501 | struct tty_struct *tp; |
| 502 | struct tty_ldisc *ld; | ||
| 500 | u32 rmask; | 503 | u32 rmask; |
| 501 | u16 head; | 504 | u16 head; |
| 502 | u16 tail; | 505 | u16 tail; |
| 503 | int data_len; | 506 | int data_len; |
| 504 | unsigned long lock_flags; | 507 | unsigned long lock_flags; |
| 505 | int flip_len; | 508 | int flip_len = 0; |
| 506 | int len = 0; | 509 | int len = 0; |
| 507 | int n = 0; | 510 | int n = 0; |
| 508 | char *buf = NULL; | ||
| 509 | char *buf2 = NULL; | ||
| 510 | int s = 0; | 511 | int s = 0; |
| 511 | int i = 0; | 512 | int i = 0; |
| 512 | 513 | ||
| @@ -574,56 +575,50 @@ void jsm_input(struct jsm_channel *ch) | |||
| 574 | 575 | ||
| 575 | /* | 576 | /* |
| 576 | * If the rxbuf is empty and we are not throttled, put as much | 577 | * If the rxbuf is empty and we are not throttled, put as much |
| 577 | * as we can directly into the linux TTY flip buffer. | 578 | * as we can directly into the linux TTY buffer. |
| 578 | * The jsm_rawreadok case takes advantage of carnal knowledge that | ||
| 579 | * the char_buf and the flag_buf are next to each other and | ||
| 580 | * are each of (2 * TTY_FLIPBUF_SIZE) size. | ||
| 581 | * | 579 | * |
| 582 | * NOTE: if(!tty->real_raw), the call to ldisc.receive_buf | ||
| 583 | *actually still uses the flag buffer, so you can't | ||
| 584 | *use it for input data | ||
| 585 | */ | 580 | */ |
| 586 | if (jsm_rawreadok) { | 581 | flip_len = TTY_FLIPBUF_SIZE; |
| 587 | if (tp->real_raw) | ||
| 588 | flip_len = MYFLIPLEN; | ||
| 589 | else | ||
| 590 | flip_len = 2 * TTY_FLIPBUF_SIZE; | ||
| 591 | } else | ||
| 592 | flip_len = TTY_FLIPBUF_SIZE - tp->flip.count; | ||
| 593 | 582 | ||
| 594 | len = min(data_len, flip_len); | 583 | len = min(data_len, flip_len); |
| 595 | len = min(len, (N_TTY_BUF_SIZE - 1) - tp->read_cnt); | 584 | len = min(len, (N_TTY_BUF_SIZE - 1) - tp->read_cnt); |
| 585 | ld = tty_ldisc_ref(tp); | ||
| 596 | 586 | ||
| 597 | if (len <= 0) { | 587 | /* |
| 598 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); | 588 | * If the DONT_FLIP flag is on, don't flush our buffer, and act |
| 599 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "jsm_input 1\n"); | 589 | * like the ld doesn't have any space to put the data right now. |
| 600 | return; | 590 | */ |
| 601 | } | 591 | if (test_bit(TTY_DONT_FLIP, &tp->flags)) |
| 592 | len = 0; | ||
| 602 | 593 | ||
| 603 | /* | 594 | /* |
| 604 | * If we're bypassing flip buffers on rx, we can blast it | 595 | * If we were unable to get a reference to the ld, |
| 605 | * right into the beginning of the buffer. | 596 | * don't flush our buffer, and act like the ld doesn't |
| 597 | * have any space to put the data right now. | ||
| 606 | */ | 598 | */ |
| 607 | if (jsm_rawreadok) { | 599 | if (!ld) { |
| 608 | if (tp->real_raw) { | 600 | len = 0; |
| 609 | if (ch->ch_flags & CH_FLIPBUF_IN_USE) { | ||
| 610 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, | ||
| 611 | "JSM - FLIPBUF in use. delaying input\n"); | ||
| 612 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); | ||
| 613 | return; | ||
| 614 | } | ||
| 615 | ch->ch_flags |= CH_FLIPBUF_IN_USE; | ||
| 616 | buf = ch->ch_bd->flipbuf; | ||
| 617 | buf2 = NULL; | ||
| 618 | } else { | ||
| 619 | buf = tp->flip.char_buf; | ||
| 620 | buf2 = tp->flip.flag_buf; | ||
| 621 | } | ||
| 622 | } else { | 601 | } else { |
| 623 | buf = tp->flip.char_buf_ptr; | 602 | /* |
| 624 | buf2 = tp->flip.flag_buf_ptr; | 603 | * If ld doesn't have a pointer to a receive_buf function, |
| 604 | * flush the data, then act like the ld doesn't have any | ||
| 605 | * space to put the data right now. | ||
| 606 | */ | ||
| 607 | if (!ld->receive_buf) { | ||
| 608 | ch->ch_r_head = ch->ch_r_tail; | ||
| 609 | len = 0; | ||
| 610 | } | ||
| 625 | } | 611 | } |
| 626 | 612 | ||
| 613 | if (len <= 0) { | ||
| 614 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); | ||
| 615 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, "jsm_input 1\n"); | ||
| 616 | if (ld) | ||
| 617 | tty_ldisc_deref(ld); | ||
| 618 | return; | ||
| 619 | } | ||
| 620 | |||
| 621 | len = tty_buffer_request_room(tp, len); | ||
| 627 | n = len; | 622 | n = len; |
| 628 | 623 | ||
| 629 | /* | 624 | /* |
| @@ -638,121 +633,47 @@ void jsm_input(struct jsm_channel *ch) | |||
| 638 | if (s <= 0) | 633 | if (s <= 0) |
| 639 | break; | 634 | break; |
| 640 | 635 | ||
| 641 | memcpy(buf, ch->ch_rqueue + tail, s); | 636 | /* |
| 642 | 637 | * If conditions are such that ld needs to see all | |
| 643 | /* buf2 is only set when port isn't raw */ | 638 | * UART errors, we will have to walk each character |
| 644 | if (buf2) | 639 | * and error byte and send them to the buffer one at |
| 645 | memcpy(buf2, ch->ch_equeue + tail, s); | 640 | * a time. |
| 646 | 641 | */ | |
| 647 | tail += s; | ||
| 648 | buf += s; | ||
| 649 | if (buf2) | ||
| 650 | buf2 += s; | ||
| 651 | n -= s; | ||
| 652 | /* Flip queue if needed */ | ||
| 653 | tail &= rmask; | ||
| 654 | } | ||
| 655 | 642 | ||
| 656 | /* | ||
| 657 | * In high performance mode, we don't have to update | ||
| 658 | * flag_buf or any of the counts or pointers into flip buf. | ||
| 659 | */ | ||
| 660 | if (!jsm_rawreadok) { | ||
| 661 | if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) { | 643 | if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) { |
| 662 | for (i = 0; i < len; i++) { | 644 | for (i = 0; i < s; i++) { |
| 663 | /* | 645 | /* |
| 664 | * Give the Linux ld the flags in the | 646 | * Give the Linux ld the flags in the |
| 665 | * format it likes. | 647 | * format it likes. |
| 666 | */ | 648 | */ |
| 667 | if (tp->flip.flag_buf_ptr[i] & UART_LSR_BI) | 649 | if (*(ch->ch_equeue +tail +i) & UART_LSR_BI) |
| 668 | tp->flip.flag_buf_ptr[i] = TTY_BREAK; | 650 | tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_BREAK); |
| 669 | else if (tp->flip.flag_buf_ptr[i] & UART_LSR_PE) | 651 | else if (*(ch->ch_equeue +tail +i) & UART_LSR_PE) |
| 670 | tp->flip.flag_buf_ptr[i] = TTY_PARITY; | 652 | tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_PARITY); |
| 671 | else if (tp->flip.flag_buf_ptr[i] & UART_LSR_FE) | 653 | else if (*(ch->ch_equeue +tail +i) & UART_LSR_FE) |
| 672 | tp->flip.flag_buf_ptr[i] = TTY_FRAME; | 654 | tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_FRAME); |
| 673 | else | 655 | else |
| 674 | tp->flip.flag_buf_ptr[i] = TTY_NORMAL; | 656 | tty_insert_flip_char(tp, *(ch->ch_rqueue +tail +i), TTY_NORMAL); |
| 675 | } | 657 | } |
| 676 | } else { | 658 | } else { |
| 677 | memset(tp->flip.flag_buf_ptr, 0, len); | 659 | tty_insert_flip_string(tp, ch->ch_rqueue + tail, s) ; |
| 678 | } | 660 | } |
| 679 | 661 | tail += s; | |
| 680 | tp->flip.char_buf_ptr += len; | 662 | n -= s; |
| 681 | tp->flip.flag_buf_ptr += len; | 663 | /* Flip queue if needed */ |
| 682 | tp->flip.count += len; | 664 | tail &= rmask; |
| 683 | } | ||
| 684 | else if (!tp->real_raw) { | ||
| 685 | if (I_PARMRK(tp) || I_BRKINT(tp) || I_INPCK(tp)) { | ||
| 686 | for (i = 0; i < len; i++) { | ||
| 687 | /* | ||
| 688 | * Give the Linux ld the flags in the | ||
| 689 | * format it likes. | ||
| 690 | */ | ||
| 691 | if (tp->flip.flag_buf_ptr[i] & UART_LSR_BI) | ||
| 692 | tp->flip.flag_buf_ptr[i] = TTY_BREAK; | ||
| 693 | else if (tp->flip.flag_buf_ptr[i] & UART_LSR_PE) | ||
| 694 | tp->flip.flag_buf_ptr[i] = TTY_PARITY; | ||
| 695 | else if (tp->flip.flag_buf_ptr[i] & UART_LSR_FE) | ||
| 696 | tp->flip.flag_buf_ptr[i] = TTY_FRAME; | ||
| 697 | else | ||
| 698 | tp->flip.flag_buf_ptr[i] = TTY_NORMAL; | ||
| 699 | } | ||
| 700 | } else | ||
| 701 | memset(tp->flip.flag_buf, 0, len); | ||
| 702 | } | 665 | } |
| 703 | 666 | ||
| 704 | /* | 667 | ch->ch_r_tail = tail & rmask; |
| 705 | * If we're doing raw reads, jam it right into the | 668 | ch->ch_e_tail = tail & rmask; |
| 706 | * line disc bypassing the flip buffers. | 669 | jsm_check_queue_flow_control(ch); |
| 707 | */ | 670 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); |
| 708 | if (jsm_rawreadok) { | ||
| 709 | if (tp->real_raw) { | ||
| 710 | ch->ch_r_tail = tail & rmask; | ||
| 711 | ch->ch_e_tail = tail & rmask; | ||
| 712 | |||
| 713 | jsm_check_queue_flow_control(ch); | ||
| 714 | |||
| 715 | /* !!! WE *MUST* LET GO OF ALL LOCKS BEFORE CALLING RECEIVE BUF !!! */ | ||
| 716 | 671 | ||
| 717 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); | 672 | /* Tell the tty layer its okay to "eat" the data now */ |
| 673 | tty_flip_buffer_push(tp); | ||
| 718 | 674 | ||
| 719 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, | 675 | if (ld) |
| 720 | "jsm_input. %d real_raw len:%d calling receive_buf for board %d\n", | 676 | tty_ldisc_deref(ld); |
| 721 | __LINE__, len, ch->ch_bd->boardnum); | ||
| 722 | tp->ldisc.receive_buf(tp, ch->ch_bd->flipbuf, NULL, len); | ||
| 723 | |||
| 724 | /* Allow use of channel flip buffer again */ | ||
| 725 | spin_lock_irqsave(&ch->ch_lock, lock_flags); | ||
| 726 | ch->ch_flags &= ~CH_FLIPBUF_IN_USE; | ||
| 727 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); | ||
| 728 | |||
| 729 | } else { | ||
| 730 | ch->ch_r_tail = tail & rmask; | ||
| 731 | ch->ch_e_tail = tail & rmask; | ||
| 732 | |||
| 733 | jsm_check_queue_flow_control(ch); | ||
| 734 | |||
| 735 | /* !!! WE *MUST* LET GO OF ALL LOCKS BEFORE CALLING RECEIVE BUF !!! */ | ||
| 736 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); | ||
| 737 | |||
| 738 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, | ||
| 739 | "jsm_input. %d not real_raw len:%d calling receive_buf for board %d\n", | ||
| 740 | __LINE__, len, ch->ch_bd->boardnum); | ||
| 741 | |||
| 742 | tp->ldisc.receive_buf(tp, tp->flip.char_buf, tp->flip.flag_buf, len); | ||
| 743 | } | ||
| 744 | } else { | ||
| 745 | ch->ch_r_tail = tail & rmask; | ||
| 746 | ch->ch_e_tail = tail & rmask; | ||
| 747 | |||
| 748 | jsm_check_queue_flow_control(ch); | ||
| 749 | |||
| 750 | spin_unlock_irqrestore(&ch->ch_lock, lock_flags); | ||
| 751 | |||
| 752 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, | ||
| 753 | "jsm_input. %d not jsm_read raw okay scheduling flip\n", __LINE__); | ||
| 754 | tty_schedule_flip(tp); | ||
| 755 | } | ||
| 756 | 677 | ||
| 757 | jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n"); | 678 | jsm_printk(IOCTL, INFO, &ch->ch_bd->pci_dev, "finish\n"); |
| 758 | } | 679 | } |
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c index b48066a64a7d..242a04104393 100644 --- a/drivers/serial/m32r_sio.c +++ b/drivers/serial/m32r_sio.c | |||
| @@ -80,7 +80,7 @@ | |||
| 80 | #include <asm/serial.h> | 80 | #include <asm/serial.h> |
| 81 | 81 | ||
| 82 | /* Standard COM flags */ | 82 | /* Standard COM flags */ |
| 83 | #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) | 83 | #define STD_COM_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST) |
| 84 | 84 | ||
| 85 | /* | 85 | /* |
| 86 | * SERIAL_PORT_DFNS tells us about built-in ports that have no | 86 | * SERIAL_PORT_DFNS tells us about built-in ports that have no |
diff --git a/drivers/serial/m32r_sio.h b/drivers/serial/m32r_sio.h index 07d0dd80aa3d..7c3ec24f7e50 100644 --- a/drivers/serial/m32r_sio.h +++ b/drivers/serial/m32r_sio.h | |||
| @@ -37,7 +37,7 @@ struct old_serial_port { | |||
| 37 | unsigned int irq; | 37 | unsigned int irq; |
| 38 | unsigned int flags; | 38 | unsigned int flags; |
| 39 | unsigned char io_type; | 39 | unsigned char io_type; |
| 40 | unsigned char *iomem_base; | 40 | unsigned char __iomem *iomem_base; |
| 41 | unsigned short iomem_reg_shift; | 41 | unsigned short iomem_reg_shift; |
| 42 | }; | 42 | }; |
| 43 | 43 | ||
diff --git a/drivers/serial/mcfserial.c b/drivers/serial/mcfserial.c index d957a3a9edf1..8cbbb954df2c 100644 --- a/drivers/serial/mcfserial.c +++ b/drivers/serial/mcfserial.c | |||
| @@ -57,20 +57,16 @@ struct timer_list mcfrs_timer_struct; | |||
| 57 | * keep going. Perhaps one day the cflag settings for the | 57 | * keep going. Perhaps one day the cflag settings for the |
| 58 | * console can be used instead. | 58 | * console can be used instead. |
| 59 | */ | 59 | */ |
| 60 | #if defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \ | ||
| 61 | defined(CONFIG_senTec) || defined(CONFIG_SNEHA) | ||
| 62 | #define CONSOLE_BAUD_RATE 19200 | ||
| 63 | #define DEFAULT_CBAUD B19200 | ||
| 64 | #endif | ||
| 65 | |||
| 66 | #if defined(CONFIG_HW_FEITH) | 60 | #if defined(CONFIG_HW_FEITH) |
| 67 | #define CONSOLE_BAUD_RATE 38400 | 61 | #define CONSOLE_BAUD_RATE 38400 |
| 68 | #define DEFAULT_CBAUD B38400 | 62 | #define DEFAULT_CBAUD B38400 |
| 69 | #endif | 63 | #elif defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB) |
| 70 | |||
| 71 | #if defined(CONFIG_MOD5272) || defined(CONFIG_M5208EVB) | ||
| 72 | #define CONSOLE_BAUD_RATE 115200 | 64 | #define CONSOLE_BAUD_RATE 115200 |
| 73 | #define DEFAULT_CBAUD B115200 | 65 | #define DEFAULT_CBAUD B115200 |
| 66 | #elif defined(CONFIG_ARNEWSH) || defined(CONFIG_FREESCALE) || \ | ||
| 67 | defined(CONFIG_senTec) || defined(CONFIG_SNEHA) | ||
| 68 | #define CONSOLE_BAUD_RATE 19200 | ||
| 69 | #define DEFAULT_CBAUD B19200 | ||
| 74 | #endif | 70 | #endif |
| 75 | 71 | ||
| 76 | #ifndef CONSOLE_BAUD_RATE | 72 | #ifndef CONSOLE_BAUD_RATE |
| @@ -350,8 +346,7 @@ static inline void receive_chars(struct mcf_serial *info) | |||
| 350 | } | 346 | } |
| 351 | tty_insert_flip_char(tty, ch, flag); | 347 | tty_insert_flip_char(tty, ch, flag); |
| 352 | } | 348 | } |
| 353 | 349 | tty_schedule_flip(tty); | |
| 354 | schedule_work(&tty->flip.work); | ||
| 355 | return; | 350 | return; |
| 356 | } | 351 | } |
| 357 | 352 | ||
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c index 4e49168c3176..868eaf4a1a68 100644 --- a/drivers/serial/mux.c +++ b/drivers/serial/mux.c | |||
| @@ -462,7 +462,7 @@ static int __init mux_probe(struct parisc_device *dev) | |||
| 462 | port->mapbase = dev->hpa.start + MUX_OFFSET + | 462 | port->mapbase = dev->hpa.start + MUX_OFFSET + |
| 463 | (i * MUX_LINE_OFFSET); | 463 | (i * MUX_LINE_OFFSET); |
| 464 | port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET); | 464 | port->membase = ioremap(port->mapbase, MUX_LINE_OFFSET); |
| 465 | port->iotype = SERIAL_IO_MEM; | 465 | port->iotype = UPIO_MEM; |
| 466 | port->type = PORT_MUX; | 466 | port->type = PORT_MUX; |
| 467 | port->irq = NO_IRQ; | 467 | port->irq = NO_IRQ; |
| 468 | port->uartclk = 0; | 468 | port->uartclk = 0; |
diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 4e03a87f3fb4..9b7ed58cb53b 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c | |||
| @@ -1492,7 +1492,7 @@ no_dma: | |||
| 1492 | /* | 1492 | /* |
| 1493 | * Init remaining bits of "port" structure | 1493 | * Init remaining bits of "port" structure |
| 1494 | */ | 1494 | */ |
| 1495 | uap->port.iotype = SERIAL_IO_MEM; | 1495 | uap->port.iotype = UPIO_MEM; |
| 1496 | uap->port.irq = np->intrs[0].line; | 1496 | uap->port.irq = np->intrs[0].line; |
| 1497 | uap->port.uartclk = ZS_CLOCK; | 1497 | uap->port.uartclk = ZS_CLOCK; |
| 1498 | uap->port.fifosize = 1; | 1498 | uap->port.fifosize = 1; |
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c index 0a2dd6c5b95f..7410e093a6b9 100644 --- a/drivers/serial/s3c2410.c +++ b/drivers/serial/s3c2410.c | |||
| @@ -161,7 +161,11 @@ s3c24xx_serial_dbg(const char *fmt, ...) | |||
| 161 | 161 | ||
| 162 | /* we can support 3 uarts, but not always use them */ | 162 | /* we can support 3 uarts, but not always use them */ |
| 163 | 163 | ||
| 164 | #ifdef CONFIG_CPU_S3C2400 | ||
| 165 | #define NR_PORTS (2) | ||
| 166 | #else | ||
| 164 | #define NR_PORTS (3) | 167 | #define NR_PORTS (3) |
| 168 | #endif | ||
| 165 | 169 | ||
| 166 | /* port irq numbers */ | 170 | /* port irq numbers */ |
| 167 | 171 | ||
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c index ff7b60b4de37..2c00b8625852 100644 --- a/drivers/serial/sa1100.c +++ b/drivers/serial/sa1100.c | |||
| @@ -628,7 +628,7 @@ static void __init sa1100_init_ports(void) | |||
| 628 | sa1100_ports[i].port.ops = &sa1100_pops; | 628 | sa1100_ports[i].port.ops = &sa1100_pops; |
| 629 | sa1100_ports[i].port.fifosize = 8; | 629 | sa1100_ports[i].port.fifosize = 8; |
| 630 | sa1100_ports[i].port.line = i; | 630 | sa1100_ports[i].port.line = i; |
| 631 | sa1100_ports[i].port.iotype = SERIAL_IO_MEM; | 631 | sa1100_ports[i].port.iotype = UPIO_MEM; |
| 632 | init_timer(&sa1100_ports[i].timer); | 632 | init_timer(&sa1100_ports[i].timer); |
| 633 | sa1100_ports[i].timer.function = sa1100_timeout; | 633 | sa1100_ports[i].timer.function = sa1100_timeout; |
| 634 | sa1100_ports[i].timer.data = (unsigned long)&sa1100_ports[i]; | 634 | sa1100_ports[i].timer.data = (unsigned long)&sa1100_ports[i]; |
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 0717abfdae06..95fb4939c675 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c | |||
| @@ -2237,7 +2237,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) | |||
| 2237 | * If this port is a console, then the spinlock is already | 2237 | * If this port is a console, then the spinlock is already |
| 2238 | * initialised. | 2238 | * initialised. |
| 2239 | */ | 2239 | */ |
| 2240 | if (!uart_console(port)) | 2240 | if (!(uart_console(port) && (port->cons->flags & CON_ENABLED))) |
| 2241 | spin_lock_init(&port->lock); | 2241 | spin_lock_init(&port->lock); |
| 2242 | 2242 | ||
| 2243 | uart_configure_port(drv, state, port); | 2243 | uart_configure_port(drv, state, port); |
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c index d0490f67f597..04186eaae227 100644 --- a/drivers/serial/serial_lh7a40x.c +++ b/drivers/serial/serial_lh7a40x.c | |||
| @@ -501,7 +501,7 @@ static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = { | |||
| 501 | .port = { | 501 | .port = { |
| 502 | .membase = (void*) io_p2v (UART1_PHYS), | 502 | .membase = (void*) io_p2v (UART1_PHYS), |
| 503 | .mapbase = UART1_PHYS, | 503 | .mapbase = UART1_PHYS, |
| 504 | .iotype = SERIAL_IO_MEM, | 504 | .iotype = UPIO_MEM, |
| 505 | .irq = IRQ_UART1INTR, | 505 | .irq = IRQ_UART1INTR, |
| 506 | .uartclk = 14745600/2, | 506 | .uartclk = 14745600/2, |
| 507 | .fifosize = 16, | 507 | .fifosize = 16, |
| @@ -514,7 +514,7 @@ static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = { | |||
| 514 | .port = { | 514 | .port = { |
| 515 | .membase = (void*) io_p2v (UART2_PHYS), | 515 | .membase = (void*) io_p2v (UART2_PHYS), |
| 516 | .mapbase = UART2_PHYS, | 516 | .mapbase = UART2_PHYS, |
| 517 | .iotype = SERIAL_IO_MEM, | 517 | .iotype = UPIO_MEM, |
| 518 | .irq = IRQ_UART2INTR, | 518 | .irq = IRQ_UART2INTR, |
| 519 | .uartclk = 14745600/2, | 519 | .uartclk = 14745600/2, |
| 520 | .fifosize = 16, | 520 | .fifosize = 16, |
| @@ -527,7 +527,7 @@ static struct uart_port_lh7a40x lh7a40x_ports[DEV_NR] = { | |||
| 527 | .port = { | 527 | .port = { |
| 528 | .membase = (void*) io_p2v (UART3_PHYS), | 528 | .membase = (void*) io_p2v (UART3_PHYS), |
| 529 | .mapbase = UART3_PHYS, | 529 | .mapbase = UART3_PHYS, |
| 530 | .iotype = SERIAL_IO_MEM, | 530 | .iotype = UPIO_MEM, |
| 531 | .irq = IRQ_UART3INTR, | 531 | .irq = IRQ_UART3INTR, |
| 532 | .uartclk = 14745600/2, | 532 | .uartclk = 14745600/2, |
| 533 | .fifosize = 16, | 533 | .fifosize = 16, |
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 80737c131ce7..44f6bf79bbe1 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
| @@ -1468,10 +1468,10 @@ static struct sci_port sci_ports[] = { | |||
| 1468 | .port = { | 1468 | .port = { |
| 1469 | .membase = (void *)0xff923000, | 1469 | .membase = (void *)0xff923000, |
| 1470 | .mapbase = 0xff923000, | 1470 | .mapbase = 0xff923000, |
| 1471 | .iotype = SERIAL_IO_MEM, | 1471 | .iotype = UPIO_MEM, |
| 1472 | .irq = 61, | 1472 | .irq = 61, |
| 1473 | .ops = &sci_uart_ops, | 1473 | .ops = &sci_uart_ops, |
| 1474 | .flags = ASYNC_BOOT_AUTOCONF, | 1474 | .flags = UPF_BOOT_AUTOCONF, |
| 1475 | .line = 0, | 1475 | .line = 0, |
| 1476 | }, | 1476 | }, |
| 1477 | .type = PORT_SCIF, | 1477 | .type = PORT_SCIF, |
| @@ -1482,10 +1482,10 @@ static struct sci_port sci_ports[] = { | |||
| 1482 | .port = { | 1482 | .port = { |
| 1483 | .membase = (void *)0xff924000, | 1483 | .membase = (void *)0xff924000, |
| 1484 | .mapbase = 0xff924000, | 1484 | .mapbase = 0xff924000, |
| 1485 | .iotype = SERIAL_IO_MEM, | 1485 | .iotype = UPIO_MEM, |
| 1486 | .irq = 62, | 1486 | .irq = 62, |
| 1487 | .ops = &sci_uart_ops, | 1487 | .ops = &sci_uart_ops, |
| 1488 | .flags = ASYNC_BOOT_AUTOCONF, | 1488 | .flags = UPF_BOOT_AUTOCONF, |
| 1489 | .line = 1, | 1489 | .line = 1, |
| 1490 | }, | 1490 | }, |
| 1491 | .type = PORT_SCIF, | 1491 | .type = PORT_SCIF, |
| @@ -1496,10 +1496,10 @@ static struct sci_port sci_ports[] = { | |||
| 1496 | .port = { | 1496 | .port = { |
| 1497 | .membase = (void *)0xff925000, | 1497 | .membase = (void *)0xff925000, |
| 1498 | .mapbase = 0xff925000, | 1498 | .mapbase = 0xff925000, |
| 1499 | .iotype = SERIAL_IO_MEM, | 1499 | .iotype = UPIO_MEM, |
| 1500 | .irq = 63, | 1500 | .irq = 63, |
| 1501 | .ops = &sci_uart_ops, | 1501 | .ops = &sci_uart_ops, |
| 1502 | .flags = ASYNC_BOOT_AUTOCONF, | 1502 | .flags = UPF_BOOT_AUTOCONF, |
| 1503 | .line = 2, | 1503 | .line = 2, |
| 1504 | }, | 1504 | }, |
| 1505 | .type = PORT_SCIF, | 1505 | .type = PORT_SCIF, |
| @@ -1511,10 +1511,10 @@ static struct sci_port sci_ports[] = { | |||
| 1511 | .port = { | 1511 | .port = { |
| 1512 | .membase = (void *)0xffe00000, | 1512 | .membase = (void *)0xffe00000, |
| 1513 | .mapbase = 0xffe00000, | 1513 | .mapbase = 0xffe00000, |
| 1514 | .iotype = SERIAL_IO_MEM, | 1514 | .iotype = UPIO_MEM, |
| 1515 | .irq = 43, | 1515 | .irq = 43, |
| 1516 | .ops = &sci_uart_ops, | 1516 | .ops = &sci_uart_ops, |
| 1517 | .flags = ASYNC_BOOT_AUTOCONF, | 1517 | .flags = UPF_BOOT_AUTOCONF, |
| 1518 | .line = 0, | 1518 | .line = 0, |
| 1519 | }, | 1519 | }, |
| 1520 | .type = PORT_SCIF, | 1520 | .type = PORT_SCIF, |
| @@ -1525,10 +1525,10 @@ static struct sci_port sci_ports[] = { | |||
| 1525 | .port = { | 1525 | .port = { |
| 1526 | .membase = (void *)0xffe10000, | 1526 | .membase = (void *)0xffe10000, |
| 1527 | .mapbase = 0xffe10000, | 1527 | .mapbase = 0xffe10000, |
| 1528 | .iotype = SERIAL_IO_MEM, | 1528 | .iotype = UPIO_MEM, |
| 1529 | .irq = 79, | 1529 | .irq = 79, |
| 1530 | .ops = &sci_uart_ops, | 1530 | .ops = &sci_uart_ops, |
| 1531 | .flags = ASYNC_BOOT_AUTOCONF, | 1531 | .flags = UPF_BOOT_AUTOCONF, |
| 1532 | .line = 1, | 1532 | .line = 1, |
| 1533 | }, | 1533 | }, |
| 1534 | .type = PORT_SCIF, | 1534 | .type = PORT_SCIF, |
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index 8bcaebcc0ad7..85664228a0b6 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c | |||
| @@ -1036,7 +1036,7 @@ static void __init sab_attach_callback(struct linux_ebus_device *edev, void *arg | |||
| 1036 | up->port.irq = edev->irqs[0]; | 1036 | up->port.irq = edev->irqs[0]; |
| 1037 | up->port.fifosize = SAB82532_XMIT_FIFO_SIZE; | 1037 | up->port.fifosize = SAB82532_XMIT_FIFO_SIZE; |
| 1038 | up->port.mapbase = (unsigned long)up->regs; | 1038 | up->port.mapbase = (unsigned long)up->regs; |
| 1039 | up->port.iotype = SERIAL_IO_MEM; | 1039 | up->port.iotype = UPIO_MEM; |
| 1040 | 1040 | ||
| 1041 | writeb(SAB82532_IPC_IC_ACT_LOW, &up->regs->w.ipc); | 1041 | writeb(SAB82532_IPC_IC_ACT_LOW, &up->regs->w.ipc); |
| 1042 | 1042 | ||
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index bc67442c6b4c..308704566948 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c | |||
| @@ -109,11 +109,11 @@ static _INLINE_ unsigned int serial_in(struct uart_sunsu_port *up, int offset) | |||
| 109 | offset <<= up->port.regshift; | 109 | offset <<= up->port.regshift; |
| 110 | 110 | ||
| 111 | switch (up->port.iotype) { | 111 | switch (up->port.iotype) { |
| 112 | case SERIAL_IO_HUB6: | 112 | case UPIO_HUB6: |
| 113 | outb(up->port.hub6 - 1 + offset, up->port.iobase); | 113 | outb(up->port.hub6 - 1 + offset, up->port.iobase); |
| 114 | return inb(up->port.iobase + 1); | 114 | return inb(up->port.iobase + 1); |
| 115 | 115 | ||
| 116 | case SERIAL_IO_MEM: | 116 | case UPIO_MEM: |
| 117 | return readb(up->port.membase + offset); | 117 | return readb(up->port.membase + offset); |
| 118 | 118 | ||
| 119 | default: | 119 | default: |
| @@ -139,12 +139,12 @@ serial_out(struct uart_sunsu_port *up, int offset, int value) | |||
| 139 | offset <<= up->port.regshift; | 139 | offset <<= up->port.regshift; |
| 140 | 140 | ||
| 141 | switch (up->port.iotype) { | 141 | switch (up->port.iotype) { |
| 142 | case SERIAL_IO_HUB6: | 142 | case UPIO_HUB6: |
| 143 | outb(up->port.hub6 - 1 + offset, up->port.iobase); | 143 | outb(up->port.hub6 - 1 + offset, up->port.iobase); |
| 144 | outb(value, up->port.iobase + 1); | 144 | outb(value, up->port.iobase + 1); |
| 145 | break; | 145 | break; |
| 146 | 146 | ||
| 147 | case SERIAL_IO_MEM: | 147 | case UPIO_MEM: |
| 148 | writeb(value, up->port.membase + offset); | 148 | writeb(value, up->port.membase + offset); |
| 149 | break; | 149 | break; |
| 150 | 150 | ||
| @@ -1052,7 +1052,7 @@ static void sunsu_autoconfig(struct uart_sunsu_port *up) | |||
| 1052 | return; | 1052 | return; |
| 1053 | 1053 | ||
| 1054 | up->type_probed = PORT_UNKNOWN; | 1054 | up->type_probed = PORT_UNKNOWN; |
| 1055 | up->port.iotype = SERIAL_IO_MEM; | 1055 | up->port.iotype = UPIO_MEM; |
| 1056 | 1056 | ||
| 1057 | /* | 1057 | /* |
| 1058 | * First we look for Ebus-bases su's | 1058 | * First we look for Ebus-bases su's |
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 3c72484adea7..5cc4d4c2935c 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c | |||
| @@ -1487,7 +1487,7 @@ static void __init sunzilog_prepare(void) | |||
| 1487 | up[(chip * 2) + 1].port.membase = (void __iomem *)&rp->channelB; | 1487 | up[(chip * 2) + 1].port.membase = (void __iomem *)&rp->channelB; |
| 1488 | 1488 | ||
| 1489 | /* Channel A */ | 1489 | /* Channel A */ |
| 1490 | up[(chip * 2) + 0].port.iotype = SERIAL_IO_MEM; | 1490 | up[(chip * 2) + 0].port.iotype = UPIO_MEM; |
| 1491 | up[(chip * 2) + 0].port.irq = zilog_irq; | 1491 | up[(chip * 2) + 0].port.irq = zilog_irq; |
| 1492 | up[(chip * 2) + 0].port.uartclk = ZS_CLOCK; | 1492 | up[(chip * 2) + 0].port.uartclk = ZS_CLOCK; |
| 1493 | up[(chip * 2) + 0].port.fifosize = 1; | 1493 | up[(chip * 2) + 0].port.fifosize = 1; |
| @@ -1498,7 +1498,7 @@ static void __init sunzilog_prepare(void) | |||
| 1498 | up[(chip * 2) + 0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A; | 1498 | up[(chip * 2) + 0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A; |
| 1499 | 1499 | ||
| 1500 | /* Channel B */ | 1500 | /* Channel B */ |
| 1501 | up[(chip * 2) + 1].port.iotype = SERIAL_IO_MEM; | 1501 | up[(chip * 2) + 1].port.iotype = UPIO_MEM; |
| 1502 | up[(chip * 2) + 1].port.irq = zilog_irq; | 1502 | up[(chip * 2) + 1].port.irq = zilog_irq; |
| 1503 | up[(chip * 2) + 1].port.uartclk = ZS_CLOCK; | 1503 | up[(chip * 2) + 1].port.uartclk = ZS_CLOCK; |
| 1504 | up[(chip * 2) + 1].port.fifosize = 1; | 1504 | up[(chip * 2) + 1].port.fifosize = 1; |
diff --git a/drivers/serial/v850e_uart.c b/drivers/serial/v850e_uart.c index 9378895a8d56..df705fda4243 100644 --- a/drivers/serial/v850e_uart.c +++ b/drivers/serial/v850e_uart.c | |||
| @@ -496,7 +496,7 @@ static int __init v850e_uart_init (void) | |||
| 496 | 496 | ||
| 497 | port->ops = &v850e_uart_ops; | 497 | port->ops = &v850e_uart_ops; |
| 498 | port->line = chan; | 498 | port->line = chan; |
| 499 | port->iotype = SERIAL_IO_MEM; | 499 | port->iotype = UPIO_MEM; |
| 500 | port->flags = UPF_BOOT_AUTOCONF; | 500 | port->flags = UPF_BOOT_AUTOCONF; |
| 501 | 501 | ||
| 502 | /* We actually use multiple IRQs, but the serial | 502 | /* We actually use multiple IRQs, but the serial |
diff --git a/drivers/sn/ioc3.c b/drivers/sn/ioc3.c index c70ae81b5d98..12357e1fa558 100644 --- a/drivers/sn/ioc3.c +++ b/drivers/sn/ioc3.c | |||
| @@ -38,10 +38,10 @@ static inline unsigned mcr_pack(unsigned pulse, unsigned sample) | |||
| 38 | 38 | ||
| 39 | static int nic_wait(struct ioc3_driver_data *idd) | 39 | static int nic_wait(struct ioc3_driver_data *idd) |
| 40 | { | 40 | { |
| 41 | volatile unsigned mcr; | 41 | unsigned mcr; |
| 42 | 42 | ||
| 43 | do { | 43 | do { |
| 44 | mcr = (volatile unsigned)idd->vma->mcr; | 44 | mcr = readl(&idd->vma->mcr); |
| 45 | } while (!(mcr & 2)); | 45 | } while (!(mcr & 2)); |
| 46 | 46 | ||
| 47 | return mcr & 1; | 47 | return mcr & 1; |
| @@ -53,7 +53,7 @@ static int nic_reset(struct ioc3_driver_data *idd) | |||
| 53 | unsigned long flags; | 53 | unsigned long flags; |
| 54 | 54 | ||
| 55 | local_irq_save(flags); | 55 | local_irq_save(flags); |
| 56 | idd->vma->mcr = mcr_pack(500, 65); | 56 | writel(mcr_pack(500, 65), &idd->vma->mcr); |
| 57 | presence = nic_wait(idd); | 57 | presence = nic_wait(idd); |
| 58 | local_irq_restore(flags); | 58 | local_irq_restore(flags); |
| 59 | 59 | ||
| @@ -68,7 +68,7 @@ static inline int nic_read_bit(struct ioc3_driver_data *idd) | |||
| 68 | unsigned long flags; | 68 | unsigned long flags; |
| 69 | 69 | ||
| 70 | local_irq_save(flags); | 70 | local_irq_save(flags); |
| 71 | idd->vma->mcr = mcr_pack(6, 13); | 71 | writel(mcr_pack(6, 13), &idd->vma->mcr); |
| 72 | result = nic_wait(idd); | 72 | result = nic_wait(idd); |
| 73 | local_irq_restore(flags); | 73 | local_irq_restore(flags); |
| 74 | 74 | ||
| @@ -80,9 +80,9 @@ static inline int nic_read_bit(struct ioc3_driver_data *idd) | |||
| 80 | static inline void nic_write_bit(struct ioc3_driver_data *idd, int bit) | 80 | static inline void nic_write_bit(struct ioc3_driver_data *idd, int bit) |
| 81 | { | 81 | { |
| 82 | if (bit) | 82 | if (bit) |
| 83 | idd->vma->mcr = mcr_pack(6, 110); | 83 | writel(mcr_pack(6, 110), &idd->vma->mcr); |
| 84 | else | 84 | else |
| 85 | idd->vma->mcr = mcr_pack(80, 30); | 85 | writel(mcr_pack(80, 30), &idd->vma->mcr); |
| 86 | 86 | ||
| 87 | nic_wait(idd); | 87 | nic_wait(idd); |
| 88 | } | 88 | } |
| @@ -337,7 +337,7 @@ static void probe_nic(struct ioc3_driver_data *idd) | |||
| 337 | int save = 0, loops = 3; | 337 | int save = 0, loops = 3; |
| 338 | unsigned long first, addr; | 338 | unsigned long first, addr; |
| 339 | 339 | ||
| 340 | idd->vma->gpcr_s = GPCR_MLAN_EN; | 340 | writel(GPCR_MLAN_EN, &idd->vma->gpcr_s); |
| 341 | 341 | ||
| 342 | while(loops>0) { | 342 | while(loops>0) { |
| 343 | idd->nic_part[0] = 0; | 343 | idd->nic_part[0] = 0; |
| @@ -408,7 +408,7 @@ static irqreturn_t ioc3_intr_io(int irq, void *arg, struct pt_regs *regs) | |||
| 408 | 408 | ||
| 409 | read_lock_irqsave(&ioc3_submodules_lock, flags); | 409 | read_lock_irqsave(&ioc3_submodules_lock, flags); |
| 410 | 410 | ||
| 411 | if(idd->dual_irq && idd->vma->eisr) { | 411 | if(idd->dual_irq && readb(&idd->vma->eisr)) { |
| 412 | /* send Ethernet IRQ to the driver */ | 412 | /* send Ethernet IRQ to the driver */ |
| 413 | if(ioc3_ethernet && idd->active[ioc3_ethernet->id] && | 413 | if(ioc3_ethernet && idd->active[ioc3_ethernet->id] && |
| 414 | ioc3_ethernet->intr) { | 414 | ioc3_ethernet->intr) { |
| @@ -682,7 +682,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) | |||
| 682 | idd->id = ioc3_counter++; | 682 | idd->id = ioc3_counter++; |
| 683 | up_write(&ioc3_devices_rwsem); | 683 | up_write(&ioc3_devices_rwsem); |
| 684 | 684 | ||
| 685 | idd->gpdr_shadow = idd->vma->gpdr; | 685 | idd->gpdr_shadow = readl(&idd->vma->gpdr); |
| 686 | 686 | ||
| 687 | /* Read IOC3 NIC contents */ | 687 | /* Read IOC3 NIC contents */ |
| 688 | probe_nic(idd); | 688 | probe_nic(idd); |
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index b77dbd63e596..7a75faeb0526 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
| @@ -75,16 +75,6 @@ config SPI_BUTTERFLY | |||
| 75 | inexpensive battery powered microcontroller evaluation board. | 75 | inexpensive battery powered microcontroller evaluation board. |
| 76 | This same cable can be used to flash new firmware. | 76 | This same cable can be used to flash new firmware. |
| 77 | 77 | ||
| 78 | config SPI_BUTTERFLY | ||
| 79 | tristate "Parallel port adapter for AVR Butterfly (DEVELOPMENT)" | ||
| 80 | depends on SPI_MASTER && PARPORT && EXPERIMENTAL | ||
| 81 | select SPI_BITBANG | ||
| 82 | help | ||
| 83 | This uses a custom parallel port cable to connect to an AVR | ||
| 84 | Butterfly <http://www.atmel.com/products/avr/butterfly>, an | ||
| 85 | inexpensive battery powered microcontroller evaluation board. | ||
| 86 | This same cable can be used to flash new firmware. | ||
| 87 | |||
| 88 | # | 78 | # |
| 89 | # Add new SPI master controllers in alphabetical order above this line | 79 | # Add new SPI master controllers in alphabetical order above this line |
| 90 | # | 80 | # |
diff --git a/drivers/spi/spi_butterfly.c b/drivers/spi/spi_butterfly.c index 79a3c59615ab..ff9e5faa4dc9 100644 --- a/drivers/spi/spi_butterfly.c +++ b/drivers/spi/spi_butterfly.c | |||
| @@ -163,21 +163,20 @@ static void butterfly_chipselect(struct spi_device *spi, int value) | |||
| 163 | struct butterfly *pp = spidev_to_pp(spi); | 163 | struct butterfly *pp = spidev_to_pp(spi); |
| 164 | 164 | ||
| 165 | /* set default clock polarity */ | 165 | /* set default clock polarity */ |
| 166 | if (value) | 166 | if (value != BITBANG_CS_INACTIVE) |
| 167 | setsck(spi, spi->mode & SPI_CPOL); | 167 | setsck(spi, spi->mode & SPI_CPOL); |
| 168 | 168 | ||
| 169 | /* no chipselect on this USI link config */ | 169 | /* no chipselect on this USI link config */ |
| 170 | if (is_usidev(spi)) | 170 | if (is_usidev(spi)) |
| 171 | return; | 171 | return; |
| 172 | 172 | ||
| 173 | /* here, value == "activate or not" */ | 173 | /* here, value == "activate or not"; |
| 174 | 174 | * most PARPORT_CONTROL_* bits are negated, so we must | |
| 175 | /* most PARPORT_CONTROL_* bits are negated */ | 175 | * morph it to value == "bit value to write in control register" |
| 176 | */ | ||
| 176 | if (spi_cs_bit == PARPORT_CONTROL_INIT) | 177 | if (spi_cs_bit == PARPORT_CONTROL_INIT) |
| 177 | value = !value; | 178 | value = !value; |
| 178 | 179 | ||
| 179 | /* here, value == "bit value to write in control register" */ | ||
| 180 | |||
| 181 | parport_frob_control(pp->port, spi_cs_bit, value ? spi_cs_bit : 0); | 180 | parport_frob_control(pp->port, spi_cs_bit, value ? spi_cs_bit : 0); |
| 182 | } | 181 | } |
| 183 | 182 | ||
| @@ -202,7 +201,9 @@ butterfly_txrx_word_mode0(struct spi_device *spi, | |||
| 202 | 201 | ||
| 203 | /* override default partitioning with cmdlinepart */ | 202 | /* override default partitioning with cmdlinepart */ |
| 204 | static struct mtd_partition partitions[] = { { | 203 | static struct mtd_partition partitions[] = { { |
| 205 | /* JFFS2 wants partitions of 4*N blocks for this device ... */ | 204 | /* JFFS2 wants partitions of 4*N blocks for this device, |
| 205 | * so sectors 0 and 1 can't be partitions by themselves. | ||
| 206 | */ | ||
| 206 | 207 | ||
| 207 | /* sector 0 = 8 pages * 264 bytes/page (1 block) | 208 | /* sector 0 = 8 pages * 264 bytes/page (1 block) |
| 208 | * sector 1 = 248 pages * 264 bytes/page | 209 | * sector 1 = 248 pages * 264 bytes/page |
| @@ -316,8 +317,9 @@ static void butterfly_attach(struct parport *p) | |||
| 316 | if (status < 0) | 317 | if (status < 0) |
| 317 | goto clean2; | 318 | goto clean2; |
| 318 | 319 | ||
| 319 | /* Bus 1 lets us talk to at45db041b (firmware disables AVR) | 320 | /* Bus 1 lets us talk to at45db041b (firmware disables AVR SPI), AVR |
| 320 | * or AVR (firmware resets at45, acts as spi slave) | 321 | * (firmware resets at45, acts as spi slave) or neither (we ignore |
| 322 | * both, AVR uses AT45). Here we expect firmware for the first option. | ||
| 321 | */ | 323 | */ |
| 322 | pp->info[0].max_speed_hz = 15 * 1000 * 1000; | 324 | pp->info[0].max_speed_hz = 15 * 1000 * 1000; |
| 323 | strcpy(pp->info[0].modalias, "mtd_dataflash"); | 325 | strcpy(pp->info[0].modalias, "mtd_dataflash"); |
| @@ -330,7 +332,9 @@ static void butterfly_attach(struct parport *p) | |||
| 330 | pp->dataflash->dev.bus_id); | 332 | pp->dataflash->dev.bus_id); |
| 331 | 333 | ||
| 332 | #ifdef HAVE_USI | 334 | #ifdef HAVE_USI |
| 333 | /* even more custom AVR firmware */ | 335 | /* Bus 2 is only for talking to the AVR, and it can work no |
| 336 | * matter who masters bus 1; needs appropriate AVR firmware. | ||
| 337 | */ | ||
| 334 | pp->info[1].max_speed_hz = 10 /* ?? */ * 1000 * 1000; | 338 | pp->info[1].max_speed_hz = 10 /* ?? */ * 1000 * 1000; |
| 335 | strcpy(pp->info[1].modalias, "butterfly"); | 339 | strcpy(pp->info[1].modalias, "butterfly"); |
| 336 | // pp->info[1].platform_data = ... TBD ... ; | 340 | // pp->info[1].platform_data = ... TBD ... ; |
| @@ -378,13 +382,8 @@ static void butterfly_detach(struct parport *p) | |||
| 378 | pp = butterfly; | 382 | pp = butterfly; |
| 379 | butterfly = NULL; | 383 | butterfly = NULL; |
| 380 | 384 | ||
| 381 | #ifdef HAVE_USI | 385 | /* stop() unregisters child devices too */ |
| 382 | spi_unregister_device(pp->butterfly); | 386 | pdev = to_platform_device(pp->bitbang.master->cdev.dev); |
| 383 | pp->butterfly = NULL; | ||
| 384 | #endif | ||
| 385 | spi_unregister_device(pp->dataflash); | ||
| 386 | pp->dataflash = NULL; | ||
| 387 | |||
| 388 | status = spi_bitbang_stop(&pp->bitbang); | 387 | status = spi_bitbang_stop(&pp->bitbang); |
| 389 | 388 | ||
| 390 | /* turn off VCC */ | 389 | /* turn off VCC */ |
| @@ -394,8 +393,6 @@ static void butterfly_detach(struct parport *p) | |||
| 394 | parport_release(pp->pd); | 393 | parport_release(pp->pd); |
| 395 | parport_unregister_device(pp->pd); | 394 | parport_unregister_device(pp->pd); |
| 396 | 395 | ||
| 397 | pdev = to_platform_device(pp->bitbang.master->cdev.dev); | ||
| 398 | |||
| 399 | (void) spi_master_put(pp->bitbang.master); | 396 | (void) spi_master_put(pp->bitbang.master); |
| 400 | 397 | ||
| 401 | platform_device_unregister(pdev); | 398 | platform_device_unregister(pdev); |
| @@ -420,4 +417,5 @@ static void __exit butterfly_exit(void) | |||
| 420 | } | 417 | } |
| 421 | module_exit(butterfly_exit); | 418 | module_exit(butterfly_exit); |
| 422 | 419 | ||
| 420 | MODULE_DESCRIPTION("Parport Adapter driver for AVR Butterfly"); | ||
| 423 | MODULE_LICENSE("GPL"); | 421 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/tc/tc.c b/drivers/tc/tc.c index a0e5af638e0e..4a51e56f85b6 100644 --- a/drivers/tc/tc.c +++ b/drivers/tc/tc.c | |||
| @@ -17,7 +17,6 @@ | |||
| 17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
| 18 | 18 | ||
| 19 | #include <asm/addrspace.h> | 19 | #include <asm/addrspace.h> |
| 20 | #include <asm/bug.h> | ||
| 21 | #include <asm/errno.h> | 20 | #include <asm/errno.h> |
| 22 | #include <asm/io.h> | 21 | #include <asm/io.h> |
| 23 | #include <asm/paccess.h> | 22 | #include <asm/paccess.h> |
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c index f6704688ee8c..5578a9dd04e8 100644 --- a/drivers/telephony/ixj.c +++ b/drivers/telephony/ixj.c | |||
| @@ -3558,10 +3558,16 @@ static void ixj_write_frame(IXJ *j) | |||
| 3558 | } | 3558 | } |
| 3559 | /* Add word 0 to G.729 frames for the 8021. Right now we don't do VAD/CNG */ | 3559 | /* Add word 0 to G.729 frames for the 8021. Right now we don't do VAD/CNG */ |
| 3560 | if (j->play_codec == G729 && (cnt == 0 || cnt == 10 || cnt == 20)) { | 3560 | if (j->play_codec == G729 && (cnt == 0 || cnt == 10 || cnt == 20)) { |
| 3561 | if(j->write_buffer_rp + cnt == 0 && j->write_buffer_rp + cnt + 1 == 0 && j->write_buffer_rp + cnt + 2 == 0 && | 3561 | if (j->write_buffer_rp[cnt] == 0 && |
| 3562 | j->write_buffer_rp + cnt + 3 == 0 && j->write_buffer_rp + cnt + 4 == 0 && j->write_buffer_rp + cnt + 5 == 0 && | 3562 | j->write_buffer_rp[cnt + 1] == 0 && |
| 3563 | j->write_buffer_rp + cnt + 6 == 0 && j->write_buffer_rp + cnt + 7 == 0 && j->write_buffer_rp + cnt + 8 == 0 && | 3563 | j->write_buffer_rp[cnt + 2] == 0 && |
| 3564 | j->write_buffer_rp + cnt + 9 == 0) { | 3564 | j->write_buffer_rp[cnt + 3] == 0 && |
| 3565 | j->write_buffer_rp[cnt + 4] == 0 && | ||
| 3566 | j->write_buffer_rp[cnt + 5] == 0 && | ||
| 3567 | j->write_buffer_rp[cnt + 6] == 0 && | ||
| 3568 | j->write_buffer_rp[cnt + 7] == 0 && | ||
| 3569 | j->write_buffer_rp[cnt + 8] == 0 && | ||
| 3570 | j->write_buffer_rp[cnt + 9] == 0) { | ||
| 3565 | /* someone is trying to write silence lets make this a type 0 frame. */ | 3571 | /* someone is trying to write silence lets make this a type 0 frame. */ |
| 3566 | outb_p(0x00, j->DSPbase + 0x0C); | 3572 | outb_p(0x00, j->DSPbase + 0x0C); |
| 3567 | outb_p(0x00, j->DSPbase + 0x0D); | 3573 | outb_p(0x00, j->DSPbase + 0x0D); |
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 076462c8ba2a..dce9d987f0fc 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
| @@ -378,7 +378,7 @@ const struct usb_device_id *usb_match_id(struct usb_interface *interface, | |||
| 378 | 378 | ||
| 379 | return NULL; | 379 | return NULL; |
| 380 | } | 380 | } |
| 381 | EXPORT_SYMBOL_GPL(usb_match_id); | 381 | EXPORT_SYMBOL(usb_match_id); |
| 382 | 382 | ||
| 383 | int usb_device_match(struct device *dev, struct device_driver *drv) | 383 | int usb_device_match(struct device *dev, struct device_driver *drv) |
| 384 | { | 384 | { |
| @@ -446,7 +446,7 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner) | |||
| 446 | 446 | ||
| 447 | return retval; | 447 | return retval; |
| 448 | } | 448 | } |
| 449 | EXPORT_SYMBOL_GPL(usb_register_driver); | 449 | EXPORT_SYMBOL(usb_register_driver); |
| 450 | 450 | ||
| 451 | /** | 451 | /** |
| 452 | * usb_deregister - unregister a USB driver | 452 | * usb_deregister - unregister a USB driver |
| @@ -469,4 +469,4 @@ void usb_deregister(struct usb_driver *driver) | |||
| 469 | 469 | ||
| 470 | usbfs_update_special(); | 470 | usbfs_update_special(); |
| 471 | } | 471 | } |
| 472 | EXPORT_SYMBOL_GPL(usb_deregister); | 472 | EXPORT_SYMBOL(usb_deregister); |
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 9d5015e99372..bd39bbd88d41 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c | |||
| @@ -13,7 +13,6 @@ | |||
| 13 | #include <linux/ctype.h> | 13 | #include <linux/ctype.h> |
| 14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
| 15 | #include <linux/fb.h> | 15 | #include <linux/fb.h> |
| 16 | #include <asm/bug.h> | ||
| 17 | 16 | ||
| 18 | static ssize_t backlight_show_power(struct class_device *cdev, char *buf) | 17 | static ssize_t backlight_show_power(struct class_device *cdev, char *buf) |
| 19 | { | 18 | { |
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index 68c690605aa7..9e32485ee7bb 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c | |||
| @@ -13,7 +13,6 @@ | |||
| 13 | #include <linux/ctype.h> | 13 | #include <linux/ctype.h> |
| 14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
| 15 | #include <linux/fb.h> | 15 | #include <linux/fb.h> |
| 16 | #include <asm/bug.h> | ||
| 17 | 16 | ||
| 18 | static ssize_t lcd_show_power(struct class_device *cdev, char *buf) | 17 | static ssize_t lcd_show_power(struct class_device *cdev, char *buf) |
| 19 | { | 18 | { |
diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index a7bcd17112c0..0339f5640a78 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c | |||
| @@ -30,10 +30,11 @@ | |||
| 30 | 30 | ||
| 31 | #define STI_DRIVERVERSION "Version 0.9a" | 31 | #define STI_DRIVERVERSION "Version 0.9a" |
| 32 | 32 | ||
| 33 | struct sti_struct *default_sti; | 33 | struct sti_struct *default_sti __read_mostly; |
| 34 | 34 | ||
| 35 | static int num_sti_roms; /* # of STI ROMS found */ | 35 | /* number of STI ROMS found and their ptrs to each struct */ |
| 36 | static struct sti_struct *sti_roms[MAX_STI_ROMS]; /* ptr to each sti_struct */ | 36 | static int num_sti_roms __read_mostly; |
| 37 | static struct sti_struct *sti_roms[MAX_STI_ROMS] __read_mostly; | ||
| 37 | 38 | ||
| 38 | 39 | ||
| 39 | /* The colour indices used by STI are | 40 | /* The colour indices used by STI are |
| @@ -266,7 +267,7 @@ sti_rom_copy(unsigned long base, unsigned long count, void *dest) | |||
| 266 | 267 | ||
| 267 | 268 | ||
| 268 | 269 | ||
| 269 | static char default_sti_path[21]; | 270 | static char default_sti_path[21] __read_mostly; |
| 270 | 271 | ||
| 271 | #ifndef MODULE | 272 | #ifndef MODULE |
| 272 | static int __init sti_setup(char *str) | 273 | static int __init sti_setup(char *str) |
| @@ -414,10 +415,10 @@ sti_init_glob_cfg(struct sti_struct *sti, | |||
| 414 | if (!sti->sti_mem_request) | 415 | if (!sti->sti_mem_request) |
| 415 | sti->sti_mem_request = 256; /* STI default */ | 416 | sti->sti_mem_request = 256; /* STI default */ |
| 416 | 417 | ||
| 417 | glob_cfg = kmalloc(sizeof(*sti->glob_cfg), GFP_KERNEL); | 418 | glob_cfg = kzalloc(sizeof(*sti->glob_cfg), GFP_KERNEL); |
| 418 | glob_cfg_ext = kmalloc(sizeof(*glob_cfg_ext), GFP_KERNEL); | 419 | glob_cfg_ext = kzalloc(sizeof(*glob_cfg_ext), GFP_KERNEL); |
| 419 | save_addr = kmalloc(save_addr_size, GFP_KERNEL); | 420 | save_addr = kzalloc(save_addr_size, GFP_KERNEL); |
| 420 | sti_mem_addr = kmalloc(sti->sti_mem_request, GFP_KERNEL); | 421 | sti_mem_addr = kzalloc(sti->sti_mem_request, GFP_KERNEL); |
| 421 | 422 | ||
| 422 | if (!(glob_cfg && glob_cfg_ext && save_addr && sti_mem_addr)) { | 423 | if (!(glob_cfg && glob_cfg_ext && save_addr && sti_mem_addr)) { |
| 423 | kfree(glob_cfg); | 424 | kfree(glob_cfg); |
| @@ -427,11 +428,6 @@ sti_init_glob_cfg(struct sti_struct *sti, | |||
| 427 | return -ENOMEM; | 428 | return -ENOMEM; |
| 428 | } | 429 | } |
| 429 | 430 | ||
| 430 | memset(glob_cfg, 0, sizeof(*glob_cfg)); | ||
| 431 | memset(glob_cfg_ext, 0, sizeof(*glob_cfg_ext)); | ||
| 432 | memset(save_addr, 0, save_addr_size); | ||
| 433 | memset(sti_mem_addr, 0, sti->sti_mem_request); | ||
| 434 | |||
| 435 | glob_cfg->ext_ptr = STI_PTR(glob_cfg_ext); | 431 | glob_cfg->ext_ptr = STI_PTR(glob_cfg_ext); |
| 436 | glob_cfg->save_addr = STI_PTR(save_addr); | 432 | glob_cfg->save_addr = STI_PTR(save_addr); |
| 437 | for (i=0; i<8; i++) { | 433 | for (i=0; i<8; i++) { |
| @@ -502,9 +498,9 @@ sti_init_glob_cfg(struct sti_struct *sti, | |||
| 502 | 498 | ||
| 503 | #ifdef CONFIG_FB | 499 | #ifdef CONFIG_FB |
| 504 | struct sti_cooked_font * __init | 500 | struct sti_cooked_font * __init |
| 505 | sti_select_fbfont( struct sti_cooked_rom *cooked_rom, char *fbfont_name ) | 501 | sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) |
| 506 | { | 502 | { |
| 507 | struct font_desc *fbfont; | 503 | const struct font_desc *fbfont; |
| 508 | unsigned int size, bpc; | 504 | unsigned int size, bpc; |
| 509 | void *dest; | 505 | void *dest; |
| 510 | struct sti_rom_font *nf; | 506 | struct sti_rom_font *nf; |
| @@ -525,10 +521,9 @@ sti_select_fbfont( struct sti_cooked_rom *cooked_rom, char *fbfont_name ) | |||
| 525 | size = bpc * 256; | 521 | size = bpc * 256; |
| 526 | size += sizeof(struct sti_rom_font); | 522 | size += sizeof(struct sti_rom_font); |
| 527 | 523 | ||
| 528 | nf = kmalloc(size, GFP_KERNEL); | 524 | nf = kzalloc(size, GFP_KERNEL); |
| 529 | if (!nf) | 525 | if (!nf) |
| 530 | return NULL; | 526 | return NULL; |
| 531 | memset(nf, 0, size); | ||
| 532 | 527 | ||
| 533 | nf->first_char = 0; | 528 | nf->first_char = 0; |
| 534 | nf->last_char = 255; | 529 | nf->last_char = 255; |
| @@ -544,7 +539,7 @@ sti_select_fbfont( struct sti_cooked_rom *cooked_rom, char *fbfont_name ) | |||
| 544 | dest += sizeof(struct sti_rom_font); | 539 | dest += sizeof(struct sti_rom_font); |
| 545 | memcpy(dest, fbfont->data, bpc*256); | 540 | memcpy(dest, fbfont->data, bpc*256); |
| 546 | 541 | ||
| 547 | cooked_font = kmalloc(sizeof(*cooked_font), GFP_KERNEL); | 542 | cooked_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL); |
| 548 | if (!cooked_font) { | 543 | if (!cooked_font) { |
| 549 | kfree(nf); | 544 | kfree(nf); |
| 550 | return NULL; | 545 | return NULL; |
| @@ -559,7 +554,7 @@ sti_select_fbfont( struct sti_cooked_rom *cooked_rom, char *fbfont_name ) | |||
| 559 | } | 554 | } |
| 560 | #else | 555 | #else |
| 561 | struct sti_cooked_font * __init | 556 | struct sti_cooked_font * __init |
| 562 | sti_select_fbfont(struct sti_cooked_rom *cooked_rom, char *fbfont_name) | 557 | sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) |
| 563 | { | 558 | { |
| 564 | return NULL; | 559 | return NULL; |
| 565 | } | 560 | } |
| @@ -617,7 +612,7 @@ sti_cook_fonts(struct sti_cooked_rom *cooked_rom, | |||
| 617 | struct sti_rom_font *raw_font, *font_start; | 612 | struct sti_rom_font *raw_font, *font_start; |
| 618 | struct sti_cooked_font *cooked_font; | 613 | struct sti_cooked_font *cooked_font; |
| 619 | 614 | ||
| 620 | cooked_font = kmalloc(sizeof(*cooked_font), GFP_KERNEL); | 615 | cooked_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL); |
| 621 | if (!cooked_font) | 616 | if (!cooked_font) |
| 622 | return 0; | 617 | return 0; |
| 623 | 618 | ||
| @@ -631,7 +626,7 @@ sti_cook_fonts(struct sti_cooked_rom *cooked_rom, | |||
| 631 | while (raw_font->next_font) { | 626 | while (raw_font->next_font) { |
| 632 | raw_font = ((void *)font_start) + (raw_font->next_font); | 627 | raw_font = ((void *)font_start) + (raw_font->next_font); |
| 633 | 628 | ||
| 634 | cooked_font->next_font = kmalloc(sizeof(*cooked_font), GFP_KERNEL); | 629 | cooked_font->next_font = kzalloc(sizeof(*cooked_font), GFP_KERNEL); |
| 635 | if (!cooked_font->next_font) | 630 | if (!cooked_font->next_font) |
| 636 | return 1; | 631 | return 1; |
| 637 | 632 | ||
| @@ -668,10 +663,9 @@ sti_bmode_font_raw(struct sti_cooked_font *f) | |||
| 668 | unsigned char *n, *p, *q; | 663 | unsigned char *n, *p, *q; |
| 669 | int size = f->raw->bytes_per_char*256+sizeof(struct sti_rom_font); | 664 | int size = f->raw->bytes_per_char*256+sizeof(struct sti_rom_font); |
| 670 | 665 | ||
| 671 | n = kmalloc (4*size, GFP_KERNEL); | 666 | n = kzalloc (4*size, GFP_KERNEL); |
| 672 | if (!n) | 667 | if (!n) |
| 673 | return NULL; | 668 | return NULL; |
| 674 | memset (n, 0, 4*size); | ||
| 675 | p = n + 3; | 669 | p = n + 3; |
| 676 | q = (unsigned char *)f->raw; | 670 | q = (unsigned char *)f->raw; |
| 677 | while (size--) { | 671 | while (size--) { |
| @@ -816,13 +810,12 @@ sti_try_rom_generic(unsigned long address, unsigned long hpa, struct pci_dev *pd | |||
| 816 | return NULL; | 810 | return NULL; |
| 817 | } | 811 | } |
| 818 | 812 | ||
| 819 | sti = kmalloc(sizeof(*sti), GFP_KERNEL); | 813 | sti = kzalloc(sizeof(*sti), GFP_KERNEL); |
| 820 | if (!sti) { | 814 | if (!sti) { |
| 821 | printk(KERN_ERR "Not enough memory !\n"); | 815 | printk(KERN_ERR "Not enough memory !\n"); |
| 822 | return NULL; | 816 | return NULL; |
| 823 | } | 817 | } |
| 824 | 818 | ||
| 825 | memset(sti, 0, sizeof(*sti)); | ||
| 826 | spin_lock_init(&sti->lock); | 819 | spin_lock_init(&sti->lock); |
| 827 | 820 | ||
| 828 | test_rom: | 821 | test_rom: |
| @@ -1035,7 +1028,7 @@ static struct parisc_driver pa_sti_driver = { | |||
| 1035 | * sti_init_roms() - detects all STI ROMs and stores them in sti_roms[] | 1028 | * sti_init_roms() - detects all STI ROMs and stores them in sti_roms[] |
| 1036 | */ | 1029 | */ |
| 1037 | 1030 | ||
| 1038 | static int sticore_initialized; | 1031 | static int sticore_initialized __read_mostly; |
| 1039 | 1032 | ||
| 1040 | static void __init sti_init_roms(void) | 1033 | static void __init sti_init_roms(void) |
| 1041 | { | 1034 | { |
diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c index f3927b6cda9d..f5361cd8ccce 100644 --- a/drivers/video/pmag-ba-fb.c +++ b/drivers/video/pmag-ba-fb.c | |||
| @@ -30,7 +30,6 @@ | |||
| 30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
| 31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
| 32 | 32 | ||
| 33 | #include <asm/bug.h> | ||
| 34 | #include <asm/io.h> | 33 | #include <asm/io.h> |
| 35 | #include <asm/system.h> | 34 | #include <asm/system.h> |
| 36 | 35 | ||
diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c index 25148de5fe67..eeeac924b500 100644 --- a/drivers/video/pmagb-b-fb.c +++ b/drivers/video/pmagb-b-fb.c | |||
| @@ -27,7 +27,6 @@ | |||
| 27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| 28 | #include <linux/types.h> | 28 | #include <linux/types.h> |
| 29 | 29 | ||
| 30 | #include <asm/bug.h> | ||
| 31 | #include <asm/io.h> | 30 | #include <asm/io.h> |
| 32 | #include <asm/system.h> | 31 | #include <asm/system.h> |
| 33 | 32 | ||
diff --git a/fs/9p/conv.c b/fs/9p/conv.c index 32a9f99154e2..bf1f10067960 100644 --- a/fs/9p/conv.c +++ b/fs/9p/conv.c | |||
| @@ -116,13 +116,19 @@ static void buf_put_int64(struct cbuf *buf, u64 val) | |||
| 116 | } | 116 | } |
| 117 | } | 117 | } |
| 118 | 118 | ||
| 119 | static void buf_put_stringn(struct cbuf *buf, const char *s, u16 slen) | 119 | static char *buf_put_stringn(struct cbuf *buf, const char *s, u16 slen) |
| 120 | { | 120 | { |
| 121 | char *ret; | ||
| 122 | |||
| 123 | ret = NULL; | ||
| 121 | if (buf_check_size(buf, slen + 2)) { | 124 | if (buf_check_size(buf, slen + 2)) { |
| 122 | buf_put_int16(buf, slen); | 125 | buf_put_int16(buf, slen); |
| 126 | ret = buf->p; | ||
| 123 | memcpy(buf->p, s, slen); | 127 | memcpy(buf->p, s, slen); |
| 124 | buf->p += slen; | 128 | buf->p += slen; |
| 125 | } | 129 | } |
| 130 | |||
| 131 | return ret; | ||
| 126 | } | 132 | } |
| 127 | 133 | ||
| 128 | static inline void buf_put_string(struct cbuf *buf, const char *s) | 134 | static inline void buf_put_string(struct cbuf *buf, const char *s) |
| @@ -430,15 +436,19 @@ static inline void v9fs_put_int64(struct cbuf *bufp, u64 val, u64 * p) | |||
| 430 | static void | 436 | static void |
| 431 | v9fs_put_str(struct cbuf *bufp, char *data, struct v9fs_str *str) | 437 | v9fs_put_str(struct cbuf *bufp, char *data, struct v9fs_str *str) |
| 432 | { | 438 | { |
| 433 | if (data) { | 439 | int len; |
| 434 | str->len = strlen(data); | 440 | char *s; |
| 435 | str->str = bufp->p; | 441 | |
| 436 | } else { | 442 | if (data) |
| 437 | str->len = 0; | 443 | len = strlen(data); |
| 438 | str->str = NULL; | 444 | else |
| 439 | } | 445 | len = 0; |
| 440 | 446 | ||
| 441 | buf_put_stringn(bufp, data, str->len); | 447 | s = buf_put_stringn(bufp, data, len); |
| 448 | if (str) { | ||
| 449 | str->len = len; | ||
| 450 | str->str = s; | ||
| 451 | } | ||
| 442 | } | 452 | } |
| 443 | 453 | ||
| 444 | static int | 454 | static int |
diff --git a/fs/9p/mux.c b/fs/9p/mux.c index 945cb368d451..ea1134eb47c8 100644 --- a/fs/9p/mux.c +++ b/fs/9p/mux.c | |||
| @@ -471,10 +471,13 @@ static void v9fs_write_work(void *a) | |||
| 471 | } | 471 | } |
| 472 | 472 | ||
| 473 | spin_lock(&m->lock); | 473 | spin_lock(&m->lock); |
| 474 | req = | 474 | again: |
| 475 | list_entry(m->unsent_req_list.next, struct v9fs_req, | 475 | req = list_entry(m->unsent_req_list.next, struct v9fs_req, |
| 476 | req_list); | 476 | req_list); |
| 477 | list_move_tail(&req->req_list, &m->req_list); | 477 | list_move_tail(&req->req_list, &m->req_list); |
| 478 | if (req->err == ERREQFLUSH) | ||
| 479 | goto again; | ||
| 480 | |||
| 478 | m->wbuf = req->tcall->sdata; | 481 | m->wbuf = req->tcall->sdata; |
| 479 | m->wsize = req->tcall->size; | 482 | m->wsize = req->tcall->size; |
| 480 | m->wpos = 0; | 483 | m->wpos = 0; |
| @@ -525,7 +528,7 @@ static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req) | |||
| 525 | struct v9fs_str *ename; | 528 | struct v9fs_str *ename; |
| 526 | 529 | ||
| 527 | tag = req->tag; | 530 | tag = req->tag; |
| 528 | if (req->rcall->id == RERROR && !req->err) { | 531 | if (!req->err && req->rcall->id == RERROR) { |
| 529 | ecode = req->rcall->params.rerror.errno; | 532 | ecode = req->rcall->params.rerror.errno; |
| 530 | ename = &req->rcall->params.rerror.error; | 533 | ename = &req->rcall->params.rerror.error; |
| 531 | 534 | ||
| @@ -551,7 +554,10 @@ static void process_request(struct v9fs_mux_data *m, struct v9fs_req *req) | |||
| 551 | req->err = -EIO; | 554 | req->err = -EIO; |
| 552 | } | 555 | } |
| 553 | 556 | ||
| 554 | if (req->cb && req->err != ERREQFLUSH) { | 557 | if (req->err == ERREQFLUSH) |
| 558 | return; | ||
| 559 | |||
| 560 | if (req->cb) { | ||
| 555 | dprintk(DEBUG_MUX, "calling callback tcall %p rcall %p\n", | 561 | dprintk(DEBUG_MUX, "calling callback tcall %p rcall %p\n", |
| 556 | req->tcall, req->rcall); | 562 | req->tcall, req->rcall); |
| 557 | 563 | ||
| @@ -812,6 +818,7 @@ v9fs_mux_rpc_cb(void *a, struct v9fs_fcall *tc, struct v9fs_fcall *rc, int err) | |||
| 812 | struct v9fs_mux_rpc *r; | 818 | struct v9fs_mux_rpc *r; |
| 813 | 819 | ||
| 814 | if (err == ERREQFLUSH) { | 820 | if (err == ERREQFLUSH) { |
| 821 | kfree(rc); | ||
| 815 | dprintk(DEBUG_MUX, "err req flush\n"); | 822 | dprintk(DEBUG_MUX, "err req flush\n"); |
| 816 | return; | 823 | return; |
| 817 | } | 824 | } |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 91f552454c76..63e5b0398e8b 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
| @@ -886,8 +886,8 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen) | |||
| 886 | } | 886 | } |
| 887 | 887 | ||
| 888 | /* copy extension buffer into buffer */ | 888 | /* copy extension buffer into buffer */ |
| 889 | if (fcall->params.rstat.stat.extension.len < buflen) | 889 | if (fcall->params.rstat.stat.extension.len+1 < buflen) |
| 890 | buflen = fcall->params.rstat.stat.extension.len; | 890 | buflen = fcall->params.rstat.stat.extension.len + 1; |
| 891 | 891 | ||
| 892 | memcpy(buffer, fcall->params.rstat.stat.extension.str, buflen - 1); | 892 | memcpy(buffer, fcall->params.rstat.stat.extension.str, buflen - 1); |
| 893 | buffer[buflen-1] = 0; | 893 | buffer[buflen-1] = 0; |
| @@ -951,7 +951,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
| 951 | if (!link) | 951 | if (!link) |
| 952 | link = ERR_PTR(-ENOMEM); | 952 | link = ERR_PTR(-ENOMEM); |
| 953 | else { | 953 | else { |
| 954 | len = v9fs_readlink(dentry, link, strlen(link)); | 954 | len = v9fs_readlink(dentry, link, PATH_MAX); |
| 955 | 955 | ||
| 956 | if (len < 0) { | 956 | if (len < 0) { |
| 957 | __putname(link); | 957 | __putname(link); |
diff --git a/fs/Kconfig b/fs/Kconfig index 93b5dc4082ff..e9749b0eecd8 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
| @@ -883,8 +883,6 @@ config CONFIGFS_FS | |||
| 883 | Both sysfs and configfs can and should exist together on the | 883 | Both sysfs and configfs can and should exist together on the |
| 884 | same system. One is not a replacement for the other. | 884 | same system. One is not a replacement for the other. |
| 885 | 885 | ||
| 886 | If unsure, say N. | ||
| 887 | |||
| 888 | endmenu | 886 | endmenu |
| 889 | 887 | ||
| 890 | menu "Miscellaneous filesystems" | 888 | menu "Miscellaneous filesystems" |
diff --git a/fs/buffer.c b/fs/buffer.c index 5e4a90ee103f..62cfd17dc5fe 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
| @@ -2867,22 +2867,22 @@ void ll_rw_block(int rw, int nr, struct buffer_head *bhs[]) | |||
| 2867 | else if (test_set_buffer_locked(bh)) | 2867 | else if (test_set_buffer_locked(bh)) |
| 2868 | continue; | 2868 | continue; |
| 2869 | 2869 | ||
| 2870 | get_bh(bh); | ||
| 2871 | if (rw == WRITE || rw == SWRITE) { | 2870 | if (rw == WRITE || rw == SWRITE) { |
| 2872 | if (test_clear_buffer_dirty(bh)) { | 2871 | if (test_clear_buffer_dirty(bh)) { |
| 2873 | bh->b_end_io = end_buffer_write_sync; | 2872 | bh->b_end_io = end_buffer_write_sync; |
| 2873 | get_bh(bh); | ||
| 2874 | submit_bh(WRITE, bh); | 2874 | submit_bh(WRITE, bh); |
| 2875 | continue; | 2875 | continue; |
| 2876 | } | 2876 | } |
| 2877 | } else { | 2877 | } else { |
| 2878 | if (!buffer_uptodate(bh)) { | 2878 | if (!buffer_uptodate(bh)) { |
| 2879 | bh->b_end_io = end_buffer_read_sync; | 2879 | bh->b_end_io = end_buffer_read_sync; |
| 2880 | get_bh(bh); | ||
| 2880 | submit_bh(rw, bh); | 2881 | submit_bh(rw, bh); |
| 2881 | continue; | 2882 | continue; |
| 2882 | } | 2883 | } |
| 2883 | } | 2884 | } |
| 2884 | unlock_buffer(bh); | 2885 | unlock_buffer(bh); |
| 2885 | put_bh(bh); | ||
| 2886 | } | 2886 | } |
| 2887 | } | 2887 | } |
| 2888 | 2888 | ||
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 5dd0207ffd46..057e60217fc5 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
| @@ -931,8 +931,8 @@ struct compat_sg_req_info { /* used by SG_GET_REQUEST_TABLE ioctl() */ | |||
| 931 | static int sg_grt_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | 931 | static int sg_grt_trans(unsigned int fd, unsigned int cmd, unsigned long arg) |
| 932 | { | 932 | { |
| 933 | int err, i; | 933 | int err, i; |
| 934 | sg_req_info_t *r; | 934 | sg_req_info_t __user *r; |
| 935 | struct compat_sg_req_info *o = (struct compat_sg_req_info *)arg; | 935 | struct compat_sg_req_info __user *o = (void __user *)arg; |
| 936 | r = compat_alloc_user_space(sizeof(sg_req_info_t)*SG_MAX_QUEUE); | 936 | r = compat_alloc_user_space(sizeof(sg_req_info_t)*SG_MAX_QUEUE); |
| 937 | err = sys_ioctl(fd,cmd,(unsigned long)r); | 937 | err = sys_ioctl(fd,cmd,(unsigned long)r); |
| 938 | if (err < 0) | 938 | if (err < 0) |
| @@ -2739,8 +2739,8 @@ static int do_ncp_setprivatedata(unsigned int fd, unsigned int cmd, unsigned lon | |||
| 2739 | static int | 2739 | static int |
| 2740 | lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg) | 2740 | lp_timeout_trans(unsigned int fd, unsigned int cmd, unsigned long arg) |
| 2741 | { | 2741 | { |
| 2742 | struct compat_timeval *tc = (struct compat_timeval *)arg; | 2742 | struct compat_timeval __user *tc = (struct compat_timeval __user *)arg; |
| 2743 | struct timeval *tn = compat_alloc_user_space(sizeof(struct timeval)); | 2743 | struct timeval __user *tn = compat_alloc_user_space(sizeof(struct timeval)); |
| 2744 | struct timeval ts; | 2744 | struct timeval ts; |
| 2745 | if (get_user(ts.tv_sec, &tc->tv_sec) || | 2745 | if (get_user(ts.tv_sec, &tc->tv_sec) || |
| 2746 | get_user(ts.tv_usec, &tc->tv_usec) || | 2746 | get_user(ts.tv_usec, &tc->tv_usec) || |
diff --git a/fs/configfs/configfs_internal.h b/fs/configfs/configfs_internal.h index 8899d9c5f6bf..f70e46951b37 100644 --- a/fs/configfs/configfs_internal.h +++ b/fs/configfs/configfs_internal.h | |||
| @@ -36,6 +36,7 @@ struct configfs_dirent { | |||
| 36 | int s_type; | 36 | int s_type; |
| 37 | umode_t s_mode; | 37 | umode_t s_mode; |
| 38 | struct dentry * s_dentry; | 38 | struct dentry * s_dentry; |
| 39 | struct iattr * s_iattr; | ||
| 39 | }; | 40 | }; |
| 40 | 41 | ||
| 41 | #define CONFIGFS_ROOT 0x0001 | 42 | #define CONFIGFS_ROOT 0x0001 |
| @@ -48,10 +49,11 @@ struct configfs_dirent { | |||
| 48 | #define CONFIGFS_NOT_PINNED (CONFIGFS_ITEM_ATTR) | 49 | #define CONFIGFS_NOT_PINNED (CONFIGFS_ITEM_ATTR) |
| 49 | 50 | ||
| 50 | extern struct vfsmount * configfs_mount; | 51 | extern struct vfsmount * configfs_mount; |
| 52 | extern kmem_cache_t *configfs_dir_cachep; | ||
| 51 | 53 | ||
| 52 | extern int configfs_is_root(struct config_item *item); | 54 | extern int configfs_is_root(struct config_item *item); |
| 53 | 55 | ||
| 54 | extern struct inode * configfs_new_inode(mode_t mode); | 56 | extern struct inode * configfs_new_inode(mode_t mode, struct configfs_dirent *); |
| 55 | extern int configfs_create(struct dentry *, int mode, int (*init)(struct inode *)); | 57 | extern int configfs_create(struct dentry *, int mode, int (*init)(struct inode *)); |
| 56 | 58 | ||
| 57 | extern int configfs_create_file(struct config_item *, const struct configfs_attribute *); | 59 | extern int configfs_create_file(struct config_item *, const struct configfs_attribute *); |
| @@ -63,6 +65,7 @@ extern void configfs_hash_and_remove(struct dentry * dir, const char * name); | |||
| 63 | 65 | ||
| 64 | extern const unsigned char * configfs_get_name(struct configfs_dirent *sd); | 66 | extern const unsigned char * configfs_get_name(struct configfs_dirent *sd); |
| 65 | extern void configfs_drop_dentry(struct configfs_dirent *sd, struct dentry *parent); | 67 | extern void configfs_drop_dentry(struct configfs_dirent *sd, struct dentry *parent); |
| 68 | extern int configfs_setattr(struct dentry *dentry, struct iattr *iattr); | ||
| 66 | 69 | ||
| 67 | extern int configfs_pin_fs(void); | 70 | extern int configfs_pin_fs(void); |
| 68 | extern void configfs_release_fs(void); | 71 | extern void configfs_release_fs(void); |
| @@ -120,8 +123,10 @@ static inline struct config_item *configfs_get_config_item(struct dentry *dentry | |||
| 120 | 123 | ||
| 121 | static inline void release_configfs_dirent(struct configfs_dirent * sd) | 124 | static inline void release_configfs_dirent(struct configfs_dirent * sd) |
| 122 | { | 125 | { |
| 123 | if (!(sd->s_type & CONFIGFS_ROOT)) | 126 | if (!(sd->s_type & CONFIGFS_ROOT)) { |
| 124 | kfree(sd); | 127 | kfree(sd->s_iattr); |
| 128 | kmem_cache_free(configfs_dir_cachep, sd); | ||
| 129 | } | ||
| 125 | } | 130 | } |
| 126 | 131 | ||
| 127 | static inline struct configfs_dirent * configfs_get(struct configfs_dirent * sd) | 132 | static inline struct configfs_dirent * configfs_get(struct configfs_dirent * sd) |
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index b668ec61527e..ca60e3abef45 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c | |||
| @@ -72,7 +72,7 @@ static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent * pare | |||
| 72 | { | 72 | { |
| 73 | struct configfs_dirent * sd; | 73 | struct configfs_dirent * sd; |
| 74 | 74 | ||
| 75 | sd = kmalloc(sizeof(*sd), GFP_KERNEL); | 75 | sd = kmem_cache_alloc(configfs_dir_cachep, GFP_KERNEL); |
| 76 | if (!sd) | 76 | if (!sd) |
| 77 | return NULL; | 77 | return NULL; |
| 78 | 78 | ||
| @@ -136,13 +136,19 @@ static int create_dir(struct config_item * k, struct dentry * p, | |||
| 136 | int error; | 136 | int error; |
| 137 | umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; | 137 | umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; |
| 138 | 138 | ||
| 139 | error = configfs_create(d, mode, init_dir); | 139 | error = configfs_make_dirent(p->d_fsdata, d, k, mode, |
| 140 | CONFIGFS_DIR); | ||
| 140 | if (!error) { | 141 | if (!error) { |
| 141 | error = configfs_make_dirent(p->d_fsdata, d, k, mode, | 142 | error = configfs_create(d, mode, init_dir); |
| 142 | CONFIGFS_DIR); | ||
| 143 | if (!error) { | 143 | if (!error) { |
| 144 | p->d_inode->i_nlink++; | 144 | p->d_inode->i_nlink++; |
| 145 | (d)->d_op = &configfs_dentry_ops; | 145 | (d)->d_op = &configfs_dentry_ops; |
| 146 | } else { | ||
| 147 | struct configfs_dirent *sd = d->d_fsdata; | ||
| 148 | if (sd) { | ||
| 149 | list_del_init(&sd->s_sibling); | ||
| 150 | configfs_put(sd); | ||
| 151 | } | ||
| 146 | } | 152 | } |
| 147 | } | 153 | } |
| 148 | return error; | 154 | return error; |
| @@ -182,12 +188,19 @@ int configfs_create_link(struct configfs_symlink *sl, | |||
| 182 | int err = 0; | 188 | int err = 0; |
| 183 | umode_t mode = S_IFLNK | S_IRWXUGO; | 189 | umode_t mode = S_IFLNK | S_IRWXUGO; |
| 184 | 190 | ||
| 185 | err = configfs_create(dentry, mode, init_symlink); | 191 | err = configfs_make_dirent(parent->d_fsdata, dentry, sl, mode, |
| 192 | CONFIGFS_ITEM_LINK); | ||
| 186 | if (!err) { | 193 | if (!err) { |
| 187 | err = configfs_make_dirent(parent->d_fsdata, dentry, sl, | 194 | err = configfs_create(dentry, mode, init_symlink); |
| 188 | mode, CONFIGFS_ITEM_LINK); | ||
| 189 | if (!err) | 195 | if (!err) |
| 190 | dentry->d_op = &configfs_dentry_ops; | 196 | dentry->d_op = &configfs_dentry_ops; |
| 197 | else { | ||
| 198 | struct configfs_dirent *sd = dentry->d_fsdata; | ||
| 199 | if (sd) { | ||
| 200 | list_del_init(&sd->s_sibling); | ||
| 201 | configfs_put(sd); | ||
| 202 | } | ||
| 203 | } | ||
| 191 | } | 204 | } |
| 192 | return err; | 205 | return err; |
| 193 | } | 206 | } |
| @@ -241,13 +254,15 @@ static int configfs_attach_attr(struct configfs_dirent * sd, struct dentry * den | |||
| 241 | struct configfs_attribute * attr = sd->s_element; | 254 | struct configfs_attribute * attr = sd->s_element; |
| 242 | int error; | 255 | int error; |
| 243 | 256 | ||
| 257 | dentry->d_fsdata = configfs_get(sd); | ||
| 258 | sd->s_dentry = dentry; | ||
| 244 | error = configfs_create(dentry, (attr->ca_mode & S_IALLUGO) | S_IFREG, init_file); | 259 | error = configfs_create(dentry, (attr->ca_mode & S_IALLUGO) | S_IFREG, init_file); |
| 245 | if (error) | 260 | if (error) { |
| 261 | configfs_put(sd); | ||
| 246 | return error; | 262 | return error; |
| 263 | } | ||
| 247 | 264 | ||
| 248 | dentry->d_op = &configfs_dentry_ops; | 265 | dentry->d_op = &configfs_dentry_ops; |
| 249 | dentry->d_fsdata = configfs_get(sd); | ||
| 250 | sd->s_dentry = dentry; | ||
| 251 | d_rehash(dentry); | 266 | d_rehash(dentry); |
| 252 | 267 | ||
| 253 | return 0; | 268 | return 0; |
| @@ -839,6 +854,7 @@ struct inode_operations configfs_dir_inode_operations = { | |||
| 839 | .symlink = configfs_symlink, | 854 | .symlink = configfs_symlink, |
| 840 | .unlink = configfs_unlink, | 855 | .unlink = configfs_unlink, |
| 841 | .lookup = configfs_lookup, | 856 | .lookup = configfs_lookup, |
| 857 | .setattr = configfs_setattr, | ||
| 842 | }; | 858 | }; |
| 843 | 859 | ||
| 844 | #if 0 | 860 | #if 0 |
diff --git a/fs/configfs/file.c b/fs/configfs/file.c index c26cd61f13af..3921920d8716 100644 --- a/fs/configfs/file.c +++ b/fs/configfs/file.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | 26 | ||
| 27 | #include <linux/fs.h> | 27 | #include <linux/fs.h> |
| 28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
| 29 | #include <linux/dnotify.h> | ||
| 30 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
| 31 | #include <asm/uaccess.h> | 30 | #include <asm/uaccess.h> |
| 32 | #include <asm/semaphore.h> | 31 | #include <asm/semaphore.h> |
| @@ -150,7 +149,7 @@ out: | |||
| 150 | /** | 149 | /** |
| 151 | * fill_write_buffer - copy buffer from userspace. | 150 | * fill_write_buffer - copy buffer from userspace. |
| 152 | * @buffer: data buffer for file. | 151 | * @buffer: data buffer for file. |
| 153 | * @userbuf: data from user. | 152 | * @buf: data from user. |
| 154 | * @count: number of bytes in @userbuf. | 153 | * @count: number of bytes in @userbuf. |
| 155 | * | 154 | * |
| 156 | * Allocate @buffer->page if it hasn't been already, then | 155 | * Allocate @buffer->page if it hasn't been already, then |
| @@ -177,8 +176,9 @@ fill_write_buffer(struct configfs_buffer * buffer, const char __user * buf, size | |||
| 177 | 176 | ||
| 178 | /** | 177 | /** |
| 179 | * flush_write_buffer - push buffer to config_item. | 178 | * flush_write_buffer - push buffer to config_item. |
| 180 | * @file: file pointer. | 179 | * @dentry: dentry to the attribute |
| 181 | * @buffer: data buffer for file. | 180 | * @buffer: data buffer for file. |
| 181 | * @count: number of bytes | ||
| 182 | * | 182 | * |
| 183 | * Get the correct pointers for the config_item and the attribute we're | 183 | * Get the correct pointers for the config_item and the attribute we're |
| 184 | * dealing with, then call the store() method for the attribute, | 184 | * dealing with, then call the store() method for the attribute, |
| @@ -217,15 +217,16 @@ static ssize_t | |||
| 217 | configfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | 217 | configfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t *ppos) |
| 218 | { | 218 | { |
| 219 | struct configfs_buffer * buffer = file->private_data; | 219 | struct configfs_buffer * buffer = file->private_data; |
| 220 | ssize_t len; | ||
| 220 | 221 | ||
| 221 | down(&buffer->sem); | 222 | down(&buffer->sem); |
| 222 | count = fill_write_buffer(buffer,buf,count); | 223 | len = fill_write_buffer(buffer, buf, count); |
| 223 | if (count > 0) | 224 | if (len > 0) |
| 224 | count = flush_write_buffer(file->f_dentry,buffer,count); | 225 | len = flush_write_buffer(file->f_dentry, buffer, count); |
| 225 | if (count > 0) | 226 | if (len > 0) |
| 226 | *ppos += count; | 227 | *ppos += len; |
| 227 | up(&buffer->sem); | 228 | up(&buffer->sem); |
| 228 | return count; | 229 | return len; |
| 229 | } | 230 | } |
| 230 | 231 | ||
| 231 | static int check_perm(struct inode * inode, struct file * file) | 232 | static int check_perm(struct inode * inode, struct file * file) |
diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c index 6577c588de9d..c153bd9534cb 100644 --- a/fs/configfs/inode.c +++ b/fs/configfs/inode.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <linux/pagemap.h> | 31 | #include <linux/pagemap.h> |
| 32 | #include <linux/namei.h> | 32 | #include <linux/namei.h> |
| 33 | #include <linux/backing-dev.h> | 33 | #include <linux/backing-dev.h> |
| 34 | #include <linux/capability.h> | ||
| 34 | 35 | ||
| 35 | #include <linux/configfs.h> | 36 | #include <linux/configfs.h> |
| 36 | #include "configfs_internal.h" | 37 | #include "configfs_internal.h" |
| @@ -48,18 +49,107 @@ static struct backing_dev_info configfs_backing_dev_info = { | |||
| 48 | .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK, | 49 | .capabilities = BDI_CAP_NO_ACCT_DIRTY | BDI_CAP_NO_WRITEBACK, |
| 49 | }; | 50 | }; |
| 50 | 51 | ||
| 51 | struct inode * configfs_new_inode(mode_t mode) | 52 | static struct inode_operations configfs_inode_operations ={ |
| 53 | .setattr = configfs_setattr, | ||
| 54 | }; | ||
| 55 | |||
| 56 | int configfs_setattr(struct dentry * dentry, struct iattr * iattr) | ||
| 57 | { | ||
| 58 | struct inode * inode = dentry->d_inode; | ||
| 59 | struct configfs_dirent * sd = dentry->d_fsdata; | ||
| 60 | struct iattr * sd_iattr; | ||
| 61 | unsigned int ia_valid = iattr->ia_valid; | ||
| 62 | int error; | ||
| 63 | |||
| 64 | if (!sd) | ||
| 65 | return -EINVAL; | ||
| 66 | |||
| 67 | sd_iattr = sd->s_iattr; | ||
| 68 | |||
| 69 | error = inode_change_ok(inode, iattr); | ||
| 70 | if (error) | ||
| 71 | return error; | ||
| 72 | |||
| 73 | error = inode_setattr(inode, iattr); | ||
| 74 | if (error) | ||
| 75 | return error; | ||
| 76 | |||
| 77 | if (!sd_iattr) { | ||
| 78 | /* setting attributes for the first time, allocate now */ | ||
| 79 | sd_iattr = kmalloc(sizeof(struct iattr), GFP_KERNEL); | ||
| 80 | if (!sd_iattr) | ||
| 81 | return -ENOMEM; | ||
| 82 | /* assign default attributes */ | ||
| 83 | memset(sd_iattr, 0, sizeof(struct iattr)); | ||
| 84 | sd_iattr->ia_mode = sd->s_mode; | ||
| 85 | sd_iattr->ia_uid = 0; | ||
| 86 | sd_iattr->ia_gid = 0; | ||
| 87 | sd_iattr->ia_atime = sd_iattr->ia_mtime = sd_iattr->ia_ctime = CURRENT_TIME; | ||
| 88 | sd->s_iattr = sd_iattr; | ||
| 89 | } | ||
| 90 | |||
| 91 | /* attributes were changed atleast once in past */ | ||
| 92 | |||
| 93 | if (ia_valid & ATTR_UID) | ||
| 94 | sd_iattr->ia_uid = iattr->ia_uid; | ||
| 95 | if (ia_valid & ATTR_GID) | ||
| 96 | sd_iattr->ia_gid = iattr->ia_gid; | ||
| 97 | if (ia_valid & ATTR_ATIME) | ||
| 98 | sd_iattr->ia_atime = timespec_trunc(iattr->ia_atime, | ||
| 99 | inode->i_sb->s_time_gran); | ||
| 100 | if (ia_valid & ATTR_MTIME) | ||
| 101 | sd_iattr->ia_mtime = timespec_trunc(iattr->ia_mtime, | ||
| 102 | inode->i_sb->s_time_gran); | ||
| 103 | if (ia_valid & ATTR_CTIME) | ||
| 104 | sd_iattr->ia_ctime = timespec_trunc(iattr->ia_ctime, | ||
| 105 | inode->i_sb->s_time_gran); | ||
| 106 | if (ia_valid & ATTR_MODE) { | ||
| 107 | umode_t mode = iattr->ia_mode; | ||
| 108 | |||
| 109 | if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) | ||
| 110 | mode &= ~S_ISGID; | ||
| 111 | sd_iattr->ia_mode = sd->s_mode = mode; | ||
| 112 | } | ||
| 113 | |||
| 114 | return error; | ||
| 115 | } | ||
| 116 | |||
| 117 | static inline void set_default_inode_attr(struct inode * inode, mode_t mode) | ||
| 118 | { | ||
| 119 | inode->i_mode = mode; | ||
| 120 | inode->i_uid = 0; | ||
| 121 | inode->i_gid = 0; | ||
| 122 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
| 123 | } | ||
| 124 | |||
| 125 | static inline void set_inode_attr(struct inode * inode, struct iattr * iattr) | ||
| 126 | { | ||
| 127 | inode->i_mode = iattr->ia_mode; | ||
| 128 | inode->i_uid = iattr->ia_uid; | ||
| 129 | inode->i_gid = iattr->ia_gid; | ||
| 130 | inode->i_atime = iattr->ia_atime; | ||
| 131 | inode->i_mtime = iattr->ia_mtime; | ||
| 132 | inode->i_ctime = iattr->ia_ctime; | ||
| 133 | } | ||
| 134 | |||
| 135 | struct inode * configfs_new_inode(mode_t mode, struct configfs_dirent * sd) | ||
| 52 | { | 136 | { |
| 53 | struct inode * inode = new_inode(configfs_sb); | 137 | struct inode * inode = new_inode(configfs_sb); |
| 54 | if (inode) { | 138 | if (inode) { |
| 55 | inode->i_mode = mode; | ||
| 56 | inode->i_uid = 0; | ||
| 57 | inode->i_gid = 0; | ||
| 58 | inode->i_blksize = PAGE_CACHE_SIZE; | 139 | inode->i_blksize = PAGE_CACHE_SIZE; |
| 59 | inode->i_blocks = 0; | 140 | inode->i_blocks = 0; |
| 60 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
| 61 | inode->i_mapping->a_ops = &configfs_aops; | 141 | inode->i_mapping->a_ops = &configfs_aops; |
| 62 | inode->i_mapping->backing_dev_info = &configfs_backing_dev_info; | 142 | inode->i_mapping->backing_dev_info = &configfs_backing_dev_info; |
| 143 | inode->i_op = &configfs_inode_operations; | ||
| 144 | |||
| 145 | if (sd->s_iattr) { | ||
| 146 | /* sysfs_dirent has non-default attributes | ||
| 147 | * get them for the new inode from persistent copy | ||
| 148 | * in sysfs_dirent | ||
| 149 | */ | ||
| 150 | set_inode_attr(inode, sd->s_iattr); | ||
| 151 | } else | ||
| 152 | set_default_inode_attr(inode, mode); | ||
| 63 | } | 153 | } |
| 64 | return inode; | 154 | return inode; |
| 65 | } | 155 | } |
| @@ -70,7 +160,8 @@ int configfs_create(struct dentry * dentry, int mode, int (*init)(struct inode * | |||
| 70 | struct inode * inode = NULL; | 160 | struct inode * inode = NULL; |
| 71 | if (dentry) { | 161 | if (dentry) { |
| 72 | if (!dentry->d_inode) { | 162 | if (!dentry->d_inode) { |
| 73 | if ((inode = configfs_new_inode(mode))) { | 163 | struct configfs_dirent *sd = dentry->d_fsdata; |
| 164 | if ((inode = configfs_new_inode(mode, sd))) { | ||
| 74 | if (dentry->d_parent && dentry->d_parent->d_inode) { | 165 | if (dentry->d_parent && dentry->d_parent->d_inode) { |
| 75 | struct inode *p_inode = dentry->d_parent->d_inode; | 166 | struct inode *p_inode = dentry->d_parent->d_inode; |
| 76 | p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME; | 167 | p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME; |
| @@ -103,10 +194,9 @@ int configfs_create(struct dentry * dentry, int mode, int (*init)(struct inode * | |||
| 103 | */ | 194 | */ |
| 104 | const unsigned char * configfs_get_name(struct configfs_dirent *sd) | 195 | const unsigned char * configfs_get_name(struct configfs_dirent *sd) |
| 105 | { | 196 | { |
| 106 | struct attribute * attr; | 197 | struct configfs_attribute *attr; |
| 107 | 198 | ||
| 108 | if (!sd || !sd->s_element) | 199 | BUG_ON(!sd || !sd->s_element); |
| 109 | BUG(); | ||
| 110 | 200 | ||
| 111 | /* These always have a dentry, so use that */ | 201 | /* These always have a dentry, so use that */ |
| 112 | if (sd->s_type & (CONFIGFS_DIR | CONFIGFS_ITEM_LINK)) | 202 | if (sd->s_type & (CONFIGFS_DIR | CONFIGFS_ITEM_LINK)) |
| @@ -114,7 +204,7 @@ const unsigned char * configfs_get_name(struct configfs_dirent *sd) | |||
| 114 | 204 | ||
| 115 | if (sd->s_type & CONFIGFS_ITEM_ATTR) { | 205 | if (sd->s_type & CONFIGFS_ITEM_ATTR) { |
| 116 | attr = sd->s_element; | 206 | attr = sd->s_element; |
| 117 | return attr->name; | 207 | return attr->ca_name; |
| 118 | } | 208 | } |
| 119 | return NULL; | 209 | return NULL; |
| 120 | } | 210 | } |
| @@ -130,13 +220,17 @@ void configfs_drop_dentry(struct configfs_dirent * sd, struct dentry * parent) | |||
| 130 | 220 | ||
| 131 | if (dentry) { | 221 | if (dentry) { |
| 132 | spin_lock(&dcache_lock); | 222 | spin_lock(&dcache_lock); |
| 223 | spin_lock(&dentry->d_lock); | ||
| 133 | if (!(d_unhashed(dentry) && dentry->d_inode)) { | 224 | if (!(d_unhashed(dentry) && dentry->d_inode)) { |
| 134 | dget_locked(dentry); | 225 | dget_locked(dentry); |
| 135 | __d_drop(dentry); | 226 | __d_drop(dentry); |
| 227 | spin_unlock(&dentry->d_lock); | ||
| 136 | spin_unlock(&dcache_lock); | 228 | spin_unlock(&dcache_lock); |
| 137 | simple_unlink(parent->d_inode, dentry); | 229 | simple_unlink(parent->d_inode, dentry); |
| 138 | } else | 230 | } else { |
| 231 | spin_unlock(&dentry->d_lock); | ||
| 139 | spin_unlock(&dcache_lock); | 232 | spin_unlock(&dcache_lock); |
| 233 | } | ||
| 140 | } | 234 | } |
| 141 | } | 235 | } |
| 142 | 236 | ||
| @@ -145,6 +239,10 @@ void configfs_hash_and_remove(struct dentry * dir, const char * name) | |||
| 145 | struct configfs_dirent * sd; | 239 | struct configfs_dirent * sd; |
| 146 | struct configfs_dirent * parent_sd = dir->d_fsdata; | 240 | struct configfs_dirent * parent_sd = dir->d_fsdata; |
| 147 | 241 | ||
| 242 | if (dir->d_inode == NULL) | ||
| 243 | /* no inode means this hasn't been made visible yet */ | ||
| 244 | return; | ||
| 245 | |||
| 148 | mutex_lock(&dir->d_inode->i_mutex); | 246 | mutex_lock(&dir->d_inode->i_mutex); |
| 149 | list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { | 247 | list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { |
| 150 | if (!sd->s_element) | 248 | if (!sd->s_element) |
diff --git a/fs/configfs/mount.c b/fs/configfs/mount.c index 1a2f6f6a4d91..f920d30478e5 100644 --- a/fs/configfs/mount.c +++ b/fs/configfs/mount.c | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | 38 | ||
| 39 | struct vfsmount * configfs_mount = NULL; | 39 | struct vfsmount * configfs_mount = NULL; |
| 40 | struct super_block * configfs_sb = NULL; | 40 | struct super_block * configfs_sb = NULL; |
| 41 | kmem_cache_t *configfs_dir_cachep; | ||
| 41 | static int configfs_mnt_count = 0; | 42 | static int configfs_mnt_count = 0; |
| 42 | 43 | ||
| 43 | static struct super_operations configfs_ops = { | 44 | static struct super_operations configfs_ops = { |
| @@ -62,6 +63,7 @@ static struct configfs_dirent configfs_root = { | |||
| 62 | .s_children = LIST_HEAD_INIT(configfs_root.s_children), | 63 | .s_children = LIST_HEAD_INIT(configfs_root.s_children), |
| 63 | .s_element = &configfs_root_group.cg_item, | 64 | .s_element = &configfs_root_group.cg_item, |
| 64 | .s_type = CONFIGFS_ROOT, | 65 | .s_type = CONFIGFS_ROOT, |
| 66 | .s_iattr = NULL, | ||
| 65 | }; | 67 | }; |
| 66 | 68 | ||
| 67 | static int configfs_fill_super(struct super_block *sb, void *data, int silent) | 69 | static int configfs_fill_super(struct super_block *sb, void *data, int silent) |
| @@ -73,9 +75,11 @@ static int configfs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 73 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; | 75 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; |
| 74 | sb->s_magic = CONFIGFS_MAGIC; | 76 | sb->s_magic = CONFIGFS_MAGIC; |
| 75 | sb->s_op = &configfs_ops; | 77 | sb->s_op = &configfs_ops; |
| 78 | sb->s_time_gran = 1; | ||
| 76 | configfs_sb = sb; | 79 | configfs_sb = sb; |
| 77 | 80 | ||
| 78 | inode = configfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO); | 81 | inode = configfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO, |
| 82 | &configfs_root); | ||
| 79 | if (inode) { | 83 | if (inode) { |
| 80 | inode->i_op = &configfs_dir_inode_operations; | 84 | inode->i_op = &configfs_dir_inode_operations; |
| 81 | inode->i_fop = &configfs_dir_operations; | 85 | inode->i_fop = &configfs_dir_operations; |
| @@ -128,19 +132,31 @@ static decl_subsys(config, NULL, NULL); | |||
| 128 | 132 | ||
| 129 | static int __init configfs_init(void) | 133 | static int __init configfs_init(void) |
| 130 | { | 134 | { |
| 131 | int err; | 135 | int err = -ENOMEM; |
| 136 | |||
| 137 | configfs_dir_cachep = kmem_cache_create("configfs_dir_cache", | ||
| 138 | sizeof(struct configfs_dirent), | ||
| 139 | 0, 0, NULL, NULL); | ||
| 140 | if (!configfs_dir_cachep) | ||
| 141 | goto out; | ||
| 132 | 142 | ||
| 133 | kset_set_kset_s(&config_subsys, kernel_subsys); | 143 | kset_set_kset_s(&config_subsys, kernel_subsys); |
| 134 | err = subsystem_register(&config_subsys); | 144 | err = subsystem_register(&config_subsys); |
| 135 | if (err) | 145 | if (err) { |
| 136 | return err; | 146 | kmem_cache_destroy(configfs_dir_cachep); |
| 147 | configfs_dir_cachep = NULL; | ||
| 148 | goto out; | ||
| 149 | } | ||
| 137 | 150 | ||
| 138 | err = register_filesystem(&configfs_fs_type); | 151 | err = register_filesystem(&configfs_fs_type); |
| 139 | if (err) { | 152 | if (err) { |
| 140 | printk(KERN_ERR "configfs: Unable to register filesystem!\n"); | 153 | printk(KERN_ERR "configfs: Unable to register filesystem!\n"); |
| 141 | subsystem_unregister(&config_subsys); | 154 | subsystem_unregister(&config_subsys); |
| 155 | kmem_cache_destroy(configfs_dir_cachep); | ||
| 156 | configfs_dir_cachep = NULL; | ||
| 142 | } | 157 | } |
| 143 | 158 | ||
| 159 | out: | ||
| 144 | return err; | 160 | return err; |
| 145 | } | 161 | } |
| 146 | 162 | ||
| @@ -148,11 +164,13 @@ static void __exit configfs_exit(void) | |||
| 148 | { | 164 | { |
| 149 | unregister_filesystem(&configfs_fs_type); | 165 | unregister_filesystem(&configfs_fs_type); |
| 150 | subsystem_unregister(&config_subsys); | 166 | subsystem_unregister(&config_subsys); |
| 167 | kmem_cache_destroy(configfs_dir_cachep); | ||
| 168 | configfs_dir_cachep = NULL; | ||
| 151 | } | 169 | } |
| 152 | 170 | ||
| 153 | MODULE_AUTHOR("Oracle"); | 171 | MODULE_AUTHOR("Oracle"); |
| 154 | MODULE_LICENSE("GPL"); | 172 | MODULE_LICENSE("GPL"); |
| 155 | MODULE_VERSION("0.0.1"); | 173 | MODULE_VERSION("0.0.2"); |
| 156 | MODULE_DESCRIPTION("Simple RAM filesystem for user driven kernel subsystem configuration."); | 174 | MODULE_DESCRIPTION("Simple RAM filesystem for user driven kernel subsystem configuration."); |
| 157 | 175 | ||
| 158 | module_init(configfs_init); | 176 | module_init(configfs_init); |
diff --git a/fs/configfs/symlink.c b/fs/configfs/symlink.c index 50f5840521a9..e5512e295cf2 100644 --- a/fs/configfs/symlink.c +++ b/fs/configfs/symlink.c | |||
| @@ -162,8 +162,7 @@ int configfs_unlink(struct inode *dir, struct dentry *dentry) | |||
| 162 | if (!(sd->s_type & CONFIGFS_ITEM_LINK)) | 162 | if (!(sd->s_type & CONFIGFS_ITEM_LINK)) |
| 163 | goto out; | 163 | goto out; |
| 164 | 164 | ||
| 165 | if (dentry->d_parent == configfs_sb->s_root) | 165 | BUG_ON(dentry->d_parent == configfs_sb->s_root); |
| 166 | BUG(); | ||
| 167 | 166 | ||
| 168 | sl = sd->s_element; | 167 | sl = sd->s_element; |
| 169 | 168 | ||
| @@ -277,5 +276,6 @@ struct inode_operations configfs_symlink_inode_operations = { | |||
| 277 | .follow_link = configfs_follow_link, | 276 | .follow_link = configfs_follow_link, |
| 278 | .readlink = generic_readlink, | 277 | .readlink = generic_readlink, |
| 279 | .put_link = configfs_put_link, | 278 | .put_link = configfs_put_link, |
| 279 | .setattr = configfs_setattr, | ||
| 280 | }; | 280 | }; |
| 281 | 281 | ||
diff --git a/fs/dcache.c b/fs/dcache.c index 86bdb93789c6..a173bba32666 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
| @@ -743,7 +743,9 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name) | |||
| 743 | dentry->d_op = NULL; | 743 | dentry->d_op = NULL; |
| 744 | dentry->d_fsdata = NULL; | 744 | dentry->d_fsdata = NULL; |
| 745 | dentry->d_mounted = 0; | 745 | dentry->d_mounted = 0; |
| 746 | #ifdef CONFIG_PROFILING | ||
| 746 | dentry->d_cookie = NULL; | 747 | dentry->d_cookie = NULL; |
| 748 | #endif | ||
| 747 | INIT_HLIST_NODE(&dentry->d_hash); | 749 | INIT_HLIST_NODE(&dentry->d_hash); |
| 748 | INIT_LIST_HEAD(&dentry->d_lru); | 750 | INIT_LIST_HEAD(&dentry->d_lru); |
| 749 | INIT_LIST_HEAD(&dentry->d_subdirs); | 751 | INIT_LIST_HEAD(&dentry->d_subdirs); |
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index efc97d9b7860..d575452cd9f7 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c | |||
| @@ -56,7 +56,7 @@ static u64 debugfs_u8_get(void *data) | |||
| 56 | DEFINE_SIMPLE_ATTRIBUTE(fops_u8, debugfs_u8_get, debugfs_u8_set, "%llu\n"); | 56 | DEFINE_SIMPLE_ATTRIBUTE(fops_u8, debugfs_u8_get, debugfs_u8_set, "%llu\n"); |
| 57 | 57 | ||
| 58 | /** | 58 | /** |
| 59 | * debugfs_create_u8 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value. | 59 | * debugfs_create_u8 - create a file in the debugfs filesystem that is used to read and write an unsigned 8 bit value. |
| 60 | * | 60 | * |
| 61 | * @name: a pointer to a string containing the name of the file to create. | 61 | * @name: a pointer to a string containing the name of the file to create. |
| 62 | * @mode: the permission that the file should have | 62 | * @mode: the permission that the file should have |
| @@ -98,7 +98,7 @@ static u64 debugfs_u16_get(void *data) | |||
| 98 | DEFINE_SIMPLE_ATTRIBUTE(fops_u16, debugfs_u16_get, debugfs_u16_set, "%llu\n"); | 98 | DEFINE_SIMPLE_ATTRIBUTE(fops_u16, debugfs_u16_get, debugfs_u16_set, "%llu\n"); |
| 99 | 99 | ||
| 100 | /** | 100 | /** |
| 101 | * debugfs_create_u16 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value. | 101 | * debugfs_create_u16 - create a file in the debugfs filesystem that is used to read and write an unsigned 16 bit value. |
| 102 | * | 102 | * |
| 103 | * @name: a pointer to a string containing the name of the file to create. | 103 | * @name: a pointer to a string containing the name of the file to create. |
| 104 | * @mode: the permission that the file should have | 104 | * @mode: the permission that the file should have |
| @@ -140,7 +140,7 @@ static u64 debugfs_u32_get(void *data) | |||
| 140 | DEFINE_SIMPLE_ATTRIBUTE(fops_u32, debugfs_u32_get, debugfs_u32_set, "%llu\n"); | 140 | DEFINE_SIMPLE_ATTRIBUTE(fops_u32, debugfs_u32_get, debugfs_u32_set, "%llu\n"); |
| 141 | 141 | ||
| 142 | /** | 142 | /** |
| 143 | * debugfs_create_u32 - create a file in the debugfs filesystem that is used to read and write a unsigned 8 bit value. | 143 | * debugfs_create_u32 - create a file in the debugfs filesystem that is used to read and write an unsigned 32 bit value. |
| 144 | * | 144 | * |
| 145 | * @name: a pointer to a string containing the name of the file to create. | 145 | * @name: a pointer to a string containing the name of the file to create. |
| 146 | * @mode: the permission that the file should have | 146 | * @mode: the permission that the file should have |
diff --git a/fs/direct-io.c b/fs/direct-io.c index 30dbbd1df511..848044af7e16 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c | |||
| @@ -857,6 +857,7 @@ do_holes: | |||
| 857 | /* Handle holes */ | 857 | /* Handle holes */ |
| 858 | if (!buffer_mapped(map_bh)) { | 858 | if (!buffer_mapped(map_bh)) { |
| 859 | char *kaddr; | 859 | char *kaddr; |
| 860 | loff_t i_size_aligned; | ||
| 860 | 861 | ||
| 861 | /* AKPM: eargh, -ENOTBLK is a hack */ | 862 | /* AKPM: eargh, -ENOTBLK is a hack */ |
| 862 | if (dio->rw == WRITE) { | 863 | if (dio->rw == WRITE) { |
| @@ -864,8 +865,14 @@ do_holes: | |||
| 864 | return -ENOTBLK; | 865 | return -ENOTBLK; |
| 865 | } | 866 | } |
| 866 | 867 | ||
| 868 | /* | ||
| 869 | * Be sure to account for a partial block as the | ||
| 870 | * last block in the file | ||
| 871 | */ | ||
| 872 | i_size_aligned = ALIGN(i_size_read(dio->inode), | ||
| 873 | 1 << blkbits); | ||
| 867 | if (dio->block_in_file >= | 874 | if (dio->block_in_file >= |
| 868 | i_size_read(dio->inode)>>blkbits) { | 875 | i_size_aligned >> blkbits) { |
| 869 | /* We hit eof */ | 876 | /* We hit eof */ |
| 870 | page_cache_release(page); | 877 | page_cache_release(page); |
| 871 | goto out; | 878 | goto out; |
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index 35acc43b897f..da52b4a5db64 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c | |||
| @@ -220,7 +220,7 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl) | |||
| 220 | struct ext2_inode_info *ei = EXT2_I(inode); | 220 | struct ext2_inode_info *ei = EXT2_I(inode); |
| 221 | int name_index; | 221 | int name_index; |
| 222 | void *value = NULL; | 222 | void *value = NULL; |
| 223 | size_t size; | 223 | size_t size = 0; |
| 224 | int error; | 224 | int error; |
| 225 | 225 | ||
| 226 | if (S_ISLNK(inode->i_mode)) | 226 | if (S_ISLNK(inode->i_mode)) |
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index 74714af4ae69..e52765219e16 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c | |||
| @@ -605,7 +605,7 @@ got: | |||
| 605 | insert_inode_hash(inode); | 605 | insert_inode_hash(inode); |
| 606 | 606 | ||
| 607 | if (DQUOT_ALLOC_INODE(inode)) { | 607 | if (DQUOT_ALLOC_INODE(inode)) { |
| 608 | err = -ENOSPC; | 608 | err = -EDQUOT; |
| 609 | goto fail_drop; | 609 | goto fail_drop; |
| 610 | } | 610 | } |
| 611 | 611 | ||
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 8d6819846fc9..cb6f9bd658de 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
| @@ -221,6 +221,11 @@ static int ext2_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
| 221 | seq_puts(seq, ",grpquota"); | 221 | seq_puts(seq, ",grpquota"); |
| 222 | #endif | 222 | #endif |
| 223 | 223 | ||
| 224 | #if defined(CONFIG_EXT2_FS_XIP) | ||
| 225 | if (sbi->s_mount_opt & EXT2_MOUNT_XIP) | ||
| 226 | seq_puts(seq, ",xip"); | ||
| 227 | #endif | ||
| 228 | |||
| 224 | return 0; | 229 | return 0; |
| 225 | } | 230 | } |
| 226 | 231 | ||
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index 47a9da2dfb4f..0d21d558b87a 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c | |||
| @@ -226,7 +226,7 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type, | |||
| 226 | struct ext3_inode_info *ei = EXT3_I(inode); | 226 | struct ext3_inode_info *ei = EXT3_I(inode); |
| 227 | int name_index; | 227 | int name_index; |
| 228 | void *value = NULL; | 228 | void *value = NULL; |
| 229 | size_t size; | 229 | size_t size = 0; |
| 230 | int error; | 230 | int error; |
| 231 | 231 | ||
| 232 | if (S_ISLNK(inode->i_mode)) | 232 | if (S_ISLNK(inode->i_mode)) |
diff --git a/fs/fat/file.c b/fs/fat/file.c index e99c5a73b39e..88aa1ae13f9f 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c | |||
| @@ -210,10 +210,30 @@ static int fat_free(struct inode *inode, int skip) | |||
| 210 | if (MSDOS_I(inode)->i_start == 0) | 210 | if (MSDOS_I(inode)->i_start == 0) |
| 211 | return 0; | 211 | return 0; |
| 212 | 212 | ||
| 213 | /* | 213 | fat_cache_inval_inode(inode); |
| 214 | * Write a new EOF, and get the remaining cluster chain for freeing. | 214 | |
| 215 | */ | ||
| 216 | wait = IS_DIRSYNC(inode); | 215 | wait = IS_DIRSYNC(inode); |
| 216 | i_start = free_start = MSDOS_I(inode)->i_start; | ||
| 217 | i_logstart = MSDOS_I(inode)->i_logstart; | ||
| 218 | |||
| 219 | /* First, we write the new file size. */ | ||
| 220 | if (!skip) { | ||
| 221 | MSDOS_I(inode)->i_start = 0; | ||
| 222 | MSDOS_I(inode)->i_logstart = 0; | ||
| 223 | } | ||
| 224 | MSDOS_I(inode)->i_attrs |= ATTR_ARCH; | ||
| 225 | inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; | ||
| 226 | if (wait) { | ||
| 227 | err = fat_sync_inode(inode); | ||
| 228 | if (err) { | ||
| 229 | MSDOS_I(inode)->i_start = i_start; | ||
| 230 | MSDOS_I(inode)->i_logstart = i_logstart; | ||
| 231 | return err; | ||
| 232 | } | ||
| 233 | } else | ||
| 234 | mark_inode_dirty(inode); | ||
| 235 | |||
| 236 | /* Write a new EOF, and get the remaining cluster chain for freeing. */ | ||
| 217 | if (skip) { | 237 | if (skip) { |
| 218 | struct fat_entry fatent; | 238 | struct fat_entry fatent; |
| 219 | int ret, fclus, dclus; | 239 | int ret, fclus, dclus; |
| @@ -244,35 +264,11 @@ static int fat_free(struct inode *inode, int skip) | |||
| 244 | return ret; | 264 | return ret; |
| 245 | 265 | ||
| 246 | free_start = ret; | 266 | free_start = ret; |
| 247 | i_start = i_logstart = 0; | ||
| 248 | fat_cache_inval_inode(inode); | ||
| 249 | } else { | ||
| 250 | fat_cache_inval_inode(inode); | ||
| 251 | |||
| 252 | i_start = free_start = MSDOS_I(inode)->i_start; | ||
| 253 | i_logstart = MSDOS_I(inode)->i_logstart; | ||
| 254 | MSDOS_I(inode)->i_start = 0; | ||
| 255 | MSDOS_I(inode)->i_logstart = 0; | ||
| 256 | } | 267 | } |
| 257 | MSDOS_I(inode)->i_attrs |= ATTR_ARCH; | ||
| 258 | inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; | ||
| 259 | if (wait) { | ||
| 260 | err = fat_sync_inode(inode); | ||
| 261 | if (err) | ||
| 262 | goto error; | ||
| 263 | } else | ||
| 264 | mark_inode_dirty(inode); | ||
| 265 | inode->i_blocks = skip << (MSDOS_SB(sb)->cluster_bits - 9); | 268 | inode->i_blocks = skip << (MSDOS_SB(sb)->cluster_bits - 9); |
| 266 | 269 | ||
| 267 | /* Freeing the remained cluster chain */ | 270 | /* Freeing the remained cluster chain */ |
| 268 | return fat_free_clusters(inode, free_start); | 271 | return fat_free_clusters(inode, free_start); |
| 269 | |||
| 270 | error: | ||
| 271 | if (i_start) { | ||
| 272 | MSDOS_I(inode)->i_start = i_start; | ||
| 273 | MSDOS_I(inode)->i_logstart = i_logstart; | ||
| 274 | } | ||
| 275 | return err; | ||
| 276 | } | 272 | } |
| 277 | 273 | ||
| 278 | void fat_truncate(struct inode *inode) | 274 | void fat_truncate(struct inode *inode) |
diff --git a/fs/fat/misc.c b/fs/fat/misc.c index 32fb0a3f1da4..944652e9dde1 100644 --- a/fs/fat/misc.c +++ b/fs/fat/misc.c | |||
| @@ -196,19 +196,9 @@ EXPORT_SYMBOL_GPL(fat_date_unix2dos); | |||
| 196 | 196 | ||
| 197 | int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs) | 197 | int fat_sync_bhs(struct buffer_head **bhs, int nr_bhs) |
| 198 | { | 198 | { |
| 199 | int i, e, err = 0; | 199 | int i, err = 0; |
| 200 | 200 | ||
| 201 | for (i = 0; i < nr_bhs; i++) { | 201 | ll_rw_block(SWRITE, nr_bhs, bhs); |
| 202 | lock_buffer(bhs[i]); | ||
| 203 | if (test_clear_buffer_dirty(bhs[i])) { | ||
| 204 | get_bh(bhs[i]); | ||
| 205 | bhs[i]->b_end_io = end_buffer_write_sync; | ||
| 206 | e = submit_bh(WRITE, bhs[i]); | ||
| 207 | if (!err && e) | ||
| 208 | err = e; | ||
| 209 | } else | ||
| 210 | unlock_buffer(bhs[i]); | ||
| 211 | } | ||
| 212 | for (i = 0; i < nr_bhs; i++) { | 202 | for (i = 0; i < nr_bhs; i++) { |
| 213 | wait_on_buffer(bhs[i]); | 203 | wait_on_buffer(bhs[i]); |
| 214 | if (buffer_eopnotsupp(bhs[i])) { | 204 | if (buffer_eopnotsupp(bhs[i])) { |
diff --git a/fs/fcntl.c b/fs/fcntl.c index 5f96786d1c73..dc4a7007f4e7 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
| @@ -208,8 +208,11 @@ static int setfl(int fd, struct file * filp, unsigned long arg) | |||
| 208 | struct inode * inode = filp->f_dentry->d_inode; | 208 | struct inode * inode = filp->f_dentry->d_inode; |
| 209 | int error = 0; | 209 | int error = 0; |
| 210 | 210 | ||
| 211 | /* O_APPEND cannot be cleared if the file is marked as append-only */ | 211 | /* |
| 212 | if (!(arg & O_APPEND) && IS_APPEND(inode)) | 212 | * O_APPEND cannot be cleared if the file is marked as append-only |
| 213 | * and the file is open for write. | ||
| 214 | */ | ||
| 215 | if (((arg ^ filp->f_flags) & O_APPEND) && IS_APPEND(inode)) | ||
| 213 | return -EPERM; | 216 | return -EPERM; |
| 214 | 217 | ||
| 215 | /* O_NOATIME can only be set by the owner or superuser */ | 218 | /* O_NOATIME can only be set by the owner or superuser */ |
| @@ -379,7 +379,6 @@ static void __devinit fdtable_defer_list_init(int cpu) | |||
| 379 | void __init files_defer_init(void) | 379 | void __init files_defer_init(void) |
| 380 | { | 380 | { |
| 381 | int i; | 381 | int i; |
| 382 | /* Really early - can't use for_each_cpu */ | 382 | for_each_cpu(i) |
| 383 | for (i = 0; i < NR_CPUS; i++) | ||
| 384 | fdtable_defer_list_init(i); | 383 | fdtable_defer_list_init(i); |
| 385 | } | 384 | } |
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 4526da8907c6..f556a0d5c0d3 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
| @@ -120,9 +120,9 @@ struct fuse_req *fuse_get_request(struct fuse_conn *fc) | |||
| 120 | return do_get_request(fc); | 120 | return do_get_request(fc); |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | /* Must be called with fuse_lock held */ | ||
| 123 | static void fuse_putback_request(struct fuse_conn *fc, struct fuse_req *req) | 124 | static void fuse_putback_request(struct fuse_conn *fc, struct fuse_req *req) |
| 124 | { | 125 | { |
| 125 | spin_lock(&fuse_lock); | ||
| 126 | if (req->preallocated) { | 126 | if (req->preallocated) { |
| 127 | atomic_dec(&fc->num_waiting); | 127 | atomic_dec(&fc->num_waiting); |
| 128 | list_add(&req->list, &fc->unused_list); | 128 | list_add(&req->list, &fc->unused_list); |
| @@ -134,11 +134,19 @@ static void fuse_putback_request(struct fuse_conn *fc, struct fuse_req *req) | |||
| 134 | fc->outstanding_debt--; | 134 | fc->outstanding_debt--; |
| 135 | else | 135 | else |
| 136 | up(&fc->outstanding_sem); | 136 | up(&fc->outstanding_sem); |
| 137 | spin_unlock(&fuse_lock); | ||
| 138 | } | 137 | } |
| 139 | 138 | ||
| 140 | void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) | 139 | void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) |
| 141 | { | 140 | { |
| 141 | if (atomic_dec_and_test(&req->count)) { | ||
| 142 | spin_lock(&fuse_lock); | ||
| 143 | fuse_putback_request(fc, req); | ||
| 144 | spin_unlock(&fuse_lock); | ||
| 145 | } | ||
| 146 | } | ||
| 147 | |||
| 148 | static void fuse_put_request_locked(struct fuse_conn *fc, struct fuse_req *req) | ||
| 149 | { | ||
| 142 | if (atomic_dec_and_test(&req->count)) | 150 | if (atomic_dec_and_test(&req->count)) |
| 143 | fuse_putback_request(fc, req); | 151 | fuse_putback_request(fc, req); |
| 144 | } | 152 | } |
| @@ -163,26 +171,36 @@ void fuse_release_background(struct fuse_req *req) | |||
| 163 | * still waiting), the 'end' callback is called if given, else the | 171 | * still waiting), the 'end' callback is called if given, else the |
| 164 | * reference to the request is released | 172 | * reference to the request is released |
| 165 | * | 173 | * |
| 174 | * Releasing extra reference for foreground requests must be done | ||
| 175 | * within the same locked region as setting state to finished. This | ||
| 176 | * is because fuse_reset_request() may be called after request is | ||
| 177 | * finished and it must be the sole possessor. If request is | ||
| 178 | * interrupted and put in the background, it will return with an error | ||
| 179 | * and hence never be reset and reused. | ||
| 180 | * | ||
| 166 | * Called with fuse_lock, unlocks it | 181 | * Called with fuse_lock, unlocks it |
| 167 | */ | 182 | */ |
| 168 | static void request_end(struct fuse_conn *fc, struct fuse_req *req) | 183 | static void request_end(struct fuse_conn *fc, struct fuse_req *req) |
| 169 | { | 184 | { |
| 170 | void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; | ||
| 171 | req->end = NULL; | ||
| 172 | list_del(&req->list); | 185 | list_del(&req->list); |
| 173 | req->state = FUSE_REQ_FINISHED; | 186 | req->state = FUSE_REQ_FINISHED; |
| 174 | spin_unlock(&fuse_lock); | 187 | if (!req->background) { |
| 175 | if (req->background) { | 188 | wake_up(&req->waitq); |
| 189 | fuse_put_request_locked(fc, req); | ||
| 190 | spin_unlock(&fuse_lock); | ||
| 191 | } else { | ||
| 192 | void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; | ||
| 193 | req->end = NULL; | ||
| 194 | spin_unlock(&fuse_lock); | ||
| 176 | down_read(&fc->sbput_sem); | 195 | down_read(&fc->sbput_sem); |
| 177 | if (fc->mounted) | 196 | if (fc->mounted) |
| 178 | fuse_release_background(req); | 197 | fuse_release_background(req); |
| 179 | up_read(&fc->sbput_sem); | 198 | up_read(&fc->sbput_sem); |
| 199 | if (end) | ||
| 200 | end(fc, req); | ||
| 201 | else | ||
| 202 | fuse_put_request(fc, req); | ||
| 180 | } | 203 | } |
| 181 | wake_up(&req->waitq); | ||
| 182 | if (end) | ||
| 183 | end(fc, req); | ||
| 184 | else | ||
| 185 | fuse_put_request(fc, req); | ||
| 186 | } | 204 | } |
| 187 | 205 | ||
| 188 | /* | 206 | /* |
diff --git a/fs/inotify.c b/fs/inotify.c index 878ccca61213..3041503bde02 100644 --- a/fs/inotify.c +++ b/fs/inotify.c | |||
| @@ -967,7 +967,7 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask) | |||
| 967 | mask_add = 1; | 967 | mask_add = 1; |
| 968 | 968 | ||
| 969 | /* don't let user-space set invalid bits: we don't want flags set */ | 969 | /* don't let user-space set invalid bits: we don't want flags set */ |
| 970 | mask &= IN_ALL_EVENTS; | 970 | mask &= IN_ALL_EVENTS | IN_ONESHOT; |
| 971 | if (unlikely(!mask)) { | 971 | if (unlikely(!mask)) { |
| 972 | ret = -EINVAL; | 972 | ret = -EINVAL; |
| 973 | goto out; | 973 | goto out; |
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c index 429f4b263cf1..ca917973c2c0 100644 --- a/fs/jbd/transaction.c +++ b/fs/jbd/transaction.c | |||
| @@ -1308,6 +1308,7 @@ int journal_stop(handle_t *handle) | |||
| 1308 | transaction_t *transaction = handle->h_transaction; | 1308 | transaction_t *transaction = handle->h_transaction; |
| 1309 | journal_t *journal = transaction->t_journal; | 1309 | journal_t *journal = transaction->t_journal; |
| 1310 | int old_handle_count, err; | 1310 | int old_handle_count, err; |
| 1311 | pid_t pid; | ||
| 1311 | 1312 | ||
| 1312 | J_ASSERT(transaction->t_updates > 0); | 1313 | J_ASSERT(transaction->t_updates > 0); |
| 1313 | J_ASSERT(journal_current_handle() == handle); | 1314 | J_ASSERT(journal_current_handle() == handle); |
| @@ -1333,8 +1334,15 @@ int journal_stop(handle_t *handle) | |||
| 1333 | * It doesn't cost much - we're about to run a commit and sleep | 1334 | * It doesn't cost much - we're about to run a commit and sleep |
| 1334 | * on IO anyway. Speeds up many-threaded, many-dir operations | 1335 | * on IO anyway. Speeds up many-threaded, many-dir operations |
| 1335 | * by 30x or more... | 1336 | * by 30x or more... |
| 1337 | * | ||
| 1338 | * But don't do this if this process was the most recent one to | ||
| 1339 | * perform a synchronous write. We do this to detect the case where a | ||
| 1340 | * single process is doing a stream of sync writes. No point in waiting | ||
| 1341 | * for joiners in that case. | ||
| 1336 | */ | 1342 | */ |
| 1337 | if (handle->h_sync) { | 1343 | pid = current->pid; |
| 1344 | if (handle->h_sync && journal->j_last_sync_writer != pid) { | ||
| 1345 | journal->j_last_sync_writer = pid; | ||
| 1338 | do { | 1346 | do { |
| 1339 | old_handle_count = transaction->t_handle_count; | 1347 | old_handle_count = transaction->t_handle_count; |
| 1340 | schedule_timeout_uninterruptible(1); | 1348 | schedule_timeout_uninterruptible(1); |
diff --git a/fs/jffs/intrep.c b/fs/jffs/intrep.c index b2e95421d932..ce7b54b0b2b7 100644 --- a/fs/jffs/intrep.c +++ b/fs/jffs/intrep.c | |||
| @@ -1965,7 +1965,7 @@ retry: | |||
| 1965 | iovec_cnt++; | 1965 | iovec_cnt++; |
| 1966 | 1966 | ||
| 1967 | if (JFFS_GET_PAD_BYTES(raw_inode->nsize)) { | 1967 | if (JFFS_GET_PAD_BYTES(raw_inode->nsize)) { |
| 1968 | static char allff[3]={255,255,255}; | 1968 | static unsigned char allff[3]={255,255,255}; |
| 1969 | /* Add some extra padding if necessary */ | 1969 | /* Add some extra padding if necessary */ |
| 1970 | node_iovec[iovec_cnt].iov_base = allff; | 1970 | node_iovec[iovec_cnt].iov_base = allff; |
| 1971 | node_iovec[iovec_cnt].iov_len = | 1971 | node_iovec[iovec_cnt].iov_len = |
diff --git a/fs/libfs.c b/fs/libfs.c index 63c020e6589e..71fd08fa4103 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
| @@ -388,6 +388,7 @@ int simple_fill_super(struct super_block *s, int magic, struct tree_descr *files | |||
| 388 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 388 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
| 389 | inode->i_op = &simple_dir_inode_operations; | 389 | inode->i_op = &simple_dir_inode_operations; |
| 390 | inode->i_fop = &simple_dir_operations; | 390 | inode->i_fop = &simple_dir_operations; |
| 391 | inode->i_nlink = 2; | ||
| 391 | root = d_alloc_root(inode); | 392 | root = d_alloc_root(inode); |
| 392 | if (!root) { | 393 | if (!root) { |
| 393 | iput(inode); | 394 | iput(inode); |
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index 145524039577..220058d8616d 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c | |||
| @@ -22,12 +22,14 @@ | |||
| 22 | #define NLMDBG_FACILITY NLMDBG_CLIENT | 22 | #define NLMDBG_FACILITY NLMDBG_CLIENT |
| 23 | #define NLMCLNT_GRACE_WAIT (5*HZ) | 23 | #define NLMCLNT_GRACE_WAIT (5*HZ) |
| 24 | #define NLMCLNT_POLL_TIMEOUT (30*HZ) | 24 | #define NLMCLNT_POLL_TIMEOUT (30*HZ) |
| 25 | #define NLMCLNT_MAX_RETRIES 3 | ||
| 25 | 26 | ||
| 26 | static int nlmclnt_test(struct nlm_rqst *, struct file_lock *); | 27 | static int nlmclnt_test(struct nlm_rqst *, struct file_lock *); |
| 27 | static int nlmclnt_lock(struct nlm_rqst *, struct file_lock *); | 28 | static int nlmclnt_lock(struct nlm_rqst *, struct file_lock *); |
| 28 | static int nlmclnt_unlock(struct nlm_rqst *, struct file_lock *); | 29 | static int nlmclnt_unlock(struct nlm_rqst *, struct file_lock *); |
| 29 | static int nlm_stat_to_errno(u32 stat); | 30 | static int nlm_stat_to_errno(u32 stat); |
| 30 | static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *host); | 31 | static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *host); |
| 32 | static int nlmclnt_cancel(struct nlm_host *, int , struct file_lock *); | ||
| 31 | 33 | ||
| 32 | static const struct rpc_call_ops nlmclnt_unlock_ops; | 34 | static const struct rpc_call_ops nlmclnt_unlock_ops; |
| 33 | static const struct rpc_call_ops nlmclnt_cancel_ops; | 35 | static const struct rpc_call_ops nlmclnt_cancel_ops; |
| @@ -598,7 +600,7 @@ out_unblock: | |||
| 598 | nlmclnt_finish_block(req); | 600 | nlmclnt_finish_block(req); |
| 599 | /* Cancel the blocked request if it is still pending */ | 601 | /* Cancel the blocked request if it is still pending */ |
| 600 | if (resp->status == NLM_LCK_BLOCKED) | 602 | if (resp->status == NLM_LCK_BLOCKED) |
| 601 | nlmclnt_cancel(host, fl); | 603 | nlmclnt_cancel(host, req->a_args.block, fl); |
| 602 | out: | 604 | out: |
| 603 | nlmclnt_release_lockargs(req); | 605 | nlmclnt_release_lockargs(req); |
| 604 | return status; | 606 | return status; |
| @@ -728,8 +730,7 @@ static const struct rpc_call_ops nlmclnt_unlock_ops = { | |||
| 728 | * We always use an async RPC call for this in order not to hang a | 730 | * We always use an async RPC call for this in order not to hang a |
| 729 | * process that has been Ctrl-C'ed. | 731 | * process that has been Ctrl-C'ed. |
| 730 | */ | 732 | */ |
| 731 | int | 733 | static int nlmclnt_cancel(struct nlm_host *host, int block, struct file_lock *fl) |
| 732 | nlmclnt_cancel(struct nlm_host *host, struct file_lock *fl) | ||
| 733 | { | 734 | { |
| 734 | struct nlm_rqst *req; | 735 | struct nlm_rqst *req; |
| 735 | unsigned long flags; | 736 | unsigned long flags; |
| @@ -750,6 +751,7 @@ nlmclnt_cancel(struct nlm_host *host, struct file_lock *fl) | |||
| 750 | req->a_flags = RPC_TASK_ASYNC; | 751 | req->a_flags = RPC_TASK_ASYNC; |
| 751 | 752 | ||
| 752 | nlmclnt_setlockargs(req, fl); | 753 | nlmclnt_setlockargs(req, fl); |
| 754 | req->a_args.block = block; | ||
| 753 | 755 | ||
| 754 | status = nlmclnt_async_call(req, NLMPROC_CANCEL, &nlmclnt_cancel_ops); | 756 | status = nlmclnt_async_call(req, NLMPROC_CANCEL, &nlmclnt_cancel_ops); |
| 755 | if (status < 0) { | 757 | if (status < 0) { |
| @@ -801,6 +803,9 @@ die: | |||
| 801 | return; | 803 | return; |
| 802 | 804 | ||
| 803 | retry_cancel: | 805 | retry_cancel: |
| 806 | /* Don't ever retry more than 3 times */ | ||
| 807 | if (req->a_retries++ >= NLMCLNT_MAX_RETRIES) | ||
| 808 | goto die; | ||
| 804 | nlm_rebind_host(req->a_host); | 809 | nlm_rebind_host(req->a_host); |
| 805 | rpc_restart_call(task); | 810 | rpc_restart_call(task); |
| 806 | rpc_delay(task, 30 * HZ); | 811 | rpc_delay(task, 30 * HZ); |
diff --git a/fs/namei.c b/fs/namei.c index 7ac9fb4acb2c..e28de846c591 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -790,7 +790,7 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) | |||
| 790 | 790 | ||
| 791 | inode = nd->dentry->d_inode; | 791 | inode = nd->dentry->d_inode; |
| 792 | if (nd->depth) | 792 | if (nd->depth) |
| 793 | lookup_flags = LOOKUP_FOLLOW; | 793 | lookup_flags = LOOKUP_FOLLOW | (nd->flags & LOOKUP_CONTINUE); |
| 794 | 794 | ||
| 795 | /* At this point we know we have a real path component. */ | 795 | /* At this point we know we have a real path component. */ |
| 796 | for(;;) { | 796 | for(;;) { |
| @@ -885,7 +885,8 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd) | |||
| 885 | last_with_slashes: | 885 | last_with_slashes: |
| 886 | lookup_flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY; | 886 | lookup_flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY; |
| 887 | last_component: | 887 | last_component: |
| 888 | nd->flags &= ~LOOKUP_CONTINUE; | 888 | /* Clear LOOKUP_CONTINUE iff it was previously unset */ |
| 889 | nd->flags &= lookup_flags | ~LOOKUP_CONTINUE; | ||
| 889 | if (lookup_flags & LOOKUP_PARENT) | 890 | if (lookup_flags & LOOKUP_PARENT) |
| 890 | goto lookup_parent; | 891 | goto lookup_parent; |
| 891 | if (this.name[0] == '.') switch (this.len) { | 892 | if (this.name[0] == '.') switch (this.len) { |
| @@ -1069,6 +1070,8 @@ static int fastcall do_path_lookup(int dfd, const char *name, | |||
| 1069 | unsigned int flags, struct nameidata *nd) | 1070 | unsigned int flags, struct nameidata *nd) |
| 1070 | { | 1071 | { |
| 1071 | int retval = 0; | 1072 | int retval = 0; |
| 1073 | int fput_needed; | ||
| 1074 | struct file *file; | ||
| 1072 | 1075 | ||
| 1073 | nd->last_type = LAST_ROOT; /* if there are only slashes... */ | 1076 | nd->last_type = LAST_ROOT; /* if there are only slashes... */ |
| 1074 | nd->flags = flags; | 1077 | nd->flags = flags; |
| @@ -1090,29 +1093,22 @@ static int fastcall do_path_lookup(int dfd, const char *name, | |||
| 1090 | nd->mnt = mntget(current->fs->pwdmnt); | 1093 | nd->mnt = mntget(current->fs->pwdmnt); |
| 1091 | nd->dentry = dget(current->fs->pwd); | 1094 | nd->dentry = dget(current->fs->pwd); |
| 1092 | } else { | 1095 | } else { |
| 1093 | struct file *file; | ||
| 1094 | int fput_needed; | ||
| 1095 | struct dentry *dentry; | 1096 | struct dentry *dentry; |
| 1096 | 1097 | ||
| 1097 | file = fget_light(dfd, &fput_needed); | 1098 | file = fget_light(dfd, &fput_needed); |
| 1098 | if (!file) { | 1099 | retval = -EBADF; |
| 1099 | retval = -EBADF; | 1100 | if (!file) |
| 1100 | goto out_fail; | 1101 | goto unlock_fail; |
| 1101 | } | ||
| 1102 | 1102 | ||
| 1103 | dentry = file->f_dentry; | 1103 | dentry = file->f_dentry; |
| 1104 | 1104 | ||
| 1105 | if (!S_ISDIR(dentry->d_inode->i_mode)) { | 1105 | retval = -ENOTDIR; |
| 1106 | retval = -ENOTDIR; | 1106 | if (!S_ISDIR(dentry->d_inode->i_mode)) |
| 1107 | fput_light(file, fput_needed); | 1107 | goto fput_unlock_fail; |
| 1108 | goto out_fail; | ||
| 1109 | } | ||
| 1110 | 1108 | ||
| 1111 | retval = file_permission(file, MAY_EXEC); | 1109 | retval = file_permission(file, MAY_EXEC); |
| 1112 | if (retval) { | 1110 | if (retval) |
| 1113 | fput_light(file, fput_needed); | 1111 | goto fput_unlock_fail; |
| 1114 | goto out_fail; | ||
| 1115 | } | ||
| 1116 | 1112 | ||
| 1117 | nd->mnt = mntget(file->f_vfsmnt); | 1113 | nd->mnt = mntget(file->f_vfsmnt); |
| 1118 | nd->dentry = dget(dentry); | 1114 | nd->dentry = dget(dentry); |
| @@ -1123,10 +1119,17 @@ static int fastcall do_path_lookup(int dfd, const char *name, | |||
| 1123 | current->total_link_count = 0; | 1119 | current->total_link_count = 0; |
| 1124 | retval = link_path_walk(name, nd); | 1120 | retval = link_path_walk(name, nd); |
| 1125 | out: | 1121 | out: |
| 1126 | if (unlikely(current->audit_context | 1122 | if (likely(retval == 0)) { |
| 1127 | && nd && nd->dentry && nd->dentry->d_inode)) | 1123 | if (unlikely(current->audit_context && nd && nd->dentry && |
| 1124 | nd->dentry->d_inode)) | ||
| 1128 | audit_inode(name, nd->dentry->d_inode, flags); | 1125 | audit_inode(name, nd->dentry->d_inode, flags); |
| 1129 | out_fail: | 1126 | } |
| 1127 | return retval; | ||
| 1128 | |||
| 1129 | fput_unlock_fail: | ||
| 1130 | fput_light(file, fput_needed); | ||
| 1131 | unlock_fail: | ||
| 1132 | read_unlock(¤t->fs->lock); | ||
| 1130 | return retval; | 1133 | return retval; |
| 1131 | } | 1134 | } |
| 1132 | 1135 | ||
diff --git a/fs/namespace.c b/fs/namespace.c index ce97becff461..058a44865beb 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
| @@ -494,7 +494,7 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill) | |||
| 494 | p->mnt_namespace = NULL; | 494 | p->mnt_namespace = NULL; |
| 495 | list_del_init(&p->mnt_child); | 495 | list_del_init(&p->mnt_child); |
| 496 | if (p->mnt_parent != p) | 496 | if (p->mnt_parent != p) |
| 497 | mnt->mnt_mountpoint->d_mounted--; | 497 | p->mnt_mountpoint->d_mounted--; |
| 498 | change_mnt_propagation(p, MS_PRIVATE); | 498 | change_mnt_propagation(p, MS_PRIVATE); |
| 499 | } | 499 | } |
| 500 | } | 500 | } |
| @@ -1325,27 +1325,17 @@ dput_out: | |||
| 1325 | return retval; | 1325 | return retval; |
| 1326 | } | 1326 | } |
| 1327 | 1327 | ||
| 1328 | int copy_namespace(int flags, struct task_struct *tsk) | 1328 | /* |
| 1329 | * Allocate a new namespace structure and populate it with contents | ||
| 1330 | * copied from the namespace of the passed in task structure. | ||
| 1331 | */ | ||
| 1332 | struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs) | ||
| 1329 | { | 1333 | { |
| 1330 | struct namespace *namespace = tsk->namespace; | 1334 | struct namespace *namespace = tsk->namespace; |
| 1331 | struct namespace *new_ns; | 1335 | struct namespace *new_ns; |
| 1332 | struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL; | 1336 | struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL; |
| 1333 | struct fs_struct *fs = tsk->fs; | ||
| 1334 | struct vfsmount *p, *q; | 1337 | struct vfsmount *p, *q; |
| 1335 | 1338 | ||
| 1336 | if (!namespace) | ||
| 1337 | return 0; | ||
| 1338 | |||
| 1339 | get_namespace(namespace); | ||
| 1340 | |||
| 1341 | if (!(flags & CLONE_NEWNS)) | ||
| 1342 | return 0; | ||
| 1343 | |||
| 1344 | if (!capable(CAP_SYS_ADMIN)) { | ||
| 1345 | put_namespace(namespace); | ||
| 1346 | return -EPERM; | ||
| 1347 | } | ||
| 1348 | |||
| 1349 | new_ns = kmalloc(sizeof(struct namespace), GFP_KERNEL); | 1339 | new_ns = kmalloc(sizeof(struct namespace), GFP_KERNEL); |
| 1350 | if (!new_ns) | 1340 | if (!new_ns) |
| 1351 | goto out; | 1341 | goto out; |
| @@ -1396,8 +1386,6 @@ int copy_namespace(int flags, struct task_struct *tsk) | |||
| 1396 | } | 1386 | } |
| 1397 | up_write(&namespace_sem); | 1387 | up_write(&namespace_sem); |
| 1398 | 1388 | ||
| 1399 | tsk->namespace = new_ns; | ||
| 1400 | |||
| 1401 | if (rootmnt) | 1389 | if (rootmnt) |
| 1402 | mntput(rootmnt); | 1390 | mntput(rootmnt); |
| 1403 | if (pwdmnt) | 1391 | if (pwdmnt) |
| @@ -1405,12 +1393,40 @@ int copy_namespace(int flags, struct task_struct *tsk) | |||
| 1405 | if (altrootmnt) | 1393 | if (altrootmnt) |
| 1406 | mntput(altrootmnt); | 1394 | mntput(altrootmnt); |
| 1407 | 1395 | ||
| 1408 | put_namespace(namespace); | 1396 | out: |
| 1409 | return 0; | 1397 | return new_ns; |
| 1398 | } | ||
| 1399 | |||
| 1400 | int copy_namespace(int flags, struct task_struct *tsk) | ||
| 1401 | { | ||
| 1402 | struct namespace *namespace = tsk->namespace; | ||
| 1403 | struct namespace *new_ns; | ||
| 1404 | int err = 0; | ||
| 1405 | |||
| 1406 | if (!namespace) | ||
| 1407 | return 0; | ||
| 1408 | |||
| 1409 | get_namespace(namespace); | ||
| 1410 | |||
| 1411 | if (!(flags & CLONE_NEWNS)) | ||
| 1412 | return 0; | ||
| 1413 | |||
| 1414 | if (!capable(CAP_SYS_ADMIN)) { | ||
| 1415 | err = -EPERM; | ||
| 1416 | goto out; | ||
| 1417 | } | ||
| 1418 | |||
| 1419 | new_ns = dup_namespace(tsk, tsk->fs); | ||
| 1420 | if (!new_ns) { | ||
| 1421 | err = -ENOMEM; | ||
| 1422 | goto out; | ||
| 1423 | } | ||
| 1424 | |||
| 1425 | tsk->namespace = new_ns; | ||
| 1410 | 1426 | ||
| 1411 | out: | 1427 | out: |
| 1412 | put_namespace(namespace); | 1428 | put_namespace(namespace); |
| 1413 | return -ENOMEM; | 1429 | return err; |
| 1414 | } | 1430 | } |
| 1415 | 1431 | ||
| 1416 | asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name, | 1432 | asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name, |
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 10ae377e68ff..04ab2fc360e7 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
| @@ -481,7 +481,7 @@ retry: | |||
| 481 | if (wdata->verf.committed != NFS_FILE_SYNC) { | 481 | if (wdata->verf.committed != NFS_FILE_SYNC) { |
| 482 | need_commit = 1; | 482 | need_commit = 1; |
| 483 | if (memcmp(&first_verf.verifier, &wdata->verf.verifier, | 483 | if (memcmp(&first_verf.verifier, &wdata->verf.verifier, |
| 484 | sizeof(first_verf.verifier))); | 484 | sizeof(first_verf.verifier))) |
| 485 | goto sync_retry; | 485 | goto sync_retry; |
| 486 | } | 486 | } |
| 487 | 487 | ||
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c index e897e00c2c9d..c0a754ecdee6 100644 --- a/fs/nfs/nfsroot.c +++ b/fs/nfs/nfsroot.c | |||
| @@ -465,10 +465,11 @@ static int __init root_nfs_ports(void) | |||
| 465 | "number from server, using default\n"); | 465 | "number from server, using default\n"); |
| 466 | port = nfsd_port; | 466 | port = nfsd_port; |
| 467 | } | 467 | } |
| 468 | nfs_port = htons(port); | 468 | nfs_port = port; |
| 469 | dprintk("Root-NFS: Portmapper on server returned %d " | 469 | dprintk("Root-NFS: Portmapper on server returned %d " |
| 470 | "as nfsd port\n", port); | 470 | "as nfsd port\n", port); |
| 471 | } | 471 | } |
| 472 | nfs_port = htons(nfs_port); | ||
| 472 | 473 | ||
| 473 | if ((port = root_nfs_getport(NFS_MNT_PROGRAM, mountd_ver, proto)) < 0) { | 474 | if ((port = root_nfs_getport(NFS_MNT_PROGRAM, mountd_ver, proto)) < 0) { |
| 474 | printk(KERN_ERR "Root-NFS: Unable to get mountd port " | 475 | printk(KERN_ERR "Root-NFS: Unable to get mountd port " |
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index a00fe8686293..6d63f1d9e5f5 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
| @@ -195,10 +195,12 @@ nfsd4_open(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_open | |||
| 195 | 195 | ||
| 196 | /* Openowner is now set, so sequence id will get bumped. Now we need | 196 | /* Openowner is now set, so sequence id will get bumped. Now we need |
| 197 | * these checks before we do any creates: */ | 197 | * these checks before we do any creates: */ |
| 198 | status = nfserr_grace; | ||
| 198 | if (nfs4_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS) | 199 | if (nfs4_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS) |
| 199 | return nfserr_grace; | 200 | goto out; |
| 201 | status = nfserr_no_grace; | ||
| 200 | if (!nfs4_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) | 202 | if (!nfs4_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) |
| 201 | return nfserr_no_grace; | 203 | goto out; |
| 202 | 204 | ||
| 203 | switch (open->op_claim_type) { | 205 | switch (open->op_claim_type) { |
| 204 | case NFS4_OPEN_CLAIM_DELEGATE_CUR: | 206 | case NFS4_OPEN_CLAIM_DELEGATE_CUR: |
diff --git a/fs/ocfs2/buffer_head_io.c b/fs/ocfs2/buffer_head_io.c index d424041b38e9..bae3d7548bea 100644 --- a/fs/ocfs2/buffer_head_io.c +++ b/fs/ocfs2/buffer_head_io.c | |||
| @@ -58,7 +58,7 @@ int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh, | |||
| 58 | goto out; | 58 | goto out; |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | down(&OCFS2_I(inode)->ip_io_sem); | 61 | mutex_lock(&OCFS2_I(inode)->ip_io_mutex); |
| 62 | 62 | ||
| 63 | lock_buffer(bh); | 63 | lock_buffer(bh); |
| 64 | set_buffer_uptodate(bh); | 64 | set_buffer_uptodate(bh); |
| @@ -82,7 +82,7 @@ int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh, | |||
| 82 | brelse(bh); | 82 | brelse(bh); |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | up(&OCFS2_I(inode)->ip_io_sem); | 85 | mutex_unlock(&OCFS2_I(inode)->ip_io_mutex); |
| 86 | out: | 86 | out: |
| 87 | mlog_exit(ret); | 87 | mlog_exit(ret); |
| 88 | return ret; | 88 | return ret; |
| @@ -125,13 +125,13 @@ int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr, | |||
| 125 | flags &= ~OCFS2_BH_CACHED; | 125 | flags &= ~OCFS2_BH_CACHED; |
| 126 | 126 | ||
| 127 | if (inode) | 127 | if (inode) |
| 128 | down(&OCFS2_I(inode)->ip_io_sem); | 128 | mutex_lock(&OCFS2_I(inode)->ip_io_mutex); |
| 129 | for (i = 0 ; i < nr ; i++) { | 129 | for (i = 0 ; i < nr ; i++) { |
| 130 | if (bhs[i] == NULL) { | 130 | if (bhs[i] == NULL) { |
| 131 | bhs[i] = sb_getblk(sb, block++); | 131 | bhs[i] = sb_getblk(sb, block++); |
| 132 | if (bhs[i] == NULL) { | 132 | if (bhs[i] == NULL) { |
| 133 | if (inode) | 133 | if (inode) |
| 134 | up(&OCFS2_I(inode)->ip_io_sem); | 134 | mutex_unlock(&OCFS2_I(inode)->ip_io_mutex); |
| 135 | status = -EIO; | 135 | status = -EIO; |
| 136 | mlog_errno(status); | 136 | mlog_errno(status); |
| 137 | goto bail; | 137 | goto bail; |
| @@ -220,7 +220,7 @@ int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr, | |||
| 220 | ocfs2_set_buffer_uptodate(inode, bh); | 220 | ocfs2_set_buffer_uptodate(inode, bh); |
| 221 | } | 221 | } |
| 222 | if (inode) | 222 | if (inode) |
| 223 | up(&OCFS2_I(inode)->ip_io_sem); | 223 | mutex_unlock(&OCFS2_I(inode)->ip_io_mutex); |
| 224 | 224 | ||
| 225 | mlog(ML_BH_IO, "block=(%"MLFu64"), nr=(%d), cached=%s\n", block, nr, | 225 | mlog(ML_BH_IO, "block=(%"MLFu64"), nr=(%d), cached=%s\n", block, nr, |
| 226 | (!(flags & OCFS2_BH_CACHED) || ignore_cache) ? "no" : "yes"); | 226 | (!(flags & OCFS2_BH_CACHED) || ignore_cache) ? "no" : "yes"); |
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index 7307ba528913..d08971d29b63 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c | |||
| @@ -917,8 +917,9 @@ static int o2hb_thread(void *data) | |||
| 917 | elapsed_msec = o2hb_elapsed_msecs(&before_hb, &after_hb); | 917 | elapsed_msec = o2hb_elapsed_msecs(&before_hb, &after_hb); |
| 918 | 918 | ||
| 919 | mlog(0, "start = %lu.%lu, end = %lu.%lu, msec = %u\n", | 919 | mlog(0, "start = %lu.%lu, end = %lu.%lu, msec = %u\n", |
| 920 | before_hb.tv_sec, before_hb.tv_usec, | 920 | before_hb.tv_sec, (unsigned long) before_hb.tv_usec, |
| 921 | after_hb.tv_sec, after_hb.tv_usec, elapsed_msec); | 921 | after_hb.tv_sec, (unsigned long) after_hb.tv_usec, |
| 922 | elapsed_msec); | ||
| 922 | 923 | ||
| 923 | if (elapsed_msec < reg->hr_timeout_ms) { | 924 | if (elapsed_msec < reg->hr_timeout_ms) { |
| 924 | /* the kthread api has blocked signals for us so no | 925 | /* the kthread api has blocked signals for us so no |
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index 35d92c01a972..d22d4cf08db1 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c | |||
| @@ -1285,14 +1285,16 @@ static void o2net_idle_timer(unsigned long data) | |||
| 1285 | mlog(ML_NOTICE, "here are some times that might help debug the " | 1285 | mlog(ML_NOTICE, "here are some times that might help debug the " |
| 1286 | "situation: (tmr %ld.%ld now %ld.%ld dr %ld.%ld adv " | 1286 | "situation: (tmr %ld.%ld now %ld.%ld dr %ld.%ld adv " |
| 1287 | "%ld.%ld:%ld.%ld func (%08x:%u) %ld.%ld:%ld.%ld)\n", | 1287 | "%ld.%ld:%ld.%ld func (%08x:%u) %ld.%ld:%ld.%ld)\n", |
| 1288 | sc->sc_tv_timer.tv_sec, sc->sc_tv_timer.tv_usec, | 1288 | sc->sc_tv_timer.tv_sec, (long) sc->sc_tv_timer.tv_usec, |
| 1289 | now.tv_sec, now.tv_usec, | 1289 | now.tv_sec, (long) now.tv_usec, |
| 1290 | sc->sc_tv_data_ready.tv_sec, sc->sc_tv_data_ready.tv_usec, | 1290 | sc->sc_tv_data_ready.tv_sec, (long) sc->sc_tv_data_ready.tv_usec, |
| 1291 | sc->sc_tv_advance_start.tv_sec, sc->sc_tv_advance_start.tv_usec, | 1291 | sc->sc_tv_advance_start.tv_sec, |
| 1292 | sc->sc_tv_advance_stop.tv_sec, sc->sc_tv_advance_stop.tv_usec, | 1292 | (long) sc->sc_tv_advance_start.tv_usec, |
| 1293 | sc->sc_tv_advance_stop.tv_sec, | ||
| 1294 | (long) sc->sc_tv_advance_stop.tv_usec, | ||
| 1293 | sc->sc_msg_key, sc->sc_msg_type, | 1295 | sc->sc_msg_key, sc->sc_msg_type, |
| 1294 | sc->sc_tv_func_start.tv_sec, sc->sc_tv_func_start.tv_usec, | 1296 | sc->sc_tv_func_start.tv_sec, (long) sc->sc_tv_func_start.tv_usec, |
| 1295 | sc->sc_tv_func_stop.tv_sec, sc->sc_tv_func_stop.tv_usec); | 1297 | sc->sc_tv_func_stop.tv_sec, (long) sc->sc_tv_func_stop.tv_usec); |
| 1296 | 1298 | ||
| 1297 | o2net_sc_queue_work(sc, &sc->sc_shutdown_work); | 1299 | o2net_sc_queue_work(sc, &sc->sc_shutdown_work); |
| 1298 | } | 1300 | } |
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h index 3fecba0a6023..42eb53b5293b 100644 --- a/fs/ocfs2/dlm/dlmcommon.h +++ b/fs/ocfs2/dlm/dlmcommon.h | |||
| @@ -657,6 +657,7 @@ void dlm_complete_thread(struct dlm_ctxt *dlm); | |||
| 657 | int dlm_launch_recovery_thread(struct dlm_ctxt *dlm); | 657 | int dlm_launch_recovery_thread(struct dlm_ctxt *dlm); |
| 658 | void dlm_complete_recovery_thread(struct dlm_ctxt *dlm); | 658 | void dlm_complete_recovery_thread(struct dlm_ctxt *dlm); |
| 659 | void dlm_wait_for_recovery(struct dlm_ctxt *dlm); | 659 | void dlm_wait_for_recovery(struct dlm_ctxt *dlm); |
| 660 | int dlm_is_node_dead(struct dlm_ctxt *dlm, u8 node); | ||
| 660 | 661 | ||
| 661 | void dlm_put(struct dlm_ctxt *dlm); | 662 | void dlm_put(struct dlm_ctxt *dlm); |
| 662 | struct dlm_ctxt *dlm_grab(struct dlm_ctxt *dlm); | 663 | struct dlm_ctxt *dlm_grab(struct dlm_ctxt *dlm); |
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index da3c22045f89..6ee30837389c 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c | |||
| @@ -573,8 +573,11 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data) | |||
| 573 | spin_lock(&dlm_domain_lock); | 573 | spin_lock(&dlm_domain_lock); |
| 574 | dlm = __dlm_lookup_domain_full(query->domain, query->name_len); | 574 | dlm = __dlm_lookup_domain_full(query->domain, query->name_len); |
| 575 | /* Once the dlm ctxt is marked as leaving then we don't want | 575 | /* Once the dlm ctxt is marked as leaving then we don't want |
| 576 | * to be put in someone's domain map. */ | 576 | * to be put in someone's domain map. |
| 577 | * Also, explicitly disallow joining at certain troublesome | ||
| 578 | * times (ie. during recovery). */ | ||
| 577 | if (dlm && dlm->dlm_state != DLM_CTXT_LEAVING) { | 579 | if (dlm && dlm->dlm_state != DLM_CTXT_LEAVING) { |
| 580 | int bit = query->node_idx; | ||
| 578 | spin_lock(&dlm->spinlock); | 581 | spin_lock(&dlm->spinlock); |
| 579 | 582 | ||
| 580 | if (dlm->dlm_state == DLM_CTXT_NEW && | 583 | if (dlm->dlm_state == DLM_CTXT_NEW && |
| @@ -586,6 +589,19 @@ static int dlm_query_join_handler(struct o2net_msg *msg, u32 len, void *data) | |||
| 586 | } else if (dlm->joining_node != DLM_LOCK_RES_OWNER_UNKNOWN) { | 589 | } else if (dlm->joining_node != DLM_LOCK_RES_OWNER_UNKNOWN) { |
| 587 | /* Disallow parallel joins. */ | 590 | /* Disallow parallel joins. */ |
| 588 | response = JOIN_DISALLOW; | 591 | response = JOIN_DISALLOW; |
| 592 | } else if (dlm->reco.state & DLM_RECO_STATE_ACTIVE) { | ||
| 593 | mlog(ML_NOTICE, "node %u trying to join, but recovery " | ||
| 594 | "is ongoing.\n", bit); | ||
| 595 | response = JOIN_DISALLOW; | ||
| 596 | } else if (test_bit(bit, dlm->recovery_map)) { | ||
| 597 | mlog(ML_NOTICE, "node %u trying to join, but it " | ||
| 598 | "still needs recovery.\n", bit); | ||
| 599 | response = JOIN_DISALLOW; | ||
| 600 | } else if (test_bit(bit, dlm->domain_map)) { | ||
| 601 | mlog(ML_NOTICE, "node %u trying to join, but it " | ||
| 602 | "is still in the domain! needs recovery?\n", | ||
| 603 | bit); | ||
| 604 | response = JOIN_DISALLOW; | ||
| 589 | } else { | 605 | } else { |
| 590 | /* Alright we're fully a part of this domain | 606 | /* Alright we're fully a part of this domain |
| 591 | * so we keep some state as to who's joining | 607 | * so we keep some state as to who's joining |
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 27e984f7e4cd..a3194fe173d9 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c | |||
| @@ -1050,17 +1050,10 @@ static int dlm_restart_lock_mastery(struct dlm_ctxt *dlm, | |||
| 1050 | node = dlm_bitmap_diff_iter_next(&bdi, &sc); | 1050 | node = dlm_bitmap_diff_iter_next(&bdi, &sc); |
| 1051 | while (node >= 0) { | 1051 | while (node >= 0) { |
| 1052 | if (sc == NODE_UP) { | 1052 | if (sc == NODE_UP) { |
| 1053 | /* a node came up. easy. might not even need | 1053 | /* a node came up. clear any old vote from |
| 1054 | * to talk to it if its node number is higher | 1054 | * the response map and set it in the vote map |
| 1055 | * or if we are already blocked. */ | 1055 | * then restart the mastery. */ |
| 1056 | mlog(0, "node up! %d\n", node); | 1056 | mlog(ML_NOTICE, "node %d up while restarting\n", node); |
| 1057 | if (blocked) | ||
| 1058 | goto next; | ||
| 1059 | |||
| 1060 | if (node > dlm->node_num) { | ||
| 1061 | mlog(0, "node > this node. skipping.\n"); | ||
| 1062 | goto next; | ||
| 1063 | } | ||
| 1064 | 1057 | ||
| 1065 | /* redo the master request, but only for the new node */ | 1058 | /* redo the master request, but only for the new node */ |
| 1066 | mlog(0, "sending request to new node\n"); | 1059 | mlog(0, "sending request to new node\n"); |
| @@ -2005,6 +1998,15 @@ fail: | |||
| 2005 | break; | 1998 | break; |
| 2006 | 1999 | ||
| 2007 | mlog(0, "timed out during migration\n"); | 2000 | mlog(0, "timed out during migration\n"); |
| 2001 | /* avoid hang during shutdown when migrating lockres | ||
| 2002 | * to a node which also goes down */ | ||
| 2003 | if (dlm_is_node_dead(dlm, target)) { | ||
| 2004 | mlog(0, "%s:%.*s: expected migration target %u " | ||
| 2005 | "is no longer up. restarting.\n", | ||
| 2006 | dlm->name, res->lockname.len, | ||
| 2007 | res->lockname.name, target); | ||
| 2008 | ret = -ERESTARTSYS; | ||
| 2009 | } | ||
| 2008 | } | 2010 | } |
| 2009 | if (ret == -ERESTARTSYS) { | 2011 | if (ret == -ERESTARTSYS) { |
| 2010 | /* migration failed, detach and clean up mle */ | 2012 | /* migration failed, detach and clean up mle */ |
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index 0c8eb1093f00..186e9a76aa58 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #include <linux/inet.h> | 39 | #include <linux/inet.h> |
| 40 | #include <linux/timer.h> | 40 | #include <linux/timer.h> |
| 41 | #include <linux/kthread.h> | 41 | #include <linux/kthread.h> |
| 42 | #include <linux/delay.h> | ||
| 42 | 43 | ||
| 43 | 44 | ||
| 44 | #include "cluster/heartbeat.h" | 45 | #include "cluster/heartbeat.h" |
| @@ -256,6 +257,27 @@ static int dlm_recovery_thread(void *data) | |||
| 256 | return 0; | 257 | return 0; |
| 257 | } | 258 | } |
| 258 | 259 | ||
| 260 | /* returns true when the recovery master has contacted us */ | ||
| 261 | static int dlm_reco_master_ready(struct dlm_ctxt *dlm) | ||
| 262 | { | ||
| 263 | int ready; | ||
| 264 | spin_lock(&dlm->spinlock); | ||
| 265 | ready = (dlm->reco.new_master != O2NM_INVALID_NODE_NUM); | ||
| 266 | spin_unlock(&dlm->spinlock); | ||
| 267 | return ready; | ||
| 268 | } | ||
| 269 | |||
| 270 | /* returns true if node is no longer in the domain | ||
| 271 | * could be dead or just not joined */ | ||
| 272 | int dlm_is_node_dead(struct dlm_ctxt *dlm, u8 node) | ||
| 273 | { | ||
| 274 | int dead; | ||
| 275 | spin_lock(&dlm->spinlock); | ||
| 276 | dead = test_bit(node, dlm->domain_map); | ||
| 277 | spin_unlock(&dlm->spinlock); | ||
| 278 | return dead; | ||
| 279 | } | ||
| 280 | |||
| 259 | /* callers of the top-level api calls (dlmlock/dlmunlock) should | 281 | /* callers of the top-level api calls (dlmlock/dlmunlock) should |
| 260 | * block on the dlm->reco.event when recovery is in progress. | 282 | * block on the dlm->reco.event when recovery is in progress. |
| 261 | * the dlm recovery thread will set this state when it begins | 283 | * the dlm recovery thread will set this state when it begins |
| @@ -297,6 +319,7 @@ static void dlm_end_recovery(struct dlm_ctxt *dlm) | |||
| 297 | static int dlm_do_recovery(struct dlm_ctxt *dlm) | 319 | static int dlm_do_recovery(struct dlm_ctxt *dlm) |
| 298 | { | 320 | { |
| 299 | int status = 0; | 321 | int status = 0; |
| 322 | int ret; | ||
| 300 | 323 | ||
| 301 | spin_lock(&dlm->spinlock); | 324 | spin_lock(&dlm->spinlock); |
| 302 | 325 | ||
| @@ -343,10 +366,13 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm) | |||
| 343 | goto master_here; | 366 | goto master_here; |
| 344 | 367 | ||
| 345 | if (dlm->reco.new_master == O2NM_INVALID_NODE_NUM) { | 368 | if (dlm->reco.new_master == O2NM_INVALID_NODE_NUM) { |
| 346 | /* choose a new master */ | 369 | /* choose a new master, returns 0 if this node |
| 347 | if (!dlm_pick_recovery_master(dlm)) { | 370 | * is the master, -EEXIST if it's another node. |
| 371 | * this does not return until a new master is chosen | ||
| 372 | * or recovery completes entirely. */ | ||
| 373 | ret = dlm_pick_recovery_master(dlm); | ||
| 374 | if (!ret) { | ||
| 348 | /* already notified everyone. go. */ | 375 | /* already notified everyone. go. */ |
| 349 | dlm->reco.new_master = dlm->node_num; | ||
| 350 | goto master_here; | 376 | goto master_here; |
| 351 | } | 377 | } |
| 352 | mlog(0, "another node will master this recovery session.\n"); | 378 | mlog(0, "another node will master this recovery session.\n"); |
| @@ -371,8 +397,13 @@ master_here: | |||
| 371 | if (status < 0) { | 397 | if (status < 0) { |
| 372 | mlog(ML_ERROR, "error %d remastering locks for node %u, " | 398 | mlog(ML_ERROR, "error %d remastering locks for node %u, " |
| 373 | "retrying.\n", status, dlm->reco.dead_node); | 399 | "retrying.\n", status, dlm->reco.dead_node); |
| 400 | /* yield a bit to allow any final network messages | ||
| 401 | * to get handled on remaining nodes */ | ||
| 402 | msleep(100); | ||
| 374 | } else { | 403 | } else { |
| 375 | /* success! see if any other nodes need recovery */ | 404 | /* success! see if any other nodes need recovery */ |
| 405 | mlog(0, "DONE mastering recovery of %s:%u here(this=%u)!\n", | ||
| 406 | dlm->name, dlm->reco.dead_node, dlm->node_num); | ||
| 376 | dlm_reset_recovery(dlm); | 407 | dlm_reset_recovery(dlm); |
| 377 | } | 408 | } |
| 378 | dlm_end_recovery(dlm); | 409 | dlm_end_recovery(dlm); |
| @@ -477,7 +508,7 @@ static int dlm_remaster_locks(struct dlm_ctxt *dlm, u8 dead_node) | |||
| 477 | BUG(); | 508 | BUG(); |
| 478 | break; | 509 | break; |
| 479 | case DLM_RECO_NODE_DATA_DEAD: | 510 | case DLM_RECO_NODE_DATA_DEAD: |
| 480 | mlog(0, "node %u died after " | 511 | mlog(ML_NOTICE, "node %u died after " |
| 481 | "requesting recovery info for " | 512 | "requesting recovery info for " |
| 482 | "node %u\n", ndata->node_num, | 513 | "node %u\n", ndata->node_num, |
| 483 | dead_node); | 514 | dead_node); |
| @@ -485,6 +516,19 @@ static int dlm_remaster_locks(struct dlm_ctxt *dlm, u8 dead_node) | |||
| 485 | // start all over | 516 | // start all over |
| 486 | destroy = 1; | 517 | destroy = 1; |
| 487 | status = -EAGAIN; | 518 | status = -EAGAIN; |
| 519 | /* instead of spinning like crazy here, | ||
| 520 | * wait for the domain map to catch up | ||
| 521 | * with the network state. otherwise this | ||
| 522 | * can be hit hundreds of times before | ||
| 523 | * the node is really seen as dead. */ | ||
| 524 | wait_event_timeout(dlm->dlm_reco_thread_wq, | ||
| 525 | dlm_is_node_dead(dlm, | ||
| 526 | ndata->node_num), | ||
| 527 | msecs_to_jiffies(1000)); | ||
| 528 | mlog(0, "waited 1 sec for %u, " | ||
| 529 | "dead? %s\n", ndata->node_num, | ||
| 530 | dlm_is_node_dead(dlm, ndata->node_num) ? | ||
| 531 | "yes" : "no"); | ||
| 488 | goto leave; | 532 | goto leave; |
| 489 | case DLM_RECO_NODE_DATA_RECEIVING: | 533 | case DLM_RECO_NODE_DATA_RECEIVING: |
| 490 | case DLM_RECO_NODE_DATA_REQUESTED: | 534 | case DLM_RECO_NODE_DATA_REQUESTED: |
| @@ -678,11 +722,27 @@ static void dlm_request_all_locks_worker(struct dlm_work_item *item, void *data) | |||
| 678 | dlm = item->dlm; | 722 | dlm = item->dlm; |
| 679 | dead_node = item->u.ral.dead_node; | 723 | dead_node = item->u.ral.dead_node; |
| 680 | reco_master = item->u.ral.reco_master; | 724 | reco_master = item->u.ral.reco_master; |
| 725 | mres = (struct dlm_migratable_lockres *)data; | ||
| 726 | |||
| 727 | if (dead_node != dlm->reco.dead_node || | ||
| 728 | reco_master != dlm->reco.new_master) { | ||
| 729 | /* show extra debug info if the recovery state is messed */ | ||
| 730 | mlog(ML_ERROR, "%s: bad reco state: reco(dead=%u, master=%u), " | ||
| 731 | "request(dead=%u, master=%u)\n", | ||
| 732 | dlm->name, dlm->reco.dead_node, dlm->reco.new_master, | ||
| 733 | dead_node, reco_master); | ||
| 734 | mlog(ML_ERROR, "%s: name=%.*s master=%u locks=%u/%u flags=%u " | ||
| 735 | "entry[0]={c=%"MLFu64",l=%u,f=%u,t=%d,ct=%d,hb=%d,n=%u}\n", | ||
| 736 | dlm->name, mres->lockname_len, mres->lockname, mres->master, | ||
| 737 | mres->num_locks, mres->total_locks, mres->flags, | ||
| 738 | mres->ml[0].cookie, mres->ml[0].list, mres->ml[0].flags, | ||
| 739 | mres->ml[0].type, mres->ml[0].convert_type, | ||
| 740 | mres->ml[0].highest_blocked, mres->ml[0].node); | ||
| 741 | BUG(); | ||
| 742 | } | ||
| 681 | BUG_ON(dead_node != dlm->reco.dead_node); | 743 | BUG_ON(dead_node != dlm->reco.dead_node); |
| 682 | BUG_ON(reco_master != dlm->reco.new_master); | 744 | BUG_ON(reco_master != dlm->reco.new_master); |
| 683 | 745 | ||
| 684 | mres = (struct dlm_migratable_lockres *)data; | ||
| 685 | |||
| 686 | /* lock resources should have already been moved to the | 746 | /* lock resources should have already been moved to the |
| 687 | * dlm->reco.resources list. now move items from that list | 747 | * dlm->reco.resources list. now move items from that list |
| 688 | * to a temp list if the dead owner matches. note that the | 748 | * to a temp list if the dead owner matches. note that the |
| @@ -757,15 +817,18 @@ int dlm_reco_data_done_handler(struct o2net_msg *msg, u32 len, void *data) | |||
| 757 | continue; | 817 | continue; |
| 758 | 818 | ||
| 759 | switch (ndata->state) { | 819 | switch (ndata->state) { |
| 820 | /* should have moved beyond INIT but not to FINALIZE yet */ | ||
| 760 | case DLM_RECO_NODE_DATA_INIT: | 821 | case DLM_RECO_NODE_DATA_INIT: |
| 761 | case DLM_RECO_NODE_DATA_DEAD: | 822 | case DLM_RECO_NODE_DATA_DEAD: |
| 762 | case DLM_RECO_NODE_DATA_DONE: | ||
| 763 | case DLM_RECO_NODE_DATA_FINALIZE_SENT: | 823 | case DLM_RECO_NODE_DATA_FINALIZE_SENT: |
| 764 | mlog(ML_ERROR, "bad ndata state for node %u:" | 824 | mlog(ML_ERROR, "bad ndata state for node %u:" |
| 765 | " state=%d\n", ndata->node_num, | 825 | " state=%d\n", ndata->node_num, |
| 766 | ndata->state); | 826 | ndata->state); |
| 767 | BUG(); | 827 | BUG(); |
| 768 | break; | 828 | break; |
| 829 | /* these states are possible at this point, anywhere along | ||
| 830 | * the line of recovery */ | ||
| 831 | case DLM_RECO_NODE_DATA_DONE: | ||
| 769 | case DLM_RECO_NODE_DATA_RECEIVING: | 832 | case DLM_RECO_NODE_DATA_RECEIVING: |
| 770 | case DLM_RECO_NODE_DATA_REQUESTED: | 833 | case DLM_RECO_NODE_DATA_REQUESTED: |
| 771 | case DLM_RECO_NODE_DATA_REQUESTING: | 834 | case DLM_RECO_NODE_DATA_REQUESTING: |
| @@ -799,13 +862,31 @@ static void dlm_move_reco_locks_to_list(struct dlm_ctxt *dlm, | |||
| 799 | { | 862 | { |
| 800 | struct dlm_lock_resource *res; | 863 | struct dlm_lock_resource *res; |
| 801 | struct list_head *iter, *iter2; | 864 | struct list_head *iter, *iter2; |
| 865 | struct dlm_lock *lock; | ||
| 802 | 866 | ||
| 803 | spin_lock(&dlm->spinlock); | 867 | spin_lock(&dlm->spinlock); |
| 804 | list_for_each_safe(iter, iter2, &dlm->reco.resources) { | 868 | list_for_each_safe(iter, iter2, &dlm->reco.resources) { |
| 805 | res = list_entry (iter, struct dlm_lock_resource, recovering); | 869 | res = list_entry (iter, struct dlm_lock_resource, recovering); |
| 870 | /* always prune any $RECOVERY entries for dead nodes, | ||
| 871 | * otherwise hangs can occur during later recovery */ | ||
| 806 | if (dlm_is_recovery_lock(res->lockname.name, | 872 | if (dlm_is_recovery_lock(res->lockname.name, |
| 807 | res->lockname.len)) | 873 | res->lockname.len)) { |
| 874 | spin_lock(&res->spinlock); | ||
| 875 | list_for_each_entry(lock, &res->granted, list) { | ||
| 876 | if (lock->ml.node == dead_node) { | ||
| 877 | mlog(0, "AHA! there was " | ||
| 878 | "a $RECOVERY lock for dead " | ||
| 879 | "node %u (%s)!\n", | ||
| 880 | dead_node, dlm->name); | ||
| 881 | list_del_init(&lock->list); | ||
| 882 | dlm_lock_put(lock); | ||
| 883 | break; | ||
| 884 | } | ||
| 885 | } | ||
| 886 | spin_unlock(&res->spinlock); | ||
| 808 | continue; | 887 | continue; |
| 888 | } | ||
| 889 | |||
| 809 | if (res->owner == dead_node) { | 890 | if (res->owner == dead_node) { |
| 810 | mlog(0, "found lockres owned by dead node while " | 891 | mlog(0, "found lockres owned by dead node while " |
| 811 | "doing recovery for node %u. sending it.\n", | 892 | "doing recovery for node %u. sending it.\n", |
| @@ -1179,7 +1260,7 @@ static void dlm_mig_lockres_worker(struct dlm_work_item *item, void *data) | |||
| 1179 | again: | 1260 | again: |
| 1180 | ret = dlm_lockres_master_requery(dlm, res, &real_master); | 1261 | ret = dlm_lockres_master_requery(dlm, res, &real_master); |
| 1181 | if (ret < 0) { | 1262 | if (ret < 0) { |
| 1182 | mlog(0, "dlm_lockres_master_requery failure: %d\n", | 1263 | mlog(0, "dlm_lockres_master_requery ret=%d\n", |
| 1183 | ret); | 1264 | ret); |
| 1184 | goto again; | 1265 | goto again; |
| 1185 | } | 1266 | } |
| @@ -1757,6 +1838,7 @@ static void dlm_do_local_recovery_cleanup(struct dlm_ctxt *dlm, u8 dead_node) | |||
| 1757 | struct dlm_lock_resource *res; | 1838 | struct dlm_lock_resource *res; |
| 1758 | int i; | 1839 | int i; |
| 1759 | struct list_head *bucket; | 1840 | struct list_head *bucket; |
| 1841 | struct dlm_lock *lock; | ||
| 1760 | 1842 | ||
| 1761 | 1843 | ||
| 1762 | /* purge any stale mles */ | 1844 | /* purge any stale mles */ |
| @@ -1780,10 +1862,25 @@ static void dlm_do_local_recovery_cleanup(struct dlm_ctxt *dlm, u8 dead_node) | |||
| 1780 | bucket = &(dlm->resources[i]); | 1862 | bucket = &(dlm->resources[i]); |
| 1781 | list_for_each(iter, bucket) { | 1863 | list_for_each(iter, bucket) { |
| 1782 | res = list_entry (iter, struct dlm_lock_resource, list); | 1864 | res = list_entry (iter, struct dlm_lock_resource, list); |
| 1865 | /* always prune any $RECOVERY entries for dead nodes, | ||
| 1866 | * otherwise hangs can occur during later recovery */ | ||
| 1783 | if (dlm_is_recovery_lock(res->lockname.name, | 1867 | if (dlm_is_recovery_lock(res->lockname.name, |
| 1784 | res->lockname.len)) | 1868 | res->lockname.len)) { |
| 1869 | spin_lock(&res->spinlock); | ||
| 1870 | list_for_each_entry(lock, &res->granted, list) { | ||
| 1871 | if (lock->ml.node == dead_node) { | ||
| 1872 | mlog(0, "AHA! there was " | ||
| 1873 | "a $RECOVERY lock for dead " | ||
| 1874 | "node %u (%s)!\n", | ||
| 1875 | dead_node, dlm->name); | ||
| 1876 | list_del_init(&lock->list); | ||
| 1877 | dlm_lock_put(lock); | ||
| 1878 | break; | ||
| 1879 | } | ||
| 1880 | } | ||
| 1881 | spin_unlock(&res->spinlock); | ||
| 1785 | continue; | 1882 | continue; |
| 1786 | 1883 | } | |
| 1787 | spin_lock(&res->spinlock); | 1884 | spin_lock(&res->spinlock); |
| 1788 | /* zero the lvb if necessary */ | 1885 | /* zero the lvb if necessary */ |
| 1789 | dlm_revalidate_lvb(dlm, res, dead_node); | 1886 | dlm_revalidate_lvb(dlm, res, dead_node); |
| @@ -1869,12 +1966,9 @@ void dlm_hb_node_up_cb(struct o2nm_node *node, int idx, void *data) | |||
| 1869 | return; | 1966 | return; |
| 1870 | 1967 | ||
| 1871 | spin_lock(&dlm->spinlock); | 1968 | spin_lock(&dlm->spinlock); |
| 1872 | |||
| 1873 | set_bit(idx, dlm->live_nodes_map); | 1969 | set_bit(idx, dlm->live_nodes_map); |
| 1874 | 1970 | /* do NOT notify mle attached to the heartbeat events. | |
| 1875 | /* notify any mles attached to the heartbeat events */ | 1971 | * new nodes are not interesting in mastery until joined. */ |
| 1876 | dlm_hb_event_notify_attached(dlm, idx, 1); | ||
| 1877 | |||
| 1878 | spin_unlock(&dlm->spinlock); | 1972 | spin_unlock(&dlm->spinlock); |
| 1879 | 1973 | ||
| 1880 | dlm_put(dlm); | 1974 | dlm_put(dlm); |
| @@ -1897,7 +1991,18 @@ static void dlm_reco_unlock_ast(void *astdata, enum dlm_status st) | |||
| 1897 | mlog(0, "unlockast for recovery lock fired!\n"); | 1991 | mlog(0, "unlockast for recovery lock fired!\n"); |
| 1898 | } | 1992 | } |
| 1899 | 1993 | ||
| 1900 | 1994 | /* | |
| 1995 | * dlm_pick_recovery_master will continually attempt to use | ||
| 1996 | * dlmlock() on the special "$RECOVERY" lockres with the | ||
| 1997 | * LKM_NOQUEUE flag to get an EX. every thread that enters | ||
| 1998 | * this function on each node racing to become the recovery | ||
| 1999 | * master will not stop attempting this until either: | ||
| 2000 | * a) this node gets the EX (and becomes the recovery master), | ||
| 2001 | * or b) dlm->reco.new_master gets set to some nodenum | ||
| 2002 | * != O2NM_INVALID_NODE_NUM (another node will do the reco). | ||
| 2003 | * so each time a recovery master is needed, the entire cluster | ||
| 2004 | * will sync at this point. if the new master dies, that will | ||
| 2005 | * be detected in dlm_do_recovery */ | ||
| 1901 | static int dlm_pick_recovery_master(struct dlm_ctxt *dlm) | 2006 | static int dlm_pick_recovery_master(struct dlm_ctxt *dlm) |
| 1902 | { | 2007 | { |
| 1903 | enum dlm_status ret; | 2008 | enum dlm_status ret; |
| @@ -1906,23 +2011,45 @@ static int dlm_pick_recovery_master(struct dlm_ctxt *dlm) | |||
| 1906 | 2011 | ||
| 1907 | mlog(0, "starting recovery of %s at %lu, dead=%u, this=%u\n", | 2012 | mlog(0, "starting recovery of %s at %lu, dead=%u, this=%u\n", |
| 1908 | dlm->name, jiffies, dlm->reco.dead_node, dlm->node_num); | 2013 | dlm->name, jiffies, dlm->reco.dead_node, dlm->node_num); |
| 1909 | retry: | 2014 | again: |
| 1910 | memset(&lksb, 0, sizeof(lksb)); | 2015 | memset(&lksb, 0, sizeof(lksb)); |
| 1911 | 2016 | ||
| 1912 | ret = dlmlock(dlm, LKM_EXMODE, &lksb, LKM_NOQUEUE|LKM_RECOVERY, | 2017 | ret = dlmlock(dlm, LKM_EXMODE, &lksb, LKM_NOQUEUE|LKM_RECOVERY, |
| 1913 | DLM_RECOVERY_LOCK_NAME, dlm_reco_ast, dlm, dlm_reco_bast); | 2018 | DLM_RECOVERY_LOCK_NAME, dlm_reco_ast, dlm, dlm_reco_bast); |
| 1914 | 2019 | ||
| 2020 | mlog(0, "%s: dlmlock($RECOVERY) returned %d, lksb=%d\n", | ||
| 2021 | dlm->name, ret, lksb.status); | ||
| 2022 | |||
| 1915 | if (ret == DLM_NORMAL) { | 2023 | if (ret == DLM_NORMAL) { |
| 1916 | mlog(0, "dlm=%s dlmlock says I got it (this=%u)\n", | 2024 | mlog(0, "dlm=%s dlmlock says I got it (this=%u)\n", |
| 1917 | dlm->name, dlm->node_num); | 2025 | dlm->name, dlm->node_num); |
| 1918 | /* I am master, send message to all nodes saying | 2026 | |
| 1919 | * that I am beginning a recovery session */ | 2027 | /* got the EX lock. check to see if another node |
| 1920 | status = dlm_send_begin_reco_message(dlm, | 2028 | * just became the reco master */ |
| 1921 | dlm->reco.dead_node); | 2029 | if (dlm_reco_master_ready(dlm)) { |
| 2030 | mlog(0, "%s: got reco EX lock, but %u will " | ||
| 2031 | "do the recovery\n", dlm->name, | ||
| 2032 | dlm->reco.new_master); | ||
| 2033 | status = -EEXIST; | ||
| 2034 | } else { | ||
| 2035 | status = dlm_send_begin_reco_message(dlm, | ||
| 2036 | dlm->reco.dead_node); | ||
| 2037 | /* this always succeeds */ | ||
| 2038 | BUG_ON(status); | ||
| 2039 | |||
| 2040 | /* set the new_master to this node */ | ||
| 2041 | spin_lock(&dlm->spinlock); | ||
| 2042 | dlm->reco.new_master = dlm->node_num; | ||
| 2043 | spin_unlock(&dlm->spinlock); | ||
| 2044 | } | ||
| 1922 | 2045 | ||
| 1923 | /* recovery lock is a special case. ast will not get fired, | 2046 | /* recovery lock is a special case. ast will not get fired, |
| 1924 | * so just go ahead and unlock it. */ | 2047 | * so just go ahead and unlock it. */ |
| 1925 | ret = dlmunlock(dlm, &lksb, 0, dlm_reco_unlock_ast, dlm); | 2048 | ret = dlmunlock(dlm, &lksb, 0, dlm_reco_unlock_ast, dlm); |
| 2049 | if (ret == DLM_DENIED) { | ||
| 2050 | mlog(0, "got DLM_DENIED, trying LKM_CANCEL\n"); | ||
| 2051 | ret = dlmunlock(dlm, &lksb, LKM_CANCEL, dlm_reco_unlock_ast, dlm); | ||
| 2052 | } | ||
| 1926 | if (ret != DLM_NORMAL) { | 2053 | if (ret != DLM_NORMAL) { |
| 1927 | /* this would really suck. this could only happen | 2054 | /* this would really suck. this could only happen |
| 1928 | * if there was a network error during the unlock | 2055 | * if there was a network error during the unlock |
| @@ -1930,20 +2057,42 @@ retry: | |||
| 1930 | * is actually "done" and the lock structure is | 2057 | * is actually "done" and the lock structure is |
| 1931 | * even freed. we can continue, but only | 2058 | * even freed. we can continue, but only |
| 1932 | * because this specific lock name is special. */ | 2059 | * because this specific lock name is special. */ |
| 1933 | mlog(0, "dlmunlock returned %d\n", ret); | 2060 | mlog(ML_ERROR, "dlmunlock returned %d\n", ret); |
| 1934 | } | ||
| 1935 | |||
| 1936 | if (status < 0) { | ||
| 1937 | mlog(0, "failed to send recovery message. " | ||
| 1938 | "must retry with new node map.\n"); | ||
| 1939 | goto retry; | ||
| 1940 | } | 2061 | } |
| 1941 | } else if (ret == DLM_NOTQUEUED) { | 2062 | } else if (ret == DLM_NOTQUEUED) { |
| 1942 | mlog(0, "dlm=%s dlmlock says another node got it (this=%u)\n", | 2063 | mlog(0, "dlm=%s dlmlock says another node got it (this=%u)\n", |
| 1943 | dlm->name, dlm->node_num); | 2064 | dlm->name, dlm->node_num); |
| 1944 | /* another node is master. wait on | 2065 | /* another node is master. wait on |
| 1945 | * reco.new_master != O2NM_INVALID_NODE_NUM */ | 2066 | * reco.new_master != O2NM_INVALID_NODE_NUM |
| 2067 | * for at most one second */ | ||
| 2068 | wait_event_timeout(dlm->dlm_reco_thread_wq, | ||
| 2069 | dlm_reco_master_ready(dlm), | ||
| 2070 | msecs_to_jiffies(1000)); | ||
| 2071 | if (!dlm_reco_master_ready(dlm)) { | ||
| 2072 | mlog(0, "%s: reco master taking awhile\n", | ||
| 2073 | dlm->name); | ||
| 2074 | goto again; | ||
| 2075 | } | ||
| 2076 | /* another node has informed this one that it is reco master */ | ||
| 2077 | mlog(0, "%s: reco master %u is ready to recover %u\n", | ||
| 2078 | dlm->name, dlm->reco.new_master, dlm->reco.dead_node); | ||
| 1946 | status = -EEXIST; | 2079 | status = -EEXIST; |
| 2080 | } else { | ||
| 2081 | struct dlm_lock_resource *res; | ||
| 2082 | |||
| 2083 | /* dlmlock returned something other than NOTQUEUED or NORMAL */ | ||
| 2084 | mlog(ML_ERROR, "%s: got %s from dlmlock($RECOVERY), " | ||
| 2085 | "lksb.status=%s\n", dlm->name, dlm_errname(ret), | ||
| 2086 | dlm_errname(lksb.status)); | ||
| 2087 | res = dlm_lookup_lockres(dlm, DLM_RECOVERY_LOCK_NAME, | ||
| 2088 | DLM_RECOVERY_LOCK_NAME_LEN); | ||
| 2089 | if (res) { | ||
| 2090 | dlm_print_one_lock_resource(res); | ||
| 2091 | dlm_lockres_put(res); | ||
| 2092 | } else { | ||
| 2093 | mlog(ML_ERROR, "recovery lock not found\n"); | ||
| 2094 | } | ||
| 2095 | BUG(); | ||
| 1947 | } | 2096 | } |
| 1948 | 2097 | ||
| 1949 | return status; | 2098 | return status; |
| @@ -1982,7 +2131,7 @@ static int dlm_send_begin_reco_message(struct dlm_ctxt *dlm, u8 dead_node) | |||
| 1982 | mlog(0, "not sending begin reco to self\n"); | 2131 | mlog(0, "not sending begin reco to self\n"); |
| 1983 | continue; | 2132 | continue; |
| 1984 | } | 2133 | } |
| 1985 | 2134 | retry: | |
| 1986 | ret = -EINVAL; | 2135 | ret = -EINVAL; |
| 1987 | mlog(0, "attempting to send begin reco msg to %d\n", | 2136 | mlog(0, "attempting to send begin reco msg to %d\n", |
| 1988 | nodenum); | 2137 | nodenum); |
| @@ -1991,8 +2140,17 @@ static int dlm_send_begin_reco_message(struct dlm_ctxt *dlm, u8 dead_node) | |||
| 1991 | /* negative status is handled ok by caller here */ | 2140 | /* negative status is handled ok by caller here */ |
| 1992 | if (ret >= 0) | 2141 | if (ret >= 0) |
| 1993 | ret = status; | 2142 | ret = status; |
| 2143 | if (dlm_is_host_down(ret)) { | ||
| 2144 | /* node is down. not involved in recovery | ||
| 2145 | * so just keep going */ | ||
| 2146 | mlog(0, "%s: node %u was down when sending " | ||
| 2147 | "begin reco msg (%d)\n", dlm->name, nodenum, ret); | ||
| 2148 | ret = 0; | ||
| 2149 | } | ||
| 1994 | if (ret < 0) { | 2150 | if (ret < 0) { |
| 1995 | struct dlm_lock_resource *res; | 2151 | struct dlm_lock_resource *res; |
| 2152 | /* this is now a serious problem, possibly ENOMEM | ||
| 2153 | * in the network stack. must retry */ | ||
| 1996 | mlog_errno(ret); | 2154 | mlog_errno(ret); |
| 1997 | mlog(ML_ERROR, "begin reco of dlm %s to node %u " | 2155 | mlog(ML_ERROR, "begin reco of dlm %s to node %u " |
| 1998 | " returned %d\n", dlm->name, nodenum, ret); | 2156 | " returned %d\n", dlm->name, nodenum, ret); |
| @@ -2004,7 +2162,10 @@ static int dlm_send_begin_reco_message(struct dlm_ctxt *dlm, u8 dead_node) | |||
| 2004 | } else { | 2162 | } else { |
| 2005 | mlog(ML_ERROR, "recovery lock not found\n"); | 2163 | mlog(ML_ERROR, "recovery lock not found\n"); |
| 2006 | } | 2164 | } |
| 2007 | break; | 2165 | /* sleep for a bit in hopes that we can avoid |
| 2166 | * another ENOMEM */ | ||
| 2167 | msleep(100); | ||
| 2168 | goto retry; | ||
| 2008 | } | 2169 | } |
| 2009 | } | 2170 | } |
| 2010 | 2171 | ||
| @@ -2027,19 +2188,34 @@ int dlm_begin_reco_handler(struct o2net_msg *msg, u32 len, void *data) | |||
| 2027 | 2188 | ||
| 2028 | spin_lock(&dlm->spinlock); | 2189 | spin_lock(&dlm->spinlock); |
| 2029 | if (dlm->reco.new_master != O2NM_INVALID_NODE_NUM) { | 2190 | if (dlm->reco.new_master != O2NM_INVALID_NODE_NUM) { |
| 2030 | mlog(0, "new_master already set to %u!\n", | 2191 | if (test_bit(dlm->reco.new_master, dlm->recovery_map)) { |
| 2031 | dlm->reco.new_master); | 2192 | mlog(0, "%s: new_master %u died, changing " |
| 2193 | "to %u\n", dlm->name, dlm->reco.new_master, | ||
| 2194 | br->node_idx); | ||
| 2195 | } else { | ||
| 2196 | mlog(0, "%s: new_master %u NOT DEAD, changing " | ||
| 2197 | "to %u\n", dlm->name, dlm->reco.new_master, | ||
| 2198 | br->node_idx); | ||
| 2199 | /* may not have seen the new master as dead yet */ | ||
| 2200 | } | ||
| 2032 | } | 2201 | } |
| 2033 | if (dlm->reco.dead_node != O2NM_INVALID_NODE_NUM) { | 2202 | if (dlm->reco.dead_node != O2NM_INVALID_NODE_NUM) { |
| 2034 | mlog(0, "dead_node already set to %u!\n", | 2203 | mlog(ML_NOTICE, "%s: dead_node previously set to %u, " |
| 2035 | dlm->reco.dead_node); | 2204 | "node %u changing it to %u\n", dlm->name, |
| 2205 | dlm->reco.dead_node, br->node_idx, br->dead_node); | ||
| 2036 | } | 2206 | } |
| 2037 | dlm->reco.new_master = br->node_idx; | 2207 | dlm->reco.new_master = br->node_idx; |
| 2038 | dlm->reco.dead_node = br->dead_node; | 2208 | dlm->reco.dead_node = br->dead_node; |
| 2039 | if (!test_bit(br->dead_node, dlm->recovery_map)) { | 2209 | if (!test_bit(br->dead_node, dlm->recovery_map)) { |
| 2040 | mlog(ML_ERROR, "recovery master %u sees %u as dead, but this " | 2210 | mlog(0, "recovery master %u sees %u as dead, but this " |
| 2041 | "node has not yet. marking %u as dead\n", | 2211 | "node has not yet. marking %u as dead\n", |
| 2042 | br->node_idx, br->dead_node, br->dead_node); | 2212 | br->node_idx, br->dead_node, br->dead_node); |
| 2213 | if (!test_bit(br->dead_node, dlm->domain_map) || | ||
| 2214 | !test_bit(br->dead_node, dlm->live_nodes_map)) | ||
| 2215 | mlog(0, "%u not in domain/live_nodes map " | ||
| 2216 | "so setting it in reco map manually\n", | ||
| 2217 | br->dead_node); | ||
| 2218 | set_bit(br->dead_node, dlm->recovery_map); | ||
| 2043 | __dlm_hb_node_down(dlm, br->dead_node); | 2219 | __dlm_hb_node_down(dlm, br->dead_node); |
| 2044 | } | 2220 | } |
| 2045 | spin_unlock(&dlm->spinlock); | 2221 | spin_unlock(&dlm->spinlock); |
diff --git a/fs/ocfs2/dlm/dlmunlock.c b/fs/ocfs2/dlm/dlmunlock.c index cec2ce1cd318..c95f08d2e925 100644 --- a/fs/ocfs2/dlm/dlmunlock.c +++ b/fs/ocfs2/dlm/dlmunlock.c | |||
| @@ -188,6 +188,19 @@ static enum dlm_status dlmunlock_common(struct dlm_ctxt *dlm, | |||
| 188 | actions &= ~(DLM_UNLOCK_REMOVE_LOCK| | 188 | actions &= ~(DLM_UNLOCK_REMOVE_LOCK| |
| 189 | DLM_UNLOCK_REGRANT_LOCK| | 189 | DLM_UNLOCK_REGRANT_LOCK| |
| 190 | DLM_UNLOCK_CLEAR_CONVERT_TYPE); | 190 | DLM_UNLOCK_CLEAR_CONVERT_TYPE); |
| 191 | } else if (status == DLM_RECOVERING || | ||
| 192 | status == DLM_MIGRATING || | ||
| 193 | status == DLM_FORWARD) { | ||
| 194 | /* must clear the actions because this unlock | ||
| 195 | * is about to be retried. cannot free or do | ||
| 196 | * any list manipulation. */ | ||
| 197 | mlog(0, "%s:%.*s: clearing actions, %s\n", | ||
| 198 | dlm->name, res->lockname.len, | ||
| 199 | res->lockname.name, | ||
| 200 | status==DLM_RECOVERING?"recovering": | ||
| 201 | (status==DLM_MIGRATING?"migrating": | ||
| 202 | "forward")); | ||
| 203 | actions = 0; | ||
| 191 | } | 204 | } |
| 192 | if (flags & LKM_CANCEL) | 205 | if (flags & LKM_CANCEL) |
| 193 | lock->cancel_pending = 0; | 206 | lock->cancel_pending = 0; |
diff --git a/fs/ocfs2/dlm/userdlm.c b/fs/ocfs2/dlm/userdlm.c index e1fdd288796e..c3764f4744ee 100644 --- a/fs/ocfs2/dlm/userdlm.c +++ b/fs/ocfs2/dlm/userdlm.c | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | * Boston, MA 021110-1307, USA. | 27 | * Boston, MA 021110-1307, USA. |
| 28 | */ | 28 | */ |
| 29 | 29 | ||
| 30 | #include <asm/signal.h> | 30 | #include <linux/signal.h> |
| 31 | 31 | ||
| 32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
| 33 | #include <linux/fs.h> | 33 | #include <linux/fs.h> |
diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c index f2fb40cd296a..b6ba292e9544 100644 --- a/fs/ocfs2/extent_map.c +++ b/fs/ocfs2/extent_map.c | |||
| @@ -262,8 +262,7 @@ static int ocfs2_extent_map_find_leaf(struct inode *inode, | |||
| 262 | el = &eb->h_list; | 262 | el = &eb->h_list; |
| 263 | } | 263 | } |
| 264 | 264 | ||
| 265 | if (el->l_tree_depth) | 265 | BUG_ON(el->l_tree_depth); |
| 266 | BUG(); | ||
| 267 | 266 | ||
| 268 | for (i = 0; i < le16_to_cpu(el->l_next_free_rec); i++) { | 267 | for (i = 0; i < le16_to_cpu(el->l_next_free_rec); i++) { |
| 269 | rec = &el->l_recs[i]; | 268 | rec = &el->l_recs[i]; |
| @@ -364,8 +363,8 @@ static int ocfs2_extent_map_lookup_read(struct inode *inode, | |||
| 364 | return ret; | 363 | return ret; |
| 365 | } | 364 | } |
| 366 | 365 | ||
| 367 | if (ent->e_tree_depth) | 366 | /* FIXME: Make sure this isn't a corruption */ |
| 368 | BUG(); /* FIXME: Make sure this isn't a corruption */ | 367 | BUG_ON(ent->e_tree_depth); |
| 369 | 368 | ||
| 370 | *ret_ent = ent; | 369 | *ret_ent = ent; |
| 371 | 370 | ||
| @@ -423,8 +422,7 @@ static int ocfs2_extent_map_try_insert(struct inode *inode, | |||
| 423 | le32_to_cpu(rec->e_clusters), NULL, | 422 | le32_to_cpu(rec->e_clusters), NULL, |
| 424 | NULL); | 423 | NULL); |
| 425 | 424 | ||
| 426 | if (!old_ent) | 425 | BUG_ON(!old_ent); |
| 427 | BUG(); | ||
| 428 | 426 | ||
| 429 | ret = -EEXIST; | 427 | ret = -EEXIST; |
| 430 | if (old_ent->e_tree_depth < tree_depth) | 428 | if (old_ent->e_tree_depth < tree_depth) |
| @@ -988,7 +986,7 @@ int __init init_ocfs2_extent_maps(void) | |||
| 988 | return 0; | 986 | return 0; |
| 989 | } | 987 | } |
| 990 | 988 | ||
| 991 | void __exit exit_ocfs2_extent_maps(void) | 989 | void exit_ocfs2_extent_maps(void) |
| 992 | { | 990 | { |
| 993 | kmem_cache_destroy(ocfs2_em_ent_cachep); | 991 | kmem_cache_destroy(ocfs2_em_ent_cachep); |
| 994 | } | 992 | } |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index eaf33caa0a1f..1715bc90e705 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
| @@ -1022,8 +1022,9 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | |||
| 1022 | } | 1022 | } |
| 1023 | newsize = count + saved_pos; | 1023 | newsize = count + saved_pos; |
| 1024 | 1024 | ||
| 1025 | mlog(0, "pos=%lld newsize=%"MLFu64" cursize=%lld\n", | 1025 | mlog(0, "pos=%lld newsize=%lld cursize=%lld\n", |
| 1026 | saved_pos, newsize, i_size_read(inode)); | 1026 | (long long) saved_pos, (long long) newsize, |
| 1027 | (long long) i_size_read(inode)); | ||
| 1027 | 1028 | ||
| 1028 | /* No need for a higher level metadata lock if we're | 1029 | /* No need for a higher level metadata lock if we're |
| 1029 | * never going past i_size. */ | 1030 | * never going past i_size. */ |
| @@ -1042,8 +1043,9 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | |||
| 1042 | spin_unlock(&OCFS2_I(inode)->ip_lock); | 1043 | spin_unlock(&OCFS2_I(inode)->ip_lock); |
| 1043 | 1044 | ||
| 1044 | mlog(0, "Writing at EOF, may need more allocation: " | 1045 | mlog(0, "Writing at EOF, may need more allocation: " |
| 1045 | "i_size = %lld, newsize = %"MLFu64", need %u clusters\n", | 1046 | "i_size = %lld, newsize = %lld, need %u clusters\n", |
| 1046 | i_size_read(inode), newsize, clusters); | 1047 | (long long) i_size_read(inode), (long long) newsize, |
| 1048 | clusters); | ||
| 1047 | 1049 | ||
| 1048 | /* We only want to continue the rest of this loop if | 1050 | /* We only want to continue the rest of this loop if |
| 1049 | * our extend will actually require more | 1051 | * our extend will actually require more |
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index d4ecc0627716..8122489c5762 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c | |||
| @@ -903,10 +903,10 @@ void ocfs2_clear_inode(struct inode *inode) | |||
| 903 | "Clear inode of %"MLFu64", inode is locked\n", | 903 | "Clear inode of %"MLFu64", inode is locked\n", |
| 904 | oi->ip_blkno); | 904 | oi->ip_blkno); |
| 905 | 905 | ||
| 906 | mlog_bug_on_msg(down_trylock(&oi->ip_io_sem), | 906 | mlog_bug_on_msg(!mutex_trylock(&oi->ip_io_mutex), |
| 907 | "Clear inode of %"MLFu64", io_sem is locked\n", | 907 | "Clear inode of %"MLFu64", io_mutex is locked\n", |
| 908 | oi->ip_blkno); | 908 | oi->ip_blkno); |
| 909 | up(&oi->ip_io_sem); | 909 | mutex_unlock(&oi->ip_io_mutex); |
| 910 | 910 | ||
| 911 | /* | 911 | /* |
| 912 | * down_trylock() returns 0, down_write_trylock() returns 1 | 912 | * down_trylock() returns 0, down_write_trylock() returns 1 |
diff --git a/fs/ocfs2/inode.h b/fs/ocfs2/inode.h index 9b0177433653..84c507961287 100644 --- a/fs/ocfs2/inode.h +++ b/fs/ocfs2/inode.h | |||
| @@ -46,10 +46,10 @@ struct ocfs2_inode_info | |||
| 46 | struct list_head ip_io_markers; | 46 | struct list_head ip_io_markers; |
| 47 | int ip_orphaned_slot; | 47 | int ip_orphaned_slot; |
| 48 | 48 | ||
| 49 | struct semaphore ip_io_sem; | 49 | struct mutex ip_io_mutex; |
| 50 | 50 | ||
| 51 | /* Used by the journalling code to attach an inode to a | 51 | /* Used by the journalling code to attach an inode to a |
| 52 | * handle. These are protected by ip_io_sem in order to lock | 52 | * handle. These are protected by ip_io_mutex in order to lock |
| 53 | * out other I/O to the inode until we either commit or | 53 | * out other I/O to the inode until we either commit or |
| 54 | * abort. */ | 54 | * abort. */ |
| 55 | struct list_head ip_handle_list; | 55 | struct list_head ip_handle_list; |
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c index 303c8d96457f..fa0bcac5ceae 100644 --- a/fs/ocfs2/journal.c +++ b/fs/ocfs2/journal.c | |||
| @@ -147,8 +147,7 @@ struct ocfs2_journal_handle *ocfs2_start_trans(struct ocfs2_super *osb, | |||
| 147 | 147 | ||
| 148 | mlog_entry("(max_buffs = %d)\n", max_buffs); | 148 | mlog_entry("(max_buffs = %d)\n", max_buffs); |
| 149 | 149 | ||
| 150 | if (!osb || !osb->journal->j_journal) | 150 | BUG_ON(!osb || !osb->journal->j_journal); |
| 151 | BUG(); | ||
| 152 | 151 | ||
| 153 | if (ocfs2_is_hard_readonly(osb)) { | 152 | if (ocfs2_is_hard_readonly(osb)) { |
| 154 | ret = -EROFS; | 153 | ret = -EROFS; |
| @@ -401,7 +400,7 @@ int ocfs2_journal_access(struct ocfs2_journal_handle *handle, | |||
| 401 | * j_trans_barrier for us. */ | 400 | * j_trans_barrier for us. */ |
| 402 | ocfs2_set_inode_lock_trans(OCFS2_SB(inode->i_sb)->journal, inode); | 401 | ocfs2_set_inode_lock_trans(OCFS2_SB(inode->i_sb)->journal, inode); |
| 403 | 402 | ||
| 404 | down(&OCFS2_I(inode)->ip_io_sem); | 403 | mutex_lock(&OCFS2_I(inode)->ip_io_mutex); |
| 405 | switch (type) { | 404 | switch (type) { |
| 406 | case OCFS2_JOURNAL_ACCESS_CREATE: | 405 | case OCFS2_JOURNAL_ACCESS_CREATE: |
| 407 | case OCFS2_JOURNAL_ACCESS_WRITE: | 406 | case OCFS2_JOURNAL_ACCESS_WRITE: |
| @@ -416,7 +415,7 @@ int ocfs2_journal_access(struct ocfs2_journal_handle *handle, | |||
| 416 | status = -EINVAL; | 415 | status = -EINVAL; |
| 417 | mlog(ML_ERROR, "Uknown access type!\n"); | 416 | mlog(ML_ERROR, "Uknown access type!\n"); |
| 418 | } | 417 | } |
| 419 | up(&OCFS2_I(inode)->ip_io_sem); | 418 | mutex_unlock(&OCFS2_I(inode)->ip_io_mutex); |
| 420 | 419 | ||
| 421 | if (status < 0) | 420 | if (status < 0) |
| 422 | mlog(ML_ERROR, "Error %d getting %d access to buffer!\n", | 421 | mlog(ML_ERROR, "Error %d getting %d access to buffer!\n", |
| @@ -561,7 +560,11 @@ int ocfs2_journal_init(struct ocfs2_journal *journal, int *dirty) | |||
| 561 | SET_INODE_JOURNAL(inode); | 560 | SET_INODE_JOURNAL(inode); |
| 562 | OCFS2_I(inode)->ip_open_count++; | 561 | OCFS2_I(inode)->ip_open_count++; |
| 563 | 562 | ||
| 564 | status = ocfs2_meta_lock(inode, NULL, &bh, 1); | 563 | /* Skip recovery waits here - journal inode metadata never |
| 564 | * changes in a live cluster so it can be considered an | ||
| 565 | * exception to the rule. */ | ||
| 566 | status = ocfs2_meta_lock_full(inode, NULL, &bh, 1, | ||
| 567 | OCFS2_META_LOCK_RECOVERY); | ||
| 565 | if (status < 0) { | 568 | if (status < 0) { |
| 566 | if (status != -ERESTARTSYS) | 569 | if (status != -ERESTARTSYS) |
| 567 | mlog(ML_ERROR, "Could not get lock on journal!\n"); | 570 | mlog(ML_ERROR, "Could not get lock on journal!\n"); |
| @@ -672,8 +675,7 @@ void ocfs2_journal_shutdown(struct ocfs2_super *osb) | |||
| 672 | 675 | ||
| 673 | mlog_entry_void(); | 676 | mlog_entry_void(); |
| 674 | 677 | ||
| 675 | if (!osb) | 678 | BUG_ON(!osb); |
| 676 | BUG(); | ||
| 677 | 679 | ||
| 678 | journal = osb->journal; | 680 | journal = osb->journal; |
| 679 | if (!journal) | 681 | if (!journal) |
| @@ -805,8 +807,7 @@ int ocfs2_journal_wipe(struct ocfs2_journal *journal, int full) | |||
| 805 | 807 | ||
| 806 | mlog_entry_void(); | 808 | mlog_entry_void(); |
| 807 | 809 | ||
| 808 | if (!journal) | 810 | BUG_ON(!journal); |
| 809 | BUG(); | ||
| 810 | 811 | ||
| 811 | status = journal_wipe(journal->j_journal, full); | 812 | status = journal_wipe(journal->j_journal, full); |
| 812 | if (status < 0) { | 813 | if (status < 0) { |
| @@ -1072,10 +1073,10 @@ restart: | |||
| 1072 | NULL); | 1073 | NULL); |
| 1073 | 1074 | ||
| 1074 | bail: | 1075 | bail: |
| 1075 | down(&osb->recovery_lock); | 1076 | mutex_lock(&osb->recovery_lock); |
| 1076 | if (!status && | 1077 | if (!status && |
| 1077 | !ocfs2_node_map_is_empty(osb, &osb->recovery_map)) { | 1078 | !ocfs2_node_map_is_empty(osb, &osb->recovery_map)) { |
| 1078 | up(&osb->recovery_lock); | 1079 | mutex_unlock(&osb->recovery_lock); |
| 1079 | goto restart; | 1080 | goto restart; |
| 1080 | } | 1081 | } |
| 1081 | 1082 | ||
| @@ -1083,7 +1084,7 @@ bail: | |||
| 1083 | mb(); /* sync with ocfs2_recovery_thread_running */ | 1084 | mb(); /* sync with ocfs2_recovery_thread_running */ |
| 1084 | wake_up(&osb->recovery_event); | 1085 | wake_up(&osb->recovery_event); |
| 1085 | 1086 | ||
| 1086 | up(&osb->recovery_lock); | 1087 | mutex_unlock(&osb->recovery_lock); |
| 1087 | 1088 | ||
| 1088 | mlog_exit(status); | 1089 | mlog_exit(status); |
| 1089 | /* no one is callint kthread_stop() for us so the kthread() api | 1090 | /* no one is callint kthread_stop() for us so the kthread() api |
| @@ -1098,7 +1099,7 @@ void ocfs2_recovery_thread(struct ocfs2_super *osb, int node_num) | |||
| 1098 | mlog_entry("(node_num=%d, osb->node_num = %d)\n", | 1099 | mlog_entry("(node_num=%d, osb->node_num = %d)\n", |
| 1099 | node_num, osb->node_num); | 1100 | node_num, osb->node_num); |
| 1100 | 1101 | ||
| 1101 | down(&osb->recovery_lock); | 1102 | mutex_lock(&osb->recovery_lock); |
| 1102 | if (osb->disable_recovery) | 1103 | if (osb->disable_recovery) |
| 1103 | goto out; | 1104 | goto out; |
| 1104 | 1105 | ||
| @@ -1120,7 +1121,7 @@ void ocfs2_recovery_thread(struct ocfs2_super *osb, int node_num) | |||
| 1120 | } | 1121 | } |
| 1121 | 1122 | ||
| 1122 | out: | 1123 | out: |
| 1123 | up(&osb->recovery_lock); | 1124 | mutex_unlock(&osb->recovery_lock); |
| 1124 | wake_up(&osb->recovery_event); | 1125 | wake_up(&osb->recovery_event); |
| 1125 | 1126 | ||
| 1126 | mlog_exit_void(); | 1127 | mlog_exit_void(); |
| @@ -1271,8 +1272,7 @@ static int ocfs2_recover_node(struct ocfs2_super *osb, | |||
| 1271 | 1272 | ||
| 1272 | /* Should not ever be called to recover ourselves -- in that | 1273 | /* Should not ever be called to recover ourselves -- in that |
| 1273 | * case we should've called ocfs2_journal_load instead. */ | 1274 | * case we should've called ocfs2_journal_load instead. */ |
| 1274 | if (osb->node_num == node_num) | 1275 | BUG_ON(osb->node_num == node_num); |
| 1275 | BUG(); | ||
| 1276 | 1276 | ||
| 1277 | slot_num = ocfs2_node_num_to_slot(si, node_num); | 1277 | slot_num = ocfs2_node_num_to_slot(si, node_num); |
| 1278 | if (slot_num == OCFS2_INVALID_SLOT) { | 1278 | if (slot_num == OCFS2_INVALID_SLOT) { |
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index f468c600cf92..8d8e4779df92 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #include <linux/rbtree.h> | 33 | #include <linux/rbtree.h> |
| 34 | #include <linux/workqueue.h> | 34 | #include <linux/workqueue.h> |
| 35 | #include <linux/kref.h> | 35 | #include <linux/kref.h> |
| 36 | #include <linux/mutex.h> | ||
| 36 | 37 | ||
| 37 | #include "cluster/nodemanager.h" | 38 | #include "cluster/nodemanager.h" |
| 38 | #include "cluster/heartbeat.h" | 39 | #include "cluster/heartbeat.h" |
| @@ -233,7 +234,7 @@ struct ocfs2_super | |||
| 233 | struct proc_dir_entry *proc_sub_dir; /* points to /proc/fs/ocfs2/<maj_min> */ | 234 | struct proc_dir_entry *proc_sub_dir; /* points to /proc/fs/ocfs2/<maj_min> */ |
| 234 | 235 | ||
| 235 | atomic_t vol_state; | 236 | atomic_t vol_state; |
| 236 | struct semaphore recovery_lock; | 237 | struct mutex recovery_lock; |
| 237 | struct task_struct *recovery_thread_task; | 238 | struct task_struct *recovery_thread_task; |
| 238 | int disable_recovery; | 239 | int disable_recovery; |
| 239 | wait_queue_head_t checkpoint_event; | 240 | wait_queue_head_t checkpoint_event; |
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 364d64bd5f10..046824b6b625 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
| @@ -932,7 +932,7 @@ static void ocfs2_inode_init_once(void *data, | |||
| 932 | oi->ip_dir_start_lookup = 0; | 932 | oi->ip_dir_start_lookup = 0; |
| 933 | 933 | ||
| 934 | init_rwsem(&oi->ip_alloc_sem); | 934 | init_rwsem(&oi->ip_alloc_sem); |
| 935 | init_MUTEX(&(oi->ip_io_sem)); | 935 | mutex_init(&oi->ip_io_mutex); |
| 936 | 936 | ||
| 937 | oi->ip_blkno = 0ULL; | 937 | oi->ip_blkno = 0ULL; |
| 938 | oi->ip_clusters = 0; | 938 | oi->ip_clusters = 0; |
| @@ -1137,9 +1137,9 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err) | |||
| 1137 | 1137 | ||
| 1138 | /* disable any new recovery threads and wait for any currently | 1138 | /* disable any new recovery threads and wait for any currently |
| 1139 | * running ones to exit. Do this before setting the vol_state. */ | 1139 | * running ones to exit. Do this before setting the vol_state. */ |
| 1140 | down(&osb->recovery_lock); | 1140 | mutex_lock(&osb->recovery_lock); |
| 1141 | osb->disable_recovery = 1; | 1141 | osb->disable_recovery = 1; |
| 1142 | up(&osb->recovery_lock); | 1142 | mutex_unlock(&osb->recovery_lock); |
| 1143 | wait_event(osb->recovery_event, !ocfs2_recovery_thread_running(osb)); | 1143 | wait_event(osb->recovery_event, !ocfs2_recovery_thread_running(osb)); |
| 1144 | 1144 | ||
| 1145 | /* At this point, we know that no more recovery threads can be | 1145 | /* At this point, we know that no more recovery threads can be |
| @@ -1254,8 +1254,7 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
| 1254 | osb->sb = sb; | 1254 | osb->sb = sb; |
| 1255 | /* Save off for ocfs2_rw_direct */ | 1255 | /* Save off for ocfs2_rw_direct */ |
| 1256 | osb->s_sectsize_bits = blksize_bits(sector_size); | 1256 | osb->s_sectsize_bits = blksize_bits(sector_size); |
| 1257 | if (!osb->s_sectsize_bits) | 1257 | BUG_ON(!osb->s_sectsize_bits); |
| 1258 | BUG(); | ||
| 1259 | 1258 | ||
| 1260 | osb->net_response_ids = 0; | 1259 | osb->net_response_ids = 0; |
| 1261 | spin_lock_init(&osb->net_response_lock); | 1260 | spin_lock_init(&osb->net_response_lock); |
| @@ -1283,7 +1282,7 @@ static int ocfs2_initialize_super(struct super_block *sb, | |||
| 1283 | snprintf(osb->dev_str, sizeof(osb->dev_str), "%u,%u", | 1282 | snprintf(osb->dev_str, sizeof(osb->dev_str), "%u,%u", |
| 1284 | MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev)); | 1283 | MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev)); |
| 1285 | 1284 | ||
| 1286 | init_MUTEX(&osb->recovery_lock); | 1285 | mutex_init(&osb->recovery_lock); |
| 1287 | 1286 | ||
| 1288 | osb->disable_recovery = 0; | 1287 | osb->disable_recovery = 0; |
| 1289 | osb->recovery_thread_task = NULL; | 1288 | osb->recovery_thread_task = NULL; |
diff --git a/fs/ocfs2/sysfile.c b/fs/ocfs2/sysfile.c index 600a8bc5b541..fc29cb7a437d 100644 --- a/fs/ocfs2/sysfile.c +++ b/fs/ocfs2/sysfile.c | |||
| @@ -77,8 +77,7 @@ struct inode *ocfs2_get_system_file_inode(struct ocfs2_super *osb, | |||
| 77 | if (arr && ((inode = *arr) != NULL)) { | 77 | if (arr && ((inode = *arr) != NULL)) { |
| 78 | /* get a ref in addition to the array ref */ | 78 | /* get a ref in addition to the array ref */ |
| 79 | inode = igrab(inode); | 79 | inode = igrab(inode); |
| 80 | if (!inode) | 80 | BUG_ON(!inode); |
| 81 | BUG(); | ||
| 82 | 81 | ||
| 83 | return inode; | 82 | return inode; |
| 84 | } | 83 | } |
| @@ -89,8 +88,7 @@ struct inode *ocfs2_get_system_file_inode(struct ocfs2_super *osb, | |||
| 89 | /* add one more if putting into array for first time */ | 88 | /* add one more if putting into array for first time */ |
| 90 | if (arr && inode) { | 89 | if (arr && inode) { |
| 91 | *arr = igrab(inode); | 90 | *arr = igrab(inode); |
| 92 | if (!*arr) | 91 | BUG_ON(!*arr); |
| 93 | BUG(); | ||
| 94 | } | 92 | } |
| 95 | return inode; | 93 | return inode; |
| 96 | } | 94 | } |
diff --git a/fs/ocfs2/uptodate.c b/fs/ocfs2/uptodate.c index 3a0458fd3e1b..300b5bedfb21 100644 --- a/fs/ocfs2/uptodate.c +++ b/fs/ocfs2/uptodate.c | |||
| @@ -388,7 +388,7 @@ out_free: | |||
| 388 | } | 388 | } |
| 389 | } | 389 | } |
| 390 | 390 | ||
| 391 | /* Item insertion is guarded by ip_io_sem, so the insertion path takes | 391 | /* Item insertion is guarded by ip_io_mutex, so the insertion path takes |
| 392 | * advantage of this by not rechecking for a duplicate insert during | 392 | * advantage of this by not rechecking for a duplicate insert during |
| 393 | * the slow case. Additionally, if the cache needs to be bumped up to | 393 | * the slow case. Additionally, if the cache needs to be bumped up to |
| 394 | * a tree, the code will not recheck after acquiring the lock -- | 394 | * a tree, the code will not recheck after acquiring the lock -- |
| @@ -418,7 +418,7 @@ void ocfs2_set_buffer_uptodate(struct inode *inode, | |||
| 418 | (unsigned long long) bh->b_blocknr); | 418 | (unsigned long long) bh->b_blocknr); |
| 419 | 419 | ||
| 420 | /* No need to recheck under spinlock - insertion is guarded by | 420 | /* No need to recheck under spinlock - insertion is guarded by |
| 421 | * ip_io_sem */ | 421 | * ip_io_mutex */ |
| 422 | spin_lock(&oi->ip_lock); | 422 | spin_lock(&oi->ip_lock); |
| 423 | if (ocfs2_insert_can_use_array(oi, ci)) { | 423 | if (ocfs2_insert_can_use_array(oi, ci)) { |
| 424 | /* Fast case - it's an array and there's a free | 424 | /* Fast case - it's an array and there's a free |
| @@ -440,7 +440,7 @@ void ocfs2_set_buffer_uptodate(struct inode *inode, | |||
| 440 | 440 | ||
| 441 | /* Called against a newly allocated buffer. Most likely nobody should | 441 | /* Called against a newly allocated buffer. Most likely nobody should |
| 442 | * be able to read this sort of metadata while it's still being | 442 | * be able to read this sort of metadata while it's still being |
| 443 | * allocated, but this is careful to take ip_io_sem anyway. */ | 443 | * allocated, but this is careful to take ip_io_mutex anyway. */ |
| 444 | void ocfs2_set_new_buffer_uptodate(struct inode *inode, | 444 | void ocfs2_set_new_buffer_uptodate(struct inode *inode, |
| 445 | struct buffer_head *bh) | 445 | struct buffer_head *bh) |
| 446 | { | 446 | { |
| @@ -451,9 +451,9 @@ void ocfs2_set_new_buffer_uptodate(struct inode *inode, | |||
| 451 | 451 | ||
| 452 | set_buffer_uptodate(bh); | 452 | set_buffer_uptodate(bh); |
| 453 | 453 | ||
| 454 | down(&oi->ip_io_sem); | 454 | mutex_lock(&oi->ip_io_mutex); |
| 455 | ocfs2_set_buffer_uptodate(inode, bh); | 455 | ocfs2_set_buffer_uptodate(inode, bh); |
| 456 | up(&oi->ip_io_sem); | 456 | mutex_unlock(&oi->ip_io_mutex); |
| 457 | } | 457 | } |
| 458 | 458 | ||
| 459 | /* Requires ip_lock. */ | 459 | /* Requires ip_lock. */ |
| @@ -537,7 +537,7 @@ int __init init_ocfs2_uptodate_cache(void) | |||
| 537 | return 0; | 537 | return 0; |
| 538 | } | 538 | } |
| 539 | 539 | ||
| 540 | void __exit exit_ocfs2_uptodate_cache(void) | 540 | void exit_ocfs2_uptodate_cache(void) |
| 541 | { | 541 | { |
| 542 | if (ocfs2_uptodate_cachep) | 542 | if (ocfs2_uptodate_cachep) |
| 543 | kmem_cache_destroy(ocfs2_uptodate_cachep); | 543 | kmem_cache_destroy(ocfs2_uptodate_cachep); |
diff --git a/fs/ocfs2/uptodate.h b/fs/ocfs2/uptodate.h index e5aacdf4eabf..01cd32d26b06 100644 --- a/fs/ocfs2/uptodate.h +++ b/fs/ocfs2/uptodate.h | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | #define OCFS2_UPTODATE_H | 27 | #define OCFS2_UPTODATE_H |
| 28 | 28 | ||
| 29 | int __init init_ocfs2_uptodate_cache(void); | 29 | int __init init_ocfs2_uptodate_cache(void); |
| 30 | void __exit exit_ocfs2_uptodate_cache(void); | 30 | void exit_ocfs2_uptodate_cache(void); |
| 31 | 31 | ||
| 32 | void ocfs2_metadata_cache_init(struct inode *inode); | 32 | void ocfs2_metadata_cache_init(struct inode *inode); |
| 33 | void ocfs2_metadata_cache_purge(struct inode *inode); | 33 | void ocfs2_metadata_cache_purge(struct inode *inode); |
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index 8f8014285a34..1d24fead51a6 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c | |||
| @@ -548,7 +548,7 @@ static int show_stat(struct seq_file *p, void *v) | |||
| 548 | } | 548 | } |
| 549 | seq_printf(p, "intr %llu", (unsigned long long)sum); | 549 | seq_printf(p, "intr %llu", (unsigned long long)sum); |
| 550 | 550 | ||
| 551 | #if !defined(CONFIG_PPC64) && !defined(CONFIG_ALPHA) | 551 | #if !defined(CONFIG_PPC64) && !defined(CONFIG_ALPHA) && !defined(CONFIG_IA64) |
| 552 | for (i = 0; i < NR_IRQS; i++) | 552 | for (i = 0; i < NR_IRQS; i++) |
| 553 | seq_printf(p, " %u", kstat_irqs(i)); | 553 | seq_printf(p, " %u", kstat_irqs(i)); |
| 554 | #endif | 554 | #endif |
diff --git a/fs/quota_v2.c b/fs/quota_v2.c index a4ef91bb4f3b..b4199ec3ece4 100644 --- a/fs/quota_v2.c +++ b/fs/quota_v2.c | |||
| @@ -35,7 +35,7 @@ static int v2_check_quota_file(struct super_block *sb, int type) | |||
| 35 | 35 | ||
| 36 | size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0); | 36 | size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0); |
| 37 | if (size != sizeof(struct v2_disk_dqheader)) { | 37 | if (size != sizeof(struct v2_disk_dqheader)) { |
| 38 | printk("quota_v2: failed read expected=%d got=%d\n", | 38 | printk("quota_v2: failed read expected=%zd got=%zd\n", |
| 39 | sizeof(struct v2_disk_dqheader), size); | 39 | sizeof(struct v2_disk_dqheader), size); |
| 40 | return 0; | 40 | return 0; |
| 41 | } | 41 | } |
diff --git a/fs/reiserfs/hashes.c b/fs/reiserfs/hashes.c index a3ec238fd9e0..e664ac16fad9 100644 --- a/fs/reiserfs/hashes.c +++ b/fs/reiserfs/hashes.c | |||
| @@ -21,7 +21,6 @@ | |||
| 21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
| 22 | #include <linux/reiserfs_fs.h> | 22 | #include <linux/reiserfs_fs.h> |
| 23 | #include <asm/types.h> | 23 | #include <asm/types.h> |
| 24 | #include <asm/bug.h> | ||
| 25 | 24 | ||
| 26 | #define DELTA 0x9E3779B9 | 25 | #define DELTA 0x9E3779B9 |
| 27 | #define FULLROUNDS 10 /* 32 is overkill, 16 is strong crypto */ | 26 | #define FULLROUNDS 10 /* 32 is overkill, 16 is strong crypto */ |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 77891de0e02e..ef5e5414e7a8 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
| @@ -1125,7 +1125,7 @@ static void handle_attrs(struct super_block *s) | |||
| 1125 | REISERFS_SB(s)->s_mount_opt &= ~(1 << REISERFS_ATTRS); | 1125 | REISERFS_SB(s)->s_mount_opt &= ~(1 << REISERFS_ATTRS); |
| 1126 | } | 1126 | } |
| 1127 | } else if (le32_to_cpu(rs->s_flags) & reiserfs_attrs_cleared) { | 1127 | } else if (le32_to_cpu(rs->s_flags) & reiserfs_attrs_cleared) { |
| 1128 | REISERFS_SB(s)->s_mount_opt |= REISERFS_ATTRS; | 1128 | REISERFS_SB(s)->s_mount_opt |= (1 << REISERFS_ATTRS); |
| 1129 | } | 1129 | } |
| 1130 | } | 1130 | } |
| 1131 | 1131 | ||
diff --git a/fs/select.c b/fs/select.c index c0f02d36c60e..bc60a3e14ef3 100644 --- a/fs/select.c +++ b/fs/select.c | |||
| @@ -510,9 +510,9 @@ asmlinkage long sys_pselect6(int n, fd_set __user *inp, fd_set __user *outp, | |||
| 510 | 510 | ||
| 511 | if (sig) { | 511 | if (sig) { |
| 512 | if (!access_ok(VERIFY_READ, sig, sizeof(void *)+sizeof(size_t)) | 512 | if (!access_ok(VERIFY_READ, sig, sizeof(void *)+sizeof(size_t)) |
| 513 | || __get_user(up, (sigset_t * __user *)sig) | 513 | || __get_user(up, (sigset_t __user * __user *)sig) |
| 514 | || __get_user(sigsetsize, | 514 | || __get_user(sigsetsize, |
| 515 | (size_t * __user)(sig+sizeof(void *)))) | 515 | (size_t __user *)(sig+sizeof(void *)))) |
| 516 | return -EFAULT; | 516 | return -EFAULT; |
| 517 | } | 517 | } |
| 518 | 518 | ||
diff --git a/fs/super.c b/fs/super.c index c177b92419c5..30294218fa63 100644 --- a/fs/super.c +++ b/fs/super.c | |||
| @@ -247,8 +247,9 @@ void generic_shutdown_super(struct super_block *sb) | |||
| 247 | 247 | ||
| 248 | /* Forget any remaining inodes */ | 248 | /* Forget any remaining inodes */ |
| 249 | if (invalidate_inodes(sb)) { | 249 | if (invalidate_inodes(sb)) { |
| 250 | printk("VFS: Busy inodes after unmount. " | 250 | printk("VFS: Busy inodes after unmount of %s. " |
| 251 | "Self-destruct in 5 seconds. Have a nice day...\n"); | 251 | "Self-destruct in 5 seconds. Have a nice day...\n", |
| 252 | sb->s_id); | ||
| 252 | } | 253 | } |
| 253 | 254 | ||
| 254 | unlock_kernel(); | 255 | unlock_kernel(); |
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index 4fae57d9d115..201049ac8a96 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c | |||
| @@ -579,10 +579,9 @@ static void udf_table_free_blocks(struct super_block * sb, | |||
| 579 | { | 579 | { |
| 580 | loffset = nextoffset; | 580 | loffset = nextoffset; |
| 581 | aed->lengthAllocDescs = cpu_to_le32(adsize); | 581 | aed->lengthAllocDescs = cpu_to_le32(adsize); |
| 582 | if (obh) | 582 | sptr = UDF_I_DATA(inode) + nextoffset - |
| 583 | sptr = UDF_I_DATA(inode) + nextoffset - udf_file_entry_alloc_offset(inode) + UDF_I_LENEATTR(inode) - adsize; | 583 | udf_file_entry_alloc_offset(inode) + |
| 584 | else | 584 | UDF_I_LENEATTR(inode) - adsize; |
| 585 | sptr = obh->b_data + nextoffset - adsize; | ||
| 586 | dptr = nbh->b_data + sizeof(struct allocExtDesc); | 585 | dptr = nbh->b_data + sizeof(struct allocExtDesc); |
| 587 | memcpy(dptr, sptr, adsize); | 586 | memcpy(dptr, sptr, adsize); |
| 588 | nextoffset = sizeof(struct allocExtDesc) + adsize; | 587 | nextoffset = sizeof(struct allocExtDesc) + adsize; |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index ca732e79c48b..ab9a7629d23e 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
| @@ -296,7 +296,7 @@ static struct dentry * | |||
| 296 | udf_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | 296 | udf_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) |
| 297 | { | 297 | { |
| 298 | struct inode *inode = NULL; | 298 | struct inode *inode = NULL; |
| 299 | struct fileIdentDesc cfi, *fi; | 299 | struct fileIdentDesc cfi; |
| 300 | struct udf_fileident_bh fibh; | 300 | struct udf_fileident_bh fibh; |
| 301 | 301 | ||
| 302 | if (dentry->d_name.len > UDF_NAME_LEN-2) | 302 | if (dentry->d_name.len > UDF_NAME_LEN-2) |
| @@ -318,7 +318,7 @@ udf_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | |||
| 318 | else | 318 | else |
| 319 | #endif /* UDF_RECOVERY */ | 319 | #endif /* UDF_RECOVERY */ |
| 320 | 320 | ||
| 321 | if ((fi = udf_find_entry(dir, dentry, &fibh, &cfi))) | 321 | if (udf_find_entry(dir, dentry, &fibh, &cfi)) |
| 322 | { | 322 | { |
| 323 | if (fibh.sbh != fibh.ebh) | 323 | if (fibh.sbh != fibh.ebh) |
| 324 | udf_release_data(fibh.ebh); | 324 | udf_release_data(fibh.ebh); |
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index e0c04e36a051..3c3f62ce2ad9 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
| @@ -376,7 +376,7 @@ out: | |||
| 376 | * This function gets the block which contains the fragment. | 376 | * This function gets the block which contains the fragment. |
| 377 | */ | 377 | */ |
| 378 | 378 | ||
| 379 | static int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create) | 379 | int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create) |
| 380 | { | 380 | { |
| 381 | struct super_block * sb = inode->i_sb; | 381 | struct super_block * sb = inode->i_sb; |
| 382 | struct ufs_sb_private_info * uspi = UFS_SB(sb)->s_uspi; | 382 | struct ufs_sb_private_info * uspi = UFS_SB(sb)->s_uspi; |
diff --git a/fs/ufs/super.c b/fs/ufs/super.c index d4aacee593ff..e9055ef7f5ac 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c | |||
| @@ -388,7 +388,8 @@ static int ufs_parse_options (char * options, unsigned * mount_options) | |||
| 388 | /* | 388 | /* |
| 389 | * Read on-disk structures associated with cylinder groups | 389 | * Read on-disk structures associated with cylinder groups |
| 390 | */ | 390 | */ |
| 391 | static int ufs_read_cylinder_structures (struct super_block *sb) { | 391 | static int ufs_read_cylinder_structures (struct super_block *sb) |
| 392 | { | ||
| 392 | struct ufs_sb_info * sbi = UFS_SB(sb); | 393 | struct ufs_sb_info * sbi = UFS_SB(sb); |
| 393 | struct ufs_sb_private_info * uspi; | 394 | struct ufs_sb_private_info * uspi; |
| 394 | struct ufs_super_block *usb; | 395 | struct ufs_super_block *usb; |
| @@ -415,6 +416,7 @@ static int ufs_read_cylinder_structures (struct super_block *sb) { | |||
| 415 | base = space = kmalloc(size, GFP_KERNEL); | 416 | base = space = kmalloc(size, GFP_KERNEL); |
| 416 | if (!base) | 417 | if (!base) |
| 417 | goto failed; | 418 | goto failed; |
| 419 | sbi->s_csp = (struct ufs_csum *)space; | ||
| 418 | for (i = 0; i < blks; i += uspi->s_fpb) { | 420 | for (i = 0; i < blks; i += uspi->s_fpb) { |
| 419 | size = uspi->s_bsize; | 421 | size = uspi->s_bsize; |
| 420 | if (i + uspi->s_fpb > blks) | 422 | if (i + uspi->s_fpb > blks) |
| @@ -430,7 +432,6 @@ static int ufs_read_cylinder_structures (struct super_block *sb) { | |||
| 430 | goto failed; | 432 | goto failed; |
| 431 | 433 | ||
| 432 | ubh_ubhcpymem (space, ubh, size); | 434 | ubh_ubhcpymem (space, ubh, size); |
| 433 | sbi->s_csp[ufs_fragstoblks(i)]=(struct ufs_csum *)space; | ||
| 434 | 435 | ||
| 435 | space += size; | 436 | space += size; |
| 436 | ubh_brelse (ubh); | 437 | ubh_brelse (ubh); |
| @@ -486,7 +487,8 @@ failed: | |||
| 486 | * Put on-disk structures associated with cylinder groups and | 487 | * Put on-disk structures associated with cylinder groups and |
| 487 | * write them back to disk | 488 | * write them back to disk |
| 488 | */ | 489 | */ |
| 489 | static void ufs_put_cylinder_structures (struct super_block *sb) { | 490 | static void ufs_put_cylinder_structures (struct super_block *sb) |
| 491 | { | ||
| 490 | struct ufs_sb_info * sbi = UFS_SB(sb); | 492 | struct ufs_sb_info * sbi = UFS_SB(sb); |
| 491 | struct ufs_sb_private_info * uspi; | 493 | struct ufs_sb_private_info * uspi; |
| 492 | struct ufs_buffer_head * ubh; | 494 | struct ufs_buffer_head * ubh; |
| @@ -499,7 +501,7 @@ static void ufs_put_cylinder_structures (struct super_block *sb) { | |||
| 499 | 501 | ||
| 500 | size = uspi->s_cssize; | 502 | size = uspi->s_cssize; |
| 501 | blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift; | 503 | blks = (size + uspi->s_fsize - 1) >> uspi->s_fshift; |
| 502 | base = space = (char*) sbi->s_csp[0]; | 504 | base = space = (char*) sbi->s_csp; |
| 503 | for (i = 0; i < blks; i += uspi->s_fpb) { | 505 | for (i = 0; i < blks; i += uspi->s_fpb) { |
| 504 | size = uspi->s_bsize; | 506 | size = uspi->s_bsize; |
| 505 | if (i + uspi->s_fpb > blks) | 507 | if (i + uspi->s_fpb > blks) |
diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c index 61d2e35012a4..02e86291ef8a 100644 --- a/fs/ufs/truncate.c +++ b/fs/ufs/truncate.c | |||
| @@ -29,6 +29,11 @@ | |||
| 29 | * Idea from Pierre del Perugia <delperug@gla.ecoledoc.ibp.fr> | 29 | * Idea from Pierre del Perugia <delperug@gla.ecoledoc.ibp.fr> |
| 30 | */ | 30 | */ |
| 31 | 31 | ||
| 32 | /* | ||
| 33 | * Modified to avoid infinite loop on 2006 by | ||
| 34 | * Evgeniy Dushistov <dushistov@mail.ru> | ||
| 35 | */ | ||
| 36 | |||
| 32 | #include <linux/errno.h> | 37 | #include <linux/errno.h> |
| 33 | #include <linux/fs.h> | 38 | #include <linux/fs.h> |
| 34 | #include <linux/ufs_fs.h> | 39 | #include <linux/ufs_fs.h> |
| @@ -65,19 +70,16 @@ | |||
| 65 | #define DIRECT_BLOCK ((inode->i_size + uspi->s_bsize - 1) >> uspi->s_bshift) | 70 | #define DIRECT_BLOCK ((inode->i_size + uspi->s_bsize - 1) >> uspi->s_bshift) |
| 66 | #define DIRECT_FRAGMENT ((inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift) | 71 | #define DIRECT_FRAGMENT ((inode->i_size + uspi->s_fsize - 1) >> uspi->s_fshift) |
| 67 | 72 | ||
| 68 | #define DATA_BUFFER_USED(bh) \ | ||
| 69 | (atomic_read(&bh->b_count)>1 || buffer_locked(bh)) | ||
| 70 | 73 | ||
| 71 | static int ufs_trunc_direct (struct inode * inode) | 74 | static int ufs_trunc_direct (struct inode * inode) |
| 72 | { | 75 | { |
| 73 | struct ufs_inode_info *ufsi = UFS_I(inode); | 76 | struct ufs_inode_info *ufsi = UFS_I(inode); |
| 74 | struct super_block * sb; | 77 | struct super_block * sb; |
| 75 | struct ufs_sb_private_info * uspi; | 78 | struct ufs_sb_private_info * uspi; |
| 76 | struct buffer_head * bh; | ||
| 77 | __fs32 * p; | 79 | __fs32 * p; |
| 78 | unsigned frag1, frag2, frag3, frag4, block1, block2; | 80 | unsigned frag1, frag2, frag3, frag4, block1, block2; |
| 79 | unsigned frag_to_free, free_count; | 81 | unsigned frag_to_free, free_count; |
| 80 | unsigned i, j, tmp; | 82 | unsigned i, tmp; |
| 81 | int retry; | 83 | int retry; |
| 82 | 84 | ||
| 83 | UFSD(("ENTER\n")) | 85 | UFSD(("ENTER\n")) |
| @@ -117,15 +119,7 @@ static int ufs_trunc_direct (struct inode * inode) | |||
| 117 | ufs_panic (sb, "ufs_trunc_direct", "internal error"); | 119 | ufs_panic (sb, "ufs_trunc_direct", "internal error"); |
| 118 | frag1 = ufs_fragnum (frag1); | 120 | frag1 = ufs_fragnum (frag1); |
| 119 | frag2 = ufs_fragnum (frag2); | 121 | frag2 = ufs_fragnum (frag2); |
| 120 | for (j = frag1; j < frag2; j++) { | 122 | |
| 121 | bh = sb_find_get_block (sb, tmp + j); | ||
| 122 | if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *p)) { | ||
| 123 | retry = 1; | ||
| 124 | brelse (bh); | ||
| 125 | goto next1; | ||
| 126 | } | ||
| 127 | bforget (bh); | ||
| 128 | } | ||
| 129 | inode->i_blocks -= (frag2-frag1) << uspi->s_nspfshift; | 123 | inode->i_blocks -= (frag2-frag1) << uspi->s_nspfshift; |
| 130 | mark_inode_dirty(inode); | 124 | mark_inode_dirty(inode); |
| 131 | ufs_free_fragments (inode, tmp + frag1, frag2 - frag1); | 125 | ufs_free_fragments (inode, tmp + frag1, frag2 - frag1); |
| @@ -140,15 +134,7 @@ next1: | |||
| 140 | tmp = fs32_to_cpu(sb, *p); | 134 | tmp = fs32_to_cpu(sb, *p); |
| 141 | if (!tmp) | 135 | if (!tmp) |
| 142 | continue; | 136 | continue; |
| 143 | for (j = 0; j < uspi->s_fpb; j++) { | 137 | |
| 144 | bh = sb_find_get_block(sb, tmp + j); | ||
| 145 | if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *p)) { | ||
| 146 | retry = 1; | ||
| 147 | brelse (bh); | ||
| 148 | goto next2; | ||
| 149 | } | ||
| 150 | bforget (bh); | ||
| 151 | } | ||
| 152 | *p = 0; | 138 | *p = 0; |
| 153 | inode->i_blocks -= uspi->s_nspb; | 139 | inode->i_blocks -= uspi->s_nspb; |
| 154 | mark_inode_dirty(inode); | 140 | mark_inode_dirty(inode); |
| @@ -162,7 +148,6 @@ next1: | |||
| 162 | frag_to_free = tmp; | 148 | frag_to_free = tmp; |
| 163 | free_count = uspi->s_fpb; | 149 | free_count = uspi->s_fpb; |
| 164 | } | 150 | } |
| 165 | next2:; | ||
| 166 | } | 151 | } |
| 167 | 152 | ||
| 168 | if (free_count > 0) | 153 | if (free_count > 0) |
| @@ -179,15 +164,7 @@ next2:; | |||
| 179 | if (!tmp ) | 164 | if (!tmp ) |
| 180 | ufs_panic(sb, "ufs_truncate_direct", "internal error"); | 165 | ufs_panic(sb, "ufs_truncate_direct", "internal error"); |
| 181 | frag4 = ufs_fragnum (frag4); | 166 | frag4 = ufs_fragnum (frag4); |
| 182 | for (j = 0; j < frag4; j++) { | 167 | |
| 183 | bh = sb_find_get_block (sb, tmp + j); | ||
| 184 | if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *p)) { | ||
| 185 | retry = 1; | ||
| 186 | brelse (bh); | ||
| 187 | goto next1; | ||
| 188 | } | ||
| 189 | bforget (bh); | ||
| 190 | } | ||
| 191 | *p = 0; | 168 | *p = 0; |
| 192 | inode->i_blocks -= frag4 << uspi->s_nspfshift; | 169 | inode->i_blocks -= frag4 << uspi->s_nspfshift; |
| 193 | mark_inode_dirty(inode); | 170 | mark_inode_dirty(inode); |
| @@ -204,9 +181,8 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p) | |||
| 204 | struct super_block * sb; | 181 | struct super_block * sb; |
| 205 | struct ufs_sb_private_info * uspi; | 182 | struct ufs_sb_private_info * uspi; |
| 206 | struct ufs_buffer_head * ind_ubh; | 183 | struct ufs_buffer_head * ind_ubh; |
| 207 | struct buffer_head * bh; | ||
| 208 | __fs32 * ind; | 184 | __fs32 * ind; |
| 209 | unsigned indirect_block, i, j, tmp; | 185 | unsigned indirect_block, i, tmp; |
| 210 | unsigned frag_to_free, free_count; | 186 | unsigned frag_to_free, free_count; |
| 211 | int retry; | 187 | int retry; |
| 212 | 188 | ||
| @@ -238,15 +214,7 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p) | |||
| 238 | tmp = fs32_to_cpu(sb, *ind); | 214 | tmp = fs32_to_cpu(sb, *ind); |
| 239 | if (!tmp) | 215 | if (!tmp) |
| 240 | continue; | 216 | continue; |
| 241 | for (j = 0; j < uspi->s_fpb; j++) { | 217 | |
| 242 | bh = sb_find_get_block(sb, tmp + j); | ||
| 243 | if ((bh && DATA_BUFFER_USED(bh)) || tmp != fs32_to_cpu(sb, *ind)) { | ||
| 244 | retry = 1; | ||
| 245 | brelse (bh); | ||
| 246 | goto next; | ||
| 247 | } | ||
| 248 | bforget (bh); | ||
| 249 | } | ||
| 250 | *ind = 0; | 218 | *ind = 0; |
| 251 | ubh_mark_buffer_dirty(ind_ubh); | 219 | ubh_mark_buffer_dirty(ind_ubh); |
| 252 | if (free_count == 0) { | 220 | if (free_count == 0) { |
| @@ -261,7 +229,6 @@ static int ufs_trunc_indirect (struct inode * inode, unsigned offset, __fs32 *p) | |||
| 261 | } | 229 | } |
| 262 | inode->i_blocks -= uspi->s_nspb; | 230 | inode->i_blocks -= uspi->s_nspb; |
| 263 | mark_inode_dirty(inode); | 231 | mark_inode_dirty(inode); |
| 264 | next:; | ||
| 265 | } | 232 | } |
| 266 | 233 | ||
| 267 | if (free_count > 0) { | 234 | if (free_count > 0) { |
| @@ -430,9 +397,7 @@ void ufs_truncate (struct inode * inode) | |||
| 430 | struct ufs_inode_info *ufsi = UFS_I(inode); | 397 | struct ufs_inode_info *ufsi = UFS_I(inode); |
| 431 | struct super_block * sb; | 398 | struct super_block * sb; |
| 432 | struct ufs_sb_private_info * uspi; | 399 | struct ufs_sb_private_info * uspi; |
| 433 | struct buffer_head * bh; | 400 | int retry; |
| 434 | unsigned offset; | ||
| 435 | int err, retry; | ||
| 436 | 401 | ||
| 437 | UFSD(("ENTER\n")) | 402 | UFSD(("ENTER\n")) |
| 438 | sb = inode->i_sb; | 403 | sb = inode->i_sb; |
| @@ -442,6 +407,9 @@ void ufs_truncate (struct inode * inode) | |||
| 442 | return; | 407 | return; |
| 443 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | 408 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) |
| 444 | return; | 409 | return; |
| 410 | |||
| 411 | block_truncate_page(inode->i_mapping, inode->i_size, ufs_getfrag_block); | ||
| 412 | |||
| 445 | lock_kernel(); | 413 | lock_kernel(); |
| 446 | while (1) { | 414 | while (1) { |
| 447 | retry = ufs_trunc_direct(inode); | 415 | retry = ufs_trunc_direct(inode); |
| @@ -457,15 +425,7 @@ void ufs_truncate (struct inode * inode) | |||
| 457 | blk_run_address_space(inode->i_mapping); | 425 | blk_run_address_space(inode->i_mapping); |
| 458 | yield(); | 426 | yield(); |
| 459 | } | 427 | } |
| 460 | offset = inode->i_size & uspi->s_fshift; | 428 | |
| 461 | if (offset) { | ||
| 462 | bh = ufs_bread (inode, inode->i_size >> uspi->s_fshift, 0, &err); | ||
| 463 | if (bh) { | ||
| 464 | memset (bh->b_data + offset, 0, uspi->s_fsize - offset); | ||
| 465 | mark_buffer_dirty (bh); | ||
| 466 | brelse (bh); | ||
| 467 | } | ||
| 468 | } | ||
| 469 | inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; | 429 | inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; |
| 470 | ufsi->i_lastfrag = DIRECT_FRAGMENT; | 430 | ufsi->i_lastfrag = DIRECT_FRAGMENT; |
| 471 | unlock_kernel(); | 431 | unlock_kernel(); |
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 9892268e3005..8f2beec526cf 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
| @@ -747,10 +747,11 @@ xfs_convert_page( | |||
| 747 | struct backing_dev_info *bdi; | 747 | struct backing_dev_info *bdi; |
| 748 | 748 | ||
| 749 | bdi = inode->i_mapping->backing_dev_info; | 749 | bdi = inode->i_mapping->backing_dev_info; |
| 750 | wbc->nr_to_write--; | ||
| 750 | if (bdi_write_congested(bdi)) { | 751 | if (bdi_write_congested(bdi)) { |
| 751 | wbc->encountered_congestion = 1; | 752 | wbc->encountered_congestion = 1; |
| 752 | done = 1; | 753 | done = 1; |
| 753 | } else if (--wbc->nr_to_write <= 0) { | 754 | } else if (wbc->nr_to_write <= 0) { |
| 754 | done = 1; | 755 | done = 1; |
| 755 | } | 756 | } |
| 756 | } | 757 | } |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index eda7919b70a1..d7f6f2d8ac8e 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
| @@ -673,6 +673,8 @@ linvfs_setattr( | |||
| 673 | if (ia_valid & ATTR_ATIME) { | 673 | if (ia_valid & ATTR_ATIME) { |
| 674 | vattr.va_mask |= XFS_AT_ATIME; | 674 | vattr.va_mask |= XFS_AT_ATIME; |
| 675 | vattr.va_atime = attr->ia_atime; | 675 | vattr.va_atime = attr->ia_atime; |
| 676 | if (ia_valid & ATTR_ATIME_SET) | ||
| 677 | inode->i_atime = attr->ia_atime; | ||
| 676 | } | 678 | } |
| 677 | if (ia_valid & ATTR_MTIME) { | 679 | if (ia_valid & ATTR_MTIME) { |
| 678 | vattr.va_mask |= XFS_AT_MTIME; | 680 | vattr.va_mask |= XFS_AT_MTIME; |
diff --git a/include/asm-alpha/system.h b/include/asm-alpha/system.h index cc9c7e8cced5..f3b7b1a59c56 100644 --- a/include/asm-alpha/system.h +++ b/include/asm-alpha/system.h | |||
| @@ -572,7 +572,7 @@ __cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new) | |||
| 572 | if something tries to do an invalid cmpxchg(). */ | 572 | if something tries to do an invalid cmpxchg(). */ |
| 573 | extern void __cmpxchg_called_with_bad_pointer(void); | 573 | extern void __cmpxchg_called_with_bad_pointer(void); |
| 574 | 574 | ||
| 575 | static inline unsigned long | 575 | static __always_inline unsigned long |
| 576 | __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) | 576 | __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) |
| 577 | { | 577 | { |
| 578 | switch (size) { | 578 | switch (size) { |
diff --git a/include/asm-arm/arch-omap/io.h b/include/asm-arm/arch-omap/io.h index f5bcc9a1aed6..b726acfcab14 100644 --- a/include/asm-arm/arch-omap/io.h +++ b/include/asm-arm/arch-omap/io.h | |||
| @@ -116,7 +116,11 @@ typedef struct { volatile u32 offset[4096]; } __regbase32; | |||
| 116 | ->offset[((vaddr)&4095)>>2] | 116 | ->offset[((vaddr)&4095)>>2] |
| 117 | #define __REG32(paddr) __REGV32(io_p2v(paddr)) | 117 | #define __REG32(paddr) __REGV32(io_p2v(paddr)) |
| 118 | 118 | ||
| 119 | extern void omap_map_common_io(void); | 119 | extern void omap1_map_common_io(void); |
| 120 | extern void omap1_init_common_hw(void); | ||
| 121 | |||
| 122 | extern void omap2_map_common_io(void); | ||
| 123 | extern void omap2_init_common_hw(void); | ||
| 120 | 124 | ||
| 121 | #else | 125 | #else |
| 122 | 126 | ||
diff --git a/include/asm-arm/arch-s3c2410/hardware.h b/include/asm-arm/arch-s3c2410/hardware.h index 1c9de29cafef..a2330bf83695 100644 --- a/include/asm-arm/arch-s3c2410/hardware.h +++ b/include/asm-arm/arch-s3c2410/hardware.h | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | * 14-Sep-2004 BJD Added misccr and getpin to gpio | 17 | * 14-Sep-2004 BJD Added misccr and getpin to gpio |
| 18 | * 01-Oct-2004 BJD Added the new gpio functions | 18 | * 01-Oct-2004 BJD Added the new gpio functions |
| 19 | * 16-Oct-2004 BJD Removed the clock variables | 19 | * 16-Oct-2004 BJD Removed the clock variables |
| 20 | * 15-Jan-2006 LCVR Added s3c2400_gpio_getirq() | ||
| 20 | */ | 21 | */ |
| 21 | 22 | ||
| 22 | #ifndef __ASM_ARCH_HARDWARE_H | 23 | #ifndef __ASM_ARCH_HARDWARE_H |
| @@ -55,6 +56,12 @@ extern unsigned int s3c2410_gpio_getcfg(unsigned int pin); | |||
| 55 | 56 | ||
| 56 | extern int s3c2410_gpio_getirq(unsigned int pin); | 57 | extern int s3c2410_gpio_getirq(unsigned int pin); |
| 57 | 58 | ||
| 59 | #ifdef CONFIG_CPU_S3C2400 | ||
| 60 | |||
| 61 | extern int s3c2400_gpio_getirq(unsigned int pin); | ||
| 62 | |||
| 63 | #endif /* CONFIG_CPU_S3C2400 */ | ||
| 64 | |||
| 58 | /* s3c2410_gpio_irqfilter | 65 | /* s3c2410_gpio_irqfilter |
| 59 | * | 66 | * |
| 60 | * set the irq filtering on the given pin | 67 | * set the irq filtering on the given pin |
diff --git a/include/asm-arm/arch-s3c2410/regs-gpio.h b/include/asm-arm/arch-s3c2410/regs-gpio.h index 7f1be48ad67e..9697f93afe74 100644 --- a/include/asm-arm/arch-s3c2410/regs-gpio.h +++ b/include/asm-arm/arch-s3c2410/regs-gpio.h | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | * 28-Mar-2005 LCVR Fixed definition of GPB10 | 22 | * 28-Mar-2005 LCVR Fixed definition of GPB10 |
| 23 | * 26-Oct-2005 BJD Added generic configuration types | 23 | * 26-Oct-2005 BJD Added generic configuration types |
| 24 | * 27-Nov-2005 LCVR Added definitions to S3C2400 registers | 24 | * 27-Nov-2005 LCVR Added definitions to S3C2400 registers |
| 25 | * 15-Jan-2006 LCVR Written S3C24XX_GPIO_BASE() macro | ||
| 25 | */ | 26 | */ |
| 26 | 27 | ||
| 27 | 28 | ||
| @@ -39,6 +40,27 @@ | |||
| 39 | #define S3C2410_GPIO_BANKG (32*6) | 40 | #define S3C2410_GPIO_BANKG (32*6) |
| 40 | #define S3C2410_GPIO_BANKH (32*7) | 41 | #define S3C2410_GPIO_BANKH (32*7) |
| 41 | 42 | ||
| 43 | #ifdef CONFIG_CPU_S3C2400 | ||
| 44 | #define S3C24XX_GPIO_BASE(x) S3C2400_GPIO_BASE(x) | ||
| 45 | #define S3C24XX_MISCCR S3C2400_MISCCR | ||
| 46 | #else | ||
| 47 | #define S3C24XX_GPIO_BASE(x) S3C2410_GPIO_BASE(x) | ||
| 48 | #define S3C24XX_MISCCR S3C2410_MISCCR | ||
| 49 | #endif /* CONFIG_CPU_S3C2400 */ | ||
| 50 | |||
| 51 | |||
| 52 | /* S3C2400 doesn't have a 1:1 mapping to S3C2410 gpio base pins */ | ||
| 53 | |||
| 54 | #define S3C2400_BANKNUM(pin) (((pin) & ~31) / 32) | ||
| 55 | #define S3C2400_BASEA2B(pin) ((((pin) & ~31) >> 2)) | ||
| 56 | #define S3C2400_BASEC2H(pin) ((S3C2400_BANKNUM(pin) * 10) + \ | ||
| 57 | (2 * (S3C2400_BANKNUM(pin)-2))) | ||
| 58 | |||
| 59 | #define S3C2400_GPIO_BASE(pin) (pin < S3C2410_GPIO_BANKC ? \ | ||
| 60 | S3C2400_BASEA2B(pin)+S3C24XX_VA_GPIO : \ | ||
| 61 | S3C2400_BASEC2H(pin)+S3C24XX_VA_GPIO) | ||
| 62 | |||
| 63 | |||
| 42 | #define S3C2410_GPIO_BASE(pin) ((((pin) & ~31) >> 1) + S3C24XX_VA_GPIO) | 64 | #define S3C2410_GPIO_BASE(pin) ((((pin) & ~31) >> 1) + S3C24XX_VA_GPIO) |
| 43 | #define S3C2410_GPIO_OFFSET(pin) ((pin) & 31) | 65 | #define S3C2410_GPIO_OFFSET(pin) ((pin) & 31) |
| 44 | 66 | ||
diff --git a/include/asm-arm/checksum.h b/include/asm-arm/checksum.h index d4256d5f3a7c..747bdd31a74b 100644 --- a/include/asm-arm/checksum.h +++ b/include/asm-arm/checksum.h | |||
| @@ -77,7 +77,7 @@ ip_fast_csum(unsigned char * iph, unsigned int ihl) | |||
| 77 | mov %0, %0, lsr #16" | 77 | mov %0, %0, lsr #16" |
| 78 | : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (tmp1) | 78 | : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (tmp1) |
| 79 | : "1" (iph), "2" (ihl) | 79 | : "1" (iph), "2" (ihl) |
| 80 | : "cc"); | 80 | : "cc", "memory"); |
| 81 | return sum; | 81 | return sum; |
| 82 | } | 82 | } |
| 83 | 83 | ||
diff --git a/include/asm-arm/mutex.h b/include/asm-arm/mutex.h index 6caa59f1f595..cb29d84e690d 100644 --- a/include/asm-arm/mutex.h +++ b/include/asm-arm/mutex.h | |||
| @@ -23,72 +23,71 @@ | |||
| 23 | * simply bail out immediately through the slow path where the lock will be | 23 | * simply bail out immediately through the slow path where the lock will be |
| 24 | * reattempted until it succeeds. | 24 | * reattempted until it succeeds. |
| 25 | */ | 25 | */ |
| 26 | #define __mutex_fastpath_lock(count, fail_fn) \ | 26 | static inline void |
| 27 | do { \ | 27 | __mutex_fastpath_lock(atomic_t *count, fastcall void (*fail_fn)(atomic_t *)) |
| 28 | int __ex_flag, __res; \ | 28 | { |
| 29 | \ | 29 | int __ex_flag, __res; |
| 30 | typecheck(atomic_t *, count); \ | 30 | |
| 31 | typecheck_fn(fastcall void (*)(atomic_t *), fail_fn); \ | 31 | __asm__ ( |
| 32 | \ | 32 | |
| 33 | __asm__ ( \ | 33 | "ldrex %0, [%2] \n\t" |
| 34 | "ldrex %0, [%2] \n" \ | 34 | "sub %0, %0, #1 \n\t" |
| 35 | "sub %0, %0, #1 \n" \ | 35 | "strex %1, %0, [%2] " |
| 36 | "strex %1, %0, [%2] \n" \ | 36 | |
| 37 | \ | 37 | : "=&r" (__res), "=&r" (__ex_flag) |
| 38 | : "=&r" (__res), "=&r" (__ex_flag) \ | 38 | : "r" (&(count)->counter) |
| 39 | : "r" (&(count)->counter) \ | 39 | : "cc","memory" ); |
| 40 | : "cc","memory" ); \ | 40 | |
| 41 | \ | 41 | __res |= __ex_flag; |
| 42 | if (unlikely(__res || __ex_flag)) \ | 42 | if (unlikely(__res != 0)) |
| 43 | fail_fn(count); \ | 43 | fail_fn(count); |
| 44 | } while (0) | 44 | } |
| 45 | 45 | ||
| 46 | #define __mutex_fastpath_lock_retval(count, fail_fn) \ | 46 | static inline int |
| 47 | ({ \ | 47 | __mutex_fastpath_lock_retval(atomic_t *count, fastcall int (*fail_fn)(atomic_t *)) |
| 48 | int __ex_flag, __res; \ | 48 | { |
| 49 | \ | 49 | int __ex_flag, __res; |
| 50 | typecheck(atomic_t *, count); \ | 50 | |
| 51 | typecheck_fn(fastcall int (*)(atomic_t *), fail_fn); \ | 51 | __asm__ ( |
| 52 | \ | 52 | |
| 53 | __asm__ ( \ | 53 | "ldrex %0, [%2] \n\t" |
| 54 | "ldrex %0, [%2] \n" \ | 54 | "sub %0, %0, #1 \n\t" |
| 55 | "sub %0, %0, #1 \n" \ | 55 | "strex %1, %0, [%2] " |
| 56 | "strex %1, %0, [%2] \n" \ | 56 | |
| 57 | \ | 57 | : "=&r" (__res), "=&r" (__ex_flag) |
| 58 | : "=&r" (__res), "=&r" (__ex_flag) \ | 58 | : "r" (&(count)->counter) |
| 59 | : "r" (&(count)->counter) \ | 59 | : "cc","memory" ); |
| 60 | : "cc","memory" ); \ | 60 | |
| 61 | \ | 61 | __res |= __ex_flag; |
| 62 | __res |= __ex_flag; \ | 62 | if (unlikely(__res != 0)) |
| 63 | if (unlikely(__res != 0)) \ | 63 | __res = fail_fn(count); |
| 64 | __res = fail_fn(count); \ | 64 | return __res; |
| 65 | __res; \ | 65 | } |
| 66 | }) | ||
| 67 | 66 | ||
| 68 | /* | 67 | /* |
| 69 | * Same trick is used for the unlock fast path. However the original value, | 68 | * Same trick is used for the unlock fast path. However the original value, |
| 70 | * rather than the result, is used to test for success in order to have | 69 | * rather than the result, is used to test for success in order to have |
| 71 | * better generated assembly. | 70 | * better generated assembly. |
| 72 | */ | 71 | */ |
| 73 | #define __mutex_fastpath_unlock(count, fail_fn) \ | 72 | static inline void |
| 74 | do { \ | 73 | __mutex_fastpath_unlock(atomic_t *count, fastcall void (*fail_fn)(atomic_t *)) |
| 75 | int __ex_flag, __res, __orig; \ | 74 | { |
| 76 | \ | 75 | int __ex_flag, __res, __orig; |
| 77 | typecheck(atomic_t *, count); \ | 76 | |
| 78 | typecheck_fn(fastcall void (*)(atomic_t *), fail_fn); \ | 77 | __asm__ ( |
| 79 | \ | 78 | |
| 80 | __asm__ ( \ | 79 | "ldrex %0, [%3] \n\t" |
| 81 | "ldrex %0, [%3] \n" \ | 80 | "add %1, %0, #1 \n\t" |
| 82 | "add %1, %0, #1 \n" \ | 81 | "strex %2, %1, [%3] " |
| 83 | "strex %2, %1, [%3] \n" \ | 82 | |
| 84 | \ | 83 | : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag) |
| 85 | : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag) \ | 84 | : "r" (&(count)->counter) |
| 86 | : "r" (&(count)->counter) \ | 85 | : "cc","memory" ); |
| 87 | : "cc","memory" ); \ | 86 | |
| 88 | \ | 87 | __orig |= __ex_flag; |
| 89 | if (unlikely(__orig || __ex_flag)) \ | 88 | if (unlikely(__orig != 0)) |
| 90 | fail_fn(count); \ | 89 | fail_fn(count); |
| 91 | } while (0) | 90 | } |
| 92 | 91 | ||
| 93 | /* | 92 | /* |
| 94 | * If the unlock was done on a contended lock, or if the unlock simply fails | 93 | * If the unlock was done on a contended lock, or if the unlock simply fails |
| @@ -110,12 +109,12 @@ __mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *)) | |||
| 110 | 109 | ||
| 111 | __asm__ ( | 110 | __asm__ ( |
| 112 | 111 | ||
| 113 | "1: ldrex %0, [%3] \n" | 112 | "1: ldrex %0, [%3] \n\t" |
| 114 | "subs %1, %0, #1 \n" | 113 | "subs %1, %0, #1 \n\t" |
| 115 | "strexeq %2, %1, [%3] \n" | 114 | "strexeq %2, %1, [%3] \n\t" |
| 116 | "movlt %0, #0 \n" | 115 | "movlt %0, #0 \n\t" |
| 117 | "cmpeq %2, #0 \n" | 116 | "cmpeq %2, #0 \n\t" |
| 118 | "bgt 1b \n" | 117 | "bgt 1b " |
| 119 | 118 | ||
| 120 | : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag) | 119 | : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag) |
| 121 | : "r" (&count->counter) | 120 | : "r" (&count->counter) |
diff --git a/include/asm-cris/bitops.h b/include/asm-cris/bitops.h index d3eb0f1e4208..b7fef1572dc0 100644 --- a/include/asm-cris/bitops.h +++ b/include/asm-cris/bitops.h | |||
| @@ -290,7 +290,7 @@ static inline int find_next_zero_bit (const unsigned long * addr, int size, int | |||
| 290 | tmp = *p; | 290 | tmp = *p; |
| 291 | 291 | ||
| 292 | found_first: | 292 | found_first: |
| 293 | tmp |= ~0UL >> size; | 293 | tmp |= ~0UL << size; |
| 294 | found_middle: | 294 | found_middle: |
| 295 | return result + ffz(tmp); | 295 | return result + ffz(tmp); |
| 296 | } | 296 | } |
diff --git a/include/asm-frv/bitops.h b/include/asm-frv/bitops.h index 02be7b3a8a83..f686b519878e 100644 --- a/include/asm-frv/bitops.h +++ b/include/asm-frv/bitops.h | |||
| @@ -209,7 +209,7 @@ static inline int find_next_zero_bit(const void *addr, int size, int offset) | |||
| 209 | tmp = *p; | 209 | tmp = *p; |
| 210 | 210 | ||
| 211 | found_first: | 211 | found_first: |
| 212 | tmp |= ~0UL >> size; | 212 | tmp |= ~0UL << size; |
| 213 | found_middle: | 213 | found_middle: |
| 214 | return result + ffz(tmp); | 214 | return result + ffz(tmp); |
| 215 | } | 215 | } |
diff --git a/include/asm-h8300/bitops.h b/include/asm-h8300/bitops.h index c0411ec9d651..ff7c2b721594 100644 --- a/include/asm-h8300/bitops.h +++ b/include/asm-h8300/bitops.h | |||
| @@ -227,7 +227,7 @@ static __inline__ int find_next_zero_bit (const unsigned long * addr, int size, | |||
| 227 | tmp = *p; | 227 | tmp = *p; |
| 228 | 228 | ||
| 229 | found_first: | 229 | found_first: |
| 230 | tmp |= ~0UL >> size; | 230 | tmp |= ~0UL << size; |
| 231 | found_middle: | 231 | found_middle: |
| 232 | return result + ffz(tmp); | 232 | return result + ffz(tmp); |
| 233 | } | 233 | } |
diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h index 36a92ed6a9d0..399145a247f2 100644 --- a/include/asm-i386/system.h +++ b/include/asm-i386/system.h | |||
| @@ -507,7 +507,7 @@ struct alt_instr { | |||
| 507 | #define smp_rmb() rmb() | 507 | #define smp_rmb() rmb() |
| 508 | #define smp_wmb() wmb() | 508 | #define smp_wmb() wmb() |
| 509 | #define smp_read_barrier_depends() read_barrier_depends() | 509 | #define smp_read_barrier_depends() read_barrier_depends() |
| 510 | #define set_mb(var, value) do { xchg(&var, value); } while (0) | 510 | #define set_mb(var, value) do { (void) xchg(&var, value); } while (0) |
| 511 | #else | 511 | #else |
| 512 | #define smp_mb() barrier() | 512 | #define smp_mb() barrier() |
| 513 | #define smp_rmb() barrier() | 513 | #define smp_rmb() barrier() |
diff --git a/include/asm-i386/topology.h b/include/asm-i386/topology.h index d7e19eb344b7..af503a122b23 100644 --- a/include/asm-i386/topology.h +++ b/include/asm-i386/topology.h | |||
| @@ -27,6 +27,15 @@ | |||
| 27 | #ifndef _ASM_I386_TOPOLOGY_H | 27 | #ifndef _ASM_I386_TOPOLOGY_H |
| 28 | #define _ASM_I386_TOPOLOGY_H | 28 | #define _ASM_I386_TOPOLOGY_H |
| 29 | 29 | ||
| 30 | #ifdef CONFIG_SMP | ||
| 31 | #define topology_physical_package_id(cpu) \ | ||
| 32 | (phys_proc_id[cpu] == BAD_APICID ? -1 : phys_proc_id[cpu]) | ||
| 33 | #define topology_core_id(cpu) \ | ||
| 34 | (cpu_core_id[cpu] == BAD_APICID ? 0 : cpu_core_id[cpu]) | ||
| 35 | #define topology_core_siblings(cpu) (cpu_core_map[cpu]) | ||
| 36 | #define topology_thread_siblings(cpu) (cpu_sibling_map[cpu]) | ||
| 37 | #endif | ||
| 38 | |||
| 30 | #ifdef CONFIG_NUMA | 39 | #ifdef CONFIG_NUMA |
| 31 | 40 | ||
| 32 | #include <asm/mpspec.h> | 41 | #include <asm/mpspec.h> |
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h index 597496ed2aee..cf6f2cd9c514 100644 --- a/include/asm-i386/unistd.h +++ b/include/asm-i386/unistd.h | |||
| @@ -315,8 +315,9 @@ | |||
| 315 | #define __NR_faccessat 307 | 315 | #define __NR_faccessat 307 |
| 316 | #define __NR_pselect6 308 | 316 | #define __NR_pselect6 308 |
| 317 | #define __NR_ppoll 309 | 317 | #define __NR_ppoll 309 |
| 318 | #define __NR_unshare 310 | ||
| 318 | 319 | ||
| 319 | #define NR_syscalls 310 | 320 | #define NR_syscalls 311 |
| 320 | 321 | ||
| 321 | /* | 322 | /* |
| 322 | * user-visible error numbers are in the range -1 - -128: see | 323 | * user-visible error numbers are in the range -1 - -128: see |
diff --git a/include/asm-ia64/ide.h b/include/asm-ia64/ide.h index e62b95301d51..93f45c5f189f 100644 --- a/include/asm-ia64/ide.h +++ b/include/asm-ia64/ide.h | |||
| @@ -17,14 +17,6 @@ | |||
| 17 | 17 | ||
| 18 | #include <linux/irq.h> | 18 | #include <linux/irq.h> |
| 19 | 19 | ||
| 20 | #ifndef MAX_HWIFS | ||
| 21 | # ifdef CONFIG_PCI | ||
| 22 | #define MAX_HWIFS 10 | ||
| 23 | # else | ||
| 24 | #define MAX_HWIFS 6 | ||
| 25 | # endif | ||
| 26 | #endif | ||
| 27 | |||
| 28 | #define IDE_ARCH_OBSOLETE_DEFAULTS | 20 | #define IDE_ARCH_OBSOLETE_DEFAULTS |
| 29 | 21 | ||
| 30 | static inline int ide_default_irq(unsigned long base) | 22 | static inline int ide_default_irq(unsigned long base) |
diff --git a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h index 09b99029ac1a..23c8e1be1911 100644 --- a/include/asm-ia64/processor.h +++ b/include/asm-ia64/processor.h | |||
| @@ -559,6 +559,23 @@ ia64_eoi (void) | |||
| 559 | 559 | ||
| 560 | #define cpu_relax() ia64_hint(ia64_hint_pause) | 560 | #define cpu_relax() ia64_hint(ia64_hint_pause) |
| 561 | 561 | ||
| 562 | static inline int | ||
| 563 | ia64_get_irr(unsigned int vector) | ||
| 564 | { | ||
| 565 | unsigned int reg = vector / 64; | ||
| 566 | unsigned int bit = vector % 64; | ||
| 567 | u64 irr; | ||
| 568 | |||
| 569 | switch (reg) { | ||
| 570 | case 0: irr = ia64_getreg(_IA64_REG_CR_IRR0); break; | ||
| 571 | case 1: irr = ia64_getreg(_IA64_REG_CR_IRR1); break; | ||
| 572 | case 2: irr = ia64_getreg(_IA64_REG_CR_IRR2); break; | ||
| 573 | case 3: irr = ia64_getreg(_IA64_REG_CR_IRR3); break; | ||
| 574 | } | ||
| 575 | |||
| 576 | return test_bit(bit, &irr); | ||
| 577 | } | ||
| 578 | |||
| 562 | static inline void | 579 | static inline void |
| 563 | ia64_set_lrr0 (unsigned long val) | 580 | ia64_set_lrr0 (unsigned long val) |
| 564 | { | 581 | { |
diff --git a/include/asm-ia64/sal.h b/include/asm-ia64/sal.h index 313cad0628d0..0b210abbe003 100644 --- a/include/asm-ia64/sal.h +++ b/include/asm-ia64/sal.h | |||
| @@ -658,15 +658,7 @@ ia64_sal_freq_base (unsigned long which, unsigned long *ticks_per_second, | |||
| 658 | return isrv.status; | 658 | return isrv.status; |
| 659 | } | 659 | } |
| 660 | 660 | ||
| 661 | /* Flush all the processor and platform level instruction and/or data caches */ | 661 | extern s64 ia64_sal_cache_flush (u64 cache_type); |
| 662 | static inline s64 | ||
| 663 | ia64_sal_cache_flush (u64 cache_type) | ||
| 664 | { | ||
| 665 | struct ia64_sal_retval isrv; | ||
| 666 | SAL_CALL(isrv, SAL_CACHE_FLUSH, cache_type, 0, 0, 0, 0, 0, 0); | ||
| 667 | return isrv.status; | ||
| 668 | } | ||
| 669 | |||
| 670 | 662 | ||
| 671 | /* Initialize all the processor and platform level instruction and data caches */ | 663 | /* Initialize all the processor and platform level instruction and data caches */ |
| 672 | static inline s64 | 664 | static inline s64 |
diff --git a/include/asm-ia64/sn/bte.h b/include/asm-ia64/sn/bte.h index f50da3d91d07..01e5b4103235 100644 --- a/include/asm-ia64/sn/bte.h +++ b/include/asm-ia64/sn/bte.h | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
| 4 | * for more details. | 4 | * for more details. |
| 5 | * | 5 | * |
| 6 | * Copyright (c) 2000-2005 Silicon Graphics, Inc. All Rights Reserved. | 6 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | 9 | ||
| @@ -100,13 +100,28 @@ | |||
| 100 | #define BTE_LNSTAT_STORE(_bte, _x) \ | 100 | #define BTE_LNSTAT_STORE(_bte, _x) \ |
| 101 | HUB_S(_bte->bte_base_addr, (_x)) | 101 | HUB_S(_bte->bte_base_addr, (_x)) |
| 102 | #define BTE_SRC_STORE(_bte, _x) \ | 102 | #define BTE_SRC_STORE(_bte, _x) \ |
| 103 | HUB_S(_bte->bte_source_addr, (_x)) | 103 | ({ \ |
| 104 | u64 __addr = ((_x) & ~AS_MASK); \ | ||
| 105 | if (is_shub2()) \ | ||
| 106 | __addr = SH2_TIO_PHYS_TO_DMA(__addr); \ | ||
| 107 | HUB_S(_bte->bte_source_addr, __addr); \ | ||
| 108 | }) | ||
| 104 | #define BTE_DEST_STORE(_bte, _x) \ | 109 | #define BTE_DEST_STORE(_bte, _x) \ |
| 105 | HUB_S(_bte->bte_destination_addr, (_x)) | 110 | ({ \ |
| 111 | u64 __addr = ((_x) & ~AS_MASK); \ | ||
| 112 | if (is_shub2()) \ | ||
| 113 | __addr = SH2_TIO_PHYS_TO_DMA(__addr); \ | ||
| 114 | HUB_S(_bte->bte_destination_addr, __addr); \ | ||
| 115 | }) | ||
| 106 | #define BTE_CTRL_STORE(_bte, _x) \ | 116 | #define BTE_CTRL_STORE(_bte, _x) \ |
| 107 | HUB_S(_bte->bte_control_addr, (_x)) | 117 | HUB_S(_bte->bte_control_addr, (_x)) |
| 108 | #define BTE_NOTIF_STORE(_bte, _x) \ | 118 | #define BTE_NOTIF_STORE(_bte, _x) \ |
| 109 | HUB_S(_bte->bte_notify_addr, (_x)) | 119 | ({ \ |
| 120 | u64 __addr = ia64_tpa((_x) & ~AS_MASK); \ | ||
| 121 | if (is_shub2()) \ | ||
| 122 | __addr = SH2_TIO_PHYS_TO_DMA(__addr); \ | ||
| 123 | HUB_S(_bte->bte_notify_addr, __addr); \ | ||
| 124 | }) | ||
| 110 | 125 | ||
| 111 | #define BTE_START_TRANSFER(_bte, _len, _mode) \ | 126 | #define BTE_START_TRANSFER(_bte, _len, _mode) \ |
| 112 | is_shub2() ? BTE_CTRL_STORE(_bte, IBLS_BUSY | (_mode << 24) | _len) \ | 127 | is_shub2() ? BTE_CTRL_STORE(_bte, IBLS_BUSY | (_mode << 24) | _len) \ |
diff --git a/include/asm-ia64/sn/intr.h b/include/asm-ia64/sn/intr.h index a3431372c6e7..60a51a406eec 100644 --- a/include/asm-ia64/sn/intr.h +++ b/include/asm-ia64/sn/intr.h | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
| 4 | * for more details. | 4 | * for more details. |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 1992 - 1997, 2000-2004 Silicon Graphics, Inc. All rights reserved. | 6 | * Copyright (C) 1992 - 1997, 2000-2006 Silicon Graphics, Inc. All rights reserved. |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #ifndef _ASM_IA64_SN_INTR_H | 9 | #ifndef _ASM_IA64_SN_INTR_H |
| @@ -11,26 +11,26 @@ | |||
| 11 | 11 | ||
| 12 | #include <linux/rcupdate.h> | 12 | #include <linux/rcupdate.h> |
| 13 | 13 | ||
| 14 | #define SGI_UART_VECTOR (0xe9) | 14 | #define SGI_UART_VECTOR 0xe9 |
| 15 | 15 | ||
| 16 | /* Reserved IRQs : Note, not to exceed IA64_SN2_FIRST_DEVICE_VECTOR */ | 16 | /* Reserved IRQs : Note, not to exceed IA64_SN2_FIRST_DEVICE_VECTOR */ |
| 17 | #define SGI_XPC_ACTIVATE (0x30) | 17 | #define SGI_XPC_ACTIVATE 0x30 |
| 18 | #define SGI_II_ERROR (0x31) | 18 | #define SGI_II_ERROR 0x31 |
| 19 | #define SGI_XBOW_ERROR (0x32) | 19 | #define SGI_XBOW_ERROR 0x32 |
| 20 | #define SGI_PCIASIC_ERROR (0x33) | 20 | #define SGI_PCIASIC_ERROR 0x33 |
| 21 | #define SGI_ACPI_SCI_INT (0x34) | 21 | #define SGI_ACPI_SCI_INT 0x34 |
| 22 | #define SGI_TIOCA_ERROR (0x35) | 22 | #define SGI_TIOCA_ERROR 0x35 |
| 23 | #define SGI_TIO_ERROR (0x36) | 23 | #define SGI_TIO_ERROR 0x36 |
| 24 | #define SGI_TIOCX_ERROR (0x37) | 24 | #define SGI_TIOCX_ERROR 0x37 |
| 25 | #define SGI_MMTIMER_VECTOR (0x38) | 25 | #define SGI_MMTIMER_VECTOR 0x38 |
| 26 | #define SGI_XPC_NOTIFY (0xe7) | 26 | #define SGI_XPC_NOTIFY 0xe7 |
| 27 | 27 | ||
| 28 | #define IA64_SN2_FIRST_DEVICE_VECTOR (0x3c) | 28 | #define IA64_SN2_FIRST_DEVICE_VECTOR 0x3c |
| 29 | #define IA64_SN2_LAST_DEVICE_VECTOR (0xe6) | 29 | #define IA64_SN2_LAST_DEVICE_VECTOR 0xe6 |
| 30 | 30 | ||
| 31 | #define SN2_IRQ_RESERVED (0x1) | 31 | #define SN2_IRQ_RESERVED 0x1 |
| 32 | #define SN2_IRQ_CONNECTED (0x2) | 32 | #define SN2_IRQ_CONNECTED 0x2 |
| 33 | #define SN2_IRQ_SHARED (0x4) | 33 | #define SN2_IRQ_SHARED 0x4 |
| 34 | 34 | ||
| 35 | // The SN PROM irq struct | 35 | // The SN PROM irq struct |
| 36 | struct sn_irq_info { | 36 | struct sn_irq_info { |
diff --git a/include/asm-ia64/system.h b/include/asm-ia64/system.h index 80c5a234e259..062538715623 100644 --- a/include/asm-ia64/system.h +++ b/include/asm-ia64/system.h | |||
| @@ -249,32 +249,7 @@ extern void ia64_load_extra (struct task_struct *task); | |||
| 249 | # define switch_to(prev,next,last) __switch_to(prev, next, last) | 249 | # define switch_to(prev,next,last) __switch_to(prev, next, last) |
| 250 | #endif | 250 | #endif |
| 251 | 251 | ||
| 252 | /* | ||
| 253 | * On IA-64, we don't want to hold the runqueue's lock during the low-level context-switch, | ||
| 254 | * because that could cause a deadlock. Here is an example by Erich Focht: | ||
| 255 | * | ||
| 256 | * Example: | ||
| 257 | * CPU#0: | ||
| 258 | * schedule() | ||
| 259 | * -> spin_lock_irq(&rq->lock) | ||
| 260 | * -> context_switch() | ||
| 261 | * -> wrap_mmu_context() | ||
| 262 | * -> read_lock(&tasklist_lock) | ||
| 263 | * | ||
| 264 | * CPU#1: | ||
| 265 | * sys_wait4() or release_task() or forget_original_parent() | ||
| 266 | * -> write_lock(&tasklist_lock) | ||
| 267 | * -> do_notify_parent() | ||
| 268 | * -> wake_up_parent() | ||
| 269 | * -> try_to_wake_up() | ||
| 270 | * -> spin_lock_irq(&parent_rq->lock) | ||
| 271 | * | ||
| 272 | * If the parent's rq happens to be on CPU#0, we'll wait for the rq->lock | ||
| 273 | * of that CPU which will not be released, because there we wait for the | ||
| 274 | * tasklist_lock to become available. | ||
| 275 | */ | ||
| 276 | #define __ARCH_WANT_UNLOCKED_CTXSW | 252 | #define __ARCH_WANT_UNLOCKED_CTXSW |
| 277 | |||
| 278 | #define ARCH_HAS_PREFETCH_SWITCH_STACK | 253 | #define ARCH_HAS_PREFETCH_SWITCH_STACK |
| 279 | #define ia64_platform_is(x) (strcmp(x, platform_name) == 0) | 254 | #define ia64_platform_is(x) (strcmp(x, platform_name) == 0) |
| 280 | 255 | ||
diff --git a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h index 412ef8e493a8..3ee19dfa46df 100644 --- a/include/asm-ia64/topology.h +++ b/include/asm-ia64/topology.h | |||
| @@ -102,6 +102,13 @@ void build_cpu_to_node_map(void); | |||
| 102 | 102 | ||
| 103 | #endif /* CONFIG_NUMA */ | 103 | #endif /* CONFIG_NUMA */ |
| 104 | 104 | ||
| 105 | #ifdef CONFIG_SMP | ||
| 106 | #define topology_physical_package_id(cpu) (cpu_data(cpu)->socket_id) | ||
| 107 | #define topology_core_id(cpu) (cpu_data(cpu)->core_id) | ||
| 108 | #define topology_core_siblings(cpu) (cpu_core_map[cpu]) | ||
| 109 | #define topology_thread_siblings(cpu) (cpu_sibling_map[cpu]) | ||
| 110 | #endif | ||
| 111 | |||
| 105 | #include <asm-generic/topology.h> | 112 | #include <asm-generic/topology.h> |
| 106 | 113 | ||
| 107 | #endif /* _ASM_IA64_TOPOLOGY_H */ | 114 | #endif /* _ASM_IA64_TOPOLOGY_H */ |
diff --git a/include/asm-m68knommu/hardirq.h b/include/asm-m68knommu/hardirq.h index e8659e739a64..476180f4cba2 100644 --- a/include/asm-m68knommu/hardirq.h +++ b/include/asm-m68knommu/hardirq.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #include <linux/config.h> | 4 | #include <linux/config.h> |
| 5 | #include <linux/cache.h> | 5 | #include <linux/cache.h> |
| 6 | #include <linux/threads.h> | 6 | #include <linux/threads.h> |
| 7 | #include <asm/irq.h> | ||
| 7 | 8 | ||
| 8 | typedef struct { | 9 | typedef struct { |
| 9 | unsigned int __softirq_pending; | 10 | unsigned int __softirq_pending; |
diff --git a/include/asm-mips/abi.h b/include/asm-mips/abi.h index 2e7e651c3e3f..1ce0518ace2e 100644 --- a/include/asm-mips/abi.h +++ b/include/asm-mips/abi.h | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
| 4 | * for more details. | 4 | * for more details. |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2005 by Ralf Baechle | 6 | * Copyright (C) 2005, 06 by Ralf Baechle (ralf@linux-mips.org) |
| 7 | * Copyright (C) 2005 MIPS Technologies, Inc. | 7 | * Copyright (C) 2005 MIPS Technologies, Inc. |
| 8 | */ | 8 | */ |
| 9 | #ifndef _ASM_ABI_H | 9 | #ifndef _ASM_ABI_H |
| @@ -13,7 +13,7 @@ | |||
| 13 | #include <asm/siginfo.h> | 13 | #include <asm/siginfo.h> |
| 14 | 14 | ||
| 15 | struct mips_abi { | 15 | struct mips_abi { |
| 16 | int (* const do_signal)(sigset_t *oldset, struct pt_regs *regs); | 16 | void (* const do_signal)(struct pt_regs *regs); |
| 17 | int (* const setup_frame)(struct k_sigaction * ka, | 17 | int (* const setup_frame)(struct k_sigaction * ka, |
| 18 | struct pt_regs *regs, int signr, | 18 | struct pt_regs *regs, int signr, |
| 19 | sigset_t *set); | 19 | sigset_t *set); |
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h index 3b0c8aaf6e8b..8e802059fe67 100644 --- a/include/asm-mips/bitops.h +++ b/include/asm-mips/bitops.h | |||
| @@ -644,20 +644,26 @@ static inline unsigned long ffz(unsigned long word) | |||
| 644 | } | 644 | } |
| 645 | 645 | ||
| 646 | /* | 646 | /* |
| 647 | * flz - find last zero in word. | 647 | * fls - find last bit set. |
| 648 | * @word: The word to search | 648 | * @word: The word to search |
| 649 | * | 649 | * |
| 650 | * Returns 0..SZLONG-1 | 650 | * Returns 1..SZLONG |
| 651 | * Undefined if no zero exists, so code should check against ~0UL first. | 651 | * Returns 0 if no bit exists |
| 652 | */ | 652 | */ |
| 653 | static inline unsigned long flz(unsigned long word) | 653 | static inline unsigned long fls(unsigned long word) |
| 654 | { | 654 | { |
| 655 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) | ||
| 656 | return __ilog2(~word); | ||
| 657 | #else | ||
| 658 | #ifdef CONFIG_32BIT | 655 | #ifdef CONFIG_32BIT |
| 659 | int r = 31, s; | 656 | #ifdef CONFIG_CPU_MIPS32 |
| 660 | word = ~word; | 657 | __asm__ ("clz %0, %1" : "=r" (word) : "r" (word)); |
| 658 | |||
| 659 | return 32 - word; | ||
| 660 | #else | ||
| 661 | { | ||
| 662 | int r = 32, s; | ||
| 663 | |||
| 664 | if (word == 0) | ||
| 665 | return 0; | ||
| 666 | |||
| 661 | s = 16; if ((word & 0xffff0000)) s = 0; r -= s; word <<= s; | 667 | s = 16; if ((word & 0xffff0000)) s = 0; r -= s; word <<= s; |
| 662 | s = 8; if ((word & 0xff000000)) s = 0; r -= s; word <<= s; | 668 | s = 8; if ((word & 0xff000000)) s = 0; r -= s; word <<= s; |
| 663 | s = 4; if ((word & 0xf0000000)) s = 0; r -= s; word <<= s; | 669 | s = 4; if ((word & 0xf0000000)) s = 0; r -= s; word <<= s; |
| @@ -665,10 +671,23 @@ static inline unsigned long flz(unsigned long word) | |||
| 665 | s = 1; if ((word & 0x80000000)) s = 0; r -= s; | 671 | s = 1; if ((word & 0x80000000)) s = 0; r -= s; |
| 666 | 672 | ||
| 667 | return r; | 673 | return r; |
| 674 | } | ||
| 668 | #endif | 675 | #endif |
| 676 | #endif /* CONFIG_32BIT */ | ||
| 677 | |||
| 669 | #ifdef CONFIG_64BIT | 678 | #ifdef CONFIG_64BIT |
| 670 | int r = 63, s; | 679 | #ifdef CONFIG_CPU_MIPS64 |
| 671 | word = ~word; | 680 | |
| 681 | __asm__ ("dclz %0, %1" : "=r" (word) : "r" (word)); | ||
| 682 | |||
| 683 | return 64 - word; | ||
| 684 | #else | ||
| 685 | { | ||
| 686 | int r = 64, s; | ||
| 687 | |||
| 688 | if (word == 0) | ||
| 689 | return 0; | ||
| 690 | |||
| 672 | s = 32; if ((word & 0xffffffff00000000UL)) s = 0; r -= s; word <<= s; | 691 | s = 32; if ((word & 0xffffffff00000000UL)) s = 0; r -= s; word <<= s; |
| 673 | s = 16; if ((word & 0xffff000000000000UL)) s = 0; r -= s; word <<= s; | 692 | s = 16; if ((word & 0xffff000000000000UL)) s = 0; r -= s; word <<= s; |
| 674 | s = 8; if ((word & 0xff00000000000000UL)) s = 0; r -= s; word <<= s; | 693 | s = 8; if ((word & 0xff00000000000000UL)) s = 0; r -= s; word <<= s; |
| @@ -677,24 +696,11 @@ static inline unsigned long flz(unsigned long word) | |||
| 677 | s = 1; if ((word & 0x8000000000000000UL)) s = 0; r -= s; | 696 | s = 1; if ((word & 0x8000000000000000UL)) s = 0; r -= s; |
| 678 | 697 | ||
| 679 | return r; | 698 | return r; |
| 699 | } | ||
| 680 | #endif | 700 | #endif |
| 681 | #endif | 701 | #endif /* CONFIG_64BIT */ |
| 682 | } | 702 | } |
| 683 | 703 | ||
| 684 | /* | ||
| 685 | * fls - find last bit set. | ||
| 686 | * @word: The word to search | ||
| 687 | * | ||
| 688 | * Returns 1..SZLONG | ||
| 689 | * Returns 0 if no bit exists | ||
| 690 | */ | ||
| 691 | static inline unsigned long fls(unsigned long word) | ||
| 692 | { | ||
| 693 | if (word == 0) | ||
| 694 | return 0; | ||
| 695 | |||
| 696 | return flz(~word) + 1; | ||
| 697 | } | ||
| 698 | #define fls64(x) generic_fls64(x) | 704 | #define fls64(x) generic_fls64(x) |
| 699 | 705 | ||
| 700 | /* | 706 | /* |
diff --git a/include/asm-mips/byteorder.h b/include/asm-mips/byteorder.h index d1fe9e5c62e4..584f8128fffd 100644 --- a/include/asm-mips/byteorder.h +++ b/include/asm-mips/byteorder.h | |||
| @@ -8,10 +8,39 @@ | |||
| 8 | #ifndef _ASM_BYTEORDER_H | 8 | #ifndef _ASM_BYTEORDER_H |
| 9 | #define _ASM_BYTEORDER_H | 9 | #define _ASM_BYTEORDER_H |
| 10 | 10 | ||
| 11 | #include <linux/config.h> | ||
| 12 | #include <linux/compiler.h> | ||
| 11 | #include <asm/types.h> | 13 | #include <asm/types.h> |
| 12 | 14 | ||
| 13 | #ifdef __GNUC__ | 15 | #ifdef __GNUC__ |
| 14 | 16 | ||
| 17 | #ifdef CONFIG_CPU_MIPSR2 | ||
| 18 | |||
| 19 | static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x) | ||
| 20 | { | ||
| 21 | __asm__( | ||
| 22 | " wsbh %0, %1 \n" | ||
| 23 | : "=r" (x) | ||
| 24 | : "r" (x)); | ||
| 25 | |||
| 26 | return x; | ||
| 27 | } | ||
| 28 | #define __arch__swab16(x) ___arch__swab16(x) | ||
| 29 | |||
| 30 | static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x) | ||
| 31 | { | ||
| 32 | __asm__( | ||
| 33 | " wsbh %0, %1 \n" | ||
| 34 | " rotr %0, %0, 16 \n" | ||
| 35 | : "=r" (x) | ||
| 36 | : "r" (x)); | ||
| 37 | |||
| 38 | return x; | ||
| 39 | } | ||
| 40 | #define __arch__swab32(x) ___arch__swab32(x) | ||
| 41 | |||
| 42 | #endif /* CONFIG_CPU_MIPSR2 */ | ||
| 43 | |||
| 15 | #if !defined(__STRICT_ANSI__) || defined(__KERNEL__) | 44 | #if !defined(__STRICT_ANSI__) || defined(__KERNEL__) |
| 16 | # define __BYTEORDER_HAS_U64__ | 45 | # define __BYTEORDER_HAS_U64__ |
| 17 | # define __SWAB_64_THRU_32__ | 46 | # define __SWAB_64_THRU_32__ |
diff --git a/include/asm-mips/cacheflush.h b/include/asm-mips/cacheflush.h index a18ba2edc0b6..aeae9fabf4a9 100644 --- a/include/asm-mips/cacheflush.h +++ b/include/asm-mips/cacheflush.h | |||
| @@ -49,8 +49,7 @@ static inline void flush_dcache_page(struct page *page) | |||
| 49 | 49 | ||
| 50 | extern void (*flush_icache_page)(struct vm_area_struct *vma, | 50 | extern void (*flush_icache_page)(struct vm_area_struct *vma, |
| 51 | struct page *page); | 51 | struct page *page); |
| 52 | extern void (*flush_icache_range)(unsigned long __user start, | 52 | extern void (*flush_icache_range)(unsigned long start, unsigned long end); |
| 53 | unsigned long __user end); | ||
| 54 | #define flush_cache_vmap(start, end) flush_cache_all() | 53 | #define flush_cache_vmap(start, end) flush_cache_all() |
| 55 | #define flush_cache_vunmap(start, end) flush_cache_all() | 54 | #define flush_cache_vunmap(start, end) flush_cache_all() |
| 56 | 55 | ||
diff --git a/include/asm-mips/hazards.h b/include/asm-mips/hazards.h index 2fc90632f88c..6111a0ce58c4 100644 --- a/include/asm-mips/hazards.h +++ b/include/asm-mips/hazards.h | |||
| @@ -100,7 +100,7 @@ | |||
| 100 | 100 | ||
| 101 | __asm__( | 101 | __asm__( |
| 102 | " .macro _ssnop \n\t" | 102 | " .macro _ssnop \n\t" |
| 103 | " sll $0, $2, 1 \n\t" | 103 | " sll $0, $0, 1 \n\t" |
| 104 | " .endm \n\t" | 104 | " .endm \n\t" |
| 105 | " \n\t" | 105 | " \n\t" |
| 106 | " .macro _ehb \n\t" | 106 | " .macro _ehb \n\t" |
diff --git a/include/asm-mips/interrupt.h b/include/asm-mips/interrupt.h index abdf54ee64cf..774348734fa0 100644 --- a/include/asm-mips/interrupt.h +++ b/include/asm-mips/interrupt.h | |||
| @@ -47,6 +47,17 @@ static inline void local_irq_enable(void) | |||
| 47 | * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs | 47 | * R4000/R4400 need three nops, the R4600 two nops and the R10000 needs |
| 48 | * no nops at all. | 48 | * no nops at all. |
| 49 | */ | 49 | */ |
| 50 | /* | ||
| 51 | * For TX49, operating only IE bit is not enough. | ||
| 52 | * | ||
| 53 | * If mfc0 $12 follows store and the mfc0 is last instruction of a | ||
| 54 | * page and fetching the next instruction causes TLB miss, the result | ||
| 55 | * of the mfc0 might wrongly contain EXL bit. | ||
| 56 | * | ||
| 57 | * ERT-TX49H2-027, ERT-TX49H3-012, ERT-TX49HL3-006, ERT-TX49H4-008 | ||
| 58 | * | ||
| 59 | * Workaround: mask EXL bit of the result or place a nop before mfc0. | ||
| 60 | */ | ||
| 50 | __asm__ ( | 61 | __asm__ ( |
| 51 | " .macro local_irq_disable\n" | 62 | " .macro local_irq_disable\n" |
| 52 | " .set push \n" | 63 | " .set push \n" |
| @@ -55,8 +66,8 @@ __asm__ ( | |||
| 55 | " di \n" | 66 | " di \n" |
| 56 | #else | 67 | #else |
| 57 | " mfc0 $1,$12 \n" | 68 | " mfc0 $1,$12 \n" |
| 58 | " ori $1,1 \n" | 69 | " ori $1,0x1f \n" |
| 59 | " xori $1,1 \n" | 70 | " xori $1,0x1f \n" |
| 60 | " .set noreorder \n" | 71 | " .set noreorder \n" |
| 61 | " mtc0 $1,$12 \n" | 72 | " mtc0 $1,$12 \n" |
| 62 | #endif | 73 | #endif |
| @@ -96,8 +107,8 @@ __asm__ ( | |||
| 96 | " andi \\result, 1 \n" | 107 | " andi \\result, 1 \n" |
| 97 | #else | 108 | #else |
| 98 | " mfc0 \\result, $12 \n" | 109 | " mfc0 \\result, $12 \n" |
| 99 | " ori $1, \\result, 1 \n" | 110 | " ori $1, \\result, 0x1f \n" |
| 100 | " xori $1, 1 \n" | 111 | " xori $1, 0x1f \n" |
| 101 | " .set noreorder \n" | 112 | " .set noreorder \n" |
| 102 | " mtc0 $1, $12 \n" | 113 | " mtc0 $1, $12 \n" |
| 103 | #endif | 114 | #endif |
| @@ -114,6 +125,7 @@ __asm__ __volatile__( \ | |||
| 114 | 125 | ||
| 115 | __asm__ ( | 126 | __asm__ ( |
| 116 | " .macro local_irq_restore flags \n" | 127 | " .macro local_irq_restore flags \n" |
| 128 | " .set push \n" | ||
| 117 | " .set noreorder \n" | 129 | " .set noreorder \n" |
| 118 | " .set noat \n" | 130 | " .set noat \n" |
| 119 | #if defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) | 131 | #if defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) |
| @@ -135,14 +147,13 @@ __asm__ ( | |||
| 135 | #else | 147 | #else |
| 136 | " mfc0 $1, $12 \n" | 148 | " mfc0 $1, $12 \n" |
| 137 | " andi \\flags, 1 \n" | 149 | " andi \\flags, 1 \n" |
| 138 | " ori $1, 1 \n" | 150 | " ori $1, 0x1f \n" |
| 139 | " xori $1, 1 \n" | 151 | " xori $1, 0x1f \n" |
| 140 | " or \\flags, $1 \n" | 152 | " or \\flags, $1 \n" |
| 141 | " mtc0 \\flags, $12 \n" | 153 | " mtc0 \\flags, $12 \n" |
| 142 | #endif | 154 | #endif |
| 143 | " irq_disable_hazard \n" | 155 | " irq_disable_hazard \n" |
| 144 | " .set at \n" | 156 | " .set pop \n" |
| 145 | " .set reorder \n" | ||
| 146 | " .endm \n"); | 157 | " .endm \n"); |
| 147 | 158 | ||
| 148 | #define local_irq_restore(flags) \ | 159 | #define local_irq_restore(flags) \ |
diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h index d42685747e7d..5a4c8a54b8f4 100644 --- a/include/asm-mips/io.h +++ b/include/asm-mips/io.h | |||
| @@ -18,7 +18,6 @@ | |||
| 18 | #include <linux/types.h> | 18 | #include <linux/types.h> |
| 19 | 19 | ||
| 20 | #include <asm/addrspace.h> | 20 | #include <asm/addrspace.h> |
| 21 | #include <asm/bug.h> | ||
| 22 | #include <asm/byteorder.h> | 21 | #include <asm/byteorder.h> |
| 23 | #include <asm/cpu.h> | 22 | #include <asm/cpu.h> |
| 24 | #include <asm/cpu-features.h> | 23 | #include <asm/cpu-features.h> |
| @@ -57,38 +56,38 @@ | |||
| 57 | * variations of functions: non-prefixed ones that preserve the value | 56 | * variations of functions: non-prefixed ones that preserve the value |
| 58 | * and prefixed ones that preserve byte addresses. The latters are | 57 | * and prefixed ones that preserve byte addresses. The latters are |
| 59 | * typically used for moving raw data between a peripheral and memory (cf. | 58 | * typically used for moving raw data between a peripheral and memory (cf. |
| 60 | * string I/O functions), hence the "mem_" prefix. | 59 | * string I/O functions), hence the "__mem_" prefix. |
| 61 | */ | 60 | */ |
| 62 | #if defined(CONFIG_SWAP_IO_SPACE) | 61 | #if defined(CONFIG_SWAP_IO_SPACE) |
| 63 | 62 | ||
| 64 | # define ioswabb(x) (x) | 63 | # define ioswabb(x) (x) |
| 65 | # define mem_ioswabb(x) (x) | 64 | # define __mem_ioswabb(x) (x) |
| 66 | # ifdef CONFIG_SGI_IP22 | 65 | # ifdef CONFIG_SGI_IP22 |
| 67 | /* | 66 | /* |
| 68 | * IP22 seems braindead enough to swap 16bits values in hardware, but | 67 | * IP22 seems braindead enough to swap 16bits values in hardware, but |
| 69 | * not 32bits. Go figure... Can't tell without documentation. | 68 | * not 32bits. Go figure... Can't tell without documentation. |
| 70 | */ | 69 | */ |
| 71 | # define ioswabw(x) (x) | 70 | # define ioswabw(x) (x) |
| 72 | # define mem_ioswabw(x) le16_to_cpu(x) | 71 | # define __mem_ioswabw(x) le16_to_cpu(x) |
| 73 | # else | 72 | # else |
| 74 | # define ioswabw(x) le16_to_cpu(x) | 73 | # define ioswabw(x) le16_to_cpu(x) |
| 75 | # define mem_ioswabw(x) (x) | 74 | # define __mem_ioswabw(x) (x) |
| 76 | # endif | 75 | # endif |
| 77 | # define ioswabl(x) le32_to_cpu(x) | 76 | # define ioswabl(x) le32_to_cpu(x) |
| 78 | # define mem_ioswabl(x) (x) | 77 | # define __mem_ioswabl(x) (x) |
| 79 | # define ioswabq(x) le64_to_cpu(x) | 78 | # define ioswabq(x) le64_to_cpu(x) |
| 80 | # define mem_ioswabq(x) (x) | 79 | # define __mem_ioswabq(x) (x) |
| 81 | 80 | ||
| 82 | #else | 81 | #else |
| 83 | 82 | ||
| 84 | # define ioswabb(x) (x) | 83 | # define ioswabb(x) (x) |
| 85 | # define mem_ioswabb(x) (x) | 84 | # define __mem_ioswabb(x) (x) |
| 86 | # define ioswabw(x) (x) | 85 | # define ioswabw(x) (x) |
| 87 | # define mem_ioswabw(x) cpu_to_le16(x) | 86 | # define __mem_ioswabw(x) cpu_to_le16(x) |
| 88 | # define ioswabl(x) (x) | 87 | # define ioswabl(x) (x) |
| 89 | # define mem_ioswabl(x) cpu_to_le32(x) | 88 | # define __mem_ioswabl(x) cpu_to_le32(x) |
| 90 | # define ioswabq(x) (x) | 89 | # define ioswabq(x) (x) |
| 91 | # define mem_ioswabq(x) cpu_to_le32(x) | 90 | # define __mem_ioswabq(x) cpu_to_le32(x) |
| 92 | 91 | ||
| 93 | #endif | 92 | #endif |
| 94 | 93 | ||
| @@ -343,7 +342,7 @@ static inline void pfx##write##bwlq(type val, \ | |||
| 343 | BUG(); \ | 342 | BUG(); \ |
| 344 | } \ | 343 | } \ |
| 345 | \ | 344 | \ |
| 346 | static inline type pfx##read##bwlq(volatile void __iomem *mem) \ | 345 | static inline type pfx##read##bwlq(const volatile void __iomem *mem) \ |
| 347 | { \ | 346 | { \ |
| 348 | volatile type *__mem; \ | 347 | volatile type *__mem; \ |
| 349 | type __val; \ | 348 | type __val; \ |
| @@ -418,7 +417,7 @@ __BUILD_MEMORY_SINGLE(bus, bwlq, type, 1) | |||
| 418 | \ | 417 | \ |
| 419 | __BUILD_MEMORY_PFX(__raw_, bwlq, type) \ | 418 | __BUILD_MEMORY_PFX(__raw_, bwlq, type) \ |
| 420 | __BUILD_MEMORY_PFX(, bwlq, type) \ | 419 | __BUILD_MEMORY_PFX(, bwlq, type) \ |
| 421 | __BUILD_MEMORY_PFX(mem_, bwlq, type) \ | 420 | __BUILD_MEMORY_PFX(__mem_, bwlq, type) \ |
| 422 | 421 | ||
| 423 | BUILDIO_MEM(b, u8) | 422 | BUILDIO_MEM(b, u8) |
| 424 | BUILDIO_MEM(w, u16) | 423 | BUILDIO_MEM(w, u16) |
| @@ -431,7 +430,7 @@ BUILDIO_MEM(q, u64) | |||
| 431 | 430 | ||
| 432 | #define BUILDIO_IOPORT(bwlq, type) \ | 431 | #define BUILDIO_IOPORT(bwlq, type) \ |
| 433 | __BUILD_IOPORT_PFX(, bwlq, type) \ | 432 | __BUILD_IOPORT_PFX(, bwlq, type) \ |
| 434 | __BUILD_IOPORT_PFX(mem_, bwlq, type) | 433 | __BUILD_IOPORT_PFX(__mem_, bwlq, type) |
| 435 | 434 | ||
| 436 | BUILDIO_IOPORT(b, u8) | 435 | BUILDIO_IOPORT(b, u8) |
| 437 | BUILDIO_IOPORT(w, u16) | 436 | BUILDIO_IOPORT(w, u16) |
| @@ -465,7 +464,7 @@ static inline void writes##bwlq(volatile void __iomem *mem, \ | |||
| 465 | const volatile type *__addr = addr; \ | 464 | const volatile type *__addr = addr; \ |
| 466 | \ | 465 | \ |
| 467 | while (count--) { \ | 466 | while (count--) { \ |
| 468 | mem_write##bwlq(*__addr, mem); \ | 467 | __mem_write##bwlq(*__addr, mem); \ |
| 469 | __addr++; \ | 468 | __addr++; \ |
| 470 | } \ | 469 | } \ |
| 471 | } \ | 470 | } \ |
| @@ -476,7 +475,7 @@ static inline void reads##bwlq(volatile void __iomem *mem, void *addr, \ | |||
| 476 | volatile type *__addr = addr; \ | 475 | volatile type *__addr = addr; \ |
| 477 | \ | 476 | \ |
| 478 | while (count--) { \ | 477 | while (count--) { \ |
| 479 | *__addr = mem_read##bwlq(mem); \ | 478 | *__addr = __mem_read##bwlq(mem); \ |
| 480 | __addr++; \ | 479 | __addr++; \ |
| 481 | } \ | 480 | } \ |
| 482 | } | 481 | } |
| @@ -489,7 +488,7 @@ static inline void outs##bwlq(unsigned long port, const void *addr, \ | |||
| 489 | const volatile type *__addr = addr; \ | 488 | const volatile type *__addr = addr; \ |
| 490 | \ | 489 | \ |
| 491 | while (count--) { \ | 490 | while (count--) { \ |
| 492 | mem_out##bwlq(*__addr, port); \ | 491 | __mem_out##bwlq(*__addr, port); \ |
| 493 | __addr++; \ | 492 | __addr++; \ |
| 494 | } \ | 493 | } \ |
| 495 | } \ | 494 | } \ |
| @@ -500,7 +499,7 @@ static inline void ins##bwlq(unsigned long port, void *addr, \ | |||
| 500 | volatile type *__addr = addr; \ | 499 | volatile type *__addr = addr; \ |
| 501 | \ | 500 | \ |
| 502 | while (count--) { \ | 501 | while (count--) { \ |
| 503 | *__addr = mem_in##bwlq(port); \ | 502 | *__addr = __mem_in##bwlq(port); \ |
| 504 | __addr++; \ | 503 | __addr++; \ |
| 505 | } \ | 504 | } \ |
| 506 | } | 505 | } |
diff --git a/include/asm-mips/mach-au1x00/au1000.h b/include/asm-mips/mach-au1x00/au1000.h index 8e1d7ed7d8e3..4686e17c206c 100644 --- a/include/asm-mips/mach-au1x00/au1000.h +++ b/include/asm-mips/mach-au1x00/au1000.h | |||
| @@ -1198,7 +1198,11 @@ extern au1xxx_irq_map_t au1xxx_irq_map[]; | |||
| 1198 | 1198 | ||
| 1199 | /* UARTS 0-3 */ | 1199 | /* UARTS 0-3 */ |
| 1200 | #define UART_BASE UART0_ADDR | 1200 | #define UART_BASE UART0_ADDR |
| 1201 | #ifdef CONFIG_SOC_AU1200 | ||
| 1202 | #define UART_DEBUG_BASE UART1_ADDR | ||
| 1203 | #else | ||
| 1201 | #define UART_DEBUG_BASE UART3_ADDR | 1204 | #define UART_DEBUG_BASE UART3_ADDR |
| 1205 | #endif | ||
| 1202 | 1206 | ||
| 1203 | #define UART_RX 0 /* Receive buffer */ | 1207 | #define UART_RX 0 /* Receive buffer */ |
| 1204 | #define UART_TX 4 /* Transmit buffer */ | 1208 | #define UART_TX 4 /* Transmit buffer */ |
diff --git a/include/asm-mips/cobalt/cobalt.h b/include/asm-mips/mach-cobalt/cobalt.h index 78e1df2095fb..78e1df2095fb 100644 --- a/include/asm-mips/cobalt/cobalt.h +++ b/include/asm-mips/mach-cobalt/cobalt.h | |||
diff --git a/include/asm-mips/mach-cobalt/cpu-feature-overrides.h b/include/asm-mips/mach-cobalt/cpu-feature-overrides.h new file mode 100644 index 000000000000..ace8c5ef9701 --- /dev/null +++ b/include/asm-mips/mach-cobalt/cpu-feature-overrides.h | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | /* | ||
| 2 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 3 | * License. See the file "COPYING" in the main directory of this archive | ||
| 4 | * for more details. | ||
| 5 | * | ||
| 6 | * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) | ||
| 7 | */ | ||
| 8 | #ifndef __ASM_COBALT_CPU_FEATURE_OVERRIDES_H | ||
| 9 | #define __ASM_COBALT_CPU_FEATURE_OVERRIDES_H | ||
| 10 | |||
| 11 | #include <linux/config.h> | ||
| 12 | |||
| 13 | #define cpu_has_tlb 1 | ||
| 14 | #define cpu_has_4kex 1 | ||
| 15 | #define cpu_has_3k_cache 0 | ||
| 16 | #define cpu_has_4k_cache 1 | ||
| 17 | #define cpu_has_tx39_cache 0 | ||
| 18 | #define cpu_has_sb1_cache 0 | ||
| 19 | #define cpu_has_fpu 1 | ||
| 20 | #define cpu_has_32fpr 1 | ||
| 21 | #define cpu_has_counter 1 | ||
| 22 | #define cpu_has_watch 0 | ||
| 23 | #define cpu_has_divec 1 | ||
| 24 | #define cpu_has_vce 0 | ||
| 25 | #define cpu_has_cache_cdex_p 0 | ||
| 26 | #define cpu_has_cache_cdex_s 0 | ||
| 27 | #define cpu_has_prefetch 0 | ||
| 28 | #define cpu_has_mcheck 0 | ||
| 29 | #define cpu_has_ejtag 0 | ||
| 30 | |||
| 31 | #define cpu_has_subset_pcaches 0 | ||
| 32 | #define cpu_dcache_line_size() 32 | ||
| 33 | #define cpu_icache_line_size() 32 | ||
| 34 | #define cpu_scache_line_size() 0 | ||
| 35 | |||
| 36 | #ifdef CONFIG_64BIT | ||
| 37 | #define cpu_has_llsc 0 | ||
| 38 | #else | ||
| 39 | #define cpu_has_llsc 1 | ||
| 40 | #endif | ||
| 41 | |||
| 42 | #define cpu_has_mips16 0 | ||
| 43 | #define cpu_has_mdmx 0 | ||
| 44 | #define cpu_has_mips3d 0 | ||
| 45 | #define cpu_has_smartmips 0 | ||
| 46 | #define cpu_has_vtag_icache 0 | ||
| 47 | #define cpu_has_ic_fills_f_dc 0 | ||
| 48 | #define cpu_icache_snoops_remote_store 0 | ||
| 49 | #define cpu_has_dsp 0 | ||
| 50 | |||
| 51 | #define cpu_has_mips32r1 0 | ||
| 52 | #define cpu_has_mips32r2 0 | ||
| 53 | #define cpu_has_mips64r1 0 | ||
| 54 | #define cpu_has_mips64r2 0 | ||
| 55 | |||
| 56 | #endif /* __ASM_COBALT_CPU_FEATURE_OVERRIDES_H */ | ||
diff --git a/include/asm-mips/cobalt/mach-gt64120.h b/include/asm-mips/mach-cobalt/mach-gt64120.h index 587fc4378f44..587fc4378f44 100644 --- a/include/asm-mips/cobalt/mach-gt64120.h +++ b/include/asm-mips/mach-cobalt/mach-gt64120.h | |||
diff --git a/include/asm-mips/mach-ip32/cpu-feature-overrides.h b/include/asm-mips/mach-ip32/cpu-feature-overrides.h index b80c30725cf6..36070b5654ab 100644 --- a/include/asm-mips/mach-ip32/cpu-feature-overrides.h +++ b/include/asm-mips/mach-ip32/cpu-feature-overrides.h | |||
| @@ -18,7 +18,7 @@ | |||
| 18 | * so, for 64bit IP32 kernel we just don't use ll/sc. | 18 | * so, for 64bit IP32 kernel we just don't use ll/sc. |
| 19 | * This does not affect luserland. | 19 | * This does not affect luserland. |
| 20 | */ | 20 | */ |
| 21 | #if defined(CONFIG_CPU_R5000) && defined(CONFIG_64BIT) | 21 | #if (defined(CONFIG_CPU_R5000) || defined(CONFIG_CPU_NEVADA)) && defined(CONFIG_64BIT) |
| 22 | #define cpu_has_llsc 0 | 22 | #define cpu_has_llsc 0 |
| 23 | #else | 23 | #else |
| 24 | #define cpu_has_llsc 1 | 24 | #define cpu_has_llsc 1 |
diff --git a/include/asm-mips/r4kcache.h b/include/asm-mips/r4kcache.h index a5ea9d828aee..cc53196efa40 100644 --- a/include/asm-mips/r4kcache.h +++ b/include/asm-mips/r4kcache.h | |||
| @@ -166,123 +166,6 @@ static inline void invalidate_tcache_page(unsigned long addr) | |||
| 166 | : "r" (base), \ | 166 | : "r" (base), \ |
| 167 | "i" (op)); | 167 | "i" (op)); |
| 168 | 168 | ||
| 169 | static inline void blast_dcache16(void) | ||
| 170 | { | ||
| 171 | unsigned long start = INDEX_BASE; | ||
| 172 | unsigned long end = start + current_cpu_data.dcache.waysize; | ||
| 173 | unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; | ||
| 174 | unsigned long ws_end = current_cpu_data.dcache.ways << | ||
| 175 | current_cpu_data.dcache.waybit; | ||
| 176 | unsigned long ws, addr; | ||
| 177 | |||
| 178 | for (ws = 0; ws < ws_end; ws += ws_inc) | ||
| 179 | for (addr = start; addr < end; addr += 0x200) | ||
| 180 | cache16_unroll32(addr|ws,Index_Writeback_Inv_D); | ||
| 181 | } | ||
| 182 | |||
| 183 | static inline void blast_dcache16_page(unsigned long page) | ||
| 184 | { | ||
| 185 | unsigned long start = page; | ||
| 186 | unsigned long end = start + PAGE_SIZE; | ||
| 187 | |||
| 188 | do { | ||
| 189 | cache16_unroll32(start,Hit_Writeback_Inv_D); | ||
| 190 | start += 0x200; | ||
| 191 | } while (start < end); | ||
| 192 | } | ||
| 193 | |||
| 194 | static inline void blast_dcache16_page_indexed(unsigned long page) | ||
| 195 | { | ||
| 196 | unsigned long start = page; | ||
| 197 | unsigned long end = start + PAGE_SIZE; | ||
| 198 | unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; | ||
| 199 | unsigned long ws_end = current_cpu_data.dcache.ways << | ||
| 200 | current_cpu_data.dcache.waybit; | ||
| 201 | unsigned long ws, addr; | ||
| 202 | |||
| 203 | for (ws = 0; ws < ws_end; ws += ws_inc) | ||
| 204 | for (addr = start; addr < end; addr += 0x200) | ||
| 205 | cache16_unroll32(addr|ws,Index_Writeback_Inv_D); | ||
| 206 | } | ||
| 207 | |||
| 208 | static inline void blast_icache16(void) | ||
| 209 | { | ||
| 210 | unsigned long start = INDEX_BASE; | ||
| 211 | unsigned long end = start + current_cpu_data.icache.waysize; | ||
| 212 | unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; | ||
| 213 | unsigned long ws_end = current_cpu_data.icache.ways << | ||
| 214 | current_cpu_data.icache.waybit; | ||
| 215 | unsigned long ws, addr; | ||
| 216 | |||
| 217 | for (ws = 0; ws < ws_end; ws += ws_inc) | ||
| 218 | for (addr = start; addr < end; addr += 0x200) | ||
| 219 | cache16_unroll32(addr|ws,Index_Invalidate_I); | ||
| 220 | } | ||
| 221 | |||
| 222 | static inline void blast_icache16_page(unsigned long page) | ||
| 223 | { | ||
| 224 | unsigned long start = page; | ||
| 225 | unsigned long end = start + PAGE_SIZE; | ||
| 226 | |||
| 227 | do { | ||
| 228 | cache16_unroll32(start,Hit_Invalidate_I); | ||
| 229 | start += 0x200; | ||
| 230 | } while (start < end); | ||
| 231 | } | ||
| 232 | |||
| 233 | static inline void blast_icache16_page_indexed(unsigned long page) | ||
| 234 | { | ||
| 235 | unsigned long start = page; | ||
| 236 | unsigned long end = start + PAGE_SIZE; | ||
| 237 | unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; | ||
| 238 | unsigned long ws_end = current_cpu_data.icache.ways << | ||
| 239 | current_cpu_data.icache.waybit; | ||
| 240 | unsigned long ws, addr; | ||
| 241 | |||
| 242 | for (ws = 0; ws < ws_end; ws += ws_inc) | ||
| 243 | for (addr = start; addr < end; addr += 0x200) | ||
| 244 | cache16_unroll32(addr|ws,Index_Invalidate_I); | ||
| 245 | } | ||
| 246 | |||
| 247 | static inline void blast_scache16(void) | ||
| 248 | { | ||
| 249 | unsigned long start = INDEX_BASE; | ||
| 250 | unsigned long end = start + current_cpu_data.scache.waysize; | ||
| 251 | unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; | ||
| 252 | unsigned long ws_end = current_cpu_data.scache.ways << | ||
| 253 | current_cpu_data.scache.waybit; | ||
| 254 | unsigned long ws, addr; | ||
| 255 | |||
| 256 | for (ws = 0; ws < ws_end; ws += ws_inc) | ||
| 257 | for (addr = start; addr < end; addr += 0x200) | ||
| 258 | cache16_unroll32(addr|ws,Index_Writeback_Inv_SD); | ||
| 259 | } | ||
| 260 | |||
| 261 | static inline void blast_scache16_page(unsigned long page) | ||
| 262 | { | ||
| 263 | unsigned long start = page; | ||
| 264 | unsigned long end = page + PAGE_SIZE; | ||
| 265 | |||
| 266 | do { | ||
| 267 | cache16_unroll32(start,Hit_Writeback_Inv_SD); | ||
| 268 | start += 0x200; | ||
| 269 | } while (start < end); | ||
| 270 | } | ||
| 271 | |||
| 272 | static inline void blast_scache16_page_indexed(unsigned long page) | ||
| 273 | { | ||
| 274 | unsigned long start = page; | ||
| 275 | unsigned long end = start + PAGE_SIZE; | ||
| 276 | unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; | ||
| 277 | unsigned long ws_end = current_cpu_data.scache.ways << | ||
| 278 | current_cpu_data.scache.waybit; | ||
| 279 | unsigned long ws, addr; | ||
| 280 | |||
| 281 | for (ws = 0; ws < ws_end; ws += ws_inc) | ||
| 282 | for (addr = start; addr < end; addr += 0x200) | ||
| 283 | cache16_unroll32(addr|ws,Index_Writeback_Inv_SD); | ||
| 284 | } | ||
| 285 | |||
| 286 | #define cache32_unroll32(base,op) \ | 169 | #define cache32_unroll32(base,op) \ |
| 287 | __asm__ __volatile__( \ | 170 | __asm__ __volatile__( \ |
| 288 | " .set push \n" \ | 171 | " .set push \n" \ |
| @@ -309,123 +192,6 @@ static inline void blast_scache16_page_indexed(unsigned long page) | |||
| 309 | : "r" (base), \ | 192 | : "r" (base), \ |
| 310 | "i" (op)); | 193 | "i" (op)); |
| 311 | 194 | ||
| 312 | static inline void blast_dcache32(void) | ||
| 313 | { | ||
| 314 | unsigned long start = INDEX_BASE; | ||
| 315 | unsigned long end = start + current_cpu_data.dcache.waysize; | ||
| 316 | unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; | ||
| 317 | unsigned long ws_end = current_cpu_data.dcache.ways << | ||
| 318 | current_cpu_data.dcache.waybit; | ||
| 319 | unsigned long ws, addr; | ||
| 320 | |||
| 321 | for (ws = 0; ws < ws_end; ws += ws_inc) | ||
| 322 | for (addr = start; addr < end; addr += 0x400) | ||
| 323 | cache32_unroll32(addr|ws,Index_Writeback_Inv_D); | ||
| 324 | } | ||
| 325 | |||
| 326 | static inline void blast_dcache32_page(unsigned long page) | ||
| 327 | { | ||
| 328 | unsigned long start = page; | ||
| 329 | unsigned long end = start + PAGE_SIZE; | ||
| 330 | |||
| 331 | do { | ||
| 332 | cache32_unroll32(start,Hit_Writeback_Inv_D); | ||
| 333 | start += 0x400; | ||
| 334 | } while (start < end); | ||
| 335 | } | ||
| 336 | |||
| 337 | static inline void blast_dcache32_page_indexed(unsigned long page) | ||
| 338 | { | ||
| 339 | unsigned long start = page; | ||
| 340 | unsigned long end = start + PAGE_SIZE; | ||
| 341 | unsigned long ws_inc = 1UL << current_cpu_data.dcache.waybit; | ||
| 342 | unsigned long ws_end = current_cpu_data.dcache.ways << | ||
| 343 | current_cpu_data.dcache.waybit; | ||
| 344 | unsigned long ws, addr; | ||
| 345 | |||
| 346 | for (ws = 0; ws < ws_end; ws += ws_inc) | ||
| 347 | for (addr = start; addr < end; addr += 0x400) | ||
| 348 | cache32_unroll32(addr|ws,Index_Writeback_Inv_D); | ||
| 349 | } | ||
| 350 | |||
| 351 | static inline void blast_icache32(void) | ||
| 352 | { | ||
| 353 | unsigned long start = INDEX_BASE; | ||
| 354 | unsigned long end = start + current_cpu_data.icache.waysize; | ||
| 355 | unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; | ||
| 356 | unsigned long ws_end = current_cpu_data.icache.ways << | ||
| 357 | current_cpu_data.icache.waybit; | ||
| 358 | unsigned long ws, addr; | ||
| 359 | |||
| 360 | for (ws = 0; ws < ws_end; ws += ws_inc) | ||
| 361 | for (addr = start; addr < end; addr += 0x400) | ||
| 362 | cache32_unroll32(addr|ws,Index_Invalidate_I); | ||
| 363 | } | ||
| 364 | |||
| 365 | static inline void blast_icache32_page(unsigned long page) | ||
| 366 | { | ||
| 367 | unsigned long start = page; | ||
| 368 | unsigned long end = start + PAGE_SIZE; | ||
| 369 | |||
| 370 | do { | ||
| 371 | cache32_unroll32(start,Hit_Invalidate_I); | ||
| 372 | start += 0x400; | ||
| 373 | } while (start < end); | ||
| 374 | } | ||
| 375 | |||
| 376 | static inline void blast_icache32_page_indexed(unsigned long page) | ||
| 377 | { | ||
| 378 | unsigned long start = page; | ||
| 379 | unsigned long end = start + PAGE_SIZE; | ||
| 380 | unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; | ||
| 381 | unsigned long ws_end = current_cpu_data.icache.ways << | ||
| 382 | current_cpu_data.icache.waybit; | ||
| 383 | unsigned long ws, addr; | ||
| 384 | |||
| 385 | for (ws = 0; ws < ws_end; ws += ws_inc) | ||
| 386 | for (addr = start; addr < end; addr += 0x400) | ||
| 387 | cache32_unroll32(addr|ws,Index_Invalidate_I); | ||
| 388 | } | ||
| 389 | |||
| 390 | static inline void blast_scache32(void) | ||
| 391 | { | ||
| 392 | unsigned long start = INDEX_BASE; | ||
| 393 | unsigned long end = start + current_cpu_data.scache.waysize; | ||
| 394 | unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; | ||
| 395 | unsigned long ws_end = current_cpu_data.scache.ways << | ||
| 396 | current_cpu_data.scache.waybit; | ||
| 397 | unsigned long ws, addr; | ||
| 398 | |||
| 399 | for (ws = 0; ws < ws_end; ws += ws_inc) | ||
| 400 | for (addr = start; addr < end; addr += 0x400) | ||
| 401 | cache32_unroll32(addr|ws,Index_Writeback_Inv_SD); | ||
| 402 | } | ||
| 403 | |||
| 404 | static inline void blast_scache32_page(unsigned long page) | ||
| 405 | { | ||
| 406 | unsigned long start = page; | ||
| 407 | unsigned long end = page + PAGE_SIZE; | ||
| 408 | |||
| 409 | do { | ||
| 410 | cache32_unroll32(start,Hit_Writeback_Inv_SD); | ||
| 411 | start += 0x400; | ||
| 412 | } while (start < end); | ||
| 413 | } | ||
| 414 | |||
| 415 | static inline void blast_scache32_page_indexed(unsigned long page) | ||
| 416 | { | ||
| 417 | unsigned long start = page; | ||
| 418 | unsigned long end = start + PAGE_SIZE; | ||
| 419 | unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; | ||
| 420 | unsigned long ws_end = current_cpu_data.scache.ways << | ||
| 421 | current_cpu_data.scache.waybit; | ||
| 422 | unsigned long ws, addr; | ||
| 423 | |||
| 424 | for (ws = 0; ws < ws_end; ws += ws_inc) | ||
| 425 | for (addr = start; addr < end; addr += 0x400) | ||
| 426 | cache32_unroll32(addr|ws,Index_Writeback_Inv_SD); | ||
| 427 | } | ||
| 428 | |||
| 429 | #define cache64_unroll32(base,op) \ | 195 | #define cache64_unroll32(base,op) \ |
| 430 | __asm__ __volatile__( \ | 196 | __asm__ __volatile__( \ |
| 431 | " .set push \n" \ | 197 | " .set push \n" \ |
| @@ -452,84 +218,6 @@ static inline void blast_scache32_page_indexed(unsigned long page) | |||
| 452 | : "r" (base), \ | 218 | : "r" (base), \ |
| 453 | "i" (op)); | 219 | "i" (op)); |
| 454 | 220 | ||
| 455 | static inline void blast_icache64(void) | ||
| 456 | { | ||
| 457 | unsigned long start = INDEX_BASE; | ||
| 458 | unsigned long end = start + current_cpu_data.icache.waysize; | ||
| 459 | unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; | ||
| 460 | unsigned long ws_end = current_cpu_data.icache.ways << | ||
| 461 | current_cpu_data.icache.waybit; | ||
| 462 | unsigned long ws, addr; | ||
| 463 | |||
| 464 | for (ws = 0; ws < ws_end; ws += ws_inc) | ||
| 465 | for (addr = start; addr < end; addr += 0x800) | ||
| 466 | cache64_unroll32(addr|ws,Index_Invalidate_I); | ||
| 467 | } | ||
| 468 | |||
| 469 | static inline void blast_icache64_page(unsigned long page) | ||
| 470 | { | ||
| 471 | unsigned long start = page; | ||
| 472 | unsigned long end = start + PAGE_SIZE; | ||
| 473 | |||
| 474 | do { | ||
| 475 | cache64_unroll32(start,Hit_Invalidate_I); | ||
| 476 | start += 0x800; | ||
| 477 | } while (start < end); | ||
| 478 | } | ||
| 479 | |||
| 480 | static inline void blast_icache64_page_indexed(unsigned long page) | ||
| 481 | { | ||
| 482 | unsigned long start = page; | ||
| 483 | unsigned long end = start + PAGE_SIZE; | ||
| 484 | unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; | ||
| 485 | unsigned long ws_end = current_cpu_data.icache.ways << | ||
| 486 | current_cpu_data.icache.waybit; | ||
| 487 | unsigned long ws, addr; | ||
| 488 | |||
| 489 | for (ws = 0; ws < ws_end; ws += ws_inc) | ||
| 490 | for (addr = start; addr < end; addr += 0x800) | ||
| 491 | cache64_unroll32(addr|ws,Index_Invalidate_I); | ||
| 492 | } | ||
| 493 | |||
| 494 | static inline void blast_scache64(void) | ||
| 495 | { | ||
| 496 | unsigned long start = INDEX_BASE; | ||
| 497 | unsigned long end = start + current_cpu_data.scache.waysize; | ||
| 498 | unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; | ||
| 499 | unsigned long ws_end = current_cpu_data.scache.ways << | ||
| 500 | current_cpu_data.scache.waybit; | ||
| 501 | unsigned long ws, addr; | ||
| 502 | |||
| 503 | for (ws = 0; ws < ws_end; ws += ws_inc) | ||
| 504 | for (addr = start; addr < end; addr += 0x800) | ||
| 505 | cache64_unroll32(addr|ws,Index_Writeback_Inv_SD); | ||
| 506 | } | ||
| 507 | |||
| 508 | static inline void blast_scache64_page(unsigned long page) | ||
| 509 | { | ||
| 510 | unsigned long start = page; | ||
| 511 | unsigned long end = page + PAGE_SIZE; | ||
| 512 | |||
| 513 | do { | ||
| 514 | cache64_unroll32(start,Hit_Writeback_Inv_SD); | ||
| 515 | start += 0x800; | ||
| 516 | } while (start < end); | ||
| 517 | } | ||
| 518 | |||
| 519 | static inline void blast_scache64_page_indexed(unsigned long page) | ||
| 520 | { | ||
| 521 | unsigned long start = page; | ||
| 522 | unsigned long end = start + PAGE_SIZE; | ||
| 523 | unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; | ||
| 524 | unsigned long ws_end = current_cpu_data.scache.ways << | ||
| 525 | current_cpu_data.scache.waybit; | ||
| 526 | unsigned long ws, addr; | ||
| 527 | |||
| 528 | for (ws = 0; ws < ws_end; ws += ws_inc) | ||
| 529 | for (addr = start; addr < end; addr += 0x800) | ||
| 530 | cache64_unroll32(addr|ws,Index_Writeback_Inv_SD); | ||
| 531 | } | ||
| 532 | |||
| 533 | #define cache128_unroll32(base,op) \ | 221 | #define cache128_unroll32(base,op) \ |
| 534 | __asm__ __volatile__( \ | 222 | __asm__ __volatile__( \ |
| 535 | " .set push \n" \ | 223 | " .set push \n" \ |
| @@ -556,43 +244,55 @@ static inline void blast_scache64_page_indexed(unsigned long page) | |||
| 556 | : "r" (base), \ | 244 | : "r" (base), \ |
| 557 | "i" (op)); | 245 | "i" (op)); |
| 558 | 246 | ||
| 559 | static inline void blast_scache128(void) | 247 | /* build blast_xxx, blast_xxx_page, blast_xxx_page_indexed */ |
| 560 | { | 248 | #define __BUILD_BLAST_CACHE(pfx, desc, indexop, hitop, lsize) \ |
| 561 | unsigned long start = INDEX_BASE; | 249 | static inline void blast_##pfx##cache##lsize(void) \ |
| 562 | unsigned long end = start + current_cpu_data.scache.waysize; | 250 | { \ |
| 563 | unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; | 251 | unsigned long start = INDEX_BASE; \ |
| 564 | unsigned long ws_end = current_cpu_data.scache.ways << | 252 | unsigned long end = start + current_cpu_data.desc.waysize; \ |
| 565 | current_cpu_data.scache.waybit; | 253 | unsigned long ws_inc = 1UL << current_cpu_data.desc.waybit; \ |
| 566 | unsigned long ws, addr; | 254 | unsigned long ws_end = current_cpu_data.desc.ways << \ |
| 567 | 255 | current_cpu_data.desc.waybit; \ | |
| 568 | for (ws = 0; ws < ws_end; ws += ws_inc) | 256 | unsigned long ws, addr; \ |
| 569 | for (addr = start; addr < end; addr += 0x1000) | 257 | \ |
| 570 | cache128_unroll32(addr|ws,Index_Writeback_Inv_SD); | 258 | for (ws = 0; ws < ws_end; ws += ws_inc) \ |
| 571 | } | 259 | for (addr = start; addr < end; addr += lsize * 32) \ |
| 572 | 260 | cache##lsize##_unroll32(addr|ws,indexop); \ | |
| 573 | static inline void blast_scache128_page(unsigned long page) | 261 | } \ |
| 574 | { | 262 | \ |
| 575 | unsigned long start = page; | 263 | static inline void blast_##pfx##cache##lsize##_page(unsigned long page) \ |
| 576 | unsigned long end = page + PAGE_SIZE; | 264 | { \ |
| 577 | 265 | unsigned long start = page; \ | |
| 578 | do { | 266 | unsigned long end = page + PAGE_SIZE; \ |
| 579 | cache128_unroll32(start,Hit_Writeback_Inv_SD); | 267 | \ |
| 580 | start += 0x1000; | 268 | do { \ |
| 581 | } while (start < end); | 269 | cache##lsize##_unroll32(start,hitop); \ |
| 582 | } | 270 | start += lsize * 32; \ |
| 583 | 271 | } while (start < end); \ | |
| 584 | static inline void blast_scache128_page_indexed(unsigned long page) | 272 | } \ |
| 585 | { | 273 | \ |
| 586 | unsigned long start = page; | 274 | static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page) \ |
| 587 | unsigned long end = start + PAGE_SIZE; | 275 | { \ |
| 588 | unsigned long ws_inc = 1UL << current_cpu_data.scache.waybit; | 276 | unsigned long start = page; \ |
| 589 | unsigned long ws_end = current_cpu_data.scache.ways << | 277 | unsigned long end = start + PAGE_SIZE; \ |
| 590 | current_cpu_data.scache.waybit; | 278 | unsigned long ws_inc = 1UL << current_cpu_data.desc.waybit; \ |
| 591 | unsigned long ws, addr; | 279 | unsigned long ws_end = current_cpu_data.desc.ways << \ |
| 592 | 280 | current_cpu_data.desc.waybit; \ | |
| 593 | for (ws = 0; ws < ws_end; ws += ws_inc) | 281 | unsigned long ws, addr; \ |
| 594 | for (addr = start; addr < end; addr += 0x1000) | 282 | \ |
| 595 | cache128_unroll32(addr|ws,Index_Writeback_Inv_SD); | 283 | for (ws = 0; ws < ws_end; ws += ws_inc) \ |
| 596 | } | 284 | for (addr = start; addr < end; addr += lsize * 32) \ |
| 285 | cache##lsize##_unroll32(addr|ws,indexop); \ | ||
| 286 | } | ||
| 287 | |||
| 288 | __BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16) | ||
| 289 | __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 16) | ||
| 290 | __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16) | ||
| 291 | __BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 32) | ||
| 292 | __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 32) | ||
| 293 | __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32) | ||
| 294 | __BUILD_BLAST_CACHE(i, icache, Index_Invalidate_I, Hit_Invalidate_I, 64) | ||
| 295 | __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64) | ||
| 296 | __BUILD_BLAST_CACHE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128) | ||
| 597 | 297 | ||
| 598 | #endif /* _ASM_R4KCACHE_H */ | 298 | #endif /* _ASM_R4KCACHE_H */ |
diff --git a/include/asm-mips/reboot.h b/include/asm-mips/reboot.h index 2f10ebcbe141..e48c0bfab257 100644 --- a/include/asm-mips/reboot.h +++ b/include/asm-mips/reboot.h | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
| 4 | * for more details. | 4 | * for more details. |
| 5 | * | 5 | * |
| 6 | * Copyright (C) 1997, 1999, 2001 by Ralf Baechle | 6 | * Copyright (C) 1997, 1999, 2001, 06 by Ralf Baechle |
| 7 | * Copyright (C) 2001 MIPS Technologies, Inc. | 7 | * Copyright (C) 2001 MIPS Technologies, Inc. |
| 8 | */ | 8 | */ |
| 9 | #ifndef _ASM_REBOOT_H | 9 | #ifndef _ASM_REBOOT_H |
| @@ -11,6 +11,5 @@ | |||
| 11 | 11 | ||
| 12 | extern void (*_machine_restart)(char *command); | 12 | extern void (*_machine_restart)(char *command); |
| 13 | extern void (*_machine_halt)(void); | 13 | extern void (*_machine_halt)(void); |
| 14 | extern void (*_machine_power_off)(void); | ||
| 15 | 14 | ||
| 16 | #endif /* _ASM_REBOOT_H */ | 15 | #endif /* _ASM_REBOOT_H */ |
diff --git a/include/asm-mips/string.h b/include/asm-mips/string.h index 5a06f6d13899..907da600fddd 100644 --- a/include/asm-mips/string.h +++ b/include/asm-mips/string.h | |||
| @@ -141,26 +141,4 @@ extern void *memcpy(void *__to, __const__ void *__from, size_t __n); | |||
| 141 | #define __HAVE_ARCH_MEMMOVE | 141 | #define __HAVE_ARCH_MEMMOVE |
| 142 | extern void *memmove(void *__dest, __const__ void *__src, size_t __n); | 142 | extern void *memmove(void *__dest, __const__ void *__src, size_t __n); |
| 143 | 143 | ||
| 144 | #ifdef CONFIG_32BIT | ||
| 145 | #define __HAVE_ARCH_MEMSCAN | ||
| 146 | static __inline__ void *memscan(void *__addr, int __c, size_t __size) | ||
| 147 | { | ||
| 148 | char *__end = (char *)__addr + __size; | ||
| 149 | unsigned char __uc = (unsigned char) __c; | ||
| 150 | |||
| 151 | __asm__(".set\tpush\n\t" | ||
| 152 | ".set\tnoat\n\t" | ||
| 153 | ".set\treorder\n\t" | ||
| 154 | "1:\tbeq\t%0,%1,2f\n\t" | ||
| 155 | "addiu\t%0,1\n\t" | ||
| 156 | "lbu\t$1,-1(%0)\n\t" | ||
| 157 | "bne\t$1,%z4,1b\n" | ||
| 158 | "2:\t.set\tpop" | ||
| 159 | : "=r" (__addr), "=r" (__end) | ||
| 160 | : "0" (__addr), "1" (__end), "Jr" (__uc)); | ||
| 161 | |||
| 162 | return __addr; | ||
| 163 | } | ||
| 164 | #endif /* CONFIG_32BIT */ | ||
| 165 | |||
| 166 | #endif /* _ASM_STRING_H */ | 144 | #endif /* _ASM_STRING_H */ |
diff --git a/include/asm-mips/thread_info.h b/include/asm-mips/thread_info.h index 1612b3fe1080..fa193f861e71 100644 --- a/include/asm-mips/thread_info.h +++ b/include/asm-mips/thread_info.h | |||
| @@ -114,6 +114,7 @@ register struct thread_info *__current_thread_info __asm__("$28"); | |||
| 114 | #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ | 114 | #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ |
| 115 | #define TIF_SYSCALL_AUDIT 4 /* syscall auditing active */ | 115 | #define TIF_SYSCALL_AUDIT 4 /* syscall auditing active */ |
| 116 | #define TIF_SECCOMP 5 /* secure computing */ | 116 | #define TIF_SECCOMP 5 /* secure computing */ |
| 117 | #define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */ | ||
| 117 | #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ | 118 | #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ |
| 118 | #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ | 119 | #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ |
| 119 | #define TIF_MEMDIE 18 | 120 | #define TIF_MEMDIE 18 |
| @@ -125,6 +126,7 @@ register struct thread_info *__current_thread_info __asm__("$28"); | |||
| 125 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) | 126 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) |
| 126 | #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) | 127 | #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) |
| 127 | #define _TIF_SECCOMP (1<<TIF_SECCOMP) | 128 | #define _TIF_SECCOMP (1<<TIF_SECCOMP) |
| 129 | #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) | ||
| 128 | #define _TIF_USEDFPU (1<<TIF_USEDFPU) | 130 | #define _TIF_USEDFPU (1<<TIF_USEDFPU) |
| 129 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) | 131 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) |
| 130 | 132 | ||
diff --git a/include/asm-mips/tx4927/tx4927.h b/include/asm-mips/tx4927/tx4927.h index 3bb7f0087d68..de85bd2245f7 100644 --- a/include/asm-mips/tx4927/tx4927.h +++ b/include/asm-mips/tx4927/tx4927.h | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | * Author: MontaVista Software, Inc. | 2 | * Author: MontaVista Software, Inc. |
| 3 | * source@mvista.com | 3 | * source@mvista.com |
| 4 | * | 4 | * |
| 5 | * Copyright 2001-2002 MontaVista Software Inc. | 5 | * Copyright 2001-2006 MontaVista Software Inc. |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
| 8 | * under the terms of the GNU General Public License as published by the | 8 | * under the terms of the GNU General Public License as published by the |
| @@ -30,10 +30,10 @@ | |||
| 30 | #include <asm/tx4927/tx4927_mips.h> | 30 | #include <asm/tx4927/tx4927_mips.h> |
| 31 | 31 | ||
| 32 | /* | 32 | /* |
| 33 | This register naming came from the intergrate cpu/controoler name TX4927 | 33 | This register naming came from the integrated CPU/controller name TX4927 |
| 34 | followed by the device name from table 4.2.2 on page 4-3 and then followed | 34 | followed by the device name from table 4.2.2 on page 4-3 and then followed |
| 35 | by the register name from table 4.2.3 on pages 4-4 to 4-8. The manaul | 35 | by the register name from table 4.2.3 on pages 4-4 to 4-8. The manaul |
| 36 | used is "TMPR4927BT Preliminary Rev 0.1 20.Jul.2001". | 36 | used was "TMPR4927BT Preliminary Rev 0.1 20.Jul.2001". |
| 37 | */ | 37 | */ |
| 38 | 38 | ||
| 39 | #define TX4927_SIO_0_BASE | 39 | #define TX4927_SIO_0_BASE |
| @@ -251,8 +251,8 @@ | |||
| 251 | 251 | ||
| 252 | /* TX4927 Timer 0 (32-bit registers) */ | 252 | /* TX4927 Timer 0 (32-bit registers) */ |
| 253 | #define TX4927_TMR0_BASE 0xf000 | 253 | #define TX4927_TMR0_BASE 0xf000 |
| 254 | #define TX4927_TMR0_TMTCR0 0xf004 | 254 | #define TX4927_TMR0_TMTCR0 0xf000 |
| 255 | #define TX4927_TMR0_TMTISR0 0xf008 | 255 | #define TX4927_TMR0_TMTISR0 0xf004 |
| 256 | #define TX4927_TMR0_TMCPRA0 0xf008 | 256 | #define TX4927_TMR0_TMCPRA0 0xf008 |
| 257 | #define TX4927_TMR0_TMCPRB0 0xf00c | 257 | #define TX4927_TMR0_TMCPRB0 0xf00c |
| 258 | #define TX4927_TMR0_TMITMR0 0xf010 | 258 | #define TX4927_TMR0_TMITMR0 0xf010 |
| @@ -264,8 +264,8 @@ | |||
| 264 | 264 | ||
| 265 | /* TX4927 Timer 1 (32-bit registers) */ | 265 | /* TX4927 Timer 1 (32-bit registers) */ |
| 266 | #define TX4927_TMR1_BASE 0xf100 | 266 | #define TX4927_TMR1_BASE 0xf100 |
| 267 | #define TX4927_TMR1_TMTCR1 0xf104 | 267 | #define TX4927_TMR1_TMTCR1 0xf100 |
| 268 | #define TX4927_TMR1_TMTISR1 0xf108 | 268 | #define TX4927_TMR1_TMTISR1 0xf104 |
| 269 | #define TX4927_TMR1_TMCPRA1 0xf108 | 269 | #define TX4927_TMR1_TMCPRA1 0xf108 |
| 270 | #define TX4927_TMR1_TMCPRB1 0xf10c | 270 | #define TX4927_TMR1_TMCPRB1 0xf10c |
| 271 | #define TX4927_TMR1_TMITMR1 0xf110 | 271 | #define TX4927_TMR1_TMITMR1 0xf110 |
| @@ -277,13 +277,12 @@ | |||
| 277 | 277 | ||
| 278 | /* TX4927 Timer 2 (32-bit registers) */ | 278 | /* TX4927 Timer 2 (32-bit registers) */ |
| 279 | #define TX4927_TMR2_BASE 0xf200 | 279 | #define TX4927_TMR2_BASE 0xf200 |
| 280 | #define TX4927_TMR2_TMTCR2 0xf104 | 280 | #define TX4927_TMR2_TMTCR2 0xf200 |
| 281 | #define TX4927_TMR2_TMTISR2 0xf208 | 281 | #define TX4927_TMR2_TMTISR2 0xf204 |
| 282 | #define TX4927_TMR2_TMCPRA2 0xf208 | 282 | #define TX4927_TMR2_TMCPRA2 0xf208 |
| 283 | #define TX4927_TMR2_TMCPRB2 0xf20c | ||
| 284 | #define TX4927_TMR2_TMITMR2 0xf210 | 283 | #define TX4927_TMR2_TMITMR2 0xf210 |
| 285 | #define TX4927_TMR2_TMCCDR2 0xf220 | 284 | #define TX4927_TMR2_TMCCDR2 0xf220 |
| 286 | #define TX4927_TMR2_TMPGMR2 0xf230 | 285 | #define TX4927_TMR2_TMWTMR2 0xf240 |
| 287 | #define TX4927_TMR2_TMTRR2 0xf2f0 | 286 | #define TX4927_TMR2_TMTRR2 0xf2f0 |
| 288 | #define TX4927_TMR2_LIMIT 0xf2ff | 287 | #define TX4927_TMR2_LIMIT 0xf2ff |
| 289 | 288 | ||
diff --git a/include/asm-mips/tx4927/tx4927_pci.h b/include/asm-mips/tx4927/tx4927_pci.h index 165f6b8b217f..66c064690f41 100644 --- a/include/asm-mips/tx4927/tx4927_pci.h +++ b/include/asm-mips/tx4927/tx4927_pci.h | |||
| @@ -253,6 +253,16 @@ struct tx4927_pcic_reg { | |||
| 253 | #define TX4927_CCFG_PCIDIVMODE_5 0x00001000 | 253 | #define TX4927_CCFG_PCIDIVMODE_5 0x00001000 |
| 254 | #define TX4927_CCFG_PCIDIVMODE_6 0x00001800 | 254 | #define TX4927_CCFG_PCIDIVMODE_6 0x00001800 |
| 255 | 255 | ||
| 256 | #define TX4937_CCFG_PCIDIVMODE_MASK 0x00001c00 | ||
| 257 | #define TX4937_CCFG_PCIDIVMODE_8 0x00000000 | ||
| 258 | #define TX4937_CCFG_PCIDIVMODE_4 0x00000400 | ||
| 259 | #define TX4937_CCFG_PCIDIVMODE_9 0x00000800 | ||
| 260 | #define TX4937_CCFG_PCIDIVMODE_4_5 0x00000c00 | ||
| 261 | #define TX4937_CCFG_PCIDIVMODE_10 0x00001000 | ||
| 262 | #define TX4937_CCFG_PCIDIVMODE_5 0x00001400 | ||
| 263 | #define TX4937_CCFG_PCIDIVMODE_11 0x00001800 | ||
| 264 | #define TX4937_CCFG_PCIDIVMODE_5_5 0x00001c00 | ||
| 265 | |||
| 256 | /* PCFG : Pin Configuration */ | 266 | /* PCFG : Pin Configuration */ |
| 257 | #define TX4927_PCFG_PCICLKEN_ALL 0x003f0000 | 267 | #define TX4927_PCFG_PCICLKEN_ALL 0x003f0000 |
| 258 | #define TX4927_PCFG_PCICLKEN(ch) (0x00010000<<(ch)) | 268 | #define TX4927_PCFG_PCICLKEN(ch) (0x00010000<<(ch)) |
diff --git a/include/asm-mips/uaccess.h b/include/asm-mips/uaccess.h index 41bb96bb2120..91d813a37823 100644 --- a/include/asm-mips/uaccess.h +++ b/include/asm-mips/uaccess.h | |||
| @@ -202,49 +202,49 @@ struct __large_struct { unsigned long buf[100]; }; | |||
| 202 | * Yuck. We need two variants, one for 64bit operation and one | 202 | * Yuck. We need two variants, one for 64bit operation and one |
| 203 | * for 32 bit mode and old iron. | 203 | * for 32 bit mode and old iron. |
| 204 | */ | 204 | */ |
| 205 | #ifdef __mips64 | 205 | #ifdef CONFIG_32BIT |
| 206 | #define __GET_USER_DW(ptr) __get_user_asm("ld", ptr) | 206 | #define __GET_USER_DW(val, ptr) __get_user_asm_ll32(val, ptr) |
| 207 | #else | 207 | #endif |
| 208 | #define __GET_USER_DW(ptr) __get_user_asm_ll32(ptr) | 208 | #ifdef CONFIG_64BIT |
| 209 | #define __GET_USER_DW(val, ptr) __get_user_asm(val, "ld", ptr) | ||
| 209 | #endif | 210 | #endif |
| 210 | 211 | ||
| 211 | #define __get_user_nocheck(x,ptr,size) \ | 212 | extern void __get_user_unknown(void); |
| 212 | ({ \ | 213 | |
| 213 | __typeof(*(ptr)) __gu_val = (__typeof(*(ptr))) 0; \ | 214 | #define __get_user_common(val, size, ptr) \ |
| 214 | long __gu_err = 0; \ | 215 | do { \ |
| 215 | \ | ||
| 216 | switch (size) { \ | 216 | switch (size) { \ |
| 217 | case 1: __get_user_asm("lb", ptr); break; \ | 217 | case 1: __get_user_asm(val, "lb", ptr); break; \ |
| 218 | case 2: __get_user_asm("lh", ptr); break; \ | 218 | case 2: __get_user_asm(val, "lh", ptr); break; \ |
| 219 | case 4: __get_user_asm("lw", ptr); break; \ | 219 | case 4: __get_user_asm(val, "lw", ptr); break; \ |
| 220 | case 8: __GET_USER_DW(ptr); break; \ | 220 | case 8: __GET_USER_DW(val, ptr); break; \ |
| 221 | default: __get_user_unknown(); break; \ | 221 | default: __get_user_unknown(); break; \ |
| 222 | } \ | 222 | } \ |
| 223 | (x) = (__typeof__(*(ptr))) __gu_val; \ | 223 | } while (0) |
| 224 | |||
| 225 | #define __get_user_nocheck(x,ptr,size) \ | ||
| 226 | ({ \ | ||
| 227 | long __gu_err; \ | ||
| 228 | \ | ||
| 229 | __get_user_common((x), size, ptr); \ | ||
| 224 | __gu_err; \ | 230 | __gu_err; \ |
| 225 | }) | 231 | }) |
| 226 | 232 | ||
| 227 | #define __get_user_check(x,ptr,size) \ | 233 | #define __get_user_check(x,ptr,size) \ |
| 228 | ({ \ | 234 | ({ \ |
| 229 | const __typeof__(*(ptr)) __user * __gu_addr = (ptr); \ | ||
| 230 | __typeof__(*(ptr)) __gu_val = 0; \ | ||
| 231 | long __gu_err = -EFAULT; \ | 235 | long __gu_err = -EFAULT; \ |
| 236 | const void __user * __gu_ptr = (ptr); \ | ||
| 237 | \ | ||
| 238 | if (likely(access_ok(VERIFY_READ, __gu_ptr, size))) \ | ||
| 239 | __get_user_common((x), size, __gu_ptr); \ | ||
| 232 | \ | 240 | \ |
| 233 | if (likely(access_ok(VERIFY_READ, __gu_addr, size))) { \ | ||
| 234 | switch (size) { \ | ||
| 235 | case 1: __get_user_asm("lb", __gu_addr); break; \ | ||
| 236 | case 2: __get_user_asm("lh", __gu_addr); break; \ | ||
| 237 | case 4: __get_user_asm("lw", __gu_addr); break; \ | ||
| 238 | case 8: __GET_USER_DW(__gu_addr); break; \ | ||
| 239 | default: __get_user_unknown(); break; \ | ||
| 240 | } \ | ||
| 241 | } \ | ||
| 242 | (x) = (__typeof__(*(ptr))) __gu_val; \ | ||
| 243 | __gu_err; \ | 241 | __gu_err; \ |
| 244 | }) | 242 | }) |
| 245 | 243 | ||
| 246 | #define __get_user_asm(insn, addr) \ | 244 | #define __get_user_asm(val, insn, addr) \ |
| 247 | { \ | 245 | { \ |
| 246 | long __gu_tmp; \ | ||
| 247 | \ | ||
| 248 | __asm__ __volatile__( \ | 248 | __asm__ __volatile__( \ |
| 249 | "1: " insn " %1, %3 \n" \ | 249 | "1: " insn " %1, %3 \n" \ |
| 250 | "2: \n" \ | 250 | "2: \n" \ |
| @@ -255,14 +255,16 @@ struct __large_struct { unsigned long buf[100]; }; | |||
| 255 | " .section __ex_table,\"a\" \n" \ | 255 | " .section __ex_table,\"a\" \n" \ |
| 256 | " "__UA_ADDR "\t1b, 3b \n" \ | 256 | " "__UA_ADDR "\t1b, 3b \n" \ |
| 257 | " .previous \n" \ | 257 | " .previous \n" \ |
| 258 | : "=r" (__gu_err), "=r" (__gu_val) \ | 258 | : "=r" (__gu_err), "=r" (__gu_tmp) \ |
| 259 | : "0" (0), "o" (__m(addr)), "i" (-EFAULT)); \ | 259 | : "0" (0), "o" (__m(addr)), "i" (-EFAULT)); \ |
| 260 | \ | ||
| 261 | (val) = (__typeof__(val)) __gu_tmp; \ | ||
| 260 | } | 262 | } |
| 261 | 263 | ||
| 262 | /* | 264 | /* |
| 263 | * Get a long long 64 using 32 bit registers. | 265 | * Get a long long 64 using 32 bit registers. |
| 264 | */ | 266 | */ |
| 265 | #define __get_user_asm_ll32(addr) \ | 267 | #define __get_user_asm_ll32(val, addr) \ |
| 266 | { \ | 268 | { \ |
| 267 | __asm__ __volatile__( \ | 269 | __asm__ __volatile__( \ |
| 268 | "1: lw %1, (%3) \n" \ | 270 | "1: lw %1, (%3) \n" \ |
| @@ -278,21 +280,20 @@ struct __large_struct { unsigned long buf[100]; }; | |||
| 278 | " " __UA_ADDR " 1b, 4b \n" \ | 280 | " " __UA_ADDR " 1b, 4b \n" \ |
| 279 | " " __UA_ADDR " 2b, 4b \n" \ | 281 | " " __UA_ADDR " 2b, 4b \n" \ |
| 280 | " .previous \n" \ | 282 | " .previous \n" \ |
| 281 | : "=r" (__gu_err), "=&r" (__gu_val) \ | 283 | : "=r" (__gu_err), "=&r" (val) \ |
| 282 | : "0" (0), "r" (addr), "i" (-EFAULT)); \ | 284 | : "0" (0), "r" (addr), "i" (-EFAULT)); \ |
| 283 | } | 285 | } |
| 284 | 286 | ||
| 285 | extern void __get_user_unknown(void); | ||
| 286 | |||
| 287 | /* | 287 | /* |
| 288 | * Yuck. We need two variants, one for 64bit operation and one | 288 | * Yuck. We need two variants, one for 64bit operation and one |
| 289 | * for 32 bit mode and old iron. | 289 | * for 32 bit mode and old iron. |
| 290 | */ | 290 | */ |
| 291 | #ifdef __mips64 | 291 | #ifdef CONFIG_32BIT |
| 292 | #define __PUT_USER_DW(ptr) __put_user_asm("sd", ptr) | ||
| 293 | #else | ||
| 294 | #define __PUT_USER_DW(ptr) __put_user_asm_ll32(ptr) | 292 | #define __PUT_USER_DW(ptr) __put_user_asm_ll32(ptr) |
| 295 | #endif | 293 | #endif |
| 294 | #ifdef CONFIG_64BIT | ||
| 295 | #define __PUT_USER_DW(ptr) __put_user_asm("sd", ptr) | ||
| 296 | #endif | ||
| 296 | 297 | ||
| 297 | #define __put_user_nocheck(x,ptr,size) \ | 298 | #define __put_user_nocheck(x,ptr,size) \ |
| 298 | ({ \ | 299 | ({ \ |
diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h index 89ea8b60e945..e7ff9b187783 100644 --- a/include/asm-mips/unistd.h +++ b/include/asm-mips/unistd.h | |||
| @@ -307,17 +307,33 @@ | |||
| 307 | #define __NR_inotify_init (__NR_Linux + 284) | 307 | #define __NR_inotify_init (__NR_Linux + 284) |
| 308 | #define __NR_inotify_add_watch (__NR_Linux + 285) | 308 | #define __NR_inotify_add_watch (__NR_Linux + 285) |
| 309 | #define __NR_inotify_rm_watch (__NR_Linux + 286) | 309 | #define __NR_inotify_rm_watch (__NR_Linux + 286) |
| 310 | 310 | #define __NR_migrate_pages (__NR_Linux + 287) | |
| 311 | #define __NR_openat (__NR_Linux + 288) | ||
| 312 | #define __NR_mkdirat (__NR_Linux + 289) | ||
| 313 | #define __NR_mknodat (__NR_Linux + 290) | ||
| 314 | #define __NR_fchownat (__NR_Linux + 291) | ||
| 315 | #define __NR_futimesat (__NR_Linux + 292) | ||
| 316 | #define __NR_newfstatat (__NR_Linux + 293) | ||
| 317 | #define __NR_unlinkat (__NR_Linux + 294) | ||
| 318 | #define __NR_renameat (__NR_Linux + 295) | ||
| 319 | #define __NR_linkat (__NR_Linux + 296) | ||
| 320 | #define __NR_symlinkat (__NR_Linux + 297) | ||
| 321 | #define __NR_readlinkat (__NR_Linux + 298) | ||
| 322 | #define __NR_fchmodat (__NR_Linux + 299) | ||
| 323 | #define __NR_faccessat (__NR_Linux + 300) | ||
| 324 | #define __NR_pselect6 (__NR_Linux + 301) | ||
| 325 | #define __NR_ppoll (__NR_Linux + 302) | ||
| 326 | #define __NR_unshare (__NR_Linux + 303) | ||
| 311 | 327 | ||
| 312 | /* | 328 | /* |
| 313 | * Offset of the last Linux o32 flavoured syscall | 329 | * Offset of the last Linux o32 flavoured syscall |
| 314 | */ | 330 | */ |
| 315 | #define __NR_Linux_syscalls 286 | 331 | #define __NR_Linux_syscalls 303 |
| 316 | 332 | ||
| 317 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ | 333 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ |
| 318 | 334 | ||
| 319 | #define __NR_O32_Linux 4000 | 335 | #define __NR_O32_Linux 4000 |
| 320 | #define __NR_O32_Linux_syscalls 283 | 336 | #define __NR_O32_Linux_syscalls 303 |
| 321 | 337 | ||
| 322 | #if _MIPS_SIM == _MIPS_SIM_ABI64 | 338 | #if _MIPS_SIM == _MIPS_SIM_ABI64 |
| 323 | 339 | ||
| @@ -571,16 +587,33 @@ | |||
| 571 | #define __NR_inotify_init (__NR_Linux + 243) | 587 | #define __NR_inotify_init (__NR_Linux + 243) |
| 572 | #define __NR_inotify_add_watch (__NR_Linux + 244) | 588 | #define __NR_inotify_add_watch (__NR_Linux + 244) |
| 573 | #define __NR_inotify_rm_watch (__NR_Linux + 245) | 589 | #define __NR_inotify_rm_watch (__NR_Linux + 245) |
| 590 | #define __NR_migrate_pages (__NR_Linux + 246) | ||
| 591 | #define __NR_openat (__NR_Linux + 247) | ||
| 592 | #define __NR_mkdirat (__NR_Linux + 248) | ||
| 593 | #define __NR_mknodat (__NR_Linux + 249) | ||
| 594 | #define __NR_fchownat (__NR_Linux + 250) | ||
| 595 | #define __NR_futimesat (__NR_Linux + 251) | ||
| 596 | #define __NR_newfstatat (__NR_Linux + 252) | ||
| 597 | #define __NR_unlinkat (__NR_Linux + 253) | ||
| 598 | #define __NR_renameat (__NR_Linux + 254) | ||
| 599 | #define __NR_linkat (__NR_Linux + 255) | ||
| 600 | #define __NR_symlinkat (__NR_Linux + 256) | ||
| 601 | #define __NR_readlinkat (__NR_Linux + 257) | ||
| 602 | #define __NR_fchmodat (__NR_Linux + 258) | ||
| 603 | #define __NR_faccessat (__NR_Linux + 259) | ||
| 604 | #define __NR_pselect6 (__NR_Linux + 260) | ||
| 605 | #define __NR_ppoll (__NR_Linux + 261) | ||
| 606 | #define __NR_unshare (__NR_Linux + 262) | ||
| 574 | 607 | ||
| 575 | /* | 608 | /* |
| 576 | * Offset of the last Linux 64-bit flavoured syscall | 609 | * Offset of the last Linux 64-bit flavoured syscall |
| 577 | */ | 610 | */ |
| 578 | #define __NR_Linux_syscalls 245 | 611 | #define __NR_Linux_syscalls 262 |
| 579 | 612 | ||
| 580 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ | 613 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ |
| 581 | 614 | ||
| 582 | #define __NR_64_Linux 5000 | 615 | #define __NR_64_Linux 5000 |
| 583 | #define __NR_64_Linux_syscalls 242 | 616 | #define __NR_64_Linux_syscalls 262 |
| 584 | 617 | ||
| 585 | #if _MIPS_SIM == _MIPS_SIM_NABI32 | 618 | #if _MIPS_SIM == _MIPS_SIM_NABI32 |
| 586 | 619 | ||
| @@ -838,16 +871,33 @@ | |||
| 838 | #define __NR_inotify_init (__NR_Linux + 247) | 871 | #define __NR_inotify_init (__NR_Linux + 247) |
| 839 | #define __NR_inotify_add_watch (__NR_Linux + 248) | 872 | #define __NR_inotify_add_watch (__NR_Linux + 248) |
| 840 | #define __NR_inotify_rm_watch (__NR_Linux + 249) | 873 | #define __NR_inotify_rm_watch (__NR_Linux + 249) |
| 874 | #define __NR_migrate_pages (__NR_Linux + 250) | ||
| 875 | #define __NR_openat (__NR_Linux + 251) | ||
| 876 | #define __NR_mkdirat (__NR_Linux + 252) | ||
| 877 | #define __NR_mknodat (__NR_Linux + 253) | ||
| 878 | #define __NR_fchownat (__NR_Linux + 254) | ||
| 879 | #define __NR_futimesat (__NR_Linux + 255) | ||
| 880 | #define __NR_newfstatat (__NR_Linux + 256) | ||
| 881 | #define __NR_unlinkat (__NR_Linux + 257) | ||
| 882 | #define __NR_renameat (__NR_Linux + 258) | ||
| 883 | #define __NR_linkat (__NR_Linux + 259) | ||
| 884 | #define __NR_symlinkat (__NR_Linux + 260) | ||
| 885 | #define __NR_readlinkat (__NR_Linux + 261) | ||
| 886 | #define __NR_fchmodat (__NR_Linux + 262) | ||
| 887 | #define __NR_faccessat (__NR_Linux + 263) | ||
| 888 | #define __NR_pselect6 (__NR_Linux + 264) | ||
| 889 | #define __NR_ppoll (__NR_Linux + 265) | ||
| 890 | #define __NR_unshare (__NR_Linux + 266) | ||
| 841 | 891 | ||
| 842 | /* | 892 | /* |
| 843 | * Offset of the last N32 flavoured syscall | 893 | * Offset of the last N32 flavoured syscall |
| 844 | */ | 894 | */ |
| 845 | #define __NR_Linux_syscalls 249 | 895 | #define __NR_Linux_syscalls 266 |
| 846 | 896 | ||
| 847 | #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ | 897 | #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ |
| 848 | 898 | ||
| 849 | #define __NR_N32_Linux 6000 | 899 | #define __NR_N32_Linux 6000 |
| 850 | #define __NR_N32_Linux_syscalls 246 | 900 | #define __NR_N32_Linux_syscalls 266 |
| 851 | 901 | ||
| 852 | #ifndef __ASSEMBLY__ | 902 | #ifndef __ASSEMBLY__ |
| 853 | 903 | ||
diff --git a/include/asm-parisc/atomic.h b/include/asm-parisc/atomic.h index 2ca56d34aaad..4dc7253ff5d0 100644 --- a/include/asm-parisc/atomic.h +++ b/include/asm-parisc/atomic.h | |||
| @@ -1,9 +1,13 @@ | |||
| 1 | /* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> | ||
| 2 | * Copyright (C) 2006 Kyle McMartin <kyle@parisc-linux.org> | ||
| 3 | */ | ||
| 4 | |||
| 1 | #ifndef _ASM_PARISC_ATOMIC_H_ | 5 | #ifndef _ASM_PARISC_ATOMIC_H_ |
| 2 | #define _ASM_PARISC_ATOMIC_H_ | 6 | #define _ASM_PARISC_ATOMIC_H_ |
| 3 | 7 | ||
| 4 | #include <linux/config.h> | 8 | #include <linux/config.h> |
| 9 | #include <linux/types.h> | ||
| 5 | #include <asm/system.h> | 10 | #include <asm/system.h> |
| 6 | /* Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org>. */ | ||
| 7 | 11 | ||
| 8 | /* | 12 | /* |
| 9 | * Atomic operations that C can't guarantee us. Useful for | 13 | * Atomic operations that C can't guarantee us. Useful for |
| @@ -46,15 +50,6 @@ extern raw_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned; | |||
| 46 | # define _atomic_spin_unlock_irqrestore(l,f) do { local_irq_restore(f); } while (0) | 50 | # define _atomic_spin_unlock_irqrestore(l,f) do { local_irq_restore(f); } while (0) |
| 47 | #endif | 51 | #endif |
| 48 | 52 | ||
| 49 | /* Note that we need not lock read accesses - aligned word writes/reads | ||
| 50 | * are atomic, so a reader never sees unconsistent values. | ||
| 51 | * | ||
| 52 | * Cache-line alignment would conflict with, for example, linux/module.h | ||
| 53 | */ | ||
| 54 | |||
| 55 | typedef struct { volatile int counter; } atomic_t; | ||
| 56 | |||
| 57 | |||
| 58 | /* This should get optimized out since it's never called. | 53 | /* This should get optimized out since it's never called. |
| 59 | ** Or get a link error if xchg is used "wrong". | 54 | ** Or get a link error if xchg is used "wrong". |
| 60 | */ | 55 | */ |
| @@ -69,10 +64,9 @@ extern unsigned long __xchg64(unsigned long, unsigned long *); | |||
| 69 | #endif | 64 | #endif |
| 70 | 65 | ||
| 71 | /* optimizer better get rid of switch since size is a constant */ | 66 | /* optimizer better get rid of switch since size is a constant */ |
| 72 | static __inline__ unsigned long __xchg(unsigned long x, __volatile__ void * ptr, | 67 | static __inline__ unsigned long |
| 73 | int size) | 68 | __xchg(unsigned long x, __volatile__ void * ptr, int size) |
| 74 | { | 69 | { |
| 75 | |||
| 76 | switch(size) { | 70 | switch(size) { |
| 77 | #ifdef __LP64__ | 71 | #ifdef __LP64__ |
| 78 | case 8: return __xchg64(x,(unsigned long *) ptr); | 72 | case 8: return __xchg64(x,(unsigned long *) ptr); |
| @@ -129,7 +123,13 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size) | |||
| 129 | (unsigned long)_n_, sizeof(*(ptr))); \ | 123 | (unsigned long)_n_, sizeof(*(ptr))); \ |
| 130 | }) | 124 | }) |
| 131 | 125 | ||
| 126 | /* Note that we need not lock read accesses - aligned word writes/reads | ||
| 127 | * are atomic, so a reader never sees unconsistent values. | ||
| 128 | * | ||
| 129 | * Cache-line alignment would conflict with, for example, linux/module.h | ||
| 130 | */ | ||
| 132 | 131 | ||
| 132 | typedef struct { volatile int counter; } atomic_t; | ||
| 133 | 133 | ||
| 134 | /* It's possible to reduce all atomic operations to either | 134 | /* It's possible to reduce all atomic operations to either |
| 135 | * __atomic_add_return, atomic_set and atomic_read (the latter | 135 | * __atomic_add_return, atomic_set and atomic_read (the latter |
| @@ -210,12 +210,66 @@ static __inline__ int atomic_read(const atomic_t *v) | |||
| 210 | 210 | ||
| 211 | #define atomic_dec_and_test(v) (atomic_dec_return(v) == 0) | 211 | #define atomic_dec_and_test(v) (atomic_dec_return(v) == 0) |
| 212 | 212 | ||
| 213 | #define ATOMIC_INIT(i) { (i) } | 213 | #define ATOMIC_INIT(i) ((atomic_t) { (i) }) |
| 214 | 214 | ||
| 215 | #define smp_mb__before_atomic_dec() smp_mb() | 215 | #define smp_mb__before_atomic_dec() smp_mb() |
| 216 | #define smp_mb__after_atomic_dec() smp_mb() | 216 | #define smp_mb__after_atomic_dec() smp_mb() |
| 217 | #define smp_mb__before_atomic_inc() smp_mb() | 217 | #define smp_mb__before_atomic_inc() smp_mb() |
| 218 | #define smp_mb__after_atomic_inc() smp_mb() | 218 | #define smp_mb__after_atomic_inc() smp_mb() |
| 219 | 219 | ||
| 220 | #ifdef __LP64__ | ||
| 221 | |||
| 222 | typedef struct { volatile s64 counter; } atomic64_t; | ||
| 223 | |||
| 224 | #define ATOMIC64_INIT(i) ((atomic64_t) { (i) }) | ||
| 225 | |||
| 226 | static __inline__ int | ||
| 227 | __atomic64_add_return(s64 i, atomic64_t *v) | ||
| 228 | { | ||
| 229 | int ret; | ||
| 230 | unsigned long flags; | ||
| 231 | _atomic_spin_lock_irqsave(v, flags); | ||
| 232 | |||
| 233 | ret = (v->counter += i); | ||
| 234 | |||
| 235 | _atomic_spin_unlock_irqrestore(v, flags); | ||
| 236 | return ret; | ||
| 237 | } | ||
| 238 | |||
| 239 | static __inline__ void | ||
| 240 | atomic64_set(atomic64_t *v, s64 i) | ||
| 241 | { | ||
| 242 | unsigned long flags; | ||
| 243 | _atomic_spin_lock_irqsave(v, flags); | ||
| 244 | |||
| 245 | v->counter = i; | ||
| 246 | |||
| 247 | _atomic_spin_unlock_irqrestore(v, flags); | ||
| 248 | } | ||
| 249 | |||
| 250 | static __inline__ s64 | ||
| 251 | atomic64_read(const atomic64_t *v) | ||
| 252 | { | ||
| 253 | return v->counter; | ||
| 254 | } | ||
| 255 | |||
| 256 | #define atomic64_add(i,v) ((void)(__atomic64_add_return( ((s64)i),(v)))) | ||
| 257 | #define atomic64_sub(i,v) ((void)(__atomic64_add_return(-((s64)i),(v)))) | ||
| 258 | #define atomic64_inc(v) ((void)(__atomic64_add_return( 1,(v)))) | ||
| 259 | #define atomic64_dec(v) ((void)(__atomic64_add_return( -1,(v)))) | ||
| 260 | |||
| 261 | #define atomic64_add_return(i,v) (__atomic64_add_return( ((s64)i),(v))) | ||
| 262 | #define atomic64_sub_return(i,v) (__atomic64_add_return(-((s64)i),(v))) | ||
| 263 | #define atomic64_inc_return(v) (__atomic64_add_return( 1,(v))) | ||
| 264 | #define atomic64_dec_return(v) (__atomic64_add_return( -1,(v))) | ||
| 265 | |||
| 266 | #define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0) | ||
| 267 | |||
| 268 | #define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0) | ||
| 269 | #define atomic64_dec_and_test(v) (atomic64_dec_return(v) == 0) | ||
| 270 | |||
| 271 | #endif /* __LP64__ */ | ||
| 272 | |||
| 220 | #include <asm-generic/atomic.h> | 273 | #include <asm-generic/atomic.h> |
| 221 | #endif | 274 | |
| 275 | #endif /* _ASM_PARISC_ATOMIC_H_ */ | ||
diff --git a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h index 1bc3c83ee74b..c53af9ff41b5 100644 --- a/include/asm-parisc/cacheflush.h +++ b/include/asm-parisc/cacheflush.h | |||
| @@ -183,4 +183,10 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long | |||
| 183 | __flush_cache_page(vma, vmaddr); | 183 | __flush_cache_page(vma, vmaddr); |
| 184 | 184 | ||
| 185 | } | 185 | } |
| 186 | |||
| 187 | #ifdef CONFIG_DEBUG_RODATA | ||
| 188 | void mark_rodata_ro(void); | ||
| 186 | #endif | 189 | #endif |
| 190 | |||
| 191 | #endif /* _PARISC_CACHEFLUSH_H */ | ||
| 192 | |||
diff --git a/include/asm-parisc/compat_ucontext.h b/include/asm-parisc/compat_ucontext.h index a1228a3d2071..2f7292afde3c 100644 --- a/include/asm-parisc/compat_ucontext.h +++ b/include/asm-parisc/compat_ucontext.h | |||
| @@ -1,8 +1,7 @@ | |||
| 1 | #ifndef _ASM_PARISC_COMPAT_UCONTEXT_H | 1 | #ifndef _ASM_PARISC_COMPAT_UCONTEXT_H |
| 2 | #define _ASM_PARISC_COMPAT_UCONTEXT_H | 2 | #define _ASM_PARISC_COMPAT_UCONTEXT_H |
| 3 | 3 | ||
| 4 | #include<linux/compat.h> | 4 | #include <linux/compat.h> |
| 5 | #include<asm/compat_signal.h> | ||
| 6 | 5 | ||
| 7 | /* 32-bit ucontext as seen from an 64-bit kernel */ | 6 | /* 32-bit ucontext as seen from an 64-bit kernel */ |
| 8 | struct compat_ucontext { | 7 | struct compat_ucontext { |
diff --git a/include/asm-parisc/grfioctl.h b/include/asm-parisc/grfioctl.h index 6a910311b56b..671e06042b40 100644 --- a/include/asm-parisc/grfioctl.h +++ b/include/asm-parisc/grfioctl.h | |||
| @@ -58,7 +58,7 @@ | |||
| 58 | #define CRT_ID_ELK_1024DB 0x27849CA5 /* Elk 1024x768 double buffer */ | 58 | #define CRT_ID_ELK_1024DB 0x27849CA5 /* Elk 1024x768 double buffer */ |
| 59 | #define CRT_ID_ELK_GS S9000_ID_A1924A /* Elk 1280x1024 GreyScale */ | 59 | #define CRT_ID_ELK_GS S9000_ID_A1924A /* Elk 1280x1024 GreyScale */ |
| 60 | #define CRT_ID_CRX24 S9000_ID_A1439A /* Piranha */ | 60 | #define CRT_ID_CRX24 S9000_ID_A1439A /* Piranha */ |
| 61 | #define CRT_ID_VISUALIZE_EG 0x2D08C0A7 /* Graffiti (built-in B132+/B160L) */ | 61 | #define CRT_ID_VISUALIZE_EG 0x2D08C0A7 /* Graffiti, A4450A (built-in B132+/B160L) */ |
| 62 | #define CRT_ID_THUNDER 0x2F23E5FC /* Thunder 1 VISUALIZE 48*/ | 62 | #define CRT_ID_THUNDER 0x2F23E5FC /* Thunder 1 VISUALIZE 48*/ |
| 63 | #define CRT_ID_THUNDER2 0x2F8D570E /* Thunder 2 VISUALIZE 48 XP*/ | 63 | #define CRT_ID_THUNDER2 0x2F8D570E /* Thunder 2 VISUALIZE 48 XP*/ |
| 64 | #define CRT_ID_HCRX S9000_ID_HCRX /* Hyperdrive HCRX */ | 64 | #define CRT_ID_HCRX S9000_ID_HCRX /* Hyperdrive HCRX */ |
diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h index f277254159b7..fe7f6a2f5aa7 100644 --- a/include/asm-parisc/pci.h +++ b/include/asm-parisc/pci.h | |||
| @@ -18,6 +18,18 @@ | |||
| 18 | */ | 18 | */ |
| 19 | #define PCI_MAX_BUSSES 256 | 19 | #define PCI_MAX_BUSSES 256 |
| 20 | 20 | ||
| 21 | |||
| 22 | /* To be used as: mdelay(pci_post_reset_delay); | ||
| 23 | * | ||
| 24 | * post_reset is the time the kernel should stall to prevent anyone from | ||
| 25 | * accessing the PCI bus once #RESET is de-asserted. | ||
| 26 | * PCI spec somewhere says 1 second but with multi-PCI bus systems, | ||
| 27 | * this makes the boot time much longer than necessary. | ||
| 28 | * 20ms seems to work for all the HP PCI implementations to date. | ||
| 29 | */ | ||
| 30 | #define pci_post_reset_delay 50 | ||
| 31 | |||
| 32 | |||
| 21 | /* | 33 | /* |
| 22 | ** pci_hba_data (aka H2P_OBJECT in HP/UX) | 34 | ** pci_hba_data (aka H2P_OBJECT in HP/UX) |
| 23 | ** | 35 | ** |
| @@ -83,7 +95,7 @@ static __inline__ int pci_is_lmmio(struct pci_hba_data *hba, unsigned long a) | |||
| 83 | 95 | ||
| 84 | /* | 96 | /* |
| 85 | ** Convert between PCI (IO_VIEW) addresses and processor (PA_VIEW) addresses. | 97 | ** Convert between PCI (IO_VIEW) addresses and processor (PA_VIEW) addresses. |
| 86 | ** See pcibios.c for more conversions used by Generic PCI code. | 98 | ** See pci.c for more conversions used by Generic PCI code. |
| 87 | ** | 99 | ** |
| 88 | ** Platform characteristics/firmware guarantee that | 100 | ** Platform characteristics/firmware guarantee that |
| 89 | ** (1) PA_VIEW - IO_VIEW = lmmio_offset for both LMMIO and ELMMIO | 101 | ** (1) PA_VIEW - IO_VIEW = lmmio_offset for both LMMIO and ELMMIO |
| @@ -191,9 +203,6 @@ struct pci_bios_ops { | |||
| 191 | */ | 203 | */ |
| 192 | extern struct pci_port_ops *pci_port; | 204 | extern struct pci_port_ops *pci_port; |
| 193 | extern struct pci_bios_ops *pci_bios; | 205 | extern struct pci_bios_ops *pci_bios; |
| 194 | extern int pci_post_reset_delay; /* delay after de-asserting #RESET */ | ||
| 195 | extern int pci_hba_count; | ||
| 196 | extern struct pci_hba_data *parisc_pci_hba[]; | ||
| 197 | 206 | ||
| 198 | #ifdef CONFIG_PCI | 207 | #ifdef CONFIG_PCI |
| 199 | extern void pcibios_register_hba(struct pci_hba_data *); | 208 | extern void pcibios_register_hba(struct pci_hba_data *); |
diff --git a/include/asm-parisc/pgalloc.h b/include/asm-parisc/pgalloc.h index 6291d6692e5d..3122fad38a1b 100644 --- a/include/asm-parisc/pgalloc.h +++ b/include/asm-parisc/pgalloc.h | |||
| @@ -137,7 +137,6 @@ static inline void pte_free_kernel(pte_t *pte) | |||
| 137 | 137 | ||
| 138 | #define pte_free(page) pte_free_kernel(page_address(page)) | 138 | #define pte_free(page) pte_free_kernel(page_address(page)) |
| 139 | 139 | ||
| 140 | extern int do_check_pgt_cache(int, int); | ||
| 141 | #define check_pgt_cache() do { } while (0) | 140 | #define check_pgt_cache() do { } while (0) |
| 142 | 141 | ||
| 143 | #endif | 142 | #endif |
diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h index b4554711c3e7..4e34c6b44059 100644 --- a/include/asm-parisc/pgtable.h +++ b/include/asm-parisc/pgtable.h | |||
| @@ -213,7 +213,7 @@ extern void *vmalloc_start; | |||
| 213 | #define PAGE_COPY PAGE_EXECREAD | 213 | #define PAGE_COPY PAGE_EXECREAD |
| 214 | #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED) | 214 | #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED) |
| 215 | #define PAGE_KERNEL __pgprot(_PAGE_KERNEL) | 215 | #define PAGE_KERNEL __pgprot(_PAGE_KERNEL) |
| 216 | #define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_DIRTY | _PAGE_ACCESSED) | 216 | #define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL & ~_PAGE_WRITE) |
| 217 | #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE) | 217 | #define PAGE_KERNEL_UNC __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE) |
| 218 | #define PAGE_GATEWAY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_GATEWAY| _PAGE_READ) | 218 | #define PAGE_GATEWAY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_GATEWAY| _PAGE_READ) |
| 219 | #define PAGE_FLUSH __pgprot(_PAGE_FLUSH) | 219 | #define PAGE_FLUSH __pgprot(_PAGE_FLUSH) |
diff --git a/include/asm-parisc/rt_sigframe.h b/include/asm-parisc/rt_sigframe.h index 5623c032b64c..f0dd3b30f6c4 100644 --- a/include/asm-parisc/rt_sigframe.h +++ b/include/asm-parisc/rt_sigframe.h | |||
| @@ -1,10 +1,6 @@ | |||
| 1 | #ifndef _ASM_PARISC_RT_SIGFRAME_H | 1 | #ifndef _ASM_PARISC_RT_SIGFRAME_H |
| 2 | #define _ASM_PARISC_RT_SIGFRAME_H | 2 | #define _ASM_PARISC_RT_SIGFRAME_H |
| 3 | 3 | ||
| 4 | #ifdef CONFIG_COMPAT | ||
| 5 | #include <asm/compat_rt_sigframe.h> | ||
| 6 | #endif | ||
| 7 | |||
| 8 | #define SIGRETURN_TRAMP 4 | 4 | #define SIGRETURN_TRAMP 4 |
| 9 | #define SIGRESTARTBLOCK_TRAMP 5 | 5 | #define SIGRESTARTBLOCK_TRAMP 5 |
| 10 | #define TRAMP_SIZE (SIGRETURN_TRAMP + SIGRESTARTBLOCK_TRAMP) | 6 | #define TRAMP_SIZE (SIGRETURN_TRAMP + SIGRESTARTBLOCK_TRAMP) |
diff --git a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h index 80b7b98c70a1..c56fccbf34ad 100644 --- a/include/asm-parisc/unistd.h +++ b/include/asm-parisc/unistd.h | |||
| @@ -761,8 +761,27 @@ | |||
| 761 | #define __NR_keyctl (__NR_Linux + 266) | 761 | #define __NR_keyctl (__NR_Linux + 266) |
| 762 | #define __NR_ioprio_set (__NR_Linux + 267) | 762 | #define __NR_ioprio_set (__NR_Linux + 267) |
| 763 | #define __NR_ioprio_get (__NR_Linux + 268) | 763 | #define __NR_ioprio_get (__NR_Linux + 268) |
| 764 | #define __NR_inotify_init (__NR_Linux + 269) | ||
| 765 | #define __NR_inotify_add_watch (__NR_Linux + 270) | ||
| 766 | #define __NR_inotify_rm_watch (__NR_Linux + 271) | ||
| 767 | #define __NR_migrate_pages (__NR_Linux + 272) | ||
| 768 | #define __NR_pselect6 (__NR_Linux + 273) | ||
| 769 | #define __NR_ppoll (__NR_Linux + 274) | ||
| 770 | #define __NR_openat (__NR_Linux + 275) | ||
| 771 | #define __NR_mkdirat (__NR_Linux + 276) | ||
| 772 | #define __NR_mknodat (__NR_Linux + 277) | ||
| 773 | #define __NR_fchownat (__NR_Linux + 278) | ||
| 774 | #define __NR_futimesat (__NR_Linux + 279) | ||
| 775 | #define __NR_newfstatat (__NR_Linux + 280) | ||
| 776 | #define __NR_unlinkat (__NR_Linux + 281) | ||
| 777 | #define __NR_renameat (__NR_Linux + 282) | ||
| 778 | #define __NR_linkat (__NR_Linux + 283) | ||
| 779 | #define __NR_symlinkat (__NR_Linux + 284) | ||
| 780 | #define __NR_readlinkat (__NR_Linux + 285) | ||
| 781 | #define __NR_fchmodat (__NR_Linux + 286) | ||
| 782 | #define __NR_faccessat (__NR_Linux + 287) | ||
| 764 | 783 | ||
| 765 | #define __NR_Linux_syscalls 269 | 784 | #define __NR_Linux_syscalls 288 |
| 766 | 785 | ||
| 767 | #define HPUX_GATEWAY_ADDR 0xC0000004 | 786 | #define HPUX_GATEWAY_ADDR 0xC0000004 |
| 768 | #define LINUX_GATEWAY_ADDR 0x100 | 787 | #define LINUX_GATEWAY_ADDR 0x100 |
diff --git a/include/asm-powerpc/compat.h b/include/asm-powerpc/compat.h index accb80c9a339..aacaabd28ac1 100644 --- a/include/asm-powerpc/compat.h +++ b/include/asm-powerpc/compat.h | |||
| @@ -126,6 +126,11 @@ static inline void __user *compat_ptr(compat_uptr_t uptr) | |||
| 126 | return (void __user *)(unsigned long)uptr; | 126 | return (void __user *)(unsigned long)uptr; |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | static inline compat_uptr_t ptr_to_compat(void __user *uptr) | ||
| 130 | { | ||
| 131 | return (u32)(unsigned long)uptr; | ||
| 132 | } | ||
| 133 | |||
| 129 | static inline void __user *compat_alloc_user_space(long len) | 134 | static inline void __user *compat_alloc_user_space(long len) |
| 130 | { | 135 | { |
| 131 | struct pt_regs *regs = current->thread.regs; | 136 | struct pt_regs *regs = current->thread.regs; |
diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h index 837756ab7dc7..2ac63f569592 100644 --- a/include/asm-powerpc/dma-mapping.h +++ b/include/asm-powerpc/dma-mapping.h | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | #include <linux/mm.h> | 15 | #include <linux/mm.h> |
| 16 | #include <asm/scatterlist.h> | 16 | #include <asm/scatterlist.h> |
| 17 | #include <asm/io.h> | 17 | #include <asm/io.h> |
| 18 | #include <asm/bug.h> | ||
| 19 | 18 | ||
| 20 | #define DMA_ERROR_CODE (~(dma_addr_t)0x0) | 19 | #define DMA_ERROR_CODE (~(dma_addr_t)0x0) |
| 21 | 20 | ||
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h index 5b2bd4eefb01..cbd297f44cce 100644 --- a/include/asm-powerpc/prom.h +++ b/include/asm-powerpc/prom.h | |||
| @@ -222,5 +222,7 @@ extern int of_address_to_resource(struct device_node *dev, int index, | |||
| 222 | extern int of_pci_address_to_resource(struct device_node *dev, int bar, | 222 | extern int of_pci_address_to_resource(struct device_node *dev, int bar, |
| 223 | struct resource *r); | 223 | struct resource *r); |
| 224 | 224 | ||
| 225 | extern void kdump_move_device_tree(void); | ||
| 226 | |||
| 225 | #endif /* __KERNEL__ */ | 227 | #endif /* __KERNEL__ */ |
| 226 | #endif /* _POWERPC_PROM_H */ | 228 | #endif /* _POWERPC_PROM_H */ |
diff --git a/include/asm-powerpc/smu.h b/include/asm-powerpc/smu.h index 82ce47607774..2dc93632f210 100644 --- a/include/asm-powerpc/smu.h +++ b/include/asm-powerpc/smu.h | |||
| @@ -521,6 +521,11 @@ struct smu_sdbp_cpupiddata { | |||
| 521 | extern struct smu_sdbp_header *smu_get_sdb_partition(int id, | 521 | extern struct smu_sdbp_header *smu_get_sdb_partition(int id, |
| 522 | unsigned int *size); | 522 | unsigned int *size); |
| 523 | 523 | ||
| 524 | /* Get "sdb" partition data from an SMU satellite */ | ||
| 525 | extern struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, | ||
| 526 | int id, unsigned int *size); | ||
| 527 | |||
| 528 | |||
| 524 | #endif /* __KERNEL__ */ | 529 | #endif /* __KERNEL__ */ |
| 525 | 530 | ||
| 526 | 531 | ||
diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h index 67cdaf3ae9fc..c044ec16a879 100644 --- a/include/asm-powerpc/thread_info.h +++ b/include/asm-powerpc/thread_info.h | |||
| @@ -37,7 +37,7 @@ struct thread_info { | |||
| 37 | int preempt_count; /* 0 => preemptable, | 37 | int preempt_count; /* 0 => preemptable, |
| 38 | <0 => BUG */ | 38 | <0 => BUG */ |
| 39 | struct restart_block restart_block; | 39 | struct restart_block restart_block; |
| 40 | void *nvgprs_frame; | 40 | void __user *nvgprs_frame; |
| 41 | /* low level flags - has atomic operations done on it */ | 41 | /* low level flags - has atomic operations done on it */ |
| 42 | unsigned long flags ____cacheline_aligned_in_smp; | 42 | unsigned long flags ____cacheline_aligned_in_smp; |
| 43 | }; | 43 | }; |
diff --git a/include/asm-s390/dasd.h b/include/asm-s390/dasd.h index 1630c26e8f45..c744ff33b1df 100644 --- a/include/asm-s390/dasd.h +++ b/include/asm-s390/dasd.h | |||
| @@ -204,7 +204,8 @@ typedef struct attrib_data_t { | |||
| 204 | * | 204 | * |
| 205 | * Here ist how the ioctl-nr should be used: | 205 | * Here ist how the ioctl-nr should be used: |
| 206 | * 0 - 31 DASD driver itself | 206 | * 0 - 31 DASD driver itself |
| 207 | * 32 - 239 still open | 207 | * 32 - 229 still open |
| 208 | * 230 - 239 DASD extended error reporting | ||
| 208 | * 240 - 255 reserved for EMC | 209 | * 240 - 255 reserved for EMC |
| 209 | *******************************************************************************/ | 210 | *******************************************************************************/ |
| 210 | 211 | ||
| @@ -236,12 +237,22 @@ typedef struct attrib_data_t { | |||
| 236 | #define BIODASDPSRD _IOR(DASD_IOCTL_LETTER,4,dasd_rssd_perf_stats_t) | 237 | #define BIODASDPSRD _IOR(DASD_IOCTL_LETTER,4,dasd_rssd_perf_stats_t) |
| 237 | /* Get Attributes (cache operations) */ | 238 | /* Get Attributes (cache operations) */ |
| 238 | #define BIODASDGATTR _IOR(DASD_IOCTL_LETTER,5,attrib_data_t) | 239 | #define BIODASDGATTR _IOR(DASD_IOCTL_LETTER,5,attrib_data_t) |
| 240 | /* retrieve extended error-reporting value */ | ||
| 241 | #define BIODASDEERGET _IOR(DASD_IOCTL_LETTER,6,int) | ||
| 239 | 242 | ||
| 240 | 243 | ||
| 241 | /* #define BIODASDFORMAT _IOW(IOCTL_LETTER,0,format_data_t) , deprecated */ | 244 | /* #define BIODASDFORMAT _IOW(IOCTL_LETTER,0,format_data_t) , deprecated */ |
| 242 | #define BIODASDFMT _IOW(DASD_IOCTL_LETTER,1,format_data_t) | 245 | #define BIODASDFMT _IOW(DASD_IOCTL_LETTER,1,format_data_t) |
| 243 | /* Set Attributes (cache operations) */ | 246 | /* Set Attributes (cache operations) */ |
| 244 | #define BIODASDSATTR _IOW(DASD_IOCTL_LETTER,2,attrib_data_t) | 247 | #define BIODASDSATTR _IOW(DASD_IOCTL_LETTER,2,attrib_data_t) |
| 248 | /* retrieve extended error-reporting value */ | ||
| 249 | #define BIODASDEERSET _IOW(DASD_IOCTL_LETTER,3,int) | ||
| 250 | |||
| 251 | |||
| 252 | /* remove all records from the eer buffer */ | ||
| 253 | #define DASD_EER_PURGE _IO(DASD_IOCTL_LETTER,230) | ||
| 254 | /* set the number of pages that are used for the internal eer buffer */ | ||
| 255 | #define DASD_EER_SETBUFSIZE _IOW(DASD_IOCTL_LETTER,230,int) | ||
| 245 | 256 | ||
| 246 | 257 | ||
| 247 | #endif /* DASD_H */ | 258 | #endif /* DASD_H */ |
diff --git a/include/asm-s390/io.h b/include/asm-s390/io.h index 71f55eb2350a..b05825dd16d7 100644 --- a/include/asm-s390/io.h +++ b/include/asm-s390/io.h | |||
| @@ -90,10 +90,16 @@ extern void iounmap(void *addr); | |||
| 90 | #define readb_relaxed(addr) readb(addr) | 90 | #define readb_relaxed(addr) readb(addr) |
| 91 | #define readw_relaxed(addr) readw(addr) | 91 | #define readw_relaxed(addr) readw(addr) |
| 92 | #define readl_relaxed(addr) readl(addr) | 92 | #define readl_relaxed(addr) readl(addr) |
| 93 | #define __raw_readb readb | ||
| 94 | #define __raw_readw readw | ||
| 95 | #define __raw_readl readl | ||
| 93 | 96 | ||
| 94 | #define writeb(b,addr) (*(volatile unsigned char *) __io_virt(addr) = (b)) | 97 | #define writeb(b,addr) (*(volatile unsigned char *) __io_virt(addr) = (b)) |
| 95 | #define writew(b,addr) (*(volatile unsigned short *) __io_virt(addr) = (b)) | 98 | #define writew(b,addr) (*(volatile unsigned short *) __io_virt(addr) = (b)) |
| 96 | #define writel(b,addr) (*(volatile unsigned int *) __io_virt(addr) = (b)) | 99 | #define writel(b,addr) (*(volatile unsigned int *) __io_virt(addr) = (b)) |
| 100 | #define __raw_writeb writeb | ||
| 101 | #define __raw_writew writew | ||
| 102 | #define __raw_writel writel | ||
| 97 | 103 | ||
| 98 | #define memset_io(a,b,c) memset(__io_virt(a),(b),(c)) | 104 | #define memset_io(a,b,c) memset(__io_virt(a),(b),(c)) |
| 99 | #define memcpy_fromio(a,b,c) memcpy((a),__io_virt(b),(c)) | 105 | #define memcpy_fromio(a,b,c) memcpy((a),__io_virt(b),(c)) |
diff --git a/include/asm-s390/timer.h b/include/asm-s390/timer.h index ea0788967c51..fcd6c256a2d1 100644 --- a/include/asm-s390/timer.h +++ b/include/asm-s390/timer.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * include/asm-s390/timer.h | 2 | * include/asm-s390/timer.h |
| 3 | * | 3 | * |
| 4 | * (C) Copyright IBM Corp. 2003 | 4 | * (C) Copyright IBM Corp. 2003,2006 |
| 5 | * Virtual CPU timer | 5 | * Virtual CPU timer |
| 6 | * | 6 | * |
| 7 | * Author: Jan Glauber (jang@de.ibm.com) | 7 | * Author: Jan Glauber (jang@de.ibm.com) |
| @@ -10,6 +10,8 @@ | |||
| 10 | #ifndef _ASM_S390_TIMER_H | 10 | #ifndef _ASM_S390_TIMER_H |
| 11 | #define _ASM_S390_TIMER_H | 11 | #define _ASM_S390_TIMER_H |
| 12 | 12 | ||
| 13 | #ifdef __KERNEL__ | ||
| 14 | |||
| 13 | #include <linux/timer.h> | 15 | #include <linux/timer.h> |
| 14 | 16 | ||
| 15 | #define VTIMER_MAX_SLICE (0x7ffffffffffff000LL) | 17 | #define VTIMER_MAX_SLICE (0x7ffffffffffff000LL) |
| @@ -43,4 +45,6 @@ extern void add_virt_timer_periodic(void *new); | |||
| 43 | extern int mod_virt_timer(struct vtimer_list *timer, __u64 expires); | 45 | extern int mod_virt_timer(struct vtimer_list *timer, __u64 expires); |
| 44 | extern int del_virt_timer(struct vtimer_list *timer); | 46 | extern int del_virt_timer(struct vtimer_list *timer); |
| 45 | 47 | ||
| 46 | #endif | 48 | #endif /* __KERNEL__ */ |
| 49 | |||
| 50 | #endif /* _ASM_S390_TIMER_H */ | ||
diff --git a/include/asm-s390/uaccess.h b/include/asm-s390/uaccess.h index be104f21c70a..0b7c0ca4c3d7 100644 --- a/include/asm-s390/uaccess.h +++ b/include/asm-s390/uaccess.h | |||
| @@ -61,7 +61,7 @@ | |||
| 61 | #define segment_eq(a,b) ((a).ar4 == (b).ar4) | 61 | #define segment_eq(a,b) ((a).ar4 == (b).ar4) |
| 62 | 62 | ||
| 63 | 63 | ||
| 64 | static inline int __access_ok(const void *addr, unsigned long size) | 64 | static inline int __access_ok(const void __user *addr, unsigned long size) |
| 65 | { | 65 | { |
| 66 | return 1; | 66 | return 1; |
| 67 | } | 67 | } |
| @@ -208,25 +208,25 @@ extern int __put_user_bad(void) __attribute__((noreturn)); | |||
| 208 | case 1: { \ | 208 | case 1: { \ |
| 209 | unsigned char __x; \ | 209 | unsigned char __x; \ |
| 210 | __get_user_asm(__x, ptr, __gu_err); \ | 210 | __get_user_asm(__x, ptr, __gu_err); \ |
| 211 | (x) = *(__typeof__(*(ptr)) *) &__x; \ | 211 | (x) = *(__force __typeof__(*(ptr)) *) &__x; \ |
| 212 | break; \ | 212 | break; \ |
| 213 | }; \ | 213 | }; \ |
| 214 | case 2: { \ | 214 | case 2: { \ |
| 215 | unsigned short __x; \ | 215 | unsigned short __x; \ |
| 216 | __get_user_asm(__x, ptr, __gu_err); \ | 216 | __get_user_asm(__x, ptr, __gu_err); \ |
| 217 | (x) = *(__typeof__(*(ptr)) *) &__x; \ | 217 | (x) = *(__force __typeof__(*(ptr)) *) &__x; \ |
| 218 | break; \ | 218 | break; \ |
| 219 | }; \ | 219 | }; \ |
| 220 | case 4: { \ | 220 | case 4: { \ |
| 221 | unsigned int __x; \ | 221 | unsigned int __x; \ |
| 222 | __get_user_asm(__x, ptr, __gu_err); \ | 222 | __get_user_asm(__x, ptr, __gu_err); \ |
| 223 | (x) = *(__typeof__(*(ptr)) *) &__x; \ | 223 | (x) = *(__force __typeof__(*(ptr)) *) &__x; \ |
| 224 | break; \ | 224 | break; \ |
| 225 | }; \ | 225 | }; \ |
| 226 | case 8: { \ | 226 | case 8: { \ |
| 227 | unsigned long long __x; \ | 227 | unsigned long long __x; \ |
| 228 | __get_user_asm(__x, ptr, __gu_err); \ | 228 | __get_user_asm(__x, ptr, __gu_err); \ |
| 229 | (x) = *(__typeof__(*(ptr)) *) &__x; \ | 229 | (x) = *(__force __typeof__(*(ptr)) *) &__x; \ |
| 230 | break; \ | 230 | break; \ |
| 231 | }; \ | 231 | }; \ |
| 232 | default: \ | 232 | default: \ |
diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h index 2ac64e65e336..0615d601a7c6 100644 --- a/include/asm-sparc/unistd.h +++ b/include/asm-sparc/unistd.h | |||
| @@ -315,11 +315,12 @@ | |||
| 315 | #define __NR_faccessat 296 | 315 | #define __NR_faccessat 296 |
| 316 | #define __NR_pselect6 297 | 316 | #define __NR_pselect6 297 |
| 317 | #define __NR_ppoll 298 | 317 | #define __NR_ppoll 298 |
| 318 | #define __NR_unshare 299 | ||
| 318 | 319 | ||
| 319 | /* WARNING: You MAY NOT add syscall numbers larger than 298, since | 320 | /* WARNING: You MAY NOT add syscall numbers larger than 299, since |
| 320 | * all of the syscall tables in the Sparc kernel are | 321 | * all of the syscall tables in the Sparc kernel are |
| 321 | * sized to have 298 entries (starting at zero). Therefore | 322 | * sized to have 299 entries (starting at zero). Therefore |
| 322 | * find a free slot in the 0-298 range. | 323 | * find a free slot in the 0-299 range. |
| 323 | */ | 324 | */ |
| 324 | 325 | ||
| 325 | #define _syscall0(type,name) \ | 326 | #define _syscall0(type,name) \ |
diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h index 84ac2bdb0902..c58ba8a096cf 100644 --- a/include/asm-sparc64/unistd.h +++ b/include/asm-sparc64/unistd.h | |||
| @@ -317,11 +317,12 @@ | |||
| 317 | #define __NR_faccessat 296 | 317 | #define __NR_faccessat 296 |
| 318 | #define __NR_pselect6 297 | 318 | #define __NR_pselect6 297 |
| 319 | #define __NR_ppoll 298 | 319 | #define __NR_ppoll 298 |
| 320 | #define __NR_unshare 299 | ||
| 320 | 321 | ||
| 321 | /* WARNING: You MAY NOT add syscall numbers larger than 298, since | 322 | /* WARNING: You MAY NOT add syscall numbers larger than 299, since |
| 322 | * all of the syscall tables in the Sparc kernel are | 323 | * all of the syscall tables in the Sparc kernel are |
| 323 | * sized to have 298 entries (starting at zero). Therefore | 324 | * sized to have 299 entries (starting at zero). Therefore |
| 324 | * find a free slot in the 0-298 range. | 325 | * find a free slot in the 0-299 range. |
| 325 | */ | 326 | */ |
| 326 | 327 | ||
| 327 | #define _syscall0(type,name) \ | 328 | #define _syscall0(type,name) \ |
diff --git a/include/asm-v850/bitops.h b/include/asm-v850/bitops.h index 8955d2376ac8..609b9e87222a 100644 --- a/include/asm-v850/bitops.h +++ b/include/asm-v850/bitops.h | |||
| @@ -188,7 +188,7 @@ static inline int find_next_zero_bit(const void *addr, int size, int offset) | |||
| 188 | tmp = *p; | 188 | tmp = *p; |
| 189 | 189 | ||
| 190 | found_first: | 190 | found_first: |
| 191 | tmp |= ~0UL >> size; | 191 | tmp |= ~0UL << size; |
| 192 | found_middle: | 192 | found_middle: |
| 193 | return result + ffz (tmp); | 193 | return result + ffz (tmp); |
| 194 | } | 194 | } |
diff --git a/include/asm-x86_64/apic.h b/include/asm-x86_64/apic.h index 4f6a4dc455bb..bdbd8935612a 100644 --- a/include/asm-x86_64/apic.h +++ b/include/asm-x86_64/apic.h | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #define APIC_DEBUG 2 | 17 | #define APIC_DEBUG 2 |
| 18 | 18 | ||
| 19 | extern int apic_verbosity; | 19 | extern int apic_verbosity; |
| 20 | extern int apic_runs_main_timer; | ||
| 20 | 21 | ||
| 21 | /* | 22 | /* |
| 22 | * Define the default level of output to be very little | 23 | * Define the default level of output to be very little |
diff --git a/include/asm-x86_64/cpufeature.h b/include/asm-x86_64/cpufeature.h index 41c0ac8559be..76bb6193ae91 100644 --- a/include/asm-x86_64/cpufeature.h +++ b/include/asm-x86_64/cpufeature.h | |||
| @@ -61,7 +61,7 @@ | |||
| 61 | #define X86_FEATURE_K6_MTRR (3*32+ 1) /* AMD K6 nonstandard MTRRs */ | 61 | #define X86_FEATURE_K6_MTRR (3*32+ 1) /* AMD K6 nonstandard MTRRs */ |
| 62 | #define X86_FEATURE_CYRIX_ARR (3*32+ 2) /* Cyrix ARRs (= MTRRs) */ | 62 | #define X86_FEATURE_CYRIX_ARR (3*32+ 2) /* Cyrix ARRs (= MTRRs) */ |
| 63 | #define X86_FEATURE_CENTAUR_MCR (3*32+ 3) /* Centaur MCRs (= MTRRs) */ | 63 | #define X86_FEATURE_CENTAUR_MCR (3*32+ 3) /* Centaur MCRs (= MTRRs) */ |
| 64 | /* 4 free */ | 64 | #define X86_FEATURE_REP_GOOD (3*32+ 4) /* rep microcode works well on this CPU */ |
| 65 | #define X86_FEATURE_CONSTANT_TSC (3*32+5) /* TSC runs at constant rate */ | 65 | #define X86_FEATURE_CONSTANT_TSC (3*32+5) /* TSC runs at constant rate */ |
| 66 | #define X86_FEATURE_SYNC_RDTSC (3*32+6) /* RDTSC syncs CPU core */ | 66 | #define X86_FEATURE_SYNC_RDTSC (3*32+6) /* RDTSC syncs CPU core */ |
| 67 | 67 | ||
diff --git a/include/asm-x86_64/hardirq.h b/include/asm-x86_64/hardirq.h index 8661b476fb40..8689951e3503 100644 --- a/include/asm-x86_64/hardirq.h +++ b/include/asm-x86_64/hardirq.h | |||
| @@ -16,23 +16,6 @@ | |||
| 16 | #define set_softirq_pending(x) write_pda(__softirq_pending, (x)) | 16 | #define set_softirq_pending(x) write_pda(__softirq_pending, (x)) |
| 17 | #define or_softirq_pending(x) or_pda(__softirq_pending, (x)) | 17 | #define or_softirq_pending(x) or_pda(__softirq_pending, (x)) |
| 18 | 18 | ||
| 19 | /* | 19 | extern void ack_bad_irq(unsigned int irq); |
| 20 | * 'what should we do if we get a hw irq event on an illegal vector'. | 20 | |
| 21 | * each architecture has to answer this themselves. | ||
| 22 | */ | ||
| 23 | static inline void ack_bad_irq(unsigned int irq) | ||
| 24 | { | ||
| 25 | printk("unexpected IRQ trap at vector %02x\n", irq); | ||
| 26 | #ifdef CONFIG_X86_LOCAL_APIC | ||
| 27 | /* | ||
| 28 | * Currently unexpected vectors happen only on SMP and APIC. | ||
| 29 | * We _must_ ack these because every local APIC has only N | ||
| 30 | * irq slots per priority level, and a 'hanging, unacked' IRQ | ||
| 31 | * holds up an irq slot - in excessive cases (when multiple | ||
| 32 | * unexpected vectors occur) that might lock up the APIC | ||
| 33 | * completely. | ||
| 34 | */ | ||
| 35 | ack_APIC_irq(); | ||
| 36 | #endif | ||
| 37 | } | ||
| 38 | #endif /* __ASM_HARDIRQ_H */ | 21 | #endif /* __ASM_HARDIRQ_H */ |
diff --git a/include/asm-x86_64/ia32_unistd.h b/include/asm-x86_64/ia32_unistd.h index 9afc0c7d3661..20468983d453 100644 --- a/include/asm-x86_64/ia32_unistd.h +++ b/include/asm-x86_64/ia32_unistd.h | |||
| @@ -313,7 +313,10 @@ | |||
| 313 | #define __NR_ia32_readlinkat 305 | 313 | #define __NR_ia32_readlinkat 305 |
| 314 | #define __NR_ia32_fchmodat 306 | 314 | #define __NR_ia32_fchmodat 306 |
| 315 | #define __NR_ia32_faccessat 307 | 315 | #define __NR_ia32_faccessat 307 |
| 316 | #define __NR_ia32_pselect6 308 | ||
| 317 | #define __NR_ia32_ppoll 309 | ||
| 318 | #define __NR_ia32_unshare 310 | ||
| 316 | 319 | ||
| 317 | #define IA32_NR_syscalls 308 /* must be > than biggest syscall! */ | 320 | #define IA32_NR_syscalls 315 /* must be > than biggest syscall! */ |
| 318 | 321 | ||
| 319 | #endif /* _ASM_X86_64_IA32_UNISTD_H_ */ | 322 | #endif /* _ASM_X86_64_IA32_UNISTD_H_ */ |
diff --git a/include/asm-x86_64/kexec.h b/include/asm-x86_64/kexec.h index ae28cd44bcd3..c564bae03433 100644 --- a/include/asm-x86_64/kexec.h +++ b/include/asm-x86_64/kexec.h | |||
| @@ -1,8 +1,9 @@ | |||
| 1 | #ifndef _X86_64_KEXEC_H | 1 | #ifndef _X86_64_KEXEC_H |
| 2 | #define _X86_64_KEXEC_H | 2 | #define _X86_64_KEXEC_H |
| 3 | 3 | ||
| 4 | #include <linux/string.h> | ||
| 5 | |||
| 4 | #include <asm/page.h> | 6 | #include <asm/page.h> |
| 5 | #include <asm/proto.h> | ||
| 6 | #include <asm/ptrace.h> | 7 | #include <asm/ptrace.h> |
| 7 | 8 | ||
| 8 | /* | 9 | /* |
diff --git a/include/asm-x86_64/numa.h b/include/asm-x86_64/numa.h index 34e434ce3268..dffe276ca2df 100644 --- a/include/asm-x86_64/numa.h +++ b/include/asm-x86_64/numa.h | |||
| @@ -22,8 +22,15 @@ extern void numa_set_node(int cpu, int node); | |||
| 22 | extern unsigned char apicid_to_node[256]; | 22 | extern unsigned char apicid_to_node[256]; |
| 23 | #ifdef CONFIG_NUMA | 23 | #ifdef CONFIG_NUMA |
| 24 | extern void __init init_cpu_to_node(void); | 24 | extern void __init init_cpu_to_node(void); |
| 25 | |||
| 26 | static inline void clear_node_cpumask(int cpu) | ||
| 27 | { | ||
| 28 | clear_bit(cpu, &node_to_cpumask[cpu_to_node(cpu)]); | ||
| 29 | } | ||
| 30 | |||
| 25 | #else | 31 | #else |
| 26 | #define init_cpu_to_node() do {} while (0) | 32 | #define init_cpu_to_node() do {} while (0) |
| 33 | #define clear_node_cpumask(cpu) do {} while (0) | ||
| 27 | #endif | 34 | #endif |
| 28 | 35 | ||
| 29 | #define NUMA_NO_NODE 0xff | 36 | #define NUMA_NO_NODE 0xff |
diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h index 115e496c6139..c99832e7bf3f 100644 --- a/include/asm-x86_64/proto.h +++ b/include/asm-x86_64/proto.h | |||
| @@ -41,10 +41,18 @@ extern void iommu_hole_init(void); | |||
| 41 | 41 | ||
| 42 | extern void time_init_gtod(void); | 42 | extern void time_init_gtod(void); |
| 43 | extern int pmtimer_mark_offset(void); | 43 | extern int pmtimer_mark_offset(void); |
| 44 | extern void pmtimer_resume(void); | ||
| 45 | extern void pmtimer_wait(unsigned); | ||
| 44 | extern unsigned int do_gettimeoffset_pm(void); | 46 | extern unsigned int do_gettimeoffset_pm(void); |
| 47 | #ifdef CONFIG_X86_PM_TIMER | ||
| 45 | extern u32 pmtmr_ioport; | 48 | extern u32 pmtmr_ioport; |
| 49 | #else | ||
| 50 | #define pmtmr_ioport 0 | ||
| 51 | #endif | ||
| 46 | extern unsigned long long monotonic_base; | 52 | extern unsigned long long monotonic_base; |
| 47 | extern int sysctl_vsyscall; | 53 | extern int sysctl_vsyscall; |
| 54 | extern int nohpet; | ||
| 55 | extern unsigned long vxtime_hz; | ||
| 48 | 56 | ||
| 49 | extern void do_softirq_thunk(void); | 57 | extern void do_softirq_thunk(void); |
| 50 | 58 | ||
| @@ -65,6 +73,9 @@ extern void free_bootmem_generic(unsigned long phys, unsigned len); | |||
| 65 | 73 | ||
| 66 | extern void load_gs_index(unsigned gs); | 74 | extern void load_gs_index(unsigned gs); |
| 67 | 75 | ||
| 76 | extern void stop_timer_interrupt(void); | ||
| 77 | extern void main_timer_handler(struct pt_regs *regs); | ||
| 78 | |||
| 68 | extern unsigned long end_pfn_map; | 79 | extern unsigned long end_pfn_map; |
| 69 | 80 | ||
| 70 | extern void show_trace(unsigned long * rsp); | 81 | extern void show_trace(unsigned long * rsp); |
diff --git a/include/asm-x86_64/system.h b/include/asm-x86_64/system.h index a73f0c789d8b..b7f66034ae7a 100644 --- a/include/asm-x86_64/system.h +++ b/include/asm-x86_64/system.h | |||
| @@ -327,7 +327,7 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, | |||
| 327 | #define wmb() asm volatile("" ::: "memory") | 327 | #define wmb() asm volatile("" ::: "memory") |
| 328 | #endif | 328 | #endif |
| 329 | #define read_barrier_depends() do {} while(0) | 329 | #define read_barrier_depends() do {} while(0) |
| 330 | #define set_mb(var, value) do { xchg(&var, value); } while (0) | 330 | #define set_mb(var, value) do { (void) xchg(&var, value); } while (0) |
| 331 | #define set_wmb(var, value) do { var = value; wmb(); } while (0) | 331 | #define set_wmb(var, value) do { var = value; wmb(); } while (0) |
| 332 | 332 | ||
| 333 | #define warn_if_not_ulong(x) do { unsigned long foo; (void) (&(x) == &foo); } while (0) | 333 | #define warn_if_not_ulong(x) do { unsigned long foo; (void) (&(x) == &foo); } while (0) |
diff --git a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h index 2fa7f27381b4..c642f5d9882d 100644 --- a/include/asm-x86_64/topology.h +++ b/include/asm-x86_64/topology.h | |||
| @@ -57,6 +57,15 @@ extern int __node_distance(int, int); | |||
| 57 | 57 | ||
| 58 | #endif | 58 | #endif |
| 59 | 59 | ||
| 60 | #ifdef CONFIG_SMP | ||
| 61 | #define topology_physical_package_id(cpu) \ | ||
| 62 | (phys_proc_id[cpu] == BAD_APICID ? -1 : phys_proc_id[cpu]) | ||
| 63 | #define topology_core_id(cpu) \ | ||
| 64 | (cpu_core_id[cpu] == BAD_APICID ? 0 : cpu_core_id[cpu]) | ||
| 65 | #define topology_core_siblings(cpu) (cpu_core_map[cpu]) | ||
| 66 | #define topology_thread_siblings(cpu) (cpu_sibling_map[cpu]) | ||
| 67 | #endif | ||
| 68 | |||
| 60 | #include <asm-generic/topology.h> | 69 | #include <asm-generic/topology.h> |
| 61 | 70 | ||
| 62 | #endif | 71 | #endif |
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h index 436d099b5b6b..da0341c57949 100644 --- a/include/asm-x86_64/unistd.h +++ b/include/asm-x86_64/unistd.h | |||
| @@ -599,8 +599,14 @@ __SYSCALL(__NR_readlinkat, sys_readlinkat) | |||
| 599 | __SYSCALL(__NR_fchmodat, sys_fchmodat) | 599 | __SYSCALL(__NR_fchmodat, sys_fchmodat) |
| 600 | #define __NR_faccessat 269 | 600 | #define __NR_faccessat 269 |
| 601 | __SYSCALL(__NR_faccessat, sys_faccessat) | 601 | __SYSCALL(__NR_faccessat, sys_faccessat) |
| 602 | 602 | #define __NR_pselect6 270 | |
| 603 | #define __NR_syscall_max __NR_faccessat | 603 | __SYSCALL(__NR_pselect6, sys_ni_syscall) /* for now */ |
| 604 | #define __NR_ppoll 271 | ||
| 605 | __SYSCALL(__NR_ppoll, sys_ni_syscall) /* for now */ | ||
| 606 | #define __NR_unshare 272 | ||
| 607 | __SYSCALL(__NR_unshare, sys_unshare) | ||
| 608 | |||
| 609 | #define __NR_syscall_max __NR_unshare | ||
| 604 | 610 | ||
| 605 | #ifndef __NO_STUBS | 611 | #ifndef __NO_STUBS |
| 606 | 612 | ||
diff --git a/include/linux/bitops.h b/include/linux/bitops.h index 6a2a19f14bb2..208650b1ad3a 100644 --- a/include/linux/bitops.h +++ b/include/linux/bitops.h | |||
| @@ -81,7 +81,7 @@ static inline int generic_fls64(__u64 x) | |||
| 81 | { | 81 | { |
| 82 | __u32 h = x >> 32; | 82 | __u32 h = x >> 32; |
| 83 | if (h) | 83 | if (h) |
| 84 | return fls(x) + 32; | 84 | return fls(h) + 32; |
| 85 | return fls(x); | 85 | return fls(x); |
| 86 | } | 86 | } |
| 87 | 87 | ||
diff --git a/include/linux/configfs.h b/include/linux/configfs.h index acffb8c9073a..a7f015027535 100644 --- a/include/linux/configfs.h +++ b/include/linux/configfs.h | |||
| @@ -126,7 +126,7 @@ extern struct config_item *config_group_find_obj(struct config_group *, const ch | |||
| 126 | 126 | ||
| 127 | 127 | ||
| 128 | struct configfs_attribute { | 128 | struct configfs_attribute { |
| 129 | char *ca_name; | 129 | const char *ca_name; |
| 130 | struct module *ca_owner; | 130 | struct module *ca_owner; |
| 131 | mode_t ca_mode; | 131 | mode_t ca_mode; |
| 132 | }; | 132 | }; |
diff --git a/include/linux/cpumask.h b/include/linux/cpumask.h index 13e9f4a3ab26..20b446f26ecd 100644 --- a/include/linux/cpumask.h +++ b/include/linux/cpumask.h | |||
| @@ -84,7 +84,6 @@ | |||
| 84 | #include <linux/kernel.h> | 84 | #include <linux/kernel.h> |
| 85 | #include <linux/threads.h> | 85 | #include <linux/threads.h> |
| 86 | #include <linux/bitmap.h> | 86 | #include <linux/bitmap.h> |
| 87 | #include <asm/bug.h> | ||
| 88 | 87 | ||
| 89 | typedef struct { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t; | 88 | typedef struct { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t; |
| 90 | extern cpumask_t _unused_cpumask_arg_; | 89 | extern cpumask_t _unused_cpumask_arg_; |
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index a3ed5e059d47..4361f3789975 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h | |||
| @@ -8,7 +8,6 @@ | |||
| 8 | #include <linux/spinlock.h> | 8 | #include <linux/spinlock.h> |
| 9 | #include <linux/cache.h> | 9 | #include <linux/cache.h> |
| 10 | #include <linux/rcupdate.h> | 10 | #include <linux/rcupdate.h> |
| 11 | #include <asm/bug.h> | ||
| 12 | 11 | ||
| 13 | struct nameidata; | 12 | struct nameidata; |
| 14 | struct vfsmount; | 13 | struct vfsmount; |
| @@ -108,7 +107,9 @@ struct dentry { | |||
| 108 | struct dentry_operations *d_op; | 107 | struct dentry_operations *d_op; |
| 109 | struct super_block *d_sb; /* The root of the dentry tree */ | 108 | struct super_block *d_sb; /* The root of the dentry tree */ |
| 110 | void *d_fsdata; /* fs-specific data */ | 109 | void *d_fsdata; /* fs-specific data */ |
| 110 | #ifdef CONFIG_PROFILING | ||
| 111 | struct dcookie_struct *d_cookie; /* cookie, if any */ | 111 | struct dcookie_struct *d_cookie; /* cookie, if any */ |
| 112 | #endif | ||
| 112 | int d_mounted; | 113 | int d_mounted; |
| 113 | unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /* small names */ | 114 | unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /* small names */ |
| 114 | }; | 115 | }; |
diff --git a/include/linux/dvb/video.h b/include/linux/dvb/video.h index b1999bfeaa56..b81e58b2ebf8 100644 --- a/include/linux/dvb/video.h +++ b/include/linux/dvb/video.h | |||
| @@ -135,7 +135,7 @@ typedef struct video_spu { | |||
| 135 | 135 | ||
| 136 | typedef struct video_spu_palette { /* SPU Palette information */ | 136 | typedef struct video_spu_palette { /* SPU Palette information */ |
| 137 | int length; | 137 | int length; |
| 138 | uint8_t *palette; | 138 | uint8_t __user *palette; |
| 139 | } video_spu_palette_t; | 139 | } video_spu_palette_t; |
| 140 | 140 | ||
| 141 | 141 | ||
diff --git a/include/linux/elevator.h b/include/linux/elevator.h index 23fe746a1d51..18cf1f3e1184 100644 --- a/include/linux/elevator.h +++ b/include/linux/elevator.h | |||
| @@ -82,6 +82,7 @@ struct elevator_queue | |||
| 82 | extern void elv_dispatch_sort(request_queue_t *, struct request *); | 82 | extern void elv_dispatch_sort(request_queue_t *, struct request *); |
| 83 | extern void elv_add_request(request_queue_t *, struct request *, int, int); | 83 | extern void elv_add_request(request_queue_t *, struct request *, int, int); |
| 84 | extern void __elv_add_request(request_queue_t *, struct request *, int, int); | 84 | extern void __elv_add_request(request_queue_t *, struct request *, int, int); |
| 85 | extern void elv_insert(request_queue_t *, struct request *, int); | ||
| 85 | extern int elv_merge(request_queue_t *, struct request **, struct bio *); | 86 | extern int elv_merge(request_queue_t *, struct request **, struct bio *); |
| 86 | extern void elv_merge_requests(request_queue_t *, struct request *, | 87 | extern void elv_merge_requests(request_queue_t *, struct request *, |
| 87 | struct request *); | 88 | struct request *); |
diff --git a/include/linux/elfcore.h b/include/linux/elfcore.h index dbd7bb4a33b7..0cf0bea010fe 100644 --- a/include/linux/elfcore.h +++ b/include/linux/elfcore.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include <linux/signal.h> | 5 | #include <linux/signal.h> |
| 6 | #include <linux/time.h> | 6 | #include <linux/time.h> |
| 7 | #include <linux/user.h> | 7 | #include <linux/user.h> |
| 8 | #include <linux/ptrace.h> | ||
| 8 | 9 | ||
| 9 | struct elf_siginfo | 10 | struct elf_siginfo |
| 10 | { | 11 | { |
diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 7863a59bd598..63f1d63cc1d8 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h | |||
| @@ -100,6 +100,9 @@ extern s32 i2c_smbus_write_block_data(struct i2c_client * client, | |||
| 100 | /* Returns the number of read bytes */ | 100 | /* Returns the number of read bytes */ |
| 101 | extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client, | 101 | extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client, |
| 102 | u8 command, u8 *values); | 102 | u8 command, u8 *values); |
| 103 | extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client, | ||
| 104 | u8 command, u8 length, | ||
| 105 | u8 *values); | ||
| 103 | 106 | ||
| 104 | /* | 107 | /* |
| 105 | * A driver is capable of handling one or more physical devices present on | 108 | * A driver is capable of handling one or more physical devices present on |
diff --git a/include/linux/i2o.h b/include/linux/i2o.h index 9ba806796667..5a9d8c599171 100644 --- a/include/linux/i2o.h +++ b/include/linux/i2o.h | |||
| @@ -1115,9 +1115,11 @@ static inline struct i2o_message *i2o_msg_get(struct i2o_controller *c) | |||
| 1115 | return ERR_PTR(-ENOMEM); | 1115 | return ERR_PTR(-ENOMEM); |
| 1116 | 1116 | ||
| 1117 | mmsg->mfa = readl(c->in_port); | 1117 | mmsg->mfa = readl(c->in_port); |
| 1118 | if (mmsg->mfa == I2O_QUEUE_EMPTY) { | 1118 | if (unlikely(mmsg->mfa >= c->in_queue.len)) { |
| 1119 | mempool_free(mmsg, c->in_msg.mempool); | 1119 | mempool_free(mmsg, c->in_msg.mempool); |
| 1120 | return ERR_PTR(-EBUSY); | 1120 | if(mmsg->mfa == I2O_QUEUE_EMPTY) |
| 1121 | return ERR_PTR(-EBUSY); | ||
| 1122 | return ERR_PTR(-EFAULT); | ||
| 1121 | } | 1123 | } |
| 1122 | 1124 | ||
| 1123 | return &mmsg->msg; | 1125 | return &mmsg->msg; |
diff --git a/include/linux/ide.h b/include/linux/ide.h index 110b3cfac021..a7fc4cc79b23 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
| @@ -582,7 +582,6 @@ typedef struct ide_drive_s { | |||
| 582 | unsigned noprobe : 1; /* from: hdx=noprobe */ | 582 | unsigned noprobe : 1; /* from: hdx=noprobe */ |
| 583 | unsigned removable : 1; /* 1 if need to do check_media_change */ | 583 | unsigned removable : 1; /* 1 if need to do check_media_change */ |
| 584 | unsigned attach : 1; /* needed for removable devices */ | 584 | unsigned attach : 1; /* needed for removable devices */ |
| 585 | unsigned is_flash : 1; /* 1 if probed as flash */ | ||
| 586 | unsigned forced_geom : 1; /* 1 if hdx=c,h,s was given at boot */ | 585 | unsigned forced_geom : 1; /* 1 if hdx=c,h,s was given at boot */ |
| 587 | unsigned no_unmask : 1; /* disallow setting unmask bit */ | 586 | unsigned no_unmask : 1; /* disallow setting unmask bit */ |
| 588 | unsigned no_io_32bit : 1; /* disallow enabling 32bit I/O */ | 587 | unsigned no_io_32bit : 1; /* disallow enabling 32bit I/O */ |
| @@ -1006,7 +1005,6 @@ extern ide_hwif_t ide_hwifs[]; /* master data repository */ | |||
| 1006 | extern int noautodma; | 1005 | extern int noautodma; |
| 1007 | 1006 | ||
| 1008 | extern int ide_end_request (ide_drive_t *drive, int uptodate, int nrsecs); | 1007 | extern int ide_end_request (ide_drive_t *drive, int uptodate, int nrsecs); |
| 1009 | extern int __ide_end_request (ide_drive_t *drive, struct request *rq, int uptodate, int nrsecs); | ||
| 1010 | 1008 | ||
| 1011 | /* | 1009 | /* |
| 1012 | * This is used on exit from the driver to designate the next irq handler | 1010 | * This is used on exit from the driver to designate the next irq handler |
diff --git a/include/linux/ioc3.h b/include/linux/ioc3.h index e7906a72a4f1..da7c09e4ede6 100644 --- a/include/linux/ioc3.h +++ b/include/linux/ioc3.h | |||
| @@ -27,7 +27,7 @@ struct ioc3_driver_data { | |||
| 27 | int id; /* IOC3 sequence number */ | 27 | int id; /* IOC3 sequence number */ |
| 28 | /* PCI mapping */ | 28 | /* PCI mapping */ |
| 29 | unsigned long pma; /* physical address */ | 29 | unsigned long pma; /* physical address */ |
| 30 | struct __iomem ioc3 *vma; /* pointer to registers */ | 30 | struct ioc3 __iomem *vma; /* pointer to registers */ |
| 31 | struct pci_dev *pdev; /* PCI device */ | 31 | struct pci_dev *pdev; /* PCI device */ |
| 32 | /* IRQ stuff */ | 32 | /* IRQ stuff */ |
| 33 | int dual_irq; /* set if separate IRQs are used */ | 33 | int dual_irq; /* set if separate IRQs are used */ |
diff --git a/include/linux/jbd.h b/include/linux/jbd.h index 558cb4c26ec9..0fe4aa891ddc 100644 --- a/include/linux/jbd.h +++ b/include/linux/jbd.h | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #define jfs_debug jbd_debug | 23 | #define jfs_debug jbd_debug |
| 24 | #else | 24 | #else |
| 25 | 25 | ||
| 26 | #include <linux/types.h> | ||
| 26 | #include <linux/buffer_head.h> | 27 | #include <linux/buffer_head.h> |
| 27 | #include <linux/journal-head.h> | 28 | #include <linux/journal-head.h> |
| 28 | #include <linux/stddef.h> | 29 | #include <linux/stddef.h> |
| @@ -238,7 +239,6 @@ typedef struct journal_superblock_s | |||
| 238 | 239 | ||
| 239 | #include <linux/fs.h> | 240 | #include <linux/fs.h> |
| 240 | #include <linux/sched.h> | 241 | #include <linux/sched.h> |
| 241 | #include <asm/bug.h> | ||
| 242 | 242 | ||
| 243 | #define JBD_ASSERTIONS | 243 | #define JBD_ASSERTIONS |
| 244 | #ifdef JBD_ASSERTIONS | 244 | #ifdef JBD_ASSERTIONS |
| @@ -618,6 +618,7 @@ struct transaction_s | |||
| 618 | * @j_wbuf: array of buffer_heads for journal_commit_transaction | 618 | * @j_wbuf: array of buffer_heads for journal_commit_transaction |
| 619 | * @j_wbufsize: maximum number of buffer_heads allowed in j_wbuf, the | 619 | * @j_wbufsize: maximum number of buffer_heads allowed in j_wbuf, the |
| 620 | * number that will fit in j_blocksize | 620 | * number that will fit in j_blocksize |
| 621 | * @j_last_sync_writer: most recent pid which did a synchronous write | ||
| 621 | * @j_private: An opaque pointer to fs-private information. | 622 | * @j_private: An opaque pointer to fs-private information. |
| 622 | */ | 623 | */ |
| 623 | 624 | ||
| @@ -807,6 +808,8 @@ struct journal_s | |||
| 807 | struct buffer_head **j_wbuf; | 808 | struct buffer_head **j_wbuf; |
| 808 | int j_wbufsize; | 809 | int j_wbufsize; |
| 809 | 810 | ||
| 811 | pid_t j_last_sync_writer; | ||
| 812 | |||
| 810 | /* | 813 | /* |
| 811 | * An opaque pointer to fs-private information. ext3 puts its | 814 | * An opaque pointer to fs-private information. ext3 puts its |
| 812 | * superblock pointer here | 815 | * superblock pointer here |
diff --git a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h index 45f625d7d0b2..3aed37314ab8 100644 --- a/include/linux/kbd_kern.h +++ b/include/linux/kbd_kern.h | |||
| @@ -151,6 +151,11 @@ extern unsigned int keymap_count; | |||
| 151 | 151 | ||
| 152 | static inline void con_schedule_flip(struct tty_struct *t) | 152 | static inline void con_schedule_flip(struct tty_struct *t) |
| 153 | { | 153 | { |
| 154 | unsigned long flags; | ||
| 155 | spin_lock_irqsave(&t->buf.lock, flags); | ||
| 156 | if (t->buf.tail != NULL) | ||
| 157 | t->buf.tail->active = 0; | ||
| 158 | spin_unlock_irqrestore(&t->buf.lock, flags); | ||
| 154 | schedule_work(&t->buf.work); | 159 | schedule_work(&t->buf.work); |
| 155 | } | 160 | } |
| 156 | 161 | ||
diff --git a/include/linux/list.h b/include/linux/list.h index 945daa1f13dd..47208bd99f9e 100644 --- a/include/linux/list.h +++ b/include/linux/list.h | |||
| @@ -34,9 +34,11 @@ struct list_head { | |||
| 34 | #define LIST_HEAD(name) \ | 34 | #define LIST_HEAD(name) \ |
| 35 | struct list_head name = LIST_HEAD_INIT(name) | 35 | struct list_head name = LIST_HEAD_INIT(name) |
| 36 | 36 | ||
| 37 | #define INIT_LIST_HEAD(ptr) do { \ | 37 | static inline void INIT_LIST_HEAD(struct list_head *list) |
| 38 | (ptr)->next = (ptr); (ptr)->prev = (ptr); \ | 38 | { |
| 39 | } while (0) | 39 | list->next = list; |
| 40 | list->prev = list; | ||
| 41 | } | ||
| 40 | 42 | ||
| 41 | /* | 43 | /* |
| 42 | * Insert a new entry between two known consecutive entries. | 44 | * Insert a new entry between two known consecutive entries. |
| @@ -534,7 +536,11 @@ struct hlist_node { | |||
| 534 | #define HLIST_HEAD_INIT { .first = NULL } | 536 | #define HLIST_HEAD_INIT { .first = NULL } |
| 535 | #define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } | 537 | #define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } |
| 536 | #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) | 538 | #define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) |
| 537 | #define INIT_HLIST_NODE(ptr) ((ptr)->next = NULL, (ptr)->pprev = NULL) | 539 | static inline void INIT_HLIST_NODE(struct hlist_node *h) |
| 540 | { | ||
| 541 | h->next = NULL; | ||
| 542 | h->pprev = NULL; | ||
| 543 | } | ||
| 538 | 544 | ||
| 539 | static inline int hlist_unhashed(const struct hlist_node *h) | 545 | static inline int hlist_unhashed(const struct hlist_node *h) |
| 540 | { | 546 | { |
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index 95c8fea293ba..920766cea79c 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h | |||
| @@ -84,6 +84,7 @@ struct nlm_rqst { | |||
| 84 | struct nlm_args a_args; /* arguments */ | 84 | struct nlm_args a_args; /* arguments */ |
| 85 | struct nlm_res a_res; /* result */ | 85 | struct nlm_res a_res; /* result */ |
| 86 | struct nlm_wait * a_block; | 86 | struct nlm_wait * a_block; |
| 87 | unsigned int a_retries; /* Retry count */ | ||
| 87 | char a_owner[NLMCLNT_OHSIZE]; | 88 | char a_owner[NLMCLNT_OHSIZE]; |
| 88 | }; | 89 | }; |
| 89 | 90 | ||
| @@ -148,7 +149,6 @@ struct nlm_rqst * nlmclnt_alloc_call(void); | |||
| 148 | int nlmclnt_prepare_block(struct nlm_rqst *req, struct nlm_host *host, struct file_lock *fl); | 149 | int nlmclnt_prepare_block(struct nlm_rqst *req, struct nlm_host *host, struct file_lock *fl); |
| 149 | void nlmclnt_finish_block(struct nlm_rqst *req); | 150 | void nlmclnt_finish_block(struct nlm_rqst *req); |
| 150 | long nlmclnt_block(struct nlm_rqst *req, long timeout); | 151 | long nlmclnt_block(struct nlm_rqst *req, long timeout); |
| 151 | int nlmclnt_cancel(struct nlm_host *, struct file_lock *); | ||
| 152 | u32 nlmclnt_grant(struct nlm_lock *); | 152 | u32 nlmclnt_grant(struct nlm_lock *); |
| 153 | void nlmclnt_recovery(struct nlm_host *, u32); | 153 | void nlmclnt_recovery(struct nlm_host *, u32); |
| 154 | int nlmclnt_reclaim(struct nlm_host *, struct file_lock *); | 154 | int nlmclnt_reclaim(struct nlm_host *, struct file_lock *); |
diff --git a/include/linux/mm.h b/include/linux/mm.h index 85854b867463..75e9f0724997 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
| @@ -303,7 +303,7 @@ struct page { | |||
| 303 | */ | 303 | */ |
| 304 | #define put_page_testzero(p) \ | 304 | #define put_page_testzero(p) \ |
| 305 | ({ \ | 305 | ({ \ |
| 306 | BUG_ON(page_count(p) == 0); \ | 306 | BUG_ON(atomic_read(&(p)->_count) == -1);\ |
| 307 | atomic_add_negative(-1, &(p)->_count); \ | 307 | atomic_add_negative(-1, &(p)->_count); \ |
| 308 | }) | 308 | }) |
| 309 | 309 | ||
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index ccd3e13de1e8..f38872abc126 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h | |||
| @@ -21,24 +21,35 @@ struct mmc_command { | |||
| 21 | u32 arg; | 21 | u32 arg; |
| 22 | u32 resp[4]; | 22 | u32 resp[4]; |
| 23 | unsigned int flags; /* expected response type */ | 23 | unsigned int flags; /* expected response type */ |
| 24 | #define MMC_RSP_NONE (0 << 0) | 24 | #define MMC_RSP_PRESENT (1 << 0) |
| 25 | #define MMC_RSP_SHORT (1 << 0) | 25 | #define MMC_RSP_136 (1 << 1) /* 136 bit response */ |
| 26 | #define MMC_RSP_LONG (2 << 0) | 26 | #define MMC_RSP_CRC (1 << 2) /* expect valid crc */ |
| 27 | #define MMC_RSP_MASK (3 << 0) | 27 | #define MMC_RSP_BUSY (1 << 3) /* card may send busy */ |
| 28 | #define MMC_RSP_CRC (1 << 3) /* expect valid crc */ | 28 | #define MMC_RSP_OPCODE (1 << 4) /* response contains opcode */ |
| 29 | #define MMC_RSP_BUSY (1 << 4) /* card may send busy */ | 29 | #define MMC_CMD_MASK (3 << 5) /* command type */ |
| 30 | #define MMC_RSP_OPCODE (1 << 5) /* response contains opcode */ | 30 | #define MMC_CMD_AC (0 << 5) |
| 31 | #define MMC_CMD_ADTC (1 << 5) | ||
| 32 | #define MMC_CMD_BC (2 << 5) | ||
| 33 | #define MMC_CMD_BCR (3 << 5) | ||
| 31 | 34 | ||
| 32 | /* | 35 | /* |
| 33 | * These are the response types, and correspond to valid bit | 36 | * These are the response types, and correspond to valid bit |
| 34 | * patterns of the above flags. One additional valid pattern | 37 | * patterns of the above flags. One additional valid pattern |
| 35 | * is all zeros, which means we don't expect a response. | 38 | * is all zeros, which means we don't expect a response. |
| 36 | */ | 39 | */ |
| 37 | #define MMC_RSP_R1 (MMC_RSP_SHORT|MMC_RSP_CRC|MMC_RSP_OPCODE) | 40 | #define MMC_RSP_NONE (0) |
| 38 | #define MMC_RSP_R1B (MMC_RSP_SHORT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY) | 41 | #define MMC_RSP_R1 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) |
| 39 | #define MMC_RSP_R2 (MMC_RSP_LONG|MMC_RSP_CRC) | 42 | #define MMC_RSP_R1B (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY) |
| 40 | #define MMC_RSP_R3 (MMC_RSP_SHORT) | 43 | #define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC) |
| 41 | #define MMC_RSP_R6 (MMC_RSP_SHORT|MMC_RSP_CRC) | 44 | #define MMC_RSP_R3 (MMC_RSP_PRESENT) |
| 45 | #define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC) | ||
| 46 | |||
| 47 | #define mmc_resp_type(cmd) ((cmd)->flags & (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE)) | ||
| 48 | |||
| 49 | /* | ||
| 50 | * These are the command types. | ||
| 51 | */ | ||
| 52 | #define mmc_cmd_type(cmd) ((cmd)->flags & MMC_CMD_TYPE) | ||
| 42 | 53 | ||
| 43 | unsigned int retries; /* max number of retries */ | 54 | unsigned int retries; /* max number of retries */ |
| 44 | unsigned int error; /* command error */ | 55 | unsigned int error; /* command error */ |
diff --git a/include/linux/mmc/protocol.h b/include/linux/mmc/protocol.h index a14dc306545b..81c3f77f652c 100644 --- a/include/linux/mmc/protocol.h +++ b/include/linux/mmc/protocol.h | |||
| @@ -79,7 +79,7 @@ | |||
| 79 | /* SD commands type argument response */ | 79 | /* SD commands type argument response */ |
| 80 | /* class 8 */ | 80 | /* class 8 */ |
| 81 | /* This is basically the same command as for MMC with some quirks. */ | 81 | /* This is basically the same command as for MMC with some quirks. */ |
| 82 | #define SD_SEND_RELATIVE_ADDR 3 /* ac R6 */ | 82 | #define SD_SEND_RELATIVE_ADDR 3 /* bcr R6 */ |
| 83 | 83 | ||
| 84 | /* Application commands */ | 84 | /* Application commands */ |
| 85 | #define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */ | 85 | #define SD_APP_SET_BUS_WIDTH 6 /* ac [1:0] bus width R1 */ |
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h index fedfbc8a287f..7dfd6e1fcde7 100644 --- a/include/linux/mtd/map.h +++ b/include/linux/mtd/map.h | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | #include <asm/unaligned.h> | 15 | #include <asm/unaligned.h> |
| 16 | #include <asm/system.h> | 16 | #include <asm/system.h> |
| 17 | #include <asm/io.h> | 17 | #include <asm/io.h> |
| 18 | #include <asm/bug.h> | ||
| 19 | 18 | ||
| 20 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_1 | 19 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_1 |
| 21 | #define map_bankwidth(map) 1 | 20 | #define map_bankwidth(map) 1 |
diff --git a/include/linux/namespace.h b/include/linux/namespace.h index 6731977c4c13..3abc8e3b4879 100644 --- a/include/linux/namespace.h +++ b/include/linux/namespace.h | |||
| @@ -15,6 +15,7 @@ struct namespace { | |||
| 15 | 15 | ||
| 16 | extern int copy_namespace(int, struct task_struct *); | 16 | extern int copy_namespace(int, struct task_struct *); |
| 17 | extern void __put_namespace(struct namespace *namespace); | 17 | extern void __put_namespace(struct namespace *namespace); |
| 18 | extern struct namespace *dup_namespace(struct task_struct *, struct fs_struct *); | ||
| 18 | 19 | ||
| 19 | static inline void put_namespace(struct namespace *namespace) | 20 | static inline void put_namespace(struct namespace *namespace) |
| 20 | { | 21 | { |
diff --git a/include/linux/netfilter_ipv4/ipt_connbytes.h b/include/linux/netfilter_ipv4/ipt_connbytes.h index b04dfa3083c9..f63e6ee91113 100644 --- a/include/linux/netfilter_ipv4/ipt_connbytes.h +++ b/include/linux/netfilter_ipv4/ipt_connbytes.h | |||
| @@ -1,10 +1,10 @@ | |||
| 1 | #ifndef _IPT_CONNBYTES_H | 1 | #ifndef _IPT_CONNBYTES_H |
| 2 | #define _IPT_CONNBYTES_H | 2 | #define _IPT_CONNBYTES_H |
| 3 | 3 | ||
| 4 | #include <net/netfilter/xt_connbytes.h> | 4 | #include <linux/netfilter/xt_connbytes.h> |
| 5 | #define ipt_connbytes_what xt_connbytes_what | 5 | #define ipt_connbytes_what xt_connbytes_what |
| 6 | 6 | ||
| 7 | #define IPT_CONNBYTES_PKTS XT_CONNBYTES_PACKETS | 7 | #define IPT_CONNBYTES_PKTS XT_CONNBYTES_PKTS |
| 8 | #define IPT_CONNBYTES_BYTES XT_CONNBYTES_BYTES | 8 | #define IPT_CONNBYTES_BYTES XT_CONNBYTES_BYTES |
| 9 | #define IPT_CONNBYTES_AVGPKT XT_CONNBYTES_AVGPKT | 9 | #define IPT_CONNBYTES_AVGPKT XT_CONNBYTES_AVGPKT |
| 10 | 10 | ||
diff --git a/include/linux/netfilter_ipv4/ipt_policy.h b/include/linux/netfilter_ipv4/ipt_policy.h index 7fd1bec453f1..a3f6eff39d33 100644 --- a/include/linux/netfilter_ipv4/ipt_policy.h +++ b/include/linux/netfilter_ipv4/ipt_policy.h | |||
| @@ -27,16 +27,22 @@ struct ipt_policy_spec | |||
| 27 | reqid:1; | 27 | reqid:1; |
| 28 | }; | 28 | }; |
| 29 | 29 | ||
| 30 | union ipt_policy_addr | ||
| 31 | { | ||
| 32 | struct in_addr a4; | ||
| 33 | struct in6_addr a6; | ||
| 34 | }; | ||
| 35 | |||
| 30 | struct ipt_policy_elem | 36 | struct ipt_policy_elem |
| 31 | { | 37 | { |
| 32 | u_int32_t saddr; | 38 | union ipt_policy_addr saddr; |
| 33 | u_int32_t smask; | 39 | union ipt_policy_addr smask; |
| 34 | u_int32_t daddr; | 40 | union ipt_policy_addr daddr; |
| 35 | u_int32_t dmask; | 41 | union ipt_policy_addr dmask; |
| 36 | u_int32_t spi; | 42 | u_int32_t spi; |
| 37 | u_int32_t reqid; | 43 | u_int32_t reqid; |
| 38 | u_int8_t proto; | 44 | u_int8_t proto; |
| 39 | u_int8_t mode; | 45 | u_int8_t mode; |
| 40 | 46 | ||
| 41 | struct ipt_policy_spec match; | 47 | struct ipt_policy_spec match; |
| 42 | struct ipt_policy_spec invert; | 48 | struct ipt_policy_spec invert; |
diff --git a/include/linux/netfilter_ipv6/ip6t_policy.h b/include/linux/netfilter_ipv6/ip6t_policy.h index 5a93afcd2ff1..671bd818300f 100644 --- a/include/linux/netfilter_ipv6/ip6t_policy.h +++ b/include/linux/netfilter_ipv6/ip6t_policy.h | |||
| @@ -27,16 +27,22 @@ struct ip6t_policy_spec | |||
| 27 | reqid:1; | 27 | reqid:1; |
| 28 | }; | 28 | }; |
| 29 | 29 | ||
| 30 | union ip6t_policy_addr | ||
| 31 | { | ||
| 32 | struct in_addr a4; | ||
| 33 | struct in6_addr a6; | ||
| 34 | }; | ||
| 35 | |||
| 30 | struct ip6t_policy_elem | 36 | struct ip6t_policy_elem |
| 31 | { | 37 | { |
| 32 | struct in6_addr saddr; | 38 | union ip6t_policy_addr saddr; |
| 33 | struct in6_addr smask; | 39 | union ip6t_policy_addr smask; |
| 34 | struct in6_addr daddr; | 40 | union ip6t_policy_addr daddr; |
| 35 | struct in6_addr dmask; | 41 | union ip6t_policy_addr dmask; |
| 36 | u_int32_t spi; | 42 | u_int32_t spi; |
| 37 | u_int32_t reqid; | 43 | u_int32_t reqid; |
| 38 | u_int8_t proto; | 44 | u_int8_t proto; |
| 39 | u_int8_t mode; | 45 | u_int8_t mode; |
| 40 | 46 | ||
| 41 | struct ip6t_policy_spec match; | 47 | struct ip6t_policy_spec match; |
| 42 | struct ip6t_policy_spec invert; | 48 | struct ip6t_policy_spec invert; |
diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h index 4726ef7ba8e8..b959a4525cbd 100644 --- a/include/linux/nodemask.h +++ b/include/linux/nodemask.h | |||
| @@ -84,7 +84,6 @@ | |||
| 84 | #include <linux/threads.h> | 84 | #include <linux/threads.h> |
| 85 | #include <linux/bitmap.h> | 85 | #include <linux/bitmap.h> |
| 86 | #include <linux/numa.h> | 86 | #include <linux/numa.h> |
| 87 | #include <asm/bug.h> | ||
| 88 | 87 | ||
| 89 | typedef struct { DECLARE_BITMAP(bits, MAX_NUMNODES); } nodemask_t; | 88 | typedef struct { DECLARE_BITMAP(bits, MAX_NUMNODES); } nodemask_t; |
| 90 | extern nodemask_t _unused_nodemask_arg_; | 89 | extern nodemask_t _unused_nodemask_arg_; |
diff --git a/include/linux/parport.h b/include/linux/parport.h index f67f838a3a1f..008d736a6c9a 100644 --- a/include/linux/parport.h +++ b/include/linux/parport.h | |||
| @@ -128,6 +128,11 @@ struct amiga_parport_state { | |||
| 128 | unsigned char statusdir;/* ciab.ddrb & 7 */ | 128 | unsigned char statusdir;/* ciab.ddrb & 7 */ |
| 129 | }; | 129 | }; |
| 130 | 130 | ||
| 131 | struct ip32_parport_state { | ||
| 132 | unsigned int dcr; | ||
| 133 | unsigned int ecr; | ||
| 134 | }; | ||
| 135 | |||
| 131 | struct parport_state { | 136 | struct parport_state { |
| 132 | union { | 137 | union { |
| 133 | struct pc_parport_state pc; | 138 | struct pc_parport_state pc; |
| @@ -135,6 +140,7 @@ struct parport_state { | |||
| 135 | struct ax_parport_state ax; | 140 | struct ax_parport_state ax; |
| 136 | struct amiga_parport_state amiga; | 141 | struct amiga_parport_state amiga; |
| 137 | /* Atari has not state. */ | 142 | /* Atari has not state. */ |
| 143 | struct ip32_parport_state ip32; | ||
| 138 | void *misc; | 144 | void *misc; |
| 139 | } u; | 145 | } u; |
| 140 | }; | 146 | }; |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index b0b908f583c5..7a61ccdcbc4b 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
| @@ -1670,6 +1670,9 @@ | |||
| 1670 | #define PCI_DEVICE_ID_SIIG_2S1P_20x_550 0x2060 | 1670 | #define PCI_DEVICE_ID_SIIG_2S1P_20x_550 0x2060 |
| 1671 | #define PCI_DEVICE_ID_SIIG_2S1P_20x_650 0x2061 | 1671 | #define PCI_DEVICE_ID_SIIG_2S1P_20x_650 0x2061 |
| 1672 | #define PCI_DEVICE_ID_SIIG_2S1P_20x_850 0x2062 | 1672 | #define PCI_DEVICE_ID_SIIG_2S1P_20x_850 0x2062 |
| 1673 | #define PCI_DEVICE_ID_SIIG_8S_20x_550 0x2080 | ||
| 1674 | #define PCI_DEVICE_ID_SIIG_8S_20x_650 0x2081 | ||
| 1675 | #define PCI_DEVICE_ID_SIIG_8S_20x_850 0x2082 | ||
| 1673 | #define PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL 0x2050 | 1676 | #define PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL 0x2050 |
| 1674 | 1677 | ||
| 1675 | #define PCI_VENDOR_ID_RADISYS 0x1331 | 1678 | #define PCI_VENDOR_ID_RADISYS 0x1331 |
| @@ -1829,6 +1832,7 @@ | |||
| 1829 | #define PCI_VENDOR_ID_AFAVLAB 0x14db | 1832 | #define PCI_VENDOR_ID_AFAVLAB 0x14db |
| 1830 | #define PCI_DEVICE_ID_AFAVLAB_P028 0x2180 | 1833 | #define PCI_DEVICE_ID_AFAVLAB_P028 0x2180 |
| 1831 | #define PCI_DEVICE_ID_AFAVLAB_P030 0x2182 | 1834 | #define PCI_DEVICE_ID_AFAVLAB_P030 0x2182 |
| 1835 | #define PCI_SUBDEVICE_ID_AFAVLAB_P061 0x2150 | ||
| 1832 | 1836 | ||
| 1833 | #define PCI_VENDOR_ID_BROADCOM 0x14e4 | 1837 | #define PCI_VENDOR_ID_BROADCOM 0x14e4 |
| 1834 | #define PCI_DEVICE_ID_TIGON3_5752 0x1600 | 1838 | #define PCI_DEVICE_ID_TIGON3_5752 0x1600 |
diff --git a/include/linux/pktcdvd.h b/include/linux/pktcdvd.h index 2c177e4c8f22..8a94c717c266 100644 --- a/include/linux/pktcdvd.h +++ b/include/linux/pktcdvd.h | |||
| @@ -114,7 +114,7 @@ struct pkt_ctrl_command { | |||
| 114 | 114 | ||
| 115 | struct packet_settings | 115 | struct packet_settings |
| 116 | { | 116 | { |
| 117 | __u8 size; /* packet size in (512 byte) sectors */ | 117 | __u32 size; /* packet size in (512 byte) sectors */ |
| 118 | __u8 fp; /* fixed packets */ | 118 | __u8 fp; /* fixed packets */ |
| 119 | __u8 link_loss; /* the rest is specified | 119 | __u8 link_loss; /* the rest is specified |
| 120 | * as per Mt Fuji */ | 120 | * as per Mt Fuji */ |
| @@ -169,8 +169,8 @@ struct packet_iosched | |||
| 169 | #if (PAGE_SIZE % CD_FRAMESIZE) != 0 | 169 | #if (PAGE_SIZE % CD_FRAMESIZE) != 0 |
| 170 | #error "PAGE_SIZE must be a multiple of CD_FRAMESIZE" | 170 | #error "PAGE_SIZE must be a multiple of CD_FRAMESIZE" |
| 171 | #endif | 171 | #endif |
| 172 | #define PACKET_MAX_SIZE 32 | 172 | #define PACKET_MAX_SIZE 128 |
| 173 | #define PAGES_PER_PACKET (PACKET_MAX_SIZE * CD_FRAMESIZE / PAGE_SIZE) | 173 | #define FRAMES_PER_PAGE (PAGE_SIZE / CD_FRAMESIZE) |
| 174 | #define PACKET_MAX_SECTORS (PACKET_MAX_SIZE * CD_FRAMESIZE >> 9) | 174 | #define PACKET_MAX_SECTORS (PACKET_MAX_SIZE * CD_FRAMESIZE >> 9) |
| 175 | 175 | ||
| 176 | enum packet_data_state { | 176 | enum packet_data_state { |
| @@ -219,7 +219,7 @@ struct packet_data | |||
| 219 | atomic_t io_errors; /* Number of read/write errors during IO */ | 219 | atomic_t io_errors; /* Number of read/write errors during IO */ |
| 220 | 220 | ||
| 221 | struct bio *r_bios[PACKET_MAX_SIZE]; /* bios to use during data gathering */ | 221 | struct bio *r_bios[PACKET_MAX_SIZE]; /* bios to use during data gathering */ |
| 222 | struct page *pages[PAGES_PER_PACKET]; | 222 | struct page *pages[PACKET_MAX_SIZE / FRAMES_PER_PAGE]; |
| 223 | 223 | ||
| 224 | int cache_valid; /* If non-zero, the data for the zone defined */ | 224 | int cache_valid; /* If non-zero, the data for the zone defined */ |
| 225 | /* by the sector variable is completely cached */ | 225 | /* by the sector variable is completely cached */ |
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index 4f34d3d60f2e..21e5a9124856 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h | |||
| @@ -190,7 +190,6 @@ static __inline__ int DQUOT_OFF(struct super_block *sb) | |||
| 190 | */ | 190 | */ |
| 191 | #define sb_dquot_ops (NULL) | 191 | #define sb_dquot_ops (NULL) |
| 192 | #define sb_quotactl_ops (NULL) | 192 | #define sb_quotactl_ops (NULL) |
| 193 | #define sync_dquots_dev(dev,type) (NULL) | ||
| 194 | #define DQUOT_INIT(inode) do { } while(0) | 193 | #define DQUOT_INIT(inode) do { } while(0) |
| 195 | #define DQUOT_DROP(inode) do { } while(0) | 194 | #define DQUOT_DROP(inode) do { } while(0) |
| 196 | #define DQUOT_ALLOC_INODE(inode) (0) | 195 | #define DQUOT_ALLOC_INODE(inode) (0) |
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 981f9aa43353..b87aefa082e2 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h | |||
| @@ -240,11 +240,14 @@ extern int rcu_pending(int cpu); | |||
| 240 | * This means that all preempt_disable code sequences, including NMI and | 240 | * This means that all preempt_disable code sequences, including NMI and |
| 241 | * hardware-interrupt handlers, in progress on entry will have completed | 241 | * hardware-interrupt handlers, in progress on entry will have completed |
| 242 | * before this primitive returns. However, this does not guarantee that | 242 | * before this primitive returns. However, this does not guarantee that |
| 243 | * softirq handlers will have completed, since in some kernels | 243 | * softirq handlers will have completed, since in some kernels, these |
| 244 | * handlers can run in process context, and can block. | ||
| 244 | * | 245 | * |
| 245 | * This primitive provides the guarantees made by the (deprecated) | 246 | * This primitive provides the guarantees made by the (deprecated) |
| 246 | * synchronize_kernel() API. In contrast, synchronize_rcu() only | 247 | * synchronize_kernel() API. In contrast, synchronize_rcu() only |
| 247 | * guarantees that rcu_read_lock() sections will have completed. | 248 | * guarantees that rcu_read_lock() sections will have completed. |
| 249 | * In "classic RCU", these two guarantees happen to be one and | ||
| 250 | * the same, but can differ in realtime RCU implementations. | ||
| 248 | */ | 251 | */ |
| 249 | #define synchronize_sched() synchronize_rcu() | 252 | #define synchronize_sched() synchronize_rcu() |
| 250 | 253 | ||
diff --git a/include/linux/reiserfs_acl.h b/include/linux/reiserfs_acl.h index 0a3605099c44..806ec5b06707 100644 --- a/include/linux/reiserfs_acl.h +++ b/include/linux/reiserfs_acl.h | |||
| @@ -58,9 +58,13 @@ extern struct reiserfs_xattr_handler posix_acl_default_handler; | |||
| 58 | extern struct reiserfs_xattr_handler posix_acl_access_handler; | 58 | extern struct reiserfs_xattr_handler posix_acl_access_handler; |
| 59 | #else | 59 | #else |
| 60 | 60 | ||
| 61 | #define reiserfs_get_acl NULL | ||
| 62 | #define reiserfs_cache_default_acl(inode) 0 | 61 | #define reiserfs_cache_default_acl(inode) 0 |
| 63 | 62 | ||
| 63 | static inline struct posix_acl *reiserfs_get_acl(struct inode *inode, int type) | ||
| 64 | { | ||
| 65 | return NULL; | ||
| 66 | } | ||
| 67 | |||
| 64 | static inline int reiserfs_xattr_posix_acl_init(void) | 68 | static inline int reiserfs_xattr_posix_acl_init(void) |
| 65 | { | 69 | { |
| 66 | return 0; | 70 | return 0; |
diff --git a/include/linux/security.h b/include/linux/security.h index bb1da86747c7..7cbef482e13a 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
| @@ -1499,15 +1499,11 @@ static inline void security_sb_post_pivotroot (struct nameidata *old_nd, | |||
| 1499 | 1499 | ||
| 1500 | static inline int security_inode_alloc (struct inode *inode) | 1500 | static inline int security_inode_alloc (struct inode *inode) |
| 1501 | { | 1501 | { |
| 1502 | if (unlikely (IS_PRIVATE (inode))) | ||
| 1503 | return 0; | ||
| 1504 | return security_ops->inode_alloc_security (inode); | 1502 | return security_ops->inode_alloc_security (inode); |
| 1505 | } | 1503 | } |
| 1506 | 1504 | ||
| 1507 | static inline void security_inode_free (struct inode *inode) | 1505 | static inline void security_inode_free (struct inode *inode) |
| 1508 | { | 1506 | { |
| 1509 | if (unlikely (IS_PRIVATE (inode))) | ||
| 1510 | return; | ||
| 1511 | security_ops->inode_free_security (inode); | 1507 | security_ops->inode_free_security (inode); |
| 1512 | } | 1508 | } |
| 1513 | 1509 | ||
diff --git a/include/linux/smp.h b/include/linux/smp.h index 9dfa3ee769ae..44153fdf73fc 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h | |||
| @@ -17,7 +17,6 @@ extern void cpu_idle(void); | |||
| 17 | #include <linux/compiler.h> | 17 | #include <linux/compiler.h> |
| 18 | #include <linux/thread_info.h> | 18 | #include <linux/thread_info.h> |
| 19 | #include <asm/smp.h> | 19 | #include <asm/smp.h> |
| 20 | #include <asm/bug.h> | ||
| 21 | 20 | ||
| 22 | /* | 21 | /* |
| 23 | * main cross-CPU interfaces, handles INIT, TLB flush, STOP, etc. | 22 | * main cross-CPU interfaces, handles INIT, TLB flush, STOP, etc. |
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h index b68c11a2d6dd..be4772ed43c0 100644 --- a/include/linux/sunrpc/auth.h +++ b/include/linux/sunrpc/auth.h | |||
| @@ -48,7 +48,7 @@ struct rpc_cred { | |||
| 48 | 48 | ||
| 49 | /* per-flavor data */ | 49 | /* per-flavor data */ |
| 50 | }; | 50 | }; |
| 51 | #define RPCAUTH_CRED_LOCKED 0x0001 | 51 | #define RPCAUTH_CRED_NEW 0x0001 |
| 52 | #define RPCAUTH_CRED_UPTODATE 0x0002 | 52 | #define RPCAUTH_CRED_UPTODATE 0x0002 |
| 53 | 53 | ||
| 54 | #define RPCAUTH_CRED_MAGIC 0x0f4aa4f0 | 54 | #define RPCAUTH_CRED_MAGIC 0x0f4aa4f0 |
| @@ -83,9 +83,10 @@ struct rpc_auth { | |||
| 83 | struct rpc_cred_cache * au_credcache; | 83 | struct rpc_cred_cache * au_credcache; |
| 84 | /* per-flavor data */ | 84 | /* per-flavor data */ |
| 85 | }; | 85 | }; |
| 86 | #define RPC_AUTH_PROC_CREDS 0x0010 /* process creds (including | 86 | |
| 87 | * uid/gid, fs[ug]id, gids) | 87 | /* Flags for rpcauth_lookupcred() */ |
| 88 | */ | 88 | #define RPCAUTH_LOOKUP_NEW 0x01 /* Accept an uninitialised cred */ |
| 89 | #define RPCAUTH_LOOKUP_ROOTCREDS 0x02 /* This really ought to go! */ | ||
| 89 | 90 | ||
| 90 | /* | 91 | /* |
| 91 | * Client authentication ops | 92 | * Client authentication ops |
| @@ -105,6 +106,7 @@ struct rpc_authops { | |||
| 105 | 106 | ||
| 106 | struct rpc_credops { | 107 | struct rpc_credops { |
| 107 | const char * cr_name; /* Name of the auth flavour */ | 108 | const char * cr_name; /* Name of the auth flavour */ |
| 109 | int (*cr_init)(struct rpc_auth *, struct rpc_cred *); | ||
| 108 | void (*crdestroy)(struct rpc_cred *); | 110 | void (*crdestroy)(struct rpc_cred *); |
| 109 | 111 | ||
| 110 | int (*crmatch)(struct auth_cred *, struct rpc_cred *, int); | 112 | int (*crmatch)(struct auth_cred *, struct rpc_cred *, int); |
diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 5dc94e777fab..37c1c76fd547 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h | |||
| @@ -43,16 +43,20 @@ extern void mark_free_pages(struct zone *zone); | |||
| 43 | /* kernel/power/swsusp.c */ | 43 | /* kernel/power/swsusp.c */ |
| 44 | extern int software_suspend(void); | 44 | extern int software_suspend(void); |
| 45 | 45 | ||
| 46 | #if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) | ||
| 46 | extern int pm_prepare_console(void); | 47 | extern int pm_prepare_console(void); |
| 47 | extern void pm_restore_console(void); | 48 | extern void pm_restore_console(void); |
| 48 | 49 | #else | |
| 50 | static inline int pm_prepare_console(void) { return 0; } | ||
| 51 | static inline void pm_restore_console(void) {} | ||
| 52 | #endif /* defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) */ | ||
| 49 | #else | 53 | #else |
| 50 | static inline int software_suspend(void) | 54 | static inline int software_suspend(void) |
| 51 | { | 55 | { |
| 52 | printk("Warning: fake suspend called\n"); | 56 | printk("Warning: fake suspend called\n"); |
| 53 | return -EPERM; | 57 | return -EPERM; |
| 54 | } | 58 | } |
| 55 | #endif | 59 | #endif /* CONFIG_PM */ |
| 56 | 60 | ||
| 57 | #ifdef CONFIG_SUSPEND_SMP | 61 | #ifdef CONFIG_SUSPEND_SMP |
| 58 | extern void disable_nonboot_cpus(void); | 62 | extern void disable_nonboot_cpus(void); |
diff --git a/include/linux/tty.h b/include/linux/tty.h index 3787102e4b12..a7bd3b4558d2 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
| @@ -57,6 +57,7 @@ struct tty_buffer { | |||
| 57 | unsigned char *flag_buf_ptr; | 57 | unsigned char *flag_buf_ptr; |
| 58 | int used; | 58 | int used; |
| 59 | int size; | 59 | int size; |
| 60 | int active; | ||
| 60 | /* Data points here */ | 61 | /* Data points here */ |
| 61 | unsigned long data[0]; | 62 | unsigned long data[0]; |
| 62 | }; | 63 | }; |
| @@ -64,6 +65,7 @@ struct tty_buffer { | |||
| 64 | struct tty_bufhead { | 65 | struct tty_bufhead { |
| 65 | struct work_struct work; | 66 | struct work_struct work; |
| 66 | struct semaphore pty_sem; | 67 | struct semaphore pty_sem; |
| 68 | spinlock_t lock; | ||
| 67 | struct tty_buffer *head; /* Queue head */ | 69 | struct tty_buffer *head; /* Queue head */ |
| 68 | struct tty_buffer *tail; /* Active buffer */ | 70 | struct tty_buffer *tail; /* Active buffer */ |
| 69 | struct tty_buffer *free; /* Free queue head */ | 71 | struct tty_buffer *free; /* Free queue head */ |
diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h index be1400e82482..82961eb19888 100644 --- a/include/linux/tty_flip.h +++ b/include/linux/tty_flip.h | |||
| @@ -17,7 +17,7 @@ _INLINE_ int tty_insert_flip_char(struct tty_struct *tty, | |||
| 17 | unsigned char ch, char flag) | 17 | unsigned char ch, char flag) |
| 18 | { | 18 | { |
| 19 | struct tty_buffer *tb = tty->buf.tail; | 19 | struct tty_buffer *tb = tty->buf.tail; |
| 20 | if (tb && tb->used < tb->size) { | 20 | if (tb && tb->active && tb->used < tb->size) { |
| 21 | tb->flag_buf_ptr[tb->used] = flag; | 21 | tb->flag_buf_ptr[tb->used] = flag; |
| 22 | tb->char_buf_ptr[tb->used++] = ch; | 22 | tb->char_buf_ptr[tb->used++] = ch; |
| 23 | return 1; | 23 | return 1; |
| @@ -27,6 +27,11 @@ _INLINE_ int tty_insert_flip_char(struct tty_struct *tty, | |||
| 27 | 27 | ||
| 28 | _INLINE_ void tty_schedule_flip(struct tty_struct *tty) | 28 | _INLINE_ void tty_schedule_flip(struct tty_struct *tty) |
| 29 | { | 29 | { |
| 30 | unsigned long flags; | ||
| 31 | spin_lock_irqsave(&tty->buf.lock, flags); | ||
| 32 | if (tty->buf.tail != NULL) | ||
| 33 | tty->buf.tail->active = 0; | ||
| 34 | spin_unlock_irqrestore(&tty->buf.lock, flags); | ||
| 30 | schedule_delayed_work(&tty->buf.work, 1); | 35 | schedule_delayed_work(&tty->buf.work, 1); |
| 31 | } | 36 | } |
| 32 | 37 | ||
diff --git a/include/linux/ufs_fs.h b/include/linux/ufs_fs.h index 7a6babeca256..b0ffe4356e5a 100644 --- a/include/linux/ufs_fs.h +++ b/include/linux/ufs_fs.h | |||
| @@ -148,11 +148,11 @@ typedef __u16 __bitwise __fs16; | |||
| 148 | #define UFS_USEEFT ((__u16)65535) | 148 | #define UFS_USEEFT ((__u16)65535) |
| 149 | 149 | ||
| 150 | #define UFS_FSOK 0x7c269d38 | 150 | #define UFS_FSOK 0x7c269d38 |
| 151 | #define UFS_FSACTIVE ((char)0x00) | 151 | #define UFS_FSACTIVE ((__s8)0x00) |
| 152 | #define UFS_FSCLEAN ((char)0x01) | 152 | #define UFS_FSCLEAN ((__s8)0x01) |
| 153 | #define UFS_FSSTABLE ((char)0x02) | 153 | #define UFS_FSSTABLE ((__s8)0x02) |
| 154 | #define UFS_FSOSF1 ((char)0x03) /* is this correct for DEC OSF/1? */ | 154 | #define UFS_FSOSF1 ((__s8)0x03) /* is this correct for DEC OSF/1? */ |
| 155 | #define UFS_FSBAD ((char)0xff) | 155 | #define UFS_FSBAD ((__s8)0xff) |
| 156 | 156 | ||
| 157 | /* From here to next blank line, s_flags for ufs_sb_info */ | 157 | /* From here to next blank line, s_flags for ufs_sb_info */ |
| 158 | /* directory entry encoding */ | 158 | /* directory entry encoding */ |
| @@ -502,8 +502,7 @@ struct ufs_super_block { | |||
| 502 | /* | 502 | /* |
| 503 | * Convert cylinder group to base address of its global summary info. | 503 | * Convert cylinder group to base address of its global summary info. |
| 504 | */ | 504 | */ |
| 505 | #define fs_cs(indx) \ | 505 | #define fs_cs(indx) s_csp[(indx)] |
| 506 | s_csp[(indx) >> uspi->s_csshift][(indx) & ~uspi->s_csmask] | ||
| 507 | 506 | ||
| 508 | /* | 507 | /* |
| 509 | * Cylinder group block for a file system. | 508 | * Cylinder group block for a file system. |
| @@ -913,6 +912,7 @@ extern int ufs_sync_inode (struct inode *); | |||
| 913 | extern void ufs_delete_inode (struct inode *); | 912 | extern void ufs_delete_inode (struct inode *); |
| 914 | extern struct buffer_head * ufs_getfrag (struct inode *, unsigned, int, int *); | 913 | extern struct buffer_head * ufs_getfrag (struct inode *, unsigned, int, int *); |
| 915 | extern struct buffer_head * ufs_bread (struct inode *, unsigned, int, int *); | 914 | extern struct buffer_head * ufs_bread (struct inode *, unsigned, int, int *); |
| 915 | extern int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create); | ||
| 916 | 916 | ||
| 917 | /* namei.c */ | 917 | /* namei.c */ |
| 918 | extern struct file_operations ufs_dir_operations; | 918 | extern struct file_operations ufs_dir_operations; |
diff --git a/include/linux/ufs_fs_sb.h b/include/linux/ufs_fs_sb.h index c1be4c226486..8ff13c160f3d 100644 --- a/include/linux/ufs_fs_sb.h +++ b/include/linux/ufs_fs_sb.h | |||
| @@ -25,7 +25,7 @@ struct ufs_csum; | |||
| 25 | 25 | ||
| 26 | struct ufs_sb_info { | 26 | struct ufs_sb_info { |
| 27 | struct ufs_sb_private_info * s_uspi; | 27 | struct ufs_sb_private_info * s_uspi; |
| 28 | struct ufs_csum * s_csp[UFS_MAXCSBUFS]; | 28 | struct ufs_csum * s_csp; |
| 29 | unsigned s_bytesex; | 29 | unsigned s_bytesex; |
| 30 | unsigned s_flags; | 30 | unsigned s_flags; |
| 31 | struct buffer_head ** s_ucg; | 31 | struct buffer_head ** s_ucg; |
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 6f6c69777648..5208b12d5550 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h | |||
| @@ -549,7 +549,7 @@ struct v4l2_framebuffer | |||
| 549 | struct v4l2_clip | 549 | struct v4l2_clip |
| 550 | { | 550 | { |
| 551 | struct v4l2_rect c; | 551 | struct v4l2_rect c; |
| 552 | struct v4l2_clip *next; | 552 | struct v4l2_clip __user *next; |
| 553 | }; | 553 | }; |
| 554 | 554 | ||
| 555 | struct v4l2_window | 555 | struct v4l2_window |
| @@ -629,6 +629,7 @@ typedef __u64 v4l2_std_id; | |||
| 629 | #define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000) | 629 | #define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000) |
| 630 | #define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000) | 630 | #define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000) |
| 631 | #define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000) | 631 | #define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000) |
| 632 | #define V4L2_STD_NTSC_M_KR ((v4l2_std_id)0x00008000) | ||
| 632 | 633 | ||
| 633 | #define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000) | 634 | #define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000) |
| 634 | #define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000) | 635 | #define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000) |
| @@ -661,7 +662,8 @@ typedef __u64 v4l2_std_id; | |||
| 661 | V4L2_STD_PAL_H |\ | 662 | V4L2_STD_PAL_H |\ |
| 662 | V4L2_STD_PAL_I) | 663 | V4L2_STD_PAL_I) |
| 663 | #define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\ | 664 | #define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\ |
| 664 | V4L2_STD_NTSC_M_JP) | 665 | V4L2_STD_NTSC_M_JP |\ |
| 666 | V4L2_STD_NTSC_M_KR) | ||
| 665 | #define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\ | 667 | #define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\ |
| 666 | V4L2_STD_SECAM_K |\ | 668 | V4L2_STD_SECAM_K |\ |
| 667 | V4L2_STD_SECAM_K1) | 669 | V4L2_STD_SECAM_K1) |
diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h index 67856eb93b43..dac43b15a5b0 100644 --- a/include/net/netfilter/nf_conntrack_l3proto.h +++ b/include/net/netfilter/nf_conntrack_l3proto.h | |||
| @@ -88,12 +88,6 @@ extern struct nf_conntrack_l3proto *nf_ct_l3protos[AF_MAX]; | |||
| 88 | extern int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto); | 88 | extern int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto); |
| 89 | extern void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto); | 89 | extern void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto); |
| 90 | 90 | ||
| 91 | static inline struct nf_conntrack_l3proto * | ||
| 92 | __nf_ct_l3proto_find(u_int16_t l3proto) | ||
| 93 | { | ||
| 94 | return nf_ct_l3protos[l3proto]; | ||
| 95 | } | ||
| 96 | |||
| 97 | extern struct nf_conntrack_l3proto * | 91 | extern struct nf_conntrack_l3proto * |
| 98 | nf_ct_l3proto_find_get(u_int16_t l3proto); | 92 | nf_ct_l3proto_find_get(u_int16_t l3proto); |
| 99 | 93 | ||
| @@ -103,4 +97,13 @@ extern void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p); | |||
| 103 | extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4; | 97 | extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4; |
| 104 | extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6; | 98 | extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6; |
| 105 | extern struct nf_conntrack_l3proto nf_conntrack_generic_l3proto; | 99 | extern struct nf_conntrack_l3proto nf_conntrack_generic_l3proto; |
| 100 | |||
| 101 | static inline struct nf_conntrack_l3proto * | ||
| 102 | __nf_ct_l3proto_find(u_int16_t l3proto) | ||
| 103 | { | ||
| 104 | if (unlikely(l3proto >= AF_MAX)) | ||
| 105 | return &nf_conntrack_generic_l3proto; | ||
| 106 | return nf_ct_l3protos[l3proto]; | ||
| 107 | } | ||
| 108 | |||
| 106 | #endif /*_NF_CONNTRACK_L3PROTO_H*/ | 109 | #endif /*_NF_CONNTRACK_L3PROTO_H*/ |
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 8c522ae031bb..072f407848a6 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
| @@ -700,7 +700,7 @@ struct sctp_chunk { | |||
| 700 | __u8 ecn_ce_done; /* Have we processed the ECN CE bit? */ | 700 | __u8 ecn_ce_done; /* Have we processed the ECN CE bit? */ |
| 701 | __u8 pdiscard; /* Discard the whole packet now? */ | 701 | __u8 pdiscard; /* Discard the whole packet now? */ |
| 702 | __u8 tsn_gap_acked; /* Is this chunk acked by a GAP ACK? */ | 702 | __u8 tsn_gap_acked; /* Is this chunk acked by a GAP ACK? */ |
| 703 | __u8 fast_retransmit; /* Is this chunk fast retransmitted? */ | 703 | __s8 fast_retransmit; /* Is this chunk fast retransmitted? */ |
| 704 | __u8 tsn_missing_report; /* Data chunk missing counter. */ | 704 | __u8 tsn_missing_report; /* Data chunk missing counter. */ |
| 705 | }; | 705 | }; |
| 706 | 706 | ||
diff --git a/include/net/sock.h b/include/net/sock.h index 1806e5b61419..30758035d616 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
| @@ -1354,12 +1354,12 @@ extern int sock_get_timestamp(struct sock *, struct timeval __user *); | |||
| 1354 | * Enable debug/info messages | 1354 | * Enable debug/info messages |
| 1355 | */ | 1355 | */ |
| 1356 | 1356 | ||
| 1357 | #if 0 | 1357 | #ifdef CONFIG_NETDEBUG |
| 1358 | #define NETDEBUG(fmt, args...) do { } while (0) | ||
| 1359 | #define LIMIT_NETDEBUG(fmt, args...) do { } while(0) | ||
| 1360 | #else | ||
| 1361 | #define NETDEBUG(fmt, args...) printk(fmt,##args) | 1358 | #define NETDEBUG(fmt, args...) printk(fmt,##args) |
| 1362 | #define LIMIT_NETDEBUG(fmt, args...) do { if (net_ratelimit()) printk(fmt,##args); } while(0) | 1359 | #define LIMIT_NETDEBUG(fmt, args...) do { if (net_ratelimit()) printk(fmt,##args); } while(0) |
| 1360 | #else | ||
| 1361 | #define NETDEBUG(fmt, args...) do { } while (0) | ||
| 1362 | #define LIMIT_NETDEBUG(fmt, args...) do { } while(0) | ||
| 1363 | #endif | 1363 | #endif |
| 1364 | 1364 | ||
| 1365 | /* | 1365 | /* |
diff --git a/init/Kconfig b/init/Kconfig index b9923b1434a2..38416a199def 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
| @@ -31,19 +31,8 @@ config EXPERIMENTAL | |||
| 31 | you say Y here, you will be offered the choice of using features or | 31 | you say Y here, you will be offered the choice of using features or |
| 32 | drivers that are currently considered to be in the alpha-test phase. | 32 | drivers that are currently considered to be in the alpha-test phase. |
| 33 | 33 | ||
| 34 | config CLEAN_COMPILE | ||
| 35 | bool "Select only drivers expected to compile cleanly" if EXPERIMENTAL | ||
| 36 | default y | ||
| 37 | help | ||
| 38 | Select this option if you don't even want to see the option | ||
| 39 | to configure known-broken drivers. | ||
| 40 | |||
| 41 | If unsure, say Y | ||
| 42 | |||
| 43 | config BROKEN | 34 | config BROKEN |
| 44 | bool | 35 | bool |
| 45 | depends on !CLEAN_COMPILE | ||
| 46 | default y | ||
| 47 | 36 | ||
| 48 | config BROKEN_ON_SMP | 37 | config BROKEN_ON_SMP |
| 49 | bool | 38 | bool |
| @@ -180,7 +169,6 @@ config SYSCTL | |||
| 180 | config AUDIT | 169 | config AUDIT |
| 181 | bool "Auditing support" | 170 | bool "Auditing support" |
| 182 | depends on NET | 171 | depends on NET |
| 183 | default y if SECURITY_SELINUX | ||
| 184 | help | 172 | help |
| 185 | Enable auditing infrastructure that can be used with another | 173 | Enable auditing infrastructure that can be used with another |
| 186 | kernel subsystem, such as SELinux (which requires this for | 174 | kernel subsystem, such as SELinux (which requires this for |
diff --git a/kernel/compat.c b/kernel/compat.c index 1867290c37e3..8c9cd88b6785 100644 --- a/kernel/compat.c +++ b/kernel/compat.c | |||
| @@ -23,7 +23,6 @@ | |||
| 23 | #include <linux/security.h> | 23 | #include <linux/security.h> |
| 24 | 24 | ||
| 25 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
| 26 | #include <asm/bug.h> | ||
| 27 | 26 | ||
| 28 | int get_compat_timespec(struct timespec *ts, const struct compat_timespec __user *cts) | 27 | int get_compat_timespec(struct timespec *ts, const struct compat_timespec __user *cts) |
| 29 | { | 28 | { |
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index fe2f71f92ae0..ba42b0a76961 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
| @@ -641,7 +641,7 @@ static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask) | |||
| 641 | * task has been modifying its cpuset. | 641 | * task has been modifying its cpuset. |
| 642 | */ | 642 | */ |
| 643 | 643 | ||
| 644 | void cpuset_update_task_memory_state() | 644 | void cpuset_update_task_memory_state(void) |
| 645 | { | 645 | { |
| 646 | int my_cpusets_mem_gen; | 646 | int my_cpusets_mem_gen; |
| 647 | struct task_struct *tsk = current; | 647 | struct task_struct *tsk = current; |
diff --git a/kernel/fork.c b/kernel/fork.c index 7f0ab5ee948c..8e88b374cee9 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -446,6 +446,55 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm) | |||
| 446 | } | 446 | } |
| 447 | } | 447 | } |
| 448 | 448 | ||
| 449 | /* | ||
| 450 | * Allocate a new mm structure and copy contents from the | ||
| 451 | * mm structure of the passed in task structure. | ||
| 452 | */ | ||
| 453 | static struct mm_struct *dup_mm(struct task_struct *tsk) | ||
| 454 | { | ||
| 455 | struct mm_struct *mm, *oldmm = current->mm; | ||
| 456 | int err; | ||
| 457 | |||
| 458 | if (!oldmm) | ||
| 459 | return NULL; | ||
| 460 | |||
| 461 | mm = allocate_mm(); | ||
| 462 | if (!mm) | ||
| 463 | goto fail_nomem; | ||
| 464 | |||
| 465 | memcpy(mm, oldmm, sizeof(*mm)); | ||
| 466 | |||
| 467 | if (!mm_init(mm)) | ||
| 468 | goto fail_nomem; | ||
| 469 | |||
| 470 | if (init_new_context(tsk, mm)) | ||
| 471 | goto fail_nocontext; | ||
| 472 | |||
| 473 | err = dup_mmap(mm, oldmm); | ||
| 474 | if (err) | ||
| 475 | goto free_pt; | ||
| 476 | |||
| 477 | mm->hiwater_rss = get_mm_rss(mm); | ||
| 478 | mm->hiwater_vm = mm->total_vm; | ||
| 479 | |||
| 480 | return mm; | ||
| 481 | |||
| 482 | free_pt: | ||
| 483 | mmput(mm); | ||
| 484 | |||
| 485 | fail_nomem: | ||
| 486 | return NULL; | ||
| 487 | |||
| 488 | fail_nocontext: | ||
| 489 | /* | ||
| 490 | * If init_new_context() failed, we cannot use mmput() to free the mm | ||
| 491 | * because it calls destroy_context() | ||
| 492 | */ | ||
| 493 | mm_free_pgd(mm); | ||
| 494 | free_mm(mm); | ||
| 495 | return NULL; | ||
| 496 | } | ||
| 497 | |||
| 449 | static int copy_mm(unsigned long clone_flags, struct task_struct * tsk) | 498 | static int copy_mm(unsigned long clone_flags, struct task_struct * tsk) |
| 450 | { | 499 | { |
| 451 | struct mm_struct * mm, *oldmm; | 500 | struct mm_struct * mm, *oldmm; |
| @@ -473,43 +522,17 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * tsk) | |||
| 473 | } | 522 | } |
| 474 | 523 | ||
| 475 | retval = -ENOMEM; | 524 | retval = -ENOMEM; |
| 476 | mm = allocate_mm(); | 525 | mm = dup_mm(tsk); |
| 477 | if (!mm) | 526 | if (!mm) |
| 478 | goto fail_nomem; | 527 | goto fail_nomem; |
| 479 | 528 | ||
| 480 | /* Copy the current MM stuff.. */ | ||
| 481 | memcpy(mm, oldmm, sizeof(*mm)); | ||
| 482 | if (!mm_init(mm)) | ||
| 483 | goto fail_nomem; | ||
| 484 | |||
| 485 | if (init_new_context(tsk,mm)) | ||
| 486 | goto fail_nocontext; | ||
| 487 | |||
| 488 | retval = dup_mmap(mm, oldmm); | ||
| 489 | if (retval) | ||
| 490 | goto free_pt; | ||
| 491 | |||
| 492 | mm->hiwater_rss = get_mm_rss(mm); | ||
| 493 | mm->hiwater_vm = mm->total_vm; | ||
| 494 | |||
| 495 | good_mm: | 529 | good_mm: |
| 496 | tsk->mm = mm; | 530 | tsk->mm = mm; |
| 497 | tsk->active_mm = mm; | 531 | tsk->active_mm = mm; |
| 498 | return 0; | 532 | return 0; |
| 499 | 533 | ||
| 500 | free_pt: | ||
| 501 | mmput(mm); | ||
| 502 | fail_nomem: | 534 | fail_nomem: |
| 503 | return retval; | 535 | return retval; |
| 504 | |||
| 505 | fail_nocontext: | ||
| 506 | /* | ||
| 507 | * If init_new_context() failed, we cannot use mmput() to free the mm | ||
| 508 | * because it calls destroy_context() | ||
| 509 | */ | ||
| 510 | mm_free_pgd(mm); | ||
| 511 | free_mm(mm); | ||
| 512 | return retval; | ||
| 513 | } | 536 | } |
| 514 | 537 | ||
| 515 | static inline struct fs_struct *__copy_fs_struct(struct fs_struct *old) | 538 | static inline struct fs_struct *__copy_fs_struct(struct fs_struct *old) |
| @@ -597,32 +620,17 @@ out: | |||
| 597 | return newf; | 620 | return newf; |
| 598 | } | 621 | } |
| 599 | 622 | ||
| 600 | static int copy_files(unsigned long clone_flags, struct task_struct * tsk) | 623 | /* |
| 624 | * Allocate a new files structure and copy contents from the | ||
| 625 | * passed in files structure. | ||
| 626 | */ | ||
| 627 | static struct files_struct *dup_fd(struct files_struct *oldf, int *errorp) | ||
| 601 | { | 628 | { |
| 602 | struct files_struct *oldf, *newf; | 629 | struct files_struct *newf; |
| 603 | struct file **old_fds, **new_fds; | 630 | struct file **old_fds, **new_fds; |
| 604 | int open_files, size, i, error = 0, expand; | 631 | int open_files, size, i, expand; |
| 605 | struct fdtable *old_fdt, *new_fdt; | 632 | struct fdtable *old_fdt, *new_fdt; |
| 606 | 633 | ||
| 607 | /* | ||
| 608 | * A background process may not have any files ... | ||
| 609 | */ | ||
| 610 | oldf = current->files; | ||
| 611 | if (!oldf) | ||
| 612 | goto out; | ||
| 613 | |||
| 614 | if (clone_flags & CLONE_FILES) { | ||
| 615 | atomic_inc(&oldf->count); | ||
| 616 | goto out; | ||
| 617 | } | ||
| 618 | |||
| 619 | /* | ||
| 620 | * Note: we may be using current for both targets (See exec.c) | ||
| 621 | * This works because we cache current->files (old) as oldf. Don't | ||
| 622 | * break this. | ||
| 623 | */ | ||
| 624 | tsk->files = NULL; | ||
| 625 | error = -ENOMEM; | ||
| 626 | newf = alloc_files(); | 634 | newf = alloc_files(); |
| 627 | if (!newf) | 635 | if (!newf) |
| 628 | goto out; | 636 | goto out; |
| @@ -651,9 +659,9 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk) | |||
| 651 | if (expand) { | 659 | if (expand) { |
| 652 | spin_unlock(&oldf->file_lock); | 660 | spin_unlock(&oldf->file_lock); |
| 653 | spin_lock(&newf->file_lock); | 661 | spin_lock(&newf->file_lock); |
| 654 | error = expand_files(newf, open_files-1); | 662 | *errorp = expand_files(newf, open_files-1); |
| 655 | spin_unlock(&newf->file_lock); | 663 | spin_unlock(&newf->file_lock); |
| 656 | if (error < 0) | 664 | if (*errorp < 0) |
| 657 | goto out_release; | 665 | goto out_release; |
| 658 | new_fdt = files_fdtable(newf); | 666 | new_fdt = files_fdtable(newf); |
| 659 | /* | 667 | /* |
| @@ -702,10 +710,8 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk) | |||
| 702 | memset(&new_fdt->close_on_exec->fds_bits[start], 0, left); | 710 | memset(&new_fdt->close_on_exec->fds_bits[start], 0, left); |
| 703 | } | 711 | } |
| 704 | 712 | ||
| 705 | tsk->files = newf; | ||
| 706 | error = 0; | ||
| 707 | out: | 713 | out: |
| 708 | return error; | 714 | return newf; |
| 709 | 715 | ||
| 710 | out_release: | 716 | out_release: |
| 711 | free_fdset (new_fdt->close_on_exec, new_fdt->max_fdset); | 717 | free_fdset (new_fdt->close_on_exec, new_fdt->max_fdset); |
| @@ -715,6 +721,40 @@ out_release: | |||
| 715 | goto out; | 721 | goto out; |
| 716 | } | 722 | } |
| 717 | 723 | ||
| 724 | static int copy_files(unsigned long clone_flags, struct task_struct * tsk) | ||
| 725 | { | ||
| 726 | struct files_struct *oldf, *newf; | ||
| 727 | int error = 0; | ||
| 728 | |||
| 729 | /* | ||
| 730 | * A background process may not have any files ... | ||
| 731 | */ | ||
| 732 | oldf = current->files; | ||
| 733 | if (!oldf) | ||
| 734 | goto out; | ||
| 735 | |||
| 736 | if (clone_flags & CLONE_FILES) { | ||
| 737 | atomic_inc(&oldf->count); | ||
| 738 | goto out; | ||
| 739 | } | ||
| 740 | |||
| 741 | /* | ||
| 742 | * Note: we may be using current for both targets (See exec.c) | ||
| 743 | * This works because we cache current->files (old) as oldf. Don't | ||
| 744 | * break this. | ||
| 745 | */ | ||
| 746 | tsk->files = NULL; | ||
| 747 | error = -ENOMEM; | ||
| 748 | newf = dup_fd(oldf, &error); | ||
| 749 | if (!newf) | ||
| 750 | goto out; | ||
| 751 | |||
| 752 | tsk->files = newf; | ||
| 753 | error = 0; | ||
| 754 | out: | ||
| 755 | return error; | ||
| 756 | } | ||
| 757 | |||
| 718 | /* | 758 | /* |
| 719 | * Helper to unshare the files of the current task. | 759 | * Helper to unshare the files of the current task. |
| 720 | * We don't want to expose copy_files internals to | 760 | * We don't want to expose copy_files internals to |
| @@ -1323,3 +1363,249 @@ void __init proc_caches_init(void) | |||
| 1323 | sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN, | 1363 | sizeof(struct mm_struct), ARCH_MIN_MMSTRUCT_ALIGN, |
| 1324 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); | 1364 | SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); |
| 1325 | } | 1365 | } |
| 1366 | |||
| 1367 | |||
| 1368 | /* | ||
| 1369 | * Check constraints on flags passed to the unshare system call and | ||
| 1370 | * force unsharing of additional process context as appropriate. | ||
| 1371 | */ | ||
| 1372 | static inline void check_unshare_flags(unsigned long *flags_ptr) | ||
| 1373 | { | ||
| 1374 | /* | ||
| 1375 | * If unsharing a thread from a thread group, must also | ||
| 1376 | * unshare vm. | ||
| 1377 | */ | ||
| 1378 | if (*flags_ptr & CLONE_THREAD) | ||
| 1379 | *flags_ptr |= CLONE_VM; | ||
| 1380 | |||
| 1381 | /* | ||
| 1382 | * If unsharing vm, must also unshare signal handlers. | ||
| 1383 | */ | ||
| 1384 | if (*flags_ptr & CLONE_VM) | ||
| 1385 | *flags_ptr |= CLONE_SIGHAND; | ||
| 1386 | |||
| 1387 | /* | ||
| 1388 | * If unsharing signal handlers and the task was created | ||
| 1389 | * using CLONE_THREAD, then must unshare the thread | ||
| 1390 | */ | ||
| 1391 | if ((*flags_ptr & CLONE_SIGHAND) && | ||
| 1392 | (atomic_read(¤t->signal->count) > 1)) | ||
| 1393 | *flags_ptr |= CLONE_THREAD; | ||
| 1394 | |||
| 1395 | /* | ||
| 1396 | * If unsharing namespace, must also unshare filesystem information. | ||
| 1397 | */ | ||
| 1398 | if (*flags_ptr & CLONE_NEWNS) | ||
| 1399 | *flags_ptr |= CLONE_FS; | ||
| 1400 | } | ||
| 1401 | |||
| 1402 | /* | ||
| 1403 | * Unsharing of tasks created with CLONE_THREAD is not supported yet | ||
| 1404 | */ | ||
| 1405 | static int unshare_thread(unsigned long unshare_flags) | ||
| 1406 | { | ||
| 1407 | if (unshare_flags & CLONE_THREAD) | ||
| 1408 | return -EINVAL; | ||
| 1409 | |||
| 1410 | return 0; | ||
| 1411 | } | ||
| 1412 | |||
| 1413 | /* | ||
| 1414 | * Unshare the filesystem structure if it is being shared | ||
| 1415 | */ | ||
| 1416 | static int unshare_fs(unsigned long unshare_flags, struct fs_struct **new_fsp) | ||
| 1417 | { | ||
| 1418 | struct fs_struct *fs = current->fs; | ||
| 1419 | |||
| 1420 | if ((unshare_flags & CLONE_FS) && | ||
| 1421 | (fs && atomic_read(&fs->count) > 1)) { | ||
| 1422 | *new_fsp = __copy_fs_struct(current->fs); | ||
| 1423 | if (!*new_fsp) | ||
| 1424 | return -ENOMEM; | ||
| 1425 | } | ||
| 1426 | |||
| 1427 | return 0; | ||
| 1428 | } | ||
| 1429 | |||
| 1430 | /* | ||
| 1431 | * Unshare the namespace structure if it is being shared | ||
| 1432 | */ | ||
| 1433 | static int unshare_namespace(unsigned long unshare_flags, struct namespace **new_nsp, struct fs_struct *new_fs) | ||
| 1434 | { | ||
| 1435 | struct namespace *ns = current->namespace; | ||
| 1436 | |||
| 1437 | if ((unshare_flags & CLONE_NEWNS) && | ||
| 1438 | (ns && atomic_read(&ns->count) > 1)) { | ||
| 1439 | if (!capable(CAP_SYS_ADMIN)) | ||
| 1440 | return -EPERM; | ||
| 1441 | |||
| 1442 | *new_nsp = dup_namespace(current, new_fs ? new_fs : current->fs); | ||
| 1443 | if (!*new_nsp) | ||
| 1444 | return -ENOMEM; | ||
| 1445 | } | ||
| 1446 | |||
| 1447 | return 0; | ||
| 1448 | } | ||
| 1449 | |||
| 1450 | /* | ||
| 1451 | * Unsharing of sighand for tasks created with CLONE_SIGHAND is not | ||
| 1452 | * supported yet | ||
| 1453 | */ | ||
| 1454 | static int unshare_sighand(unsigned long unshare_flags, struct sighand_struct **new_sighp) | ||
| 1455 | { | ||
| 1456 | struct sighand_struct *sigh = current->sighand; | ||
| 1457 | |||
| 1458 | if ((unshare_flags & CLONE_SIGHAND) && | ||
| 1459 | (sigh && atomic_read(&sigh->count) > 1)) | ||
| 1460 | return -EINVAL; | ||
| 1461 | else | ||
| 1462 | return 0; | ||
| 1463 | } | ||
| 1464 | |||
| 1465 | /* | ||
| 1466 | * Unshare vm if it is being shared | ||
| 1467 | */ | ||
| 1468 | static int unshare_vm(unsigned long unshare_flags, struct mm_struct **new_mmp) | ||
| 1469 | { | ||
| 1470 | struct mm_struct *mm = current->mm; | ||
| 1471 | |||
| 1472 | if ((unshare_flags & CLONE_VM) && | ||
| 1473 | (mm && atomic_read(&mm->mm_users) > 1)) { | ||
| 1474 | *new_mmp = dup_mm(current); | ||
| 1475 | if (!*new_mmp) | ||
| 1476 | return -ENOMEM; | ||
| 1477 | } | ||
| 1478 | |||
| 1479 | return 0; | ||
| 1480 | } | ||
| 1481 | |||
| 1482 | /* | ||
| 1483 | * Unshare file descriptor table if it is being shared | ||
| 1484 | */ | ||
| 1485 | static int unshare_fd(unsigned long unshare_flags, struct files_struct **new_fdp) | ||
| 1486 | { | ||
| 1487 | struct files_struct *fd = current->files; | ||
| 1488 | int error = 0; | ||
| 1489 | |||
| 1490 | if ((unshare_flags & CLONE_FILES) && | ||
| 1491 | (fd && atomic_read(&fd->count) > 1)) { | ||
| 1492 | *new_fdp = dup_fd(fd, &error); | ||
| 1493 | if (!*new_fdp) | ||
| 1494 | return error; | ||
| 1495 | } | ||
| 1496 | |||
| 1497 | return 0; | ||
| 1498 | } | ||
| 1499 | |||
| 1500 | /* | ||
| 1501 | * Unsharing of semundo for tasks created with CLONE_SYSVSEM is not | ||
| 1502 | * supported yet | ||
| 1503 | */ | ||
| 1504 | static int unshare_semundo(unsigned long unshare_flags, struct sem_undo_list **new_ulistp) | ||
| 1505 | { | ||
| 1506 | if (unshare_flags & CLONE_SYSVSEM) | ||
| 1507 | return -EINVAL; | ||
| 1508 | |||
| 1509 | return 0; | ||
| 1510 | } | ||
| 1511 | |||
| 1512 | /* | ||
| 1513 | * unshare allows a process to 'unshare' part of the process | ||
| 1514 | * context which was originally shared using clone. copy_* | ||
| 1515 | * functions used by do_fork() cannot be used here directly | ||
| 1516 | * because they modify an inactive task_struct that is being | ||
| 1517 | * constructed. Here we are modifying the current, active, | ||
| 1518 | * task_struct. | ||
| 1519 | */ | ||
| 1520 | asmlinkage long sys_unshare(unsigned long unshare_flags) | ||
| 1521 | { | ||
| 1522 | int err = 0; | ||
| 1523 | struct fs_struct *fs, *new_fs = NULL; | ||
| 1524 | struct namespace *ns, *new_ns = NULL; | ||
| 1525 | struct sighand_struct *sigh, *new_sigh = NULL; | ||
| 1526 | struct mm_struct *mm, *new_mm = NULL, *active_mm = NULL; | ||
| 1527 | struct files_struct *fd, *new_fd = NULL; | ||
| 1528 | struct sem_undo_list *new_ulist = NULL; | ||
| 1529 | |||
| 1530 | check_unshare_flags(&unshare_flags); | ||
| 1531 | |||
| 1532 | if ((err = unshare_thread(unshare_flags))) | ||
| 1533 | goto bad_unshare_out; | ||
| 1534 | if ((err = unshare_fs(unshare_flags, &new_fs))) | ||
| 1535 | goto bad_unshare_cleanup_thread; | ||
| 1536 | if ((err = unshare_namespace(unshare_flags, &new_ns, new_fs))) | ||
| 1537 | goto bad_unshare_cleanup_fs; | ||
| 1538 | if ((err = unshare_sighand(unshare_flags, &new_sigh))) | ||
| 1539 | goto bad_unshare_cleanup_ns; | ||
| 1540 | if ((err = unshare_vm(unshare_flags, &new_mm))) | ||
| 1541 | goto bad_unshare_cleanup_sigh; | ||
| 1542 | if ((err = unshare_fd(unshare_flags, &new_fd))) | ||
| 1543 | goto bad_unshare_cleanup_vm; | ||
| 1544 | if ((err = unshare_semundo(unshare_flags, &new_ulist))) | ||
| 1545 | goto bad_unshare_cleanup_fd; | ||
| 1546 | |||
| 1547 | if (new_fs || new_ns || new_sigh || new_mm || new_fd || new_ulist) { | ||
| 1548 | |||
| 1549 | task_lock(current); | ||
| 1550 | |||
| 1551 | if (new_fs) { | ||
| 1552 | fs = current->fs; | ||
| 1553 | current->fs = new_fs; | ||
| 1554 | new_fs = fs; | ||
| 1555 | } | ||
| 1556 | |||
| 1557 | if (new_ns) { | ||
| 1558 | ns = current->namespace; | ||
| 1559 | current->namespace = new_ns; | ||
| 1560 | new_ns = ns; | ||
| 1561 | } | ||
| 1562 | |||
| 1563 | if (new_sigh) { | ||
| 1564 | sigh = current->sighand; | ||
| 1565 | current->sighand = new_sigh; | ||
| 1566 | new_sigh = sigh; | ||
| 1567 | } | ||
| 1568 | |||
| 1569 | if (new_mm) { | ||
| 1570 | mm = current->mm; | ||
| 1571 | active_mm = current->active_mm; | ||
| 1572 | current->mm = new_mm; | ||
| 1573 | current->active_mm = new_mm; | ||
| 1574 | activate_mm(active_mm, new_mm); | ||
| 1575 | new_mm = mm; | ||
| 1576 | } | ||
| 1577 | |||
| 1578 | if (new_fd) { | ||
| 1579 | fd = current->files; | ||
| 1580 | current->files = new_fd; | ||
| 1581 | new_fd = fd; | ||
| 1582 | } | ||
| 1583 | |||
| 1584 | task_unlock(current); | ||
| 1585 | } | ||
| 1586 | |||
| 1587 | bad_unshare_cleanup_fd: | ||
| 1588 | if (new_fd) | ||
| 1589 | put_files_struct(new_fd); | ||
| 1590 | |||
| 1591 | bad_unshare_cleanup_vm: | ||
| 1592 | if (new_mm) | ||
| 1593 | mmput(new_mm); | ||
| 1594 | |||
| 1595 | bad_unshare_cleanup_sigh: | ||
| 1596 | if (new_sigh) | ||
| 1597 | if (atomic_dec_and_test(&new_sigh->count)) | ||
| 1598 | kmem_cache_free(sighand_cachep, new_sigh); | ||
| 1599 | |||
| 1600 | bad_unshare_cleanup_ns: | ||
| 1601 | if (new_ns) | ||
| 1602 | put_namespace(new_ns); | ||
| 1603 | |||
| 1604 | bad_unshare_cleanup_fs: | ||
| 1605 | if (new_fs) | ||
| 1606 | put_fs_struct(new_fs); | ||
| 1607 | |||
| 1608 | bad_unshare_cleanup_thread: | ||
| 1609 | bad_unshare_out: | ||
| 1610 | return err; | ||
| 1611 | } | ||
diff --git a/kernel/intermodule.c b/kernel/intermodule.c index 0cbe633420fb..55b1e5b85db9 100644 --- a/kernel/intermodule.c +++ b/kernel/intermodule.c | |||
| @@ -179,3 +179,6 @@ EXPORT_SYMBOL(inter_module_register); | |||
| 179 | EXPORT_SYMBOL(inter_module_unregister); | 179 | EXPORT_SYMBOL(inter_module_unregister); |
| 180 | EXPORT_SYMBOL(inter_module_get_request); | 180 | EXPORT_SYMBOL(inter_module_get_request); |
| 181 | EXPORT_SYMBOL(inter_module_put); | 181 | EXPORT_SYMBOL(inter_module_put); |
| 182 | |||
| 183 | MODULE_LICENSE("GPL"); | ||
| 184 | |||
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 3ea6325228da..fef1af8a73ce 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
| @@ -344,23 +344,6 @@ void __kprobes kprobe_flush_task(struct task_struct *tk) | |||
| 344 | spin_unlock_irqrestore(&kretprobe_lock, flags); | 344 | spin_unlock_irqrestore(&kretprobe_lock, flags); |
| 345 | } | 345 | } |
| 346 | 346 | ||
| 347 | /* | ||
| 348 | * This kprobe pre_handler is registered with every kretprobe. When probe | ||
| 349 | * hits it will set up the return probe. | ||
| 350 | */ | ||
| 351 | static int __kprobes pre_handler_kretprobe(struct kprobe *p, | ||
| 352 | struct pt_regs *regs) | ||
| 353 | { | ||
| 354 | struct kretprobe *rp = container_of(p, struct kretprobe, kp); | ||
| 355 | unsigned long flags = 0; | ||
| 356 | |||
| 357 | /*TODO: consider to only swap the RA after the last pre_handler fired */ | ||
| 358 | spin_lock_irqsave(&kretprobe_lock, flags); | ||
| 359 | arch_prepare_kretprobe(rp, regs); | ||
| 360 | spin_unlock_irqrestore(&kretprobe_lock, flags); | ||
| 361 | return 0; | ||
| 362 | } | ||
| 363 | |||
| 364 | static inline void free_rp_inst(struct kretprobe *rp) | 347 | static inline void free_rp_inst(struct kretprobe *rp) |
| 365 | { | 348 | { |
| 366 | struct kretprobe_instance *ri; | 349 | struct kretprobe_instance *ri; |
| @@ -578,6 +561,23 @@ void __kprobes unregister_jprobe(struct jprobe *jp) | |||
| 578 | 561 | ||
| 579 | #ifdef ARCH_SUPPORTS_KRETPROBES | 562 | #ifdef ARCH_SUPPORTS_KRETPROBES |
| 580 | 563 | ||
| 564 | /* | ||
| 565 | * This kprobe pre_handler is registered with every kretprobe. When probe | ||
| 566 | * hits it will set up the return probe. | ||
| 567 | */ | ||
| 568 | static int __kprobes pre_handler_kretprobe(struct kprobe *p, | ||
| 569 | struct pt_regs *regs) | ||
| 570 | { | ||
| 571 | struct kretprobe *rp = container_of(p, struct kretprobe, kp); | ||
| 572 | unsigned long flags = 0; | ||
| 573 | |||
| 574 | /*TODO: consider to only swap the RA after the last pre_handler fired */ | ||
| 575 | spin_lock_irqsave(&kretprobe_lock, flags); | ||
| 576 | arch_prepare_kretprobe(rp, regs); | ||
| 577 | spin_unlock_irqrestore(&kretprobe_lock, flags); | ||
| 578 | return 0; | ||
| 579 | } | ||
| 580 | |||
| 581 | int __kprobes register_kretprobe(struct kretprobe *rp) | 581 | int __kprobes register_kretprobe(struct kretprobe *rp) |
| 582 | { | 582 | { |
| 583 | int ret = 0; | 583 | int ret = 0; |
| @@ -631,12 +631,12 @@ void __kprobes unregister_kretprobe(struct kretprobe *rp) | |||
| 631 | unregister_kprobe(&rp->kp); | 631 | unregister_kprobe(&rp->kp); |
| 632 | /* No race here */ | 632 | /* No race here */ |
| 633 | spin_lock_irqsave(&kretprobe_lock, flags); | 633 | spin_lock_irqsave(&kretprobe_lock, flags); |
| 634 | free_rp_inst(rp); | ||
| 635 | while ((ri = get_used_rp_inst(rp)) != NULL) { | 634 | while ((ri = get_used_rp_inst(rp)) != NULL) { |
| 636 | ri->rp = NULL; | 635 | ri->rp = NULL; |
| 637 | hlist_del(&ri->uflist); | 636 | hlist_del(&ri->uflist); |
| 638 | } | 637 | } |
| 639 | spin_unlock_irqrestore(&kretprobe_lock, flags); | 638 | spin_unlock_irqrestore(&kretprobe_lock, flags); |
| 639 | free_rp_inst(rp); | ||
| 640 | } | 640 | } |
| 641 | 641 | ||
| 642 | static int __init init_kprobes(void) | 642 | static int __init init_kprobes(void) |
diff --git a/kernel/module.c b/kernel/module.c index 618ed6e23ecc..5aad477ddc79 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -1670,6 +1670,9 @@ static struct module *load_module(void __user *umod, | |||
| 1670 | goto free_mod; | 1670 | goto free_mod; |
| 1671 | } | 1671 | } |
| 1672 | 1672 | ||
| 1673 | /* Userspace could have altered the string after the strlen_user() */ | ||
| 1674 | args[arglen - 1] = '\0'; | ||
| 1675 | |||
| 1673 | if (find_module(mod->name)) { | 1676 | if (find_module(mod->name)) { |
| 1674 | err = -EEXIST; | 1677 | err = -EEXIST; |
| 1675 | goto free_mod; | 1678 | goto free_mod; |
| @@ -2092,7 +2095,8 @@ static unsigned long mod_find_symname(struct module *mod, const char *name) | |||
| 2092 | unsigned int i; | 2095 | unsigned int i; |
| 2093 | 2096 | ||
| 2094 | for (i = 0; i < mod->num_symtab; i++) | 2097 | for (i = 0; i < mod->num_symtab; i++) |
| 2095 | if (strcmp(name, mod->strtab+mod->symtab[i].st_name) == 0) | 2098 | if (strcmp(name, mod->strtab+mod->symtab[i].st_name) == 0 && |
| 2099 | mod->symtab[i].st_info != 'U') | ||
| 2096 | return mod->symtab[i].st_value; | 2100 | return mod->symtab[i].st_value; |
| 2097 | return 0; | 2101 | return 0; |
| 2098 | } | 2102 | } |
diff --git a/kernel/power/console.c b/kernel/power/console.c index 579d239d129f..623786d44159 100644 --- a/kernel/power/console.c +++ b/kernel/power/console.c | |||
| @@ -9,7 +9,9 @@ | |||
| 9 | #include <linux/console.h> | 9 | #include <linux/console.h> |
| 10 | #include "power.h" | 10 | #include "power.h" |
| 11 | 11 | ||
| 12 | #ifdef SUSPEND_CONSOLE | 12 | #if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) |
| 13 | #define SUSPEND_CONSOLE (MAX_NR_CONSOLES-1) | ||
| 14 | |||
| 13 | static int orig_fgconsole, orig_kmsg; | 15 | static int orig_fgconsole, orig_kmsg; |
| 14 | 16 | ||
| 15 | int pm_prepare_console(void) | 17 | int pm_prepare_console(void) |
diff --git a/kernel/power/power.h b/kernel/power/power.h index d8f0d1a76bae..388dba680841 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h | |||
| @@ -1,14 +1,6 @@ | |||
| 1 | #include <linux/suspend.h> | 1 | #include <linux/suspend.h> |
| 2 | #include <linux/utsname.h> | 2 | #include <linux/utsname.h> |
| 3 | 3 | ||
| 4 | /* With SUSPEND_CONSOLE defined suspend looks *really* cool, but | ||
| 5 | we probably do not take enough locks for switching consoles, etc, | ||
| 6 | so bad things might happen. | ||
| 7 | */ | ||
| 8 | #if defined(CONFIG_VT) && defined(CONFIG_VT_CONSOLE) | ||
| 9 | #define SUSPEND_CONSOLE (MAX_NR_CONSOLES-1) | ||
| 10 | #endif | ||
| 11 | |||
| 12 | struct swsusp_info { | 4 | struct swsusp_info { |
| 13 | struct new_utsname uts; | 5 | struct new_utsname uts; |
| 14 | u32 version_code; | 6 | u32 version_code; |
| @@ -42,14 +34,6 @@ static struct subsys_attribute _name##_attr = { \ | |||
| 42 | 34 | ||
| 43 | extern struct subsystem power_subsys; | 35 | extern struct subsystem power_subsys; |
| 44 | 36 | ||
| 45 | #ifdef SUSPEND_CONSOLE | ||
| 46 | extern int pm_prepare_console(void); | ||
| 47 | extern void pm_restore_console(void); | ||
| 48 | #else | ||
| 49 | static int pm_prepare_console(void) { return 0; } | ||
| 50 | static void pm_restore_console(void) {} | ||
| 51 | #endif | ||
| 52 | |||
| 53 | /* References to section boundaries */ | 37 | /* References to section boundaries */ |
| 54 | extern const void __nosave_begin, __nosave_end; | 38 | extern const void __nosave_begin, __nosave_end; |
| 55 | 39 | ||
diff --git a/kernel/power/swsusp.c b/kernel/power/swsusp.c index 59c91c148e82..4e90905f0e87 100644 --- a/kernel/power/swsusp.c +++ b/kernel/power/swsusp.c | |||
| @@ -743,7 +743,6 @@ static int submit(int rw, pgoff_t page_off, void *page) | |||
| 743 | if (!bio) | 743 | if (!bio) |
| 744 | return -ENOMEM; | 744 | return -ENOMEM; |
| 745 | bio->bi_sector = page_off * (PAGE_SIZE >> 9); | 745 | bio->bi_sector = page_off * (PAGE_SIZE >> 9); |
| 746 | bio_get(bio); | ||
| 747 | bio->bi_bdev = resume_bdev; | 746 | bio->bi_bdev = resume_bdev; |
| 748 | bio->bi_end_io = end_io; | 747 | bio->bi_end_io = end_io; |
| 749 | 748 | ||
| @@ -753,14 +752,13 @@ static int submit(int rw, pgoff_t page_off, void *page) | |||
| 753 | goto Done; | 752 | goto Done; |
| 754 | } | 753 | } |
| 755 | 754 | ||
| 756 | if (rw == WRITE) | ||
| 757 | bio_set_pages_dirty(bio); | ||
| 758 | 755 | ||
| 759 | atomic_set(&io_done, 1); | 756 | atomic_set(&io_done, 1); |
| 760 | submit_bio(rw | (1 << BIO_RW_SYNC), bio); | 757 | submit_bio(rw | (1 << BIO_RW_SYNC), bio); |
| 761 | while (atomic_read(&io_done)) | 758 | while (atomic_read(&io_done)) |
| 762 | yield(); | 759 | yield(); |
| 763 | 760 | if (rw == READ) | |
| 761 | bio_set_pages_dirty(bio); | ||
| 764 | Done: | 762 | Done: |
| 765 | bio_put(bio); | 763 | bio_put(bio); |
| 766 | return error; | 764 | return error; |
diff --git a/kernel/sched.c b/kernel/sched.c index f77f23f8f479..bc38804e40dd 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
| @@ -5551,13 +5551,15 @@ static void calibrate_migration_costs(const cpumask_t *cpu_map) | |||
| 5551 | -1 | 5551 | -1 |
| 5552 | #endif | 5552 | #endif |
| 5553 | ); | 5553 | ); |
| 5554 | printk("migration_cost="); | 5554 | if (system_state == SYSTEM_BOOTING) { |
| 5555 | for (distance = 0; distance <= max_distance; distance++) { | 5555 | printk("migration_cost="); |
| 5556 | if (distance) | 5556 | for (distance = 0; distance <= max_distance; distance++) { |
| 5557 | printk(","); | 5557 | if (distance) |
| 5558 | printk("%ld", (long)migration_cost[distance] / 1000); | 5558 | printk(","); |
| 5559 | printk("%ld", (long)migration_cost[distance] / 1000); | ||
| 5560 | } | ||
| 5561 | printk("\n"); | ||
| 5559 | } | 5562 | } |
| 5560 | printk("\n"); | ||
| 5561 | j1 = jiffies; | 5563 | j1 = jiffies; |
| 5562 | if (migration_debug) | 5564 | if (migration_debug) |
| 5563 | printk("migration: %ld seconds\n", (j1-j0)/HZ); | 5565 | printk("migration: %ld seconds\n", (j1-j0)/HZ); |
| @@ -6109,7 +6111,7 @@ void __init sched_init(void) | |||
| 6109 | runqueue_t *rq; | 6111 | runqueue_t *rq; |
| 6110 | int i, j, k; | 6112 | int i, j, k; |
| 6111 | 6113 | ||
| 6112 | for (i = 0; i < NR_CPUS; i++) { | 6114 | for_each_cpu(i) { |
| 6113 | prio_array_t *array; | 6115 | prio_array_t *array; |
| 6114 | 6116 | ||
| 6115 | rq = cpu_rq(i); | 6117 | rq = cpu_rq(i); |
diff --git a/kernel/signal.c b/kernel/signal.c index d3efafd8109a..b373fc2420da 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
| @@ -283,7 +283,7 @@ static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags, | |||
| 283 | return(q); | 283 | return(q); |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | static inline void __sigqueue_free(struct sigqueue *q) | 286 | static void __sigqueue_free(struct sigqueue *q) |
| 287 | { | 287 | { |
| 288 | if (q->flags & SIGQUEUE_PREALLOC) | 288 | if (q->flags & SIGQUEUE_PREALLOC) |
| 289 | return; | 289 | return; |
diff --git a/kernel/sys.c b/kernel/sys.c index 0929c698affc..f91218a5463e 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
| @@ -428,7 +428,7 @@ void kernel_kexec(void) | |||
| 428 | { | 428 | { |
| 429 | #ifdef CONFIG_KEXEC | 429 | #ifdef CONFIG_KEXEC |
| 430 | struct kimage *image; | 430 | struct kimage *image; |
| 431 | image = xchg(&kexec_image, 0); | 431 | image = xchg(&kexec_image, NULL); |
| 432 | if (!image) { | 432 | if (!image) { |
| 433 | return; | 433 | return; |
| 434 | } | 434 | } |
diff --git a/kernel/time.c b/kernel/time.c index 1f23e683d6aa..804539165d8b 100644 --- a/kernel/time.c +++ b/kernel/time.c | |||
| @@ -637,15 +637,16 @@ void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec) | |||
| 637 | * | 637 | * |
| 638 | * Returns the timespec representation of the nsec parameter. | 638 | * Returns the timespec representation of the nsec parameter. |
| 639 | */ | 639 | */ |
| 640 | inline struct timespec ns_to_timespec(const nsec_t nsec) | 640 | struct timespec ns_to_timespec(const nsec_t nsec) |
| 641 | { | 641 | { |
| 642 | struct timespec ts; | 642 | struct timespec ts; |
| 643 | 643 | ||
| 644 | if (nsec) | 644 | if (!nsec) |
| 645 | ts.tv_sec = div_long_long_rem_signed(nsec, NSEC_PER_SEC, | 645 | return (struct timespec) {0, 0}; |
| 646 | &ts.tv_nsec); | 646 | |
| 647 | else | 647 | ts.tv_sec = div_long_long_rem_signed(nsec, NSEC_PER_SEC, &ts.tv_nsec); |
| 648 | ts.tv_sec = ts.tv_nsec = 0; | 648 | if (unlikely(nsec < 0)) |
| 649 | set_normalized_timespec(&ts, ts.tv_sec, ts.tv_nsec); | ||
| 649 | 650 | ||
| 650 | return ts; | 651 | return ts; |
| 651 | } | 652 | } |
diff --git a/kernel/timer.c b/kernel/timer.c index 4f1cb0ab5251..b9dad3994676 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
| @@ -495,7 +495,7 @@ unsigned long next_timer_interrupt(void) | |||
| 495 | base = &__get_cpu_var(tvec_bases); | 495 | base = &__get_cpu_var(tvec_bases); |
| 496 | spin_lock(&base->t_base.lock); | 496 | spin_lock(&base->t_base.lock); |
| 497 | expires = base->timer_jiffies + (LONG_MAX >> 1); | 497 | expires = base->timer_jiffies + (LONG_MAX >> 1); |
| 498 | list = 0; | 498 | list = NULL; |
| 499 | 499 | ||
| 500 | /* Look for timer events in tv1. */ | 500 | /* Look for timer events in tv1. */ |
| 501 | j = base->timer_jiffies & TVR_MASK; | 501 | j = base->timer_jiffies & TVR_MASK; |
diff --git a/lib/int_sqrt.c b/lib/int_sqrt.c index a5d2cdc5684c..fd355a99327c 100644 --- a/lib/int_sqrt.c +++ b/lib/int_sqrt.c | |||
| @@ -15,7 +15,7 @@ unsigned long int_sqrt(unsigned long x) | |||
| 15 | op = x; | 15 | op = x; |
| 16 | res = 0; | 16 | res = 0; |
| 17 | 17 | ||
| 18 | one = 1 << 30; | 18 | one = 1UL << (BITS_PER_LONG - 2); |
| 19 | while (one > op) | 19 | while (one > op) |
| 20 | one >>= 2; | 20 | one >>= 2; |
| 21 | 21 | ||
diff --git a/lib/kobject.c b/lib/kobject.c index 7a0e6809490d..efe67fa96a71 100644 --- a/lib/kobject.c +++ b/lib/kobject.c | |||
| @@ -72,6 +72,8 @@ static int get_kobj_path_length(struct kobject *kobj) | |||
| 72 | * Add 1 to strlen for leading '/' of each level. | 72 | * Add 1 to strlen for leading '/' of each level. |
| 73 | */ | 73 | */ |
| 74 | do { | 74 | do { |
| 75 | if (kobject_name(parent) == NULL) | ||
| 76 | return 0; | ||
| 75 | length += strlen(kobject_name(parent)) + 1; | 77 | length += strlen(kobject_name(parent)) + 1; |
| 76 | parent = parent->parent; | 78 | parent = parent->parent; |
| 77 | } while (parent); | 79 | } while (parent); |
| @@ -107,6 +109,8 @@ char *kobject_get_path(struct kobject *kobj, gfp_t gfp_mask) | |||
| 107 | int len; | 109 | int len; |
| 108 | 110 | ||
| 109 | len = get_kobj_path_length(kobj); | 111 | len = get_kobj_path_length(kobj); |
| 112 | if (len == 0) | ||
| 113 | return NULL; | ||
| 110 | path = kmalloc(len, gfp_mask); | 114 | path = kmalloc(len, gfp_mask); |
| 111 | if (!path) | 115 | if (!path) |
| 112 | return NULL; | 116 | return NULL; |
| @@ -162,6 +166,11 @@ int kobject_add(struct kobject * kobj) | |||
| 162 | return -ENOENT; | 166 | return -ENOENT; |
| 163 | if (!kobj->k_name) | 167 | if (!kobj->k_name) |
| 164 | kobj->k_name = kobj->name; | 168 | kobj->k_name = kobj->name; |
| 169 | if (!kobj->k_name) { | ||
| 170 | pr_debug("kobject attempted to be registered with no name!\n"); | ||
| 171 | WARN_ON(1); | ||
| 172 | return -EINVAL; | ||
| 173 | } | ||
| 165 | parent = kobject_get(kobj->parent); | 174 | parent = kobject_get(kobj->parent); |
| 166 | 175 | ||
| 167 | pr_debug("kobject %s: registering. parent: %s, set: %s\n", | 176 | pr_debug("kobject %s: registering. parent: %s, set: %s\n", |
diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c index f56e27ae9d52..1b1985c136ec 100644 --- a/lib/kobject_uevent.c +++ b/lib/kobject_uevent.c | |||
| @@ -22,7 +22,7 @@ | |||
| 22 | #include <linux/kobject.h> | 22 | #include <linux/kobject.h> |
| 23 | #include <net/sock.h> | 23 | #include <net/sock.h> |
| 24 | 24 | ||
| 25 | #define BUFFER_SIZE 1024 /* buffer for the variables */ | 25 | #define BUFFER_SIZE 2048 /* buffer for the variables */ |
| 26 | #define NUM_ENVP 32 /* number of env pointers */ | 26 | #define NUM_ENVP 32 /* number of env pointers */ |
| 27 | 27 | ||
| 28 | #if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET) | 28 | #if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET) |
diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c index c8bb8cc899d7..d8b6bb419d49 100644 --- a/lib/spinlock_debug.c +++ b/lib/spinlock_debug.c | |||
| @@ -72,9 +72,9 @@ static void __spin_lock_debug(spinlock_t *lock) | |||
| 72 | 72 | ||
| 73 | for (;;) { | 73 | for (;;) { |
| 74 | for (i = 0; i < loops_per_jiffy * HZ; i++) { | 74 | for (i = 0; i < loops_per_jiffy * HZ; i++) { |
| 75 | cpu_relax(); | ||
| 76 | if (__raw_spin_trylock(&lock->raw_lock)) | 75 | if (__raw_spin_trylock(&lock->raw_lock)) |
| 77 | return; | 76 | return; |
| 77 | __delay(1); | ||
| 78 | } | 78 | } |
| 79 | /* lockup suspected: */ | 79 | /* lockup suspected: */ |
| 80 | if (print_once) { | 80 | if (print_once) { |
| @@ -144,9 +144,9 @@ static void __read_lock_debug(rwlock_t *lock) | |||
| 144 | 144 | ||
| 145 | for (;;) { | 145 | for (;;) { |
| 146 | for (i = 0; i < loops_per_jiffy * HZ; i++) { | 146 | for (i = 0; i < loops_per_jiffy * HZ; i++) { |
| 147 | cpu_relax(); | ||
| 148 | if (__raw_read_trylock(&lock->raw_lock)) | 147 | if (__raw_read_trylock(&lock->raw_lock)) |
| 149 | return; | 148 | return; |
| 149 | __delay(1); | ||
| 150 | } | 150 | } |
| 151 | /* lockup suspected: */ | 151 | /* lockup suspected: */ |
| 152 | if (print_once) { | 152 | if (print_once) { |
| @@ -217,9 +217,9 @@ static void __write_lock_debug(rwlock_t *lock) | |||
| 217 | 217 | ||
| 218 | for (;;) { | 218 | for (;;) { |
| 219 | for (i = 0; i < loops_per_jiffy * HZ; i++) { | 219 | for (i = 0; i < loops_per_jiffy * HZ; i++) { |
| 220 | cpu_relax(); | ||
| 221 | if (__raw_write_trylock(&lock->raw_lock)) | 220 | if (__raw_write_trylock(&lock->raw_lock)) |
| 222 | return; | 221 | return; |
| 222 | __delay(1); | ||
| 223 | } | 223 | } |
| 224 | /* lockup suspected: */ | 224 | /* lockup suspected: */ |
| 225 | if (print_once) { | 225 | if (print_once) { |
diff --git a/lib/ts_bm.c b/lib/ts_bm.c index 8a8b3a16133e..c4c1ac5fbd1a 100644 --- a/lib/ts_bm.c +++ b/lib/ts_bm.c | |||
| @@ -94,10 +94,28 @@ next: bs = bm->bad_shift[text[shift-i]]; | |||
| 94 | return UINT_MAX; | 94 | return UINT_MAX; |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | static int subpattern(u8 *pattern, int i, int j, int g) | ||
| 98 | { | ||
| 99 | int x = i+g-1, y = j+g-1, ret = 0; | ||
| 100 | |||
| 101 | while(pattern[x--] == pattern[y--]) { | ||
| 102 | if (y < 0) { | ||
| 103 | ret = 1; | ||
| 104 | break; | ||
| 105 | } | ||
| 106 | if (--g == 0) { | ||
| 107 | ret = pattern[i-1] != pattern[j-1]; | ||
| 108 | break; | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 112 | return ret; | ||
| 113 | } | ||
| 114 | |||
| 97 | static void compute_prefix_tbl(struct ts_bm *bm, const u8 *pattern, | 115 | static void compute_prefix_tbl(struct ts_bm *bm, const u8 *pattern, |
| 98 | unsigned int len) | 116 | unsigned int len) |
| 99 | { | 117 | { |
| 100 | int i, j, ended, l[ASIZE]; | 118 | int i, j, g; |
| 101 | 119 | ||
| 102 | for (i = 0; i < ASIZE; i++) | 120 | for (i = 0; i < ASIZE; i++) |
| 103 | bm->bad_shift[i] = len; | 121 | bm->bad_shift[i] = len; |
| @@ -106,23 +124,15 @@ static void compute_prefix_tbl(struct ts_bm *bm, const u8 *pattern, | |||
| 106 | 124 | ||
| 107 | /* Compute the good shift array, used to match reocurrences | 125 | /* Compute the good shift array, used to match reocurrences |
| 108 | * of a subpattern */ | 126 | * of a subpattern */ |
| 109 | for (i = 1; i < bm->patlen; i++) { | ||
| 110 | for (j = 0; j < bm->patlen && bm->pattern[bm->patlen - 1 - j] | ||
| 111 | == bm->pattern[bm->patlen - 1 - i - j]; j++); | ||
| 112 | l[i] = j; | ||
| 113 | } | ||
| 114 | |||
| 115 | bm->good_shift[0] = 1; | 127 | bm->good_shift[0] = 1; |
| 116 | for (i = 1; i < bm->patlen; i++) | 128 | for (i = 1; i < bm->patlen; i++) |
| 117 | bm->good_shift[i] = bm->patlen; | 129 | bm->good_shift[i] = bm->patlen; |
| 118 | for (i = bm->patlen - 1; i > 0; i--) | 130 | for (i = bm->patlen-1, g = 1; i > 0; g++, i--) { |
| 119 | bm->good_shift[l[i]] = i; | 131 | for (j = i-1; j >= 1-g ; j--) |
| 120 | ended = 0; | 132 | if (subpattern(bm->pattern, i, j, g)) { |
| 121 | for (i = 0; i < bm->patlen; i++) { | 133 | bm->good_shift[g] = bm->patlen-j-g; |
| 122 | if (l[i] == bm->patlen - 1 - i) | 134 | break; |
| 123 | ended = i; | 135 | } |
| 124 | if (ended) | ||
| 125 | bm->good_shift[i] = ended; | ||
| 126 | } | 136 | } |
| 127 | } | 137 | } |
| 128 | 138 | ||
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index b21d78c941b5..67f29516662a 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
| @@ -107,7 +107,7 @@ struct page *alloc_huge_page(struct vm_area_struct *vma, unsigned long addr) | |||
| 107 | set_page_count(page, 1); | 107 | set_page_count(page, 1); |
| 108 | page[1].mapping = (void *)free_huge_page; | 108 | page[1].mapping = (void *)free_huge_page; |
| 109 | for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); ++i) | 109 | for (i = 0; i < (HPAGE_SIZE/PAGE_SIZE); ++i) |
| 110 | clear_highpage(&page[i]); | 110 | clear_user_highpage(&page[i], addr); |
| 111 | return page; | 111 | return page; |
| 112 | } | 112 | } |
| 113 | 113 | ||
| @@ -391,12 +391,7 @@ static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma, | |||
| 391 | 391 | ||
| 392 | if (!new_page) { | 392 | if (!new_page) { |
| 393 | page_cache_release(old_page); | 393 | page_cache_release(old_page); |
| 394 | 394 | return VM_FAULT_OOM; | |
| 395 | /* Logically this is OOM, not a SIGBUS, but an OOM | ||
| 396 | * could cause the kernel to go killing other | ||
| 397 | * processes which won't help the hugepage situation | ||
| 398 | * at all (?) */ | ||
| 399 | return VM_FAULT_SIGBUS; | ||
| 400 | } | 395 | } |
| 401 | 396 | ||
| 402 | spin_unlock(&mm->page_table_lock); | 397 | spin_unlock(&mm->page_table_lock); |
| @@ -444,6 +439,7 @@ retry: | |||
| 444 | page = alloc_huge_page(vma, address); | 439 | page = alloc_huge_page(vma, address); |
| 445 | if (!page) { | 440 | if (!page) { |
| 446 | hugetlb_put_quota(mapping); | 441 | hugetlb_put_quota(mapping); |
| 442 | ret = VM_FAULT_OOM; | ||
| 447 | goto out; | 443 | goto out; |
| 448 | } | 444 | } |
| 449 | 445 | ||
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 27da6d5c77ba..3bd7fb7e4b75 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
| @@ -1159,6 +1159,7 @@ static inline unsigned interleave_nid(struct mempolicy *pol, | |||
| 1159 | return interleave_nodes(pol); | 1159 | return interleave_nodes(pol); |
| 1160 | } | 1160 | } |
| 1161 | 1161 | ||
| 1162 | #ifdef CONFIG_HUGETLBFS | ||
| 1162 | /* Return a zonelist suitable for a huge page allocation. */ | 1163 | /* Return a zonelist suitable for a huge page allocation. */ |
| 1163 | struct zonelist *huge_zonelist(struct vm_area_struct *vma, unsigned long addr) | 1164 | struct zonelist *huge_zonelist(struct vm_area_struct *vma, unsigned long addr) |
| 1164 | { | 1165 | { |
| @@ -1172,6 +1173,7 @@ struct zonelist *huge_zonelist(struct vm_area_struct *vma, unsigned long addr) | |||
| 1172 | } | 1173 | } |
| 1173 | return zonelist_policy(GFP_HIGHUSER, pol); | 1174 | return zonelist_policy(GFP_HIGHUSER, pol); |
| 1174 | } | 1175 | } |
| 1176 | #endif | ||
| 1175 | 1177 | ||
| 1176 | /* Allocate a page in interleaved policy. | 1178 | /* Allocate a page in interleaved policy. |
| 1177 | Own path because it needs to do special accounting. */ | 1179 | Own path because it needs to do special accounting. */ |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 44b4eb4202d9..dde04ff4be31 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
| @@ -1213,18 +1213,21 @@ static void __get_page_state(struct page_state *ret, int nr, cpumask_t *cpumask) | |||
| 1213 | { | 1213 | { |
| 1214 | int cpu = 0; | 1214 | int cpu = 0; |
| 1215 | 1215 | ||
| 1216 | memset(ret, 0, sizeof(*ret)); | 1216 | memset(ret, 0, nr * sizeof(unsigned long)); |
| 1217 | cpus_and(*cpumask, *cpumask, cpu_online_map); | 1217 | cpus_and(*cpumask, *cpumask, cpu_online_map); |
| 1218 | 1218 | ||
| 1219 | cpu = first_cpu(*cpumask); | 1219 | cpu = first_cpu(*cpumask); |
| 1220 | while (cpu < NR_CPUS) { | 1220 | while (cpu < NR_CPUS) { |
| 1221 | unsigned long *in, *out, off; | 1221 | unsigned long *in, *out, off; |
| 1222 | 1222 | ||
| 1223 | if (!cpu_isset(cpu, *cpumask)) | ||
| 1224 | continue; | ||
| 1225 | |||
| 1223 | in = (unsigned long *)&per_cpu(page_states, cpu); | 1226 | in = (unsigned long *)&per_cpu(page_states, cpu); |
| 1224 | 1227 | ||
| 1225 | cpu = next_cpu(cpu, *cpumask); | 1228 | cpu = next_cpu(cpu, *cpumask); |
| 1226 | 1229 | ||
| 1227 | if (cpu < NR_CPUS) | 1230 | if (likely(cpu < NR_CPUS)) |
| 1228 | prefetch(&per_cpu(page_states, cpu)); | 1231 | prefetch(&per_cpu(page_states, cpu)); |
| 1229 | 1232 | ||
| 1230 | out = (unsigned long *)ret; | 1233 | out = (unsigned long *)ret; |
| @@ -1886,8 +1889,7 @@ static void setup_pagelist_highmark(struct per_cpu_pageset *p, | |||
| 1886 | * not check if the processor is online before following the pageset pointer. | 1889 | * not check if the processor is online before following the pageset pointer. |
| 1887 | * Other parts of the kernel may not check if the zone is available. | 1890 | * Other parts of the kernel may not check if the zone is available. |
| 1888 | */ | 1891 | */ |
| 1889 | static struct per_cpu_pageset | 1892 | static struct per_cpu_pageset boot_pageset[NR_CPUS]; |
| 1890 | boot_pageset[NR_CPUS]; | ||
| 1891 | 1893 | ||
| 1892 | /* | 1894 | /* |
| 1893 | * Dynamically allocate memory for the | 1895 | * Dynamically allocate memory for the |
| @@ -294,6 +294,7 @@ struct kmem_list3 { | |||
| 294 | unsigned long next_reap; | 294 | unsigned long next_reap; |
| 295 | int free_touched; | 295 | int free_touched; |
| 296 | unsigned int free_limit; | 296 | unsigned int free_limit; |
| 297 | unsigned int colour_next; /* Per-node cache coloring */ | ||
| 297 | spinlock_t list_lock; | 298 | spinlock_t list_lock; |
| 298 | struct array_cache *shared; /* shared per node */ | 299 | struct array_cache *shared; /* shared per node */ |
| 299 | struct array_cache **alien; /* on other nodes */ | 300 | struct array_cache **alien; /* on other nodes */ |
| @@ -344,6 +345,7 @@ static void kmem_list3_init(struct kmem_list3 *parent) | |||
| 344 | INIT_LIST_HEAD(&parent->slabs_free); | 345 | INIT_LIST_HEAD(&parent->slabs_free); |
| 345 | parent->shared = NULL; | 346 | parent->shared = NULL; |
| 346 | parent->alien = NULL; | 347 | parent->alien = NULL; |
| 348 | parent->colour_next = 0; | ||
| 347 | spin_lock_init(&parent->list_lock); | 349 | spin_lock_init(&parent->list_lock); |
| 348 | parent->free_objects = 0; | 350 | parent->free_objects = 0; |
| 349 | parent->free_touched = 0; | 351 | parent->free_touched = 0; |
| @@ -390,7 +392,6 @@ struct kmem_cache { | |||
| 390 | 392 | ||
| 391 | size_t colour; /* cache colouring range */ | 393 | size_t colour; /* cache colouring range */ |
| 392 | unsigned int colour_off; /* colour offset */ | 394 | unsigned int colour_off; /* colour offset */ |
| 393 | unsigned int colour_next; /* cache colouring */ | ||
| 394 | struct kmem_cache *slabp_cache; | 395 | struct kmem_cache *slabp_cache; |
| 395 | unsigned int slab_size; | 396 | unsigned int slab_size; |
| 396 | unsigned int dflags; /* dynamic flags */ | 397 | unsigned int dflags; /* dynamic flags */ |
| @@ -883,14 +884,14 @@ static void __drain_alien_cache(struct kmem_cache *cachep, | |||
| 883 | } | 884 | } |
| 884 | } | 885 | } |
| 885 | 886 | ||
| 886 | static void drain_alien_cache(struct kmem_cache *cachep, struct kmem_list3 *l3) | 887 | static void drain_alien_cache(struct kmem_cache *cachep, struct array_cache **alien) |
| 887 | { | 888 | { |
| 888 | int i = 0; | 889 | int i = 0; |
| 889 | struct array_cache *ac; | 890 | struct array_cache *ac; |
| 890 | unsigned long flags; | 891 | unsigned long flags; |
| 891 | 892 | ||
| 892 | for_each_online_node(i) { | 893 | for_each_online_node(i) { |
| 893 | ac = l3->alien[i]; | 894 | ac = alien[i]; |
| 894 | if (ac) { | 895 | if (ac) { |
| 895 | spin_lock_irqsave(&ac->lock, flags); | 896 | spin_lock_irqsave(&ac->lock, flags); |
| 896 | __drain_alien_cache(cachep, ac, i); | 897 | __drain_alien_cache(cachep, ac, i); |
| @@ -899,9 +900,18 @@ static void drain_alien_cache(struct kmem_cache *cachep, struct kmem_list3 *l3) | |||
| 899 | } | 900 | } |
| 900 | } | 901 | } |
| 901 | #else | 902 | #else |
| 902 | #define alloc_alien_cache(node, limit) do { } while (0) | 903 | |
| 903 | #define free_alien_cache(ac_ptr) do { } while (0) | 904 | #define drain_alien_cache(cachep, alien) do { } while (0) |
| 904 | #define drain_alien_cache(cachep, l3) do { } while (0) | 905 | |
| 906 | static inline struct array_cache **alloc_alien_cache(int node, int limit) | ||
| 907 | { | ||
| 908 | return (struct array_cache **) 0x01020304ul; | ||
| 909 | } | ||
| 910 | |||
| 911 | static inline void free_alien_cache(struct array_cache **ac_ptr) | ||
| 912 | { | ||
| 913 | } | ||
| 914 | |||
| 905 | #endif | 915 | #endif |
| 906 | 916 | ||
| 907 | static int __devinit cpuup_callback(struct notifier_block *nfb, | 917 | static int __devinit cpuup_callback(struct notifier_block *nfb, |
| @@ -935,6 +945,11 @@ static int __devinit cpuup_callback(struct notifier_block *nfb, | |||
| 935 | l3->next_reap = jiffies + REAPTIMEOUT_LIST3 + | 945 | l3->next_reap = jiffies + REAPTIMEOUT_LIST3 + |
| 936 | ((unsigned long)cachep) % REAPTIMEOUT_LIST3; | 946 | ((unsigned long)cachep) % REAPTIMEOUT_LIST3; |
| 937 | 947 | ||
| 948 | /* | ||
| 949 | * The l3s don't come and go as CPUs come and | ||
| 950 | * go. cache_chain_mutex is sufficient | ||
| 951 | * protection here. | ||
| 952 | */ | ||
| 938 | cachep->nodelists[node] = l3; | 953 | cachep->nodelists[node] = l3; |
| 939 | } | 954 | } |
| 940 | 955 | ||
| @@ -949,26 +964,46 @@ static int __devinit cpuup_callback(struct notifier_block *nfb, | |||
| 949 | & array cache's */ | 964 | & array cache's */ |
| 950 | list_for_each_entry(cachep, &cache_chain, next) { | 965 | list_for_each_entry(cachep, &cache_chain, next) { |
| 951 | struct array_cache *nc; | 966 | struct array_cache *nc; |
| 967 | struct array_cache *shared; | ||
| 968 | struct array_cache **alien; | ||
| 952 | 969 | ||
| 953 | nc = alloc_arraycache(node, cachep->limit, | 970 | nc = alloc_arraycache(node, cachep->limit, |
| 954 | cachep->batchcount); | 971 | cachep->batchcount); |
| 955 | if (!nc) | 972 | if (!nc) |
| 956 | goto bad; | 973 | goto bad; |
| 974 | shared = alloc_arraycache(node, | ||
| 975 | cachep->shared * cachep->batchcount, | ||
| 976 | 0xbaadf00d); | ||
| 977 | if (!shared) | ||
| 978 | goto bad; | ||
| 979 | |||
| 980 | alien = alloc_alien_cache(node, cachep->limit); | ||
| 981 | if (!alien) | ||
| 982 | goto bad; | ||
| 957 | cachep->array[cpu] = nc; | 983 | cachep->array[cpu] = nc; |
| 958 | 984 | ||
| 959 | l3 = cachep->nodelists[node]; | 985 | l3 = cachep->nodelists[node]; |
| 960 | BUG_ON(!l3); | 986 | BUG_ON(!l3); |
| 961 | if (!l3->shared) { | ||
| 962 | if (!(nc = alloc_arraycache(node, | ||
| 963 | cachep->shared * | ||
| 964 | cachep->batchcount, | ||
| 965 | 0xbaadf00d))) | ||
| 966 | goto bad; | ||
| 967 | 987 | ||
| 968 | /* we are serialised from CPU_DEAD or | 988 | spin_lock_irq(&l3->list_lock); |
| 969 | CPU_UP_CANCELLED by the cpucontrol lock */ | 989 | if (!l3->shared) { |
| 970 | l3->shared = nc; | 990 | /* |
| 991 | * We are serialised from CPU_DEAD or | ||
| 992 | * CPU_UP_CANCELLED by the cpucontrol lock | ||
| 993 | */ | ||
| 994 | l3->shared = shared; | ||
| 995 | shared = NULL; | ||
| 996 | } | ||
| 997 | #ifdef CONFIG_NUMA | ||
| 998 | if (!l3->alien) { | ||
| 999 | l3->alien = alien; | ||
| 1000 | alien = NULL; | ||
| 971 | } | 1001 | } |
| 1002 | #endif | ||
| 1003 | spin_unlock_irq(&l3->list_lock); | ||
| 1004 | |||
| 1005 | kfree(shared); | ||
| 1006 | free_alien_cache(alien); | ||
| 972 | } | 1007 | } |
| 973 | mutex_unlock(&cache_chain_mutex); | 1008 | mutex_unlock(&cache_chain_mutex); |
| 974 | break; | 1009 | break; |
| @@ -977,25 +1012,34 @@ static int __devinit cpuup_callback(struct notifier_block *nfb, | |||
| 977 | break; | 1012 | break; |
| 978 | #ifdef CONFIG_HOTPLUG_CPU | 1013 | #ifdef CONFIG_HOTPLUG_CPU |
| 979 | case CPU_DEAD: | 1014 | case CPU_DEAD: |
| 1015 | /* | ||
| 1016 | * Even if all the cpus of a node are down, we don't free the | ||
| 1017 | * kmem_list3 of any cache. This to avoid a race between | ||
| 1018 | * cpu_down, and a kmalloc allocation from another cpu for | ||
| 1019 | * memory from the node of the cpu going down. The list3 | ||
| 1020 | * structure is usually allocated from kmem_cache_create() and | ||
| 1021 | * gets destroyed at kmem_cache_destroy(). | ||
| 1022 | */ | ||
| 980 | /* fall thru */ | 1023 | /* fall thru */ |
| 981 | case CPU_UP_CANCELED: | 1024 | case CPU_UP_CANCELED: |
| 982 | mutex_lock(&cache_chain_mutex); | 1025 | mutex_lock(&cache_chain_mutex); |
| 983 | 1026 | ||
| 984 | list_for_each_entry(cachep, &cache_chain, next) { | 1027 | list_for_each_entry(cachep, &cache_chain, next) { |
| 985 | struct array_cache *nc; | 1028 | struct array_cache *nc; |
| 1029 | struct array_cache *shared; | ||
| 1030 | struct array_cache **alien; | ||
| 986 | cpumask_t mask; | 1031 | cpumask_t mask; |
| 987 | 1032 | ||
| 988 | mask = node_to_cpumask(node); | 1033 | mask = node_to_cpumask(node); |
| 989 | spin_lock_irq(&cachep->spinlock); | ||
| 990 | /* cpu is dead; no one can alloc from it. */ | 1034 | /* cpu is dead; no one can alloc from it. */ |
| 991 | nc = cachep->array[cpu]; | 1035 | nc = cachep->array[cpu]; |
| 992 | cachep->array[cpu] = NULL; | 1036 | cachep->array[cpu] = NULL; |
| 993 | l3 = cachep->nodelists[node]; | 1037 | l3 = cachep->nodelists[node]; |
| 994 | 1038 | ||
| 995 | if (!l3) | 1039 | if (!l3) |
| 996 | goto unlock_cache; | 1040 | goto free_array_cache; |
| 997 | 1041 | ||
| 998 | spin_lock(&l3->list_lock); | 1042 | spin_lock_irq(&l3->list_lock); |
| 999 | 1043 | ||
| 1000 | /* Free limit for this kmem_list3 */ | 1044 | /* Free limit for this kmem_list3 */ |
| 1001 | l3->free_limit -= cachep->batchcount; | 1045 | l3->free_limit -= cachep->batchcount; |
| @@ -1003,34 +1047,44 @@ static int __devinit cpuup_callback(struct notifier_block *nfb, | |||
| 1003 | free_block(cachep, nc->entry, nc->avail, node); | 1047 | free_block(cachep, nc->entry, nc->avail, node); |
| 1004 | 1048 | ||
| 1005 | if (!cpus_empty(mask)) { | 1049 | if (!cpus_empty(mask)) { |
| 1006 | spin_unlock(&l3->list_lock); | 1050 | spin_unlock_irq(&l3->list_lock); |
| 1007 | goto unlock_cache; | 1051 | goto free_array_cache; |
| 1008 | } | 1052 | } |
| 1009 | 1053 | ||
| 1010 | if (l3->shared) { | 1054 | shared = l3->shared; |
| 1055 | if (shared) { | ||
| 1011 | free_block(cachep, l3->shared->entry, | 1056 | free_block(cachep, l3->shared->entry, |
| 1012 | l3->shared->avail, node); | 1057 | l3->shared->avail, node); |
| 1013 | kfree(l3->shared); | ||
| 1014 | l3->shared = NULL; | 1058 | l3->shared = NULL; |
| 1015 | } | 1059 | } |
| 1016 | if (l3->alien) { | ||
| 1017 | drain_alien_cache(cachep, l3); | ||
| 1018 | free_alien_cache(l3->alien); | ||
| 1019 | l3->alien = NULL; | ||
| 1020 | } | ||
| 1021 | 1060 | ||
| 1022 | /* free slabs belonging to this node */ | 1061 | alien = l3->alien; |
| 1023 | if (__node_shrink(cachep, node)) { | 1062 | l3->alien = NULL; |
| 1024 | cachep->nodelists[node] = NULL; | 1063 | |
| 1025 | spin_unlock(&l3->list_lock); | 1064 | spin_unlock_irq(&l3->list_lock); |
| 1026 | kfree(l3); | 1065 | |
| 1027 | } else { | 1066 | kfree(shared); |
| 1028 | spin_unlock(&l3->list_lock); | 1067 | if (alien) { |
| 1068 | drain_alien_cache(cachep, alien); | ||
| 1069 | free_alien_cache(alien); | ||
| 1029 | } | 1070 | } |
| 1030 | unlock_cache: | 1071 | free_array_cache: |
| 1031 | spin_unlock_irq(&cachep->spinlock); | ||
| 1032 | kfree(nc); | 1072 | kfree(nc); |
| 1033 | } | 1073 | } |
| 1074 | /* | ||
| 1075 | * In the previous loop, all the objects were freed to | ||
| 1076 | * the respective cache's slabs, now we can go ahead and | ||
| 1077 | * shrink each nodelist to its limit. | ||
| 1078 | */ | ||
| 1079 | list_for_each_entry(cachep, &cache_chain, next) { | ||
| 1080 | l3 = cachep->nodelists[node]; | ||
| 1081 | if (!l3) | ||
| 1082 | continue; | ||
| 1083 | spin_lock_irq(&l3->list_lock); | ||
| 1084 | /* free slabs belonging to this node */ | ||
| 1085 | __node_shrink(cachep, node); | ||
| 1086 | spin_unlock_irq(&l3->list_lock); | ||
| 1087 | } | ||
| 1034 | mutex_unlock(&cache_chain_mutex); | 1088 | mutex_unlock(&cache_chain_mutex); |
| 1035 | break; | 1089 | break; |
| 1036 | #endif | 1090 | #endif |
| @@ -1119,7 +1173,6 @@ void __init kmem_cache_init(void) | |||
| 1119 | BUG(); | 1173 | BUG(); |
| 1120 | 1174 | ||
| 1121 | cache_cache.colour = left_over / cache_cache.colour_off; | 1175 | cache_cache.colour = left_over / cache_cache.colour_off; |
| 1122 | cache_cache.colour_next = 0; | ||
| 1123 | cache_cache.slab_size = ALIGN(cache_cache.num * sizeof(kmem_bufctl_t) + | 1176 | cache_cache.slab_size = ALIGN(cache_cache.num * sizeof(kmem_bufctl_t) + |
| 1124 | sizeof(struct slab), cache_line_size()); | 1177 | sizeof(struct slab), cache_line_size()); |
| 1125 | 1178 | ||
| @@ -2011,18 +2064,16 @@ static void drain_cpu_caches(struct kmem_cache *cachep) | |||
| 2011 | 2064 | ||
| 2012 | smp_call_function_all_cpus(do_drain, cachep); | 2065 | smp_call_function_all_cpus(do_drain, cachep); |
| 2013 | check_irq_on(); | 2066 | check_irq_on(); |
| 2014 | spin_lock_irq(&cachep->spinlock); | ||
| 2015 | for_each_online_node(node) { | 2067 | for_each_online_node(node) { |
| 2016 | l3 = cachep->nodelists[node]; | 2068 | l3 = cachep->nodelists[node]; |
| 2017 | if (l3) { | 2069 | if (l3) { |
| 2018 | spin_lock(&l3->list_lock); | 2070 | spin_lock_irq(&l3->list_lock); |
| 2019 | drain_array_locked(cachep, l3->shared, 1, node); | 2071 | drain_array_locked(cachep, l3->shared, 1, node); |
| 2020 | spin_unlock(&l3->list_lock); | 2072 | spin_unlock_irq(&l3->list_lock); |
| 2021 | if (l3->alien) | 2073 | if (l3->alien) |
| 2022 | drain_alien_cache(cachep, l3); | 2074 | drain_alien_cache(cachep, l3->alien); |
| 2023 | } | 2075 | } |
| 2024 | } | 2076 | } |
| 2025 | spin_unlock_irq(&cachep->spinlock); | ||
| 2026 | } | 2077 | } |
| 2027 | 2078 | ||
| 2028 | static int __node_shrink(struct kmem_cache *cachep, int node) | 2079 | static int __node_shrink(struct kmem_cache *cachep, int node) |
| @@ -2324,20 +2375,20 @@ static int cache_grow(struct kmem_cache *cachep, gfp_t flags, int nodeid) | |||
| 2324 | */ | 2375 | */ |
| 2325 | ctor_flags |= SLAB_CTOR_ATOMIC; | 2376 | ctor_flags |= SLAB_CTOR_ATOMIC; |
| 2326 | 2377 | ||
| 2327 | /* About to mess with non-constant members - lock. */ | 2378 | /* Take the l3 list lock to change the colour_next on this node */ |
| 2328 | check_irq_off(); | 2379 | check_irq_off(); |
| 2329 | spin_lock(&cachep->spinlock); | 2380 | l3 = cachep->nodelists[nodeid]; |
| 2381 | spin_lock(&l3->list_lock); | ||
| 2330 | 2382 | ||
| 2331 | /* Get colour for the slab, and cal the next value. */ | 2383 | /* Get colour for the slab, and cal the next value. */ |
| 2332 | offset = cachep->colour_next; | 2384 | offset = l3->colour_next; |
| 2333 | cachep->colour_next++; | 2385 | l3->colour_next++; |
| 2334 | if (cachep->colour_next >= cachep->colour) | 2386 | if (l3->colour_next >= cachep->colour) |
| 2335 | cachep->colour_next = 0; | 2387 | l3->colour_next = 0; |
| 2336 | offset *= cachep->colour_off; | 2388 | spin_unlock(&l3->list_lock); |
| 2337 | 2389 | ||
| 2338 | spin_unlock(&cachep->spinlock); | 2390 | offset *= cachep->colour_off; |
| 2339 | 2391 | ||
| 2340 | check_irq_off(); | ||
| 2341 | if (local_flags & __GFP_WAIT) | 2392 | if (local_flags & __GFP_WAIT) |
| 2342 | local_irq_enable(); | 2393 | local_irq_enable(); |
| 2343 | 2394 | ||
| @@ -2367,7 +2418,6 @@ static int cache_grow(struct kmem_cache *cachep, gfp_t flags, int nodeid) | |||
| 2367 | if (local_flags & __GFP_WAIT) | 2418 | if (local_flags & __GFP_WAIT) |
| 2368 | local_irq_disable(); | 2419 | local_irq_disable(); |
| 2369 | check_irq_off(); | 2420 | check_irq_off(); |
| 2370 | l3 = cachep->nodelists[nodeid]; | ||
| 2371 | spin_lock(&l3->list_lock); | 2421 | spin_lock(&l3->list_lock); |
| 2372 | 2422 | ||
| 2373 | /* Make slab active. */ | 2423 | /* Make slab active. */ |
| @@ -2725,6 +2775,7 @@ static void *__cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int node | |||
| 2725 | BUG_ON(!l3); | 2775 | BUG_ON(!l3); |
| 2726 | 2776 | ||
| 2727 | retry: | 2777 | retry: |
| 2778 | check_irq_off(); | ||
| 2728 | spin_lock(&l3->list_lock); | 2779 | spin_lock(&l3->list_lock); |
| 2729 | entry = l3->slabs_partial.next; | 2780 | entry = l3->slabs_partial.next; |
| 2730 | if (entry == &l3->slabs_partial) { | 2781 | if (entry == &l3->slabs_partial) { |
| @@ -3304,11 +3355,11 @@ static int do_tune_cpucache(struct kmem_cache *cachep, int limit, int batchcount | |||
| 3304 | smp_call_function_all_cpus(do_ccupdate_local, (void *)&new); | 3355 | smp_call_function_all_cpus(do_ccupdate_local, (void *)&new); |
| 3305 | 3356 | ||
| 3306 | check_irq_on(); | 3357 | check_irq_on(); |
| 3307 | spin_lock_irq(&cachep->spinlock); | 3358 | spin_lock(&cachep->spinlock); |
| 3308 | cachep->batchcount = batchcount; | 3359 | cachep->batchcount = batchcount; |
| 3309 | cachep->limit = limit; | 3360 | cachep->limit = limit; |
| 3310 | cachep->shared = shared; | 3361 | cachep->shared = shared; |
| 3311 | spin_unlock_irq(&cachep->spinlock); | 3362 | spin_unlock(&cachep->spinlock); |
| 3312 | 3363 | ||
| 3313 | for_each_online_cpu(i) { | 3364 | for_each_online_cpu(i) { |
| 3314 | struct array_cache *ccold = new.new[i]; | 3365 | struct array_cache *ccold = new.new[i]; |
| @@ -3440,7 +3491,7 @@ static void cache_reap(void *unused) | |||
| 3440 | 3491 | ||
| 3441 | l3 = searchp->nodelists[numa_node_id()]; | 3492 | l3 = searchp->nodelists[numa_node_id()]; |
| 3442 | if (l3->alien) | 3493 | if (l3->alien) |
| 3443 | drain_alien_cache(searchp, l3); | 3494 | drain_alien_cache(searchp, l3->alien); |
| 3444 | spin_lock_irq(&l3->list_lock); | 3495 | spin_lock_irq(&l3->list_lock); |
| 3445 | 3496 | ||
| 3446 | drain_array_locked(searchp, cpu_cache_get(searchp), 0, | 3497 | drain_array_locked(searchp, cpu_cache_get(searchp), 0, |
| @@ -3564,8 +3615,7 @@ static int s_show(struct seq_file *m, void *p) | |||
| 3564 | int node; | 3615 | int node; |
| 3565 | struct kmem_list3 *l3; | 3616 | struct kmem_list3 *l3; |
| 3566 | 3617 | ||
| 3567 | check_irq_on(); | 3618 | spin_lock(&cachep->spinlock); |
| 3568 | spin_lock_irq(&cachep->spinlock); | ||
| 3569 | active_objs = 0; | 3619 | active_objs = 0; |
| 3570 | num_slabs = 0; | 3620 | num_slabs = 0; |
| 3571 | for_each_online_node(node) { | 3621 | for_each_online_node(node) { |
| @@ -3573,7 +3623,8 @@ static int s_show(struct seq_file *m, void *p) | |||
| 3573 | if (!l3) | 3623 | if (!l3) |
| 3574 | continue; | 3624 | continue; |
| 3575 | 3625 | ||
| 3576 | spin_lock(&l3->list_lock); | 3626 | check_irq_on(); |
| 3627 | spin_lock_irq(&l3->list_lock); | ||
| 3577 | 3628 | ||
| 3578 | list_for_each(q, &l3->slabs_full) { | 3629 | list_for_each(q, &l3->slabs_full) { |
| 3579 | slabp = list_entry(q, struct slab, list); | 3630 | slabp = list_entry(q, struct slab, list); |
| @@ -3598,9 +3649,10 @@ static int s_show(struct seq_file *m, void *p) | |||
| 3598 | num_slabs++; | 3649 | num_slabs++; |
| 3599 | } | 3650 | } |
| 3600 | free_objects += l3->free_objects; | 3651 | free_objects += l3->free_objects; |
| 3601 | shared_avail += l3->shared->avail; | 3652 | if (l3->shared) |
| 3653 | shared_avail += l3->shared->avail; | ||
| 3602 | 3654 | ||
| 3603 | spin_unlock(&l3->list_lock); | 3655 | spin_unlock_irq(&l3->list_lock); |
| 3604 | } | 3656 | } |
| 3605 | num_slabs += active_slabs; | 3657 | num_slabs += active_slabs; |
| 3606 | num_objs = num_slabs * cachep->num; | 3658 | num_objs = num_slabs * cachep->num; |
| @@ -3644,7 +3696,7 @@ static int s_show(struct seq_file *m, void *p) | |||
| 3644 | } | 3696 | } |
| 3645 | #endif | 3697 | #endif |
| 3646 | seq_putc(m, '\n'); | 3698 | seq_putc(m, '\n'); |
| 3647 | spin_unlock_irq(&cachep->spinlock); | 3699 | spin_unlock(&cachep->spinlock); |
| 3648 | return 0; | 3700 | return 0; |
| 3649 | } | 3701 | } |
| 3650 | 3702 | ||
| @@ -336,7 +336,7 @@ EXPORT_SYMBOL(slab_reclaim_pages); | |||
| 336 | 336 | ||
| 337 | #ifdef CONFIG_SMP | 337 | #ifdef CONFIG_SMP |
| 338 | 338 | ||
| 339 | void *__alloc_percpu(size_t size, size_t align) | 339 | void *__alloc_percpu(size_t size) |
| 340 | { | 340 | { |
| 341 | int i; | 341 | int i; |
| 342 | struct percpu_data *pdata = kmalloc(sizeof (*pdata), GFP_KERNEL); | 342 | struct percpu_data *pdata = kmalloc(sizeof (*pdata), GFP_KERNEL); |
| @@ -34,19 +34,22 @@ | |||
| 34 | /* How many pages do we try to swap or page in/out together? */ | 34 | /* How many pages do we try to swap or page in/out together? */ |
| 35 | int page_cluster; | 35 | int page_cluster; |
| 36 | 36 | ||
| 37 | void put_page(struct page *page) | 37 | static void put_compound_page(struct page *page) |
| 38 | { | 38 | { |
| 39 | if (unlikely(PageCompound(page))) { | 39 | page = (struct page *)page_private(page); |
| 40 | page = (struct page *)page_private(page); | 40 | if (put_page_testzero(page)) { |
| 41 | if (put_page_testzero(page)) { | 41 | void (*dtor)(struct page *page); |
| 42 | void (*dtor)(struct page *page); | ||
| 43 | 42 | ||
| 44 | dtor = (void (*)(struct page *))page[1].mapping; | 43 | dtor = (void (*)(struct page *))page[1].mapping; |
| 45 | (*dtor)(page); | 44 | (*dtor)(page); |
| 46 | } | ||
| 47 | return; | ||
| 48 | } | 45 | } |
| 49 | if (put_page_testzero(page)) | 46 | } |
| 47 | |||
| 48 | void put_page(struct page *page) | ||
| 49 | { | ||
| 50 | if (unlikely(PageCompound(page))) | ||
| 51 | put_compound_page(page); | ||
| 52 | else if (put_page_testzero(page)) | ||
| 50 | __page_cache_release(page); | 53 | __page_cache_release(page); |
| 51 | } | 54 | } |
| 52 | EXPORT_SYMBOL(put_page); | 55 | EXPORT_SYMBOL(put_page); |
| @@ -244,6 +247,15 @@ void release_pages(struct page **pages, int nr, int cold) | |||
| 244 | struct page *page = pages[i]; | 247 | struct page *page = pages[i]; |
| 245 | struct zone *pagezone; | 248 | struct zone *pagezone; |
| 246 | 249 | ||
| 250 | if (unlikely(PageCompound(page))) { | ||
| 251 | if (zone) { | ||
| 252 | spin_unlock_irq(&zone->lru_lock); | ||
| 253 | zone = NULL; | ||
| 254 | } | ||
| 255 | put_compound_page(page); | ||
| 256 | continue; | ||
| 257 | } | ||
| 258 | |||
| 247 | if (!put_page_testzero(page)) | 259 | if (!put_page_testzero(page)) |
| 248 | continue; | 260 | continue; |
| 249 | 261 | ||
diff --git a/net/802/psnap.c b/net/802/psnap.c index 4d638944d933..34e42968b477 100644 --- a/net/802/psnap.c +++ b/net/802/psnap.c | |||
| @@ -59,8 +59,10 @@ static int snap_rcv(struct sk_buff *skb, struct net_device *dev, | |||
| 59 | proto = find_snap_client(skb->h.raw); | 59 | proto = find_snap_client(skb->h.raw); |
| 60 | if (proto) { | 60 | if (proto) { |
| 61 | /* Pass the frame on. */ | 61 | /* Pass the frame on. */ |
| 62 | u8 *hdr = skb->data; | ||
| 62 | skb->h.raw += 5; | 63 | skb->h.raw += 5; |
| 63 | skb_pull(skb, 5); | 64 | skb_pull(skb, 5); |
| 65 | skb_postpull_rcsum(skb, hdr, 5); | ||
| 64 | rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev); | 66 | rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev); |
| 65 | } else { | 67 | } else { |
| 66 | skb->sk = NULL; | 68 | skb->sk = NULL; |
diff --git a/net/Kconfig b/net/Kconfig index bc603d9aea56..5126f58d9c44 100644 --- a/net/Kconfig +++ b/net/Kconfig | |||
| @@ -27,6 +27,13 @@ if NET | |||
| 27 | 27 | ||
| 28 | menu "Networking options" | 28 | menu "Networking options" |
| 29 | 29 | ||
| 30 | config NETDEBUG | ||
| 31 | bool "Network packet debugging" | ||
| 32 | help | ||
| 33 | You can say Y here if you want to get additional messages useful in | ||
| 34 | debugging bad packets, but can overwhelm logs under denial of service | ||
| 35 | attacks. | ||
| 36 | |||
| 30 | source "net/packet/Kconfig" | 37 | source "net/packet/Kconfig" |
| 31 | source "net/unix/Kconfig" | 38 | source "net/unix/Kconfig" |
| 32 | source "net/xfrm/Kconfig" | 39 | source "net/xfrm/Kconfig" |
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c index ce617b3dbbb8..802baf755ef4 100644 --- a/net/bridge/netfilter/ebt_ulog.c +++ b/net/bridge/netfilter/ebt_ulog.c | |||
| @@ -46,7 +46,7 @@ | |||
| 46 | #define PRINTR(format, args...) do { if (net_ratelimit()) \ | 46 | #define PRINTR(format, args...) do { if (net_ratelimit()) \ |
| 47 | printk(format , ## args); } while (0) | 47 | printk(format , ## args); } while (0) |
| 48 | 48 | ||
| 49 | static unsigned int nlbufsiz = 4096; | 49 | static unsigned int nlbufsiz = NLMSG_GOODSIZE; |
| 50 | module_param(nlbufsiz, uint, 0600); | 50 | module_param(nlbufsiz, uint, 0600); |
| 51 | MODULE_PARM_DESC(nlbufsiz, "netlink buffer size (number of bytes) " | 51 | MODULE_PARM_DESC(nlbufsiz, "netlink buffer size (number of bytes) " |
| 52 | "(defaults to 4096)"); | 52 | "(defaults to 4096)"); |
| @@ -98,12 +98,14 @@ static void ulog_timer(unsigned long data) | |||
| 98 | static struct sk_buff *ulog_alloc_skb(unsigned int size) | 98 | static struct sk_buff *ulog_alloc_skb(unsigned int size) |
| 99 | { | 99 | { |
| 100 | struct sk_buff *skb; | 100 | struct sk_buff *skb; |
| 101 | unsigned int n; | ||
| 101 | 102 | ||
| 102 | skb = alloc_skb(nlbufsiz, GFP_ATOMIC); | 103 | n = max(size, nlbufsiz); |
| 104 | skb = alloc_skb(n, GFP_ATOMIC); | ||
| 103 | if (!skb) { | 105 | if (!skb) { |
| 104 | PRINTR(KERN_ERR "ebt_ulog: can't alloc whole buffer " | 106 | PRINTR(KERN_ERR "ebt_ulog: can't alloc whole buffer " |
| 105 | "of size %ub!\n", nlbufsiz); | 107 | "of size %ub!\n", n); |
| 106 | if (size < nlbufsiz) { | 108 | if (n > size) { |
| 107 | /* try to allocate only as much as we need for | 109 | /* try to allocate only as much as we need for |
| 108 | * current packet */ | 110 | * current packet */ |
| 109 | skb = alloc_skb(size, GFP_ATOMIC); | 111 | skb = alloc_skb(size, GFP_ATOMIC); |
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 00729b3604f8..cbd4020cc84d 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
| @@ -934,6 +934,13 @@ static int do_replace(void __user *user, unsigned int len) | |||
| 934 | BUGPRINT("Entries_size never zero\n"); | 934 | BUGPRINT("Entries_size never zero\n"); |
| 935 | return -EINVAL; | 935 | return -EINVAL; |
| 936 | } | 936 | } |
| 937 | /* overflow check */ | ||
| 938 | if (tmp.nentries >= ((INT_MAX - sizeof(struct ebt_table_info)) / NR_CPUS - | ||
| 939 | SMP_CACHE_BYTES) / sizeof(struct ebt_counter)) | ||
| 940 | return -ENOMEM; | ||
| 941 | if (tmp.num_counters >= INT_MAX / sizeof(struct ebt_counter)) | ||
| 942 | return -ENOMEM; | ||
| 943 | |||
| 937 | countersize = COUNTER_OFFSET(tmp.nentries) * | 944 | countersize = COUNTER_OFFSET(tmp.nentries) * |
| 938 | (highest_possible_processor_id()+1); | 945 | (highest_possible_processor_id()+1); |
| 939 | newinfo = (struct ebt_table_info *) | 946 | newinfo = (struct ebt_table_info *) |
diff --git a/net/core/dev.c b/net/core/dev.c index ffb82073056e..2afb0de95329 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -3237,7 +3237,7 @@ static int __init net_dev_init(void) | |||
| 3237 | * Initialise the packet receive queues. | 3237 | * Initialise the packet receive queues. |
| 3238 | */ | 3238 | */ |
| 3239 | 3239 | ||
| 3240 | for (i = 0; i < NR_CPUS; i++) { | 3240 | for_each_cpu(i) { |
| 3241 | struct softnet_data *queue; | 3241 | struct softnet_data *queue; |
| 3242 | 3242 | ||
| 3243 | queue = &per_cpu(softnet_data, i); | 3243 | queue = &per_cpu(softnet_data, i); |
diff --git a/net/core/utils.c b/net/core/utils.c index ac1d1fcf8673..fdc4f38bc46c 100644 --- a/net/core/utils.c +++ b/net/core/utils.c | |||
| @@ -121,7 +121,7 @@ void __init net_random_init(void) | |||
| 121 | { | 121 | { |
| 122 | int i; | 122 | int i; |
| 123 | 123 | ||
| 124 | for (i = 0; i < NR_CPUS; i++) { | 124 | for_each_cpu(i) { |
| 125 | struct nrnd_state *state = &per_cpu(net_rand_state,i); | 125 | struct nrnd_state *state = &per_cpu(net_rand_state,i); |
| 126 | __net_srandom(state, i+jiffies); | 126 | __net_srandom(state, i+jiffies); |
| 127 | } | 127 | } |
| @@ -133,7 +133,7 @@ static int net_random_reseed(void) | |||
| 133 | unsigned long seed[NR_CPUS]; | 133 | unsigned long seed[NR_CPUS]; |
| 134 | 134 | ||
| 135 | get_random_bytes(seed, sizeof(seed)); | 135 | get_random_bytes(seed, sizeof(seed)); |
| 136 | for (i = 0; i < NR_CPUS; i++) { | 136 | for_each_cpu(i) { |
| 137 | struct nrnd_state *state = &per_cpu(net_rand_state,i); | 137 | struct nrnd_state *state = &per_cpu(net_rand_state,i); |
| 138 | __net_srandom(state, seed[i]); | 138 | __net_srandom(state, seed[i]); |
| 139 | } | 139 | } |
diff --git a/net/dccp/ccids/lib/tfrc_equation.c b/net/dccp/ccids/lib/tfrc_equation.c index d2b5933b4510..add3cae65e2d 100644 --- a/net/dccp/ccids/lib/tfrc_equation.c +++ b/net/dccp/ccids/lib/tfrc_equation.c | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | #include <linux/config.h> | 15 | #include <linux/config.h> |
| 16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 17 | 17 | ||
| 18 | #include <asm/bug.h> | ||
| 19 | #include <asm/div64.h> | 18 | #include <asm/div64.h> |
| 20 | 19 | ||
| 21 | #include "tfrc.h" | 20 | #include "tfrc.h" |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 105039eb7629..4d1c40972a4b 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
| @@ -385,7 +385,7 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) | |||
| 385 | u32 daddr; | 385 | u32 daddr; |
| 386 | 386 | ||
| 387 | if (ip_options_echo(&icmp_param->replyopts, skb)) | 387 | if (ip_options_echo(&icmp_param->replyopts, skb)) |
| 388 | goto out; | 388 | return; |
| 389 | 389 | ||
| 390 | if (icmp_xmit_lock()) | 390 | if (icmp_xmit_lock()) |
| 391 | return; | 391 | return; |
| @@ -416,7 +416,6 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) | |||
| 416 | ip_rt_put(rt); | 416 | ip_rt_put(rt); |
| 417 | out_unlock: | 417 | out_unlock: |
| 418 | icmp_xmit_unlock(); | 418 | icmp_xmit_unlock(); |
| 419 | out:; | ||
| 420 | } | 419 | } |
| 421 | 420 | ||
| 422 | 421 | ||
| @@ -525,7 +524,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, u32 info) | |||
| 525 | iph->tos; | 524 | iph->tos; |
| 526 | 525 | ||
| 527 | if (ip_options_echo(&icmp_param.replyopts, skb_in)) | 526 | if (ip_options_echo(&icmp_param.replyopts, skb_in)) |
| 528 | goto ende; | 527 | goto out_unlock; |
| 529 | 528 | ||
| 530 | 529 | ||
| 531 | /* | 530 | /* |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 0b4e95f93dad..64ce52bf0485 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
| @@ -1578,7 +1578,7 @@ static int sf_setstate(struct ip_mc_list *pmc) | |||
| 1578 | new_in = psf->sf_count[MCAST_INCLUDE] != 0; | 1578 | new_in = psf->sf_count[MCAST_INCLUDE] != 0; |
| 1579 | if (new_in) { | 1579 | if (new_in) { |
| 1580 | if (!psf->sf_oldin) { | 1580 | if (!psf->sf_oldin) { |
| 1581 | struct ip_sf_list *prev = 0; | 1581 | struct ip_sf_list *prev = NULL; |
| 1582 | 1582 | ||
| 1583 | for (dpsf=pmc->tomb; dpsf; dpsf=dpsf->sf_next) { | 1583 | for (dpsf=pmc->tomb; dpsf; dpsf=dpsf->sf_next) { |
| 1584 | if (dpsf->sf_inaddr == psf->sf_inaddr) | 1584 | if (dpsf->sf_inaddr == psf->sf_inaddr) |
diff --git a/net/ipv4/multipath_wrandom.c b/net/ipv4/multipath_wrandom.c index d34a9fa608e0..342d0b9098f5 100644 --- a/net/ipv4/multipath_wrandom.c +++ b/net/ipv4/multipath_wrandom.c | |||
| @@ -228,7 +228,7 @@ static void wrandom_set_nhinfo(__u32 network, | |||
| 228 | struct multipath_dest *d, *target_dest = NULL; | 228 | struct multipath_dest *d, *target_dest = NULL; |
| 229 | 229 | ||
| 230 | /* store the weight information for a certain route */ | 230 | /* store the weight information for a certain route */ |
| 231 | spin_lock(&state[state_idx].lock); | 231 | spin_lock_bh(&state[state_idx].lock); |
| 232 | 232 | ||
| 233 | /* find state entry for gateway or add one if necessary */ | 233 | /* find state entry for gateway or add one if necessary */ |
| 234 | list_for_each_entry_rcu(r, &state[state_idx].head, list) { | 234 | list_for_each_entry_rcu(r, &state[state_idx].head, list) { |
| @@ -276,7 +276,7 @@ static void wrandom_set_nhinfo(__u32 network, | |||
| 276 | * we are finished | 276 | * we are finished |
| 277 | */ | 277 | */ |
| 278 | 278 | ||
| 279 | spin_unlock(&state[state_idx].lock); | 279 | spin_unlock_bh(&state[state_idx].lock); |
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | static void __multipath_free(struct rcu_head *head) | 282 | static void __multipath_free(struct rcu_head *head) |
| @@ -302,7 +302,7 @@ static void wrandom_flush(void) | |||
| 302 | for (i = 0; i < MULTIPATH_STATE_SIZE; ++i) { | 302 | for (i = 0; i < MULTIPATH_STATE_SIZE; ++i) { |
| 303 | struct multipath_route *r; | 303 | struct multipath_route *r; |
| 304 | 304 | ||
| 305 | spin_lock(&state[i].lock); | 305 | spin_lock_bh(&state[i].lock); |
| 306 | list_for_each_entry_rcu(r, &state[i].head, list) { | 306 | list_for_each_entry_rcu(r, &state[i].head, list) { |
| 307 | struct multipath_dest *d; | 307 | struct multipath_dest *d; |
| 308 | list_for_each_entry_rcu(d, &r->dests, list) { | 308 | list_for_each_entry_rcu(d, &r->dests, list) { |
| @@ -315,7 +315,7 @@ static void wrandom_flush(void) | |||
| 315 | __multipath_free); | 315 | __multipath_free); |
| 316 | } | 316 | } |
| 317 | 317 | ||
| 318 | spin_unlock(&state[i].lock); | 318 | spin_unlock_bh(&state[i].lock); |
| 319 | } | 319 | } |
| 320 | } | 320 | } |
| 321 | 321 | ||
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index afe3d8f8177d..dd1048be8a01 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
| @@ -807,6 +807,13 @@ static int do_replace(void __user *user, unsigned int len) | |||
| 807 | if (len != sizeof(tmp) + tmp.size) | 807 | if (len != sizeof(tmp) + tmp.size) |
| 808 | return -ENOPROTOOPT; | 808 | return -ENOPROTOOPT; |
| 809 | 809 | ||
| 810 | /* overflow check */ | ||
| 811 | if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS - | ||
| 812 | SMP_CACHE_BYTES) | ||
| 813 | return -ENOMEM; | ||
| 814 | if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) | ||
| 815 | return -ENOMEM; | ||
| 816 | |||
| 810 | newinfo = xt_alloc_table_info(tmp.size); | 817 | newinfo = xt_alloc_table_info(tmp.size); |
| 811 | if (!newinfo) | 818 | if (!newinfo) |
| 812 | return -ENOMEM; | 819 | return -ENOMEM; |
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c index c9ebbe0d2d9c..e0b5926c76f9 100644 --- a/net/ipv4/netfilter/ip_conntrack_netlink.c +++ b/net/ipv4/netfilter/ip_conntrack_netlink.c | |||
| @@ -1216,7 +1216,7 @@ static int ctnetlink_expect_event(struct notifier_block *this, | |||
| 1216 | 1216 | ||
| 1217 | b = skb->tail; | 1217 | b = skb->tail; |
| 1218 | 1218 | ||
| 1219 | type |= NFNL_SUBSYS_CTNETLINK << 8; | 1219 | type |= NFNL_SUBSYS_CTNETLINK_EXP << 8; |
| 1220 | nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg)); | 1220 | nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg)); |
| 1221 | nfmsg = NLMSG_DATA(nlh); | 1221 | nfmsg = NLMSG_DATA(nlh); |
| 1222 | 1222 | ||
| @@ -1567,6 +1567,7 @@ static struct nfnetlink_subsystem ctnl_exp_subsys = { | |||
| 1567 | }; | 1567 | }; |
| 1568 | 1568 | ||
| 1569 | MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK); | 1569 | MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK); |
| 1570 | MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_EXP); | ||
| 1570 | 1571 | ||
| 1571 | static int __init ctnetlink_init(void) | 1572 | static int __init ctnetlink_init(void) |
| 1572 | { | 1573 | { |
diff --git a/net/ipv4/netfilter/ip_conntrack_tftp.c b/net/ipv4/netfilter/ip_conntrack_tftp.c index d3c5a371f993..4ba4463cec28 100644 --- a/net/ipv4/netfilter/ip_conntrack_tftp.c +++ b/net/ipv4/netfilter/ip_conntrack_tftp.c | |||
| @@ -71,6 +71,7 @@ static int tftp_help(struct sk_buff **pskb, | |||
| 71 | 71 | ||
| 72 | exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; | 72 | exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; |
| 73 | exp->mask.src.ip = 0xffffffff; | 73 | exp->mask.src.ip = 0xffffffff; |
| 74 | exp->mask.src.u.udp.port = 0; | ||
| 74 | exp->mask.dst.ip = 0xffffffff; | 75 | exp->mask.dst.ip = 0xffffffff; |
| 75 | exp->mask.dst.u.udp.port = 0xffff; | 76 | exp->mask.dst.u.udp.port = 0xffff; |
| 76 | exp->mask.dst.protonum = 0xff; | 77 | exp->mask.dst.protonum = 0xff; |
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index ad438fb185b8..92c54999a19d 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c | |||
| @@ -209,8 +209,8 @@ ip_nat_in(unsigned int hooknum, | |||
| 209 | && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) { | 209 | && (ct = ip_conntrack_get(*pskb, &ctinfo)) != NULL) { |
| 210 | enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); | 210 | enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); |
| 211 | 211 | ||
| 212 | if (ct->tuplehash[dir].tuple.src.ip != | 212 | if (ct->tuplehash[dir].tuple.dst.ip != |
| 213 | ct->tuplehash[!dir].tuple.dst.ip) { | 213 | ct->tuplehash[!dir].tuple.src.ip) { |
| 214 | dst_release((*pskb)->dst); | 214 | dst_release((*pskb)->dst); |
| 215 | (*pskb)->dst = NULL; | 215 | (*pskb)->dst = NULL; |
| 216 | } | 216 | } |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 2371b2062c2d..16f47c675fef 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
| @@ -921,6 +921,13 @@ do_replace(void __user *user, unsigned int len) | |||
| 921 | if (len != sizeof(tmp) + tmp.size) | 921 | if (len != sizeof(tmp) + tmp.size) |
| 922 | return -ENOPROTOOPT; | 922 | return -ENOPROTOOPT; |
| 923 | 923 | ||
| 924 | /* overflow check */ | ||
| 925 | if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS - | ||
| 926 | SMP_CACHE_BYTES) | ||
| 927 | return -ENOMEM; | ||
| 928 | if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) | ||
| 929 | return -ENOMEM; | ||
| 930 | |||
| 924 | newinfo = xt_alloc_table_info(tmp.size); | 931 | newinfo = xt_alloc_table_info(tmp.size); |
| 925 | if (!newinfo) | 932 | if (!newinfo) |
| 926 | return -ENOMEM; | 933 | return -ENOMEM; |
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index 641dbc477650..180a9ea57b69 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c | |||
| @@ -35,6 +35,10 @@ | |||
| 35 | * each nlgroup you are using, so the total kernel memory usage increases | 35 | * each nlgroup you are using, so the total kernel memory usage increases |
| 36 | * by that factor. | 36 | * by that factor. |
| 37 | * | 37 | * |
| 38 | * Actually you should use nlbufsiz a bit smaller than PAGE_SIZE, since | ||
| 39 | * nlbufsiz is used with alloc_skb, which adds another | ||
| 40 | * sizeof(struct skb_shared_info). Use NLMSG_GOODSIZE instead. | ||
| 41 | * | ||
| 38 | * flushtimeout: | 42 | * flushtimeout: |
| 39 | * Specify, after how many hundredths of a second the queue should be | 43 | * Specify, after how many hundredths of a second the queue should be |
| 40 | * flushed even if it is not full yet. | 44 | * flushed even if it is not full yet. |
| @@ -76,7 +80,7 @@ MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NFLOG); | |||
| 76 | 80 | ||
| 77 | #define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0) | 81 | #define PRINTR(format, args...) do { if (net_ratelimit()) printk(format , ## args); } while (0) |
| 78 | 82 | ||
| 79 | static unsigned int nlbufsiz = 4096; | 83 | static unsigned int nlbufsiz = NLMSG_GOODSIZE; |
| 80 | module_param(nlbufsiz, uint, 0400); | 84 | module_param(nlbufsiz, uint, 0400); |
| 81 | MODULE_PARM_DESC(nlbufsiz, "netlink buffer size"); | 85 | MODULE_PARM_DESC(nlbufsiz, "netlink buffer size"); |
| 82 | 86 | ||
| @@ -143,22 +147,26 @@ static void ulog_timer(unsigned long data) | |||
| 143 | static struct sk_buff *ulog_alloc_skb(unsigned int size) | 147 | static struct sk_buff *ulog_alloc_skb(unsigned int size) |
| 144 | { | 148 | { |
| 145 | struct sk_buff *skb; | 149 | struct sk_buff *skb; |
| 150 | unsigned int n; | ||
| 146 | 151 | ||
| 147 | /* alloc skb which should be big enough for a whole | 152 | /* alloc skb which should be big enough for a whole |
| 148 | * multipart message. WARNING: has to be <= 131000 | 153 | * multipart message. WARNING: has to be <= 131000 |
| 149 | * due to slab allocator restrictions */ | 154 | * due to slab allocator restrictions */ |
| 150 | 155 | ||
| 151 | skb = alloc_skb(nlbufsiz, GFP_ATOMIC); | 156 | n = max(size, nlbufsiz); |
| 157 | skb = alloc_skb(n, GFP_ATOMIC); | ||
| 152 | if (!skb) { | 158 | if (!skb) { |
| 153 | PRINTR("ipt_ULOG: can't alloc whole buffer %ub!\n", | 159 | PRINTR("ipt_ULOG: can't alloc whole buffer %ub!\n", n); |
| 154 | nlbufsiz); | ||
| 155 | 160 | ||
| 156 | /* try to allocate only as much as we need for | 161 | if (n > size) { |
| 157 | * current packet */ | 162 | /* try to allocate only as much as we need for |
| 163 | * current packet */ | ||
| 158 | 164 | ||
| 159 | skb = alloc_skb(size, GFP_ATOMIC); | 165 | skb = alloc_skb(size, GFP_ATOMIC); |
| 160 | if (!skb) | 166 | if (!skb) |
| 161 | PRINTR("ipt_ULOG: can't even allocate %ub\n", size); | 167 | PRINTR("ipt_ULOG: can't even allocate %ub\n", |
| 168 | size); | ||
| 169 | } | ||
| 162 | } | 170 | } |
| 163 | 171 | ||
| 164 | return skb; | 172 | return skb; |
diff --git a/net/ipv4/netfilter/ipt_policy.c b/net/ipv4/netfilter/ipt_policy.c index 18ca8258a1c5..5a7a265280f9 100644 --- a/net/ipv4/netfilter/ipt_policy.c +++ b/net/ipv4/netfilter/ipt_policy.c | |||
| @@ -26,10 +26,13 @@ MODULE_LICENSE("GPL"); | |||
| 26 | static inline int | 26 | static inline int |
| 27 | match_xfrm_state(struct xfrm_state *x, const struct ipt_policy_elem *e) | 27 | match_xfrm_state(struct xfrm_state *x, const struct ipt_policy_elem *e) |
| 28 | { | 28 | { |
| 29 | #define MATCH(x,y) (!e->match.x || ((e->x == (y)) ^ e->invert.x)) | 29 | #define MATCH_ADDR(x,y,z) (!e->match.x || \ |
| 30 | ((e->x.a4.s_addr == (e->y.a4.s_addr & (z))) \ | ||
| 31 | ^ e->invert.x)) | ||
| 32 | #define MATCH(x,y) (!e->match.x || ((e->x == (y)) ^ e->invert.x)) | ||
| 30 | 33 | ||
| 31 | return MATCH(saddr, x->props.saddr.a4 & e->smask) && | 34 | return MATCH_ADDR(saddr, smask, x->props.saddr.a4) && |
| 32 | MATCH(daddr, x->id.daddr.a4 & e->dmask) && | 35 | MATCH_ADDR(daddr, dmask, x->id.daddr.a4) && |
| 33 | MATCH(proto, x->id.proto) && | 36 | MATCH(proto, x->id.proto) && |
| 34 | MATCH(mode, x->props.mode) && | 37 | MATCH(mode, x->props.mode) && |
| 35 | MATCH(spi, x->id.spi) && | 38 | MATCH(spi, x->id.spi) && |
| @@ -89,7 +92,7 @@ match_policy_out(const struct sk_buff *skb, const struct ipt_policy_info *info) | |||
| 89 | return 0; | 92 | return 0; |
| 90 | } | 93 | } |
| 91 | 94 | ||
| 92 | return strict ? 1 : 0; | 95 | return strict ? i == info->len : 0; |
| 93 | } | 96 | } |
| 94 | 97 | ||
| 95 | static int match(const struct sk_buff *skb, | 98 | static int match(const struct sk_buff *skb, |
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 39d49dc333a7..1b167c4bb3be 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
| @@ -49,7 +49,7 @@ static int fold_prot_inuse(struct proto *proto) | |||
| 49 | int res = 0; | 49 | int res = 0; |
| 50 | int cpu; | 50 | int cpu; |
| 51 | 51 | ||
| 52 | for (cpu = 0; cpu < NR_CPUS; cpu++) | 52 | for_each_cpu(cpu) |
| 53 | res += proto->stats[cpu].inuse; | 53 | res += proto->stats[cpu].inuse; |
| 54 | 54 | ||
| 55 | return res; | 55 | return res; |
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 42196ba3b0b9..45f7ae58f2c0 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
| @@ -8,7 +8,6 @@ | |||
| 8 | * | 8 | * |
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <asm/bug.h> | ||
| 12 | #include <linux/compiler.h> | 11 | #include <linux/compiler.h> |
| 13 | #include <linux/config.h> | 12 | #include <linux/config.h> |
| 14 | #include <linux/inetdevice.h> | 13 | #include <linux/inetdevice.h> |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index d328d5986143..b7d8822c1be4 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -2165,6 +2165,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, | |||
| 2165 | dev->name); | 2165 | dev->name); |
| 2166 | break; | 2166 | break; |
| 2167 | } | 2167 | } |
| 2168 | |||
| 2169 | if (idev) | ||
| 2170 | idev->if_flags |= IF_READY; | ||
| 2168 | } else { | 2171 | } else { |
| 2169 | if (!netif_carrier_ok(dev)) { | 2172 | if (!netif_carrier_ok(dev)) { |
| 2170 | /* device is still not ready. */ | 2173 | /* device is still not ready. */ |
| @@ -3321,9 +3324,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | |||
| 3321 | 3324 | ||
| 3322 | switch (event) { | 3325 | switch (event) { |
| 3323 | case RTM_NEWADDR: | 3326 | case RTM_NEWADDR: |
| 3324 | dst_hold(&ifp->rt->u.dst); | 3327 | ip6_ins_rt(ifp->rt, NULL, NULL, NULL); |
| 3325 | if (ip6_ins_rt(ifp->rt, NULL, NULL, NULL)) | ||
| 3326 | dst_release(&ifp->rt->u.dst); | ||
| 3327 | if (ifp->idev->cnf.forwarding) | 3328 | if (ifp->idev->cnf.forwarding) |
| 3328 | addrconf_join_anycast(ifp); | 3329 | addrconf_join_anycast(ifp); |
| 3329 | break; | 3330 | break; |
| @@ -3334,8 +3335,6 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) | |||
| 3334 | dst_hold(&ifp->rt->u.dst); | 3335 | dst_hold(&ifp->rt->u.dst); |
| 3335 | if (ip6_del_rt(ifp->rt, NULL, NULL, NULL)) | 3336 | if (ip6_del_rt(ifp->rt, NULL, NULL, NULL)) |
| 3336 | dst_free(&ifp->rt->u.dst); | 3337 | dst_free(&ifp->rt->u.dst); |
| 3337 | else | ||
| 3338 | dst_release(&ifp->rt->u.dst); | ||
| 3339 | break; | 3338 | break; |
| 3340 | } | 3339 | } |
| 3341 | } | 3340 | } |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 064ffab82a9f..6c9711ac1c03 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
| @@ -369,12 +369,6 @@ int inet6_destroy_sock(struct sock *sk) | |||
| 369 | struct sk_buff *skb; | 369 | struct sk_buff *skb; |
| 370 | struct ipv6_txoptions *opt; | 370 | struct ipv6_txoptions *opt; |
| 371 | 371 | ||
| 372 | /* | ||
| 373 | * Release destination entry | ||
| 374 | */ | ||
| 375 | |||
| 376 | sk_dst_reset(sk); | ||
| 377 | |||
| 378 | /* Release rx options */ | 372 | /* Release rx options */ |
| 379 | 373 | ||
| 380 | if ((skb = xchg(&np->pktoptions, NULL)) != NULL) | 374 | if ((skb = xchg(&np->pktoptions, NULL)) != NULL) |
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 4420948a1bfe..807c021d64a2 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
| @@ -1978,7 +1978,7 @@ static int sf_setstate(struct ifmcaddr6 *pmc) | |||
| 1978 | new_in = psf->sf_count[MCAST_INCLUDE] != 0; | 1978 | new_in = psf->sf_count[MCAST_INCLUDE] != 0; |
| 1979 | if (new_in) { | 1979 | if (new_in) { |
| 1980 | if (!psf->sf_oldin) { | 1980 | if (!psf->sf_oldin) { |
| 1981 | struct ip6_sf_list *prev = 0; | 1981 | struct ip6_sf_list *prev = NULL; |
| 1982 | 1982 | ||
| 1983 | for (dpsf=pmc->mca_tomb; dpsf; | 1983 | for (dpsf=pmc->mca_tomb; dpsf; |
| 1984 | dpsf=dpsf->sf_next) { | 1984 | dpsf=dpsf->sf_next) { |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 847068fd3367..74ff56c322f4 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
| @@ -978,6 +978,13 @@ do_replace(void __user *user, unsigned int len) | |||
| 978 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 978 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) |
| 979 | return -EFAULT; | 979 | return -EFAULT; |
| 980 | 980 | ||
| 981 | /* overflow check */ | ||
| 982 | if (tmp.size >= (INT_MAX - sizeof(struct xt_table_info)) / NR_CPUS - | ||
| 983 | SMP_CACHE_BYTES) | ||
| 984 | return -ENOMEM; | ||
| 985 | if (tmp.num_counters >= INT_MAX / sizeof(struct xt_counters)) | ||
| 986 | return -ENOMEM; | ||
| 987 | |||
| 981 | newinfo = xt_alloc_table_info(tmp.size); | 988 | newinfo = xt_alloc_table_info(tmp.size); |
| 982 | if (!newinfo) | 989 | if (!newinfo) |
| 983 | return -ENOMEM; | 990 | return -ENOMEM; |
diff --git a/net/ipv6/netfilter/ip6t_policy.c b/net/ipv6/netfilter/ip6t_policy.c index afe1cc4c18a5..3d39ec924041 100644 --- a/net/ipv6/netfilter/ip6t_policy.c +++ b/net/ipv6/netfilter/ip6t_policy.c | |||
| @@ -26,8 +26,9 @@ MODULE_LICENSE("GPL"); | |||
| 26 | static inline int | 26 | static inline int |
| 27 | match_xfrm_state(struct xfrm_state *x, const struct ip6t_policy_elem *e) | 27 | match_xfrm_state(struct xfrm_state *x, const struct ip6t_policy_elem *e) |
| 28 | { | 28 | { |
| 29 | #define MATCH_ADDR(x,y,z) (!e->match.x || \ | 29 | #define MATCH_ADDR(x,y,z) (!e->match.x || \ |
| 30 | ((ip6_masked_addrcmp((z), &e->x, &e->y)) == 0) ^ e->invert.x) | 30 | ((!ip6_masked_addrcmp(&e->x.a6, &e->y.a6, z)) \ |
| 31 | ^ e->invert.x)) | ||
| 31 | #define MATCH(x,y) (!e->match.x || ((e->x == (y)) ^ e->invert.x)) | 32 | #define MATCH(x,y) (!e->match.x || ((e->x == (y)) ^ e->invert.x)) |
| 32 | 33 | ||
| 33 | return MATCH_ADDR(saddr, smask, (struct in6_addr *)&x->props.saddr.a6) && | 34 | return MATCH_ADDR(saddr, smask, (struct in6_addr *)&x->props.saddr.a6) && |
| @@ -91,7 +92,7 @@ match_policy_out(const struct sk_buff *skb, const struct ip6t_policy_info *info) | |||
| 91 | return 0; | 92 | return 0; |
| 92 | } | 93 | } |
| 93 | 94 | ||
| 94 | return strict ? 1 : 0; | 95 | return strict ? i == info->len : 0; |
| 95 | } | 96 | } |
| 96 | 97 | ||
| 97 | static int match(const struct sk_buff *skb, | 98 | static int match(const struct sk_buff *skb, |
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index 50a13e75d70e..4238b1ed8860 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c | |||
| @@ -38,7 +38,7 @@ static int fold_prot_inuse(struct proto *proto) | |||
| 38 | int res = 0; | 38 | int res = 0; |
| 39 | int cpu; | 39 | int cpu; |
| 40 | 40 | ||
| 41 | for (cpu=0; cpu<NR_CPUS; cpu++) | 41 | for_each_cpu(cpu) |
| 42 | res += proto->stats[cpu].inuse; | 42 | res += proto->stats[cpu].inuse; |
| 43 | 43 | ||
| 44 | return res; | 44 | return res; |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 66f1d12ea578..738376cf0c51 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
| @@ -35,7 +35,6 @@ | |||
| 35 | #include <linux/skbuff.h> | 35 | #include <linux/skbuff.h> |
| 36 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
| 37 | #include <asm/ioctls.h> | 37 | #include <asm/ioctls.h> |
| 38 | #include <asm/bug.h> | ||
| 39 | 38 | ||
| 40 | #include <net/ip.h> | 39 | #include <net/ip.h> |
| 41 | #include <net/sock.h> | 40 | #include <net/sock.h> |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 69bd957380e7..91cce8b2d7a5 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
| @@ -11,7 +11,6 @@ | |||
| 11 | * | 11 | * |
| 12 | */ | 12 | */ |
| 13 | 13 | ||
| 14 | #include <asm/bug.h> | ||
| 15 | #include <linux/compiler.h> | 14 | #include <linux/compiler.h> |
| 16 | #include <linux/config.h> | 15 | #include <linux/config.h> |
| 17 | #include <linux/netdevice.h> | 16 | #include <linux/netdevice.h> |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 62bb509f05d4..0ce337a1d974 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
| @@ -188,7 +188,7 @@ extern struct nf_conntrack_protocol nf_conntrack_generic_protocol; | |||
| 188 | struct nf_conntrack_protocol * | 188 | struct nf_conntrack_protocol * |
| 189 | __nf_ct_proto_find(u_int16_t l3proto, u_int8_t protocol) | 189 | __nf_ct_proto_find(u_int16_t l3proto, u_int8_t protocol) |
| 190 | { | 190 | { |
| 191 | if (unlikely(nf_ct_protos[l3proto] == NULL)) | 191 | if (unlikely(l3proto >= AF_MAX || nf_ct_protos[l3proto] == NULL)) |
| 192 | return &nf_conntrack_generic_protocol; | 192 | return &nf_conntrack_generic_protocol; |
| 193 | 193 | ||
| 194 | return nf_ct_protos[l3proto][protocol]; | 194 | return nf_ct_protos[l3proto][protocol]; |
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c index ab0c920f0d30..6f210f399762 100644 --- a/net/netfilter/nf_conntrack_ftp.c +++ b/net/netfilter/nf_conntrack_ftp.c | |||
| @@ -657,8 +657,6 @@ static int __init init(void) | |||
| 657 | /* FIXME should be configurable whether IPv4 and IPv6 FTP connections | 657 | /* FIXME should be configurable whether IPv4 and IPv6 FTP connections |
| 658 | are tracked or not - YK */ | 658 | are tracked or not - YK */ |
| 659 | for (i = 0; i < ports_c; i++) { | 659 | for (i = 0; i < ports_c; i++) { |
| 660 | memset(&ftp[i], 0, sizeof(struct nf_conntrack_helper)); | ||
| 661 | |||
| 662 | ftp[i][0].tuple.src.l3num = PF_INET; | 660 | ftp[i][0].tuple.src.l3num = PF_INET; |
| 663 | ftp[i][1].tuple.src.l3num = PF_INET6; | 661 | ftp[i][1].tuple.src.l3num = PF_INET6; |
| 664 | for (j = 0; j < 2; j++) { | 662 | for (j = 0; j < 2; j++) { |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 73ab16bc7d40..9ff3463037e1 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
| @@ -1232,7 +1232,7 @@ static int ctnetlink_expect_event(struct notifier_block *this, | |||
| 1232 | 1232 | ||
| 1233 | b = skb->tail; | 1233 | b = skb->tail; |
| 1234 | 1234 | ||
| 1235 | type |= NFNL_SUBSYS_CTNETLINK << 8; | 1235 | type |= NFNL_SUBSYS_CTNETLINK_EXP << 8; |
| 1236 | nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg)); | 1236 | nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(struct nfgenmsg)); |
| 1237 | nfmsg = NLMSG_DATA(nlh); | 1237 | nfmsg = NLMSG_DATA(nlh); |
| 1238 | 1238 | ||
| @@ -1589,6 +1589,7 @@ static struct nfnetlink_subsystem ctnl_exp_subsys = { | |||
| 1589 | }; | 1589 | }; |
| 1590 | 1590 | ||
| 1591 | MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK); | 1591 | MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK); |
| 1592 | MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_EXP); | ||
| 1592 | 1593 | ||
| 1593 | static int __init ctnetlink_init(void) | 1594 | static int __init ctnetlink_init(void) |
| 1594 | { | 1595 | { |
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index e10512e229b6..3b3c781b40c0 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c | |||
| @@ -37,7 +37,7 @@ | |||
| 37 | #include "../bridge/br_private.h" | 37 | #include "../bridge/br_private.h" |
| 38 | #endif | 38 | #endif |
| 39 | 39 | ||
| 40 | #define NFULNL_NLBUFSIZ_DEFAULT 4096 | 40 | #define NFULNL_NLBUFSIZ_DEFAULT NLMSG_GOODSIZE |
| 41 | #define NFULNL_TIMEOUT_DEFAULT 100 /* every second */ | 41 | #define NFULNL_TIMEOUT_DEFAULT 100 /* every second */ |
| 42 | #define NFULNL_QTHRESH_DEFAULT 100 /* 100 packets */ | 42 | #define NFULNL_QTHRESH_DEFAULT 100 /* 100 packets */ |
| 43 | 43 | ||
| @@ -314,24 +314,28 @@ static struct sk_buff *nfulnl_alloc_skb(unsigned int inst_size, | |||
| 314 | unsigned int pkt_size) | 314 | unsigned int pkt_size) |
| 315 | { | 315 | { |
| 316 | struct sk_buff *skb; | 316 | struct sk_buff *skb; |
| 317 | unsigned int n; | ||
| 317 | 318 | ||
| 318 | UDEBUG("entered (%u, %u)\n", inst_size, pkt_size); | 319 | UDEBUG("entered (%u, %u)\n", inst_size, pkt_size); |
| 319 | 320 | ||
| 320 | /* alloc skb which should be big enough for a whole multipart | 321 | /* alloc skb which should be big enough for a whole multipart |
| 321 | * message. WARNING: has to be <= 128k due to slab restrictions */ | 322 | * message. WARNING: has to be <= 128k due to slab restrictions */ |
| 322 | 323 | ||
| 323 | skb = alloc_skb(inst_size, GFP_ATOMIC); | 324 | n = max(inst_size, pkt_size); |
| 325 | skb = alloc_skb(n, GFP_ATOMIC); | ||
| 324 | if (!skb) { | 326 | if (!skb) { |
| 325 | PRINTR("nfnetlink_log: can't alloc whole buffer (%u bytes)\n", | 327 | PRINTR("nfnetlink_log: can't alloc whole buffer (%u bytes)\n", |
| 326 | inst_size); | 328 | inst_size); |
| 327 | 329 | ||
| 328 | /* try to allocate only as much as we need for current | 330 | if (n > pkt_size) { |
| 329 | * packet */ | 331 | /* try to allocate only as much as we need for current |
| 332 | * packet */ | ||
| 330 | 333 | ||
| 331 | skb = alloc_skb(pkt_size, GFP_ATOMIC); | 334 | skb = alloc_skb(pkt_size, GFP_ATOMIC); |
| 332 | if (!skb) | 335 | if (!skb) |
| 333 | PRINTR("nfnetlink_log: can't even alloc %u bytes\n", | 336 | PRINTR("nfnetlink_log: can't even alloc %u " |
| 334 | pkt_size); | 337 | "bytes\n", pkt_size); |
| 338 | } | ||
| 335 | } | 339 | } |
| 336 | 340 | ||
| 337 | return skb; | 341 | return skb; |
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 18ed9c5d209c..cac38b2e147a 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c | |||
| @@ -825,7 +825,8 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb, | |||
| 825 | } | 825 | } |
| 826 | 826 | ||
| 827 | if (nfqa[NFQA_MARK-1]) | 827 | if (nfqa[NFQA_MARK-1]) |
| 828 | skb->nfmark = ntohl(*(u_int32_t *)NFA_DATA(nfqa[NFQA_MARK-1])); | 828 | entry->skb->nfmark = ntohl(*(u_int32_t *) |
| 829 | NFA_DATA(nfqa[NFQA_MARK-1])); | ||
| 829 | 830 | ||
| 830 | issue_verdict(entry, verdict); | 831 | issue_verdict(entry, verdict); |
| 831 | instance_put(queue); | 832 | instance_put(queue); |
diff --git a/net/sctp/output.c b/net/sctp/output.c index a40991ef72c9..437cba7260a4 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
| @@ -608,7 +608,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet, | |||
| 608 | * When a Fast Retransmit is being performed the sender SHOULD | 608 | * When a Fast Retransmit is being performed the sender SHOULD |
| 609 | * ignore the value of cwnd and SHOULD NOT delay retransmission. | 609 | * ignore the value of cwnd and SHOULD NOT delay retransmission. |
| 610 | */ | 610 | */ |
| 611 | if (!chunk->fast_retransmit) | 611 | if (chunk->fast_retransmit <= 0) |
| 612 | if (transport->flight_size >= transport->cwnd) { | 612 | if (transport->flight_size >= transport->cwnd) { |
| 613 | retval = SCTP_XMIT_RWND_FULL; | 613 | retval = SCTP_XMIT_RWND_FULL; |
| 614 | goto finish; | 614 | goto finish; |
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index efb72faba20c..f148f9576dd2 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
| @@ -406,7 +406,7 @@ void sctp_retransmit_mark(struct sctp_outq *q, | |||
| 406 | * chunks that are not yet acked should be added to the | 406 | * chunks that are not yet acked should be added to the |
| 407 | * retransmit queue. | 407 | * retransmit queue. |
| 408 | */ | 408 | */ |
| 409 | if ((fast_retransmit && chunk->fast_retransmit) || | 409 | if ((fast_retransmit && (chunk->fast_retransmit > 0)) || |
| 410 | (!fast_retransmit && !chunk->tsn_gap_acked)) { | 410 | (!fast_retransmit && !chunk->tsn_gap_acked)) { |
| 411 | /* RFC 2960 6.2.1 Processing a Received SACK | 411 | /* RFC 2960 6.2.1 Processing a Received SACK |
| 412 | * | 412 | * |
| @@ -603,7 +603,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, | |||
| 603 | /* Mark the chunk as ineligible for fast retransmit | 603 | /* Mark the chunk as ineligible for fast retransmit |
| 604 | * after it is retransmitted. | 604 | * after it is retransmitted. |
| 605 | */ | 605 | */ |
| 606 | chunk->fast_retransmit = 0; | 606 | if (chunk->fast_retransmit > 0) |
| 607 | chunk->fast_retransmit = -1; | ||
| 607 | 608 | ||
| 608 | *start_timer = 1; | 609 | *start_timer = 1; |
| 609 | q->empty = 0; | 610 | q->empty = 0; |
| @@ -621,7 +622,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt, | |||
| 621 | list_for_each(lchunk1, lqueue) { | 622 | list_for_each(lchunk1, lqueue) { |
| 622 | chunk1 = list_entry(lchunk1, struct sctp_chunk, | 623 | chunk1 = list_entry(lchunk1, struct sctp_chunk, |
| 623 | transmitted_list); | 624 | transmitted_list); |
| 624 | chunk1->fast_retransmit = 0; | 625 | if (chunk1->fast_retransmit > 0) |
| 626 | chunk1->fast_retransmit = -1; | ||
| 625 | } | 627 | } |
| 626 | } | 628 | } |
| 627 | } | 629 | } |
| @@ -1562,11 +1564,11 @@ static void sctp_mark_missing(struct sctp_outq *q, | |||
| 1562 | /* | 1564 | /* |
| 1563 | * M4) If any DATA chunk is found to have a | 1565 | * M4) If any DATA chunk is found to have a |
| 1564 | * 'TSN.Missing.Report' | 1566 | * 'TSN.Missing.Report' |
| 1565 | * value larger than or equal to 4, mark that chunk for | 1567 | * value larger than or equal to 3, mark that chunk for |
| 1566 | * retransmission and start the fast retransmit procedure. | 1568 | * retransmission and start the fast retransmit procedure. |
| 1567 | */ | 1569 | */ |
| 1568 | 1570 | ||
| 1569 | if (chunk->tsn_missing_report >= 4) { | 1571 | if (chunk->tsn_missing_report >= 3) { |
| 1570 | chunk->fast_retransmit = 1; | 1572 | chunk->fast_retransmit = 1; |
| 1571 | do_fast_retransmit = 1; | 1573 | do_fast_retransmit = 1; |
| 1572 | } | 1574 | } |
diff --git a/net/socket.c b/net/socket.c index b38a263853c3..a00851f981db 100644 --- a/net/socket.c +++ b/net/socket.c | |||
| @@ -2078,7 +2078,7 @@ void socket_seq_show(struct seq_file *seq) | |||
| 2078 | int cpu; | 2078 | int cpu; |
| 2079 | int counter = 0; | 2079 | int counter = 0; |
| 2080 | 2080 | ||
| 2081 | for (cpu = 0; cpu < NR_CPUS; cpu++) | 2081 | for_each_cpu(cpu) |
| 2082 | counter += per_cpu(sockets_in_use, cpu); | 2082 | counter += per_cpu(sockets_in_use, cpu); |
| 2083 | 2083 | ||
| 2084 | /* It can be negative, by the way. 8) */ | 2084 | /* It can be negative, by the way. 8) */ |
diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 9ac1b8c26c01..8d6f1a176b15 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c | |||
| @@ -184,7 +184,7 @@ rpcauth_gc_credcache(struct rpc_auth *auth, struct hlist_head *free) | |||
| 184 | */ | 184 | */ |
| 185 | struct rpc_cred * | 185 | struct rpc_cred * |
| 186 | rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, | 186 | rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, |
| 187 | int taskflags) | 187 | int flags) |
| 188 | { | 188 | { |
| 189 | struct rpc_cred_cache *cache = auth->au_credcache; | 189 | struct rpc_cred_cache *cache = auth->au_credcache; |
| 190 | HLIST_HEAD(free); | 190 | HLIST_HEAD(free); |
| @@ -193,7 +193,7 @@ rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, | |||
| 193 | *cred = NULL; | 193 | *cred = NULL; |
| 194 | int nr = 0; | 194 | int nr = 0; |
| 195 | 195 | ||
| 196 | if (!(taskflags & RPC_TASK_ROOTCREDS)) | 196 | if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) |
| 197 | nr = acred->uid & RPC_CREDCACHE_MASK; | 197 | nr = acred->uid & RPC_CREDCACHE_MASK; |
| 198 | retry: | 198 | retry: |
| 199 | spin_lock(&rpc_credcache_lock); | 199 | spin_lock(&rpc_credcache_lock); |
| @@ -202,7 +202,7 @@ retry: | |||
| 202 | hlist_for_each_safe(pos, next, &cache->hashtable[nr]) { | 202 | hlist_for_each_safe(pos, next, &cache->hashtable[nr]) { |
| 203 | struct rpc_cred *entry; | 203 | struct rpc_cred *entry; |
| 204 | entry = hlist_entry(pos, struct rpc_cred, cr_hash); | 204 | entry = hlist_entry(pos, struct rpc_cred, cr_hash); |
| 205 | if (entry->cr_ops->crmatch(acred, entry, taskflags)) { | 205 | if (entry->cr_ops->crmatch(acred, entry, flags)) { |
| 206 | hlist_del(&entry->cr_hash); | 206 | hlist_del(&entry->cr_hash); |
| 207 | cred = entry; | 207 | cred = entry; |
| 208 | break; | 208 | break; |
| @@ -224,7 +224,7 @@ retry: | |||
| 224 | rpcauth_destroy_credlist(&free); | 224 | rpcauth_destroy_credlist(&free); |
| 225 | 225 | ||
| 226 | if (!cred) { | 226 | if (!cred) { |
| 227 | new = auth->au_ops->crcreate(auth, acred, taskflags); | 227 | new = auth->au_ops->crcreate(auth, acred, flags); |
| 228 | if (!IS_ERR(new)) { | 228 | if (!IS_ERR(new)) { |
| 229 | #ifdef RPC_DEBUG | 229 | #ifdef RPC_DEBUG |
| 230 | new->cr_magic = RPCAUTH_CRED_MAGIC; | 230 | new->cr_magic = RPCAUTH_CRED_MAGIC; |
| @@ -232,13 +232,21 @@ retry: | |||
| 232 | goto retry; | 232 | goto retry; |
| 233 | } else | 233 | } else |
| 234 | cred = new; | 234 | cred = new; |
| 235 | } else if ((cred->cr_flags & RPCAUTH_CRED_NEW) | ||
| 236 | && cred->cr_ops->cr_init != NULL | ||
| 237 | && !(flags & RPCAUTH_LOOKUP_NEW)) { | ||
| 238 | int res = cred->cr_ops->cr_init(auth, cred); | ||
| 239 | if (res < 0) { | ||
| 240 | put_rpccred(cred); | ||
| 241 | cred = ERR_PTR(res); | ||
| 242 | } | ||
| 235 | } | 243 | } |
| 236 | 244 | ||
| 237 | return (struct rpc_cred *) cred; | 245 | return (struct rpc_cred *) cred; |
| 238 | } | 246 | } |
| 239 | 247 | ||
| 240 | struct rpc_cred * | 248 | struct rpc_cred * |
| 241 | rpcauth_lookupcred(struct rpc_auth *auth, int taskflags) | 249 | rpcauth_lookupcred(struct rpc_auth *auth, int flags) |
| 242 | { | 250 | { |
| 243 | struct auth_cred acred = { | 251 | struct auth_cred acred = { |
| 244 | .uid = current->fsuid, | 252 | .uid = current->fsuid, |
| @@ -250,7 +258,7 @@ rpcauth_lookupcred(struct rpc_auth *auth, int taskflags) | |||
| 250 | dprintk("RPC: looking up %s cred\n", | 258 | dprintk("RPC: looking up %s cred\n", |
| 251 | auth->au_ops->au_name); | 259 | auth->au_ops->au_name); |
| 252 | get_group_info(acred.group_info); | 260 | get_group_info(acred.group_info); |
| 253 | ret = auth->au_ops->lookup_cred(auth, &acred, taskflags); | 261 | ret = auth->au_ops->lookup_cred(auth, &acred, flags); |
| 254 | put_group_info(acred.group_info); | 262 | put_group_info(acred.group_info); |
| 255 | return ret; | 263 | return ret; |
| 256 | } | 264 | } |
| @@ -265,11 +273,14 @@ rpcauth_bindcred(struct rpc_task *task) | |||
| 265 | .group_info = current->group_info, | 273 | .group_info = current->group_info, |
| 266 | }; | 274 | }; |
| 267 | struct rpc_cred *ret; | 275 | struct rpc_cred *ret; |
| 276 | int flags = 0; | ||
| 268 | 277 | ||
| 269 | dprintk("RPC: %4d looking up %s cred\n", | 278 | dprintk("RPC: %4d looking up %s cred\n", |
| 270 | task->tk_pid, task->tk_auth->au_ops->au_name); | 279 | task->tk_pid, task->tk_auth->au_ops->au_name); |
| 271 | get_group_info(acred.group_info); | 280 | get_group_info(acred.group_info); |
| 272 | ret = auth->au_ops->lookup_cred(auth, &acred, task->tk_flags); | 281 | if (task->tk_flags & RPC_TASK_ROOTCREDS) |
| 282 | flags |= RPCAUTH_LOOKUP_ROOTCREDS; | ||
| 283 | ret = auth->au_ops->lookup_cred(auth, &acred, flags); | ||
| 273 | if (!IS_ERR(ret)) | 284 | if (!IS_ERR(ret)) |
| 274 | task->tk_msg.rpc_cred = ret; | 285 | task->tk_msg.rpc_cred = ret; |
| 275 | else | 286 | else |
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 8d782282ec19..bb46efd92e57 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
| @@ -158,6 +158,7 @@ gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx) | |||
| 158 | old = gss_cred->gc_ctx; | 158 | old = gss_cred->gc_ctx; |
| 159 | gss_cred->gc_ctx = ctx; | 159 | gss_cred->gc_ctx = ctx; |
| 160 | cred->cr_flags |= RPCAUTH_CRED_UPTODATE; | 160 | cred->cr_flags |= RPCAUTH_CRED_UPTODATE; |
| 161 | cred->cr_flags &= ~RPCAUTH_CRED_NEW; | ||
| 161 | write_unlock(&gss_ctx_lock); | 162 | write_unlock(&gss_ctx_lock); |
| 162 | if (old) | 163 | if (old) |
| 163 | gss_put_ctx(old); | 164 | gss_put_ctx(old); |
| @@ -580,7 +581,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
| 580 | } else { | 581 | } else { |
| 581 | struct auth_cred acred = { .uid = uid }; | 582 | struct auth_cred acred = { .uid = uid }; |
| 582 | spin_unlock(&gss_auth->lock); | 583 | spin_unlock(&gss_auth->lock); |
| 583 | cred = rpcauth_lookup_credcache(clnt->cl_auth, &acred, 0); | 584 | cred = rpcauth_lookup_credcache(clnt->cl_auth, &acred, RPCAUTH_LOOKUP_NEW); |
| 584 | if (IS_ERR(cred)) { | 585 | if (IS_ERR(cred)) { |
| 585 | err = PTR_ERR(cred); | 586 | err = PTR_ERR(cred); |
| 586 | goto err_put_ctx; | 587 | goto err_put_ctx; |
| @@ -758,13 +759,13 @@ gss_destroy_cred(struct rpc_cred *rc) | |||
| 758 | * Lookup RPCSEC_GSS cred for the current process | 759 | * Lookup RPCSEC_GSS cred for the current process |
| 759 | */ | 760 | */ |
| 760 | static struct rpc_cred * | 761 | static struct rpc_cred * |
| 761 | gss_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int taskflags) | 762 | gss_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) |
| 762 | { | 763 | { |
| 763 | return rpcauth_lookup_credcache(auth, acred, taskflags); | 764 | return rpcauth_lookup_credcache(auth, acred, flags); |
| 764 | } | 765 | } |
| 765 | 766 | ||
| 766 | static struct rpc_cred * | 767 | static struct rpc_cred * |
| 767 | gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int taskflags) | 768 | gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) |
| 768 | { | 769 | { |
| 769 | struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth); | 770 | struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth); |
| 770 | struct gss_cred *cred = NULL; | 771 | struct gss_cred *cred = NULL; |
| @@ -785,13 +786,8 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int taskflags) | |||
| 785 | */ | 786 | */ |
| 786 | cred->gc_flags = 0; | 787 | cred->gc_flags = 0; |
| 787 | cred->gc_base.cr_ops = &gss_credops; | 788 | cred->gc_base.cr_ops = &gss_credops; |
| 789 | cred->gc_base.cr_flags = RPCAUTH_CRED_NEW; | ||
| 788 | cred->gc_service = gss_auth->service; | 790 | cred->gc_service = gss_auth->service; |
| 789 | do { | ||
| 790 | err = gss_create_upcall(gss_auth, cred); | ||
| 791 | } while (err == -EAGAIN); | ||
| 792 | if (err < 0) | ||
| 793 | goto out_err; | ||
| 794 | |||
| 795 | return &cred->gc_base; | 791 | return &cred->gc_base; |
| 796 | 792 | ||
| 797 | out_err: | 793 | out_err: |
| @@ -801,13 +797,34 @@ out_err: | |||
| 801 | } | 797 | } |
| 802 | 798 | ||
| 803 | static int | 799 | static int |
| 804 | gss_match(struct auth_cred *acred, struct rpc_cred *rc, int taskflags) | 800 | gss_cred_init(struct rpc_auth *auth, struct rpc_cred *cred) |
| 801 | { | ||
| 802 | struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth); | ||
| 803 | struct gss_cred *gss_cred = container_of(cred,struct gss_cred, gc_base); | ||
| 804 | int err; | ||
| 805 | |||
| 806 | do { | ||
| 807 | err = gss_create_upcall(gss_auth, gss_cred); | ||
| 808 | } while (err == -EAGAIN); | ||
| 809 | return err; | ||
| 810 | } | ||
| 811 | |||
| 812 | static int | ||
| 813 | gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags) | ||
| 805 | { | 814 | { |
| 806 | struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base); | 815 | struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base); |
| 807 | 816 | ||
| 817 | /* | ||
| 818 | * If the searchflags have set RPCAUTH_LOOKUP_NEW, then | ||
| 819 | * we don't really care if the credential has expired or not, | ||
| 820 | * since the caller should be prepared to reinitialise it. | ||
| 821 | */ | ||
| 822 | if ((flags & RPCAUTH_LOOKUP_NEW) && (rc->cr_flags & RPCAUTH_CRED_NEW)) | ||
| 823 | goto out; | ||
| 808 | /* Don't match with creds that have expired. */ | 824 | /* Don't match with creds that have expired. */ |
| 809 | if (gss_cred->gc_ctx && time_after(jiffies, gss_cred->gc_ctx->gc_expiry)) | 825 | if (gss_cred->gc_ctx && time_after(jiffies, gss_cred->gc_ctx->gc_expiry)) |
| 810 | return 0; | 826 | return 0; |
| 827 | out: | ||
| 811 | return (rc->cr_uid == acred->uid); | 828 | return (rc->cr_uid == acred->uid); |
| 812 | } | 829 | } |
| 813 | 830 | ||
| @@ -1241,6 +1258,7 @@ static struct rpc_authops authgss_ops = { | |||
| 1241 | static struct rpc_credops gss_credops = { | 1258 | static struct rpc_credops gss_credops = { |
| 1242 | .cr_name = "AUTH_GSS", | 1259 | .cr_name = "AUTH_GSS", |
| 1243 | .crdestroy = gss_destroy_cred, | 1260 | .crdestroy = gss_destroy_cred, |
| 1261 | .cr_init = gss_cred_init, | ||
| 1244 | .crmatch = gss_match, | 1262 | .crmatch = gss_match, |
| 1245 | .crmarshal = gss_marshal, | 1263 | .crmarshal = gss_marshal, |
| 1246 | .crrefresh = gss_refresh, | 1264 | .crrefresh = gss_refresh, |
diff --git a/net/sunrpc/auth_unix.c b/net/sunrpc/auth_unix.c index 1b3ed4fd1987..df14b6bfbf10 100644 --- a/net/sunrpc/auth_unix.c +++ b/net/sunrpc/auth_unix.c | |||
| @@ -75,7 +75,7 @@ unx_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) | |||
| 75 | 75 | ||
| 76 | atomic_set(&cred->uc_count, 1); | 76 | atomic_set(&cred->uc_count, 1); |
| 77 | cred->uc_flags = RPCAUTH_CRED_UPTODATE; | 77 | cred->uc_flags = RPCAUTH_CRED_UPTODATE; |
| 78 | if (flags & RPC_TASK_ROOTCREDS) { | 78 | if (flags & RPCAUTH_LOOKUP_ROOTCREDS) { |
| 79 | cred->uc_uid = 0; | 79 | cred->uc_uid = 0; |
| 80 | cred->uc_gid = 0; | 80 | cred->uc_gid = 0; |
| 81 | cred->uc_gids[0] = NOGROUP; | 81 | cred->uc_gids[0] = NOGROUP; |
| @@ -108,12 +108,12 @@ unx_destroy_cred(struct rpc_cred *cred) | |||
| 108 | * request root creds (e.g. for NFS swapping). | 108 | * request root creds (e.g. for NFS swapping). |
| 109 | */ | 109 | */ |
| 110 | static int | 110 | static int |
| 111 | unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int taskflags) | 111 | unx_match(struct auth_cred *acred, struct rpc_cred *rcred, int flags) |
| 112 | { | 112 | { |
| 113 | struct unx_cred *cred = (struct unx_cred *) rcred; | 113 | struct unx_cred *cred = (struct unx_cred *) rcred; |
| 114 | int i; | 114 | int i; |
| 115 | 115 | ||
| 116 | if (!(taskflags & RPC_TASK_ROOTCREDS)) { | 116 | if (!(flags & RPCAUTH_LOOKUP_ROOTCREDS)) { |
| 117 | int groups; | 117 | int groups; |
| 118 | 118 | ||
| 119 | if (cred->uc_uid != acred->uid | 119 | if (cred->uc_uid != acred->uid |
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 9764c80ab0b2..a5c0c7b6e151 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
| @@ -38,44 +38,42 @@ static kmem_cache_t *rpc_inode_cachep __read_mostly; | |||
| 38 | 38 | ||
| 39 | #define RPC_UPCALL_TIMEOUT (30*HZ) | 39 | #define RPC_UPCALL_TIMEOUT (30*HZ) |
| 40 | 40 | ||
| 41 | static void | 41 | static void rpc_purge_list(struct rpc_inode *rpci, struct list_head *head, |
| 42 | __rpc_purge_list(struct rpc_inode *rpci, struct list_head *head, int err) | 42 | void (*destroy_msg)(struct rpc_pipe_msg *), int err) |
| 43 | { | 43 | { |
| 44 | struct rpc_pipe_msg *msg; | 44 | struct rpc_pipe_msg *msg; |
| 45 | void (*destroy_msg)(struct rpc_pipe_msg *); | ||
| 46 | 45 | ||
| 47 | destroy_msg = rpci->ops->destroy_msg; | 46 | if (list_empty(head)) |
| 48 | while (!list_empty(head)) { | 47 | return; |
| 48 | do { | ||
| 49 | msg = list_entry(head->next, struct rpc_pipe_msg, list); | 49 | msg = list_entry(head->next, struct rpc_pipe_msg, list); |
| 50 | list_del_init(&msg->list); | 50 | list_del(&msg->list); |
| 51 | msg->errno = err; | 51 | msg->errno = err; |
| 52 | destroy_msg(msg); | 52 | destroy_msg(msg); |
| 53 | } | 53 | } while (!list_empty(head)); |
| 54 | } | ||
| 55 | |||
| 56 | static void | ||
| 57 | __rpc_purge_upcall(struct inode *inode, int err) | ||
| 58 | { | ||
| 59 | struct rpc_inode *rpci = RPC_I(inode); | ||
| 60 | |||
| 61 | __rpc_purge_list(rpci, &rpci->pipe, err); | ||
| 62 | rpci->pipelen = 0; | ||
| 63 | wake_up(&rpci->waitq); | 54 | wake_up(&rpci->waitq); |
| 64 | } | 55 | } |
| 65 | 56 | ||
| 66 | static void | 57 | static void |
| 67 | rpc_timeout_upcall_queue(void *data) | 58 | rpc_timeout_upcall_queue(void *data) |
| 68 | { | 59 | { |
| 60 | LIST_HEAD(free_list); | ||
| 69 | struct rpc_inode *rpci = (struct rpc_inode *)data; | 61 | struct rpc_inode *rpci = (struct rpc_inode *)data; |
| 70 | struct inode *inode = &rpci->vfs_inode; | 62 | struct inode *inode = &rpci->vfs_inode; |
| 63 | void (*destroy_msg)(struct rpc_pipe_msg *); | ||
| 71 | 64 | ||
| 72 | mutex_lock(&inode->i_mutex); | 65 | spin_lock(&inode->i_lock); |
| 73 | if (rpci->ops == NULL) | 66 | if (rpci->ops == NULL) { |
| 74 | goto out; | 67 | spin_unlock(&inode->i_lock); |
| 75 | if (rpci->nreaders == 0 && !list_empty(&rpci->pipe)) | 68 | return; |
| 76 | __rpc_purge_upcall(inode, -ETIMEDOUT); | 69 | } |
| 77 | out: | 70 | destroy_msg = rpci->ops->destroy_msg; |
| 78 | mutex_unlock(&inode->i_mutex); | 71 | if (rpci->nreaders == 0) { |
| 72 | list_splice_init(&rpci->pipe, &free_list); | ||
| 73 | rpci->pipelen = 0; | ||
| 74 | } | ||
| 75 | spin_unlock(&inode->i_lock); | ||
| 76 | rpc_purge_list(rpci, &free_list, destroy_msg, -ETIMEDOUT); | ||
| 79 | } | 77 | } |
| 80 | 78 | ||
| 81 | int | 79 | int |
| @@ -84,7 +82,7 @@ rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg) | |||
| 84 | struct rpc_inode *rpci = RPC_I(inode); | 82 | struct rpc_inode *rpci = RPC_I(inode); |
| 85 | int res = -EPIPE; | 83 | int res = -EPIPE; |
| 86 | 84 | ||
| 87 | mutex_lock(&inode->i_mutex); | 85 | spin_lock(&inode->i_lock); |
| 88 | if (rpci->ops == NULL) | 86 | if (rpci->ops == NULL) |
| 89 | goto out; | 87 | goto out; |
| 90 | if (rpci->nreaders) { | 88 | if (rpci->nreaders) { |
| @@ -100,7 +98,7 @@ rpc_queue_upcall(struct inode *inode, struct rpc_pipe_msg *msg) | |||
| 100 | res = 0; | 98 | res = 0; |
| 101 | } | 99 | } |
| 102 | out: | 100 | out: |
| 103 | mutex_unlock(&inode->i_mutex); | 101 | spin_unlock(&inode->i_lock); |
| 104 | wake_up(&rpci->waitq); | 102 | wake_up(&rpci->waitq); |
| 105 | return res; | 103 | return res; |
| 106 | } | 104 | } |
| @@ -115,21 +113,29 @@ static void | |||
| 115 | rpc_close_pipes(struct inode *inode) | 113 | rpc_close_pipes(struct inode *inode) |
| 116 | { | 114 | { |
| 117 | struct rpc_inode *rpci = RPC_I(inode); | 115 | struct rpc_inode *rpci = RPC_I(inode); |
| 116 | struct rpc_pipe_ops *ops; | ||
| 118 | 117 | ||
| 119 | mutex_lock(&inode->i_mutex); | 118 | mutex_lock(&inode->i_mutex); |
| 120 | if (rpci->ops != NULL) { | 119 | ops = rpci->ops; |
| 120 | if (ops != NULL) { | ||
| 121 | LIST_HEAD(free_list); | ||
| 122 | |||
| 123 | spin_lock(&inode->i_lock); | ||
| 121 | rpci->nreaders = 0; | 124 | rpci->nreaders = 0; |
| 122 | __rpc_purge_list(rpci, &rpci->in_upcall, -EPIPE); | 125 | list_splice_init(&rpci->in_upcall, &free_list); |
| 123 | __rpc_purge_upcall(inode, -EPIPE); | 126 | list_splice_init(&rpci->pipe, &free_list); |
| 124 | rpci->nwriters = 0; | 127 | rpci->pipelen = 0; |
| 125 | if (rpci->ops->release_pipe) | ||
| 126 | rpci->ops->release_pipe(inode); | ||
| 127 | rpci->ops = NULL; | 128 | rpci->ops = NULL; |
| 129 | spin_unlock(&inode->i_lock); | ||
| 130 | rpc_purge_list(rpci, &free_list, ops->destroy_msg, -EPIPE); | ||
| 131 | rpci->nwriters = 0; | ||
| 132 | if (ops->release_pipe) | ||
| 133 | ops->release_pipe(inode); | ||
| 134 | cancel_delayed_work(&rpci->queue_timeout); | ||
| 135 | flush_scheduled_work(); | ||
| 128 | } | 136 | } |
| 129 | rpc_inode_setowner(inode, NULL); | 137 | rpc_inode_setowner(inode, NULL); |
| 130 | mutex_unlock(&inode->i_mutex); | 138 | mutex_unlock(&inode->i_mutex); |
| 131 | cancel_delayed_work(&rpci->queue_timeout); | ||
| 132 | flush_scheduled_work(); | ||
| 133 | } | 139 | } |
| 134 | 140 | ||
| 135 | static struct inode * | 141 | static struct inode * |
| @@ -177,16 +183,26 @@ rpc_pipe_release(struct inode *inode, struct file *filp) | |||
| 177 | goto out; | 183 | goto out; |
| 178 | msg = (struct rpc_pipe_msg *)filp->private_data; | 184 | msg = (struct rpc_pipe_msg *)filp->private_data; |
| 179 | if (msg != NULL) { | 185 | if (msg != NULL) { |
| 186 | spin_lock(&inode->i_lock); | ||
| 180 | msg->errno = -EAGAIN; | 187 | msg->errno = -EAGAIN; |
| 181 | list_del_init(&msg->list); | 188 | list_del(&msg->list); |
| 189 | spin_unlock(&inode->i_lock); | ||
| 182 | rpci->ops->destroy_msg(msg); | 190 | rpci->ops->destroy_msg(msg); |
| 183 | } | 191 | } |
| 184 | if (filp->f_mode & FMODE_WRITE) | 192 | if (filp->f_mode & FMODE_WRITE) |
| 185 | rpci->nwriters --; | 193 | rpci->nwriters --; |
| 186 | if (filp->f_mode & FMODE_READ) | 194 | if (filp->f_mode & FMODE_READ) { |
| 187 | rpci->nreaders --; | 195 | rpci->nreaders --; |
| 188 | if (!rpci->nreaders) | 196 | if (rpci->nreaders == 0) { |
| 189 | __rpc_purge_upcall(inode, -EAGAIN); | 197 | LIST_HEAD(free_list); |
| 198 | spin_lock(&inode->i_lock); | ||
| 199 | list_splice_init(&rpci->pipe, &free_list); | ||
| 200 | rpci->pipelen = 0; | ||
| 201 | spin_unlock(&inode->i_lock); | ||
| 202 | rpc_purge_list(rpci, &free_list, | ||
| 203 | rpci->ops->destroy_msg, -EAGAIN); | ||
| 204 | } | ||
| 205 | } | ||
| 190 | if (rpci->ops->release_pipe) | 206 | if (rpci->ops->release_pipe) |
| 191 | rpci->ops->release_pipe(inode); | 207 | rpci->ops->release_pipe(inode); |
| 192 | out: | 208 | out: |
| @@ -209,6 +225,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset) | |||
| 209 | } | 225 | } |
| 210 | msg = filp->private_data; | 226 | msg = filp->private_data; |
| 211 | if (msg == NULL) { | 227 | if (msg == NULL) { |
| 228 | spin_lock(&inode->i_lock); | ||
| 212 | if (!list_empty(&rpci->pipe)) { | 229 | if (!list_empty(&rpci->pipe)) { |
| 213 | msg = list_entry(rpci->pipe.next, | 230 | msg = list_entry(rpci->pipe.next, |
| 214 | struct rpc_pipe_msg, | 231 | struct rpc_pipe_msg, |
| @@ -218,6 +235,7 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset) | |||
| 218 | filp->private_data = msg; | 235 | filp->private_data = msg; |
| 219 | msg->copied = 0; | 236 | msg->copied = 0; |
| 220 | } | 237 | } |
| 238 | spin_unlock(&inode->i_lock); | ||
| 221 | if (msg == NULL) | 239 | if (msg == NULL) |
| 222 | goto out_unlock; | 240 | goto out_unlock; |
| 223 | } | 241 | } |
| @@ -225,7 +243,9 @@ rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset) | |||
| 225 | res = rpci->ops->upcall(filp, msg, buf, len); | 243 | res = rpci->ops->upcall(filp, msg, buf, len); |
| 226 | if (res < 0 || msg->len == msg->copied) { | 244 | if (res < 0 || msg->len == msg->copied) { |
| 227 | filp->private_data = NULL; | 245 | filp->private_data = NULL; |
| 228 | list_del_init(&msg->list); | 246 | spin_lock(&inode->i_lock); |
| 247 | list_del(&msg->list); | ||
| 248 | spin_unlock(&inode->i_lock); | ||
| 229 | rpci->ops->destroy_msg(msg); | 249 | rpci->ops->destroy_msg(msg); |
| 230 | } | 250 | } |
| 231 | out_unlock: | 251 | out_unlock: |
| @@ -610,7 +630,7 @@ rpc_lookup_negative(char *path, struct nameidata *nd) | |||
| 610 | return ERR_PTR(error); | 630 | return ERR_PTR(error); |
| 611 | dir = nd->dentry->d_inode; | 631 | dir = nd->dentry->d_inode; |
| 612 | mutex_lock(&dir->i_mutex); | 632 | mutex_lock(&dir->i_mutex); |
| 613 | dentry = lookup_hash(nd); | 633 | dentry = lookup_one_len(nd->last.name, nd->dentry, nd->last.len); |
| 614 | if (IS_ERR(dentry)) | 634 | if (IS_ERR(dentry)) |
| 615 | goto out_err; | 635 | goto out_err; |
| 616 | if (dentry->d_inode) { | 636 | if (dentry->d_inode) { |
| @@ -672,7 +692,7 @@ rpc_rmdir(char *path) | |||
| 672 | return error; | 692 | return error; |
| 673 | dir = nd.dentry->d_inode; | 693 | dir = nd.dentry->d_inode; |
| 674 | mutex_lock(&dir->i_mutex); | 694 | mutex_lock(&dir->i_mutex); |
| 675 | dentry = lookup_hash(&nd); | 695 | dentry = lookup_one_len(nd.last.name, nd.dentry, nd.last.len); |
| 676 | if (IS_ERR(dentry)) { | 696 | if (IS_ERR(dentry)) { |
| 677 | error = PTR_ERR(dentry); | 697 | error = PTR_ERR(dentry); |
| 678 | goto out_release; | 698 | goto out_release; |
| @@ -733,7 +753,7 @@ rpc_unlink(char *path) | |||
| 733 | return error; | 753 | return error; |
| 734 | dir = nd.dentry->d_inode; | 754 | dir = nd.dentry->d_inode; |
| 735 | mutex_lock(&dir->i_mutex); | 755 | mutex_lock(&dir->i_mutex); |
| 736 | dentry = lookup_hash(&nd); | 756 | dentry = lookup_one_len(nd.last.name, nd.dentry, nd.last.len); |
| 737 | if (IS_ERR(dentry)) { | 757 | if (IS_ERR(dentry)) { |
| 738 | error = PTR_ERR(dentry); | 758 | error = PTR_ERR(dentry); |
| 739 | goto out_release; | 759 | goto out_release; |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 077bbf9fb9b7..dbf4620768d6 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -13,7 +13,6 @@ | |||
| 13 | * | 13 | * |
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | #include <asm/bug.h> | ||
| 17 | #include <linux/config.h> | 16 | #include <linux/config.h> |
| 18 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
| 19 | #include <linux/kmod.h> | 18 | #include <linux/kmod.h> |
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 5760e057ecba..d64aae85c378 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile | |||
| @@ -123,7 +123,17 @@ KBUILD_HAVE_NLS := $(shell \ | |||
| 123 | then echo yes ; \ | 123 | then echo yes ; \ |
| 124 | else echo no ; fi) | 124 | else echo no ; fi) |
| 125 | ifeq ($(KBUILD_HAVE_NLS),no) | 125 | ifeq ($(KBUILD_HAVE_NLS),no) |
| 126 | HOSTCFLAGS += -DKBUILD_NO_NLS | 126 | HOSTCFLAGS += -DKBUILD_NO_NLS |
| 127 | else | ||
| 128 | KBUILD_NEED_LINTL := $(shell \ | ||
| 129 | if echo -e "\#include <libintl.h>\nint main(int a, char** b) { gettext(\"\"); return 0; }\n" | \ | ||
| 130 | $(HOSTCC) $(HOSTCFLAGS) -x c - -o /dev/null> /dev/null 2>&1 ; \ | ||
| 131 | then echo no ; \ | ||
| 132 | else echo yes ; fi) | ||
| 133 | ifeq ($(KBUILD_NEED_LINTL),yes) | ||
| 134 | HOSTLOADLIBES_conf += -lintl | ||
| 135 | HOSTLOADLIBES_mconf += -lintl | ||
| 136 | endif | ||
| 127 | endif | 137 | endif |
| 128 | 138 | ||
| 129 | # generated files seem to need this to find local include files | 139 | # generated files seem to need this to find local include files |
diff --git a/scripts/kconfig/lxdialog/Makefile b/scripts/kconfig/lxdialog/Makefile index fae3e29fc924..bbf4887cff74 100644 --- a/scripts/kconfig/lxdialog/Makefile +++ b/scripts/kconfig/lxdialog/Makefile | |||
| @@ -2,8 +2,11 @@ | |||
| 2 | # | 2 | # |
| 3 | 3 | ||
| 4 | check-lxdialog := $(srctree)/$(src)/check-lxdialog.sh | 4 | check-lxdialog := $(srctree)/$(src)/check-lxdialog.sh |
| 5 | HOST_EXTRACFLAGS:= $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) | 5 | |
| 6 | HOST_LOADLIBES := $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) | 6 | # Use reursively expanded variables so we do not call gcc unless |
| 7 | # we really need to do so. (Do not call gcc as part of make mrproper) | ||
| 8 | HOST_EXTRACFLAGS = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) | ||
| 9 | HOST_LOADLIBES = $(shell $(CONFIG_SHELL) $(check-lxdialog) -ldflags $(HOSTCC)) | ||
| 7 | 10 | ||
| 8 | HOST_EXTRACFLAGS += -DLOCALE | 11 | HOST_EXTRACFLAGS += -DLOCALE |
| 9 | 12 | ||
diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh index 448e353923f3..120d624e672c 100644 --- a/scripts/kconfig/lxdialog/check-lxdialog.sh +++ b/scripts/kconfig/lxdialog/check-lxdialog.sh | |||
| @@ -4,17 +4,17 @@ | |||
| 4 | # What library to link | 4 | # What library to link |
| 5 | ldflags() | 5 | ldflags() |
| 6 | { | 6 | { |
| 7 | echo "main() {}" | $cc -lncursesw -xc - -o /dev/null 2> /dev/null | 7 | $cc -print-file-name=libncursesw.so | grep -q / |
| 8 | if [ $? -eq 0 ]; then | 8 | if [ $? -eq 0 ]; then |
| 9 | echo '-lncursesw' | 9 | echo '-lncursesw' |
| 10 | exit | 10 | exit |
| 11 | fi | 11 | fi |
| 12 | echo "main() {}" | $cc -lncurses -xc - -o /dev/null 2> /dev/null | 12 | $cc -print-file-name=libncurses.so | grep -q / |
| 13 | if [ $? -eq 0 ]; then | 13 | if [ $? -eq 0 ]; then |
| 14 | echo '-lncurses' | 14 | echo '-lncurses' |
| 15 | exit | 15 | exit |
| 16 | fi | 16 | fi |
| 17 | echo "main() {}" | $cc -lcurses -xc - -o /dev/null 2> /dev/null | 17 | $cc -print-file-name=libcurses.so | grep -q / |
| 18 | if [ $? -eq 0 ]; then | 18 | if [ $? -eq 0 ]; then |
| 19 | echo '-lcurses' | 19 | echo '-lcurses' |
| 20 | exit | 20 | exit |
| @@ -36,10 +36,13 @@ ccflags() | |||
| 36 | fi | 36 | fi |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | compiler="" | 39 | # Temp file, try to clean up after us |
| 40 | tmp=.lxdialog.tmp | ||
| 41 | trap "rm -f $tmp" 0 1 2 3 15 | ||
| 42 | |||
| 40 | # Check if we can link to ncurses | 43 | # Check if we can link to ncurses |
| 41 | check() { | 44 | check() { |
| 42 | echo "main() {}" | $cc -xc - -o /dev/null 2> /dev/null | 45 | echo "main() {}" | $cc -xc - -o $tmp 2> /dev/null |
| 43 | if [ $? != 0 ]; then | 46 | if [ $? != 0 ]; then |
| 44 | echo " *** Unable to find the ncurses libraries." 1>&2 | 47 | echo " *** Unable to find the ncurses libraries." 1>&2 |
| 45 | echo " *** make menuconfig require the ncurses libraries" 1>&2 | 48 | echo " *** make menuconfig require the ncurses libraries" 1>&2 |
| @@ -59,6 +62,7 @@ if [ $# == 0 ]; then | |||
| 59 | exit 1 | 62 | exit 1 |
| 60 | fi | 63 | fi |
| 61 | 64 | ||
| 65 | cc="" | ||
| 62 | case "$1" in | 66 | case "$1" in |
| 63 | "-check") | 67 | "-check") |
| 64 | shift | 68 | shift |
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 90db5c76cf6e..0c62798ac7d8 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
| @@ -67,9 +67,10 @@ asmlinkage long sys_add_key(const char __user *_type, | |||
| 67 | description = kmalloc(dlen + 1, GFP_KERNEL); | 67 | description = kmalloc(dlen + 1, GFP_KERNEL); |
| 68 | if (!description) | 68 | if (!description) |
| 69 | goto error; | 69 | goto error; |
| 70 | description[dlen] = '\0'; | ||
| 70 | 71 | ||
| 71 | ret = -EFAULT; | 72 | ret = -EFAULT; |
| 72 | if (copy_from_user(description, _description, dlen + 1) != 0) | 73 | if (copy_from_user(description, _description, dlen) != 0) |
| 73 | goto error2; | 74 | goto error2; |
| 74 | 75 | ||
| 75 | /* pull the payload in if one was supplied */ | 76 | /* pull the payload in if one was supplied */ |
| @@ -161,9 +162,10 @@ asmlinkage long sys_request_key(const char __user *_type, | |||
| 161 | description = kmalloc(dlen + 1, GFP_KERNEL); | 162 | description = kmalloc(dlen + 1, GFP_KERNEL); |
| 162 | if (!description) | 163 | if (!description) |
| 163 | goto error; | 164 | goto error; |
| 165 | description[dlen] = '\0'; | ||
| 164 | 166 | ||
| 165 | ret = -EFAULT; | 167 | ret = -EFAULT; |
| 166 | if (copy_from_user(description, _description, dlen + 1) != 0) | 168 | if (copy_from_user(description, _description, dlen) != 0) |
| 167 | goto error2; | 169 | goto error2; |
| 168 | 170 | ||
| 169 | /* pull the callout info into kernel space */ | 171 | /* pull the callout info into kernel space */ |
| @@ -182,9 +184,10 @@ asmlinkage long sys_request_key(const char __user *_type, | |||
| 182 | callout_info = kmalloc(dlen + 1, GFP_KERNEL); | 184 | callout_info = kmalloc(dlen + 1, GFP_KERNEL); |
| 183 | if (!callout_info) | 185 | if (!callout_info) |
| 184 | goto error2; | 186 | goto error2; |
| 187 | callout_info[dlen] = '\0'; | ||
| 185 | 188 | ||
| 186 | ret = -EFAULT; | 189 | ret = -EFAULT; |
| 187 | if (copy_from_user(callout_info, _callout_info, dlen + 1) != 0) | 190 | if (copy_from_user(callout_info, _callout_info, dlen) != 0) |
| 188 | goto error3; | 191 | goto error3; |
| 189 | } | 192 | } |
| 190 | 193 | ||
| @@ -279,9 +282,10 @@ long keyctl_join_session_keyring(const char __user *_name) | |||
| 279 | name = kmalloc(nlen + 1, GFP_KERNEL); | 282 | name = kmalloc(nlen + 1, GFP_KERNEL); |
| 280 | if (!name) | 283 | if (!name) |
| 281 | goto error; | 284 | goto error; |
| 285 | name[nlen] = '\0'; | ||
| 282 | 286 | ||
| 283 | ret = -EFAULT; | 287 | ret = -EFAULT; |
| 284 | if (copy_from_user(name, _name, nlen + 1) != 0) | 288 | if (copy_from_user(name, _name, nlen) != 0) |
| 285 | goto error2; | 289 | goto error2; |
| 286 | } | 290 | } |
| 287 | 291 | ||
| @@ -583,9 +587,10 @@ long keyctl_keyring_search(key_serial_t ringid, | |||
| 583 | description = kmalloc(dlen + 1, GFP_KERNEL); | 587 | description = kmalloc(dlen + 1, GFP_KERNEL); |
| 584 | if (!description) | 588 | if (!description) |
| 585 | goto error; | 589 | goto error; |
| 590 | description[dlen] = '\0'; | ||
| 586 | 591 | ||
| 587 | ret = -EFAULT; | 592 | ret = -EFAULT; |
| 588 | if (copy_from_user(description, _description, dlen + 1) != 0) | 593 | if (copy_from_user(description, _description, dlen) != 0) |
| 589 | goto error2; | 594 | goto error2; |
| 590 | 595 | ||
| 591 | /* get the keyring at which to begin the search */ | 596 | /* get the keyring at which to begin the search */ |
diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig index b59582b92283..f636f53ca544 100644 --- a/security/selinux/Kconfig +++ b/security/selinux/Kconfig | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | config SECURITY_SELINUX | 1 | config SECURITY_SELINUX |
| 2 | bool "NSA SELinux Support" | 2 | bool "NSA SELinux Support" |
| 3 | depends on SECURITY && NET && INET | 3 | depends on SECURITY_NETWORK && AUDIT && NET && INET |
| 4 | default n | 4 | default n |
| 5 | help | 5 | help |
| 6 | This selects NSA Security-Enhanced Linux (SELinux). | 6 | This selects NSA Security-Enhanced Linux (SELinux). |
diff --git a/security/selinux/Makefile b/security/selinux/Makefile index 06d54d9d20a5..688c0a267b62 100644 --- a/security/selinux/Makefile +++ b/security/selinux/Makefile | |||
| @@ -4,9 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | obj-$(CONFIG_SECURITY_SELINUX) := selinux.o ss/ | 5 | obj-$(CONFIG_SECURITY_SELINUX) := selinux.o ss/ |
| 6 | 6 | ||
| 7 | selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o | 7 | selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o |
| 8 | |||
| 9 | selinux-$(CONFIG_SECURITY_NETWORK) += netif.o | ||
| 10 | 8 | ||
| 11 | selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o | 9 | selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o |
| 12 | 10 | ||
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index 53d6c7bbf564..ac5d69bb3377 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c | |||
| @@ -43,13 +43,11 @@ static const struct av_perm_to_string | |||
| 43 | #undef S_ | 43 | #undef S_ |
| 44 | }; | 44 | }; |
| 45 | 45 | ||
| 46 | #ifdef CONFIG_AUDIT | ||
| 47 | static const char *class_to_string[] = { | 46 | static const char *class_to_string[] = { |
| 48 | #define S_(s) s, | 47 | #define S_(s) s, |
| 49 | #include "class_to_string.h" | 48 | #include "class_to_string.h" |
| 50 | #undef S_ | 49 | #undef S_ |
| 51 | }; | 50 | }; |
| 52 | #endif | ||
| 53 | 51 | ||
| 54 | #define TB_(s) static const char * s [] = { | 52 | #define TB_(s) static const char * s [] = { |
| 55 | #define TE_(s) }; | 53 | #define TE_(s) }; |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 4ae834d89bce..b7773bf68efa 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -232,7 +232,6 @@ static void superblock_free_security(struct super_block *sb) | |||
| 232 | kfree(sbsec); | 232 | kfree(sbsec); |
| 233 | } | 233 | } |
| 234 | 234 | ||
| 235 | #ifdef CONFIG_SECURITY_NETWORK | ||
| 236 | static int sk_alloc_security(struct sock *sk, int family, gfp_t priority) | 235 | static int sk_alloc_security(struct sock *sk, int family, gfp_t priority) |
| 237 | { | 236 | { |
| 238 | struct sk_security_struct *ssec; | 237 | struct sk_security_struct *ssec; |
| @@ -261,7 +260,6 @@ static void sk_free_security(struct sock *sk) | |||
| 261 | sk->sk_security = NULL; | 260 | sk->sk_security = NULL; |
| 262 | kfree(ssec); | 261 | kfree(ssec); |
| 263 | } | 262 | } |
| 264 | #endif /* CONFIG_SECURITY_NETWORK */ | ||
| 265 | 263 | ||
| 266 | /* The security server must be initialized before | 264 | /* The security server must be initialized before |
| 267 | any labeling or access decisions can be provided. */ | 265 | any labeling or access decisions can be provided. */ |
| @@ -2736,8 +2734,6 @@ static void selinux_task_to_inode(struct task_struct *p, | |||
| 2736 | return; | 2734 | return; |
| 2737 | } | 2735 | } |
| 2738 | 2736 | ||
| 2739 | #ifdef CONFIG_SECURITY_NETWORK | ||
| 2740 | |||
| 2741 | /* Returns error only if unable to parse addresses */ | 2737 | /* Returns error only if unable to parse addresses */ |
| 2742 | static int selinux_parse_skb_ipv4(struct sk_buff *skb, struct avc_audit_data *ad) | 2738 | static int selinux_parse_skb_ipv4(struct sk_buff *skb, struct avc_audit_data *ad) |
| 2743 | { | 2739 | { |
| @@ -3556,15 +3552,6 @@ static unsigned int selinux_ipv6_postroute_last(unsigned int hooknum, | |||
| 3556 | 3552 | ||
| 3557 | #endif /* CONFIG_NETFILTER */ | 3553 | #endif /* CONFIG_NETFILTER */ |
| 3558 | 3554 | ||
| 3559 | #else | ||
| 3560 | |||
| 3561 | static inline int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) | ||
| 3562 | { | ||
| 3563 | return 0; | ||
| 3564 | } | ||
| 3565 | |||
| 3566 | #endif /* CONFIG_SECURITY_NETWORK */ | ||
| 3567 | |||
| 3568 | static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) | 3555 | static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) |
| 3569 | { | 3556 | { |
| 3570 | struct task_security_struct *tsec; | 3557 | struct task_security_struct *tsec; |
| @@ -4340,7 +4327,6 @@ static struct security_operations selinux_ops = { | |||
| 4340 | .getprocattr = selinux_getprocattr, | 4327 | .getprocattr = selinux_getprocattr, |
| 4341 | .setprocattr = selinux_setprocattr, | 4328 | .setprocattr = selinux_setprocattr, |
| 4342 | 4329 | ||
| 4343 | #ifdef CONFIG_SECURITY_NETWORK | ||
| 4344 | .unix_stream_connect = selinux_socket_unix_stream_connect, | 4330 | .unix_stream_connect = selinux_socket_unix_stream_connect, |
| 4345 | .unix_may_send = selinux_socket_unix_may_send, | 4331 | .unix_may_send = selinux_socket_unix_may_send, |
| 4346 | 4332 | ||
| @@ -4362,7 +4348,6 @@ static struct security_operations selinux_ops = { | |||
| 4362 | .sk_alloc_security = selinux_sk_alloc_security, | 4348 | .sk_alloc_security = selinux_sk_alloc_security, |
| 4363 | .sk_free_security = selinux_sk_free_security, | 4349 | .sk_free_security = selinux_sk_free_security, |
| 4364 | .sk_getsid = selinux_sk_getsid_security, | 4350 | .sk_getsid = selinux_sk_getsid_security, |
| 4365 | #endif | ||
| 4366 | 4351 | ||
| 4367 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 4352 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
| 4368 | .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, | 4353 | .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, |
| @@ -4440,7 +4425,7 @@ next_sb: | |||
| 4440 | all processes and objects when they are created. */ | 4425 | all processes and objects when they are created. */ |
| 4441 | security_initcall(selinux_init); | 4426 | security_initcall(selinux_init); |
| 4442 | 4427 | ||
| 4443 | #if defined(CONFIG_SECURITY_NETWORK) && defined(CONFIG_NETFILTER) | 4428 | #if defined(CONFIG_NETFILTER) |
| 4444 | 4429 | ||
| 4445 | static struct nf_hook_ops selinux_ipv4_op = { | 4430 | static struct nf_hook_ops selinux_ipv4_op = { |
| 4446 | .hook = selinux_ipv4_postroute_last, | 4431 | .hook = selinux_ipv4_postroute_last, |
| @@ -4501,13 +4486,13 @@ static void selinux_nf_ip_exit(void) | |||
| 4501 | } | 4486 | } |
| 4502 | #endif | 4487 | #endif |
| 4503 | 4488 | ||
| 4504 | #else /* CONFIG_SECURITY_NETWORK && CONFIG_NETFILTER */ | 4489 | #else /* CONFIG_NETFILTER */ |
| 4505 | 4490 | ||
| 4506 | #ifdef CONFIG_SECURITY_SELINUX_DISABLE | 4491 | #ifdef CONFIG_SECURITY_SELINUX_DISABLE |
| 4507 | #define selinux_nf_ip_exit() | 4492 | #define selinux_nf_ip_exit() |
| 4508 | #endif | 4493 | #endif |
| 4509 | 4494 | ||
| 4510 | #endif /* CONFIG_SECURITY_NETWORK && CONFIG_NETFILTER */ | 4495 | #endif /* CONFIG_NETFILTER */ |
| 4511 | 4496 | ||
| 4512 | #ifdef CONFIG_SECURITY_SELINUX_DISABLE | 4497 | #ifdef CONFIG_SECURITY_SELINUX_DISABLE |
| 4513 | int selinux_disable(void) | 4498 | int selinux_disable(void) |
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 54147c1f6361..149feb410654 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c | |||
| @@ -882,14 +882,20 @@ static int __devinit aaci_probe(struct amba_device *dev, void *id) | |||
| 882 | writel(0x1fff, aaci->base + AACI_INTCLR); | 882 | writel(0x1fff, aaci->base + AACI_INTCLR); |
| 883 | writel(aaci->maincr, aaci->base + AACI_MAINCR); | 883 | writel(aaci->maincr, aaci->base + AACI_MAINCR); |
| 884 | 884 | ||
| 885 | ret = aaci_probe_ac97(aaci); | ||
| 886 | if (ret) | ||
| 887 | goto out; | ||
| 888 | |||
| 885 | /* | 889 | /* |
| 886 | * Size the FIFOs. | 890 | * Size the FIFOs (must be multiple of 16). |
| 887 | */ | 891 | */ |
| 888 | aaci->fifosize = aaci_size_fifo(aaci); | 892 | aaci->fifosize = aaci_size_fifo(aaci); |
| 889 | 893 | if (aaci->fifosize & 15) { | |
| 890 | ret = aaci_probe_ac97(aaci); | 894 | printk(KERN_WARNING "AACI: fifosize = %d not supported\n", |
| 891 | if (ret) | 895 | aaci->fifosize); |
| 896 | ret = -ENODEV; | ||
| 892 | goto out; | 897 | goto out; |
| 898 | } | ||
| 893 | 899 | ||
| 894 | ret = aaci_init_pcm(aaci); | 900 | ret = aaci_init_pcm(aaci); |
| 895 | if (ret) | 901 | if (ret) |
diff --git a/sound/oss/dmasound/tas_common.h b/sound/oss/dmasound/tas_common.h index 3a6d48666db0..0741c28e56ce 100644 --- a/sound/oss/dmasound/tas_common.h +++ b/sound/oss/dmasound/tas_common.h | |||
| @@ -178,10 +178,10 @@ tas_write_register( struct tas_data_t *self, | |||
| 178 | if (write_mode & WRITE_SHADOW) | 178 | if (write_mode & WRITE_SHADOW) |
| 179 | memcpy(self->shadow[reg_num],data,reg_width); | 179 | memcpy(self->shadow[reg_num],data,reg_width); |
| 180 | if (write_mode & WRITE_HW) { | 180 | if (write_mode & WRITE_HW) { |
| 181 | rc=i2c_smbus_write_block_data(self->client, | 181 | rc=i2c_smbus_write_i2c_block_data(self->client, |
| 182 | reg_num, | 182 | reg_num, |
| 183 | reg_width, | 183 | reg_width, |
| 184 | data); | 184 | data); |
| 185 | if (rc < 0) { | 185 | if (rc < 0) { |
| 186 | printk("tas: I2C block write failed \n"); | 186 | printk("tas: I2C block write failed \n"); |
| 187 | return rc; | 187 | return rc; |
| @@ -199,10 +199,10 @@ tas_sync_register( struct tas_data_t *self, | |||
| 199 | 199 | ||
| 200 | if (reg_width==0 || self==NULL) | 200 | if (reg_width==0 || self==NULL) |
| 201 | return -EINVAL; | 201 | return -EINVAL; |
| 202 | rc=i2c_smbus_write_block_data(self->client, | 202 | rc=i2c_smbus_write_i2c_block_data(self->client, |
| 203 | reg_num, | 203 | reg_num, |
| 204 | reg_width, | 204 | reg_width, |
| 205 | self->shadow[reg_num]); | 205 | self->shadow[reg_num]); |
| 206 | if (rc < 0) { | 206 | if (rc < 0) { |
| 207 | printk("tas: I2C block write failed \n"); | 207 | printk("tas: I2C block write failed \n"); |
| 208 | return rc; | 208 | return rc; |
diff --git a/sound/oss/emu10k1/recmgr.c b/sound/oss/emu10k1/recmgr.c index 67c3fd04cfdd..2ce56180e7d4 100644 --- a/sound/oss/emu10k1/recmgr.c +++ b/sound/oss/emu10k1/recmgr.c | |||
| @@ -29,7 +29,7 @@ | |||
| 29 | ********************************************************************** | 29 | ********************************************************************** |
| 30 | */ | 30 | */ |
| 31 | 31 | ||
| 32 | #include <asm/delay.h> | 32 | #include <linux/delay.h> |
| 33 | #include "8010.h" | 33 | #include "8010.h" |
| 34 | #include "recmgr.h" | 34 | #include "recmgr.h" |
| 35 | 35 | ||
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c index 4988f873a7ba..aa57170101fd 100644 --- a/sound/ppc/pmac.c +++ b/sound/ppc/pmac.c | |||
| @@ -66,7 +66,7 @@ static int snd_pmac_dbdma_alloc(struct snd_pmac *chip, struct pmac_dbdma *rec, i | |||
| 66 | 66 | ||
| 67 | static void snd_pmac_dbdma_free(struct snd_pmac *chip, struct pmac_dbdma *rec) | 67 | static void snd_pmac_dbdma_free(struct snd_pmac *chip, struct pmac_dbdma *rec) |
| 68 | { | 68 | { |
| 69 | if (rec) { | 69 | if (rec->space) { |
| 70 | unsigned int rsize = sizeof(struct dbdma_cmd) * (rec->size + 1); | 70 | unsigned int rsize = sizeof(struct dbdma_cmd) * (rec->size + 1); |
| 71 | 71 | ||
| 72 | dma_free_coherent(&chip->pdev->dev, rsize, rec->space, rec->dma_base); | 72 | dma_free_coherent(&chip->pdev->dev, rsize, rec->space, rec->dma_base); |
| @@ -881,6 +881,7 @@ static int __init snd_pmac_detect(struct snd_pmac *chip) | |||
| 881 | chip->can_capture = 1; | 881 | chip->can_capture = 1; |
| 882 | chip->num_freqs = ARRAY_SIZE(awacs_freqs); | 882 | chip->num_freqs = ARRAY_SIZE(awacs_freqs); |
| 883 | chip->freq_table = awacs_freqs; | 883 | chip->freq_table = awacs_freqs; |
| 884 | chip->pdev = NULL; | ||
| 884 | 885 | ||
| 885 | chip->control_mask = MASK_IEPC | MASK_IEE | 0x11; /* default */ | 886 | chip->control_mask = MASK_IEPC | MASK_IEE | 0x11; /* default */ |
| 886 | 887 | ||
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c index 15c63cb2ccba..838fc113c441 100644 --- a/sound/ppc/tumbler.c +++ b/sound/ppc/tumbler.c | |||
| @@ -239,8 +239,8 @@ static int tumbler_set_master_volume(struct pmac_tumbler *mix) | |||
| 239 | block[4] = (right_vol >> 8) & 0xff; | 239 | block[4] = (right_vol >> 8) & 0xff; |
| 240 | block[5] = (right_vol >> 0) & 0xff; | 240 | block[5] = (right_vol >> 0) & 0xff; |
| 241 | 241 | ||
| 242 | if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_VOL, | 242 | if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_VOL, 6, |
| 243 | 6, block) < 0) { | 243 | block) < 0) { |
| 244 | snd_printk("failed to set volume \n"); | 244 | snd_printk("failed to set volume \n"); |
| 245 | return -EINVAL; | 245 | return -EINVAL; |
| 246 | } | 246 | } |
| @@ -345,8 +345,8 @@ static int tumbler_set_drc(struct pmac_tumbler *mix) | |||
| 345 | val[1] = 0; | 345 | val[1] = 0; |
| 346 | } | 346 | } |
| 347 | 347 | ||
| 348 | if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_DRC, | 348 | if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_DRC, |
| 349 | 2, val) < 0) { | 349 | 2, val) < 0) { |
| 350 | snd_printk("failed to set DRC\n"); | 350 | snd_printk("failed to set DRC\n"); |
| 351 | return -EINVAL; | 351 | return -EINVAL; |
| 352 | } | 352 | } |
| @@ -381,8 +381,8 @@ static int snapper_set_drc(struct pmac_tumbler *mix) | |||
| 381 | val[4] = 0x60; | 381 | val[4] = 0x60; |
| 382 | val[5] = 0xa0; | 382 | val[5] = 0xa0; |
| 383 | 383 | ||
| 384 | if (i2c_smbus_write_block_data(mix->i2c.client, TAS_REG_DRC, | 384 | if (i2c_smbus_write_i2c_block_data(mix->i2c.client, TAS_REG_DRC, |
| 385 | 6, val) < 0) { | 385 | 6, val) < 0) { |
| 386 | snd_printk("failed to set DRC\n"); | 386 | snd_printk("failed to set DRC\n"); |
| 387 | return -EINVAL; | 387 | return -EINVAL; |
| 388 | } | 388 | } |
| @@ -492,8 +492,8 @@ static int tumbler_set_mono_volume(struct pmac_tumbler *mix, | |||
| 492 | vol = info->table[vol]; | 492 | vol = info->table[vol]; |
| 493 | for (i = 0; i < info->bytes; i++) | 493 | for (i = 0; i < info->bytes; i++) |
| 494 | block[i] = (vol >> ((info->bytes - i - 1) * 8)) & 0xff; | 494 | block[i] = (vol >> ((info->bytes - i - 1) * 8)) & 0xff; |
| 495 | if (i2c_smbus_write_block_data(mix->i2c.client, info->reg, | 495 | if (i2c_smbus_write_i2c_block_data(mix->i2c.client, info->reg, |
| 496 | info->bytes, block) < 0) { | 496 | info->bytes, block) < 0) { |
| 497 | snd_printk("failed to set mono volume %d\n", info->index); | 497 | snd_printk("failed to set mono volume %d\n", info->index); |
| 498 | return -EINVAL; | 498 | return -EINVAL; |
| 499 | } | 499 | } |
| @@ -625,7 +625,8 @@ static int snapper_set_mix_vol1(struct pmac_tumbler *mix, int idx, int ch, int r | |||
| 625 | for (j = 0; j < 3; j++) | 625 | for (j = 0; j < 3; j++) |
| 626 | block[i * 3 + j] = (vol >> ((2 - j) * 8)) & 0xff; | 626 | block[i * 3 + j] = (vol >> ((2 - j) * 8)) & 0xff; |
| 627 | } | 627 | } |
| 628 | if (i2c_smbus_write_block_data(mix->i2c.client, reg, 9, block) < 0) { | 628 | if (i2c_smbus_write_i2c_block_data(mix->i2c.client, reg, |
| 629 | 9, block) < 0) { | ||
| 629 | snd_printk("failed to set mono volume %d\n", reg); | 630 | snd_printk("failed to set mono volume %d\n", reg); |
| 630 | return -EINVAL; | 631 | return -EINVAL; |
| 631 | } | 632 | } |
