Since for-2.6.40/core was forked off the 2.6.39 devel tree, we've had churn in the core area that makes it difficult to handle patches for eg cfq or blk-throttle. Instead of requiring that they be based in older versions with bugs that have been fixed later in the rc cycle, merge in 2.6.39 final. Also fixes up conflicts in the below files. Conflicts: drivers/block/paride/pcd.c drivers/cdrom/viocd.c drivers/ide/ide-cd.c
Unified · Split
| @@ -294,6 +294,7 @@ · 293 unmodified lines | ||
| 294 | 294 | <!ENTITY sub-srggb10 SYSTEM "v4l/pixfmt-srggb10.xml"> |
| 295 | 295 | <!ENTITY sub-srggb8 SYSTEM "v4l/pixfmt-srggb8.xml"> |
| 296 | 296 | <!ENTITY sub-y10 SYSTEM "v4l/pixfmt-y10.xml"> |
| 297 | +<!ENTITY sub-y12 SYSTEM "v4l/pixfmt-y12.xml"> | |
| 297 | 298 | <!ENTITY sub-pixfmt SYSTEM "v4l/pixfmt.xml"> |
| 298 | 299 | <!ENTITY sub-cropcap SYSTEM "v4l/vidioc-cropcap.xml"> |
| 299 | 300 | <!ENTITY sub-dbg-g-register SYSTEM "v4l/vidioc-dbg-g-register.xml"> |
| @@ -34,7 +34,7 @@ · 33 unmodified lines | ||
| 34 | 34 | <varlistentry> |
| 35 | 35 | <term><parameter>request</parameter></term> |
| 36 | 36 | <listitem> |
| 37 | − <para>MEDIA_IOC_ENUM_LINKS</para> | |
| 37 | + <para>MEDIA_IOC_SETUP_LINK</para> | |
| 38 | 38 | </listitem> |
| 39 | 39 | </varlistentry> |
| 40 | 40 | <varlistentry> |
| @@ -0,0 +1,79 @@ | ||
| 1 | +<refentry id="V4L2-PIX-FMT-Y12"> | |
| 2 | + <refmeta> | |
| 3 | + <refentrytitle>V4L2_PIX_FMT_Y12 ('Y12 ')</refentrytitle> | |
| 4 | + &manvol; | |
| 5 | + </refmeta> | |
| 6 | + <refnamediv> | |
| 7 | + <refname><constant>V4L2_PIX_FMT_Y12</constant></refname> | |
| 8 | + <refpurpose>Grey-scale image</refpurpose> | |
| 9 | + </refnamediv> | |
| 10 | + <refsect1> | |
| 11 | + <title>Description</title> | |
| 12 | + | |
| 13 | + <para>This is a grey-scale image with a depth of 12 bits per pixel. Pixels | |
| 14 | +are stored in 16-bit words with unused high bits padded with 0. The least | |
| 15 | +significant byte is stored at lower memory addresses (little-endian).</para> | |
| 16 | + | |
| 17 | + <example> | |
| 18 | + <title><constant>V4L2_PIX_FMT_Y12</constant> 4 × 4 | |
| 19 | +pixel image</title> | |
| 20 | + | |
| 21 | + <formalpara> | |
| 22 | + <title>Byte Order.</title> | |
| 23 | + <para>Each cell is one byte. | |
| 24 | + <informaltable frame="none"> | |
| 25 | + <tgroup cols="9" align="center"> | |
| 26 | + <colspec align="left" colwidth="2*" /> | |
| 27 | + <tbody valign="top"> | |
| 28 | + <row> | |
| 29 | + <entry>start + 0:</entry> | |
| 30 | + <entry>Y'<subscript>00low</subscript></entry> | |
| 31 | + <entry>Y'<subscript>00high</subscript></entry> | |
| 32 | + <entry>Y'<subscript>01low</subscript></entry> | |
| 33 | + <entry>Y'<subscript>01high</subscript></entry> | |
| 34 | + <entry>Y'<subscript>02low</subscript></entry> | |
| 35 | + <entry>Y'<subscript>02high</subscript></entry> | |
| 36 | + <entry>Y'<subscript>03low</subscript></entry> | |
| 37 | + <entry>Y'<subscript>03high</subscript></entry> | |
| 38 | + </row> | |
| 39 | + <row> | |
| 40 | + <entry>start + 8:</entry> | |
| 41 | + <entry>Y'<subscript>10low</subscript></entry> | |
| 42 | + <entry>Y'<subscript>10high</subscript></entry> | |
| 43 | + <entry>Y'<subscript>11low</subscript></entry> | |
| 44 | + <entry>Y'<subscript>11high</subscript></entry> | |
| 45 | + <entry>Y'<subscript>12low</subscript></entry> | |
| 46 | + <entry>Y'<subscript>12high</subscript></entry> | |
| 47 | + <entry>Y'<subscript>13low</subscript></entry> | |
| 48 | + <entry>Y'<subscript>13high</subscript></entry> | |
| 49 | + </row> | |
| 50 | + <row> | |
| 51 | + <entry>start + 16:</entry> | |
| 52 | + <entry>Y'<subscript>20low</subscript></entry> | |
| 53 | + <entry>Y'<subscript>20high</subscript></entry> | |
| 54 | + <entry>Y'<subscript>21low</subscript></entry> | |
| 55 | + <entry>Y'<subscript>21high</subscript></entry> | |
| 56 | + <entry>Y'<subscript>22low</subscript></entry> | |
| 57 | + <entry>Y'<subscript>22high</subscript></entry> | |
| 58 | + <entry>Y'<subscript>23low</subscript></entry> | |
| 59 | + <entry>Y'<subscript>23high</subscript></entry> | |
| 60 | + </row> | |
| 61 | + <row> | |
| 62 | + <entry>start + 24:</entry> | |
| 63 | + <entry>Y'<subscript>30low</subscript></entry> | |
| 64 | + <entry>Y'<subscript>30high</subscript></entry> | |
| 65 | + <entry>Y'<subscript>31low</subscript></entry> | |
| 66 | + <entry>Y'<subscript>31high</subscript></entry> | |
| 67 | + <entry>Y'<subscript>32low</subscript></entry> | |
| 68 | + <entry>Y'<subscript>32high</subscript></entry> | |
| 69 | + <entry>Y'<subscript>33low</subscript></entry> | |
| 70 | + <entry>Y'<subscript>33high</subscript></entry> | |
| 71 | + </row> | |
| 72 | + </tbody> | |
| 73 | + </tgroup> | |
| 74 | + </informaltable> | |
| 75 | + </para> | |
| 76 | + </formalpara> | |
| 77 | + </example> | |
| 78 | + </refsect1> | |
| 79 | +</refentry> | |
| @@ -696,6 +696,7 @@ information.</para> · 695 unmodified lines | ||
| 696 | 696 | &sub-packed-yuv; |
| 697 | 697 | &sub-grey; |
| 698 | 698 | &sub-y10; |
| 699 | + &sub-y12; | |
| 699 | 700 | &sub-y16; |
| 700 | 701 | &sub-yuyv; |
| 701 | 702 | &sub-uyvy; |
| @@ -456,6 +456,23 @@ · 455 unmodified lines | ||
| 456 | 456 | <entry>b<subscript>1</subscript></entry> |
| 457 | 457 | <entry>b<subscript>0</subscript></entry> |
| 458 | 458 | </row> |
| 459 | + <row id="V4L2-MBUS-FMT-SGBRG8-1X8"> | |
| 460 | + <entry>V4L2_MBUS_FMT_SGBRG8_1X8</entry> | |
| 461 | + <entry>0x3013</entry> | |
| 462 | + <entry></entry> | |
| 463 | + <entry>-</entry> | |
| 464 | + <entry>-</entry> | |
| 465 | + <entry>-</entry> | |
| 466 | + <entry>-</entry> | |
| 467 | + <entry>g<subscript>7</subscript></entry> | |
| 468 | + <entry>g<subscript>6</subscript></entry> | |
| 469 | + <entry>g<subscript>5</subscript></entry> | |
| 470 | + <entry>g<subscript>4</subscript></entry> | |
| 471 | + <entry>g<subscript>3</subscript></entry> | |
| 472 | + <entry>g<subscript>2</subscript></entry> | |
| 473 | + <entry>g<subscript>1</subscript></entry> | |
| 474 | + <entry>g<subscript>0</subscript></entry> | |
| 475 | + </row> | |
| 459 | 476 | <row id="V4L2-MBUS-FMT-SGRBG8-1X8"> |
| 460 | 477 | <entry>V4L2_MBUS_FMT_SGRBG8_1X8</entry> |
| 461 | 478 | <entry>0x3002</entry> |
| @@ -473,6 +490,23 @@ · 11 unmodified lines | ||
| 473 | 490 | <entry>g<subscript>1</subscript></entry> |
| 474 | 491 | <entry>g<subscript>0</subscript></entry> |
| 475 | 492 | </row> |
| 493 | + <row id="V4L2-MBUS-FMT-SRGGB8-1X8"> | |
| 494 | + <entry>V4L2_MBUS_FMT_SRGGB8_1X8</entry> | |
| 495 | + <entry>0x3014</entry> | |
| 496 | + <entry></entry> | |
| 497 | + <entry>-</entry> | |
| 498 | + <entry>-</entry> | |
| 499 | + <entry>-</entry> | |
| 500 | + <entry>-</entry> | |
| 501 | + <entry>r<subscript>7</subscript></entry> | |
| 502 | + <entry>r<subscript>6</subscript></entry> | |
| 503 | + <entry>r<subscript>5</subscript></entry> | |
| 504 | + <entry>r<subscript>4</subscript></entry> | |
| 505 | + <entry>r<subscript>3</subscript></entry> | |
| 506 | + <entry>r<subscript>2</subscript></entry> | |
| 507 | + <entry>r<subscript>1</subscript></entry> | |
| 508 | + <entry>r<subscript>0</subscript></entry> | |
| 509 | + </row> | |
| 476 | 510 | <row id="V4L2-MBUS-FMT-SBGGR10-DPCM8-1X8"> |
| 477 | 511 | <entry>V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8</entry> |
| 478 | 512 | <entry>0x300b</entry> |
| @@ -2159,6 +2193,31 @@ · 1680 unmodified lines | ||
| 2159 | 2193 | <entry>u<subscript>1</subscript></entry> |
| 2160 | 2194 | <entry>u<subscript>0</subscript></entry> |
| 2161 | 2195 | </row> |
| 2196 | + <row id="V4L2-MBUS-FMT-Y12-1X12"> | |
| 2197 | + <entry>V4L2_MBUS_FMT_Y12_1X12</entry> | |
| 2198 | + <entry>0x2013</entry> | |
| 2199 | + <entry></entry> | |
| 2200 | + <entry>-</entry> | |
| 2201 | + <entry>-</entry> | |
| 2202 | + <entry>-</entry> | |
| 2203 | + <entry>-</entry> | |
| 2204 | + <entry>-</entry> | |
| 2205 | + <entry>-</entry> | |
| 2206 | + <entry>-</entry> | |
| 2207 | + <entry>-</entry> | |
| 2208 | + <entry>y<subscript>11</subscript></entry> | |
| 2209 | + <entry>y<subscript>10</subscript></entry> | |
| 2210 | + <entry>y<subscript>9</subscript></entry> | |
| 2211 | + <entry>y<subscript>8</subscript></entry> | |
| 2212 | + <entry>y<subscript>7</subscript></entry> | |
| 2213 | + <entry>y<subscript>6</subscript></entry> | |
| 2214 | + <entry>y<subscript>5</subscript></entry> | |
| 2215 | + <entry>y<subscript>4</subscript></entry> | |
| 2216 | + <entry>y<subscript>3</subscript></entry> | |
| 2217 | + <entry>y<subscript>2</subscript></entry> | |
| 2218 | + <entry>y<subscript>1</subscript></entry> | |
| 2219 | + <entry>y<subscript>0</subscript></entry> | |
| 2220 | + </row> | |
| 2162 | 2221 | <row id="V4L2-MBUS-FMT-UYVY8-1X16"> |
| 2163 | 2222 | <entry>V4L2_MBUS_FMT_UYVY8_1X16</entry> |
| 2164 | 2223 | <entry>0x200f</entry> |
| @@ -52,8 +52,10 @@ Brief summary of control files. · 51 unmodified lines | ||
| 52 | 52 | tasks # attach a task(thread) and show list of threads |
| 53 | 53 | cgroup.procs # show list of processes |
| 54 | 54 | cgroup.event_control # an interface for event_fd() |
| 55 | − memory.usage_in_bytes # show current memory(RSS+Cache) usage. | |
| 56 | − memory.memsw.usage_in_bytes # show current memory+Swap usage | |
| 55 | + memory.usage_in_bytes # show current res_counter usage for memory | |
| 56 | + (See 5.5 for details) | |
| 57 | + memory.memsw.usage_in_bytes # show current res_counter usage for memory+Swap | |
| 58 | + (See 5.5 for details) | |
| 57 | 59 | memory.limit_in_bytes # set/show limit of memory usage |
| 58 | 60 | memory.memsw.limit_in_bytes # set/show limit of memory+Swap usage |
| 59 | 61 | memory.failcnt # show the number of memory usage hits limits |
| @@ -453,6 +455,15 @@ memory under it will be reclaimed. · 393 unmodified lines | ||
| 453 | 455 | You can reset failcnt by writing 0 to failcnt file. |
| 454 | 456 | # echo 0 > .../memory.failcnt |
| 455 | 457 | |
| 458 | +5.5 usage_in_bytes | |
| 459 | + | |
| 460 | +For efficiency, as other kernel components, memory cgroup uses some optimization | |
| 461 | +to avoid unnecessary cacheline false sharing. usage_in_bytes is affected by the | |
| 462 | +method and doesn't show 'exact' value of memory(and swap) usage, it's an fuzz | |
| 463 | +value for efficient access. (Of course, when necessary, it's synchronized.) | |
| 464 | +If you want to know more exact memory usage, you should use RSS+CACHE(+SWAP) | |
| 465 | +value in memory.stat(see 5.2). | |
| 466 | + | |
| 456 | 467 | 6. Hierarchy support |
| 457 | 468 | |
| 458 | 469 | The memory controller supports a deep hierarchy and hierarchical accounting. |
| @@ -66,10 +66,10 @@ trick is to ensure that any needed memory allocations are done before · 65 unmodified lines | ||
| 66 | 66 | entering atomic context, using: |
| 67 | 67 | |
| 68 | 68 | int flex_array_prealloc(struct flex_array *array, unsigned int start, |
| 69 | − unsigned int end, gfp_t flags); | |
| 69 | + unsigned int nr_elements, gfp_t flags); | |
| 70 | 70 | |
| 71 | 71 | This function will ensure that memory for the elements indexed in the range |
| 72 | −defined by start and end has been allocated. Thereafter, a | |
| 72 | +defined by start and nr_elements has been allocated. Thereafter, a | |
| 73 | 73 | flex_array_put() call on an element in that range is guaranteed not to |
| 74 | 74 | block. |
| 75 | 75 | |
| @@ -14,10 +14,6 @@ Supported chips: · 13 unmodified lines | ||
| 14 | 14 | Prefix: 'gl523sm' |
| 15 | 15 | Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e |
| 16 | 16 | Datasheet: |
| 17 | − * Intel Xeon Processor | |
| 18 | − Prefix: - any other - may require 'force_adm1021' parameter | |
| 19 | − Addresses scanned: none | |
| 20 | − Datasheet: Publicly available at Intel website | |
| 21 | 17 | * Maxim MAX1617 |
| 22 | 18 | Prefix: 'max1617' |
| 23 | 19 | Addresses scanned: I2C 0x18 - 0x1a, 0x29 - 0x2b, 0x4c - 0x4e |
| @@ -91,21 +87,27 @@ will do no harm, but will return 'old' values. It is possible to make · 67 unmodified lines | ||
| 91 | 87 | ADM1021-clones do faster measurements, but there is really no good reason |
| 92 | 88 | for that. |
| 93 | 89 | |
| 94 | −Xeon support | |
| 95 | −------------ | |
| 96 | 90 | |
| 97 | −Some Xeon processors have real max1617, adm1021, or compatible chips | |
| 98 | −within them, with two temperature sensors. | |
| 91 | +Netburst-based Xeon support | |
| 92 | +--------------------------- | |
| 99 | 93 | |
| 100 | −Other Xeons have chips with only one sensor. | |
| 94 | +Some Xeon processors based on the Netburst (early Pentium 4, from 2001 to | |
| 95 | +2003) microarchitecture had real MAX1617, ADM1021, or compatible chips | |
| 96 | +within them, with two temperature sensors. Other Xeon processors of this | |
| 97 | +era (with 400 MHz FSB) had chips with only one temperature sensor. | |
| 101 | 98 | |
| 102 | −If you have a Xeon, and the adm1021 module loads, and both temperatures | |
| 103 | −appear valid, then things are good. | |
| 99 | +If you have such an old Xeon, and you get two valid temperatures when | |
| 100 | +loading the adm1021 module, then things are good. | |
| 104 | 101 | |
| 105 | −If the adm1021 module doesn't load, you should try this: | |
| 106 | − modprobe adm1021 force_adm1021=BUS,ADDRESS | |
| 107 | − ADDRESS can only be 0x18, 0x1a, 0x29, 0x2b, 0x4c, or 0x4e. | |
| 102 | +If nothing happens when loading the adm1021 module, and you are certain | |
| 103 | +that your specific Xeon processor model includes compatible sensors, you | |
| 104 | +will have to explicitly instantiate the sensor chips from user-space. See | |
| 105 | +method 4 in Documentation/i2c/instantiating-devices. Possible slave | |
| 106 | +addresses are 0x18, 0x1a, 0x29, 0x2b, 0x4c, or 0x4e. It is likely that | |
| 107 | +only temp2 will be correct and temp1 will have to be ignored. | |
| 108 | 108 | |
| 109 | −If you have dual Xeons you may have appear to have two separate | |
| 110 | −adm1021-compatible chips, or two single-temperature sensors, at distinct | |
| 111 | −addresses. | |
| 109 | +Previous generations of the Xeon processor (based on Pentium II/III) | |
| 110 | +didn't have these sensors. Next generations of Xeon processors (533 MHz | |
| 111 | +FSB and faster) lost them, until the Core-based generation which | |
| 112 | +introduced integrated digital thermal sensors. These are supported by | |
| 113 | +the coretemp driver. | |
| @@ -32,6 +32,16 @@ Supported chips: · 31 unmodified lines | ||
| 32 | 32 | Addresses scanned: I2C 0x4c and 0x4d |
| 33 | 33 | Datasheet: Publicly available at the ON Semiconductor website |
| 34 | 34 | http://www.onsemi.com/PowerSolutions/product.do?id=ADT7461 |
| 35 | + * Analog Devices ADT7461A | |
| 36 | + Prefix: 'adt7461a' | |
| 37 | + Addresses scanned: I2C 0x4c and 0x4d | |
| 38 | + Datasheet: Publicly available at the ON Semiconductor website | |
| 39 | + http://www.onsemi.com/PowerSolutions/product.do?id=ADT7461A | |
| 40 | + * ON Semiconductor NCT1008 | |
| 41 | + Prefix: 'nct1008' | |
| 42 | + Addresses scanned: I2C 0x4c and 0x4d | |
| 43 | + Datasheet: Publicly available at the ON Semiconductor website | |
| 44 | + http://www.onsemi.com/PowerSolutions/product.do?id=NCT1008 | |
| 35 | 45 | * Maxim MAX6646 |
| 36 | 46 | Prefix: 'max6646' |
| 37 | 47 | Addresses scanned: I2C 0x4d |
| @@ -149,7 +159,7 @@ ADM1032: · 111 unmodified lines | ||
| 149 | 159 | * ALERT is triggered by open remote sensor. |
| 150 | 160 | * SMBus PEC support for Write Byte and Receive Byte transactions. |
| 151 | 161 | |
| 152 | −ADT7461: | |
| 162 | +ADT7461, ADT7461A, NCT1008: | |
| 153 | 163 | * Extended temperature range (breaks compatibility) |
| 154 | 164 | * Lower resolution for remote temperature |
| 155 | 165 | |
| @@ -195,9 +205,9 @@ are exported, one for each channel, but these values are of course linked. · 39 unmodified lines | ||
| 195 | 205 | Only the local hysteresis can be set from user-space, and the same delta |
| 196 | 206 | applies to the remote hysteresis. |
| 197 | 207 | |
| 198 | −The lm90 driver will not update its values more frequently than every | |
| 199 | −other second; reading them more often will do no harm, but will return | |
| 200 | −'old' values. | |
| 208 | +The lm90 driver will not update its values more frequently than configured with | |
| 209 | +the update_interval attribute; reading them more often will do no harm, but will | |
| 210 | +return 'old' values. | |
| 201 | 211 | |
| 202 | 212 | SMBus Alert Support |
| 203 | 213 | ------------------- |
| @@ -205,11 +215,12 @@ SMBus Alert Support · 1 unmodified line | ||
| 205 | 215 | This driver has basic support for SMBus alert. When an alert is received, |
| 206 | 216 | the status register is read and the faulty temperature channel is logged. |
| 207 | 217 | |
| 208 | −The Analog Devices chips (ADM1032 and ADT7461) do not implement the SMBus | |
| 209 | −alert protocol properly so additional care is needed: the ALERT output is | |
| 210 | −disabled when an alert is received, and is re-enabled only when the alarm | |
| 211 | −is gone. Otherwise the chip would block alerts from other chips in the bus | |
| 212 | −as long as the alarm is active. | |
| 218 | +The Analog Devices chips (ADM1032, ADT7461 and ADT7461A) and ON | |
| 219 | +Semiconductor chips (NCT1008) do not implement the SMBus alert protocol | |
| 220 | +properly so additional care is needed: the ALERT output is disabled when | |
| 221 | +an alert is received, and is re-enabled only when the alarm is gone. | |
| 222 | +Otherwise the chip would block alerts from other chips in the bus as long | |
| 223 | +as the alarm is active. | |
| 213 | 224 | |
| 214 | 225 | PEC Support |
| 215 | 226 | ----------- |
| @@ -0,0 +1,62 @@ | ||
| 1 | +Kernel driver max16064 | |
| 2 | +====================== | |
| 3 | + | |
| 4 | +Supported chips: | |
| 5 | + * Maxim MAX16064 | |
| 6 | + Prefix: 'max16064' | |
| 7 | + Addresses scanned: - | |
| 8 | + Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX16064.pdf | |
| 9 | + | |
| 10 | +Author: Guenter Roeck <guenter.roeck@ericsson.com> | |
| 11 | + | |
| 12 | + | |
| 13 | +Description | |
| 14 | +----------- | |
| 15 | + | |
| 16 | +This driver supports hardware montoring for Maxim MAX16064 Quad Power-Supply | |
| 17 | +Controller with Active-Voltage Output Control and PMBus Interface. | |
| 18 | + | |
| 19 | +The driver is a client driver to the core PMBus driver. | |
| 20 | +Please see Documentation/hwmon/pmbus for details on PMBus client drivers. | |
| 21 | + | |
| 22 | + | |
| 23 | +Usage Notes | |
| 24 | +----------- | |
| 25 | + | |
| 26 | +This driver does not auto-detect devices. You will have to instantiate the | |
| 27 | +devices explicitly. Please see Documentation/i2c/instantiating-devices for | |
| 28 | +details. | |
| 29 | + | |
| 30 | + | |
| 31 | +Platform data support | |
| 32 | +--------------------- | |
| 33 | + | |
| 34 | +The driver supports standard PMBus driver platform data. | |
| 35 | + | |
| 36 | + | |
| 37 | +Sysfs entries | |
| 38 | +------------- | |
| 39 | + | |
| 40 | +The following attributes are supported. Limits are read-write; all other | |
| 41 | +attributes are read-only. | |
| 42 | + | |
| 43 | +in[1-4]_label "vout[1-4]" | |
| 44 | +in[1-4]_input Measured voltage. From READ_VOUT register. | |
| 45 | +in[1-4]_min Minumum Voltage. From VOUT_UV_WARN_LIMIT register. | |
| 46 | +in[1-4]_max Maximum voltage. From VOUT_OV_WARN_LIMIT register. | |
| 47 | +in[1-4]_lcrit Critical minumum Voltage. VOUT_UV_FAULT_LIMIT register. | |
| 48 | +in[1-4]_crit Critical maximum voltage. From VOUT_OV_FAULT_LIMIT register. | |
| 49 | +in[1-4]_min_alarm Voltage low alarm. From VOLTAGE_UV_WARNING status. | |
| 50 | +in[1-4]_max_alarm Voltage high alarm. From VOLTAGE_OV_WARNING status. | |
| 51 | +in[1-4]_lcrit_alarm Voltage critical low alarm. From VOLTAGE_UV_FAULT status. | |
| 52 | +in[1-4]_crit_alarm Voltage critical high alarm. From VOLTAGE_OV_FAULT status. | |
| 53 | + | |
| 54 | +temp1_input Measured temperature. From READ_TEMPERATURE_1 register. | |
| 55 | +temp1_max Maximum temperature. From OT_WARN_LIMIT register. | |
| 56 | +temp1_crit Critical high temperature. From OT_FAULT_LIMIT register. | |
| 57 | +temp1_max_alarm Chip temperature high alarm. Set by comparing | |
| 58 | + READ_TEMPERATURE_1 with OT_WARN_LIMIT if TEMP_OT_WARNING | |
| 59 | + status is set. | |
| 60 | +temp1_crit_alarm Chip temperature critical high alarm. Set by comparing | |
| 61 | + READ_TEMPERATURE_1 with OT_FAULT_LIMIT if TEMP_OT_FAULT | |
| 62 | + status is set. | |
| @@ -0,0 +1,79 @@ | ||
| 1 | +Kernel driver max34440 | |
| 2 | +====================== | |
| 3 | + | |
| 4 | +Supported chips: | |
| 5 | + * Maxim MAX34440 | |
| 6 | + Prefixes: 'max34440' | |
| 7 | + Addresses scanned: - | |
| 8 | + Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX34440.pdf | |
| 9 | + * Maxim MAX34441 | |
| 10 | + PMBus 5-Channel Power-Supply Manager and Intelligent Fan Controller | |
| 11 | + Prefixes: 'max34441' | |
| 12 | + Addresses scanned: - | |
| 13 | + Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX34441.pdf | |
| 14 | + | |
| 15 | +Author: Guenter Roeck <guenter.roeck@ericsson.com> | |
| 16 | + | |
| 17 | + | |
| 18 | +Description | |
| 19 | +----------- | |
| 20 | + | |
| 21 | +This driver supports hardware montoring for Maxim MAX34440 PMBus 6-Channel | |
| 22 | +Power-Supply Manager and MAX34441 PMBus 5-Channel Power-Supply Manager | |
| 23 | +and Intelligent Fan Controller. | |
| 24 | + | |
| 25 | +The driver is a client driver to the core PMBus driver. Please see | |
| 26 | +Documentation/hwmon/pmbus for details on PMBus client drivers. | |
| 27 | + | |
| 28 | + | |
| 29 | +Usage Notes | |
| 30 | +----------- | |
| 31 | + | |
| 32 | +This driver does not auto-detect devices. You will have to instantiate the | |
| 33 | +devices explicitly. Please see Documentation/i2c/instantiating-devices for | |
| 34 | +details. | |
| 35 | + | |
| 36 | + | |
| 37 | +Platform data support | |
| 38 | +--------------------- | |
| 39 | + | |
| 40 | +The driver supports standard PMBus driver platform data. | |
| 41 | + | |
| 42 | + | |
| 43 | +Sysfs entries | |
| 44 | +------------- | |
| 45 | + | |
| 46 | +The following attributes are supported. Limits are read-write; all other | |
| 47 | +attributes are read-only. | |
| 48 | + | |
| 49 | +in[1-6]_label "vout[1-6]". | |
| 50 | +in[1-6]_input Measured voltage. From READ_VOUT register. | |
| 51 | +in[1-6]_min Minumum Voltage. From VOUT_UV_WARN_LIMIT register. | |
| 52 | +in[1-6]_max Maximum voltage. From VOUT_OV_WARN_LIMIT register. | |
| 53 | +in[1-6]_lcrit Critical minumum Voltage. VOUT_UV_FAULT_LIMIT register. | |
| 54 | +in[1-6]_crit Critical maximum voltage. From VOUT_OV_FAULT_LIMIT register. | |
| 55 | +in[1-6]_min_alarm Voltage low alarm. From VOLTAGE_UV_WARNING status. | |
| 56 | +in[1-6]_max_alarm Voltage high alarm. From VOLTAGE_OV_WARNING status. | |
| 57 | +in[1-6]_lcrit_alarm Voltage critical low alarm. From VOLTAGE_UV_FAULT status. | |
| 58 | +in[1-6]_crit_alarm Voltage critical high alarm. From VOLTAGE_OV_FAULT status. | |
| 59 | + | |
| 60 | +curr[1-6]_label "iout[1-6]". | |
| 61 | +curr[1-6]_input Measured current. From READ_IOUT register. | |
| 62 | +curr[1-6]_max Maximum current. From IOUT_OC_WARN_LIMIT register. | |
| 63 | +curr[1-6]_crit Critical maximum current. From IOUT_OC_FAULT_LIMIT register. | |
| 64 | +curr[1-6]_max_alarm Current high alarm. From IOUT_OC_WARNING status. | |
| 65 | +curr[1-6]_crit_alarm Current critical high alarm. From IOUT_OC_FAULT status. | |
| 66 | + | |
| 67 | + in6 and curr6 attributes only exist for MAX34440. | |
| 68 | + | |
| 69 | +temp[1-8]_input Measured temperatures. From READ_TEMPERATURE_1 register. | |
| 70 | + temp1 is the chip's internal temperature. temp2..temp5 | |
| 71 | + are remote I2C temperature sensors. For MAX34441, temp6 | |
| 72 | + is a remote thermal-diode sensor. For MAX34440, temp6..8 | |
| 73 | + are remote I2C temperature sensors. | |
| 74 | +temp[1-8]_max Maximum temperature. From OT_WARN_LIMIT register. | |
| 75 | +temp[1-8]_crit Critical high temperature. From OT_FAULT_LIMIT register. | |
| 76 | +temp[1-8]_max_alarm Temperature high alarm. | |
| 77 | +temp[1-8]_crit_alarm Temperature critical high alarm. | |
| 78 | + | |
| 79 | + temp7 and temp8 attributes only exist for MAX34440. | |
| @@ -0,0 +1,69 @@ | ||
| 1 | +Kernel driver max8688 | |
| 2 | +===================== | |
| 3 | + | |
| 4 | +Supported chips: | |
| 5 | + * Maxim MAX8688 | |
| 6 | + Prefix: 'max8688' | |
| 7 | + Addresses scanned: - | |
| 8 | + Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX8688.pdf | |
| 9 | + | |
| 10 | +Author: Guenter Roeck <guenter.roeck@ericsson.com> | |
| 11 | + | |
| 12 | + | |
| 13 | +Description | |
| 14 | +----------- | |
| 15 | + | |
| 16 | +This driver supports hardware montoring for Maxim MAX8688 Digital Power-Supply | |
| 17 | +Controller/Monitor with PMBus Interface. | |
| 18 | + | |
| 19 | +The driver is a client driver to the core PMBus driver. Please see | |
| 20 | +Documentation/hwmon/pmbus for details on PMBus client drivers. | |
| 21 | + | |
| 22 | + | |
| 23 | +Usage Notes | |
| 24 | +----------- | |
| 25 | + | |
| 26 | +This driver does not auto-detect devices. You will have to instantiate the | |
| 27 | +devices explicitly. Please see Documentation/i2c/instantiating-devices for | |
| 28 | +details. | |
| 29 | + | |
| 30 | + | |
| 31 | +Platform data support | |
| 32 | +--------------------- | |
| 33 | + | |
| 34 | +The driver supports standard PMBus driver platform data. | |
| 35 | + | |
| 36 | + | |
| 37 | +Sysfs entries | |
| 38 | +------------- | |
| 39 | + | |
| 40 | +The following attributes are supported. Limits are read-write; all other | |
| 41 | +attributes are read-only. | |
| 42 | + | |
| 43 | +in1_label "vout1" | |
| 44 | +in1_input Measured voltage. From READ_VOUT register. | |
| 45 | +in1_min Minumum Voltage. From VOUT_UV_WARN_LIMIT register. | |
| 46 | +in1_max Maximum voltage. From VOUT_OV_WARN_LIMIT register. | |
| 47 | +in1_lcrit Critical minumum Voltage. VOUT_UV_FAULT_LIMIT register. | |
| 48 | +in1_crit Critical maximum voltage. From VOUT_OV_FAULT_LIMIT register. | |
| 49 | +in1_min_alarm Voltage low alarm. From VOLTAGE_UV_WARNING status. | |
| 50 | +in1_max_alarm Voltage high alarm. From VOLTAGE_OV_WARNING status. | |
| 51 | +in1_lcrit_alarm Voltage critical low alarm. From VOLTAGE_UV_FAULT status. | |
| 52 | +in1_crit_alarm Voltage critical high alarm. From VOLTAGE_OV_FAULT status. | |
| 53 | + | |
| 54 | +curr1_label "iout1" | |
| 55 | +curr1_input Measured current. From READ_IOUT register. | |
| 56 | +curr1_max Maximum current. From IOUT_OC_WARN_LIMIT register. | |
| 57 | +curr1_crit Critical maximum current. From IOUT_OC_FAULT_LIMIT register. | |
| 58 | +curr1_max_alarm Current high alarm. From IOUT_OC_WARN_LIMIT register. | |
| 59 | +curr1_crit_alarm Current critical high alarm. From IOUT_OC_FAULT status. | |
| 60 | + | |
| 61 | +temp1_input Measured temperature. From READ_TEMPERATURE_1 register. | |
| 62 | +temp1_max Maximum temperature. From OT_WARN_LIMIT register. | |
| 63 | +temp1_crit Critical high temperature. From OT_FAULT_LIMIT register. | |
| 64 | +temp1_max_alarm Chip temperature high alarm. Set by comparing | |
| 65 | + READ_TEMPERATURE_1 with OT_WARN_LIMIT if TEMP_OT_WARNING | |
| 66 | + status is set. | |
| 67 | +temp1_crit_alarm Chip temperature critical high alarm. Set by comparing | |
| 68 | + READ_TEMPERATURE_1 with OT_FAULT_LIMIT if TEMP_OT_FAULT | |
| 69 | + status is set. | |
| @@ -13,26 +13,6 @@ Supported chips: · 12 unmodified lines | ||
| 13 | 13 | Prefix: 'ltc2978' |
| 14 | 14 | Addresses scanned: - |
| 15 | 15 | Datasheet: http://cds.linear.com/docs/Datasheet/2978fa.pdf |
| 16 | − * Maxim MAX16064 | |
| 17 | − Quad Power-Supply Controller | |
| 18 | − Prefix: 'max16064' | |
| 19 | − Addresses scanned: - | |
| 20 | − Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX16064.pdf | |
| 21 | − * Maxim MAX34440 | |
| 22 | − PMBus 6-Channel Power-Supply Manager | |
| 23 | − Prefixes: 'max34440' | |
| 24 | − Addresses scanned: - | |
| 25 | − Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX34440.pdf | |
| 26 | − * Maxim MAX34441 | |
| 27 | − PMBus 5-Channel Power-Supply Manager and Intelligent Fan Controller | |
| 28 | − Prefixes: 'max34441' | |
| 29 | − Addresses scanned: - | |
| 30 | − Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX34441.pdf | |
| 31 | − * Maxim MAX8688 | |
| 32 | − Digital Power-Supply Controller/Monitor | |
| 33 | − Prefix: 'max8688' | |
| 34 | − Addresses scanned: - | |
| 35 | − Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX8688.pdf | |
| 36 | 16 | * Generic PMBus devices |
| 37 | 17 | Prefix: 'pmbus' |
| 38 | 18 | Addresses scanned: - |
| @@ -175,11 +155,13 @@ currX_crit Critical maximum current. · 136 unmodified lines | ||
| 175 | 155 | From IIN_OC_FAULT_LIMIT or IOUT_OC_FAULT_LIMIT register. |
| 176 | 156 | currX_alarm Current high alarm. |
| 177 | 157 | From IIN_OC_WARNING or IOUT_OC_WARNING status. |
| 158 | +currX_max_alarm Current high alarm. | |
| 159 | + From IIN_OC_WARN_LIMIT or IOUT_OC_WARN_LIMIT status. | |
| 178 | 160 | currX_lcrit_alarm Output current critical low alarm. |
| 179 | 161 | From IOUT_UC_FAULT status. |
| 180 | 162 | currX_crit_alarm Current critical high alarm. |
| 181 | 163 | From IIN_OC_FAULT or IOUT_OC_FAULT status. |
| 182 | −currX_label "iin" or "vinY" | |
| 164 | +currX_label "iin" or "ioutY" | |
| 183 | 165 | |
| 184 | 166 | powerX_input Measured power. From READ_PIN or READ_POUT register. |
| 185 | 167 | powerX_cap Output power cap. From POUT_MAX register. |
| @@ -193,13 +175,13 @@ powerX_crit_alarm Output power critical high alarm. · 7 unmodified lines | ||
| 193 | 175 | From POUT_OP_FAULT status. |
| 194 | 176 | powerX_label "pin" or "poutY" |
| 195 | 177 | |
| 196 | −tempX_input Measured tempererature. | |
| 178 | +tempX_input Measured temperature. | |
| 197 | 179 | From READ_TEMPERATURE_X register. |
| 198 | −tempX_min Mimimum tempererature. From UT_WARN_LIMIT register. | |
| 199 | −tempX_max Maximum tempererature. From OT_WARN_LIMIT register. | |
| 200 | −tempX_lcrit Critical low tempererature. | |
| 180 | +tempX_min Mimimum temperature. From UT_WARN_LIMIT register. | |
| 181 | +tempX_max Maximum temperature. From OT_WARN_LIMIT register. | |
| 182 | +tempX_lcrit Critical low temperature. | |
| 201 | 183 | From UT_FAULT_LIMIT register. |
| 202 | −tempX_crit Critical high tempererature. | |
| 184 | +tempX_crit Critical high temperature. | |
| 203 | 185 | From OT_FAULT_LIMIT register. |
| 204 | 186 | tempX_min_alarm Chip temperature low alarm. Set by comparing |
| 205 | 187 | READ_TEMPERATURE_X with UT_WARN_LIMIT if |
| @@ -150,8 +150,8 @@ in8_crit_alarm Channel F critical alarm · 149 unmodified lines | ||
| 150 | 150 | in9_crit_alarm AIN1 critical alarm |
| 151 | 151 | in10_crit_alarm AIN2 critical alarm |
| 152 | 152 | |
| 153 | −temp1_input Chip tempererature | |
| 154 | −temp1_min Mimimum chip tempererature | |
| 155 | −temp1_max Maximum chip tempererature | |
| 156 | −temp1_crit Critical chip tempererature | |
| 153 | +temp1_input Chip temperature | |
| 154 | +temp1_min Mimimum chip temperature | |
| 155 | +temp1_max Maximum chip temperature | |
| 156 | +temp1_crit Critical chip temperature | |
| 157 | 157 | temp1_crit_alarm Temperature critical alarm |
| @@ -0,0 +1,109 @@ | ||
| 1 | + How to Get Your Patch Accepted Into the Hwmon Subsystem | |
| 2 | + ------------------------------------------------------- | |
| 3 | + | |
| 4 | +This text is is a collection of suggestions for people writing patches or | |
| 5 | +drivers for the hwmon subsystem. Following these suggestions will greatly | |
| 6 | +increase the chances of your change being accepted. | |
| 7 | + | |
| 8 | + | |
| 9 | +1. General | |
| 10 | +---------- | |
| 11 | + | |
| 12 | +* It should be unnecessary to mention, but please read and follow | |
| 13 | + Documentation/SubmitChecklist | |
| 14 | + Documentation/SubmittingDrivers | |
| 15 | + Documentation/SubmittingPatches | |
| 16 | + Documentation/CodingStyle | |
| 17 | + | |
| 18 | +* If your patch generates checkpatch warnings, please refrain from explanations | |
| 19 | + such as "I don't like that coding style". Keep in mind that each unnecessary | |
| 20 | + warning helps hiding a real problem. If you don't like the kernel coding | |
| 21 | + style, don't write kernel drivers. | |
| 22 | + | |
| 23 | +* Please test your patch thoroughly. We are not your test group. | |
| 24 | + Sometimes a patch can not or not completely be tested because of missing | |
| 25 | + hardware. In such cases, you should test-build the code on at least one | |
| 26 | + architecture. If run-time testing was not achieved, it should be written | |
| 27 | + explicitly below the patch header. | |
| 28 | + | |
| 29 | +* If your patch (or the driver) is affected by configuration options such as | |
| 30 | + CONFIG_SMP or CONFIG_HOTPLUG, make sure it compiles for all configuration | |
| 31 | + variants. | |
| 32 | + | |
| 33 | + | |
| 34 | +2. Adding functionality to existing drivers | |
| 35 | +------------------------------------------- | |
| 36 | + | |
| 37 | +* Make sure the documentation in Documentation/hwmon/<driver_name> is up to | |
| 38 | + date. | |
| 39 | + | |
| 40 | +* Make sure the information in Kconfig is up to date. | |
| 41 | + | |
| 42 | +* If the added functionality requires some cleanup or structural changes, split | |
| 43 | + your patch into a cleanup part and the actual addition. This makes it easier | |
| 44 | + to review your changes, and to bisect any resulting problems. | |
| 45 | + | |
| 46 | +* Never mix bug fixes, cleanup, and functional enhancements in a single patch. | |
| 47 | + | |
| 48 | + | |
| 49 | +3. New drivers | |
| 50 | +-------------- | |
| 51 | + | |
| 52 | +* Running your patch or driver file(s) through checkpatch does not mean its | |
| 53 | + formatting is clean. If unsure about formatting in your new driver, run it | |
| 54 | + through Lindent. Lindent is not perfect, and you may have to do some minor | |
| 55 | + cleanup, but it is a good start. | |
| 56 | + | |
| 57 | +* Consider adding yourself to MAINTAINERS. | |
| 58 | + | |
| 59 | +* Document the driver in Documentation/hwmon/<driver_name>. | |
| 60 | + | |
| 61 | +* Add the driver to Kconfig and Makefile in alphabetical order. | |
| 62 | + | |
| 63 | +* Make sure that all dependencies are listed in Kconfig. For new drivers, it | |
| 64 | + is most likely prudent to add a dependency on EXPERIMENTAL. | |
| 65 | + | |
| 66 | +* Avoid forward declarations if you can. Rearrange the code if necessary. | |
| 67 | + | |
| 68 | +* Avoid calculations in macros and macro-generated functions. While such macros | |
| 69 | + may save a line or so in the source, it obfuscates the code and makes code | |
| 70 | + review more difficult. It may also result in code which is more complicated | |
| 71 | + than necessary. Use inline functions or just regular functions instead. | |
| 72 | + | |
| 73 | +* If the driver has a detect function, make sure it is silent. Debug messages | |
| 74 | + and messages printed after a successful detection are acceptable, but it | |
| 75 | + must not print messages such as "Chip XXX not found/supported". | |
| 76 | + | |
| 77 | + Keep in mind that the detect function will run for all drivers supporting an | |
| 78 | + address if a chip is detected on that address. Unnecessary messages will just | |
| 79 | + pollute the kernel log and not provide any value. | |
| 80 | + | |
| 81 | +* Provide a detect function if and only if a chip can be detected reliably. | |
| 82 | + | |
| 83 | +* Avoid writing to chip registers in the detect function. If you have to write, | |
| 84 | + only do it after you have already gathered enough data to be certain that the | |
| 85 | + detection is going to be successful. | |
| 86 | + | |
| 87 | + Keep in mind that the chip might not be what your driver believes it is, and | |
| 88 | + writing to it might cause a bad misconfiguration. | |
| 89 | + | |
| 90 | +* Make sure there are no race conditions in the probe function. Specifically, | |
| 91 | + completely initialize your chip first, then create sysfs entries and register | |
| 92 | + with the hwmon subsystem. | |
| 93 | + | |
| 94 | +* Do not provide support for deprecated sysfs attributes. | |
| 95 | + | |
| 96 | +* Do not create non-standard attributes unless really needed. If you have to use | |
| 97 | + non-standard attributes, or you believe you do, discuss it on the mailing list | |
| 98 | + first. Either case, provide a detailed explanation why you need the | |
| 99 | + non-standard attribute(s). | |
| 100 | + Standard attributes are specified in Documentation/hwmon/sysfs-interface. | |
| 101 | + | |
| 102 | +* When deciding which sysfs attributes to support, look at the chip's | |
| 103 | + capabilities. While we do not expect your driver to support everything the | |
| 104 | + chip may offer, it should at least support all limits and alarms. | |
| 105 | + | |
| 106 | +* Last but not least, please check if a driver for your chip already exists | |
| 107 | + before starting to write a new driver. Especially for temperature sensors, | |
| 108 | + new chips are often variants of previously released chips. In some cases, | |
| 109 | + a presumably new chip may simply have been relabeled. | |
| @@ -552,6 +552,16 @@ also have · 551 unmodified lines | ||
| 552 | 552 | within the array where IO will be blocked. This is currently |
| 553 | 553 | only supported for raid4/5/6. |
| 554 | 554 | |
| 555 | + sync_min | |
| 556 | + sync_max | |
| 557 | + The two values, given as numbers of sectors, indicate a range | |
| 558 | + withing the array where 'check'/'repair' will operate. Must be | |
| 559 | + a multiple of chunk_size. When it reaches "sync_max" it will | |
| 560 | + pause, rather than complete. | |
| 561 | + You can use 'select' or 'poll' on "sync_completed" to wait for | |
| 562 | + that number to reach sync_max. Then you can either increase | |
| 563 | + "sync_max", or can write 'idle' to "sync_action". | |
| 564 | + | |
| 555 | 565 | |
| 556 | 566 | Each active md device may also have attributes specific to the |
| 557 | 567 | personality module that manages it. |
| @@ -87,14 +87,14 @@ accumulator. ALSA uses accumulators 0 and 1 for left and right PCM. · 86 unmodified lines | ||
| 87 | 87 | The result is forwarded to the ADC capture FIFO (thus to the standard capture |
| 88 | 88 | PCM device). |
| 89 | 89 | |
| 90 | −name='Music Playback Volume',index=0 | |
| 90 | +name='Synth Playback Volume',index=0 | |
| 91 | 91 | |
| 92 | 92 | This control is used to attenuate samples for left and right MIDI FX-bus |
| 93 | 93 | accumulators. ALSA uses accumulators 4 and 5 for left and right MIDI samples. |
| 94 | 94 | The result samples are forwarded to the front DAC PCM slots of the AC97 codec. |
| 95 | 95 | |
| 96 | −name='Music Capture Volume',index=0 | |
| 97 | −name='Music Capture Switch',index=0 | |
| 96 | +name='Synth Capture Volume',index=0 | |
| 97 | +name='Synth Capture Switch',index=0 | |
| 98 | 98 | |
| 99 | 99 | These controls are used to attenuate samples for left and right MIDI FX-bus |
| 100 | 100 | accumulator. ALSA uses accumulators 4 and 5 for left and right PCM. |
| @@ -37,7 +37,7 @@ Generic scaling / cropping scheme · 36 unmodified lines | ||
| 37 | 37 | -1'- |
| 38 | 38 | |
| 39 | 39 | In the above chart minuses and slashes represent "real" data amounts, points and |
| 40 | −accents represent "useful" data, basically, CEU scaled amd cropped output, | |
| 40 | +accents represent "useful" data, basically, CEU scaled and cropped output, | |
| 41 | 41 | mapped back onto the client's source plane. |
| 42 | 42 | |
| 43 | 43 | Such a configuration can be produced by user requests: |
| @@ -65,7 +65,7 @@ Do not touch input rectangle - it is already optimal. · 21 unmodified lines | ||
| 65 | 65 | |
| 66 | 66 | 1. Calculate current sensor scales: |
| 67 | 67 | |
| 68 | − scale_s = ((3') - (3)) / ((2') - (2)) | |
| 68 | + scale_s = ((2') - (2)) / ((3') - (3)) | |
| 69 | 69 | |
| 70 | 70 | 2. Calculate "effective" input crop (sensor subwindow) - CEU crop scaled back at |
| 71 | 71 | current sensor scales onto input window - this is user S_CROP: |
| @@ -80,7 +80,7 @@ window: · 8 unmodified lines | ||
| 80 | 80 | 4. Calculate sensor output window by applying combined scales to real input |
| 81 | 81 | window: |
| 82 | 82 | |
| 83 | − width_s_out = ((2') - (2)) / scale_comb | |
| 83 | + width_s_out = ((7') - (7)) = ((2') - (2)) / scale_comb | |
| 84 | 84 | |
| 85 | 85 | 5. Apply iterative sensor S_FMT for sensor output window. |
| 86 | 86 | |
| @@ -12,6 +12,7 @@ CONTENTS · 11 unmodified lines | ||
| 12 | 12 | 4. Application Programming Interface (API) |
| 13 | 13 | 5. Example Execution Scenarios |
| 14 | 14 | 6. Guidelines |
| 15 | +7. Debugging | |
| 15 | 16 | |
| 16 | 17 | |
| 17 | 18 | 1. Introduction |
| @@ -379,3 +380,42 @@ If q1 has WQ_CPU_INTENSIVE set, · 361 unmodified lines | ||
| 379 | 380 | * Unless work items are expected to consume a huge amount of CPU |
| 380 | 381 | cycles, using a bound wq is usually beneficial due to the increased |
| 381 | 382 | level of locality in wq operations and work item execution. |
| 383 | + | |
| 384 | + | |
| 385 | +7. Debugging | |
| 386 | + | |
| 387 | +Because the work functions are executed by generic worker threads | |
| 388 | +there are a few tricks needed to shed some light on misbehaving | |
| 389 | +workqueue users. | |
| 390 | + | |
| 391 | +Worker threads show up in the process list as: | |
| 392 | + | |
| 393 | +root 5671 0.0 0.0 0 0 ? S 12:07 0:00 [kworker/0:1] | |
| 394 | +root 5672 0.0 0.0 0 0 ? S 12:07 0:00 [kworker/1:2] | |
| 395 | +root 5673 0.0 0.0 0 0 ? S 12:12 0:00 [kworker/0:0] | |
| 396 | +root 5674 0.0 0.0 0 0 ? S 12:13 0:00 [kworker/1:0] | |
| 397 | + | |
| 398 | +If kworkers are going crazy (using too much cpu), there are two types | |
| 399 | +of possible problems: | |
| 400 | + | |
| 401 | + 1. Something beeing scheduled in rapid succession | |
| 402 | + 2. A single work item that consumes lots of cpu cycles | |
| 403 | + | |
| 404 | +The first one can be tracked using tracing: | |
| 405 | + | |
| 406 | + $ echo workqueue:workqueue_queue_work > /sys/kernel/debug/tracing/set_event | |
| 407 | + $ cat /sys/kernel/debug/tracing/trace_pipe > out.txt | |
| 408 | + (wait a few secs) | |
| 409 | + ^C | |
| 410 | + | |
| 411 | +If something is busy looping on work queueing, it would be dominating | |
| 412 | +the output and the offender can be determined with the work item | |
| 413 | +function. | |
| 414 | + | |
| 415 | +For the second type of problems it should be possible to just check | |
| 416 | +the stack trace of the offending worker thread. | |
| 417 | + | |
| 418 | + $ cat /proc/THE_OFFENDING_KWORKER/stack | |
| 419 | + | |
| 420 | +The work item's function should be trivially visible in the stack | |
| 421 | +trace. | |
| @@ -151,6 +151,7 @@ S: Maintained · 150 unmodified lines | ||
| 151 | 151 | F: drivers/net/hamradio/6pack.c |
| 152 | 152 | |
| 153 | 153 | 8169 10/100/1000 GIGABIT ETHERNET DRIVER |
| 154 | +M: Realtek linux nic maintainers <nic_swsd@realtek.com> | |
| 154 | 155 | M: Francois Romieu <romieu@fr.zoreil.com> |
| 155 | 156 | L: netdev@vger.kernel.org |
| 156 | 157 | S: Maintained |
| @@ -1031,12 +1032,13 @@ W: http://www.fluff.org/ben/linux/ · 874 unmodified lines | ||
| 1031 | 1032 | S: Maintained |
| 1032 | 1033 | F: arch/arm/mach-s3c64xx/ |
| 1033 | 1034 | |
| 1034 | −ARM/S5P ARM ARCHITECTURES | |
| 1035 | +ARM/S5P EXYNOS ARM ARCHITECTURES | |
| 1035 | 1036 | M: Kukjin Kim <kgene.kim@samsung.com> |
| 1036 | 1037 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 1037 | 1038 | L: linux-samsung-soc@vger.kernel.org (moderated for non-subscribers) |
| 1038 | 1039 | S: Maintained |
| 1039 | 1040 | F: arch/arm/mach-s5p*/ |
| 1041 | +F: arch/arm/mach-exynos*/ | |
| 1040 | 1042 | |
| 1041 | 1043 | ARM/SAMSUNG MOBILE MACHINE SUPPORT |
| 1042 | 1044 | M: Kyungmin Park <kyungmin.park@samsung.com> |
| @@ -2807,42 +2809,23 @@ GPIO SUBSYSTEM · 1764 unmodified lines | ||
| 2807 | 2809 | M: Grant Likely <grant.likely@secretlab.ca> |
| 2808 | 2810 | S: Maintained |
| 2809 | 2811 | T: git git://git.secretlab.ca/git/linux-2.6.git |
| 2810 | −F: Documentation/gpio/gpio.txt | |
| 2812 | +F: Documentation/gpio.txt | |
| 2811 | 2813 | F: drivers/gpio/ |
| 2812 | 2814 | F: include/linux/gpio* |
| 2813 | 2815 | |
| 2816 | +GRE DEMULTIPLEXER DRIVER | |
| 2817 | +M: Dmitry Kozlov <xeb@mail.ru> | |
| 2818 | +L: netdev@vger.kernel.org | |
| 2819 | +S: Maintained | |
| 2820 | +F: net/ipv4/gre.c | |
| 2821 | +F: include/net/gre.h | |
| 2822 | + | |
| 2814 | 2823 | GRETH 10/100/1G Ethernet MAC device driver |
| 2815 | 2824 | M: Kristoffer Glembo <kristoffer@gaisler.com> |
| 2816 | 2825 | L: netdev@vger.kernel.org |
| 2817 | 2826 | S: Maintained |
| 2818 | 2827 | F: drivers/net/greth* |
| 2819 | 2828 | |
| 2820 | −HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER | |
| 2821 | −M: Frank Seidel <frank@f-seidel.de> | |
| 2822 | −L: platform-driver-x86@vger.kernel.org | |
| 2823 | −W: http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/ | |
| 2824 | −S: Maintained | |
| 2825 | −F: drivers/platform/x86/hdaps.c | |
| 2826 | − | |
| 2827 | −HWPOISON MEMORY FAILURE HANDLING | |
| 2828 | −M: Andi Kleen <andi@firstfloor.org> | |
| 2829 | −L: linux-mm@kvack.org | |
| 2830 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-mce-2.6.git hwpoison | |
| 2831 | −S: Maintained | |
| 2832 | −F: mm/memory-failure.c | |
| 2833 | −F: mm/hwpoison-inject.c | |
| 2834 | − | |
| 2835 | −HYPERVISOR VIRTUAL CONSOLE DRIVER | |
| 2836 | −L: linuxppc-dev@lists.ozlabs.org | |
| 2837 | −S: Odd Fixes | |
| 2838 | −F: drivers/tty/hvc/ | |
| 2839 | − | |
| 2840 | −iSCSI BOOT FIRMWARE TABLE (iBFT) DRIVER | |
| 2841 | −M: Peter Jones <pjones@redhat.com> | |
| 2842 | −M: Konrad Rzeszutek Wilk <konrad@kernel.org> | |
| 2843 | −S: Maintained | |
| 2844 | −F: drivers/firmware/iscsi_ibft* | |
| 2845 | − | |
| 2846 | 2829 | GSPCA FINEPIX SUBDRIVER |
| 2847 | 2830 | M: Frank Zago <frank@zago.net> |
| 2848 | 2831 | L: linux-media@vger.kernel.org |
| @@ -2893,6 +2876,26 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git · 44 unmodified lines | ||
| 2893 | 2876 | S: Maintained |
| 2894 | 2877 | F: drivers/media/video/gspca/ |
| 2895 | 2878 | |
| 2879 | +HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER | |
| 2880 | +M: Frank Seidel <frank@f-seidel.de> | |
| 2881 | +L: platform-driver-x86@vger.kernel.org | |
| 2882 | +W: http://www.kernel.org/pub/linux/kernel/people/fseidel/hdaps/ | |
| 2883 | +S: Maintained | |
| 2884 | +F: drivers/platform/x86/hdaps.c | |
| 2885 | + | |
| 2886 | +HWPOISON MEMORY FAILURE HANDLING | |
| 2887 | +M: Andi Kleen <andi@firstfloor.org> | |
| 2888 | +L: linux-mm@kvack.org | |
| 2889 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/ak/linux-mce-2.6.git hwpoison | |
| 2890 | +S: Maintained | |
| 2891 | +F: mm/memory-failure.c | |
| 2892 | +F: mm/hwpoison-inject.c | |
| 2893 | + | |
| 2894 | +HYPERVISOR VIRTUAL CONSOLE DRIVER | |
| 2895 | +L: linuxppc-dev@lists.ozlabs.org | |
| 2896 | +S: Odd Fixes | |
| 2897 | +F: drivers/tty/hvc/ | |
| 2898 | + | |
| 2896 | 2899 | HARDWARE MONITORING |
| 2897 | 2900 | M: Jean Delvare <khali@linux-fr.org> |
| 2898 | 2901 | M: Guenter Roeck <guenter.roeck@ericsson.com> |
| @@ -3476,6 +3479,12 @@ F: Documentation/isapnp.txt · 577 unmodified lines | ||
| 3476 | 3479 | F: drivers/pnp/isapnp/ |
| 3477 | 3480 | F: include/linux/isapnp.h |
| 3478 | 3481 | |
| 3482 | +iSCSI BOOT FIRMWARE TABLE (iBFT) DRIVER | |
| 3483 | +M: Peter Jones <pjones@redhat.com> | |
| 3484 | +M: Konrad Rzeszutek Wilk <konrad@kernel.org> | |
| 3485 | +S: Maintained | |
| 3486 | +F: drivers/firmware/iscsi_ibft* | |
| 3487 | + | |
| 3479 | 3488 | ISCSI |
| 3480 | 3489 | M: Mike Christie <michaelc@cs.wisc.edu> |
| 3481 | 3490 | L: open-iscsi@googlegroups.com |
| @@ -4987,6 +4996,13 @@ F: Documentation/pps/ · 1505 unmodified lines | ||
| 4987 | 4996 | F: drivers/pps/ |
| 4988 | 4997 | F: include/linux/pps*.h |
| 4989 | 4998 | |
| 4999 | +PPTP DRIVER | |
| 5000 | +M: Dmitry Kozlov <xeb@mail.ru> | |
| 5001 | +L: netdev@vger.kernel.org | |
| 5002 | +S: Maintained | |
| 5003 | +F: drivers/net/pptp.c | |
| 5004 | +W: http://sourceforge.net/projects/accel-pptp | |
| 5005 | + | |
| 4990 | 5006 | PREEMPTIBLE KERNEL |
| 4991 | 5007 | M: Robert Love <rml@tech9.net> |
| 4992 | 5008 | L: kpreempt-tech@lists.sourceforge.net |
| @@ -5395,7 +5411,7 @@ F: drivers/media/video/*7146* · 402 unmodified lines | ||
| 5395 | 5411 | F: include/media/*7146* |
| 5396 | 5412 | |
| 5397 | 5413 | SAMSUNG AUDIO (ASoC) DRIVERS |
| 5398 | −M: Jassi Brar <jassi.brar@samsung.com> | |
| 5414 | +M: Jassi Brar <jassisinghbrar@gmail.com> | |
| 5399 | 5415 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
| 5400 | 5416 | S: Supported |
| 5401 | 5417 | F: sound/soc/samsung |
| @@ -6554,7 +6570,7 @@ S: Maintained · 1152 unmodified lines | ||
| 6554 | 6570 | F: drivers/usb/host/uhci* |
| 6555 | 6571 | |
| 6556 | 6572 | USB "USBNET" DRIVER FRAMEWORK |
| 6557 | −M: David Brownell <dbrownell@users.sourceforge.net> | |
| 6573 | +M: Oliver Neukum <oneukum@suse.de> | |
| 6558 | 6574 | L: netdev@vger.kernel.org |
| 6559 | 6575 | W: http://www.linux-usb.org/usbnet |
| 6560 | 6576 | S: Maintained |
| @@ -6920,6 +6936,18 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86. · 359 unmodified lines | ||
| 6920 | 6936 | S: Maintained |
| 6921 | 6937 | F: drivers/platform/x86 |
| 6922 | 6938 | |
| 6939 | +XEN HYPERVISOR INTERFACE | |
| 6940 | +M: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> | |
| 6941 | +M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | |
| 6942 | +L: xen-devel@lists.xensource.com (moderated for non-subscribers) | |
| 6943 | +L: virtualization@lists.linux-foundation.org | |
| 6944 | +S: Supported | |
| 6945 | +F: arch/x86/xen/ | |
| 6946 | +F: drivers/*/xen-*front.c | |
| 6947 | +F: drivers/xen/ | |
| 6948 | +F: arch/x86/include/asm/xen/ | |
| 6949 | +F: include/xen/ | |
| 6950 | + | |
| 6923 | 6951 | XEN NETWORK BACKEND DRIVER |
| 6924 | 6952 | M: Ian Campbell <ian.campbell@citrix.com> |
| 6925 | 6953 | L: xen-devel@lists.xensource.com (moderated for non-subscribers) |
| @@ -6941,18 +6969,6 @@ S: Supported · 15 unmodified lines | ||
| 6941 | 6969 | F: arch/x86/xen/*swiotlb* |
| 6942 | 6970 | F: drivers/xen/*swiotlb* |
| 6943 | 6971 | |
| 6944 | −XEN HYPERVISOR INTERFACE | |
| 6945 | −M: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com> | |
| 6946 | −M: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | |
| 6947 | −L: xen-devel@lists.xensource.com (moderated for non-subscribers) | |
| 6948 | −L: virtualization@lists.linux-foundation.org | |
| 6949 | −S: Supported | |
| 6950 | −F: arch/x86/xen/ | |
| 6951 | −F: drivers/*/xen-*front.c | |
| 6952 | −F: drivers/xen/ | |
| 6953 | −F: arch/x86/include/asm/xen/ | |
| 6954 | −F: include/xen/ | |
| 6955 | − | |
| 6956 | 6972 | XFS FILESYSTEM |
| 6957 | 6973 | P: Silicon Graphics Inc |
| 6958 | 6974 | M: Alex Elder <aelder@sgi.com> |
| @@ -7022,20 +7038,6 @@ M: "Maciej W. Rozycki" <macro@linux-mips.org> · 63 unmodified lines | ||
| 7022 | 7038 | S: Maintained |
| 7023 | 7039 | F: drivers/tty/serial/zs.* |
| 7024 | 7040 | |
| 7025 | −GRE DEMULTIPLEXER DRIVER | |
| 7026 | −M: Dmitry Kozlov <xeb@mail.ru> | |
| 7027 | −L: netdev@vger.kernel.org | |
| 7028 | −S: Maintained | |
| 7029 | −F: net/ipv4/gre.c | |
| 7030 | −F: include/net/gre.h | |
| 7031 | − | |
| 7032 | −PPTP DRIVER | |
| 7033 | −M: Dmitry Kozlov <xeb@mail.ru> | |
| 7034 | −L: netdev@vger.kernel.org | |
| 7035 | −S: Maintained | |
| 7036 | −F: drivers/net/pptp.c | |
| 7037 | −W: http://sourceforge.net/projects/accel-pptp | |
| 7038 | − | |
| 7039 | 7041 | THE REST |
| 7040 | 7042 | M: Linus Torvalds <torvalds@linux-foundation.org> |
| 7041 | 7043 | L: linux-kernel@vger.kernel.org |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | VERSION = 2 |
| 2 | 2 | PATCHLEVEL = 6 |
| 3 | 3 | SUBLEVEL = 39 |
| 4 | −EXTRAVERSION = -rc4 | |
| 4 | +EXTRAVERSION = | |
| 5 | 5 | NAME = Flesh-Eating Bats with Fangs |
| 6 | 6 | |
| 7 | 7 | # *DOCUMENTATION* |
| @@ -452,10 +452,14 @@ · 451 unmodified lines | ||
| 452 | 452 | #define __NR_fanotify_init 494 |
| 453 | 453 | #define __NR_fanotify_mark 495 |
| 454 | 454 | #define __NR_prlimit64 496 |
| 455 | +#define __NR_name_to_handle_at 497 | |
| 456 | +#define __NR_open_by_handle_at 498 | |
| 457 | +#define __NR_clock_adjtime 499 | |
| 458 | +#define __NR_syncfs 500 | |
| 455 | 459 | |
| 456 | 460 | #ifdef __KERNEL__ |
| 457 | 461 | |
| 458 | −#define NR_SYSCALLS 497 | |
| 462 | +#define NR_SYSCALLS 501 | |
| 459 | 463 | |
| 460 | 464 | #define __ARCH_WANT_IPC_PARSE_VERSION |
| 461 | 465 | #define __ARCH_WANT_OLD_READDIR |
| @@ -498,23 +498,27 @@ sys_call_table: · 497 unmodified lines | ||
| 498 | 498 | .quad sys_ni_syscall /* sys_timerfd */ |
| 499 | 499 | .quad sys_eventfd |
| 500 | 500 | .quad sys_recvmmsg |
| 501 | − .quad sys_fallocate /* 480 */ | |
| 501 | + .quad sys_fallocate /* 480 */ | |
| 502 | 502 | .quad sys_timerfd_create |
| 503 | 503 | .quad sys_timerfd_settime |
| 504 | 504 | .quad sys_timerfd_gettime |
| 505 | 505 | .quad sys_signalfd4 |
| 506 | − .quad sys_eventfd2 /* 485 */ | |
| 506 | + .quad sys_eventfd2 /* 485 */ | |
| 507 | 507 | .quad sys_epoll_create1 |
| 508 | 508 | .quad sys_dup3 |
| 509 | 509 | .quad sys_pipe2 |
| 510 | 510 | .quad sys_inotify_init1 |
| 511 | − .quad sys_preadv /* 490 */ | |
| 511 | + .quad sys_preadv /* 490 */ | |
| 512 | 512 | .quad sys_pwritev |
| 513 | 513 | .quad sys_rt_tgsigqueueinfo |
| 514 | 514 | .quad sys_perf_event_open |
| 515 | 515 | .quad sys_fanotify_init |
| 516 | − .quad sys_fanotify_mark /* 495 */ | |
| 516 | + .quad sys_fanotify_mark /* 495 */ | |
| 517 | 517 | .quad sys_prlimit64 |
| 518 | + .quad sys_name_to_handle_at | |
| 519 | + .quad sys_open_by_handle_at | |
| 520 | + .quad sys_clock_adjtime | |
| 521 | + .quad sys_syncfs /* 500 */ | |
| 518 | 522 | |
| 519 | 523 | .size sys_call_table, . - sys_call_table |
| 520 | 524 | .type sys_call_table, @object |
| @@ -375,8 +375,7 @@ static struct clocksource clocksource_rpcc = { · 374 unmodified lines | ||
| 375 | 375 | |
| 376 | 376 | static inline void register_rpcc_clocksource(long cycle_freq) |
| 377 | 377 | { |
| 378 | − clocksource_calc_mult_shift(&clocksource_rpcc, cycle_freq, 4); | |
| 379 | − clocksource_register(&clocksource_rpcc); | |
| 378 | + clocksource_register_hz(&clocksource_rpcc, cycle_freq); | |
| 380 | 379 | } |
| 381 | 380 | #else /* !CONFIG_SMP */ |
| 382 | 381 | static inline void register_rpcc_clocksource(long cycle_freq) |
| @@ -74,7 +74,7 @@ ZTEXTADDR := $(CONFIG_ZBOOT_ROM_TEXT) · 73 unmodified lines | ||
| 74 | 74 | ZBSSADDR := $(CONFIG_ZBOOT_ROM_BSS) |
| 75 | 75 | else |
| 76 | 76 | ZTEXTADDR := 0 |
| 77 | −ZBSSADDR := ALIGN(4) | |
| 77 | +ZBSSADDR := ALIGN(8) | |
| 78 | 78 | endif |
| 79 | 79 | |
| 80 | 80 | SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/ |
| @@ -179,15 +179,14 @@ not_angel: · 178 unmodified lines | ||
| 179 | 179 | bl cache_on |
| 180 | 180 | |
| 181 | 181 | restart: adr r0, LC0 |
| 182 | − ldmia r0, {r1, r2, r3, r5, r6, r9, r11, r12} | |
| 183 | − ldr sp, [r0, #32] | |
| 182 | + ldmia r0, {r1, r2, r3, r6, r9, r11, r12} | |
| 183 | + ldr sp, [r0, #28] | |
| 184 | 184 | |
| 185 | 185 | /* |
| 186 | 186 | * We might be running at a different address. We need |
| 187 | 187 | * to fix up various pointers. |
| 188 | 188 | */ |
| 189 | 189 | sub r0, r0, r1 @ calculate the delta offset |
| 190 | − add r5, r5, r0 @ _start | |
| 191 | 190 | add r6, r6, r0 @ _edata |
| 192 | 191 | |
| 193 | 192 | #ifndef CONFIG_ZBOOT_ROM |
| @@ -206,31 +205,40 @@ restart: adr r0, LC0 · 12 unmodified lines | ||
| 206 | 205 | /* |
| 207 | 206 | * Check to see if we will overwrite ourselves. |
| 208 | 207 | * r4 = final kernel address |
| 209 | − * r5 = start of this image | |
| 210 | 208 | * r9 = size of decompressed image |
| 211 | 209 | * r10 = end of this image, including bss/stack/malloc space if non XIP |
| 212 | 210 | * We basically want: |
| 213 | − * r4 >= r10 -> OK | |
| 214 | − * r4 + image length <= r5 -> OK | |
| 211 | + * r4 - 16k page directory >= r10 -> OK | |
| 212 | + * r4 + image length <= current position (pc) -> OK | |
| 215 | 213 | */ |
| 214 | + add r10, r10, #16384 | |
| 216 | 215 | cmp r4, r10 |
| 217 | 216 | bhs wont_overwrite |
| 218 | 217 | add r10, r4, r9 |
| 219 | − cmp r10, r5 | |
| 218 | + ARM( cmp r10, pc ) | |
| 219 | + THUMB( mov lr, pc ) | |
| 220 | + THUMB( cmp r10, lr ) | |
| 220 | 221 | bls wont_overwrite |
| 221 | 222 | |
| 222 | 223 | /* |
| 223 | 224 | * Relocate ourselves past the end of the decompressed kernel. |
| 224 | − * r5 = start of this image | |
| 225 | 225 | * r6 = _edata |
| 226 | 226 | * r10 = end of the decompressed kernel |
| 227 | 227 | * Because we always copy ahead, we need to do it from the end and go |
| 228 | 228 | * backward in case the source and destination overlap. |
| 229 | 229 | */ |
| 230 | − /* Round up to next 256-byte boundary. */ | |
| 231 | − add r10, r10, #256 | |
| 230 | + /* | |
| 231 | + * Bump to the next 256-byte boundary with the size of | |
| 232 | + * the relocation code added. This avoids overwriting | |
| 233 | + * ourself when the offset is small. | |
| 234 | + */ | |
| 235 | + add r10, r10, #((reloc_code_end - restart + 256) & ~255) | |
| 232 | 236 | bic r10, r10, #255 |
| 233 | 237 | |
| 238 | + /* Get start of code we want to copy and align it down. */ | |
| 239 | + adr r5, restart | |
| 240 | + bic r5, r5, #31 | |
| 241 | + | |
| 234 | 242 | sub r9, r6, r5 @ size to copy |
| 235 | 243 | add r9, r9, #31 @ rounded up to a multiple |
| 236 | 244 | bic r9, r9, #31 @ ... of 32 bytes |
| @@ -245,6 +253,11 @@ restart: adr r0, LC0 · 8 unmodified lines | ||
| 245 | 253 | /* Preserve offset to relocated code. */ |
| 246 | 254 | sub r6, r9, r6 |
| 247 | 255 | |
| 256 | +#ifndef CONFIG_ZBOOT_ROM | |
| 257 | + /* cache_clean_flush may use the stack, so relocate it */ | |
| 258 | + add sp, sp, r6 | |
| 259 | +#endif | |
| 260 | + | |
| 248 | 261 | bl cache_clean_flush |
| 249 | 262 | |
| 250 | 263 | adr r0, BSYM(restart) |
| @@ -333,7 +346,6 @@ not_relocated: mov r0, #0 · 82 unmodified lines | ||
| 333 | 346 | LC0: .word LC0 @ r1 |
| 334 | 347 | .word __bss_start @ r2 |
| 335 | 348 | .word _end @ r3 |
| 336 | − .word _start @ r5 | |
| 337 | 349 | .word _edata @ r6 |
| 338 | 350 | .word _image_size @ r9 |
| 339 | 351 | .word _got_start @ r11 |
| @@ -1062,6 +1074,7 @@ memdump: mov r12, r0 · 722 unmodified lines | ||
| 1062 | 1074 | #endif |
| 1063 | 1075 | |
| 1064 | 1076 | .ltorg |
| 1077 | +reloc_code_end: | |
| 1065 | 1078 | |
| 1066 | 1079 | .align |
| 1067 | 1080 | .section ".stack", "aw", %nobits |
| @@ -54,6 +54,7 @@ SECTIONS · 53 unmodified lines | ||
| 54 | 54 | .bss : { *(.bss) } |
| 55 | 55 | _end = .; |
| 56 | 56 | |
| 57 | + . = ALIGN(8); /* the stack must be 64-bit aligned */ | |
| 57 | 58 | .stack : { *(.stack) } |
| 58 | 59 | |
| 59 | 60 | .stab 0 : { *(.stab) } |
| @@ -0,0 +1,48 @@ | ||
| 1 | +CONFIG_EXPERIMENTAL=y | |
| 2 | +CONFIG_LOG_BUF_SHIFT=14 | |
| 3 | +CONFIG_EMBEDDED=y | |
| 4 | +# CONFIG_HOTPLUG is not set | |
| 5 | +# CONFIG_ELF_CORE is not set | |
| 6 | +# CONFIG_FUTEX is not set | |
| 7 | +# CONFIG_TIMERFD is not set | |
| 8 | +# CONFIG_VM_EVENT_COUNTERS is not set | |
| 9 | +# CONFIG_COMPAT_BRK is not set | |
| 10 | +CONFIG_SLAB=y | |
| 11 | +# CONFIG_LBDAF is not set | |
| 12 | +# CONFIG_BLK_DEV_BSG is not set | |
| 13 | +# CONFIG_IOSCHED_DEADLINE is not set | |
| 14 | +# CONFIG_IOSCHED_CFQ is not set | |
| 15 | +# CONFIG_MMU is not set | |
| 16 | +CONFIG_ARCH_AT91=y | |
| 17 | +CONFIG_ARCH_AT91X40=y | |
| 18 | +CONFIG_MACH_AT91EB01=y | |
| 19 | +CONFIG_AT91_EARLY_USART0=y | |
| 20 | +CONFIG_CPU_ARM7TDMI=y | |
| 21 | +CONFIG_SET_MEM_PARAM=y | |
| 22 | +CONFIG_DRAM_BASE=0x01000000 | |
| 23 | +CONFIG_DRAM_SIZE=0x00400000 | |
| 24 | +CONFIG_FLASH_MEM_BASE=0x01400000 | |
| 25 | +CONFIG_PROCESSOR_ID=0x14000040 | |
| 26 | +CONFIG_ZBOOT_ROM_TEXT=0x0 | |
| 27 | +CONFIG_ZBOOT_ROM_BSS=0x0 | |
| 28 | +CONFIG_BINFMT_FLAT=y | |
| 29 | +# CONFIG_SUSPEND is not set | |
| 30 | +# CONFIG_FW_LOADER is not set | |
| 31 | +CONFIG_MTD=y | |
| 32 | +CONFIG_MTD_PARTITIONS=y | |
| 33 | +CONFIG_MTD_CHAR=y | |
| 34 | +CONFIG_MTD_BLOCK=y | |
| 35 | +CONFIG_MTD_RAM=y | |
| 36 | +CONFIG_MTD_ROM=y | |
| 37 | +CONFIG_BLK_DEV_RAM=y | |
| 38 | +# CONFIG_INPUT is not set | |
| 39 | +# CONFIG_SERIO is not set | |
| 40 | +# CONFIG_VT is not set | |
| 41 | +# CONFIG_DEVKMEM is not set | |
| 42 | +# CONFIG_HW_RANDOM is not set | |
| 43 | +# CONFIG_HWMON is not set | |
| 44 | +# CONFIG_USB_SUPPORT is not set | |
| 45 | +CONFIG_EXT2_FS=y | |
| 46 | +# CONFIG_DNOTIFY is not set | |
| 47 | +CONFIG_ROMFS_FS=y | |
| 48 | +# CONFIG_ENABLE_MUST_CHECK is not set | |
| @@ -2,6 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | #define __ASM_ARM_CPUTYPE_H |
| 3 | 3 | |
| 4 | 4 | #include <linux/stringify.h> |
| 5 | +#include <linux/kernel.h> | |
| 5 | 6 | |
| 6 | 7 | #define CPUID_ID 0 |
| 7 | 8 | #define CPUID_CACHETYPE 1 |
| @@ -39,10 +39,13 @@ typedef u32 kprobe_opcode_t; · 38 unmodified lines | ||
| 39 | 39 | struct kprobe; |
| 40 | 40 | typedef void (kprobe_insn_handler_t)(struct kprobe *, struct pt_regs *); |
| 41 | 41 | |
| 42 | +typedef unsigned long (kprobe_check_cc)(unsigned long); | |
| 43 | + | |
| 42 | 44 | /* Architecture specific copy of original instruction. */ |
| 43 | 45 | struct arch_specific_insn { |
| 44 | 46 | kprobe_opcode_t *insn; |
| 45 | 47 | kprobe_insn_handler_t *insn_handler; |
| 48 | + kprobe_check_cc *insn_check_cc; | |
| 46 | 49 | }; |
| 47 | 50 | |
| 48 | 51 | struct prev_kprobe { |
| @@ -159,7 +159,7 @@ extern unsigned int user_debug; · 158 unmodified lines | ||
| 159 | 159 | #include <mach/barriers.h> |
| 160 | 160 | #elif defined(CONFIG_ARM_DMA_MEM_BUFFERABLE) || defined(CONFIG_SMP) |
| 161 | 161 | #define mb() do { dsb(); outer_sync(); } while (0) |
| 162 | −#define rmb() dmb() | |
| 162 | +#define rmb() dsb() | |
| 163 | 163 | #define wmb() mb() |
| 164 | 164 | #else |
| 165 | 165 | #include <asm/memory.h> |
| @@ -396,6 +396,10 @@ · 395 unmodified lines | ||
| 396 | 396 | #define __NR_fanotify_init (__NR_SYSCALL_BASE+367) |
| 397 | 397 | #define __NR_fanotify_mark (__NR_SYSCALL_BASE+368) |
| 398 | 398 | #define __NR_prlimit64 (__NR_SYSCALL_BASE+369) |
| 399 | +#define __NR_name_to_handle_at (__NR_SYSCALL_BASE+370) | |
| 400 | +#define __NR_open_by_handle_at (__NR_SYSCALL_BASE+371) | |
| 401 | +#define __NR_clock_adjtime (__NR_SYSCALL_BASE+372) | |
| 402 | +#define __NR_syncfs (__NR_SYSCALL_BASE+373) | |
| 399 | 403 | |
| 400 | 404 | /* |
| 401 | 405 | * The following SWIs are ARM private. |
| @@ -379,6 +379,10 @@ · 378 unmodified lines | ||
| 379 | 379 | CALL(sys_fanotify_init) |
| 380 | 380 | CALL(sys_fanotify_mark) |
| 381 | 381 | CALL(sys_prlimit64) |
| 382 | +/* 370 */ CALL(sys_name_to_handle_at) | |
| 383 | + CALL(sys_open_by_handle_at) | |
| 384 | + CALL(sys_clock_adjtime) | |
| 385 | + CALL(sys_syncfs) | |
| 382 | 386 | #ifndef syscalls_counted |
| 383 | 387 | .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls |
| 384 | 388 | #define syscalls_counted |
| @@ -34,9 +34,6 @@ · 33 unmodified lines | ||
| 34 | 34 | * |
| 35 | 35 | * *) If the PC is written to by the instruction, the |
| 36 | 36 | * instruction must be fully simulated in software. |
| 37 | − * If it is a conditional instruction, the handler | |
| 38 | − * will use insn[0] to copy its condition code to | |
| 39 | − * set r0 to 1 and insn[1] to "mov pc, lr" to return. | |
| 40 | 37 | * |
| 41 | 38 | * *) Otherwise, a modified form of the instruction is |
| 42 | 39 | * directly executed. Its handler calls the |
| @@ -68,13 +65,17 @@ · 25 unmodified lines | ||
| 68 | 65 | |
| 69 | 66 | #define branch_displacement(insn) sign_extend(((insn) & 0xffffff) << 2, 25) |
| 70 | 67 | |
| 68 | +#define is_r15(insn, bitpos) (((insn) & (0xf << bitpos)) == (0xf << bitpos)) | |
| 69 | + | |
| 70 | +/* | |
| 71 | + * Test if load/store instructions writeback the address register. | |
| 72 | + * if P (bit 24) == 0 or W (bit 21) == 1 | |
| 73 | + */ | |
| 74 | +#define is_writeback(insn) ((insn ^ 0x01000000) & 0x01200000) | |
| 75 | + | |
| 71 | 76 | #define PSR_fs (PSR_f|PSR_s) |
| 72 | 77 | |
| 73 | 78 | #define KPROBE_RETURN_INSTRUCTION 0xe1a0f00e /* mov pc, lr */ |
| 74 | −#define SET_R0_TRUE_INSTRUCTION 0xe3a00001 /* mov r0, #1 */ | |
| 75 | − | |
| 76 | −#define truecc_insn(insn) (((insn) & 0xf0000000) | \ | |
| 77 | − (SET_R0_TRUE_INSTRUCTION & 0x0fffffff)) | |
| 78 | 79 | |
| 79 | 80 | typedef long (insn_0arg_fn_t)(void); |
| 80 | 81 | typedef long (insn_1arg_fn_t)(long); |
| @@ -419,14 +420,10 @@ insnslot_llret_4arg_rwflags(long r0, long r1, long r2, long r3, long *cpsr, · 338 unmodified lines | ||
| 419 | 420 | |
| 420 | 421 | static void __kprobes simulate_bbl(struct kprobe *p, struct pt_regs *regs) |
| 421 | 422 | { |
| 422 | − insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; | |
| 423 | 423 | kprobe_opcode_t insn = p->opcode; |
| 424 | 424 | long iaddr = (long)p->addr; |
| 425 | 425 | int disp = branch_displacement(insn); |
| 426 | 426 | |
| 427 | − if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn)) | |
| 428 | − return; | |
| 429 | − | |
| 430 | 427 | if (insn & (1 << 24)) |
| 431 | 428 | regs->ARM_lr = iaddr + 4; |
| 432 | 429 | |
| @@ -446,14 +443,10 @@ static void __kprobes simulate_blx1(struct kprobe *p, struct pt_regs *regs) · 13 unmodified lines | ||
| 446 | 443 | |
| 447 | 444 | static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs) |
| 448 | 445 | { |
| 449 | − insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; | |
| 450 | 446 | kprobe_opcode_t insn = p->opcode; |
| 451 | 447 | int rm = insn & 0xf; |
| 452 | 448 | long rmv = regs->uregs[rm]; |
| 453 | 449 | |
| 454 | − if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn)) | |
| 455 | − return; | |
| 456 | − | |
| 457 | 450 | if (insn & (1 << 5)) |
| 458 | 451 | regs->ARM_lr = (long)p->addr + 4; |
| 459 | 452 | |
| @@ -463,9 +456,16 @@ static void __kprobes simulate_blx2bx(struct kprobe *p, struct pt_regs *regs) · 3 unmodified lines | ||
| 463 | 456 | regs->ARM_cpsr |= PSR_T_BIT; |
| 464 | 457 | } |
| 465 | 458 | |
| 459 | +static void __kprobes simulate_mrs(struct kprobe *p, struct pt_regs *regs) | |
| 460 | +{ | |
| 461 | + kprobe_opcode_t insn = p->opcode; | |
| 462 | + int rd = (insn >> 12) & 0xf; | |
| 463 | + unsigned long mask = 0xf8ff03df; /* Mask out execution state */ | |
| 464 | + regs->uregs[rd] = regs->ARM_cpsr & mask; | |
| 465 | +} | |
| 466 | + | |
| 466 | 467 | static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs) |
| 467 | 468 | { |
| 468 | − insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; | |
| 469 | 469 | kprobe_opcode_t insn = p->opcode; |
| 470 | 470 | int rn = (insn >> 16) & 0xf; |
| 471 | 471 | int lbit = insn & (1 << 20); |
| @@ -476,9 +476,6 @@ static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs) · 4 unmodified lines | ||
| 476 | 476 | int reg_bit_vector; |
| 477 | 477 | int reg_count; |
| 478 | 478 | |
| 479 | − if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn)) | |
| 480 | − return; | |
| 481 | − | |
| 482 | 479 | reg_count = 0; |
| 483 | 480 | reg_bit_vector = insn & 0xffff; |
| 484 | 481 | while (reg_bit_vector) { |
| @@ -510,11 +507,6 @@ static void __kprobes simulate_ldm1stm1(struct kprobe *p, struct pt_regs *regs) · 25 unmodified lines | ||
| 510 | 507 | |
| 511 | 508 | static void __kprobes simulate_stm1_pc(struct kprobe *p, struct pt_regs *regs) |
| 512 | 509 | { |
| 513 | − insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; | |
| 514 | − | |
| 515 | − if (!insnslot_1arg_rflags(0, regs->ARM_cpsr, i_fn)) | |
| 516 | − return; | |
| 517 | − | |
| 518 | 510 | regs->ARM_pc = (long)p->addr + str_pc_offset; |
| 519 | 511 | simulate_ldm1stm1(p, regs); |
| 520 | 512 | regs->ARM_pc = (long)p->addr + 4; |
| @@ -525,24 +517,16 @@ static void __kprobes simulate_mov_ipsp(struct kprobe *p, struct pt_regs *regs) · 4 unmodified lines | ||
| 525 | 517 | regs->uregs[12] = regs->uregs[13]; |
| 526 | 518 | } |
| 527 | 519 | |
| 528 | −static void __kprobes emulate_ldcstc(struct kprobe *p, struct pt_regs *regs) | |
| 529 | −{ | |
| 530 | − insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; | |
| 531 | − kprobe_opcode_t insn = p->opcode; | |
| 532 | − int rn = (insn >> 16) & 0xf; | |
| 533 | − long rnv = regs->uregs[rn]; | |
| 534 | − | |
| 535 | − /* Save Rn in case of writeback. */ | |
| 536 | − regs->uregs[rn] = insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn); | |
| 537 | −} | |
| 538 | − | |
| 539 | 520 | static void __kprobes emulate_ldrd(struct kprobe *p, struct pt_regs *regs) |
| 540 | 521 | { |
| 541 | 522 | insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0]; |
| 542 | 523 | kprobe_opcode_t insn = p->opcode; |
| 524 | + long ppc = (long)p->addr + 8; | |
| 543 | 525 | int rd = (insn >> 12) & 0xf; |
| 544 | 526 | int rn = (insn >> 16) & 0xf; |
| 545 | 527 | int rm = insn & 0xf; /* rm may be invalid, don't care. */ |
| 528 | + long rmv = (rm == 15) ? ppc : regs->uregs[rm]; | |
| 529 | + long rnv = (rn == 15) ? ppc : regs->uregs[rn]; | |
| 546 | 530 | |
| 547 | 531 | /* Not following the C calling convention here, so need asm(). */ |
| 548 | 532 | __asm__ __volatile__ ( |
| @@ -554,29 +538,36 @@ static void __kprobes emulate_ldrd(struct kprobe *p, struct pt_regs *regs) · 5 unmodified lines | ||
| 554 | 538 | "str r0, %[rn] \n\t" /* in case of writeback */ |
| 555 | 539 | "str r2, %[rd0] \n\t" |
| 556 | 540 | "str r3, %[rd1] \n\t" |
| 557 | − : [rn] "+m" (regs->uregs[rn]), | |
| 541 | + : [rn] "+m" (rnv), | |
| 558 | 542 | [rd0] "=m" (regs->uregs[rd]), |
| 559 | 543 | [rd1] "=m" (regs->uregs[rd+1]) |
| 560 | − : [rm] "m" (regs->uregs[rm]), | |
| 544 | + : [rm] "m" (rmv), | |
| 561 | 545 | [cpsr] "r" (regs->ARM_cpsr), |
| 562 | 546 | [i_fn] "r" (i_fn) |
| 563 | 547 | : "r0", "r1", "r2", "r3", "lr", "cc" |
| 564 | 548 | ); |
| 549 | + if (is_writeback(insn)) | |
| 550 | + regs->uregs[rn] = rnv; | |
| 565 | 551 | } |
| 566 | 552 | |
| 567 | 553 | static void __kprobes emulate_strd(struct kprobe *p, struct pt_regs *regs) |
| 568 | 554 | { |
| 569 | 555 | insn_4arg_fn_t *i_fn = (insn_4arg_fn_t *)&p->ainsn.insn[0]; |
| 570 | 556 | kprobe_opcode_t insn = p->opcode; |
| 557 | + long ppc = (long)p->addr + 8; | |
| 571 | 558 | int rd = (insn >> 12) & 0xf; |
| 572 | 559 | int rn = (insn >> 16) & 0xf; |
| 573 | 560 | int rm = insn & 0xf; |
| 574 | − long rnv = regs->uregs[rn]; | |
| 575 | − long rmv = regs->uregs[rm]; /* rm/rmv may be invalid, don't care. */ | |
| 561 | + long rnv = (rn == 15) ? ppc : regs->uregs[rn]; | |
| 562 | + /* rm/rmv may be invalid, don't care. */ | |
| 563 | + long rmv = (rm == 15) ? ppc : regs->uregs[rm]; | |
| 564 | + long rnv_wb; | |
| 576 | 565 | |
| 577 | − regs->uregs[rn] = insnslot_4arg_rflags(rnv, rmv, regs->uregs[rd], | |
| 566 | + rnv_wb = insnslot_4arg_rflags(rnv, rmv, regs->uregs[rd], | |
| 578 | 567 | regs->uregs[rd+1], |
| 579 | 568 | regs->ARM_cpsr, i_fn); |
| 569 | + if (is_writeback(insn)) | |
| 570 | + regs->uregs[rn] = rnv_wb; | |
| 580 | 571 | } |
| 581 | 572 | |
| 582 | 573 | static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs) |
| @@ -630,31 +621,6 @@ static void __kprobes emulate_str(struct kprobe *p, struct pt_regs *regs) · 47 unmodified lines | ||
| 630 | 621 | regs->uregs[rn] = rnv_wb; /* Save Rn in case of writeback. */ |
| 631 | 622 | } |
| 632 | 623 | |
| 633 | −static void __kprobes emulate_mrrc(struct kprobe *p, struct pt_regs *regs) | |
| 634 | −{ | |
| 635 | − insn_llret_0arg_fn_t *i_fn = (insn_llret_0arg_fn_t *)&p->ainsn.insn[0]; | |
| 636 | − kprobe_opcode_t insn = p->opcode; | |
| 637 | − union reg_pair fnr; | |
| 638 | − int rd = (insn >> 12) & 0xf; | |
| 639 | − int rn = (insn >> 16) & 0xf; | |
| 640 | − | |
| 641 | − fnr.dr = insnslot_llret_0arg_rflags(regs->ARM_cpsr, i_fn); | |
| 642 | − regs->uregs[rn] = fnr.r0; | |
| 643 | − regs->uregs[rd] = fnr.r1; | |
| 644 | −} | |
| 645 | − | |
| 646 | −static void __kprobes emulate_mcrr(struct kprobe *p, struct pt_regs *regs) | |
| 647 | −{ | |
| 648 | − insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0]; | |
| 649 | − kprobe_opcode_t insn = p->opcode; | |
| 650 | − int rd = (insn >> 12) & 0xf; | |
| 651 | − int rn = (insn >> 16) & 0xf; | |
| 652 | − long rnv = regs->uregs[rn]; | |
| 653 | − long rdv = regs->uregs[rd]; | |
| 654 | − | |
| 655 | − insnslot_2arg_rflags(rnv, rdv, regs->ARM_cpsr, i_fn); | |
| 656 | −} | |
| 657 | − | |
| 658 | 624 | static void __kprobes emulate_sat(struct kprobe *p, struct pt_regs *regs) |
| 659 | 625 | { |
| 660 | 626 | insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; |
| @@ -688,32 +654,32 @@ static void __kprobes emulate_none(struct kprobe *p, struct pt_regs *regs) · 27 unmodified lines | ||
| 688 | 654 | insnslot_0arg_rflags(regs->ARM_cpsr, i_fn); |
| 689 | 655 | } |
| 690 | 656 | |
| 691 | −static void __kprobes emulate_rd12(struct kprobe *p, struct pt_regs *regs) | |
| 657 | +static void __kprobes emulate_nop(struct kprobe *p, struct pt_regs *regs) | |
| 692 | 658 | { |
| 693 | − insn_0arg_fn_t *i_fn = (insn_0arg_fn_t *)&p->ainsn.insn[0]; | |
| 694 | − kprobe_opcode_t insn = p->opcode; | |
| 695 | − int rd = (insn >> 12) & 0xf; | |
| 696 | − | |
| 697 | − regs->uregs[rd] = insnslot_0arg_rflags(regs->ARM_cpsr, i_fn); | |
| 698 | 659 | } |
| 699 | 660 | |
| 700 | −static void __kprobes emulate_ird12(struct kprobe *p, struct pt_regs *regs) | |
| 661 | +static void __kprobes | |
| 662 | +emulate_rd12_modify(struct kprobe *p, struct pt_regs *regs) | |
| 701 | 663 | { |
| 702 | 664 | insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; |
| 703 | 665 | kprobe_opcode_t insn = p->opcode; |
| 704 | − int ird = (insn >> 12) & 0xf; | |
| 666 | + int rd = (insn >> 12) & 0xf; | |
| 667 | + long rdv = regs->uregs[rd]; | |
| 705 | 668 | |
| 706 | − insnslot_1arg_rflags(regs->uregs[ird], regs->ARM_cpsr, i_fn); | |
| 669 | + regs->uregs[rd] = insnslot_1arg_rflags(rdv, regs->ARM_cpsr, i_fn); | |
| 707 | 670 | } |
| 708 | 671 | |
| 709 | −static void __kprobes emulate_rn16(struct kprobe *p, struct pt_regs *regs) | |
| 672 | +static void __kprobes | |
| 673 | +emulate_rd12rn0_modify(struct kprobe *p, struct pt_regs *regs) | |
| 710 | 674 | { |
| 711 | − insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; | |
| 675 | + insn_2arg_fn_t *i_fn = (insn_2arg_fn_t *)&p->ainsn.insn[0]; | |
| 712 | 676 | kprobe_opcode_t insn = p->opcode; |
| 713 | − int rn = (insn >> 16) & 0xf; | |
| 677 | + int rd = (insn >> 12) & 0xf; | |
| 678 | + int rn = insn & 0xf; | |
| 679 | + long rdv = regs->uregs[rd]; | |
| 714 | 680 | long rnv = regs->uregs[rn]; |
| 715 | 681 | |
| 716 | − insnslot_1arg_rflags(rnv, regs->ARM_cpsr, i_fn); | |
| 682 | + regs->uregs[rd] = insnslot_2arg_rflags(rdv, rnv, regs->ARM_cpsr, i_fn); | |
| 717 | 683 | } |
| 718 | 684 | |
| 719 | 685 | static void __kprobes emulate_rd12rm0(struct kprobe *p, struct pt_regs *regs) |
| @@ -818,6 +784,17 @@ emulate_alu_imm_rwflags(struct kprobe *p, struct pt_regs *regs) · 98 unmodified lines | ||
| 818 | 784 | regs->uregs[rd] = insnslot_1arg_rwflags(rnv, ®s->ARM_cpsr, i_fn); |
| 819 | 785 | } |
| 820 | 786 | |
| 787 | +static void __kprobes | |
| 788 | +emulate_alu_tests_imm(struct kprobe *p, struct pt_regs *regs) | |
| 789 | +{ | |
| 790 | + insn_1arg_fn_t *i_fn = (insn_1arg_fn_t *)&p->ainsn.insn[0]; | |
| 791 | + kprobe_opcode_t insn = p->opcode; | |
| 792 | + int rn = (insn >> 16) & 0xf; | |
| 793 | + long rnv = (rn == 15) ? (long)p->addr + 8 : regs->uregs[rn]; | |
| 794 | + | |
| 795 | + insnslot_1arg_rwflags(rnv, ®s->ARM_cpsr, i_fn); | |
| 796 | +} | |
| 797 | + | |
| 821 | 798 | static void __kprobes |
| 822 | 799 | emulate_alu_rflags(struct kprobe *p, struct pt_regs *regs) |
| 823 | 800 | { |
| @@ -854,14 +831,34 @@ emulate_alu_rwflags(struct kprobe *p, struct pt_regs *regs) · 30 unmodified lines | ||
| 854 | 831 | insnslot_3arg_rwflags(rnv, rmv, rsv, ®s->ARM_cpsr, i_fn); |
| 855 | 832 | } |
| 856 | 833 | |
| 834 | +static void __kprobes | |
| 835 | +emulate_alu_tests(struct kprobe *p, struct pt_regs *regs) | |
| 836 | +{ | |
| 837 | + insn_3arg_fn_t *i_fn = (insn_3arg_fn_t *)&p->ainsn.insn[0]; | |
| 838 | + kprobe_opcode_t insn = p->opcode; | |
| 839 | + long ppc = (long)p->addr + 8; | |
| 840 | + int rn = (insn >> 16) & 0xf; | |
| 841 | + int rs = (insn >> 8) & 0xf; /* rs/rsv may be invalid, don't care. */ | |
| 842 | + int rm = insn & 0xf; | |
| 843 | + long rnv = (rn == 15) ? ppc : regs->uregs[rn]; | |
| 844 | + long rmv = (rm == 15) ? ppc : regs->uregs[rm]; | |
| 845 | + long rsv = regs->uregs[rs]; | |
| 846 | + | |
| 847 | + insnslot_3arg_rwflags(rnv, rmv, rsv, ®s->ARM_cpsr, i_fn); | |
| 848 | +} | |
| 849 | + | |
| 857 | 850 | static enum kprobe_insn __kprobes |
| 858 | 851 | prep_emulate_ldr_str(kprobe_opcode_t insn, struct arch_specific_insn *asi) |
| 859 | 852 | { |
| 860 | − int ibit = (insn & (1 << 26)) ? 25 : 22; | |
| 853 | + int not_imm = (insn & (1 << 26)) ? (insn & (1 << 25)) | |
| 854 | + : (~insn & (1 << 22)); | |
| 855 | + | |
| 856 | + if (is_writeback(insn) && is_r15(insn, 16)) | |
| 857 | + return INSN_REJECTED; /* Writeback to PC */ | |
| 861 | 858 | |
| 862 | 859 | insn &= 0xfff00fff; |
| 863 | 860 | insn |= 0x00001000; /* Rn = r0, Rd = r1 */ |
| 864 | − if (insn & (1 << ibit)) { | |
| 861 | + if (not_imm) { | |
| 865 | 862 | insn &= ~0xf; |
| 866 | 863 | insn |= 2; /* Rm = r2 */ |
| 867 | 864 | } |
| @@ -871,20 +868,40 @@ prep_emulate_ldr_str(kprobe_opcode_t insn, struct arch_specific_insn *asi) · 3 unmodified lines | ||
| 871 | 868 | } |
| 872 | 869 | |
| 873 | 870 | static enum kprobe_insn __kprobes |
| 874 | −prep_emulate_rd12rm0(kprobe_opcode_t insn, struct arch_specific_insn *asi) | |
| 871 | +prep_emulate_rd12_modify(kprobe_opcode_t insn, struct arch_specific_insn *asi) | |
| 875 | 872 | { |
| 876 | − insn &= 0xffff0ff0; /* Rd = r0, Rm = r0 */ | |
| 873 | + if (is_r15(insn, 12)) | |
| 874 | + return INSN_REJECTED; /* Rd is PC */ | |
| 875 | + | |
| 876 | + insn &= 0xffff0fff; /* Rd = r0 */ | |
| 877 | 877 | asi->insn[0] = insn; |
| 878 | − asi->insn_handler = emulate_rd12rm0; | |
| 878 | + asi->insn_handler = emulate_rd12_modify; | |
| 879 | 879 | return INSN_GOOD; |
| 880 | 880 | } |
| 881 | 881 | |
| 882 | 882 | static enum kprobe_insn __kprobes |
| 883 | −prep_emulate_rd12(kprobe_opcode_t insn, struct arch_specific_insn *asi) | |
| 883 | +prep_emulate_rd12rn0_modify(kprobe_opcode_t insn, | |
| 884 | + struct arch_specific_insn *asi) | |
| 884 | 885 | { |
| 885 | − insn &= 0xffff0fff; /* Rd = r0 */ | |
| 886 | + if (is_r15(insn, 12)) | |
| 887 | + return INSN_REJECTED; /* Rd is PC */ | |
| 888 | + | |
| 889 | + insn &= 0xffff0ff0; /* Rd = r0 */ | |
| 890 | + insn |= 0x00000001; /* Rn = r1 */ | |
| 891 | + asi->insn[0] = insn; | |
| 892 | + asi->insn_handler = emulate_rd12rn0_modify; | |
| 893 | + return INSN_GOOD; | |
| 894 | +} | |
| 895 | + | |
| 896 | +static enum kprobe_insn __kprobes | |
| 897 | +prep_emulate_rd12rm0(kprobe_opcode_t insn, struct arch_specific_insn *asi) | |
| 898 | +{ | |
| 899 | + if (is_r15(insn, 12)) | |
| 900 | + return INSN_REJECTED; /* Rd is PC */ | |
| 901 | + | |
| 902 | + insn &= 0xffff0ff0; /* Rd = r0, Rm = r0 */ | |
| 886 | 903 | asi->insn[0] = insn; |
| 887 | − asi->insn_handler = emulate_rd12; | |
| 904 | + asi->insn_handler = emulate_rd12rm0; | |
| 888 | 905 | return INSN_GOOD; |
| 889 | 906 | } |
| 890 | 907 | |
| @@ -892,6 +909,9 @@ static enum kprobe_insn __kprobes · 1 unmodified line | ||
| 892 | 909 | prep_emulate_rd12rn16rm0_wflags(kprobe_opcode_t insn, |
| 893 | 910 | struct arch_specific_insn *asi) |
| 894 | 911 | { |
| 912 | + if (is_r15(insn, 12)) | |
| 913 | + return INSN_REJECTED; /* Rd is PC */ | |
| 914 | + | |
| 895 | 915 | insn &= 0xfff00ff0; /* Rd = r0, Rn = r0 */ |
| 896 | 916 | insn |= 0x00000001; /* Rm = r1 */ |
| 897 | 917 | asi->insn[0] = insn; |
| @@ -903,6 +923,9 @@ static enum kprobe_insn __kprobes · 5 unmodified lines | ||
| 903 | 923 | prep_emulate_rd16rs8rm0_wflags(kprobe_opcode_t insn, |
| 904 | 924 | struct arch_specific_insn *asi) |
| 905 | 925 | { |
| 926 | + if (is_r15(insn, 16)) | |
| 927 | + return INSN_REJECTED; /* Rd is PC */ | |
| 928 | + | |
| 906 | 929 | insn &= 0xfff0f0f0; /* Rd = r0, Rs = r0 */ |
| 907 | 930 | insn |= 0x00000001; /* Rm = r1 */ |
| 908 | 931 | asi->insn[0] = insn; |
| @@ -914,6 +937,9 @@ static enum kprobe_insn __kprobes · 5 unmodified lines | ||
| 914 | 937 | prep_emulate_rd16rn12rs8rm0_wflags(kprobe_opcode_t insn, |
| 915 | 938 | struct arch_specific_insn *asi) |
| 916 | 939 | { |
| 940 | + if (is_r15(insn, 16)) | |
| 941 | + return INSN_REJECTED; /* Rd is PC */ | |
| 942 | + | |
| 917 | 943 | insn &= 0xfff000f0; /* Rd = r0, Rn = r0 */ |
| 918 | 944 | insn |= 0x00000102; /* Rs = r1, Rm = r2 */ |
| 919 | 945 | asi->insn[0] = insn; |
| @@ -925,6 +951,9 @@ static enum kprobe_insn __kprobes · 5 unmodified lines | ||
| 925 | 951 | prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn, |
| 926 | 952 | struct arch_specific_insn *asi) |
| 927 | 953 | { |
| 954 | + if (is_r15(insn, 16) || is_r15(insn, 12)) | |
| 955 | + return INSN_REJECTED; /* RdHi or RdLo is PC */ | |
| 956 | + | |
| 928 | 957 | insn &= 0xfff000f0; /* RdHi = r0, RdLo = r1 */ |
| 929 | 958 | insn |= 0x00001203; /* Rs = r2, Rm = r3 */ |
| 930 | 959 | asi->insn[0] = insn; |
| @@ -945,20 +974,13 @@ prep_emulate_rdhi16rdlo12rs8rm0_wflags(kprobe_opcode_t insn, · 14 unmodified lines | ||
| 945 | 974 | static enum kprobe_insn __kprobes |
| 946 | 975 | space_1111(kprobe_opcode_t insn, struct arch_specific_insn *asi) |
| 947 | 976 | { |
| 948 | − /* CPS mmod == 1 : 1111 0001 0000 xx10 xxxx xxxx xx0x xxxx */ | |
| 949 | − /* RFE : 1111 100x x0x1 xxxx xxxx 1010 xxxx xxxx */ | |
| 950 | − /* SRS : 1111 100x x1x0 1101 xxxx 0101 xxxx xxxx */ | |
| 951 | − if ((insn & 0xfff30020) == 0xf1020000 || | |
| 952 | − (insn & 0xfe500f00) == 0xf8100a00 || | |
| 953 | − (insn & 0xfe5f0f00) == 0xf84d0500) | |
| 954 | − return INSN_REJECTED; | |
| 955 | − | |
| 956 | − /* PLD : 1111 01x1 x101 xxxx xxxx xxxx xxxx xxxx : */ | |
| 957 | − if ((insn & 0xfd700000) == 0xf4500000) { | |
| 958 | − insn &= 0xfff0ffff; /* Rn = r0 */ | |
| 959 | − asi->insn[0] = insn; | |
| 960 | − asi->insn_handler = emulate_rn16; | |
| 961 | − return INSN_GOOD; | |
| 977 | + /* memory hint : 1111 0100 x001 xxxx xxxx xxxx xxxx xxxx : */ | |
| 978 | + /* PLDI : 1111 0100 x101 xxxx xxxx xxxx xxxx xxxx : */ | |
| 979 | + /* PLDW : 1111 0101 x001 xxxx xxxx xxxx xxxx xxxx : */ | |
| 980 | + /* PLD : 1111 0101 x101 xxxx xxxx xxxx xxxx xxxx : */ | |
| 981 | + if ((insn & 0xfe300000) == 0xf4100000) { | |
| 982 | + asi->insn_handler = emulate_nop; | |
| 983 | + return INSN_GOOD_NO_SLOT; | |
| 962 | 984 | } |
| 963 | 985 | |
| 964 | 986 | /* BLX(1) : 1111 101x xxxx xxxx xxxx xxxx xxxx xxxx : */ |
| @@ -967,41 +989,22 @@ space_1111(kprobe_opcode_t insn, struct arch_specific_insn *asi) · 2 unmodified lines | ||
| 967 | 989 | return INSN_GOOD_NO_SLOT; |
| 968 | 990 | } |
| 969 | 991 | |
| 970 | − /* SETEND : 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */ | |
| 971 | − /* CDP2 : 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ | |
| 972 | − if ((insn & 0xffff00f0) == 0xf1010000 || | |
| 973 | − (insn & 0xff000010) == 0xfe000000) { | |
| 974 | − asi->insn[0] = insn; | |
| 975 | − asi->insn_handler = emulate_none; | |
| 976 | − return INSN_GOOD; | |
| 977 | − } | |
| 992 | + /* CPS : 1111 0001 0000 xxx0 xxxx xxxx xx0x xxxx */ | |
| 993 | + /* SETEND: 1111 0001 0000 0001 xxxx xxxx 0000 xxxx */ | |
| 978 | 994 | |
| 995 | + /* SRS : 1111 100x x1x0 xxxx xxxx xxxx xxxx xxxx */ | |
| 996 | + /* RFE : 1111 100x x0x1 xxxx xxxx xxxx xxxx xxxx */ | |
| 997 | + | |
| 998 | + /* Coprocessor instructions... */ | |
| 979 | 999 | /* MCRR2 : 1111 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */ |
| 980 | 1000 | /* MRRC2 : 1111 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd != Rn) */ |
| 981 | − if ((insn & 0xffe00000) == 0xfc400000) { | |
| 982 | − insn &= 0xfff00fff; /* Rn = r0 */ | |
| 983 | − insn |= 0x00001000; /* Rd = r1 */ | |
| 984 | − asi->insn[0] = insn; | |
| 985 | − asi->insn_handler = | |
| 986 | − (insn & (1 << 20)) ? emulate_mrrc : emulate_mcrr; | |
| 987 | − return INSN_GOOD; | |
| 988 | − } | |
| 1001 | + /* LDC2 : 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ | |
| 1002 | + /* STC2 : 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */ | |
| 1003 | + /* CDP2 : 1111 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ | |
| 1004 | + /* MCR2 : 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ | |
| 1005 | + /* MRC2 : 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ | |
| 989 | 1006 | |
| 990 | − /* LDC2 : 1111 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ | |
| 991 | − /* STC2 : 1111 110x xxx0 xxxx xxxx xxxx xxxx xxxx */ | |
| 992 | − if ((insn & 0xfe000000) == 0xfc000000) { | |
| 993 | − insn &= 0xfff0ffff; /* Rn = r0 */ | |
| 994 | − asi->insn[0] = insn; | |
| 995 | − asi->insn_handler = emulate_ldcstc; | |
| 996 | − return INSN_GOOD; | |
| 997 | − } | |
| 998 | − | |
| 999 | − /* MCR2 : 1111 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ | |
| 1000 | − /* MRC2 : 1111 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ | |
| 1001 | − insn &= 0xffff0fff; /* Rd = r0 */ | |
| 1002 | − asi->insn[0] = insn; | |
| 1003 | − asi->insn_handler = (insn & (1 << 20)) ? emulate_rd12 : emulate_ird12; | |
| 1004 | − return INSN_GOOD; | |
| 1007 | + return INSN_REJECTED; | |
| 1005 | 1008 | } |
| 1006 | 1009 | |
| 1007 | 1010 | static enum kprobe_insn __kprobes |
| @@ -1010,19 +1013,18 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi) · 2 unmodified lines | ||
| 1010 | 1013 | /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx xxx0 xxxx */ |
| 1011 | 1014 | if ((insn & 0x0f900010) == 0x01000000) { |
| 1012 | 1015 | |
| 1013 | − /* BXJ : cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */ | |
| 1014 | − /* MSR : cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */ | |
| 1015 | − if ((insn & 0x0ff000f0) == 0x01200020 || | |
| 1016 | − (insn & 0x0fb000f0) == 0x01200000) | |
| 1017 | − return INSN_REJECTED; | |
| 1018 | − | |
| 1019 | − /* MRS : cccc 0001 0x00 xxxx xxxx xxxx 0000 xxxx */ | |
| 1020 | − if ((insn & 0x0fb00010) == 0x01000000) | |
| 1021 | − return prep_emulate_rd12(insn, asi); | |
| 1016 | + /* MRS cpsr : cccc 0001 0000 xxxx xxxx xxxx 0000 xxxx */ | |
| 1017 | + if ((insn & 0x0ff000f0) == 0x01000000) { | |
| 1018 | + if (is_r15(insn, 12)) | |
| 1019 | + return INSN_REJECTED; /* Rd is PC */ | |
| 1020 | + asi->insn_handler = simulate_mrs; | |
| 1021 | + return INSN_GOOD_NO_SLOT; | |
| 1022 | + } | |
| 1022 | 1023 | |
| 1023 | 1024 | /* SMLALxy : cccc 0001 0100 xxxx xxxx xxxx 1xx0 xxxx */ |
| 1024 | 1025 | if ((insn & 0x0ff00090) == 0x01400080) |
| 1025 | − return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi); | |
| 1026 | + return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, | |
| 1027 | + asi); | |
| 1026 | 1028 | |
| 1027 | 1029 | /* SMULWy : cccc 0001 0010 xxxx xxxx xxxx 1x10 xxxx */ |
| 1028 | 1030 | /* SMULxy : cccc 0001 0110 xxxx xxxx xxxx 1xx0 xxxx */ |
| @@ -1031,24 +1033,29 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi) · 2 unmodified lines | ||
| 1031 | 1033 | return prep_emulate_rd16rs8rm0_wflags(insn, asi); |
| 1032 | 1034 | |
| 1033 | 1035 | /* SMLAxy : cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx : Q */ |
| 1034 | − /* SMLAWy : cccc 0001 0010 xxxx xxxx xxxx 0x00 xxxx : Q */ | |
| 1035 | − return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); | |
| 1036 | + /* SMLAWy : cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx : Q */ | |
| 1037 | + if ((insn & 0x0ff00090) == 0x01000080 || | |
| 1038 | + (insn & 0x0ff000b0) == 0x01200080) | |
| 1039 | + return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); | |
| 1040 | + | |
| 1041 | + /* BXJ : cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */ | |
| 1042 | + /* MSR : cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */ | |
| 1043 | + /* MRS spsr : cccc 0001 0100 xxxx xxxx xxxx 0000 xxxx */ | |
| 1036 | 1044 | |
| 1045 | + /* Other instruction encodings aren't yet defined */ | |
| 1046 | + return INSN_REJECTED; | |
| 1037 | 1047 | } |
| 1038 | 1048 | |
| 1039 | 1049 | /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx 0xx1 xxxx */ |
| 1040 | 1050 | else if ((insn & 0x0f900090) == 0x01000010) { |
| 1041 | 1051 | |
| 1042 | − /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */ | |
| 1043 | − if ((insn & 0xfff000f0) == 0xe1200070) | |
| 1044 | − return INSN_REJECTED; | |
| 1045 | − | |
| 1046 | 1052 | /* BLX(2) : cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */ |
| 1047 | 1053 | /* BX : cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */ |
| 1048 | 1054 | if ((insn & 0x0ff000d0) == 0x01200010) { |
| 1049 | − asi->insn[0] = truecc_insn(insn); | |
| 1055 | + if ((insn & 0x0ff000ff) == 0x0120003f) | |
| 1056 | + return INSN_REJECTED; /* BLX pc */ | |
| 1050 | 1057 | asi->insn_handler = simulate_blx2bx; |
| 1051 | − return INSN_GOOD; | |
| 1058 | + return INSN_GOOD_NO_SLOT; | |
| 1052 | 1059 | } |
| 1053 | 1060 | |
| 1054 | 1061 | /* CLZ : cccc 0001 0110 xxxx xxxx xxxx 0001 xxxx */ |
| @@ -1059,17 +1066,27 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi) · 4 unmodified lines | ||
| 1059 | 1066 | /* QSUB : cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx :Q */ |
| 1060 | 1067 | /* QDADD : cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx :Q */ |
| 1061 | 1068 | /* QDSUB : cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx :Q */ |
| 1062 | − return prep_emulate_rd12rn16rm0_wflags(insn, asi); | |
| 1069 | + if ((insn & 0x0f9000f0) == 0x01000050) | |
| 1070 | + return prep_emulate_rd12rn16rm0_wflags(insn, asi); | |
| 1071 | + | |
| 1072 | + /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */ | |
| 1073 | + /* SMC : cccc 0001 0110 xxxx xxxx xxxx 0111 xxxx */ | |
| 1074 | + | |
| 1075 | + /* Other instruction encodings aren't yet defined */ | |
| 1076 | + return INSN_REJECTED; | |
| 1063 | 1077 | } |
| 1064 | 1078 | |
| 1065 | 1079 | /* cccc 0000 xxxx xxxx xxxx xxxx xxxx 1001 xxxx */ |
| 1066 | − else if ((insn & 0x0f000090) == 0x00000090) { | |
| 1080 | + else if ((insn & 0x0f0000f0) == 0x00000090) { | |
| 1067 | 1081 | |
| 1068 | 1082 | /* MUL : cccc 0000 0000 xxxx xxxx xxxx 1001 xxxx : */ |
| 1069 | 1083 | /* MULS : cccc 0000 0001 xxxx xxxx xxxx 1001 xxxx :cc */ |
| 1070 | 1084 | /* MLA : cccc 0000 0010 xxxx xxxx xxxx 1001 xxxx : */ |
| 1071 | 1085 | /* MLAS : cccc 0000 0011 xxxx xxxx xxxx 1001 xxxx :cc */ |
| 1072 | 1086 | /* UMAAL : cccc 0000 0100 xxxx xxxx xxxx 1001 xxxx : */ |
| 1087 | + /* undef : cccc 0000 0101 xxxx xxxx xxxx 1001 xxxx : */ | |
| 1088 | + /* MLS : cccc 0000 0110 xxxx xxxx xxxx 1001 xxxx : */ | |
| 1089 | + /* undef : cccc 0000 0111 xxxx xxxx xxxx 1001 xxxx : */ | |
| 1073 | 1090 | /* UMULL : cccc 0000 1000 xxxx xxxx xxxx 1001 xxxx : */ |
| 1074 | 1091 | /* UMULLS : cccc 0000 1001 xxxx xxxx xxxx 1001 xxxx :cc */ |
| 1075 | 1092 | /* UMLAL : cccc 0000 1010 xxxx xxxx xxxx 1001 xxxx : */ |
| @@ -1078,13 +1095,15 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi) · 2 unmodified lines | ||
| 1078 | 1095 | /* SMULLS : cccc 0000 1101 xxxx xxxx xxxx 1001 xxxx :cc */ |
| 1079 | 1096 | /* SMLAL : cccc 0000 1110 xxxx xxxx xxxx 1001 xxxx : */ |
| 1080 | 1097 | /* SMLALS : cccc 0000 1111 xxxx xxxx xxxx 1001 xxxx :cc */ |
| 1081 | − if ((insn & 0x0fe000f0) == 0x00000090) { | |
| 1082 | − return prep_emulate_rd16rs8rm0_wflags(insn, asi); | |
| 1083 | − } else if ((insn & 0x0fe000f0) == 0x00200090) { | |
| 1084 | − return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); | |
| 1085 | − } else { | |
| 1086 | − return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi); | |
| 1087 | − } | |
| 1098 | + if ((insn & 0x00d00000) == 0x00500000) | |
| 1099 | + return INSN_REJECTED; | |
| 1100 | + else if ((insn & 0x00e00000) == 0x00000000) | |
| 1101 | + return prep_emulate_rd16rs8rm0_wflags(insn, asi); | |
| 1102 | + else if ((insn & 0x00a00000) == 0x00200000) | |
| 1103 | + return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); | |
| 1104 | + else | |
| 1105 | + return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, | |
| 1106 | + asi); | |
| 1088 | 1107 | } |
| 1089 | 1108 | |
| 1090 | 1109 | /* cccc 000x xxxx xxxx xxxx xxxx xxxx 1xx1 xxxx */ |
| @@ -1092,23 +1111,45 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi) · 1 unmodified line | ||
| 1092 | 1111 | |
| 1093 | 1112 | /* SWP : cccc 0001 0000 xxxx xxxx xxxx 1001 xxxx */ |
| 1094 | 1113 | /* SWPB : cccc 0001 0100 xxxx xxxx xxxx 1001 xxxx */ |
| 1095 | − /* LDRD : cccc 000x xxx0 xxxx xxxx xxxx 1101 xxxx */ | |
| 1096 | − /* STRD : cccc 000x xxx0 xxxx xxxx xxxx 1111 xxxx */ | |
| 1114 | + /* ??? : cccc 0001 0x01 xxxx xxxx xxxx 1001 xxxx */ | |
| 1115 | + /* ??? : cccc 0001 0x10 xxxx xxxx xxxx 1001 xxxx */ | |
| 1116 | + /* ??? : cccc 0001 0x11 xxxx xxxx xxxx 1001 xxxx */ | |
| 1097 | 1117 | /* STREX : cccc 0001 1000 xxxx xxxx xxxx 1001 xxxx */ |
| 1098 | 1118 | /* LDREX : cccc 0001 1001 xxxx xxxx xxxx 1001 xxxx */ |
| 1119 | + /* STREXD: cccc 0001 1010 xxxx xxxx xxxx 1001 xxxx */ | |
| 1120 | + /* LDREXD: cccc 0001 1011 xxxx xxxx xxxx 1001 xxxx */ | |
| 1121 | + /* STREXB: cccc 0001 1100 xxxx xxxx xxxx 1001 xxxx */ | |
| 1122 | + /* LDREXB: cccc 0001 1101 xxxx xxxx xxxx 1001 xxxx */ | |
| 1123 | + /* STREXH: cccc 0001 1110 xxxx xxxx xxxx 1001 xxxx */ | |
| 1124 | + /* LDREXH: cccc 0001 1111 xxxx xxxx xxxx 1001 xxxx */ | |
| 1125 | + | |
| 1126 | + /* LDRD : cccc 000x xxx0 xxxx xxxx xxxx 1101 xxxx */ | |
| 1127 | + /* STRD : cccc 000x xxx0 xxxx xxxx xxxx 1111 xxxx */ | |
| 1099 | 1128 | /* LDRH : cccc 000x xxx1 xxxx xxxx xxxx 1011 xxxx */ |
| 1100 | 1129 | /* STRH : cccc 000x xxx0 xxxx xxxx xxxx 1011 xxxx */ |
| 1101 | 1130 | /* LDRSB : cccc 000x xxx1 xxxx xxxx xxxx 1101 xxxx */ |
| 1102 | 1131 | /* LDRSH : cccc 000x xxx1 xxxx xxxx xxxx 1111 xxxx */ |
| 1103 | − if ((insn & 0x0fb000f0) == 0x01000090) { | |
| 1104 | − /* SWP/SWPB */ | |
| 1105 | − return prep_emulate_rd12rn16rm0_wflags(insn, asi); | |
| 1132 | + if ((insn & 0x0f0000f0) == 0x01000090) { | |
| 1133 | + if ((insn & 0x0fb000f0) == 0x01000090) { | |
| 1134 | + /* SWP/SWPB */ | |
| 1135 | + return prep_emulate_rd12rn16rm0_wflags(insn, | |
| 1136 | + asi); | |
| 1137 | + } else { | |
| 1138 | + /* STREX/LDREX variants and unallocaed space */ | |
| 1139 | + return INSN_REJECTED; | |
| 1140 | + } | |
| 1141 | + | |
| 1106 | 1142 | } else if ((insn & 0x0e1000d0) == 0x00000d0) { |
| 1107 | 1143 | /* STRD/LDRD */ |
| 1144 | + if ((insn & 0x0000e000) == 0x0000e000) | |
| 1145 | + return INSN_REJECTED; /* Rd is LR or PC */ | |
| 1146 | + if (is_writeback(insn) && is_r15(insn, 16)) | |
| 1147 | + return INSN_REJECTED; /* Writeback to PC */ | |
| 1148 | + | |
| 1108 | 1149 | insn &= 0xfff00fff; |
| 1109 | 1150 | insn |= 0x00002000; /* Rn = r0, Rd = r2 */ |
| 1110 | − if (insn & (1 << 22)) { | |
| 1111 | − /* I bit */ | |
| 1151 | + if (!(insn & (1 << 22))) { | |
| 1152 | + /* Register index */ | |
| 1112 | 1153 | insn &= ~0xf; |
| 1113 | 1154 | insn |= 1; /* Rm = r1 */ |
| 1114 | 1155 | } |
| @@ -1118,6 +1159,9 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi) · 3 unmodified lines | ||
| 1118 | 1159 | return INSN_GOOD; |
| 1119 | 1160 | } |
| 1120 | 1161 | |
| 1162 | + /* LDRH/STRH/LDRSB/LDRSH */ | |
| 1163 | + if (is_r15(insn, 12)) | |
| 1164 | + return INSN_REJECTED; /* Rd is PC */ | |
| 1121 | 1165 | return prep_emulate_ldr_str(insn, asi); |
| 1122 | 1166 | } |
| 1123 | 1167 | |
| @@ -1125,7 +1169,7 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi) · 1 unmodified line | ||
| 1125 | 1169 | |
| 1126 | 1170 | /* |
| 1127 | 1171 | * ALU op with S bit and Rd == 15 : |
| 1128 | − * cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx | |
| 1172 | + * cccc 000x xxx1 xxxx 1111 xxxx xxxx xxxx | |
| 1129 | 1173 | */ |
| 1130 | 1174 | if ((insn & 0x0e10f000) == 0x0010f000) |
| 1131 | 1175 | return INSN_REJECTED; |
| @@ -1154,22 +1198,61 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi) · 22 unmodified lines | ||
| 1154 | 1198 | insn |= 0x00000200; /* Rs = r2 */ |
| 1155 | 1199 | } |
| 1156 | 1200 | asi->insn[0] = insn; |
| 1157 | − asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */ | |
| 1201 | + | |
| 1202 | + if ((insn & 0x0f900000) == 0x01100000) { | |
| 1203 | + /* | |
| 1204 | + * TST : cccc 0001 0001 xxxx xxxx xxxx xxxx xxxx | |
| 1205 | + * TEQ : cccc 0001 0011 xxxx xxxx xxxx xxxx xxxx | |
| 1206 | + * CMP : cccc 0001 0101 xxxx xxxx xxxx xxxx xxxx | |
| 1207 | + * CMN : cccc 0001 0111 xxxx xxxx xxxx xxxx xxxx | |
| 1208 | + */ | |
| 1209 | + asi->insn_handler = emulate_alu_tests; | |
| 1210 | + } else { | |
| 1211 | + /* ALU ops which write to Rd */ | |
| 1212 | + asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */ | |
| 1158 | 1213 | emulate_alu_rwflags : emulate_alu_rflags; |
| 1214 | + } | |
| 1159 | 1215 | return INSN_GOOD; |
| 1160 | 1216 | } |
| 1161 | 1217 | |
| 1162 | 1218 | static enum kprobe_insn __kprobes |
| 1163 | 1219 | space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi) |
| 1164 | 1220 | { |
| 1221 | + /* MOVW : cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */ | |
| 1222 | + /* MOVT : cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */ | |
| 1223 | + if ((insn & 0x0fb00000) == 0x03000000) | |
| 1224 | + return prep_emulate_rd12_modify(insn, asi); | |
| 1225 | + | |
| 1226 | + /* hints : cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */ | |
| 1227 | + if ((insn & 0x0fff0000) == 0x03200000) { | |
| 1228 | + unsigned op2 = insn & 0x000000ff; | |
| 1229 | + if (op2 == 0x01 || op2 == 0x04) { | |
| 1230 | + /* YIELD : cccc 0011 0010 0000 xxxx xxxx 0000 0001 */ | |
| 1231 | + /* SEV : cccc 0011 0010 0000 xxxx xxxx 0000 0100 */ | |
| 1232 | + asi->insn[0] = insn; | |
| 1233 | + asi->insn_handler = emulate_none; | |
| 1234 | + return INSN_GOOD; | |
| 1235 | + } else if (op2 <= 0x03) { | |
| 1236 | + /* NOP : cccc 0011 0010 0000 xxxx xxxx 0000 0000 */ | |
| 1237 | + /* WFE : cccc 0011 0010 0000 xxxx xxxx 0000 0010 */ | |
| 1238 | + /* WFI : cccc 0011 0010 0000 xxxx xxxx 0000 0011 */ | |
| 1239 | + /* | |
| 1240 | + * We make WFE and WFI true NOPs to avoid stalls due | |
| 1241 | + * to missing events whilst processing the probe. | |
| 1242 | + */ | |
| 1243 | + asi->insn_handler = emulate_nop; | |
| 1244 | + return INSN_GOOD_NO_SLOT; | |
| 1245 | + } | |
| 1246 | + /* For DBG and unallocated hints it's safest to reject them */ | |
| 1247 | + return INSN_REJECTED; | |
| 1248 | + } | |
| 1249 | + | |
| 1165 | 1250 | /* |
| 1166 | 1251 | * MSR : cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx |
| 1167 | − * Undef : cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx | |
| 1168 | 1252 | * ALU op with S bit and Rd == 15 : |
| 1169 | 1253 | * cccc 001x xxx1 xxxx 1111 xxxx xxxx xxxx |
| 1170 | 1254 | */ |
| 1171 | 1255 | if ((insn & 0x0fb00000) == 0x03200000 || /* MSR */ |
| 1172 | − (insn & 0x0ff00000) == 0x03400000 || /* Undef */ | |
| 1173 | 1256 | (insn & 0x0e10f000) == 0x0210f000) /* ALU s-bit, R15 */ |
| 1174 | 1257 | return INSN_REJECTED; |
| 1175 | 1258 | |
| @@ -1180,10 +1263,22 @@ space_cccc_001x(kprobe_opcode_t insn, struct arch_specific_insn *asi) · 4 unmodified lines | ||
| 1180 | 1263 | * *S (bit 20) updates condition codes |
| 1181 | 1264 | * ADC/SBC/RSC reads the C flag |
| 1182 | 1265 | */ |
| 1183 | − insn &= 0xffff0fff; /* Rd = r0 */ | |
| 1266 | + insn &= 0xfff00fff; /* Rn = r0 and Rd = r0 */ | |
| 1184 | 1267 | asi->insn[0] = insn; |
| 1185 | − asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */ | |
| 1268 | + | |
| 1269 | + if ((insn & 0x0f900000) == 0x03100000) { | |
| 1270 | + /* | |
| 1271 | + * TST : cccc 0011 0001 xxxx xxxx xxxx xxxx xxxx | |
| 1272 | + * TEQ : cccc 0011 0011 xxxx xxxx xxxx xxxx xxxx | |
| 1273 | + * CMP : cccc 0011 0101 xxxx xxxx xxxx xxxx xxxx | |
| 1274 | + * CMN : cccc 0011 0111 xxxx xxxx xxxx xxxx xxxx | |
| 1275 | + */ | |
| 1276 | + asi->insn_handler = emulate_alu_tests_imm; | |
| 1277 | + } else { | |
| 1278 | + /* ALU ops which write to Rd */ | |
| 1279 | + asi->insn_handler = (insn & (1 << 20)) ? /* S-bit */ | |
| 1186 | 1280 | emulate_alu_imm_rwflags : emulate_alu_imm_rflags; |
| 1281 | + } | |
| 1187 | 1282 | return INSN_GOOD; |
| 1188 | 1283 | } |
| 1189 | 1284 | |
| @@ -1192,6 +1287,8 @@ space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi) · 2 unmodified lines | ||
| 1192 | 1287 | { |
| 1193 | 1288 | /* SEL : cccc 0110 1000 xxxx xxxx xxxx 1011 xxxx GE: !!! */ |
| 1194 | 1289 | if ((insn & 0x0ff000f0) == 0x068000b0) { |
| 1290 | + if (is_r15(insn, 12)) | |
| 1291 | + return INSN_REJECTED; /* Rd is PC */ | |
| 1195 | 1292 | insn &= 0xfff00ff0; /* Rd = r0, Rn = r0 */ |
| 1196 | 1293 | insn |= 0x00000001; /* Rm = r1 */ |
| 1197 | 1294 | asi->insn[0] = insn; |
| @@ -1205,6 +1302,8 @@ space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi) · 7 unmodified lines | ||
| 1205 | 1302 | /* USAT16 : cccc 0110 1110 xxxx xxxx xxxx 0011 xxxx :Q */ |
| 1206 | 1303 | if ((insn & 0x0fa00030) == 0x06a00010 || |
| 1207 | 1304 | (insn & 0x0fb000f0) == 0x06a00030) { |
| 1305 | + if (is_r15(insn, 12)) | |
| 1306 | + return INSN_REJECTED; /* Rd is PC */ | |
| 1208 | 1307 | insn &= 0xffff0ff0; /* Rd = r0, Rm = r0 */ |
| 1209 | 1308 | asi->insn[0] = insn; |
| 1210 | 1309 | asi->insn_handler = emulate_sat; |
| @@ -1213,57 +1312,101 @@ space_cccc_0110__1(kprobe_opcode_t insn, struct arch_specific_insn *asi) · 2 unmodified lines | ||
| 1213 | 1312 | |
| 1214 | 1313 | /* REV : cccc 0110 1011 xxxx xxxx xxxx 0011 xxxx */ |
| 1215 | 1314 | /* REV16 : cccc 0110 1011 xxxx xxxx xxxx 1011 xxxx */ |
| 1315 | + /* RBIT : cccc 0110 1111 xxxx xxxx xxxx 0011 xxxx */ | |
| 1216 | 1316 | /* REVSH : cccc 0110 1111 xxxx xxxx xxxx 1011 xxxx */ |
| 1217 | 1317 | if ((insn & 0x0ff00070) == 0x06b00030 || |
| 1218 | − (insn & 0x0ff000f0) == 0x06f000b0) | |
| 1318 | + (insn & 0x0ff00070) == 0x06f00030) | |
| 1219 | 1319 | return prep_emulate_rd12rm0(insn, asi); |
| 1220 | 1320 | |
| 1321 | + /* ??? : cccc 0110 0000 xxxx xxxx xxxx xxx1 xxxx : */ | |
| 1221 | 1322 | /* SADD16 : cccc 0110 0001 xxxx xxxx xxxx 0001 xxxx :GE */ |
| 1222 | 1323 | /* SADDSUBX : cccc 0110 0001 xxxx xxxx xxxx 0011 xxxx :GE */ |
| 1223 | 1324 | /* SSUBADDX : cccc 0110 0001 xxxx xxxx xxxx 0101 xxxx :GE */ |
| 1224 | 1325 | /* SSUB16 : cccc 0110 0001 xxxx xxxx xxxx 0111 xxxx :GE */ |
| 1225 | 1326 | /* SADD8 : cccc 0110 0001 xxxx xxxx xxxx 1001 xxxx :GE */ |
| 1327 | + /* ??? : cccc 0110 0001 xxxx xxxx xxxx 1011 xxxx : */ | |
| 1328 | + /* ??? : cccc 0110 0001 xxxx xxxx xxxx 1101 xxxx : */ | |
| 1226 | 1329 | /* SSUB8 : cccc 0110 0001 xxxx xxxx xxxx 1111 xxxx :GE */ |
| 1227 | 1330 | /* QADD16 : cccc 0110 0010 xxxx xxxx xxxx 0001 xxxx : */ |
| 1228 | 1331 | /* QADDSUBX : cccc 0110 0010 xxxx xxxx xxxx 0011 xxxx : */ |
| 1229 | 1332 | /* QSUBADDX : cccc 0110 0010 xxxx xxxx xxxx 0101 xxxx : */ |
| 1230 | 1333 | /* QSUB16 : cccc 0110 0010 xxxx xxxx xxxx 0111 xxxx : */ |
| 1231 | 1334 | /* QADD8 : cccc 0110 0010 xxxx xxxx xxxx 1001 xxxx : */ |
| 1335 | + /* ??? : cccc 0110 0010 xxxx xxxx xxxx 1011 xxxx : */ | |
| 1336 | + /* ??? : cccc 0110 0010 xxxx xxxx xxxx 1101 xxxx : */ | |
| 1232 | 1337 | /* QSUB8 : cccc 0110 0010 xxxx xxxx xxxx 1111 xxxx : */ |
| 1233 | 1338 | /* SHADD16 : cccc 0110 0011 xxxx xxxx xxxx 0001 xxxx : */ |
| 1234 | 1339 | /* SHADDSUBX : cccc 0110 0011 xxxx xxxx xxxx 0011 xxxx : */ |
| 1235 | 1340 | /* SHSUBADDX : cccc 0110 0011 xxxx xxxx xxxx 0101 xxxx : */ |
| 1236 | 1341 | /* SHSUB16 : cccc 0110 0011 xxxx xxxx xxxx 0111 xxxx : */ |
| 1237 | 1342 | /* SHADD8 : cccc 0110 0011 xxxx xxxx xxxx 1001 xxxx : */ |
| 1343 | + /* ??? : cccc 0110 0011 xxxx xxxx xxxx 1011 xxxx : */ | |
| 1344 | + /* ??? : cccc 0110 0011 xxxx xxxx xxxx 1101 xxxx : */ | |
| 1238 | 1345 | /* SHSUB8 : cccc 0110 0011 xxxx xxxx xxxx 1111 xxxx : */ |
| 1346 | + /* ??? : cccc 0110 0100 xxxx xxxx xxxx xxx1 xxxx : */ | |
| 1239 | 1347 | /* UADD16 : cccc 0110 0101 xxxx xxxx xxxx 0001 xxxx :GE */ |
| 1240 | 1348 | /* UADDSUBX : cccc 0110 0101 xxxx xxxx xxxx 0011 xxxx :GE */ |
| 1241 | 1349 | /* USUBADDX : cccc 0110 0101 xxxx xxxx xxxx 0101 xxxx :GE */ |
| 1242 | 1350 | /* USUB16 : cccc 0110 0101 xxxx xxxx xxxx 0111 xxxx :GE */ |
| 1243 | 1351 | /* UADD8 : cccc 0110 0101 xxxx xxxx xxxx 1001 xxxx :GE */ |
| 1352 | + /* ??? : cccc 0110 0101 xxxx xxxx xxxx 1011 xxxx : */ | |
| 1353 | + /* ??? : cccc 0110 0101 xxxx xxxx xxxx 1101 xxxx : */ | |
| 1244 | 1354 | /* USUB8 : cccc 0110 0101 xxxx xxxx xxxx 1111 xxxx :GE */ |
| 1245 | 1355 | /* UQADD16 : cccc 0110 0110 xxxx xxxx xxxx 0001 xxxx : */ |
| 1246 | 1356 | /* UQADDSUBX : cccc 0110 0110 xxxx xxxx xxxx 0011 xxxx : */ |
| 1247 | 1357 | /* UQSUBADDX : cccc 0110 0110 xxxx xxxx xxxx 0101 xxxx : */ |
| 1248 | 1358 | /* UQSUB16 : cccc 0110 0110 xxxx xxxx xxxx 0111 xxxx : */ |
| 1249 | 1359 | /* UQADD8 : cccc 0110 0110 xxxx xxxx xxxx 1001 xxxx : */ |
| 1360 | + /* ??? : cccc 0110 0110 xxxx xxxx xxxx 1011 xxxx : */ | |
| 1361 | + /* ??? : cccc 0110 0110 xxxx xxxx xxxx 1101 xxxx : */ | |
| 1250 | 1362 | /* UQSUB8 : cccc 0110 0110 xxxx xxxx xxxx 1111 xxxx : */ |
| 1251 | 1363 | /* UHADD16 : cccc 0110 0111 xxxx xxxx xxxx 0001 xxxx : */ |
| 1252 | 1364 | /* UHADDSUBX : cccc 0110 0111 xxxx xxxx xxxx 0011 xxxx : */ |
| 1253 | 1365 | /* UHSUBADDX : cccc 0110 0111 xxxx xxxx xxxx 0101 xxxx : */ |
| 1254 | 1366 | /* UHSUB16 : cccc 0110 0111 xxxx xxxx xxxx 0111 xxxx : */ |
| 1255 | 1367 | /* UHADD8 : cccc 0110 0111 xxxx xxxx xxxx 1001 xxxx : */ |
| 1368 | + /* ??? : cccc 0110 0111 xxxx xxxx xxxx 1011 xxxx : */ | |
| 1369 | + /* ??? : cccc 0110 0111 xxxx xxxx xxxx 1101 xxxx : */ | |
| 1256 | 1370 | /* UHSUB8 : cccc 0110 0111 xxxx xxxx xxxx 1111 xxxx : */ |
| 1371 | + if ((insn & 0x0f800010) == 0x06000010) { | |
| 1372 | + if ((insn & 0x00300000) == 0x00000000 || | |
| 1373 | + (insn & 0x000000e0) == 0x000000a0 || | |
| 1374 | + (insn & 0x000000e0) == 0x000000c0) | |
| 1375 | + return INSN_REJECTED; /* Unallocated space */ | |
| 1376 | + return prep_emulate_rd12rn16rm0_wflags(insn, asi); | |
| 1377 | + } | |
| 1378 | + | |
| 1257 | 1379 | /* PKHBT : cccc 0110 1000 xxxx xxxx xxxx x001 xxxx : */ |
| 1258 | 1380 | /* PKHTB : cccc 0110 1000 xxxx xxxx xxxx x101 xxxx : */ |
| 1381 | + if ((insn & 0x0ff00030) == 0x06800010) | |
| 1382 | + return prep_emulate_rd12rn16rm0_wflags(insn, asi); | |
| 1383 | + | |
| 1259 | 1384 | /* SXTAB16 : cccc 0110 1000 xxxx xxxx xxxx 0111 xxxx : */ |
| 1260 | − /* SXTB : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx : */ | |
| 1385 | + /* SXTB16 : cccc 0110 1000 1111 xxxx xxxx 0111 xxxx : */ | |
| 1386 | + /* ??? : cccc 0110 1001 xxxx xxxx xxxx 0111 xxxx : */ | |
| 1261 | 1387 | /* SXTAB : cccc 0110 1010 xxxx xxxx xxxx 0111 xxxx : */ |
| 1388 | + /* SXTB : cccc 0110 1010 1111 xxxx xxxx 0111 xxxx : */ | |
| 1262 | 1389 | /* SXTAH : cccc 0110 1011 xxxx xxxx xxxx 0111 xxxx : */ |
| 1390 | + /* SXTH : cccc 0110 1011 1111 xxxx xxxx 0111 xxxx : */ | |
| 1263 | 1391 | /* UXTAB16 : cccc 0110 1100 xxxx xxxx xxxx 0111 xxxx : */ |
| 1392 | + /* UXTB16 : cccc 0110 1100 1111 xxxx xxxx 0111 xxxx : */ | |
| 1393 | + /* ??? : cccc 0110 1101 xxxx xxxx xxxx 0111 xxxx : */ | |
| 1264 | 1394 | /* UXTAB : cccc 0110 1110 xxxx xxxx xxxx 0111 xxxx : */ |
| 1395 | + /* UXTB : cccc 0110 1110 1111 xxxx xxxx 0111 xxxx : */ | |
| 1265 | 1396 | /* UXTAH : cccc 0110 1111 xxxx xxxx xxxx 0111 xxxx : */ |
| 1266 | − return prep_emulate_rd12rn16rm0_wflags(insn, asi); | |
| 1397 | + /* UXTH : cccc 0110 1111 1111 xxxx xxxx 0111 xxxx : */ | |
| 1398 | + if ((insn & 0x0f8000f0) == 0x06800070) { | |
| 1399 | + if ((insn & 0x00300000) == 0x00100000) | |
| 1400 | + return INSN_REJECTED; /* Unallocated space */ | |
| 1401 | + | |
| 1402 | + if ((insn & 0x000f0000) == 0x000f0000) | |
| 1403 | + return prep_emulate_rd12rm0(insn, asi); | |
| 1404 | + else | |
| 1405 | + return prep_emulate_rd12rn16rm0_wflags(insn, asi); | |
| 1406 | + } | |
| 1407 | + | |
| 1408 | + /* Other instruction encodings aren't yet defined */ | |
| 1409 | + return INSN_REJECTED; | |
| 1267 | 1410 | } |
| 1268 | 1411 | |
| 1269 | 1412 | static enum kprobe_insn __kprobes |
| @@ -1273,29 +1416,49 @@ space_cccc_0111__1(kprobe_opcode_t insn, struct arch_specific_insn *asi) · 3 unmodified lines | ||
| 1273 | 1416 | if ((insn & 0x0ff000f0) == 0x03f000f0) |
| 1274 | 1417 | return INSN_REJECTED; |
| 1275 | 1418 | |
| 1276 | − /* USADA8 : cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx */ | |
| 1277 | − /* USAD8 : cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx */ | |
| 1278 | − if ((insn & 0x0ff000f0) == 0x07800010) | |
| 1279 | − return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); | |
| 1280 | − | |
| 1281 | 1419 | /* SMLALD : cccc 0111 0100 xxxx xxxx xxxx 00x1 xxxx */ |
| 1282 | 1420 | /* SMLSLD : cccc 0111 0100 xxxx xxxx xxxx 01x1 xxxx */ |
| 1283 | 1421 | if ((insn & 0x0ff00090) == 0x07400010) |
| 1284 | 1422 | return prep_emulate_rdhi16rdlo12rs8rm0_wflags(insn, asi); |
| 1285 | 1423 | |
| 1286 | 1424 | /* SMLAD : cccc 0111 0000 xxxx xxxx xxxx 00x1 xxxx :Q */ |
| 1425 | + /* SMUAD : cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx :Q */ | |
| 1287 | 1426 | /* SMLSD : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx :Q */ |
| 1427 | + /* SMUSD : cccc 0111 0000 xxxx 1111 xxxx 01x1 xxxx : */ | |
| 1288 | 1428 | /* SMMLA : cccc 0111 0101 xxxx xxxx xxxx 00x1 xxxx : */ |
| 1289 | − /* SMMLS : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx : */ | |
| 1429 | + /* SMMUL : cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx : */ | |
| 1430 | + /* USADA8 : cccc 0111 1000 xxxx xxxx xxxx 0001 xxxx : */ | |
| 1431 | + /* USAD8 : cccc 0111 1000 xxxx 1111 xxxx 0001 xxxx : */ | |
| 1290 | 1432 | if ((insn & 0x0ff00090) == 0x07000010 || |
| 1291 | 1433 | (insn & 0x0ff000d0) == 0x07500010 || |
| 1292 | − (insn & 0x0ff000d0) == 0x075000d0) | |
| 1434 | + (insn & 0x0ff000f0) == 0x07800010) { | |
| 1435 | + | |
| 1436 | + if ((insn & 0x0000f000) == 0x0000f000) | |
| 1437 | + return prep_emulate_rd16rs8rm0_wflags(insn, asi); | |
| 1438 | + else | |
| 1439 | + return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); | |
| 1440 | + } | |
| 1441 | + | |
| 1442 | + /* SMMLS : cccc 0111 0101 xxxx xxxx xxxx 11x1 xxxx : */ | |
| 1443 | + if ((insn & 0x0ff000d0) == 0x075000d0) | |
| 1293 | 1444 | return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); |
| 1294 | 1445 | |
| 1295 | − /* SMUSD : cccc 0111 0000 xxxx xxxx xxxx 01x1 xxxx : */ | |
| 1296 | − /* SMUAD : cccc 0111 0000 xxxx 1111 xxxx 00x1 xxxx :Q */ | |
| 1297 | − /* SMMUL : cccc 0111 0101 xxxx 1111 xxxx 00x1 xxxx : */ | |
| 1298 | − return prep_emulate_rd16rs8rm0_wflags(insn, asi); | |
| 1446 | + /* SBFX : cccc 0111 101x xxxx xxxx xxxx x101 xxxx : */ | |
| 1447 | + /* UBFX : cccc 0111 111x xxxx xxxx xxxx x101 xxxx : */ | |
| 1448 | + if ((insn & 0x0fa00070) == 0x07a00050) | |
| 1449 | + return prep_emulate_rd12rm0(insn, asi); | |
| 1450 | + | |
| 1451 | + /* BFI : cccc 0111 110x xxxx xxxx xxxx x001 xxxx : */ | |
| 1452 | + /* BFC : cccc 0111 110x xxxx xxxx xxxx x001 1111 : */ | |
| 1453 | + if ((insn & 0x0fe00070) == 0x07c00010) { | |
| 1454 | + | |
| 1455 | + if ((insn & 0x0000000f) == 0x0000000f) | |
| 1456 | + return prep_emulate_rd12_modify(insn, asi); | |
| 1457 | + else | |
| 1458 | + return prep_emulate_rd12rn0_modify(insn, asi); | |
| 1459 | + } | |
| 1460 | + | |
| 1461 | + return INSN_REJECTED; | |
| 1299 | 1462 | } |
| 1300 | 1463 | |
| 1301 | 1464 | static enum kprobe_insn __kprobes |
| @@ -1309,6 +1472,10 @@ space_cccc_01xx(kprobe_opcode_t insn, struct arch_specific_insn *asi) · 7 unmodified lines | ||
| 1309 | 1472 | /* STRB : cccc 01xx x1x0 xxxx xxxx xxxx xxxx xxxx */ |
| 1310 | 1473 | /* STRBT : cccc 01x0 x110 xxxx xxxx xxxx xxxx xxxx */ |
| 1311 | 1474 | /* STRT : cccc 01x0 x010 xxxx xxxx xxxx xxxx xxxx */ |
| 1475 | + | |
| 1476 | + if ((insn & 0x00500000) == 0x00500000 && is_r15(insn, 12)) | |
| 1477 | + return INSN_REJECTED; /* LDRB into PC */ | |
| 1478 | + | |
| 1312 | 1479 | return prep_emulate_ldr_str(insn, asi); |
| 1313 | 1480 | } |
| 1314 | 1481 | |
| @@ -1323,10 +1490,9 @@ space_cccc_100x(kprobe_opcode_t insn, struct arch_specific_insn *asi) · 8 unmodified lines | ||
| 1323 | 1490 | |
| 1324 | 1491 | /* LDM(1) : cccc 100x x0x1 xxxx xxxx xxxx xxxx xxxx */ |
| 1325 | 1492 | /* STM(1) : cccc 100x x0x0 xxxx xxxx xxxx xxxx xxxx */ |
| 1326 | − asi->insn[0] = truecc_insn(insn); | |
| 1327 | 1493 | asi->insn_handler = ((insn & 0x108000) == 0x008000) ? /* STM & R15 */ |
| 1328 | 1494 | simulate_stm1_pc : simulate_ldm1stm1; |
| 1329 | − return INSN_GOOD; | |
| 1495 | + return INSN_GOOD_NO_SLOT; | |
| 1330 | 1496 | } |
| 1331 | 1497 | |
| 1332 | 1498 | static enum kprobe_insn __kprobes |
| @@ -1334,58 +1500,117 @@ space_cccc_101x(kprobe_opcode_t insn, struct arch_specific_insn *asi) · 1 unmodified line | ||
| 1334 | 1500 | { |
| 1335 | 1501 | /* B : cccc 1010 xxxx xxxx xxxx xxxx xxxx xxxx */ |
| 1336 | 1502 | /* BL : cccc 1011 xxxx xxxx xxxx xxxx xxxx xxxx */ |
| 1337 | − asi->insn[0] = truecc_insn(insn); | |
| 1338 | 1503 | asi->insn_handler = simulate_bbl; |
| 1339 | − return INSN_GOOD; | |
| 1504 | + return INSN_GOOD_NO_SLOT; | |
| 1340 | 1505 | } |
| 1341 | 1506 | |
| 1342 | 1507 | static enum kprobe_insn __kprobes |
| 1343 | −space_cccc_1100_010x(kprobe_opcode_t insn, struct arch_specific_insn *asi) | |
| 1508 | +space_cccc_11xx(kprobe_opcode_t insn, struct arch_specific_insn *asi) | |
| 1344 | 1509 | { |
| 1510 | + /* Coprocessor instructions... */ | |
| 1345 | 1511 | /* MCRR : cccc 1100 0100 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */ |
| 1346 | 1512 | /* MRRC : cccc 1100 0101 xxxx xxxx xxxx xxxx xxxx : (Rd!=Rn) */ |
| 1347 | − insn &= 0xfff00fff; | |
| 1348 | − insn |= 0x00001000; /* Rn = r0, Rd = r1 */ | |
| 1349 | − asi->insn[0] = insn; | |
| 1350 | − asi->insn_handler = (insn & (1 << 20)) ? emulate_mrrc : emulate_mcrr; | |
| 1351 | − return INSN_GOOD; | |
| 1513 | + /* LDC : cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ | |
| 1514 | + /* STC : cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */ | |
| 1515 | + /* CDP : cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ | |
| 1516 | + /* MCR : cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ | |
| 1517 | + /* MRC : cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ | |
| 1518 | + | |
| 1519 | + /* SVC : cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */ | |
| 1520 | + | |
| 1521 | + return INSN_REJECTED; | |
| 1352 | 1522 | } |
| 1353 | 1523 | |
| 1354 | −static enum kprobe_insn __kprobes | |
| 1355 | −space_cccc_110x(kprobe_opcode_t insn, struct arch_specific_insn *asi) | |
| 1524 | +static unsigned long __kprobes __check_eq(unsigned long cpsr) | |
| 1356 | 1525 | { |
| 1357 | − /* LDC : cccc 110x xxx1 xxxx xxxx xxxx xxxx xxxx */ | |
| 1358 | − /* STC : cccc 110x xxx0 xxxx xxxx xxxx xxxx xxxx */ | |
| 1359 | − insn &= 0xfff0ffff; /* Rn = r0 */ | |
| 1360 | − asi->insn[0] = insn; | |
| 1361 | − asi->insn_handler = emulate_ldcstc; | |
| 1362 | − return INSN_GOOD; | |
| 1526 | + return cpsr & PSR_Z_BIT; | |
| 1363 | 1527 | } |
| 1364 | 1528 | |
| 1365 | −static enum kprobe_insn __kprobes | |
| 1366 | −space_cccc_111x(kprobe_opcode_t insn, struct arch_specific_insn *asi) | |
| 1529 | +static unsigned long __kprobes __check_ne(unsigned long cpsr) | |
| 1367 | 1530 | { |
| 1368 | − /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */ | |
| 1369 | − /* SWI : cccc 1111 xxxx xxxx xxxx xxxx xxxx xxxx */ | |
| 1370 | − if ((insn & 0xfff000f0) == 0xe1200070 || | |
| 1371 | − (insn & 0x0f000000) == 0x0f000000) | |
| 1372 | − return INSN_REJECTED; | |
| 1531 | + return (~cpsr) & PSR_Z_BIT; | |
| 1532 | +} | |
| 1373 | 1533 | |
| 1374 | − /* CDP : cccc 1110 xxxx xxxx xxxx xxxx xxx0 xxxx */ | |
| 1375 | − if ((insn & 0x0f000010) == 0x0e000000) { | |
| 1376 | − asi->insn[0] = insn; | |
| 1377 | − asi->insn_handler = emulate_none; | |
| 1378 | − return INSN_GOOD; | |
| 1379 | − } | |
| 1534 | +static unsigned long __kprobes __check_cs(unsigned long cpsr) | |
| 1535 | +{ | |
| 1536 | + return cpsr & PSR_C_BIT; | |
| 1537 | +} | |
| 1380 | 1538 | |
| 1381 | − /* MCR : cccc 1110 xxx0 xxxx xxxx xxxx xxx1 xxxx */ | |
| 1382 | − /* MRC : cccc 1110 xxx1 xxxx xxxx xxxx xxx1 xxxx */ | |
| 1383 | − insn &= 0xffff0fff; /* Rd = r0 */ | |
| 1384 | − asi->insn[0] = insn; | |
| 1385 | − asi->insn_handler = (insn & (1 << 20)) ? emulate_rd12 : emulate_ird12; | |
| 1386 | − return INSN_GOOD; | |
| 1539 | +static unsigned long __kprobes __check_cc(unsigned long cpsr) | |
| 1540 | +{ | |
| 1541 | + return (~cpsr) & PSR_C_BIT; | |
| 1542 | +} | |
| 1543 | + | |
| 1544 | +static unsigned long __kprobes __check_mi(unsigned long cpsr) | |
| 1545 | +{ | |
| 1546 | + return cpsr & PSR_N_BIT; | |
| 1547 | +} | |
| 1548 | + | |
| 1549 | +static unsigned long __kprobes __check_pl(unsigned long cpsr) | |
| 1550 | +{ | |
| 1551 | + return (~cpsr) & PSR_N_BIT; | |
| 1552 | +} | |
| 1553 | + | |
| 1554 | +static unsigned long __kprobes __check_vs(unsigned long cpsr) | |
| 1555 | +{ | |
| 1556 | + return cpsr & PSR_V_BIT; | |
| 1557 | +} | |
| 1558 | + | |
| 1559 | +static unsigned long __kprobes __check_vc(unsigned long cpsr) | |
| 1560 | +{ | |
| 1561 | + return (~cpsr) & PSR_V_BIT; | |
| 1562 | +} | |
| 1563 | + | |
| 1564 | +static unsigned long __kprobes __check_hi(unsigned long cpsr) | |
| 1565 | +{ | |
| 1566 | + cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */ | |
| 1567 | + return cpsr & PSR_C_BIT; | |
| 1387 | 1568 | } |
| 1388 | 1569 | |
| 1570 | +static unsigned long __kprobes __check_ls(unsigned long cpsr) | |
| 1571 | +{ | |
| 1572 | + cpsr &= ~(cpsr >> 1); /* PSR_C_BIT &= ~PSR_Z_BIT */ | |
| 1573 | + return (~cpsr) & PSR_C_BIT; | |
| 1574 | +} | |
| 1575 | + | |
| 1576 | +static unsigned long __kprobes __check_ge(unsigned long cpsr) | |
| 1577 | +{ | |
| 1578 | + cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ | |
| 1579 | + return (~cpsr) & PSR_N_BIT; | |
| 1580 | +} | |
| 1581 | + | |
| 1582 | +static unsigned long __kprobes __check_lt(unsigned long cpsr) | |
| 1583 | +{ | |
| 1584 | + cpsr ^= (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ | |
| 1585 | + return cpsr & PSR_N_BIT; | |
| 1586 | +} | |
| 1587 | + | |
| 1588 | +static unsigned long __kprobes __check_gt(unsigned long cpsr) | |
| 1589 | +{ | |
| 1590 | + unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ | |
| 1591 | + temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */ | |
| 1592 | + return (~temp) & PSR_N_BIT; | |
| 1593 | +} | |
| 1594 | + | |
| 1595 | +static unsigned long __kprobes __check_le(unsigned long cpsr) | |
| 1596 | +{ | |
| 1597 | + unsigned long temp = cpsr ^ (cpsr << 3); /* PSR_N_BIT ^= PSR_V_BIT */ | |
| 1598 | + temp |= (cpsr << 1); /* PSR_N_BIT |= PSR_Z_BIT */ | |
| 1599 | + return temp & PSR_N_BIT; | |
| 1600 | +} | |
| 1601 | + | |
| 1602 | +static unsigned long __kprobes __check_al(unsigned long cpsr) | |
| 1603 | +{ | |
| 1604 | + return true; | |
| 1605 | +} | |
| 1606 | + | |
| 1607 | +static kprobe_check_cc * const condition_checks[16] = { | |
| 1608 | + &__check_eq, &__check_ne, &__check_cs, &__check_cc, | |
| 1609 | + &__check_mi, &__check_pl, &__check_vs, &__check_vc, | |
| 1610 | + &__check_hi, &__check_ls, &__check_ge, &__check_lt, | |
| 1611 | + &__check_gt, &__check_le, &__check_al, &__check_al | |
| 1612 | +}; | |
| 1613 | + | |
| 1389 | 1614 | /* Return: |
| 1390 | 1615 | * INSN_REJECTED If instruction is one not allowed to kprobe, |
| 1391 | 1616 | * INSN_GOOD If instruction is supported and uses instruction slot, |
| @@ -1401,133 +1626,45 @@ space_cccc_111x(kprobe_opcode_t insn, struct arch_specific_insn *asi) · 9 unmodified lines | ||
| 1401 | 1626 | enum kprobe_insn __kprobes |
| 1402 | 1627 | arm_kprobe_decode_insn(kprobe_opcode_t insn, struct arch_specific_insn *asi) |
| 1403 | 1628 | { |
| 1629 | + asi->insn_check_cc = condition_checks[insn>>28]; | |
| 1404 | 1630 | asi->insn[1] = KPROBE_RETURN_INSTRUCTION; |
| 1405 | 1631 | |
| 1406 | − if ((insn & 0xf0000000) == 0xf0000000) { | |
| 1632 | + if ((insn & 0xf0000000) == 0xf0000000) | |
| 1407 | 1633 | |
| 1408 | 1634 | return space_1111(insn, asi); |
| 1409 | 1635 | |
| 1410 | − } else if ((insn & 0x0e000000) == 0x00000000) { | |
| 1636 | + else if ((insn & 0x0e000000) == 0x00000000) | |
| 1411 | 1637 | |
| 1412 | 1638 | return space_cccc_000x(insn, asi); |
| 1413 | 1639 | |
| 1414 | − } else if ((insn & 0x0e000000) == 0x02000000) { | |
| 1640 | + else if ((insn & 0x0e000000) == 0x02000000) | |
| 1415 | 1641 | |
| 1416 | 1642 | return space_cccc_001x(insn, asi); |
| 1417 | 1643 | |
| 1418 | − } else if ((insn & 0x0f000010) == 0x06000010) { | |
| 1644 | + else if ((insn & 0x0f000010) == 0x06000010) | |
| 1419 | 1645 | |
| 1420 | 1646 | return space_cccc_0110__1(insn, asi); |
| 1421 | 1647 | |
| 1422 | − } else if ((insn & 0x0f000010) == 0x07000010) { | |
| 1648 | + else if ((insn & 0x0f000010) == 0x07000010) | |
| 1423 | 1649 | |
| 1424 | 1650 | return space_cccc_0111__1(insn, asi); |
| 1425 | 1651 | |
| 1426 | − } else if ((insn & 0x0c000000) == 0x04000000) { | |
| 1652 | + else if ((insn & 0x0c000000) == 0x04000000) | |
| 1427 | 1653 | |
| 1428 | 1654 | return space_cccc_01xx(insn, asi); |
| 1429 | 1655 | |
| 1430 | − } else if ((insn & 0x0e000000) == 0x08000000) { | |
| 1656 | + else if ((insn & 0x0e000000) == 0x08000000) | |
| 1431 | 1657 | |
| 1432 | 1658 | return space_cccc_100x(insn, asi); |
| 1433 | 1659 | |
| 1434 | − } else if ((insn & 0x0e000000) == 0x0a000000) { | |
| 1660 | + else if ((insn & 0x0e000000) == 0x0a000000) | |
| 1435 | 1661 | |
| 1436 | 1662 | return space_cccc_101x(insn, asi); |
| 1437 | 1663 | |
| 1438 | − } else if ((insn & 0x0fe00000) == 0x0c400000) { | |
| 1439 | − | |
| 1440 | − return space_cccc_1100_010x(insn, asi); | |
| 1441 | − | |
| 1442 | − } else if ((insn & 0x0e000000) == 0x0c000000) { | |
| 1443 | − | |
| 1444 | − return space_cccc_110x(insn, asi); | |
| 1445 | − | |
| 1446 | − } | |
| 1447 | − | |
| 1448 | − return space_cccc_111x(insn, asi); | |
| 1664 | + return space_cccc_11xx(insn, asi); | |
| 1449 | 1665 | } |
| 1450 | 1666 | |
| 1451 | 1667 | void __init arm_kprobe_decode_init(void) |
| 1452 | 1668 | { |
| 1453 | 1669 | find_str_pc_offset(); |
| 1454 | 1670 | } |
| 1455 | − | |
| 1456 | − | |
| 1457 | −/* | |
| 1458 | − * All ARM instructions listed below. | |
| 1459 | − * | |
| 1460 | − * Instructions and their general purpose registers are given. | |
| 1461 | − * If a particular register may not use R15, it is prefixed with a "!". | |
| 1462 | − * If marked with a "*" means the value returned by reading R15 | |
| 1463 | − * is implementation defined. | |
| 1464 | − * | |
| 1465 | − * ADC/ADD/AND/BIC/CMN/CMP/EOR/MOV/MVN/ORR/RSB/RSC/SBC/SUB/TEQ | |
| 1466 | − * TST: Rd, Rn, Rm, !Rs | |
| 1467 | − * BX: Rm | |
| 1468 | − * BLX(2): !Rm | |
| 1469 | − * BX: Rm (R15 legal, but discouraged) | |
| 1470 | − * BXJ: !Rm, | |
| 1471 | − * CLZ: !Rd, !Rm | |
| 1472 | − * CPY: Rd, Rm | |
| 1473 | − * LDC/2,STC/2 immediate offset & unindex: Rn | |
| 1474 | − * LDC/2,STC/2 immediate pre/post-indexed: !Rn | |
| 1475 | − * LDM(1/3): !Rn, register_list | |
| 1476 | − * LDM(2): !Rn, !register_list | |
| 1477 | − * LDR,STR,PLD immediate offset: Rd, Rn | |
| 1478 | − * LDR,STR,PLD register offset: Rd, Rn, !Rm | |
| 1479 | − * LDR,STR,PLD scaled register offset: Rd, !Rn, !Rm | |
| 1480 | − * LDR,STR immediate pre/post-indexed: Rd, !Rn | |
| 1481 | − * LDR,STR register pre/post-indexed: Rd, !Rn, !Rm | |
| 1482 | − * LDR,STR scaled register pre/post-indexed: Rd, !Rn, !Rm | |
| 1483 | − * LDRB,STRB immediate offset: !Rd, Rn | |
| 1484 | − * LDRB,STRB register offset: !Rd, Rn, !Rm | |
| 1485 | − * LDRB,STRB scaled register offset: !Rd, !Rn, !Rm | |
| 1486 | − * LDRB,STRB immediate pre/post-indexed: !Rd, !Rn | |
| 1487 | − * LDRB,STRB register pre/post-indexed: !Rd, !Rn, !Rm | |
| 1488 | − * LDRB,STRB scaled register pre/post-indexed: !Rd, !Rn, !Rm | |
| 1489 | − * LDRT,LDRBT,STRBT immediate pre/post-indexed: !Rd, !Rn | |
| 1490 | − * LDRT,LDRBT,STRBT register pre/post-indexed: !Rd, !Rn, !Rm | |
| 1491 | − * LDRT,LDRBT,STRBT scaled register pre/post-indexed: !Rd, !Rn, !Rm | |
| 1492 | − * LDRH/SH/SB/D,STRH/SH/SB/D immediate offset: !Rd, Rn | |
| 1493 | − * LDRH/SH/SB/D,STRH/SH/SB/D register offset: !Rd, Rn, !Rm | |
| 1494 | − * LDRH/SH/SB/D,STRH/SH/SB/D immediate pre/post-indexed: !Rd, !Rn | |
| 1495 | − * LDRH/SH/SB/D,STRH/SH/SB/D register pre/post-indexed: !Rd, !Rn, !Rm | |
| 1496 | − * LDREX: !Rd, !Rn | |
| 1497 | − * MCR/2: !Rd | |
| 1498 | − * MCRR/2,MRRC/2: !Rd, !Rn | |
| 1499 | − * MLA: !Rd, !Rn, !Rm, !Rs | |
| 1500 | − * MOV: Rd | |
| 1501 | − * MRC/2: !Rd (if Rd==15, only changes cond codes, not the register) | |
| 1502 | − * MRS,MSR: !Rd | |
| 1503 | − * MUL: !Rd, !Rm, !Rs | |
| 1504 | − * PKH{BT,TB}: !Rd, !Rn, !Rm | |
| 1505 | − * QDADD,[U]QADD/16/8/SUBX: !Rd, !Rm, !Rn | |
| 1506 | − * QDSUB,[U]QSUB/16/8/ADDX: !Rd, !Rm, !Rn | |
| 1507 | − * REV/16/SH: !Rd, !Rm | |
| 1508 | − * RFE: !Rn | |
| 1509 | − * {S,U}[H]ADD{16,8,SUBX},{S,U}[H]SUB{16,8,ADDX}: !Rd, !Rn, !Rm | |
| 1510 | − * SEL: !Rd, !Rn, !Rm | |
| 1511 | − * SMLA<x><y>,SMLA{D,W<y>},SMLSD,SMML{A,S}: !Rd, !Rn, !Rm, !Rs | |
| 1512 | − * SMLAL<x><y>,SMLA{D,LD},SMLSLD,SMMULL,SMULW<y>: !RdHi, !RdLo, !Rm, !Rs | |
| 1513 | − * SMMUL,SMUAD,SMUL<x><y>,SMUSD: !Rd, !Rm, !Rs | |
| 1514 | − * SSAT/16: !Rd, !Rm | |
| 1515 | − * STM(1/2): !Rn, register_list* (R15 in reg list not recommended) | |
| 1516 | − * STRT immediate pre/post-indexed: Rd*, !Rn | |
| 1517 | − * STRT register pre/post-indexed: Rd*, !Rn, !Rm | |
| 1518 | − * STRT scaled register pre/post-indexed: Rd*, !Rn, !Rm | |
| 1519 | − * STREX: !Rd, !Rn, !Rm | |
| 1520 | − * SWP/B: !Rd, !Rn, !Rm | |
| 1521 | − * {S,U}XTA{B,B16,H}: !Rd, !Rn, !Rm | |
| 1522 | − * {S,U}XT{B,B16,H}: !Rd, !Rm | |
| 1523 | − * UM{AA,LA,UL}L: !RdHi, !RdLo, !Rm, !Rs | |
| 1524 | − * USA{D8,A8,T,T16}: !Rd, !Rm, !Rs | |
| 1525 | − * | |
| 1526 | − * May transfer control by writing R15 (possible mode changes or alternate | |
| 1527 | − * mode accesses marked by "*"): | |
| 1528 | − * ALU op (* with s-bit), B, BL, BKPT, BLX(1/2), BX, BXJ, CPS*, CPY, | |
| 1529 | − * LDM(1), LDM(2/3)*, LDR, MOV, RFE*, SWI* | |
| 1530 | − * | |
| 1531 | − * Instructions that do not take general registers, nor transfer control: | |
| 1532 | − * CDP/2, SETEND, SRS* | |
| 1533 | − */ | |
| @@ -134,7 +134,8 @@ static void __kprobes singlestep(struct kprobe *p, struct pt_regs *regs, · 133 unmodified lines | ||
| 134 | 134 | struct kprobe_ctlblk *kcb) |
| 135 | 135 | { |
| 136 | 136 | regs->ARM_pc += 4; |
| 137 | − p->ainsn.insn_handler(p, regs); | |
| 137 | + if (p->ainsn.insn_check_cc(regs->ARM_cpsr)) | |
| 138 | + p->ainsn.insn_handler(p, regs); | |
| 138 | 139 | } |
| 139 | 140 | |
| 140 | 141 | /* |
| @@ -746,7 +746,8 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) · 745 unmodified lines | ||
| 746 | 746 | |
| 747 | 747 | tail = (struct frame_tail __user *)regs->ARM_fp - 1; |
| 748 | 748 | |
| 749 | − while (tail && !((unsigned long)tail & 0x3)) | |
| 749 | + while ((entry->nr < PERF_MAX_STACK_DEPTH) && | |
| 750 | + tail && !((unsigned long)tail & 0x3)) | |
| 750 | 751 | tail = user_backtrace(tail, entry); |
| 751 | 752 | } |
| 752 | 753 | |
| @@ -767,12 +767,20 @@ long arch_ptrace(struct task_struct *child, long request, · 766 unmodified lines | ||
| 767 | 767 | |
| 768 | 768 | #ifdef CONFIG_HAVE_HW_BREAKPOINT |
| 769 | 769 | case PTRACE_GETHBPREGS: |
| 770 | + if (ptrace_get_breakpoints(child) < 0) | |
| 771 | + return -ESRCH; | |
| 772 | + | |
| 770 | 773 | ret = ptrace_gethbpregs(child, addr, |
| 771 | 774 | (unsigned long __user *)data); |
| 775 | + ptrace_put_breakpoints(child); | |
| 772 | 776 | break; |
| 773 | 777 | case PTRACE_SETHBPREGS: |
| 778 | + if (ptrace_get_breakpoints(child) < 0) | |
| 779 | + return -ESRCH; | |
| 780 | + | |
| 774 | 781 | ret = ptrace_sethbpregs(child, addr, |
| 775 | 782 | (unsigned long __user *)data); |
| 783 | + ptrace_put_breakpoints(child); | |
| 776 | 784 | break; |
| 777 | 785 | #endif |
| 778 | 786 | |
| @@ -597,45 +597,19 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info, · 596 unmodified lines | ||
| 597 | 597 | return err; |
| 598 | 598 | } |
| 599 | 599 | |
| 600 | −static inline void setup_syscall_restart(struct pt_regs *regs) | |
| 601 | −{ | |
| 602 | − regs->ARM_r0 = regs->ARM_ORIG_r0; | |
| 603 | − regs->ARM_pc -= thumb_mode(regs) ? 2 : 4; | |
| 604 | −} | |
| 605 | − | |
| 606 | 600 | /* |
| 607 | 601 | * OK, we're invoking a handler |
| 608 | 602 | */ |
| 609 | 603 | static int |
| 610 | 604 | handle_signal(unsigned long sig, struct k_sigaction *ka, |
| 611 | 605 | siginfo_t *info, sigset_t *oldset, |
| 612 | − struct pt_regs * regs, int syscall) | |
| 606 | + struct pt_regs * regs) | |
| 613 | 607 | { |
| 614 | 608 | struct thread_info *thread = current_thread_info(); |
| 615 | 609 | struct task_struct *tsk = current; |
| 616 | 610 | int usig = sig; |
| 617 | 611 | int ret; |
| 618 | 612 | |
| 619 | − /* | |
| 620 | − * If we were from a system call, check for system call restarting... | |
| 621 | − */ | |
| 622 | − if (syscall) { | |
| 623 | − switch (regs->ARM_r0) { | |
| 624 | − case -ERESTART_RESTARTBLOCK: | |
| 625 | − case -ERESTARTNOHAND: | |
| 626 | − regs->ARM_r0 = -EINTR; | |
| 627 | − break; | |
| 628 | − case -ERESTARTSYS: | |
| 629 | − if (!(ka->sa.sa_flags & SA_RESTART)) { | |
| 630 | − regs->ARM_r0 = -EINTR; | |
| 631 | − break; | |
| 632 | − } | |
| 633 | − /* fallthrough */ | |
| 634 | − case -ERESTARTNOINTR: | |
| 635 | − setup_syscall_restart(regs); | |
| 636 | − } | |
| 637 | − } | |
| 638 | − | |
| 639 | 613 | /* |
| 640 | 614 | * translate the signal |
| 641 | 615 | */ |
| @@ -685,6 +659,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, · 43 unmodified lines | ||
| 685 | 659 | */ |
| 686 | 660 | static void do_signal(struct pt_regs *regs, int syscall) |
| 687 | 661 | { |
| 662 | + unsigned int retval = 0, continue_addr = 0, restart_addr = 0; | |
| 688 | 663 | struct k_sigaction ka; |
| 689 | 664 | siginfo_t info; |
| 690 | 665 | int signr; |
| @@ -698,18 +673,61 @@ static void do_signal(struct pt_regs *regs, int syscall) · 7 unmodified lines | ||
| 698 | 673 | if (!user_mode(regs)) |
| 699 | 674 | return; |
| 700 | 675 | |
| 676 | + /* | |
| 677 | + * If we were from a system call, check for system call restarting... | |
| 678 | + */ | |
| 679 | + if (syscall) { | |
| 680 | + continue_addr = regs->ARM_pc; | |
| 681 | + restart_addr = continue_addr - (thumb_mode(regs) ? 2 : 4); | |
| 682 | + retval = regs->ARM_r0; | |
| 683 | + | |
| 684 | + /* | |
| 685 | + * Prepare for system call restart. We do this here so that a | |
| 686 | + * debugger will see the already changed PSW. | |
| 687 | + */ | |
| 688 | + switch (retval) { | |
| 689 | + case -ERESTARTNOHAND: | |
| 690 | + case -ERESTARTSYS: | |
| 691 | + case -ERESTARTNOINTR: | |
| 692 | + regs->ARM_r0 = regs->ARM_ORIG_r0; | |
| 693 | + regs->ARM_pc = restart_addr; | |
| 694 | + break; | |
| 695 | + case -ERESTART_RESTARTBLOCK: | |
| 696 | + regs->ARM_r0 = -EINTR; | |
| 697 | + break; | |
| 698 | + } | |
| 699 | + } | |
| 700 | + | |
| 701 | 701 | if (try_to_freeze()) |
| 702 | 702 | goto no_signal; |
| 703 | 703 | |
| 704 | + /* | |
| 705 | + * Get the signal to deliver. When running under ptrace, at this | |
| 706 | + * point the debugger may change all our registers ... | |
| 707 | + */ | |
| 704 | 708 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
| 705 | 709 | if (signr > 0) { |
| 706 | 710 | sigset_t *oldset; |
| 707 | 711 | |
| 712 | + /* | |
| 713 | + * Depending on the signal settings we may need to revert the | |
| 714 | + * decision to restart the system call. But skip this if a | |
| 715 | + * debugger has chosen to restart at a different PC. | |
| 716 | + */ | |
| 717 | + if (regs->ARM_pc == restart_addr) { | |
| 718 | + if (retval == -ERESTARTNOHAND | |
| 719 | + || (retval == -ERESTARTSYS | |
| 720 | + && !(ka.sa.sa_flags & SA_RESTART))) { | |
| 721 | + regs->ARM_r0 = -EINTR; | |
| 722 | + regs->ARM_pc = continue_addr; | |
| 723 | + } | |
| 724 | + } | |
| 725 | + | |
| 708 | 726 | if (test_thread_flag(TIF_RESTORE_SIGMASK)) |
| 709 | 727 | oldset = ¤t->saved_sigmask; |
| 710 | 728 | else |
| 711 | 729 | oldset = ¤t->blocked; |
| 712 | − if (handle_signal(signr, &ka, &info, oldset, regs, syscall) == 0) { | |
| 730 | + if (handle_signal(signr, &ka, &info, oldset, regs) == 0) { | |
| 713 | 731 | /* |
| 714 | 732 | * A signal was successfully delivered; the saved |
| 715 | 733 | * sigmask will have been stored in the signal frame, |
| @@ -723,11 +741,14 @@ static void do_signal(struct pt_regs *regs, int syscall) · 7 unmodified lines | ||
| 723 | 741 | } |
| 724 | 742 | |
| 725 | 743 | no_signal: |
| 726 | − /* | |
| 727 | − * No signal to deliver to the process - restart the syscall. | |
| 728 | − */ | |
| 729 | 744 | if (syscall) { |
| 730 | − if (regs->ARM_r0 == -ERESTART_RESTARTBLOCK) { | |
| 745 | + /* | |
| 746 | + * Handle restarting a different system call. As above, | |
| 747 | + * if a debugger has chosen to restart at a different PC, | |
| 748 | + * ignore the restart. | |
| 749 | + */ | |
| 750 | + if (retval == -ERESTART_RESTARTBLOCK | |
| 751 | + && regs->ARM_pc == continue_addr) { | |
| 731 | 752 | if (thumb_mode(regs)) { |
| 732 | 753 | regs->ARM_r7 = __NR_restart_syscall - __NR_SYSCALL_BASE; |
| 733 | 754 | regs->ARM_pc -= 2; |
| @@ -750,11 +771,6 @@ static void do_signal(struct pt_regs *regs, int syscall) · 16 unmodified lines | ||
| 750 | 771 | #endif |
| 751 | 772 | } |
| 752 | 773 | } |
| 753 | − if (regs->ARM_r0 == -ERESTARTNOHAND || | |
| 754 | − regs->ARM_r0 == -ERESTARTSYS || | |
| 755 | − regs->ARM_r0 == -ERESTARTNOINTR) { | |
| 756 | − setup_syscall_restart(regs); | |
| 757 | − } | |
| 758 | 774 | |
| 759 | 775 | /* If there's no signal to deliver, we just put the saved sigmask |
| 760 | 776 | * back. |
| @@ -479,7 +479,7 @@ static void broadcast_timer_set_mode(enum clock_event_mode mode, · 478 unmodified lines | ||
| 479 | 479 | { |
| 480 | 480 | } |
| 481 | 481 | |
| 482 | −static void broadcast_timer_setup(struct clock_event_device *evt) | |
| 482 | +static void __cpuinit broadcast_timer_setup(struct clock_event_device *evt) | |
| 483 | 483 | { |
| 484 | 484 | evt->name = "dummy_timer"; |
| 485 | 485 | evt->features = CLOCK_EVT_FEAT_ONESHOT | |
| @@ -311,7 +311,7 @@ asmlinkage long sys_oabi_semtimedop(int semid, · 310 unmodified lines | ||
| 311 | 311 | long err; |
| 312 | 312 | int i; |
| 313 | 313 | |
| 314 | − if (nsops < 1) | |
| 314 | + if (nsops < 1 || nsops > SEMOPM) | |
| 315 | 315 | return -EINVAL; |
| 316 | 316 | sops = kmalloc(sizeof(*sops) * nsops, GFP_KERNEL); |
| 317 | 317 | if (!sops) |
| @@ -83,6 +83,7 @@ config ARCH_AT91CAP9 · 82 unmodified lines | ||
| 83 | 83 | select CPU_ARM926T |
| 84 | 84 | select GENERIC_CLOCKEVENTS |
| 85 | 85 | select HAVE_FB_ATMEL |
| 86 | + select HAVE_NET_MACB | |
| 86 | 87 | |
| 87 | 88 | config ARCH_AT572D940HF |
| 88 | 89 | bool "AT572D940HF" |
| @@ -30,6 +30,11 @@ · 29 unmodified lines | ||
| 30 | 30 | #include <mach/board.h> |
| 31 | 31 | #include "generic.h" |
| 32 | 32 | |
| 33 | +static void __init at91eb01_init_irq(void) | |
| 34 | +{ | |
| 35 | + at91x40_init_interrupts(NULL); | |
| 36 | +} | |
| 37 | + | |
| 33 | 38 | static void __init at91eb01_map_io(void) |
| 34 | 39 | { |
| 35 | 40 | at91x40_initialize(40000000); |
| @@ -38,7 +43,7 @@ static void __init at91eb01_map_io(void) · 2 unmodified lines | ||
| 38 | 43 | MACHINE_START(AT91EB01, "Atmel AT91 EB01") |
| 39 | 44 | /* Maintainer: Greg Ungerer <gerg@snapgear.com> */ |
| 40 | 45 | .timer = &at91x40_timer, |
| 41 | − .init_irq = at91x40_init_interrupts, | |
| 46 | + .init_irq = at91eb01_init_irq, | |
| 42 | 47 | .map_io = at91eb01_map_io, |
| 43 | 48 | MACHINE_END |
| 44 | 49 | |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | #define ARCH_ID_AT91SAM9G45 0x819b05a0 |
| 28 | 28 | #define ARCH_ID_AT91SAM9G45MRL 0x819b05a2 /* aka 9G45-ES2 & non ES lots */ |
| 29 | 29 | #define ARCH_ID_AT91SAM9G45ES 0x819b05a1 /* 9G45-ES (Engineering Sample) */ |
| 30 | +#define ARCH_ID_AT91SAM9X5 0x819a05a0 | |
| 30 | 31 | #define ARCH_ID_AT91CAP9 0x039A03A0 |
| 31 | 32 | |
| 32 | 33 | #define ARCH_ID_AT91SAM9XE128 0x329973a0 |
| @@ -55,6 +56,12 @@ static inline unsigned long at91_cpu_fully_identify(void) · 22 unmodified lines | ||
| 55 | 56 | #define ARCH_EXID_AT91SAM9G46 0x00000003 |
| 56 | 57 | #define ARCH_EXID_AT91SAM9G45 0x00000004 |
| 57 | 58 | |
| 59 | +#define ARCH_EXID_AT91SAM9G15 0x00000000 | |
| 60 | +#define ARCH_EXID_AT91SAM9G35 0x00000001 | |
| 61 | +#define ARCH_EXID_AT91SAM9X35 0x00000002 | |
| 62 | +#define ARCH_EXID_AT91SAM9G25 0x00000003 | |
| 63 | +#define ARCH_EXID_AT91SAM9X25 0x00000004 | |
| 64 | + | |
| 58 | 65 | static inline unsigned long at91_exid_identify(void) |
| 59 | 66 | { |
| 60 | 67 | return at91_sys_read(AT91_DBGU_EXID); |
| @@ -143,6 +150,27 @@ static inline unsigned long at91cap9_rev_identify(void) · 82 unmodified lines | ||
| 143 | 150 | #define cpu_is_at91sam9m11() (0) |
| 144 | 151 | #endif |
| 145 | 152 | |
| 153 | +#ifdef CONFIG_ARCH_AT91SAM9X5 | |
| 154 | +#define cpu_is_at91sam9x5() (at91_cpu_identify() == ARCH_ID_AT91SAM9X5) | |
| 155 | +#define cpu_is_at91sam9g15() (cpu_is_at91sam9x5() && \ | |
| 156 | + (at91_exid_identify() == ARCH_EXID_AT91SAM9G15)) | |
| 157 | +#define cpu_is_at91sam9g35() (cpu_is_at91sam9x5() && \ | |
| 158 | + (at91_exid_identify() == ARCH_EXID_AT91SAM9G35)) | |
| 159 | +#define cpu_is_at91sam9x35() (cpu_is_at91sam9x5() && \ | |
| 160 | + (at91_exid_identify() == ARCH_EXID_AT91SAM9X35)) | |
| 161 | +#define cpu_is_at91sam9g25() (cpu_is_at91sam9x5() && \ | |
| 162 | + (at91_exid_identify() == ARCH_EXID_AT91SAM9G25)) | |
| 163 | +#define cpu_is_at91sam9x25() (cpu_is_at91sam9x5() && \ | |
| 164 | + (at91_exid_identify() == ARCH_EXID_AT91SAM9X25)) | |
| 165 | +#else | |
| 166 | +#define cpu_is_at91sam9x5() (0) | |
| 167 | +#define cpu_is_at91sam9g15() (0) | |
| 168 | +#define cpu_is_at91sam9g35() (0) | |
| 169 | +#define cpu_is_at91sam9x35() (0) | |
| 170 | +#define cpu_is_at91sam9g25() (0) | |
| 171 | +#define cpu_is_at91sam9x25() (0) | |
| 172 | +#endif | |
| 173 | + | |
| 146 | 174 | #ifdef CONFIG_ARCH_AT91CAP9 |
| 147 | 175 | #define cpu_is_at91cap9() (at91_cpu_identify() == ARCH_ID_AT91CAP9) |
| 148 | 176 | #define cpu_is_at91cap9_revB() (at91cap9_rev_identify() == ARCH_REVISION_CAP9_B) |
| @@ -63,6 +63,7 @@ config MACH_DAVINCI_EVM · 62 unmodified lines | ||
| 63 | 63 | depends on ARCH_DAVINCI_DM644x |
| 64 | 64 | select MISC_DEVICES |
| 65 | 65 | select EEPROM_AT24 |
| 66 | + select I2C | |
| 66 | 67 | help |
| 67 | 68 | Configure this option to specify the whether the board used |
| 68 | 69 | for development is a DM644x EVM |
| @@ -72,6 +73,7 @@ config MACH_SFFSDR · 3 unmodified lines | ||
| 72 | 73 | depends on ARCH_DAVINCI_DM644x |
| 73 | 74 | select MISC_DEVICES |
| 74 | 75 | select EEPROM_AT24 |
| 76 | + select I2C | |
| 75 | 77 | help |
| 76 | 78 | Say Y here to select the Lyrtech Small Form Factor |
| 77 | 79 | Software Defined Radio (SFFSDR) board. |
| @@ -105,6 +107,7 @@ config MACH_DAVINCI_DM6467_EVM · 27 unmodified lines | ||
| 105 | 107 | select MACH_DAVINCI_DM6467TEVM |
| 106 | 108 | select MISC_DEVICES |
| 107 | 109 | select EEPROM_AT24 |
| 110 | + select I2C | |
| 108 | 111 | help |
| 109 | 112 | Configure this option to specify the whether the board used |
| 110 | 113 | for development is a DM6467 EVM |
| @@ -118,6 +121,7 @@ config MACH_DAVINCI_DM365_EVM · 7 unmodified lines | ||
| 118 | 121 | depends on ARCH_DAVINCI_DM365 |
| 119 | 122 | select MISC_DEVICES |
| 120 | 123 | select EEPROM_AT24 |
| 124 | + select I2C | |
| 121 | 125 | help |
| 122 | 126 | Configure this option to specify whether the board used |
| 123 | 127 | for development is a DM365 EVM |
| @@ -129,6 +133,7 @@ config MACH_DAVINCI_DA830_EVM · 5 unmodified lines | ||
| 129 | 133 | select GPIO_PCF857X |
| 130 | 134 | select MISC_DEVICES |
| 131 | 135 | select EEPROM_AT24 |
| 136 | + select I2C | |
| 132 | 137 | help |
| 133 | 138 | Say Y here to select the TI DA830/OMAP-L137/AM17x Evaluation Module. |
| 134 | 139 | |
| @@ -205,6 +210,7 @@ config MACH_MITYOMAPL138 · 70 unmodified lines | ||
| 205 | 210 | depends on ARCH_DAVINCI_DA850 |
| 206 | 211 | select MISC_DEVICES |
| 207 | 212 | select EEPROM_AT24 |
| 213 | + select I2C | |
| 208 | 214 | help |
| 209 | 215 | Say Y here to select the Critical Link MityDSP-L138/MityARM-1808 |
| 210 | 216 | System on Module. Information on this SoM may be found at |
| @@ -29,7 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include <mach/mux.h> |
| 30 | 30 | #include <mach/spi.h> |
| 31 | 31 | |
| 32 | −#define MITYOMAPL138_PHY_ID "0:03" | |
| 32 | +#define MITYOMAPL138_PHY_ID "" | |
| 33 | 33 | |
| 34 | 34 | #define FACTORY_CONFIG_MAGIC 0x012C0138 |
| 35 | 35 | #define FACTORY_CONFIG_VERSION 0x00010001 |
| @@ -414,7 +414,7 @@ static struct resource mityomapl138_nandflash_resource[] = { · 378 unmodified lines | ||
| 414 | 414 | |
| 415 | 415 | static struct platform_device mityomapl138_nandflash_device = { |
| 416 | 416 | .name = "davinci_nand", |
| 417 | − .id = 0, | |
| 417 | + .id = 1, | |
| 418 | 418 | .dev = { |
| 419 | 419 | .platform_data = &mityomapl138_nandflash_data, |
| 420 | 420 | }, |
| @@ -39,7 +39,8 @@ · 38 unmodified lines | ||
| 39 | 39 | #define DA8XX_GPIO_BASE 0x01e26000 |
| 40 | 40 | #define DA8XX_I2C1_BASE 0x01e28000 |
| 41 | 41 | #define DA8XX_SPI0_BASE 0x01c41000 |
| 42 | −#define DA8XX_SPI1_BASE 0x01f0e000 | |
| 42 | +#define DA830_SPI1_BASE 0x01e12000 | |
| 43 | +#define DA850_SPI1_BASE 0x01f0e000 | |
| 43 | 44 | |
| 44 | 45 | #define DA8XX_EMAC_CTRL_REG_OFFSET 0x3000 |
| 45 | 46 | #define DA8XX_EMAC_MOD_REG_OFFSET 0x2000 |
| @@ -762,8 +763,8 @@ static struct resource da8xx_spi0_resources[] = { · 716 unmodified lines | ||
| 762 | 763 | |
| 763 | 764 | static struct resource da8xx_spi1_resources[] = { |
| 764 | 765 | [0] = { |
| 765 | − .start = DA8XX_SPI1_BASE, | |
| 766 | − .end = DA8XX_SPI1_BASE + SZ_4K - 1, | |
| 766 | + .start = DA830_SPI1_BASE, | |
| 767 | + .end = DA830_SPI1_BASE + SZ_4K - 1, | |
| 767 | 768 | .flags = IORESOURCE_MEM, |
| 768 | 769 | }, |
| 769 | 770 | [1] = { |
| @@ -832,5 +833,10 @@ int __init da8xx_register_spi(int instance, struct spi_board_info *info, · 62 unmodified lines | ||
| 832 | 833 | |
| 833 | 834 | da8xx_spi_pdata[instance].num_chipselect = len; |
| 834 | 835 | |
| 836 | + if (instance == 1 && cpu_is_davinci_da850()) { | |
| 837 | + da8xx_spi1_resources[0].start = DA850_SPI1_BASE; | |
| 838 | + da8xx_spi1_resources[0].end = DA850_SPI1_BASE + SZ_4K - 1; | |
| 839 | + } | |
| 840 | + | |
| 835 | 841 | return platform_device_register(&da8xx_spi_device[instance]); |
| 836 | 842 | } |
| @@ -314,7 +314,7 @@ static struct clk timer2_clk = { · 313 unmodified lines | ||
| 314 | 314 | .name = "timer2", |
| 315 | 315 | .parent = &pll1_aux_clk, |
| 316 | 316 | .lpsc = DAVINCI_LPSC_TIMER2, |
| 317 | − .usecount = 1, /* REVISIT: why can't' this be disabled? */ | |
| 317 | + .usecount = 1, /* REVISIT: why can't this be disabled? */ | |
| 318 | 318 | }; |
| 319 | 319 | |
| 320 | 320 | static struct clk timer3_clk = { |
| @@ -274,7 +274,7 @@ static struct clk timer2_clk = { · 273 unmodified lines | ||
| 274 | 274 | .name = "timer2", |
| 275 | 275 | .parent = &pll1_aux_clk, |
| 276 | 276 | .lpsc = DAVINCI_LPSC_TIMER2, |
| 277 | − .usecount = 1, /* REVISIT: why can't' this be disabled? */ | |
| 277 | + .usecount = 1, /* REVISIT: why can't this be disabled? */ | |
| 278 | 278 | }; |
| 279 | 279 | |
| 280 | 280 | static struct clk_lookup dm644x_clks[] = { |
| @@ -24,6 +24,9 @@ · 23 unmodified lines | ||
| 24 | 24 | |
| 25 | 25 | #define UART_SHIFT 2 |
| 26 | 26 | |
| 27 | +#define davinci_uart_v2p(x) ((x) - PAGE_OFFSET + PLAT_PHYS_OFFSET) | |
| 28 | +#define davinci_uart_p2v(x) ((x) - PLAT_PHYS_OFFSET + PAGE_OFFSET) | |
| 29 | + | |
| 27 | 30 | .pushsection .data |
| 28 | 31 | davinci_uart_phys: .word 0 |
| 29 | 32 | davinci_uart_virt: .word 0 |
| @@ -34,7 +37,7 @@ davinci_uart_virt: .word 0 · 4 unmodified lines | ||
| 34 | 37 | /* Use davinci_uart_phys/virt if already configured */ |
| 35 | 38 | 10: mrc p15, 0, \rp, c1, c0 |
| 36 | 39 | tst \rp, #1 @ MMU enabled? |
| 37 | − ldreq \rp, =__virt_to_phys(davinci_uart_phys) | |
| 40 | + ldreq \rp, =davinci_uart_v2p(davinci_uart_phys) | |
| 38 | 41 | ldrne \rp, =davinci_uart_phys |
| 39 | 42 | add \rv, \rp, #4 @ davinci_uart_virt |
| 40 | 43 | ldr \rp, [\rp, #0] |
| @@ -48,18 +51,18 @@ davinci_uart_virt: .word 0 · 7 unmodified lines | ||
| 48 | 51 | tst \rp, #1 @ MMU enabled? |
| 49 | 52 | |
| 50 | 53 | /* Copy uart phys address from decompressor uart info */ |
| 51 | − ldreq \rv, =__virt_to_phys(davinci_uart_phys) | |
| 54 | + ldreq \rv, =davinci_uart_v2p(davinci_uart_phys) | |
| 52 | 55 | ldrne \rv, =davinci_uart_phys |
| 53 | 56 | ldreq \rp, =DAVINCI_UART_INFO |
| 54 | − ldrne \rp, =__phys_to_virt(DAVINCI_UART_INFO) | |
| 57 | + ldrne \rp, =davinci_uart_p2v(DAVINCI_UART_INFO) | |
| 55 | 58 | ldr \rp, [\rp, #0] |
| 56 | 59 | str \rp, [\rv] |
| 57 | 60 | |
| 58 | 61 | /* Copy uart virt address from decompressor uart info */ |
| 59 | − ldreq \rv, =__virt_to_phys(davinci_uart_virt) | |
| 62 | + ldreq \rv, =davinci_uart_v2p(davinci_uart_virt) | |
| 60 | 63 | ldrne \rv, =davinci_uart_virt |
| 61 | 64 | ldreq \rp, =DAVINCI_UART_INFO |
| 62 | − ldrne \rp, =__phys_to_virt(DAVINCI_UART_INFO) | |
| 65 | + ldrne \rp, =davinci_uart_p2v(DAVINCI_UART_INFO) | |
| 63 | 66 | ldr \rp, [\rp, #4] |
| 64 | 67 | str \rp, [\rv] |
| 65 | 68 | |
| @@ -22,7 +22,7 @@ · 21 unmodified lines | ||
| 22 | 22 | * |
| 23 | 23 | * This area sits just below the page tables (see arch/arm/kernel/head.S). |
| 24 | 24 | */ |
| 25 | −#define DAVINCI_UART_INFO (PHYS_OFFSET + 0x3ff8) | |
| 25 | +#define DAVINCI_UART_INFO (PLAT_PHYS_OFFSET + 0x3ff8) | |
| 26 | 26 | |
| 27 | 27 | #define DAVINCI_UART0_BASE (IO_PHYS + 0x20000) |
| 28 | 28 | #define DAVINCI_UART1_BASE (IO_PHYS + 0x20400) |
| @@ -257,11 +257,16 @@ static const struct fsl_usb2_platform_data otg_device_pdata __initconst = { · 256 unmodified lines | ||
| 257 | 257 | .workaround = FLS_USB2_WORKAROUND_ENGCM09152, |
| 258 | 258 | }; |
| 259 | 259 | |
| 260 | +static int vpr200_usbh_init(struct platform_device *pdev) | |
| 261 | +{ | |
| 262 | + return mx35_initialize_usb_hw(pdev->id, | |
| 263 | + MXC_EHCI_INTERFACE_SINGLE_UNI | MXC_EHCI_INTERNAL_PHY); | |
| 264 | +} | |
| 265 | + | |
| 260 | 266 | /* USB HOST config */ |
| 261 | 267 | static const struct mxc_usbh_platform_data usb_host_pdata __initconst = { |
| 262 | − .portsc = MXC_EHCI_MODE_SERIAL, | |
| 263 | − .flags = MXC_EHCI_INTERFACE_SINGLE_UNI | | |
| 264 | − MXC_EHCI_INTERNAL_PHY, | |
| 268 | + .init = vpr200_usbh_init, | |
| 269 | + .portsc = MXC_EHCI_MODE_SERIAL, | |
| 265 | 270 | }; |
| 266 | 271 | |
| 267 | 272 | static struct platform_device *devices[] __initdata = { |
| @@ -193,7 +193,7 @@ static iomux_v3_cfg_t mx53_loco_pads[] = { · 192 unmodified lines | ||
| 193 | 193 | .wakeup = wake, \ |
| 194 | 194 | } |
| 195 | 195 | |
| 196 | −static const struct gpio_keys_button loco_buttons[] __initconst = { | |
| 196 | +static struct gpio_keys_button loco_buttons[] = { | |
| 197 | 197 | GPIO_BUTTON(MX53_LOCO_POWER, KEY_POWER, 1, "power", 0), |
| 198 | 198 | GPIO_BUTTON(MX53_LOCO_UI1, KEY_VOLUMEUP, 1, "volume-up", 0), |
| 199 | 199 | GPIO_BUTTON(MX53_LOCO_UI2, KEY_VOLUMEDOWN, 1, "volume-down", 0), |
| @@ -295,11 +295,11 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \ · 294 unmodified lines | ||
| 295 | 295 | unsigned long diff, parent_rate, calc_rate; \ |
| 296 | 296 | int i; \ |
| 297 | 297 | \ |
| 298 | − parent_rate = clk_get_rate(clk->parent); \ | |
| 299 | 298 | div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV; \ |
| 300 | 299 | bm_busy = BM_CLKCTRL_##dr##_BUSY; \ |
| 301 | 300 | \ |
| 302 | 301 | if (clk->parent == &ref_xtal_clk) { \ |
| 302 | + parent_rate = clk_get_rate(clk->parent); \ | |
| 303 | 303 | div = DIV_ROUND_UP(parent_rate, rate); \ |
| 304 | 304 | if (clk == &cpu_clk) { \ |
| 305 | 305 | div_max = BM_CLKCTRL_CPU_DIV_XTAL >> \ |
| @@ -309,6 +309,11 @@ static int name##_set_rate(struct clk *clk, unsigned long rate) \ · 3 unmodified lines | ||
| 309 | 309 | if (div == 0 || div > div_max) \ |
| 310 | 310 | return -EINVAL; \ |
| 311 | 311 | } else { \ |
| 312 | + /* \ | |
| 313 | + * hack alert: this block modifies clk->parent, too, \ | |
| 314 | + * so the base to use it the grand parent. \ | |
| 315 | + */ \ | |
| 316 | + parent_rate = clk_get_rate(clk->parent->parent); \ | |
| 312 | 317 | rate >>= PARENT_RATE_SHIFT; \ |
| 313 | 318 | parent_rate >>= PARENT_RATE_SHIFT; \ |
| 314 | 319 | diff = parent_rate; \ |
| @@ -68,7 +68,7 @@ obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o · 67 unmodified lines | ||
| 68 | 68 | obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o |
| 69 | 69 | |
| 70 | 70 | AFLAGS_sleep24xx.o :=-Wa,-march=armv6 |
| 71 | −AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a | |
| 71 | +AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a$(plus_sec) | |
| 72 | 72 | |
| 73 | 73 | ifeq ($(CONFIG_PM_VERBOSE),y) |
| 74 | 74 | CFLAGS_pm_bus.o += -DDEBUG |
| @@ -141,14 +141,19 @@ static void __init rx51_init(void) · 140 unmodified lines | ||
| 141 | 141 | static void __init rx51_map_io(void) |
| 142 | 142 | { |
| 143 | 143 | omap2_set_globals_3xxx(); |
| 144 | − rx51_video_mem_init(); | |
| 145 | 144 | omap34xx_map_common_io(); |
| 146 | 145 | } |
| 147 | 146 | |
| 147 | +static void __init rx51_reserve(void) | |
| 148 | +{ | |
| 149 | + rx51_video_mem_init(); | |
| 150 | + omap_reserve(); | |
| 151 | +} | |
| 152 | + | |
| 148 | 153 | MACHINE_START(NOKIA_RX51, "Nokia RX-51 board") |
| 149 | 154 | /* Maintainer: Lauri Leukkunen <lauri.leukkunen@nokia.com> */ |
| 150 | 155 | .boot_params = 0x80000100, |
| 151 | − .reserve = omap_reserve, | |
| 156 | + .reserve = rx51_reserve, | |
| 152 | 157 | .map_io = rx51_map_io, |
| 153 | 158 | .init_early = rx51_init_early, |
| 154 | 159 | .init_irq = omap_init_irq, |
| @@ -115,6 +115,7 @@ int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate) · 114 unmodified lines | ||
| 115 | 115 | sdrc_cs0->rfr_ctrl, sdrc_cs0->actim_ctrla, |
| 116 | 116 | sdrc_cs0->actim_ctrlb, sdrc_cs0->mr, |
| 117 | 117 | 0, 0, 0, 0); |
| 118 | + clk->rate = rate; | |
| 118 | 119 | |
| 119 | 120 | return 0; |
| 120 | 121 | } |
| @@ -3116,14 +3116,9 @@ static struct omap_clk omap44xx_clks[] = { · 3115 unmodified lines | ||
| 3116 | 3116 | CLK(NULL, "dsp_fck", &dsp_fck, CK_443X), |
| 3117 | 3117 | CLK("omapdss_dss", "sys_clk", &dss_sys_clk, CK_443X), |
| 3118 | 3118 | CLK("omapdss_dss", "tv_clk", &dss_tv_clk, CK_443X), |
| 3119 | − CLK("omapdss_dss", "dss_clk", &dss_dss_clk, CK_443X), | |
| 3120 | 3119 | CLK("omapdss_dss", "video_clk", &dss_48mhz_clk, CK_443X), |
| 3121 | − CLK("omapdss_dss", "fck", &dss_fck, CK_443X), | |
| 3122 | − /* | |
| 3123 | − * On OMAP4, DSS ick is a dummy clock; this is needed for compatibility | |
| 3124 | − * with OMAP2/3. | |
| 3125 | − */ | |
| 3126 | − CLK("omapdss_dss", "ick", &dummy_ck, CK_443X), | |
| 3120 | + CLK("omapdss_dss", "fck", &dss_dss_clk, CK_443X), | |
| 3121 | + CLK("omapdss_dss", "ick", &dss_fck, CK_443X), | |
| 3127 | 3122 | CLK(NULL, "efuse_ctrl_cust_fck", &efuse_ctrl_cust_fck, CK_443X), |
| 3128 | 3123 | CLK(NULL, "emif1_fck", &emif1_fck, CK_443X), |
| 3129 | 3124 | CLK(NULL, "emif2_fck", &emif2_fck, CK_443X), |
| @@ -247,6 +247,7 @@ struct omap3_cm_regs { · 246 unmodified lines | ||
| 247 | 247 | u32 per_cm_clksel; |
| 248 | 248 | u32 emu_cm_clksel; |
| 249 | 249 | u32 emu_cm_clkstctrl; |
| 250 | + u32 pll_cm_autoidle; | |
| 250 | 251 | u32 pll_cm_autoidle2; |
| 251 | 252 | u32 pll_cm_clksel4; |
| 252 | 253 | u32 pll_cm_clksel5; |
| @@ -319,6 +320,15 @@ void omap3_cm_save_context(void) · 66 unmodified lines | ||
| 319 | 320 | omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, CM_CLKSEL1); |
| 320 | 321 | cm_context.emu_cm_clkstctrl = |
| 321 | 322 | omap2_cm_read_mod_reg(OMAP3430_EMU_MOD, OMAP2_CM_CLKSTCTRL); |
| 323 | + /* | |
| 324 | + * As per erratum i671, ROM code does not respect the PER DPLL | |
| 325 | + * programming scheme if CM_AUTOIDLE_PLL.AUTO_PERIPH_DPLL == 1. | |
| 326 | + * In this case, even though this register has been saved in | |
| 327 | + * scratchpad contents, we need to restore AUTO_PERIPH_DPLL | |
| 328 | + * by ourselves. So, we need to save it anyway. | |
| 329 | + */ | |
| 330 | + cm_context.pll_cm_autoidle = | |
| 331 | + omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE); | |
| 322 | 332 | cm_context.pll_cm_autoidle2 = |
| 323 | 333 | omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE2); |
| 324 | 334 | cm_context.pll_cm_clksel4 = |
| @@ -441,6 +451,13 @@ void omap3_cm_restore_context(void) · 116 unmodified lines | ||
| 441 | 451 | CM_CLKSEL1); |
| 442 | 452 | omap2_cm_write_mod_reg(cm_context.emu_cm_clkstctrl, OMAP3430_EMU_MOD, |
| 443 | 453 | OMAP2_CM_CLKSTCTRL); |
| 454 | + /* | |
| 455 | + * As per erratum i671, ROM code does not respect the PER DPLL | |
| 456 | + * programming scheme if CM_AUTOIDLE_PLL.AUTO_PERIPH_DPLL == 1. | |
| 457 | + * In this case, we need to restore AUTO_PERIPH_DPLL by ourselves. | |
| 458 | + */ | |
| 459 | + omap2_cm_write_mod_reg(cm_context.pll_cm_autoidle, PLL_MOD, | |
| 460 | + CM_AUTOIDLE); | |
| 444 | 461 | omap2_cm_write_mod_reg(cm_context.pll_cm_autoidle2, PLL_MOD, |
| 445 | 462 | CM_AUTOIDLE2); |
| 446 | 463 | omap2_cm_write_mod_reg(cm_context.pll_cm_clksel4, PLL_MOD, |
| @@ -316,8 +316,14 @@ void omap3_save_scratchpad_contents(void) · 315 unmodified lines | ||
| 316 | 316 | omap2_cm_read_mod_reg(WKUP_MOD, CM_CLKSEL); |
| 317 | 317 | prcm_block_contents.cm_clken_pll = |
| 318 | 318 | omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN); |
| 319 | + /* | |
| 320 | + * As per erratum i671, ROM code does not respect the PER DPLL | |
| 321 | + * programming scheme if CM_AUTOIDLE_PLL..AUTO_PERIPH_DPLL == 1. | |
| 322 | + * Then, in anycase, clear these bits to avoid extra latencies. | |
| 323 | + */ | |
| 319 | 324 | prcm_block_contents.cm_autoidle_pll = |
| 320 | − omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_AUTOIDLE_PLL); | |
| 325 | + omap2_cm_read_mod_reg(PLL_MOD, CM_AUTOIDLE) & | |
| 326 | + ~OMAP3430_AUTO_PERIPH_DPLL_MASK; | |
| 321 | 327 | prcm_block_contents.cm_clksel1_pll = |
| 322 | 328 | omap2_cm_read_mod_reg(PLL_MOD, OMAP3430_CM_CLKSEL1_PLL); |
| 323 | 329 | prcm_block_contents.cm_clksel2_pll = |
| @@ -1639,6 +1639,7 @@ static struct omap_hwmod_ocp_if *omap2420_gpio1_slaves[] = { · 1638 unmodified lines | ||
| 1639 | 1639 | |
| 1640 | 1640 | static struct omap_hwmod omap2420_gpio1_hwmod = { |
| 1641 | 1641 | .name = "gpio1", |
| 1642 | + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, | |
| 1642 | 1643 | .mpu_irqs = omap242x_gpio1_irqs, |
| 1643 | 1644 | .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio1_irqs), |
| 1644 | 1645 | .main_clk = "gpios_fck", |
| @@ -1669,6 +1670,7 @@ static struct omap_hwmod_ocp_if *omap2420_gpio2_slaves[] = { · 24 unmodified lines | ||
| 1669 | 1670 | |
| 1670 | 1671 | static struct omap_hwmod omap2420_gpio2_hwmod = { |
| 1671 | 1672 | .name = "gpio2", |
| 1673 | + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, | |
| 1672 | 1674 | .mpu_irqs = omap242x_gpio2_irqs, |
| 1673 | 1675 | .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio2_irqs), |
| 1674 | 1676 | .main_clk = "gpios_fck", |
| @@ -1699,6 +1701,7 @@ static struct omap_hwmod_ocp_if *omap2420_gpio3_slaves[] = { · 24 unmodified lines | ||
| 1699 | 1701 | |
| 1700 | 1702 | static struct omap_hwmod omap2420_gpio3_hwmod = { |
| 1701 | 1703 | .name = "gpio3", |
| 1704 | + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, | |
| 1702 | 1705 | .mpu_irqs = omap242x_gpio3_irqs, |
| 1703 | 1706 | .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio3_irqs), |
| 1704 | 1707 | .main_clk = "gpios_fck", |
| @@ -1729,6 +1732,7 @@ static struct omap_hwmod_ocp_if *omap2420_gpio4_slaves[] = { · 24 unmodified lines | ||
| 1729 | 1732 | |
| 1730 | 1733 | static struct omap_hwmod omap2420_gpio4_hwmod = { |
| 1731 | 1734 | .name = "gpio4", |
| 1735 | + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, | |
| 1732 | 1736 | .mpu_irqs = omap242x_gpio4_irqs, |
| 1733 | 1737 | .mpu_irqs_cnt = ARRAY_SIZE(omap242x_gpio4_irqs), |
| 1734 | 1738 | .main_clk = "gpios_fck", |
| @@ -1782,7 +1786,7 @@ static struct omap_hwmod_irq_info omap2420_dma_system_irqs[] = { · 47 unmodified lines | ||
| 1782 | 1786 | static struct omap_hwmod_addr_space omap2420_dma_system_addrs[] = { |
| 1783 | 1787 | { |
| 1784 | 1788 | .pa_start = 0x48056000, |
| 1785 | − .pa_end = 0x4a0560ff, | |
| 1789 | + .pa_end = 0x48056fff, | |
| 1786 | 1790 | .flags = ADDR_TYPE_RT |
| 1787 | 1791 | }, |
| 1788 | 1792 | }; |
| @@ -1742,6 +1742,7 @@ static struct omap_hwmod_ocp_if *omap2430_gpio1_slaves[] = { · 1741 unmodified lines | ||
| 1742 | 1742 | |
| 1743 | 1743 | static struct omap_hwmod omap2430_gpio1_hwmod = { |
| 1744 | 1744 | .name = "gpio1", |
| 1745 | + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, | |
| 1745 | 1746 | .mpu_irqs = omap243x_gpio1_irqs, |
| 1746 | 1747 | .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio1_irqs), |
| 1747 | 1748 | .main_clk = "gpios_fck", |
| @@ -1772,6 +1773,7 @@ static struct omap_hwmod_ocp_if *omap2430_gpio2_slaves[] = { · 24 unmodified lines | ||
| 1772 | 1773 | |
| 1773 | 1774 | static struct omap_hwmod omap2430_gpio2_hwmod = { |
| 1774 | 1775 | .name = "gpio2", |
| 1776 | + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, | |
| 1775 | 1777 | .mpu_irqs = omap243x_gpio2_irqs, |
| 1776 | 1778 | .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio2_irqs), |
| 1777 | 1779 | .main_clk = "gpios_fck", |
| @@ -1802,6 +1804,7 @@ static struct omap_hwmod_ocp_if *omap2430_gpio3_slaves[] = { · 24 unmodified lines | ||
| 1802 | 1804 | |
| 1803 | 1805 | static struct omap_hwmod omap2430_gpio3_hwmod = { |
| 1804 | 1806 | .name = "gpio3", |
| 1807 | + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, | |
| 1805 | 1808 | .mpu_irqs = omap243x_gpio3_irqs, |
| 1806 | 1809 | .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio3_irqs), |
| 1807 | 1810 | .main_clk = "gpios_fck", |
| @@ -1832,6 +1835,7 @@ static struct omap_hwmod_ocp_if *omap2430_gpio4_slaves[] = { · 24 unmodified lines | ||
| 1832 | 1835 | |
| 1833 | 1836 | static struct omap_hwmod omap2430_gpio4_hwmod = { |
| 1834 | 1837 | .name = "gpio4", |
| 1838 | + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, | |
| 1835 | 1839 | .mpu_irqs = omap243x_gpio4_irqs, |
| 1836 | 1840 | .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio4_irqs), |
| 1837 | 1841 | .main_clk = "gpios_fck", |
| @@ -1862,6 +1866,7 @@ static struct omap_hwmod_ocp_if *omap2430_gpio5_slaves[] = { · 24 unmodified lines | ||
| 1862 | 1866 | |
| 1863 | 1867 | static struct omap_hwmod omap2430_gpio5_hwmod = { |
| 1864 | 1868 | .name = "gpio5", |
| 1869 | + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, | |
| 1865 | 1870 | .mpu_irqs = omap243x_gpio5_irqs, |
| 1866 | 1871 | .mpu_irqs_cnt = ARRAY_SIZE(omap243x_gpio5_irqs), |
| 1867 | 1872 | .main_clk = "gpio5_fck", |
| @@ -1915,7 +1920,7 @@ static struct omap_hwmod_irq_info omap2430_dma_system_irqs[] = { · 47 unmodified lines | ||
| 1915 | 1920 | static struct omap_hwmod_addr_space omap2430_dma_system_addrs[] = { |
| 1916 | 1921 | { |
| 1917 | 1922 | .pa_start = 0x48056000, |
| 1918 | − .pa_end = 0x4a0560ff, | |
| 1923 | + .pa_end = 0x48056fff, | |
| 1919 | 1924 | .flags = ADDR_TYPE_RT |
| 1920 | 1925 | }, |
| 1921 | 1926 | }; |
| @@ -2141,6 +2141,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio1_slaves[] = { · 2140 unmodified lines | ||
| 2141 | 2141 | |
| 2142 | 2142 | static struct omap_hwmod omap3xxx_gpio1_hwmod = { |
| 2143 | 2143 | .name = "gpio1", |
| 2144 | + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, | |
| 2144 | 2145 | .mpu_irqs = omap3xxx_gpio1_irqs, |
| 2145 | 2146 | .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio1_irqs), |
| 2146 | 2147 | .main_clk = "gpio1_ick", |
| @@ -2177,6 +2178,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio2_slaves[] = { · 30 unmodified lines | ||
| 2177 | 2178 | |
| 2178 | 2179 | static struct omap_hwmod omap3xxx_gpio2_hwmod = { |
| 2179 | 2180 | .name = "gpio2", |
| 2181 | + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, | |
| 2180 | 2182 | .mpu_irqs = omap3xxx_gpio2_irqs, |
| 2181 | 2183 | .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio2_irqs), |
| 2182 | 2184 | .main_clk = "gpio2_ick", |
| @@ -2213,6 +2215,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio3_slaves[] = { · 30 unmodified lines | ||
| 2213 | 2215 | |
| 2214 | 2216 | static struct omap_hwmod omap3xxx_gpio3_hwmod = { |
| 2215 | 2217 | .name = "gpio3", |
| 2218 | + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, | |
| 2216 | 2219 | .mpu_irqs = omap3xxx_gpio3_irqs, |
| 2217 | 2220 | .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio3_irqs), |
| 2218 | 2221 | .main_clk = "gpio3_ick", |
| @@ -2249,6 +2252,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio4_slaves[] = { · 30 unmodified lines | ||
| 2249 | 2252 | |
| 2250 | 2253 | static struct omap_hwmod omap3xxx_gpio4_hwmod = { |
| 2251 | 2254 | .name = "gpio4", |
| 2255 | + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, | |
| 2252 | 2256 | .mpu_irqs = omap3xxx_gpio4_irqs, |
| 2253 | 2257 | .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio4_irqs), |
| 2254 | 2258 | .main_clk = "gpio4_ick", |
| @@ -2285,6 +2289,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio5_slaves[] = { · 30 unmodified lines | ||
| 2285 | 2289 | |
| 2286 | 2290 | static struct omap_hwmod omap3xxx_gpio5_hwmod = { |
| 2287 | 2291 | .name = "gpio5", |
| 2292 | + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, | |
| 2288 | 2293 | .mpu_irqs = omap3xxx_gpio5_irqs, |
| 2289 | 2294 | .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio5_irqs), |
| 2290 | 2295 | .main_clk = "gpio5_ick", |
| @@ -2321,6 +2326,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_gpio6_slaves[] = { · 30 unmodified lines | ||
| 2321 | 2326 | |
| 2322 | 2327 | static struct omap_hwmod omap3xxx_gpio6_hwmod = { |
| 2323 | 2328 | .name = "gpio6", |
| 2329 | + .flags = HWMOD_CONTROL_OPT_CLKS_IN_RESET, | |
| 2324 | 2330 | .mpu_irqs = omap3xxx_gpio6_irqs, |
| 2325 | 2331 | .mpu_irqs_cnt = ARRAY_SIZE(omap3xxx_gpio6_irqs), |
| 2326 | 2332 | .main_clk = "gpio6_ick", |
| @@ -2386,7 +2392,7 @@ static struct omap_hwmod_irq_info omap3xxx_dma_system_irqs[] = { · 59 unmodified lines | ||
| 2386 | 2392 | static struct omap_hwmod_addr_space omap3xxx_dma_system_addrs[] = { |
| 2387 | 2393 | { |
| 2388 | 2394 | .pa_start = 0x48056000, |
| 2389 | − .pa_end = 0x4a0560ff, | |
| 2395 | + .pa_end = 0x48056fff, | |
| 2390 | 2396 | .flags = ADDR_TYPE_RT |
| 2391 | 2397 | }, |
| 2392 | 2398 | }; |
| @@ -885,7 +885,7 @@ static struct omap_hwmod_ocp_if *omap44xx_dma_system_masters[] = { · 884 unmodified lines | ||
| 885 | 885 | static struct omap_hwmod_addr_space omap44xx_dma_system_addrs[] = { |
| 886 | 886 | { |
| 887 | 887 | .pa_start = 0x4a056000, |
| 888 | − .pa_end = 0x4a0560ff, | |
| 888 | + .pa_end = 0x4a056fff, | |
| 889 | 889 | .flags = ADDR_TYPE_RT |
| 890 | 890 | }, |
| 891 | 891 | }; |
| @@ -196,11 +196,11 @@ static irqreturn_t omap3_l3_app_irq(int irq, void *_l3) · 195 unmodified lines | ||
| 196 | 196 | /* No timeout error for debug sources */ |
| 197 | 197 | } |
| 198 | 198 | |
| 199 | − base = ((l3->rt) + (*(omap3_l3_bases[int_type] + err_source))); | |
| 200 | − | |
| 201 | 199 | /* identify the error source */ |
| 202 | 200 | for (err_source = 0; !(status & (1 << err_source)); err_source++) |
| 203 | 201 | ; |
| 202 | + | |
| 203 | + base = l3->rt + *(omap3_l3_bases[int_type] + err_source); | |
| 204 | 204 | error = omap3_l3_readll(base, L3_ERROR_LOG); |
| 205 | 205 | |
| 206 | 206 | if (error) { |
| @@ -89,6 +89,7 @@ static void omap2_init_processor_devices(void) · 88 unmodified lines | ||
| 89 | 89 | if (cpu_is_omap44xx()) { |
| 90 | 90 | _init_omap_device("l3_main_1", &l3_dev); |
| 91 | 91 | _init_omap_device("dsp", &dsp_dev); |
| 92 | + _init_omap_device("iva", &iva_dev); | |
| 92 | 93 | } else { |
| 93 | 94 | _init_omap_device("l3_main", &l3_dev); |
| 94 | 95 | } |
| @@ -114,7 +114,6 @@ static int __init _config_common_vdd_data(struct omap_vdd_info *vdd) · 113 unmodified lines | ||
| 114 | 114 | sys_clk_speed /= 1000; |
| 115 | 115 | |
| 116 | 116 | /* Generic voltage parameters */ |
| 117 | − vdd->curr_volt = 1200000; | |
| 118 | 117 | vdd->volt_scale = vp_forceupdate_scale_voltage; |
| 119 | 118 | vdd->vp_enabled = false; |
| 120 | 119 | |
| @@ -711,7 +711,7 @@ static struct regulator_consumer_supply bq24022_consumers[] = { · 710 unmodified lines | ||
| 711 | 711 | static struct regulator_init_data bq24022_init_data = { |
| 712 | 712 | .constraints = { |
| 713 | 713 | .max_uA = 500000, |
| 714 | − .valid_ops_mask = REGULATOR_CHANGE_CURRENT, | |
| 714 | + .valid_ops_mask = REGULATOR_CHANGE_CURRENT|REGULATOR_CHANGE_STATUS, | |
| 715 | 715 | }, |
| 716 | 716 | .num_consumer_supplies = ARRAY_SIZE(bq24022_consumers), |
| 717 | 717 | .consumer_supplies = bq24022_consumers, |
| @@ -599,7 +599,7 @@ static struct regulator_consumer_supply bq24022_consumers[] = { · 598 unmodified lines | ||
| 599 | 599 | static struct regulator_init_data bq24022_init_data = { |
| 600 | 600 | .constraints = { |
| 601 | 601 | .max_uA = 500000, |
| 602 | − .valid_ops_mask = REGULATOR_CHANGE_CURRENT, | |
| 602 | + .valid_ops_mask = REGULATOR_CHANGE_CURRENT | REGULATOR_CHANGE_STATUS, | |
| 603 | 603 | }, |
| 604 | 604 | .num_consumer_supplies = ARRAY_SIZE(bq24022_consumers), |
| 605 | 605 | .consumer_supplies = bq24022_consumers, |
| @@ -4,5 +4,5 @@ · 3 unmodified lines | ||
| 4 | 4 | * operation to deadlock the system. |
| 5 | 5 | */ |
| 6 | 6 | #define mb() dsb() |
| 7 | −#define rmb() dmb() | |
| 7 | +#define rmb() dsb() | |
| 8 | 8 | #define wmb() mb() |
| @@ -409,6 +409,10 @@ struct platform_device s3c24xx_pwm_device = { · 408 unmodified lines | ||
| 409 | 409 | .num_resources = 0, |
| 410 | 410 | }; |
| 411 | 411 | |
| 412 | +static struct platform_device gta02_dfbmcs320_device = { | |
| 413 | + .name = "dfbmcs320", | |
| 414 | +}; | |
| 415 | + | |
| 412 | 416 | static struct i2c_board_info gta02_i2c_devs[] __initdata = { |
| 413 | 417 | { |
| 414 | 418 | I2C_BOARD_INFO("pcf50633", 0x73), |
| @@ -523,6 +527,7 @@ static struct platform_device *gta02_devices[] __initdata = { · 108 unmodified lines | ||
| 523 | 527 | &s3c_device_iis, |
| 524 | 528 | &samsung_asoc_dma, |
| 525 | 529 | &s3c_device_i2c0, |
| 530 | + >a02_dfbmcs320_device, | |
| 526 | 531 | >a02_buttons_device, |
| 527 | 532 | &s3c_device_adc, |
| 528 | 533 | &s3c_device_ts, |
| @@ -23,7 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | |
| 24 | 24 | #include <asm/outercache.h> |
| 25 | 25 | |
| 26 | −#define rmb() dmb() | |
| 26 | +#define rmb() dsb() | |
| 27 | 27 | #define wmb() do { dsb(); outer_sync(); } while (0) |
| 28 | 28 | #define mb() wmb() |
| 29 | 29 | |
| @@ -178,16 +178,15 @@ static struct i2c_board_info __initdata mop500_i2c0_devices[] = { · 177 unmodified lines | ||
| 178 | 178 | .irq = NOMADIK_GPIO_TO_IRQ(217), |
| 179 | 179 | .platform_data = &mop500_tc35892_data, |
| 180 | 180 | }, |
| 181 | −}; | |
| 182 | − | |
| 183 | −/* I2C0 devices only available prior to HREFv60 */ | |
| 184 | −static struct i2c_board_info __initdata mop500_i2c0_old_devices[] = { | |
| 181 | + /* I2C0 devices only available prior to HREFv60 */ | |
| 185 | 182 | { |
| 186 | 183 | I2C_BOARD_INFO("tps61052", 0x33), |
| 187 | 184 | .platform_data = &mop500_tps61052_data, |
| 188 | 185 | }, |
| 189 | 186 | }; |
| 190 | 187 | |
| 188 | +#define NUM_PRE_V60_I2C0_DEVICES 1 | |
| 189 | + | |
| 191 | 190 | static struct i2c_board_info __initdata mop500_i2c2_devices[] = { |
| 192 | 191 | { |
| 193 | 192 | /* lp5521 LED driver, 1st device */ |
| @@ -425,6 +424,8 @@ static void __init mop500_uart_init(void) · 231 unmodified lines | ||
| 425 | 424 | |
| 426 | 425 | static void __init mop500_init_machine(void) |
| 427 | 426 | { |
| 427 | + int i2c0_devs; | |
| 428 | + | |
| 428 | 429 | /* |
| 429 | 430 | * The HREFv60 board removed a GPIO expander and routed |
| 430 | 431 | * all these GPIO pins to the internal GPIO controller |
| @@ -448,11 +449,11 @@ static void __init mop500_init_machine(void) · 17 unmodified lines | ||
| 448 | 449 | |
| 449 | 450 | platform_device_register(&ab8500_device); |
| 450 | 451 | |
| 451 | − i2c_register_board_info(0, mop500_i2c0_devices, | |
| 452 | − ARRAY_SIZE(mop500_i2c0_devices)); | |
| 453 | − if (!machine_is_hrefv60()) | |
| 454 | − i2c_register_board_info(0, mop500_i2c0_old_devices, | |
| 455 | − ARRAY_SIZE(mop500_i2c0_old_devices)); | |
| 452 | + i2c0_devs = ARRAY_SIZE(mop500_i2c0_devices); | |
| 453 | + if (machine_is_hrefv60()) | |
| 454 | + i2c0_devs -= NUM_PRE_V60_I2C0_DEVICES; | |
| 455 | + | |
| 456 | + i2c_register_board_info(0, mop500_i2c0_devices, i2c0_devs); | |
| 456 | 457 | i2c_register_board_info(2, mop500_i2c2_devices, |
| 457 | 458 | ARRAY_SIZE(mop500_i2c2_devices)); |
| 458 | 459 | } |
| @@ -392,7 +392,7 @@ free_memmap(unsigned long start_pfn, unsigned long end_pfn) · 391 unmodified lines | ||
| 392 | 392 | * Convert start_pfn/end_pfn to a struct page pointer. |
| 393 | 393 | */ |
| 394 | 394 | start_pg = pfn_to_page(start_pfn - 1) + 1; |
| 395 | − end_pg = pfn_to_page(end_pfn); | |
| 395 | + end_pg = pfn_to_page(end_pfn - 1) + 1; | |
| 396 | 396 | |
| 397 | 397 | /* |
| 398 | 398 | * Convert to physical addresses, and |
| @@ -426,6 +426,14 @@ static void __init free_unused_memmap(struct meminfo *mi) · 27 unmodified lines | ||
| 426 | 426 | |
| 427 | 427 | bank_start = bank_pfn_start(bank); |
| 428 | 428 | |
| 429 | +#ifdef CONFIG_SPARSEMEM | |
| 430 | + /* | |
| 431 | + * Take care not to free memmap entries that don't exist | |
| 432 | + * due to SPARSEMEM sections which aren't present. | |
| 433 | + */ | |
| 434 | + bank_start = min(bank_start, | |
| 435 | + ALIGN(prev_bank_end, PAGES_PER_SECTION)); | |
| 436 | +#endif | |
| 429 | 437 | /* |
| 430 | 438 | * If we had a previous bank, and there is a space |
| 431 | 439 | * between the current bank and the previous, free it. |
| @@ -440,6 +448,12 @@ static void __init free_unused_memmap(struct meminfo *mi) · 8 unmodified lines | ||
| 440 | 448 | */ |
| 441 | 449 | prev_bank_end = ALIGN(bank_pfn_end(bank), MAX_ORDER_NR_PAGES); |
| 442 | 450 | } |
| 451 | + | |
| 452 | +#ifdef CONFIG_SPARSEMEM | |
| 453 | + if (!IS_ALIGNED(prev_bank_end, PAGES_PER_SECTION)) | |
| 454 | + free_memmap(prev_bank_end, | |
| 455 | + ALIGN(prev_bank_end, PAGES_PER_SECTION)); | |
| 456 | +#endif | |
| 443 | 457 | } |
| 444 | 458 | |
| 445 | 459 | static void __init free_highpages(void) |
| @@ -395,7 +395,7 @@ ENTRY(xscale_dma_a0_map_area) · 394 unmodified lines | ||
| 395 | 395 | teq r2, #DMA_TO_DEVICE |
| 396 | 396 | beq xscale_dma_clean_range |
| 397 | 397 | b xscale_dma_flush_range |
| 398 | −ENDPROC(xscsale_dma_a0_map_area) | |
| 398 | +ENDPROC(xscale_dma_a0_map_area) | |
| 399 | 399 | |
| 400 | 400 | /* |
| 401 | 401 | * dma_unmap_area(start, size, dir) |
| @@ -295,6 +295,12 @@ static int mxc_gpio_direction_output(struct gpio_chip *chip, · 294 unmodified lines | ||
| 295 | 295 | return 0; |
| 296 | 296 | } |
| 297 | 297 | |
| 298 | +/* | |
| 299 | + * This lock class tells lockdep that GPIO irqs are in a different | |
| 300 | + * category than their parents, so it won't report false recursion. | |
| 301 | + */ | |
| 302 | +static struct lock_class_key gpio_lock_class; | |
| 303 | + | |
| 298 | 304 | int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt) |
| 299 | 305 | { |
| 300 | 306 | int i, j; |
| @@ -311,6 +317,7 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt) · 10 unmodified lines | ||
| 311 | 317 | __raw_writel(~0, port[i].base + GPIO_ISR); |
| 312 | 318 | for (j = port[i].virtual_irq_start; |
| 313 | 319 | j < port[i].virtual_irq_start + 32; j++) { |
| 320 | + irq_set_lockdep_class(j, &gpio_lock_class); | |
| 314 | 321 | irq_set_chip_and_handler(j, &gpio_irq_chip, |
| 315 | 322 | handle_level_irq); |
| 316 | 323 | set_irq_flags(j, IRQF_VALID); |
| @@ -124,6 +124,8 @@ imx_ssi_fiq_start: · 123 unmodified lines | ||
| 124 | 124 | 1: |
| 125 | 125 | @ return from FIQ |
| 126 | 126 | subs pc, lr, #4 |
| 127 | + | |
| 128 | + .align | |
| 127 | 129 | imx_ssi_fiq_base: |
| 128 | 130 | .word 0x0 |
| 129 | 131 | imx_ssi_fiq_rx_buffer: |
| @@ -793,6 +793,8 @@ static irqreturn_t iommu_fault_handler(int irq, void *data) · 792 unmodified lines | ||
| 793 | 793 | clk_enable(obj->clk); |
| 794 | 794 | errs = iommu_report_fault(obj, &da); |
| 795 | 795 | clk_disable(obj->clk); |
| 796 | + if (errs == 0) | |
| 797 | + return IRQ_HANDLED; | |
| 796 | 798 | |
| 797 | 799 | /* Fault callback or TLB/PTE Dynamic loading */ |
| 798 | 800 | if (obj->isr && !obj->isr(obj, da, errs, obj->isr_priv)) |
| @@ -300,6 +300,8 @@ void __init paging_init(void) · 299 unmodified lines | ||
| 300 | 300 | zones_size[ZONE_DMA] = m68k_memory[i].size >> PAGE_SHIFT; |
| 301 | 301 | free_area_init_node(i, zones_size, |
| 302 | 302 | m68k_memory[i].addr >> PAGE_SHIFT, NULL); |
| 303 | + if (node_present_pages(i)) | |
| 304 | + node_set_state(i, N_NORMAL_MEMORY); | |
| 303 | 305 | } |
| 304 | 306 | } |
| 305 | 307 | |
| @@ -997,9 +997,6 @@ config IRQ_GT641XX · 996 unmodified lines | ||
| 997 | 997 | config IRQ_GIC |
| 998 | 998 | bool |
| 999 | 999 | |
| 1000 | −config IRQ_CPU_OCTEON | |
| 1001 | − bool | |
| 1002 | − | |
| 1003 | 1000 | config MIPS_BOARDS_GEN |
| 1004 | 1001 | bool |
| 1005 | 1002 | |
| @@ -1359,8 +1356,6 @@ config CPU_SB1 · 353 unmodified lines | ||
| 1359 | 1356 | config CPU_CAVIUM_OCTEON |
| 1360 | 1357 | bool "Cavium Octeon processor" |
| 1361 | 1358 | depends on SYS_HAS_CPU_CAVIUM_OCTEON |
| 1362 | − select IRQ_CPU | |
| 1363 | − select IRQ_CPU_OCTEON | |
| 1364 | 1359 | select CPU_HAS_PREFETCH |
| 1365 | 1360 | select CPU_SUPPORTS_64BIT_KERNEL |
| 1366 | 1361 | select SYS_SUPPORTS_SMP |
| @@ -127,13 +127,10 @@ const char *get_system_type(void) · 126 unmodified lines | ||
| 127 | 127 | void __init board_setup(void) |
| 128 | 128 | { |
| 129 | 129 | unsigned long bcsr1, bcsr2; |
| 130 | − u32 pin_func; | |
| 131 | 130 | |
| 132 | 131 | bcsr1 = DB1000_BCSR_PHYS_ADDR; |
| 133 | 132 | bcsr2 = DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS; |
| 134 | 133 | |
| 135 | − pin_func = 0; | |
| 136 | − | |
| 137 | 134 | #ifdef CONFIG_MIPS_DB1000 |
| 138 | 135 | printk(KERN_INFO "AMD Alchemy Au1000/Db1000 Board\n"); |
| 139 | 136 | #endif |
| @@ -164,12 +161,16 @@ void __init board_setup(void) · 24 unmodified lines | ||
| 164 | 161 | /* Not valid for Au1550 */ |
| 165 | 162 | #if defined(CONFIG_IRDA) && \ |
| 166 | 163 | (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100)) |
| 167 | − /* Set IRFIRSEL instead of GPIO15 */ | |
| 168 | − pin_func = au_readl(SYS_PINFUNC) | SYS_PF_IRF; | |
| 169 | − au_writel(pin_func, SYS_PINFUNC); | |
| 170 | − /* Power off until the driver is in use */ | |
| 171 | − bcsr_mod(BCSR_RESETS, BCSR_RESETS_IRDA_MODE_MASK, | |
| 172 | − BCSR_RESETS_IRDA_MODE_OFF); | |
| 164 | + { | |
| 165 | + u32 pin_func; | |
| 166 | + | |
| 167 | + /* Set IRFIRSEL instead of GPIO15 */ | |
| 168 | + pin_func = au_readl(SYS_PINFUNC) | SYS_PF_IRF; | |
| 169 | + au_writel(pin_func, SYS_PINFUNC); | |
| 170 | + /* Power off until the driver is in use */ | |
| 171 | + bcsr_mod(BCSR_RESETS, BCSR_RESETS_IRDA_MODE_MASK, | |
| 172 | + BCSR_RESETS_IRDA_MODE_OFF); | |
| 173 | + } | |
| 173 | 174 | #endif |
| 174 | 175 | bcsr_write(BCSR_PCMCIA, 0); /* turn off PCMCIA power */ |
| 175 | 176 | |
| @@ -177,31 +178,35 @@ void __init board_setup(void) · 1 unmodified line | ||
| 177 | 178 | alchemy_gpio1_input_enable(); |
| 178 | 179 | |
| 179 | 180 | #ifdef CONFIG_MIPS_MIRAGE |
| 180 | − /* GPIO[20] is output */ | |
| 181 | − alchemy_gpio_direction_output(20, 0); | |
| 181 | + { | |
| 182 | + u32 pin_func; | |
| 182 | 183 | |
| 183 | − /* Set GPIO[210:208] instead of SSI_0 */ | |
| 184 | − pin_func = au_readl(SYS_PINFUNC) | SYS_PF_S0; | |
| 184 | + /* GPIO[20] is output */ | |
| 185 | + alchemy_gpio_direction_output(20, 0); | |
| 185 | 186 | |
| 186 | − /* Set GPIO[215:211] for LEDs */ | |
| 187 | − pin_func |= 5 << 2; | |
| 187 | + /* Set GPIO[210:208] instead of SSI_0 */ | |
| 188 | + pin_func = au_readl(SYS_PINFUNC) | SYS_PF_S0; | |
| 188 | 189 | |
| 189 | − /* Set GPIO[214:213] for more LEDs */ | |
| 190 | − pin_func |= 5 << 12; | |
| 190 | + /* Set GPIO[215:211] for LEDs */ | |
| 191 | + pin_func |= 5 << 2; | |
| 191 | 192 | |
| 192 | − /* Set GPIO[207:200] instead of PCMCIA/LCD */ | |
| 193 | − pin_func |= SYS_PF_LCD | SYS_PF_PC; | |
| 194 | − au_writel(pin_func, SYS_PINFUNC); | |
| 193 | + /* Set GPIO[214:213] for more LEDs */ | |
| 194 | + pin_func |= 5 << 12; | |
| 195 | 195 | |
| 196 | − /* | |
| 197 | − * Enable speaker amplifier. This should | |
| 198 | − * be part of the audio driver. | |
| 199 | − */ | |
| 200 | − alchemy_gpio_direction_output(209, 1); | |
| 196 | + /* Set GPIO[207:200] instead of PCMCIA/LCD */ | |
| 197 | + pin_func |= SYS_PF_LCD | SYS_PF_PC; | |
| 198 | + au_writel(pin_func, SYS_PINFUNC); | |
| 201 | 199 | |
| 202 | − pm_power_off = mirage_power_off; | |
| 203 | − _machine_halt = mirage_power_off; | |
| 204 | − _machine_restart = (void(*)(char *))mips_softreset; | |
| 200 | + /* | |
| 201 | + * Enable speaker amplifier. This should | |
| 202 | + * be part of the audio driver. | |
| 203 | + */ | |
| 204 | + alchemy_gpio_direction_output(209, 1); | |
| 205 | + | |
| 206 | + pm_power_off = mirage_power_off; | |
| 207 | + _machine_halt = mirage_power_off; | |
| 208 | + _machine_restart = (void(*)(char *))mips_softreset; | |
| 209 | + } | |
| 205 | 210 | #endif |
| 206 | 211 | |
| 207 | 212 | #ifdef CONFIG_MIPS_BOSPORUS |
| @@ -51,10 +51,9 @@ void __init prom_init(void) · 50 unmodified lines | ||
| 51 | 51 | prom_init_cmdline(); |
| 52 | 52 | |
| 53 | 53 | memsize_str = prom_getenv("memsize"); |
| 54 | − if (!memsize_str) | |
| 54 | + if (!memsize_str || strict_strtoul(memsize_str, 0, &memsize)) | |
| 55 | 55 | memsize = 0x04000000; |
| 56 | − else | |
| 57 | − strict_strtoul(memsize_str, 0, &memsize); | |
| 56 | + | |
| 58 | 57 | add_memory_region(0, memsize, BOOT_MEM_RAM); |
| 59 | 58 | } |
| 60 | 59 | |
| @@ -325,9 +325,7 @@ int __init ar7_gpio_init(void) · 324 unmodified lines | ||
| 325 | 325 | size = 0x1f; |
| 326 | 326 | } |
| 327 | 327 | |
| 328 | − gpch->regs = ioremap_nocache(AR7_REGS_GPIO, | |
| 329 | − AR7_REGS_GPIO + 0x10); | |
| 330 | − | |
| 328 | + gpch->regs = ioremap_nocache(AR7_REGS_GPIO, size); | |
| 331 | 329 | if (!gpch->regs) { |
| 332 | 330 | printk(KERN_ERR "%s: failed to ioremap regs\n", |
| 333 | 331 | gpch->chip.label); |
| @@ -16,8 +16,8 @@ · 15 unmodified lines | ||
| 16 | 16 | |
| 17 | 17 | int main(int argc, char *argv[]) |
| 18 | 18 | { |
| 19 | + unsigned long long vmlinux_size, vmlinux_load_addr, vmlinuz_load_addr; | |
| 19 | 20 | struct stat sb; |
| 20 | − uint64_t vmlinux_size, vmlinux_load_addr, vmlinuz_load_addr; | |
| 21 | 21 | |
| 22 | 22 | if (argc != 3) { |
| 23 | 23 | fprintf(stderr, "Usage: %s <pathname> <vmlinux_load_addr>\n", |
| @@ -1,11 +1,7 @@ | ||
| 1 | −config CAVIUM_OCTEON_SPECIFIC_OPTIONS | |
| 2 | − bool "Enable Octeon specific options" | |
| 3 | − depends on CPU_CAVIUM_OCTEON | |
| 4 | − default "y" | |
| 1 | +if CPU_CAVIUM_OCTEON | |
| 5 | 2 | |
| 6 | 3 | config CAVIUM_CN63XXP1 |
| 7 | 4 | bool "Enable CN63XXP1 errata worarounds" |
| 8 | − depends on CAVIUM_OCTEON_SPECIFIC_OPTIONS | |
| 9 | 5 | default "n" |
| 10 | 6 | help |
| 11 | 7 | The CN63XXP1 chip requires build time workarounds to |
| @@ -16,7 +12,6 @@ config CAVIUM_CN63XXP1 · 4 unmodified lines | ||
| 16 | 12 | |
| 17 | 13 | config CAVIUM_OCTEON_2ND_KERNEL |
| 18 | 14 | bool "Build the kernel to be used as a 2nd kernel on the same chip" |
| 19 | − depends on CAVIUM_OCTEON_SPECIFIC_OPTIONS | |
| 20 | 15 | default "n" |
| 21 | 16 | help |
| 22 | 17 | This option configures this kernel to be linked at a different |
| @@ -26,7 +21,6 @@ config CAVIUM_OCTEON_2ND_KERNEL · 3 unmodified lines | ||
| 26 | 21 | |
| 27 | 22 | config CAVIUM_OCTEON_HW_FIX_UNALIGNED |
| 28 | 23 | bool "Enable hardware fixups of unaligned loads and stores" |
| 29 | − depends on CAVIUM_OCTEON_SPECIFIC_OPTIONS | |
| 30 | 24 | default "y" |
| 31 | 25 | help |
| 32 | 26 | Configure the Octeon hardware to automatically fix unaligned loads |
| @@ -38,7 +32,6 @@ config CAVIUM_OCTEON_HW_FIX_UNALIGNED · 5 unmodified lines | ||
| 38 | 32 | |
| 39 | 33 | config CAVIUM_OCTEON_CVMSEG_SIZE |
| 40 | 34 | int "Number of L1 cache lines reserved for CVMSEG memory" |
| 41 | − depends on CAVIUM_OCTEON_SPECIFIC_OPTIONS | |
| 42 | 35 | range 0 54 |
| 43 | 36 | default 1 |
| 44 | 37 | help |
| @@ -50,7 +43,6 @@ config CAVIUM_OCTEON_CVMSEG_SIZE · 5 unmodified lines | ||
| 50 | 43 | |
| 51 | 44 | config CAVIUM_OCTEON_LOCK_L2 |
| 52 | 45 | bool "Lock often used kernel code in the L2" |
| 53 | − depends on CAVIUM_OCTEON_SPECIFIC_OPTIONS | |
| 54 | 46 | default "y" |
| 55 | 47 | help |
| 56 | 48 | Enable locking parts of the kernel into the L2 cache. |
| @@ -93,7 +85,6 @@ config CAVIUM_OCTEON_LOCK_L2_MEMCPY · 36 unmodified lines | ||
| 93 | 85 | config ARCH_SPARSEMEM_ENABLE |
| 94 | 86 | def_bool y |
| 95 | 87 | select SPARSEMEM_STATIC |
| 96 | − depends on CPU_CAVIUM_OCTEON | |
| 97 | 88 | |
| 98 | 89 | config CAVIUM_OCTEON_HELPER |
| 99 | 90 | def_bool y |
| @@ -107,6 +98,8 @@ config NEED_SG_DMA_LENGTH · 7 unmodified lines | ||
| 107 | 98 | |
| 108 | 99 | config SWIOTLB |
| 109 | 100 | def_bool y |
| 110 | − depends on CPU_CAVIUM_OCTEON | |
| 111 | 101 | select IOMMU_HELPER |
| 112 | 102 | select NEED_SG_DMA_LENGTH |
| 103 | + | |
| 104 | + | |
| 105 | +endif # CPU_CAVIUM_OCTEON | |
| @@ -17,6 +17,6 @@ · 16 unmodified lines | ||
| 17 | 17 | #define SMP_CACHE_SHIFT L1_CACHE_SHIFT |
| 18 | 18 | #define SMP_CACHE_BYTES L1_CACHE_BYTES |
| 19 | 19 | |
| 20 | −#define __read_mostly __attribute__((__section__(".data.read_mostly"))) | |
| 20 | +#define __read_mostly __attribute__((__section__(".data..read_mostly"))) | |
| 21 | 21 | |
| 22 | 22 | #endif /* _ASM_CACHE_H */ |
| @@ -14,6 +14,9 @@ · 13 unmodified lines | ||
| 14 | 14 | #ifndef __ASM_CEVT_R4K_H |
| 15 | 15 | #define __ASM_CEVT_R4K_H |
| 16 | 16 | |
| 17 | +#include <linux/clockchips.h> | |
| 18 | +#include <asm/time.h> | |
| 19 | + | |
| 17 | 20 | DECLARE_PER_CPU(struct clock_event_device, mips_clockevent_device); |
| 18 | 21 | |
| 19 | 22 | void mips_event_handler(struct clock_event_device *dev); |
| @@ -5,7 +5,9 @@ · 4 unmodified lines | ||
| 5 | 5 | #include <asm/cache.h> |
| 6 | 6 | #include <asm-generic/dma-coherent.h> |
| 7 | 7 | |
| 8 | +#ifndef CONFIG_SGI_IP27 /* Kludge to fix 2.6.39 build for IP27 */ | |
| 8 | 9 | #include <dma-coherence.h> |
| 10 | +#endif | |
| 9 | 11 | |
| 10 | 12 | extern struct dma_map_ops *mips_dma_map_ops; |
| 11 | 13 | |
| @@ -70,6 +70,7 @@ static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, · 69 unmodified lines | ||
| 70 | 70 | static inline void huge_ptep_clear_flush(struct vm_area_struct *vma, |
| 71 | 71 | unsigned long addr, pte_t *ptep) |
| 72 | 72 | { |
| 73 | + flush_tlb_mm(vma->vm_mm); | |
| 73 | 74 | } |
| 74 | 75 | |
| 75 | 76 | static inline int huge_pte_none(pte_t pte) |
| @@ -88,7 +88,7 @@ struct bcm_tag { · 87 unmodified lines | ||
| 88 | 88 | char kernel_crc[CRC_LEN]; |
| 89 | 89 | /* 228-235: Unused at present */ |
| 90 | 90 | char reserved1[8]; |
| 91 | − /* 236-239: CRC32 of header excluding tagVersion */ | |
| 91 | + /* 236-239: CRC32 of header excluding last 20 bytes */ | |
| 92 | 92 | char header_crc[CRC_LEN]; |
| 93 | 93 | /* 240-255: Unused at present */ |
| 94 | 94 | char reserved2[16]; |
| @@ -211,7 +211,7 @@ EXPORT_SYMBOL(vdma_free); · 210 unmodified lines | ||
| 211 | 211 | */ |
| 212 | 212 | int vdma_remap(unsigned long laddr, unsigned long paddr, unsigned long size) |
| 213 | 213 | { |
| 214 | − int first, pages, npages; | |
| 214 | + int first, pages; | |
| 215 | 215 | |
| 216 | 216 | if (laddr > 0xffffff) { |
| 217 | 217 | if (vdma_debug) |
| @@ -228,8 +228,7 @@ int vdma_remap(unsigned long laddr, unsigned long paddr, unsigned long size) · 10 unmodified lines | ||
| 228 | 228 | return -EINVAL; /* invalid physical address */ |
| 229 | 229 | } |
| 230 | 230 | |
| 231 | − npages = pages = | |
| 232 | − (((paddr & (VDMA_PAGESIZE - 1)) + size) >> 12) + 1; | |
| 231 | + pages = (((paddr & (VDMA_PAGESIZE - 1)) + size) >> 12) + 1; | |
| 233 | 232 | first = laddr >> 12; |
| 234 | 233 | if (vdma_debug) |
| 235 | 234 | printk("vdma_remap: first=%x, pages=%x\n", first, pages); |
| @@ -242,9 +242,7 @@ EXPORT_SYMBOL_GPL(jz4740_dma_get_residue); · 241 unmodified lines | ||
| 242 | 242 | |
| 243 | 243 | static void jz4740_dma_chan_irq(struct jz4740_dma_chan *dma) |
| 244 | 244 | { |
| 245 | − uint32_t status; | |
| 246 | − | |
| 247 | − status = jz4740_dma_read(JZ_REG_DMA_STATUS_CTRL(dma->id)); | |
| 245 | + (void) jz4740_dma_read(JZ_REG_DMA_STATUS_CTRL(dma->id)); | |
| 248 | 246 | |
| 249 | 247 | jz4740_dma_write_mask(JZ_REG_DMA_STATUS_CTRL(dma->id), 0, |
| 250 | 248 | JZ_DMA_STATUS_CTRL_ENABLE | JZ_DMA_STATUS_CTRL_TRANSFER_DONE); |
| @@ -89,7 +89,7 @@ static int jz4740_clockevent_set_next(unsigned long evt, · 88 unmodified lines | ||
| 89 | 89 | |
| 90 | 90 | static struct clock_event_device jz4740_clockevent = { |
| 91 | 91 | .name = "jz4740-timer", |
| 92 | − .features = CLOCK_EVT_FEAT_PERIODIC, | |
| 92 | + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | |
| 93 | 93 | .set_next_event = jz4740_clockevent_set_next, |
| 94 | 94 | .set_mode = jz4740_clockevent_set_mode, |
| 95 | 95 | .rating = 200, |
| @@ -27,11 +27,13 @@ void jz4740_timer_enable_watchdog(void) · 26 unmodified lines | ||
| 27 | 27 | { |
| 28 | 28 | writel(BIT(16), jz4740_timer_base + JZ_REG_TIMER_STOP_CLEAR); |
| 29 | 29 | } |
| 30 | +EXPORT_SYMBOL_GPL(jz4740_timer_enable_watchdog); | |
| 30 | 31 | |
| 31 | 32 | void jz4740_timer_disable_watchdog(void) |
| 32 | 33 | { |
| 33 | 34 | writel(BIT(16), jz4740_timer_base + JZ_REG_TIMER_STOP_SET); |
| 34 | 35 | } |
| 36 | +EXPORT_SYMBOL_GPL(jz4740_timer_disable_watchdog); | |
| 35 | 37 | |
| 36 | 38 | void __init jz4740_timer_init(void) |
| 37 | 39 | { |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | |
| 24 | 24 | #define JAL 0x0c000000 /* jump & link: ip --> ra, jump to target */ |
| 25 | 25 | #define ADDR_MASK 0x03ffffff /* op_code|addr : 31...26|25 ....0 */ |
| 26 | +#define JUMP_RANGE_MASK ((1UL << 28) - 1) | |
| 26 | 27 | |
| 27 | 28 | #define INSN_NOP 0x00000000 /* nop */ |
| 28 | 29 | #define INSN_JAL(addr) \ |
| @@ -44,12 +45,12 @@ static inline void ftrace_dyn_arch_init_insns(void) · 15 unmodified lines | ||
| 44 | 45 | |
| 45 | 46 | /* jal (ftrace_caller + 8), jump over the first two instruction */ |
| 46 | 47 | buf = (u32 *)&insn_jal_ftrace_caller; |
| 47 | − uasm_i_jal(&buf, (FTRACE_ADDR + 8)); | |
| 48 | + uasm_i_jal(&buf, (FTRACE_ADDR + 8) & JUMP_RANGE_MASK); | |
| 48 | 49 | |
| 49 | 50 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER |
| 50 | 51 | /* j ftrace_graph_caller */ |
| 51 | 52 | buf = (u32 *)&insn_j_ftrace_graph_caller; |
| 52 | − uasm_i_j(&buf, (unsigned long)ftrace_graph_caller); | |
| 53 | + uasm_i_j(&buf, (unsigned long)ftrace_graph_caller & JUMP_RANGE_MASK); | |
| 53 | 54 | #endif |
| 54 | 55 | } |
| 55 | 56 | |
| @@ -540,8 +540,8 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) · 539 unmodified lines | ||
| 540 | 540 | secure_computing(regs->regs[2]); |
| 541 | 541 | |
| 542 | 542 | if (unlikely(current->audit_context) && entryexit) |
| 543 | − audit_syscall_exit(AUDITSC_RESULT(regs->regs[2]), | |
| 544 | − regs->regs[2]); | |
| 543 | + audit_syscall_exit(AUDITSC_RESULT(regs->regs[7]), | |
| 544 | + -regs->regs[2]); | |
| 545 | 545 | |
| 546 | 546 | if (!(current->ptrace & PT_PTRACED)) |
| 547 | 547 | goto out; |
| @@ -565,7 +565,7 @@ einval: li v0, -ENOSYS · 564 unmodified lines | ||
| 565 | 565 | sys sys_ioprio_get 2 /* 4315 */ |
| 566 | 566 | sys sys_utimensat 4 |
| 567 | 567 | sys sys_signalfd 3 |
| 568 | − sys sys_ni_syscall 0 | |
| 568 | + sys sys_ni_syscall 0 /* was timerfd */ | |
| 569 | 569 | sys sys_eventfd 1 |
| 570 | 570 | sys sys_fallocate 6 /* 4320 */ |
| 571 | 571 | sys sys_timerfd_create 2 |
| @@ -404,7 +404,7 @@ sys_call_table: · 403 unmodified lines | ||
| 404 | 404 | PTR sys_ioprio_get |
| 405 | 405 | PTR sys_utimensat /* 5275 */ |
| 406 | 406 | PTR sys_signalfd |
| 407 | − PTR sys_ni_syscall | |
| 407 | + PTR sys_ni_syscall /* was timerfd */ | |
| 408 | 408 | PTR sys_eventfd |
| 409 | 409 | PTR sys_fallocate |
| 410 | 410 | PTR sys_timerfd_create /* 5280 */ |
| @@ -403,7 +403,7 @@ EXPORT(sysn32_call_table) · 402 unmodified lines | ||
| 403 | 403 | PTR sys_ioprio_get |
| 404 | 404 | PTR compat_sys_utimensat |
| 405 | 405 | PTR compat_sys_signalfd /* 6280 */ |
| 406 | − PTR sys_ni_syscall | |
| 406 | + PTR sys_ni_syscall /* was timerfd */ | |
| 407 | 407 | PTR sys_eventfd |
| 408 | 408 | PTR sys_fallocate |
| 409 | 409 | PTR sys_timerfd_create |
| @@ -522,7 +522,7 @@ sys_call_table: · 521 unmodified lines | ||
| 522 | 522 | PTR sys_ioprio_get /* 4315 */ |
| 523 | 523 | PTR compat_sys_utimensat |
| 524 | 524 | PTR compat_sys_signalfd |
| 525 | − PTR sys_ni_syscall | |
| 525 | + PTR sys_ni_syscall /* was timerfd */ | |
| 526 | 526 | PTR sys_eventfd |
| 527 | 527 | PTR sys32_fallocate /* 4320 */ |
| 528 | 528 | PTR sys_timerfd_create |
| @@ -374,7 +374,8 @@ void __noreturn die(const char *str, struct pt_regs *regs) · 373 unmodified lines | ||
| 374 | 374 | unsigned long dvpret = dvpe(); |
| 375 | 375 | #endif /* CONFIG_MIPS_MT_SMTC */ |
| 376 | 376 | |
| 377 | − notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV); | |
| 377 | + if (notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV) == NOTIFY_STOP) | |
| 378 | + sig = 0; | |
| 378 | 379 | |
| 379 | 380 | console_verbose(); |
| 380 | 381 | spin_lock_irq(&die_lock); |
| @@ -383,9 +384,6 @@ void __noreturn die(const char *str, struct pt_regs *regs) · 2 unmodified lines | ||
| 383 | 384 | mips_mt_regdump(dvpret); |
| 384 | 385 | #endif /* CONFIG_MIPS_MT_SMTC */ |
| 385 | 386 | |
| 386 | − if (notify_die(DIE_OOPS, str, regs, 0, regs_to_trapnr(regs), SIGSEGV) == NOTIFY_STOP) | |
| 387 | − sig = 0; | |
| 388 | − | |
| 389 | 387 | printk("%s[#%d]:\n", str, ++die_counter); |
| 390 | 388 | show_registers(regs); |
| 391 | 389 | add_taint(TAINT_DIE); |
| @@ -74,6 +74,7 @@ SECTIONS · 73 unmodified lines | ||
| 74 | 74 | INIT_TASK_DATA(PAGE_SIZE) |
| 75 | 75 | NOSAVE_DATA |
| 76 | 76 | CACHELINE_ALIGNED_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT) |
| 77 | + READ_MOSTLY_DATA(1 << CONFIG_MIPS_L1_CACHE_SHIFT) | |
| 77 | 78 | DATA_DATA |
| 78 | 79 | CONSTRUCTORS |
| 79 | 80 | } |
| @@ -29,9 +29,10 @@ unsigned long memsize, highmemsize; · 28 unmodified lines | ||
| 29 | 29 | |
| 30 | 30 | #define parse_even_earlier(res, option, p) \ |
| 31 | 31 | do { \ |
| 32 | − int ret; \ | |
| 32 | + unsigned int tmp __maybe_unused; \ | |
| 33 | + \ | |
| 33 | 34 | if (strncmp(option, (char *)p, strlen(option)) == 0) \ |
| 34 | − ret = strict_strtol((char *)p + strlen(option"="), 10, &res); \ | |
| 35 | + tmp = strict_strtol((char *)p + strlen(option"="), 10, &res); \ | |
| 35 | 36 | } while (0) |
| 36 | 37 | |
| 37 | 38 | void __init prom_init_env(void) |
| @@ -1075,7 +1075,6 @@ static int __cpuinit probe_scache(void) · 1074 unmodified lines | ||
| 1075 | 1075 | unsigned long flags, addr, begin, end, pow2; |
| 1076 | 1076 | unsigned int config = read_c0_config(); |
| 1077 | 1077 | struct cpuinfo_mips *c = ¤t_cpu_data; |
| 1078 | − int tmp; | |
| 1079 | 1078 | |
| 1080 | 1079 | if (config & CONF_SC) |
| 1081 | 1080 | return 0; |
| @@ -1108,7 +1107,6 @@ static int __cpuinit probe_scache(void) · 26 unmodified lines | ||
| 1108 | 1107 | |
| 1109 | 1108 | /* Now search for the wrap around point. */ |
| 1110 | 1109 | pow2 = (128 * 1024); |
| 1111 | − tmp = 0; | |
| 1112 | 1110 | for (addr = begin + (128 * 1024); addr < end; addr = begin + pow2) { |
| 1113 | 1111 | cache_op(Index_Load_Tag_SD, addr); |
| 1114 | 1112 | __asm__ __volatile__("nop; nop; nop; nop;"); /* hazard... */ |
| @@ -1151,8 +1151,8 @@ static void __cpuinit build_r4000_tlb_refill_handler(void) · 1150 unmodified lines | ||
| 1151 | 1151 | struct uasm_reloc *r = relocs; |
| 1152 | 1152 | u32 *f; |
| 1153 | 1153 | unsigned int final_len; |
| 1154 | − struct mips_huge_tlb_info htlb_info; | |
| 1155 | − enum vmalloc64_mode vmalloc_mode; | |
| 1154 | + struct mips_huge_tlb_info htlb_info __maybe_unused; | |
| 1155 | + enum vmalloc64_mode vmalloc_mode __maybe_unused; | |
| 1156 | 1156 | |
| 1157 | 1157 | memset(tlb_handler, 0, sizeof(tlb_handler)); |
| 1158 | 1158 | memset(labels, 0, sizeof(labels)); |
| @@ -193,8 +193,6 @@ extern struct plat_smp_ops msmtc_smp_ops; · 192 unmodified lines | ||
| 193 | 193 | |
| 194 | 194 | void __init prom_init(void) |
| 195 | 195 | { |
| 196 | − int result; | |
| 197 | − | |
| 198 | 196 | prom_argc = fw_arg0; |
| 199 | 197 | _prom_argv = (int *) fw_arg1; |
| 200 | 198 | _prom_envp = (int *) fw_arg2; |
| @@ -360,20 +358,14 @@ void __init prom_init(void) · 159 unmodified lines | ||
| 360 | 358 | #ifdef CONFIG_SERIAL_8250_CONSOLE |
| 361 | 359 | console_config(); |
| 362 | 360 | #endif |
| 363 | − /* Early detection of CMP support */ | |
| 364 | − result = gcmp_probe(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ); | |
| 365 | − | |
| 366 | 361 | #ifdef CONFIG_MIPS_CMP |
| 367 | − if (result) | |
| 362 | + /* Early detection of CMP support */ | |
| 363 | + if (gcmp_probe(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ)) | |
| 368 | 364 | register_smp_ops(&cmp_smp_ops); |
| 365 | + else | |
| 369 | 366 | #endif |
| 370 | 367 | #ifdef CONFIG_MIPS_MT_SMP |
| 371 | −#ifdef CONFIG_MIPS_CMP | |
| 372 | − if (!result) | |
| 373 | 368 | register_smp_ops(&vsmp_smp_ops); |
| 374 | −#else | |
| 375 | − register_smp_ops(&vsmp_smp_ops); | |
| 376 | −#endif | |
| 377 | 369 | #endif |
| 378 | 370 | #ifdef CONFIG_MIPS_MT_SMTC |
| 379 | 371 | register_smp_ops(&msmtc_smp_ops); |
| @@ -56,7 +56,6 @@ static DEFINE_RAW_SPINLOCK(mips_irq_lock); · 55 unmodified lines | ||
| 56 | 56 | static inline int mips_pcibios_iack(void) |
| 57 | 57 | { |
| 58 | 58 | int irq; |
| 59 | − u32 dummy; | |
| 60 | 59 | |
| 61 | 60 | /* |
| 62 | 61 | * Determine highest priority pending interrupt by performing |
| @@ -83,7 +82,7 @@ static inline int mips_pcibios_iack(void) · 20 unmodified lines | ||
| 83 | 82 | BONITO_PCIMAP_CFG = 0x20000; |
| 84 | 83 | |
| 85 | 84 | /* Flush Bonito register block */ |
| 86 | − dummy = BONITO_PCIMAP_CFG; | |
| 85 | + (void) BONITO_PCIMAP_CFG; | |
| 87 | 86 | iob(); /* sync */ |
| 88 | 87 | |
| 89 | 88 | irq = __raw_readl((u32 *)_pcictrl_bonito_pcicfg); |
| @@ -97,7 +97,7 @@ static int msp_per_irq_set_affinity(struct irq_data *d, · 96 unmodified lines | ||
| 97 | 97 | |
| 98 | 98 | static struct irq_chip msp_per_irq_controller = { |
| 99 | 99 | .name = "MSP_PER", |
| 100 | − .irq_enable = unmask_per_irq. | |
| 100 | + .irq_enable = unmask_per_irq, | |
| 101 | 101 | .irq_disable = mask_per_irq, |
| 102 | 102 | .irq_ack = msp_per_irq_ack, |
| 103 | 103 | #ifdef CONFIG_SMP |
| @@ -35,7 +35,7 @@ LEAF(swsusp_arch_resume) · 34 unmodified lines | ||
| 35 | 35 | 0: |
| 36 | 36 | PTR_L t1, PBE_ADDRESS(t0) /* source */ |
| 37 | 37 | PTR_L t2, PBE_ORIG_ADDRESS(t0) /* destination */ |
| 38 | − PTR_ADDIU t3, t1, PAGE_SIZE | |
| 38 | + PTR_ADDU t3, t1, PAGE_SIZE | |
| 39 | 39 | 1: |
| 40 | 40 | REG_L t8, (t1) |
| 41 | 41 | REG_S t8, (t2) |
| @@ -185,7 +185,7 @@ int __init rb532_gpio_init(void) · 184 unmodified lines | ||
| 185 | 185 | struct resource *r; |
| 186 | 186 | |
| 187 | 187 | r = rb532_gpio_reg0_res; |
| 188 | − rb532_gpio_chip->regbase = ioremap_nocache(r->start, r->end - r->start); | |
| 188 | + rb532_gpio_chip->regbase = ioremap_nocache(r->start, resource_size(r)); | |
| 189 | 189 | |
| 190 | 190 | if (!rb532_gpio_chip->regbase) { |
| 191 | 191 | printk(KERN_ERR "rb532: cannot remap GPIO register 0\n"); |
| @@ -132,7 +132,7 @@ static struct platform_device eth1_device = { · 131 unmodified lines | ||
| 132 | 132 | */ |
| 133 | 133 | static int __init sgiseeq_devinit(void) |
| 134 | 134 | { |
| 135 | − unsigned int tmp; | |
| 135 | + unsigned int pbdma __maybe_unused; | |
| 136 | 136 | int res, i; |
| 137 | 137 | |
| 138 | 138 | eth0_pd.hpc = hpc3c0; |
| @@ -151,7 +151,7 @@ static int __init sgiseeq_devinit(void) · 12 unmodified lines | ||
| 151 | 151 | |
| 152 | 152 | /* Second HPC is missing? */ |
| 153 | 153 | if (ip22_is_fullhouse() || |
| 154 | − get_dbe(tmp, (unsigned int *)&hpc3c1->pbdma[1])) | |
| 154 | + get_dbe(pbdma, (unsigned int *)&hpc3c1->pbdma[1])) | |
| 155 | 155 | return 0; |
| 156 | 156 | |
| 157 | 157 | sgimc->giopar |= SGIMC_GIOPAR_MASTEREXP1 | SGIMC_GIOPAR_EXP164 | |
| @@ -32,7 +32,7 @@ · 31 unmodified lines | ||
| 32 | 32 | static unsigned long dosample(void) |
| 33 | 33 | { |
| 34 | 34 | u32 ct0, ct1; |
| 35 | − u8 msb, lsb; | |
| 35 | + u8 msb; | |
| 36 | 36 | |
| 37 | 37 | /* Start the counter. */ |
| 38 | 38 | sgint->tcword = (SGINT_TCWORD_CNT2 | SGINT_TCWORD_CALL | |
| @@ -46,7 +46,7 @@ static unsigned long dosample(void) · 7 unmodified lines | ||
| 46 | 46 | /* Latch and spin until top byte of counter2 is zero */ |
| 47 | 47 | do { |
| 48 | 48 | writeb(SGINT_TCWORD_CNT2 | SGINT_TCWORD_CLAT, &sgint->tcword); |
| 49 | − lsb = readb(&sgint->tcnt2); | |
| 49 | + (void) readb(&sgint->tcnt2); | |
| 50 | 50 | msb = readb(&sgint->tcnt2); |
| 51 | 51 | ct1 = read_c0_count(); |
| 52 | 52 | } while (msb); |
| @@ -29,7 +29,6 @@ unsigned long hub_pio_map(cnodeid_t cnode, xwidgetnum_t widget, · 28 unmodified lines | ||
| 29 | 29 | unsigned long xtalk_addr, size_t size) |
| 30 | 30 | { |
| 31 | 31 | nasid_t nasid = COMPACT_TO_NASID_NODEID(cnode); |
| 32 | − volatile hubreg_t junk; | |
| 33 | 32 | unsigned i; |
| 34 | 33 | |
| 35 | 34 | /* use small-window mapping if possible */ |
| @@ -64,7 +63,7 @@ unsigned long hub_pio_map(cnodeid_t cnode, xwidgetnum_t widget, · 28 unmodified lines | ||
| 64 | 63 | * after we write it. |
| 65 | 64 | */ |
| 66 | 65 | IIO_ITTE_PUT(nasid, i, HUB_PIO_MAP_TO_MEM, widget, xtalk_addr); |
| 67 | − junk = HUB_L(IIO_ITTE_GET(nasid, i)); | |
| 66 | + (void) HUB_L(IIO_ITTE_GET(nasid, i)); | |
| 68 | 67 | |
| 69 | 68 | return NODE_BWIN_BASE(nasid, widget) + (xtalk_addr % BWIN_SIZE); |
| 70 | 69 | } |
| @@ -54,11 +54,8 @@ void __init setup_replication_mask(void) · 53 unmodified lines | ||
| 54 | 54 | |
| 55 | 55 | static __init void set_ktext_source(nasid_t client_nasid, nasid_t server_nasid) |
| 56 | 56 | { |
| 57 | − cnodeid_t client_cnode; | |
| 58 | 57 | kern_vars_t *kvp; |
| 59 | 58 | |
| 60 | − client_cnode = NASID_TO_COMPACT_NODEID(client_nasid); | |
| 61 | − | |
| 62 | 59 | kvp = &hub_data(client_nasid)->kern_vars; |
| 63 | 60 | |
| 64 | 61 | KERN_VARS_ADDR(client_nasid) = (unsigned long)kvp; |
| @@ -95,7 +95,7 @@ static void __init sni_a20r_timer_setup(void) · 94 unmodified lines | ||
| 95 | 95 | static __init unsigned long dosample(void) |
| 96 | 96 | { |
| 97 | 97 | u32 ct0, ct1; |
| 98 | − volatile u8 msb, lsb; | |
| 98 | + volatile u8 msb; | |
| 99 | 99 | |
| 100 | 100 | /* Start the counter. */ |
| 101 | 101 | outb_p(0x34, 0x43); |
| @@ -108,7 +108,7 @@ static __init unsigned long dosample(void) · 6 unmodified lines | ||
| 108 | 108 | /* Latch and spin until top byte of counter0 is zero */ |
| 109 | 109 | do { |
| 110 | 110 | outb(0x00, 0x43); |
| 111 | − lsb = inb(0x40); | |
| 111 | + (void) inb(0x40); | |
| 112 | 112 | msb = inb(0x40); |
| 113 | 113 | ct1 = read_c0_count(); |
| 114 | 114 | } while (msb); |
| @@ -266,8 +266,10 @@ static void __init setup_bootmem(void) · 265 unmodified lines | ||
| 266 | 266 | } |
| 267 | 267 | memset(pfnnid_map, 0xff, sizeof(pfnnid_map)); |
| 268 | 268 | |
| 269 | − for (i = 0; i < npmem_ranges; i++) | |
| 269 | + for (i = 0; i < npmem_ranges; i++) { | |
| 270 | + node_set_state(i, N_NORMAL_MEMORY); | |
| 270 | 271 | node_set_online(i); |
| 272 | + } | |
| 271 | 273 | #endif |
| 272 | 274 | |
| 273 | 275 | /* |
| @@ -393,8 +393,8 @@ typedef struct fec { · 392 unmodified lines | ||
| 393 | 393 | uint fec_addr_low; /* lower 32 bits of station address */ |
| 394 | 394 | ushort fec_addr_high; /* upper 16 bits of station address */ |
| 395 | 395 | ushort res1; /* reserved */ |
| 396 | − uint fec_hash_table_high; /* upper 32-bits of hash table */ | |
| 397 | − uint fec_hash_table_low; /* lower 32-bits of hash table */ | |
| 396 | + uint fec_grp_hash_table_high; /* upper 32-bits of hash table */ | |
| 397 | + uint fec_grp_hash_table_low; /* lower 32-bits of hash table */ | |
| 398 | 398 | uint fec_r_des_start; /* beginning of Rx descriptor ring */ |
| 399 | 399 | uint fec_x_des_start; /* beginning of Tx descriptor ring */ |
| 400 | 400 | uint fec_r_buff_size; /* Rx buffer size */ |
| @@ -60,7 +60,7 @@ · 59 unmodified lines | ||
| 60 | 60 | * |
| 61 | 61 | * Obviously, the GART is not cache coherent and so any change to it |
| 62 | 62 | * must be flushed to memory (or maybe just make the GART space non |
| 63 | − * cachable). AGP memory itself does't seem to be cache coherent neither. | |
| 63 | + * cachable). AGP memory itself doesn't seem to be cache coherent neither. | |
| 64 | 64 | * |
| 65 | 65 | * In order to invalidate the GART (which is probably necessary to inval |
| 66 | 66 | * the bridge internal TLBs), the following sequence has to be written, |
| @@ -933,12 +933,16 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, · 932 unmodified lines | ||
| 933 | 933 | if (data && !(data & DABR_TRANSLATION)) |
| 934 | 934 | return -EIO; |
| 935 | 935 | #ifdef CONFIG_HAVE_HW_BREAKPOINT |
| 936 | + if (ptrace_get_breakpoints(task) < 0) | |
| 937 | + return -ESRCH; | |
| 938 | + | |
| 936 | 939 | bp = thread->ptrace_bps[0]; |
| 937 | 940 | if ((!data) || !(data & (DABR_DATA_WRITE | DABR_DATA_READ))) { |
| 938 | 941 | if (bp) { |
| 939 | 942 | unregister_hw_breakpoint(bp); |
| 940 | 943 | thread->ptrace_bps[0] = NULL; |
| 941 | 944 | } |
| 945 | + ptrace_put_breakpoints(task); | |
| 942 | 946 | return 0; |
| 943 | 947 | } |
| 944 | 948 | if (bp) { |
| @@ -948,9 +952,12 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, · 3 unmodified lines | ||
| 948 | 952 | (DABR_DATA_WRITE | DABR_DATA_READ), |
| 949 | 953 | &attr.bp_type); |
| 950 | 954 | ret = modify_user_hw_breakpoint(bp, &attr); |
| 951 | − if (ret) | |
| 955 | + if (ret) { | |
| 956 | + ptrace_put_breakpoints(task); | |
| 952 | 957 | return ret; |
| 958 | + } | |
| 953 | 959 | thread->ptrace_bps[0] = bp; |
| 960 | + ptrace_put_breakpoints(task); | |
| 954 | 961 | thread->dabr = data; |
| 955 | 962 | return 0; |
| 956 | 963 | } |
| @@ -965,9 +972,12 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, · 8 unmodified lines | ||
| 965 | 972 | ptrace_triggered, task); |
| 966 | 973 | if (IS_ERR(bp)) { |
| 967 | 974 | thread->ptrace_bps[0] = NULL; |
| 975 | + ptrace_put_breakpoints(task); | |
| 968 | 976 | return PTR_ERR(bp); |
| 969 | 977 | } |
| 970 | 978 | |
| 979 | + ptrace_put_breakpoints(task); | |
| 980 | + | |
| 971 | 981 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ |
| 972 | 982 | |
| 973 | 983 | /* Move contents to the DABR register */ |
| @@ -318,17 +318,20 @@ static const struct platform_suspend_ops mpc83xx_suspend_ops = { · 317 unmodified lines | ||
| 318 | 318 | .end = mpc83xx_suspend_end, |
| 319 | 319 | }; |
| 320 | 320 | |
| 321 | +static struct of_device_id pmc_match[]; | |
| 321 | 322 | static int pmc_probe(struct platform_device *ofdev) |
| 322 | 323 | { |
| 324 | + const struct of_device_id *match; | |
| 323 | 325 | struct device_node *np = ofdev->dev.of_node; |
| 324 | 326 | struct resource res; |
| 325 | 327 | struct pmc_type *type; |
| 326 | 328 | int ret = 0; |
| 327 | 329 | |
| 328 | − if (!ofdev->dev.of_match) | |
| 330 | + match = of_match_device(pmc_match, &ofdev->dev); | |
| 331 | + if (!match) | |
| 329 | 332 | return -EINVAL; |
| 330 | 333 | |
| 331 | − type = ofdev->dev.of_match->data; | |
| 334 | + type = match->data; | |
| 332 | 335 | |
| 333 | 336 | if (!of_device_is_available(np)) |
| 334 | 337 | return -ENODEV; |
| @@ -304,8 +304,10 @@ static int __devinit fsl_msi_setup_hwirq(struct fsl_msi *msi, · 303 unmodified lines | ||
| 304 | 304 | return 0; |
| 305 | 305 | } |
| 306 | 306 | |
| 307 | +static const struct of_device_id fsl_of_msi_ids[]; | |
| 307 | 308 | static int __devinit fsl_of_msi_probe(struct platform_device *dev) |
| 308 | 309 | { |
| 310 | + const struct of_device_id *match; | |
| 309 | 311 | struct fsl_msi *msi; |
| 310 | 312 | struct resource res; |
| 311 | 313 | int err, i, j, irq_index, count; |
| @@ -316,9 +318,10 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev) · 4 unmodified lines | ||
| 316 | 318 | u32 offset; |
| 317 | 319 | static const u32 all_avail[] = { 0, NR_MSI_IRQS }; |
| 318 | 320 | |
| 319 | − if (!dev->dev.of_match) | |
| 321 | + match = of_match_device(fsl_of_msi_ids, &dev->dev); | |
| 322 | + if (!match) | |
| 320 | 323 | return -EINVAL; |
| 321 | − features = dev->dev.of_match->data; | |
| 324 | + features = match->data; | |
| 322 | 325 | |
| 323 | 326 | printk(KERN_DEBUG "Setting up Freescale MSI support\n"); |
| 324 | 327 | |
| @@ -76,7 +76,7 @@ static void prng_seed(int nbytes) · 75 unmodified lines | ||
| 76 | 76 | |
| 77 | 77 | /* Add the entropy */ |
| 78 | 78 | while (nbytes >= 8) { |
| 79 | − *((__u64 *)parm_block) ^= *((__u64 *)buf+i*8); | |
| 79 | + *((__u64 *)parm_block) ^= *((__u64 *)(buf+i)); | |
| 80 | 80 | prng_add_entropy(); |
| 81 | 81 | i += 8; |
| 82 | 82 | nbytes -= 8; |
| @@ -9,9 +9,22 @@ · 8 unmodified lines | ||
| 9 | 9 | #define _ASM_S390_DIAG_H |
| 10 | 10 | |
| 11 | 11 | /* |
| 12 | − * Diagnose 10: Release pages | |
| 12 | + * Diagnose 10: Release page range | |
| 13 | 13 | */ |
| 14 | −extern void diag10(unsigned long addr); | |
| 14 | +static inline void diag10_range(unsigned long start_pfn, unsigned long num_pfn) | |
| 15 | +{ | |
| 16 | + unsigned long start_addr, end_addr; | |
| 17 | + | |
| 18 | + start_addr = start_pfn << PAGE_SHIFT; | |
| 19 | + end_addr = (start_pfn + num_pfn - 1) << PAGE_SHIFT; | |
| 20 | + | |
| 21 | + asm volatile( | |
| 22 | + "0: diag %0,%1,0x10\n" | |
| 23 | + "1:\n" | |
| 24 | + EX_TABLE(0b, 1b) | |
| 25 | + EX_TABLE(1b, 1b) | |
| 26 | + : : "a" (start_addr), "a" (end_addr)); | |
| 27 | +} | |
| 15 | 28 | |
| 16 | 29 | /* |
| 17 | 30 | * Diagnose 14: Input spool file manipulation |
| @@ -23,7 +23,7 @@ static inline int init_new_context(struct task_struct *tsk, · 22 unmodified lines | ||
| 23 | 23 | #ifdef CONFIG_64BIT |
| 24 | 24 | mm->context.asce_bits |= _ASCE_TYPE_REGION3; |
| 25 | 25 | #endif |
| 26 | − if (current->mm->context.alloc_pgste) { | |
| 26 | + if (current->mm && current->mm->context.alloc_pgste) { | |
| 27 | 27 | /* |
| 28 | 28 | * alloc_pgste indicates, that any NEW context will be created |
| 29 | 29 | * with extended page tables. The old context is unchanged. The |
| @@ -8,27 +8,6 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <linux/module.h> |
| 9 | 9 | #include <asm/diag.h> |
| 10 | 10 | |
| 11 | −/* | |
| 12 | − * Diagnose 10: Release pages | |
| 13 | − */ | |
| 14 | −void diag10(unsigned long addr) | |
| 15 | −{ | |
| 16 | − if (addr >= 0x7ff00000) | |
| 17 | − return; | |
| 18 | − asm volatile( | |
| 19 | −#ifdef CONFIG_64BIT | |
| 20 | − " sam31\n" | |
| 21 | − " diag %0,%0,0x10\n" | |
| 22 | − "0: sam64\n" | |
| 23 | −#else | |
| 24 | − " diag %0,%0,0x10\n" | |
| 25 | − "0:\n" | |
| 26 | −#endif | |
| 27 | − EX_TABLE(0b, 0b) | |
| 28 | − : : "a" (addr)); | |
| 29 | −} | |
| 30 | −EXPORT_SYMBOL(diag10); | |
| 31 | − | |
| 32 | 11 | /* |
| 33 | 12 | * Diagnose 14: Input spool file manipulation |
| 34 | 13 | */ |
| @@ -672,6 +672,7 @@ static struct insn opcode_b2[] = { · 671 unmodified lines | ||
| 672 | 672 | { "rp", 0x77, INSTR_S_RD }, |
| 673 | 673 | { "stcke", 0x78, INSTR_S_RD }, |
| 674 | 674 | { "sacf", 0x79, INSTR_S_RD }, |
| 675 | + { "spp", 0x80, INSTR_S_RD }, | |
| 675 | 676 | { "stsi", 0x7d, INSTR_S_RD }, |
| 676 | 677 | { "srnm", 0x99, INSTR_S_RD }, |
| 677 | 678 | { "stfpc", 0x9c, INSTR_S_RD }, |
| @@ -836,7 +836,7 @@ restart_base: · 835 unmodified lines | ||
| 836 | 836 | stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on |
| 837 | 837 | basr %r14,0 |
| 838 | 838 | l %r14,restart_addr-.(%r14) |
| 839 | − br %r14 # branch to start_secondary | |
| 839 | + basr %r14,%r14 # branch to start_secondary | |
| 840 | 840 | restart_addr: |
| 841 | 841 | .long start_secondary |
| 842 | 842 | .align 8 |
| @@ -841,7 +841,7 @@ restart_base: · 840 unmodified lines | ||
| 841 | 841 | mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1) |
| 842 | 842 | xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER |
| 843 | 843 | stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on |
| 844 | − jg start_secondary | |
| 844 | + brasl %r14,start_secondary | |
| 845 | 845 | .align 8 |
| 846 | 846 | restart_vtime: |
| 847 | 847 | .long 0x7fffffff,0xffffffff |
| @@ -48,10 +48,10 @@ sie_irq_handler: · 47 unmodified lines | ||
| 48 | 48 | tm __TI_flags+7(%r2),_TIF_EXIT_SIE |
| 49 | 49 | jz 0f |
| 50 | 50 | larl %r2,sie_exit # work pending, leave sie |
| 51 | − stg %r2,__LC_RETURN_PSW+8 | |
| 51 | + stg %r2,SPI_PSW+8(0,%r15) | |
| 52 | 52 | br %r14 |
| 53 | 53 | 0: larl %r2,sie_reenter # re-enter with guest id |
| 54 | − stg %r2,__LC_RETURN_PSW+8 | |
| 54 | + stg %r2,SPI_PSW+8(0,%r15) | |
| 55 | 55 | 1: br %r14 |
| 56 | 56 | |
| 57 | 57 | /* |
| @@ -91,7 +91,7 @@ static long cmm_alloc_pages(long nr, long *counter, · 90 unmodified lines | ||
| 91 | 91 | } else |
| 92 | 92 | free_page((unsigned long) npa); |
| 93 | 93 | } |
| 94 | − diag10(addr); | |
| 94 | + diag10_range(addr >> PAGE_SHIFT, 1); | |
| 95 | 95 | pa->pages[pa->index++] = addr; |
| 96 | 96 | (*counter)++; |
| 97 | 97 | spin_unlock(&cmm_lock); |
| @@ -543,7 +543,6 @@ static void pfault_interrupt(unsigned int ext_int_code, · 542 unmodified lines | ||
| 543 | 543 | struct task_struct *tsk; |
| 544 | 544 | __u16 subcode; |
| 545 | 545 | |
| 546 | − kstat_cpu(smp_processor_id()).irqs[EXTINT_PFL]++; | |
| 547 | 546 | /* |
| 548 | 547 | * Get the external interruption subcode & pfault |
| 549 | 548 | * initial/completion signal bit. VM stores this |
| @@ -553,14 +552,15 @@ static void pfault_interrupt(unsigned int ext_int_code, · 3 unmodified lines | ||
| 553 | 552 | subcode = ext_int_code >> 16; |
| 554 | 553 | if ((subcode & 0xff00) != __SUBCODE_MASK) |
| 555 | 554 | return; |
| 555 | + kstat_cpu(smp_processor_id()).irqs[EXTINT_PFL]++; | |
| 556 | 556 | |
| 557 | 557 | /* |
| 558 | 558 | * Get the token (= address of the task structure of the affected task). |
| 559 | 559 | */ |
| 560 | 560 | #ifdef CONFIG_64BIT |
| 561 | − tsk = *(struct task_struct **) param64; | |
| 561 | + tsk = (struct task_struct *) param64; | |
| 562 | 562 | #else |
| 563 | − tsk = *(struct task_struct **) param32; | |
| 563 | + tsk = (struct task_struct *) param32; | |
| 564 | 564 | #endif |
| 565 | 565 | |
| 566 | 566 | if (subcode & 0x0080) { |
| @@ -24,12 +24,13 @@ static void change_page_attr(unsigned long addr, int numpages, · 23 unmodified lines | ||
| 24 | 24 | WARN_ON_ONCE(1); |
| 25 | 25 | continue; |
| 26 | 26 | } |
| 27 | − ptep = pte_offset_kernel(pmdp, addr + i * PAGE_SIZE); | |
| 27 | + ptep = pte_offset_kernel(pmdp, addr); | |
| 28 | 28 | |
| 29 | 29 | pte = *ptep; |
| 30 | 30 | pte = set(pte); |
| 31 | − ptep_invalidate(&init_mm, addr + i * PAGE_SIZE, ptep); | |
| 31 | + ptep_invalidate(&init_mm, addr, ptep); | |
| 32 | 32 | *ptep = pte; |
| 33 | + addr += PAGE_SIZE; | |
| 33 | 34 | } |
| 34 | 35 | } |
| 35 | 36 | |
| @@ -1021,20 +1021,14 @@ deallocate_exit: · 1020 unmodified lines | ||
| 1021 | 1021 | return rc; |
| 1022 | 1022 | } |
| 1023 | 1023 | |
| 1024 | −long hwsampler_query_min_interval(void) | |
| 1024 | +unsigned long hwsampler_query_min_interval(void) | |
| 1025 | 1025 | { |
| 1026 | − if (min_sampler_rate) | |
| 1027 | − return min_sampler_rate; | |
| 1028 | − else | |
| 1029 | − return -EINVAL; | |
| 1026 | + return min_sampler_rate; | |
| 1030 | 1027 | } |
| 1031 | 1028 | |
| 1032 | −long hwsampler_query_max_interval(void) | |
| 1029 | +unsigned long hwsampler_query_max_interval(void) | |
| 1033 | 1030 | { |
| 1034 | − if (max_sampler_rate) | |
| 1035 | − return max_sampler_rate; | |
| 1036 | − else | |
| 1037 | − return -EINVAL; | |
| 1031 | + return max_sampler_rate; | |
| 1038 | 1032 | } |
| 1039 | 1033 | |
| 1040 | 1034 | unsigned long hwsampler_get_sample_overflow_count(unsigned int cpu) |
| @@ -102,8 +102,8 @@ int hwsampler_setup(void); · 101 unmodified lines | ||
| 102 | 102 | int hwsampler_shutdown(void); |
| 103 | 103 | int hwsampler_allocate(unsigned long sdbt, unsigned long sdb); |
| 104 | 104 | int hwsampler_deallocate(void); |
| 105 | −long hwsampler_query_min_interval(void); | |
| 106 | −long hwsampler_query_max_interval(void); | |
| 105 | +unsigned long hwsampler_query_min_interval(void); | |
| 106 | +unsigned long hwsampler_query_max_interval(void); | |
| 107 | 107 | int hwsampler_start_all(unsigned long interval); |
| 108 | 108 | int hwsampler_stop_all(void); |
| 109 | 109 | int hwsampler_deactivate(unsigned int cpu); |
| @@ -145,15 +145,11 @@ static int oprofile_hwsampler_init(struct oprofile_operations *ops) · 144 unmodified lines | ||
| 145 | 145 | * create hwsampler files only if hwsampler_setup() succeeds. |
| 146 | 146 | */ |
| 147 | 147 | oprofile_min_interval = hwsampler_query_min_interval(); |
| 148 | − if (oprofile_min_interval < 0) { | |
| 149 | − oprofile_min_interval = 0; | |
| 148 | + if (oprofile_min_interval == 0) | |
| 150 | 149 | return -ENODEV; |
| 151 | − } | |
| 152 | 150 | oprofile_max_interval = hwsampler_query_max_interval(); |
| 153 | − if (oprofile_max_interval < 0) { | |
| 154 | − oprofile_max_interval = 0; | |
| 151 | + if (oprofile_max_interval == 0) | |
| 155 | 152 | return -ENODEV; |
| 156 | − } | |
| 157 | 153 | |
| 158 | 154 | if (oprofile_timer_init(ops)) |
| 159 | 155 | return -ENODEV; |
| @@ -117,7 +117,11 @@ void user_enable_single_step(struct task_struct *child) · 116 unmodified lines | ||
| 117 | 117 | |
| 118 | 118 | set_tsk_thread_flag(child, TIF_SINGLESTEP); |
| 119 | 119 | |
| 120 | + if (ptrace_get_breakpoints(child) < 0) | |
| 121 | + return; | |
| 122 | + | |
| 120 | 123 | set_single_step(child, pc); |
| 124 | + ptrace_put_breakpoints(child); | |
| 121 | 125 | } |
| 122 | 126 | |
| 123 | 127 | void user_disable_single_step(struct task_struct *child) |
| @@ -165,7 +165,7 @@ static int __devinit apc_probe(struct platform_device *op) · 164 unmodified lines | ||
| 165 | 165 | return 0; |
| 166 | 166 | } |
| 167 | 167 | |
| 168 | −static struct of_device_id __initdata apc_match[] = { | |
| 168 | +static struct of_device_id apc_match[] = { | |
| 169 | 169 | { |
| 170 | 170 | .name = APC_OBPNAME, |
| 171 | 171 | }, |
| @@ -452,8 +452,10 @@ static void __devinit sabre_pbm_init(struct pci_pbm_info *pbm, · 451 unmodified lines | ||
| 452 | 452 | sabre_scan_bus(pbm, &op->dev); |
| 453 | 453 | } |
| 454 | 454 | |
| 455 | +static const struct of_device_id sabre_match[]; | |
| 455 | 456 | static int __devinit sabre_probe(struct platform_device *op) |
| 456 | 457 | { |
| 458 | + const struct of_device_id *match; | |
| 457 | 459 | const struct linux_prom64_registers *pr_regs; |
| 458 | 460 | struct device_node *dp = op->dev.of_node; |
| 459 | 461 | struct pci_pbm_info *pbm; |
| @@ -463,7 +465,8 @@ static int __devinit sabre_probe(struct platform_device *op) · 3 unmodified lines | ||
| 463 | 465 | const u32 *vdma; |
| 464 | 466 | u64 clear_irq; |
| 465 | 467 | |
| 466 | − hummingbird_p = op->dev.of_match && (op->dev.of_match->data != NULL); | |
| 468 | + match = of_match_device(sabre_match, &op->dev); | |
| 469 | + hummingbird_p = match && (match->data != NULL); | |
| 467 | 470 | if (!hummingbird_p) { |
| 468 | 471 | struct device_node *cpu_dp; |
| 469 | 472 | |
| @@ -1458,11 +1458,15 @@ out_err: · 1457 unmodified lines | ||
| 1458 | 1458 | return err; |
| 1459 | 1459 | } |
| 1460 | 1460 | |
| 1461 | +static const struct of_device_id schizo_match[]; | |
| 1461 | 1462 | static int __devinit schizo_probe(struct platform_device *op) |
| 1462 | 1463 | { |
| 1463 | − if (!op->dev.of_match) | |
| 1464 | + const struct of_device_id *match; | |
| 1465 | + | |
| 1466 | + match = of_match_device(schizo_match, &op->dev); | |
| 1467 | + if (!match) | |
| 1464 | 1468 | return -EINVAL; |
| 1465 | − return __schizo_init(op, (unsigned long) op->dev.of_match->data); | |
| 1469 | + return __schizo_init(op, (unsigned long)match->data); | |
| 1466 | 1470 | } |
| 1467 | 1471 | |
| 1468 | 1472 | /* The ordering of this table is very important. Some Tomatillo |
| @@ -69,7 +69,7 @@ static int __devinit pmc_probe(struct platform_device *op) · 68 unmodified lines | ||
| 69 | 69 | return 0; |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | −static struct of_device_id __initdata pmc_match[] = { | |
| 72 | +static struct of_device_id pmc_match[] = { | |
| 73 | 73 | { |
| 74 | 74 | .name = PMC_OBPNAME, |
| 75 | 75 | }, |
| @@ -53,6 +53,7 @@ cpumask_t smp_commenced_mask = CPU_MASK_NONE; · 52 unmodified lines | ||
| 53 | 53 | void __cpuinit smp_store_cpu_info(int id) |
| 54 | 54 | { |
| 55 | 55 | int cpu_node; |
| 56 | + int mid; | |
| 56 | 57 | |
| 57 | 58 | cpu_data(id).udelay_val = loops_per_jiffy; |
| 58 | 59 | |
| @@ -60,10 +61,13 @@ void __cpuinit smp_store_cpu_info(int id) · 1 unmodified line | ||
| 60 | 61 | cpu_data(id).clock_tick = prom_getintdefault(cpu_node, |
| 61 | 62 | "clock-frequency", 0); |
| 62 | 63 | cpu_data(id).prom_node = cpu_node; |
| 63 | − cpu_data(id).mid = cpu_get_hwmid(cpu_node); | |
| 64 | + mid = cpu_get_hwmid(cpu_node); | |
| 64 | 65 | |
| 65 | − if (cpu_data(id).mid < 0) | |
| 66 | − panic("No MID found for CPU%d at node 0x%08d", id, cpu_node); | |
| 66 | + if (mid < 0) { | |
| 67 | + printk(KERN_NOTICE "No MID found for CPU%d at node 0x%08d", id, cpu_node); | |
| 68 | + mid = 0; | |
| 69 | + } | |
| 70 | + cpu_data(id).mid = mid; | |
| 67 | 71 | } |
| 68 | 72 | |
| 69 | 73 | void __init smp_cpus_done(unsigned int max_cpus) |
| @@ -168,7 +168,7 @@ static int __devinit clock_probe(struct platform_device *op) · 167 unmodified lines | ||
| 168 | 168 | return 0; |
| 169 | 169 | } |
| 170 | 170 | |
| 171 | −static struct of_device_id __initdata clock_match[] = { | |
| 171 | +static struct of_device_id clock_match[] = { | |
| 172 | 172 | { |
| 173 | 173 | .name = "eeprom", |
| 174 | 174 | }, |
| @@ -289,10 +289,16 @@ cc_end_cruft: · 288 unmodified lines | ||
| 289 | 289 | |
| 290 | 290 | /* Also, handle the alignment code out of band. */ |
| 291 | 291 | cc_dword_align: |
| 292 | − cmp %g1, 6 | |
| 293 | − bl,a ccte | |
| 292 | + cmp %g1, 16 | |
| 293 | + bge 1f | |
| 294 | + srl %g1, 1, %o3 | |
| 295 | +2: cmp %o3, 0 | |
| 296 | + be,a ccte | |
| 294 | 297 | andcc %g1, 0xf, %o3 |
| 295 | − andcc %o0, 0x1, %g0 | |
| 298 | + andcc %o3, %o0, %g0 ! Check %o0 only (%o1 has the same last 2 bits) | |
| 299 | + be,a 2b | |
| 300 | + srl %o3, 1, %o3 | |
| 301 | +1: andcc %o0, 0x1, %g0 | |
| 296 | 302 | bne ccslow |
| 297 | 303 | andcc %o0, 0x2, %g0 |
| 298 | 304 | be 1f |
| @@ -47,7 +47,7 @@ config HOSTFS · 46 unmodified lines | ||
| 47 | 47 | |
| 48 | 48 | config HPPFS |
| 49 | 49 | tristate "HoneyPot ProcFS (EXPERIMENTAL)" |
| 50 | − depends on EXPERIMENTAL | |
| 50 | + depends on EXPERIMENTAL && PROC_FS | |
| 51 | 51 | help |
| 52 | 52 | hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc |
| 53 | 53 | entries to be overridden, removed, or fabricated from the host. |
| @@ -49,7 +49,10 @@ static inline struct thread_info *current_thread_info(void) · 48 unmodified lines | ||
| 49 | 49 | { |
| 50 | 50 | struct thread_info *ti; |
| 51 | 51 | unsigned long mask = THREAD_SIZE - 1; |
| 52 | − ti = (struct thread_info *) (((unsigned long) &ti) & ~mask); | |
| 52 | + void *p; | |
| 53 | + | |
| 54 | + asm volatile ("" : "=r" (p) : "0" (&ti)); | |
| 55 | + ti = (struct thread_info *) (((unsigned long)p) & ~mask); | |
| 53 | 56 | return ti; |
| 54 | 57 | } |
| 55 | 58 | |
| @@ -5,6 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | |
| 6 | 6 | #include <stdio.h> |
| 7 | 7 | #include <stdlib.h> |
| 8 | +#include <unistd.h> | |
| 8 | 9 | #include <errno.h> |
| 9 | 10 | #include <signal.h> |
| 10 | 11 | #include <string.h> |
| @@ -75,6 +76,26 @@ void setup_hostinfo(char *buf, int len) · 64 unmodified lines | ||
| 75 | 76 | host.release, host.version, host.machine); |
| 76 | 77 | } |
| 77 | 78 | |
| 79 | +/* | |
| 80 | + * We cannot use glibc's abort(). It makes use of tgkill() which | |
| 81 | + * has no effect within UML's kernel threads. | |
| 82 | + * After that glibc would execute an invalid instruction to kill | |
| 83 | + * the calling process and UML crashes with SIGSEGV. | |
| 84 | + */ | |
| 85 | +static inline void __attribute__ ((noreturn)) uml_abort(void) | |
| 86 | +{ | |
| 87 | + sigset_t sig; | |
| 88 | + | |
| 89 | + fflush(NULL); | |
| 90 | + | |
| 91 | + if (!sigemptyset(&sig) && !sigaddset(&sig, SIGABRT)) | |
| 92 | + sigprocmask(SIG_UNBLOCK, &sig, 0); | |
| 93 | + | |
| 94 | + for (;;) | |
| 95 | + if (kill(getpid(), SIGABRT) < 0) | |
| 96 | + exit(127); | |
| 97 | +} | |
| 98 | + | |
| 78 | 99 | void os_dump_core(void) |
| 79 | 100 | { |
| 80 | 101 | int pid; |
| @@ -116,5 +137,5 @@ void os_dump_core(void) · 35 unmodified lines | ||
| 116 | 137 | while ((pid = waitpid(-1, NULL, WNOHANG | __WALL)) > 0) |
| 117 | 138 | os_kill_ptraced_process(pid, 0); |
| 118 | 139 | |
| 119 | − abort(); | |
| 140 | + uml_abort(); | |
| 120 | 141 | } |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ |
| 6 | 6 | ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \ |
| 7 | − sys_call_table.o tls.o | |
| 7 | + sys_call_table.o tls.o atomic64_cx8_32.o | |
| 8 | 8 | |
| 9 | 9 | obj-$(CONFIG_BINFMT_ELF) += elfcore.o |
| 10 | 10 | |
| @@ -0,0 +1,225 @@ | ||
| 1 | +/* | |
| 2 | + * atomic64_t for 586+ | |
| 3 | + * | |
| 4 | + * Copied from arch/x86/lib/atomic64_cx8_32.S | |
| 5 | + * | |
| 6 | + * Copyright © 2010 Luca Barbieri | |
| 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 | + */ | |
| 14 | + | |
| 15 | +#include <linux/linkage.h> | |
| 16 | +#include <asm/alternative-asm.h> | |
| 17 | +#include <asm/dwarf2.h> | |
| 18 | + | |
| 19 | +.macro SAVE reg | |
| 20 | + pushl_cfi %\reg | |
| 21 | + CFI_REL_OFFSET \reg, 0 | |
| 22 | +.endm | |
| 23 | + | |
| 24 | +.macro RESTORE reg | |
| 25 | + popl_cfi %\reg | |
| 26 | + CFI_RESTORE \reg | |
| 27 | +.endm | |
| 28 | + | |
| 29 | +.macro read64 reg | |
| 30 | + movl %ebx, %eax | |
| 31 | + movl %ecx, %edx | |
| 32 | +/* we need LOCK_PREFIX since otherwise cmpxchg8b always does the write */ | |
| 33 | + LOCK_PREFIX | |
| 34 | + cmpxchg8b (\reg) | |
| 35 | +.endm | |
| 36 | + | |
| 37 | +ENTRY(atomic64_read_cx8) | |
| 38 | + CFI_STARTPROC | |
| 39 | + | |
| 40 | + read64 %ecx | |
| 41 | + ret | |
| 42 | + CFI_ENDPROC | |
| 43 | +ENDPROC(atomic64_read_cx8) | |
| 44 | + | |
| 45 | +ENTRY(atomic64_set_cx8) | |
| 46 | + CFI_STARTPROC | |
| 47 | + | |
| 48 | +1: | |
| 49 | +/* we don't need LOCK_PREFIX since aligned 64-bit writes | |
| 50 | + * are atomic on 586 and newer */ | |
| 51 | + cmpxchg8b (%esi) | |
| 52 | + jne 1b | |
| 53 | + | |
| 54 | + ret | |
| 55 | + CFI_ENDPROC | |
| 56 | +ENDPROC(atomic64_set_cx8) | |
| 57 | + | |
| 58 | +ENTRY(atomic64_xchg_cx8) | |
| 59 | + CFI_STARTPROC | |
| 60 | + | |
| 61 | + movl %ebx, %eax | |
| 62 | + movl %ecx, %edx | |
| 63 | +1: | |
| 64 | + LOCK_PREFIX | |
| 65 | + cmpxchg8b (%esi) | |
| 66 | + jne 1b | |
| 67 | + | |
| 68 | + ret | |
| 69 | + CFI_ENDPROC | |
| 70 | +ENDPROC(atomic64_xchg_cx8) | |
| 71 | + | |
| 72 | +.macro addsub_return func ins insc | |
| 73 | +ENTRY(atomic64_\func\()_return_cx8) | |
| 74 | + CFI_STARTPROC | |
| 75 | + SAVE ebp | |
| 76 | + SAVE ebx | |
| 77 | + SAVE esi | |
| 78 | + SAVE edi | |
| 79 | + | |
| 80 | + movl %eax, %esi | |
| 81 | + movl %edx, %edi | |
| 82 | + movl %ecx, %ebp | |
| 83 | + | |
| 84 | + read64 %ebp | |
| 85 | +1: | |
| 86 | + movl %eax, %ebx | |
| 87 | + movl %edx, %ecx | |
| 88 | + \ins\()l %esi, %ebx | |
| 89 | + \insc\()l %edi, %ecx | |
| 90 | + LOCK_PREFIX | |
| 91 | + cmpxchg8b (%ebp) | |
| 92 | + jne 1b | |
| 93 | + | |
| 94 | +10: | |
| 95 | + movl %ebx, %eax | |
| 96 | + movl %ecx, %edx | |
| 97 | + RESTORE edi | |
| 98 | + RESTORE esi | |
| 99 | + RESTORE ebx | |
| 100 | + RESTORE ebp | |
| 101 | + ret | |
| 102 | + CFI_ENDPROC | |
| 103 | +ENDPROC(atomic64_\func\()_return_cx8) | |
| 104 | +.endm | |
| 105 | + | |
| 106 | +addsub_return add add adc | |
| 107 | +addsub_return sub sub sbb | |
| 108 | + | |
| 109 | +.macro incdec_return func ins insc | |
| 110 | +ENTRY(atomic64_\func\()_return_cx8) | |
| 111 | + CFI_STARTPROC | |
| 112 | + SAVE ebx | |
| 113 | + | |
| 114 | + read64 %esi | |
| 115 | +1: | |
| 116 | + movl %eax, %ebx | |
| 117 | + movl %edx, %ecx | |
| 118 | + \ins\()l $1, %ebx | |
| 119 | + \insc\()l $0, %ecx | |
| 120 | + LOCK_PREFIX | |
| 121 | + cmpxchg8b (%esi) | |
| 122 | + jne 1b | |
| 123 | + | |
| 124 | +10: | |
| 125 | + movl %ebx, %eax | |
| 126 | + movl %ecx, %edx | |
| 127 | + RESTORE ebx | |
| 128 | + ret | |
| 129 | + CFI_ENDPROC | |
| 130 | +ENDPROC(atomic64_\func\()_return_cx8) | |
| 131 | +.endm | |
| 132 | + | |
| 133 | +incdec_return inc add adc | |
| 134 | +incdec_return dec sub sbb | |
| 135 | + | |
| 136 | +ENTRY(atomic64_dec_if_positive_cx8) | |
| 137 | + CFI_STARTPROC | |
| 138 | + SAVE ebx | |
| 139 | + | |
| 140 | + read64 %esi | |
| 141 | +1: | |
| 142 | + movl %eax, %ebx | |
| 143 | + movl %edx, %ecx | |
| 144 | + subl $1, %ebx | |
| 145 | + sbb $0, %ecx | |
| 146 | + js 2f | |
| 147 | + LOCK_PREFIX | |
| 148 | + cmpxchg8b (%esi) | |
| 149 | + jne 1b | |
| 150 | + | |
| 151 | +2: | |
| 152 | + movl %ebx, %eax | |
| 153 | + movl %ecx, %edx | |
| 154 | + RESTORE ebx | |
| 155 | + ret | |
| 156 | + CFI_ENDPROC | |
| 157 | +ENDPROC(atomic64_dec_if_positive_cx8) | |
| 158 | + | |
| 159 | +ENTRY(atomic64_add_unless_cx8) | |
| 160 | + CFI_STARTPROC | |
| 161 | + SAVE ebp | |
| 162 | + SAVE ebx | |
| 163 | +/* these just push these two parameters on the stack */ | |
| 164 | + SAVE edi | |
| 165 | + SAVE esi | |
| 166 | + | |
| 167 | + movl %ecx, %ebp | |
| 168 | + movl %eax, %esi | |
| 169 | + movl %edx, %edi | |
| 170 | + | |
| 171 | + read64 %ebp | |
| 172 | +1: | |
| 173 | + cmpl %eax, 0(%esp) | |
| 174 | + je 4f | |
| 175 | +2: | |
| 176 | + movl %eax, %ebx | |
| 177 | + movl %edx, %ecx | |
| 178 | + addl %esi, %ebx | |
| 179 | + adcl %edi, %ecx | |
| 180 | + LOCK_PREFIX | |
| 181 | + cmpxchg8b (%ebp) | |
| 182 | + jne 1b | |
| 183 | + | |
| 184 | + movl $1, %eax | |
| 185 | +3: | |
| 186 | + addl $8, %esp | |
| 187 | + CFI_ADJUST_CFA_OFFSET -8 | |
| 188 | + RESTORE ebx | |
| 189 | + RESTORE ebp | |
| 190 | + ret | |
| 191 | +4: | |
| 192 | + cmpl %edx, 4(%esp) | |
| 193 | + jne 2b | |
| 194 | + xorl %eax, %eax | |
| 195 | + jmp 3b | |
| 196 | + CFI_ENDPROC | |
| 197 | +ENDPROC(atomic64_add_unless_cx8) | |
| 198 | + | |
| 199 | +ENTRY(atomic64_inc_not_zero_cx8) | |
| 200 | + CFI_STARTPROC | |
| 201 | + SAVE ebx | |
| 202 | + | |
| 203 | + read64 %esi | |
| 204 | +1: | |
| 205 | + testl %eax, %eax | |
| 206 | + je 4f | |
| 207 | +2: | |
| 208 | + movl %eax, %ebx | |
| 209 | + movl %edx, %ecx | |
| 210 | + addl $1, %ebx | |
| 211 | + adcl $0, %ecx | |
| 212 | + LOCK_PREFIX | |
| 213 | + cmpxchg8b (%esi) | |
| 214 | + jne 1b | |
| 215 | + | |
| 216 | + movl $1, %eax | |
| 217 | +3: | |
| 218 | + RESTORE ebx | |
| 219 | + ret | |
| 220 | +4: | |
| 221 | + testl %edx, %edx | |
| 222 | + jne 2b | |
| 223 | + jmp 3b | |
| 224 | + CFI_ENDPROC | |
| 225 | +ENDPROC(atomic64_inc_not_zero_cx8) | |
| @@ -91,7 +91,7 @@ static int detect_memory_e801(void) · 90 unmodified lines | ||
| 91 | 91 | if (oreg.ax > 15*1024) { |
| 92 | 92 | return -1; /* Bogus! */ |
| 93 | 93 | } else if (oreg.ax == 15*1024) { |
| 94 | − boot_params.alt_mem_k = (oreg.dx << 6) + oreg.ax; | |
| 94 | + boot_params.alt_mem_k = (oreg.bx << 6) + oreg.ax; | |
| 95 | 95 | } else { |
| 96 | 96 | /* |
| 97 | 97 | * This ignores memory above 16MB if we have a memory |
| @@ -78,6 +78,7 @@ · 77 unmodified lines | ||
| 78 | 78 | #define APIC_DEST_LOGICAL 0x00800 |
| 79 | 79 | #define APIC_DEST_PHYSICAL 0x00000 |
| 80 | 80 | #define APIC_DM_FIXED 0x00000 |
| 81 | +#define APIC_DM_FIXED_MASK 0x00700 | |
| 81 | 82 | #define APIC_DM_LOWEST 0x00100 |
| 82 | 83 | #define APIC_DM_SMI 0x00200 |
| 83 | 84 | #define APIC_DM_REMRD 0x00300 |
| @@ -66,7 +66,7 @@ static inline void gart_set_size_and_enable(struct pci_dev *dev, u32 order) · 65 unmodified lines | ||
| 66 | 66 | * Don't enable translation but enable GART IO and CPU accesses. |
| 67 | 67 | * Also, set DISTLBWALKPRB since GART tables memory is UC. |
| 68 | 68 | */ |
| 69 | − ctl = DISTLBWALKPRB | order << 1; | |
| 69 | + ctl = order << 1; | |
| 70 | 70 | |
| 71 | 71 | pci_write_config_dword(dev, AMD64_GARTAPERTURECTL, ctl); |
| 72 | 72 | } |
| @@ -75,17 +75,17 @@ static inline void enable_gart_translation(struct pci_dev *dev, u64 addr) · 2 unmodified lines | ||
| 75 | 75 | { |
| 76 | 76 | u32 tmp, ctl; |
| 77 | 77 | |
| 78 | − /* address of the mappings table */ | |
| 79 | − addr >>= 12; | |
| 80 | − tmp = (u32) addr<<4; | |
| 81 | − tmp &= ~0xf; | |
| 82 | − pci_write_config_dword(dev, AMD64_GARTTABLEBASE, tmp); | |
| 83 | − | |
| 84 | − /* Enable GART translation for this hammer. */ | |
| 85 | − pci_read_config_dword(dev, AMD64_GARTAPERTURECTL, &ctl); | |
| 86 | − ctl |= GARTEN; | |
| 87 | − ctl &= ~(DISGARTCPU | DISGARTIO); | |
| 88 | − pci_write_config_dword(dev, AMD64_GARTAPERTURECTL, ctl); | |
| 78 | + /* address of the mappings table */ | |
| 79 | + addr >>= 12; | |
| 80 | + tmp = (u32) addr<<4; | |
| 81 | + tmp &= ~0xf; | |
| 82 | + pci_write_config_dword(dev, AMD64_GARTTABLEBASE, tmp); | |
| 83 | + | |
| 84 | + /* Enable GART translation for this hammer. */ | |
| 85 | + pci_read_config_dword(dev, AMD64_GARTAPERTURECTL, &ctl); | |
| 86 | + ctl |= GARTEN | DISTLBWALKPRB; | |
| 87 | + ctl &= ~(DISGARTCPU | DISGARTIO); | |
| 88 | + pci_write_config_dword(dev, AMD64_GARTAPERTURECTL, ctl); | |
| 89 | 89 | } |
| 90 | 90 | |
| 91 | 91 | static inline int aperture_valid(u64 aper_base, u32 aper_size, u32 min_size) |
| @@ -150,7 +150,7 @@ void setup_IO_APIC_irq_extra(u32 gsi); · 149 unmodified lines | ||
| 150 | 150 | extern void ioapic_and_gsi_init(void); |
| 151 | 151 | extern void ioapic_insert_resources(void); |
| 152 | 152 | |
| 153 | −int io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr); | |
| 153 | +int io_apic_setup_irq_pin_once(unsigned int irq, int node, struct io_apic_irq_attr *attr); | |
| 154 | 154 | |
| 155 | 155 | extern struct IO_APIC_route_entry **alloc_ioapic_entries(void); |
| 156 | 156 | extern void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries); |
| @@ -51,7 +51,7 @@ static inline void numa_remove_cpu(int cpu) { } · 50 unmodified lines | ||
| 51 | 51 | #endif /* CONFIG_NUMA */ |
| 52 | 52 | |
| 53 | 53 | #ifdef CONFIG_DEBUG_PER_CPU_MAPS |
| 54 | −struct cpumask __cpuinit *debug_cpumask_set_cpu(int cpu, int enable); | |
| 54 | +void debug_cpumask_set_cpu(int cpu, int node, bool enable); | |
| 55 | 55 | #endif |
| 56 | 56 | |
| 57 | 57 | #endif /* _ASM_X86_NUMA_H */ |
| @@ -299,6 +299,7 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn, · 298 unmodified lines | ||
| 299 | 299 | /* Install a pte for a particular vaddr in kernel space. */ |
| 300 | 300 | void set_pte_vaddr(unsigned long vaddr, pte_t pte); |
| 301 | 301 | |
| 302 | +extern void native_pagetable_reserve(u64 start, u64 end); | |
| 302 | 303 | #ifdef CONFIG_X86_32 |
| 303 | 304 | extern void native_pagetable_setup_start(pgd_t *base); |
| 304 | 305 | extern void native_pagetable_setup_done(pgd_t *base); |
| @@ -94,6 +94,8 @@ · 93 unmodified lines | ||
| 94 | 94 | /* after this # consecutive successes, bump up the throttle if it was lowered */ |
| 95 | 95 | #define COMPLETE_THRESHOLD 5 |
| 96 | 96 | |
| 97 | +#define UV_LB_SUBNODEID 0x10 | |
| 98 | + | |
| 97 | 99 | /* |
| 98 | 100 | * number of entries in the destination side payload queue |
| 99 | 101 | */ |
| @@ -124,7 +126,7 @@ · 24 unmodified lines | ||
| 124 | 126 | * The distribution specification (32 bytes) is interpreted as a 256-bit |
| 125 | 127 | * distribution vector. Adjacent bits correspond to consecutive even numbered |
| 126 | 128 | * nodeIDs. The result of adding the index of a given bit to the 15-bit |
| 127 | − * 'base_dest_nodeid' field of the header corresponds to the | |
| 129 | + * 'base_dest_nasid' field of the header corresponds to the | |
| 128 | 130 | * destination nodeID associated with that specified bit. |
| 129 | 131 | */ |
| 130 | 132 | struct bau_target_uvhubmask { |
| @@ -176,7 +178,7 @@ struct bau_msg_payload { · 45 unmodified lines | ||
| 176 | 178 | struct bau_msg_header { |
| 177 | 179 | unsigned int dest_subnodeid:6; /* must be 0x10, for the LB */ |
| 178 | 180 | /* bits 5:0 */ |
| 179 | − unsigned int base_dest_nodeid:15; /* nasid of the */ | |
| 181 | + unsigned int base_dest_nasid:15; /* nasid of the */ | |
| 180 | 182 | /* bits 20:6 */ /* first bit in uvhub map */ |
| 181 | 183 | unsigned int command:8; /* message type */ |
| 182 | 184 | /* bits 28:21 */ |
| @@ -378,6 +380,10 @@ struct ptc_stats { · 195 unmodified lines | ||
| 378 | 380 | unsigned long d_rcanceled; /* number of messages canceled by resets */ |
| 379 | 381 | }; |
| 380 | 382 | |
| 383 | +struct hub_and_pnode { | |
| 384 | + short uvhub; | |
| 385 | + short pnode; | |
| 386 | +}; | |
| 381 | 387 | /* |
| 382 | 388 | * one per-cpu; to locate the software tables |
| 383 | 389 | */ |
| @@ -399,10 +405,12 @@ struct bau_control { · 15 unmodified lines | ||
| 399 | 405 | int baudisabled; |
| 400 | 406 | int set_bau_off; |
| 401 | 407 | short cpu; |
| 408 | + short osnode; | |
| 402 | 409 | short uvhub_cpu; |
| 403 | 410 | short uvhub; |
| 404 | 411 | short cpus_in_socket; |
| 405 | 412 | short cpus_in_uvhub; |
| 413 | + short partition_base_pnode; | |
| 406 | 414 | unsigned short message_number; |
| 407 | 415 | unsigned short uvhub_quiesce; |
| 408 | 416 | short socket_acknowledge_count[DEST_Q_SIZE]; |
| @@ -422,15 +430,16 @@ struct bau_control { · 13 unmodified lines | ||
| 422 | 430 | int congested_period; |
| 423 | 431 | cycles_t period_time; |
| 424 | 432 | long period_requests; |
| 433 | + struct hub_and_pnode *target_hub_and_pnode; | |
| 425 | 434 | }; |
| 426 | 435 | |
| 427 | 436 | static inline int bau_uvhub_isset(int uvhub, struct bau_target_uvhubmask *dstp) |
| 428 | 437 | { |
| 429 | 438 | return constant_test_bit(uvhub, &dstp->bits[0]); |
| 430 | 439 | } |
| 431 | −static inline void bau_uvhub_set(int uvhub, struct bau_target_uvhubmask *dstp) | |
| 440 | +static inline void bau_uvhub_set(int pnode, struct bau_target_uvhubmask *dstp) | |
| 432 | 441 | { |
| 433 | − __set_bit(uvhub, &dstp->bits[0]); | |
| 442 | + __set_bit(pnode, &dstp->bits[0]); | |
| 434 | 443 | } |
| 435 | 444 | static inline void bau_uvhubs_clear(struct bau_target_uvhubmask *dstp, |
| 436 | 445 | int nbits) |
| @@ -398,6 +398,8 @@ struct uv_blade_info { · 397 unmodified lines | ||
| 398 | 398 | unsigned short nr_online_cpus; |
| 399 | 399 | unsigned short pnode; |
| 400 | 400 | short memory_nid; |
| 401 | + spinlock_t nmi_lock; | |
| 402 | + unsigned long nmi_count; | |
| 401 | 403 | }; |
| 402 | 404 | extern struct uv_blade_info *uv_blade_info; |
| 403 | 405 | extern short *uv_node_to_blade; |
| @@ -5,7 +5,7 @@ · 4 unmodified lines | ||
| 5 | 5 | * |
| 6 | 6 | * SGI UV MMR definitions |
| 7 | 7 | * |
| 8 | − * Copyright (C) 2007-2010 Silicon Graphics, Inc. All rights reserved. | |
| 8 | + * Copyright (C) 2007-2011 Silicon Graphics, Inc. All rights reserved. | |
| 9 | 9 | */ |
| 10 | 10 | |
| 11 | 11 | #ifndef _ASM_X86_UV_UV_MMRS_H |
| @@ -1099,5 +1099,19 @@ union uvh_rtc1_int_config_u { · 1087 unmodified lines | ||
| 1099 | 1099 | } s; |
| 1100 | 1100 | }; |
| 1101 | 1101 | |
| 1102 | +/* ========================================================================= */ | |
| 1103 | +/* UVH_SCRATCH5 */ | |
| 1104 | +/* ========================================================================= */ | |
| 1105 | +#define UVH_SCRATCH5 0x2d0200UL | |
| 1106 | +#define UVH_SCRATCH5_32 0x00778 | |
| 1107 | + | |
| 1108 | +#define UVH_SCRATCH5_SCRATCH5_SHFT 0 | |
| 1109 | +#define UVH_SCRATCH5_SCRATCH5_MASK 0xffffffffffffffffUL | |
| 1110 | +union uvh_scratch5_u { | |
| 1111 | + unsigned long v; | |
| 1112 | + struct uvh_scratch5_s { | |
| 1113 | + unsigned long scratch5 : 64; /* RW, W1CS */ | |
| 1114 | + } s; | |
| 1115 | +}; | |
| 1102 | 1116 | |
| 1103 | 1117 | #endif /* __ASM_UV_MMRS_X86_H__ */ |
| @@ -67,6 +67,17 @@ struct x86_init_oem { · 66 unmodified lines | ||
| 67 | 67 | void (*banner)(void); |
| 68 | 68 | }; |
| 69 | 69 | |
| 70 | +/** | |
| 71 | + * struct x86_init_mapping - platform specific initial kernel pagetable setup | |
| 72 | + * @pagetable_reserve: reserve a range of addresses for kernel pagetable usage | |
| 73 | + * | |
| 74 | + * For more details on the purpose of this hook, look in | |
| 75 | + * init_memory_mapping and the commit that added it. | |
| 76 | + */ | |
| 77 | +struct x86_init_mapping { | |
| 78 | + void (*pagetable_reserve)(u64 start, u64 end); | |
| 79 | +}; | |
| 80 | + | |
| 70 | 81 | /** |
| 71 | 82 | * struct x86_init_paging - platform specific paging functions |
| 72 | 83 | * @pagetable_setup_start: platform specific pre paging_init() call |
| @@ -123,6 +134,7 @@ struct x86_init_ops { · 50 unmodified lines | ||
| 123 | 134 | struct x86_init_mpparse mpparse; |
| 124 | 135 | struct x86_init_irqs irqs; |
| 125 | 136 | struct x86_init_oem oem; |
| 137 | + struct x86_init_mapping mapping; | |
| 126 | 138 | struct x86_init_paging paging; |
| 127 | 139 | struct x86_init_timers timers; |
| 128 | 140 | struct x86_init_iommu iommu; |
| @@ -499,7 +499,7 @@ out: · 498 unmodified lines | ||
| 499 | 499 | * Don't enable translation yet but enable GART IO and CPU |
| 500 | 500 | * accesses and set DISTLBWALKPRB since GART table memory is UC. |
| 501 | 501 | */ |
| 502 | − u32 ctl = DISTLBWALKPRB | aper_order << 1; | |
| 502 | + u32 ctl = aper_order << 1; | |
| 503 | 503 | |
| 504 | 504 | bus = amd_nb_bus_dev_ranges[i].bus; |
| 505 | 505 | dev_base = amd_nb_bus_dev_ranges[i].dev_base; |
| @@ -128,8 +128,8 @@ static int __init parse_noapic(char *str) · 127 unmodified lines | ||
| 128 | 128 | } |
| 129 | 129 | early_param("noapic", parse_noapic); |
| 130 | 130 | |
| 131 | −static int io_apic_setup_irq_pin_once(unsigned int irq, int node, | |
| 132 | − struct io_apic_irq_attr *attr); | |
| 131 | +static int io_apic_setup_irq_pin(unsigned int irq, int node, | |
| 132 | + struct io_apic_irq_attr *attr); | |
| 133 | 133 | |
| 134 | 134 | /* Will be called in mpparse/acpi/sfi codes for saving IRQ info */ |
| 135 | 135 | void mp_save_irq(struct mpc_intsrc *m) |
| @@ -3570,7 +3570,7 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev) · 3434 unmodified lines | ||
| 3570 | 3570 | } |
| 3571 | 3571 | #endif /* CONFIG_HT_IRQ */ |
| 3572 | 3572 | |
| 3573 | −int | |
| 3573 | +static int | |
| 3574 | 3574 | io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr) |
| 3575 | 3575 | { |
| 3576 | 3576 | struct irq_cfg *cfg = alloc_irq_and_cfg_at(irq, node); |
| @@ -3585,8 +3585,8 @@ io_apic_setup_irq_pin(unsigned int irq, int node, struct io_apic_irq_attr *attr) · 8 unmodified lines | ||
| 3585 | 3585 | return ret; |
| 3586 | 3586 | } |
| 3587 | 3587 | |
| 3588 | −static int io_apic_setup_irq_pin_once(unsigned int irq, int node, | |
| 3589 | − struct io_apic_irq_attr *attr) | |
| 3588 | +int io_apic_setup_irq_pin_once(unsigned int irq, int node, | |
| 3589 | + struct io_apic_irq_attr *attr) | |
| 3590 | 3590 | { |
| 3591 | 3591 | unsigned int id = attr->ioapic, pin = attr->ioapic_pin; |
| 3592 | 3592 | int ret; |
| @@ -37,6 +37,13 @@ · 36 unmodified lines | ||
| 37 | 37 | #include <asm/smp.h> |
| 38 | 38 | #include <asm/x86_init.h> |
| 39 | 39 | #include <asm/emergency-restart.h> |
| 40 | +#include <asm/nmi.h> | |
| 41 | + | |
| 42 | +/* BMC sets a bit this MMR non-zero before sending an NMI */ | |
| 43 | +#define UVH_NMI_MMR UVH_SCRATCH5 | |
| 44 | +#define UVH_NMI_MMR_CLEAR (UVH_NMI_MMR + 8) | |
| 45 | +#define UV_NMI_PENDING_MASK (1UL << 63) | |
| 46 | +DEFINE_PER_CPU(unsigned long, cpu_last_nmi_count); | |
| 40 | 47 | |
| 41 | 48 | DEFINE_PER_CPU(int, x2apic_extra_bits); |
| 42 | 49 | |
| @@ -642,18 +649,46 @@ void __cpuinit uv_cpu_init(void) · 599 unmodified lines | ||
| 642 | 649 | */ |
| 643 | 650 | int uv_handle_nmi(struct notifier_block *self, unsigned long reason, void *data) |
| 644 | 651 | { |
| 652 | + unsigned long real_uv_nmi; | |
| 653 | + int bid; | |
| 654 | + | |
| 645 | 655 | if (reason != DIE_NMIUNKNOWN) |
| 646 | 656 | return NOTIFY_OK; |
| 647 | 657 | |
| 648 | 658 | if (in_crash_kexec) |
| 649 | 659 | /* do nothing if entering the crash kernel */ |
| 650 | 660 | return NOTIFY_OK; |
| 661 | + | |
| 651 | 662 | /* |
| 652 | − * Use a lock so only one cpu prints at a time | |
| 653 | − * to prevent intermixed output. | |
| 663 | + * Each blade has an MMR that indicates when an NMI has been sent | |
| 664 | + * to cpus on the blade. If an NMI is detected, atomically | |
| 665 | + * clear the MMR and update a per-blade NMI count used to | |
| 666 | + * cause each cpu on the blade to notice a new NMI. | |
| 667 | + */ | |
| 668 | + bid = uv_numa_blade_id(); | |
| 669 | + real_uv_nmi = (uv_read_local_mmr(UVH_NMI_MMR) & UV_NMI_PENDING_MASK); | |
| 670 | + | |
| 671 | + if (unlikely(real_uv_nmi)) { | |
| 672 | + spin_lock(&uv_blade_info[bid].nmi_lock); | |
| 673 | + real_uv_nmi = (uv_read_local_mmr(UVH_NMI_MMR) & UV_NMI_PENDING_MASK); | |
| 674 | + if (real_uv_nmi) { | |
| 675 | + uv_blade_info[bid].nmi_count++; | |
| 676 | + uv_write_local_mmr(UVH_NMI_MMR_CLEAR, UV_NMI_PENDING_MASK); | |
| 677 | + } | |
| 678 | + spin_unlock(&uv_blade_info[bid].nmi_lock); | |
| 679 | + } | |
| 680 | + | |
| 681 | + if (likely(__get_cpu_var(cpu_last_nmi_count) == uv_blade_info[bid].nmi_count)) | |
| 682 | + return NOTIFY_DONE; | |
| 683 | + | |
| 684 | + __get_cpu_var(cpu_last_nmi_count) = uv_blade_info[bid].nmi_count; | |
| 685 | + | |
| 686 | + /* | |
| 687 | + * Use a lock so only one cpu prints at a time. | |
| 688 | + * This prevents intermixed output. | |
| 654 | 689 | */ |
| 655 | 690 | spin_lock(&uv_nmi_lock); |
| 656 | − pr_info("NMI stack dump cpu %u:\n", smp_processor_id()); | |
| 691 | + pr_info("UV NMI stack dump cpu %u:\n", smp_processor_id()); | |
| 657 | 692 | dump_stack(); |
| 658 | 693 | spin_unlock(&uv_nmi_lock); |
| 659 | 694 | |
| @@ -661,7 +696,8 @@ int uv_handle_nmi(struct notifier_block *self, unsigned long reason, void *data) · 1 unmodified line | ||
| 661 | 696 | } |
| 662 | 697 | |
| 663 | 698 | static struct notifier_block uv_dump_stack_nmi_nb = { |
| 664 | − .notifier_call = uv_handle_nmi | |
| 699 | + .notifier_call = uv_handle_nmi, | |
| 700 | + .priority = NMI_LOCAL_LOW_PRIOR - 1, | |
| 665 | 701 | }; |
| 666 | 702 | |
| 667 | 703 | void uv_register_nmi_notifier(void) |
| @@ -720,8 +756,9 @@ void __init uv_system_init(void) · 52 unmodified lines | ||
| 720 | 756 | printk(KERN_DEBUG "UV: Found %d blades\n", uv_num_possible_blades()); |
| 721 | 757 | |
| 722 | 758 | bytes = sizeof(struct uv_blade_info) * uv_num_possible_blades(); |
| 723 | − uv_blade_info = kmalloc(bytes, GFP_KERNEL); | |
| 759 | + uv_blade_info = kzalloc(bytes, GFP_KERNEL); | |
| 724 | 760 | BUG_ON(!uv_blade_info); |
| 761 | + | |
| 725 | 762 | for (blade = 0; blade < uv_num_possible_blades(); blade++) |
| 726 | 763 | uv_blade_info[blade].memory_nid = -1; |
| 727 | 764 | |
| @@ -747,6 +784,7 @@ void __init uv_system_init(void) · 19 unmodified lines | ||
| 747 | 784 | uv_blade_info[blade].pnode = pnode; |
| 748 | 785 | uv_blade_info[blade].nr_possible_cpus = 0; |
| 749 | 786 | uv_blade_info[blade].nr_online_cpus = 0; |
| 787 | + spin_lock_init(&uv_blade_info[blade].nmi_lock); | |
| 750 | 788 | max_pnode = max(pnode, max_pnode); |
| 751 | 789 | blade++; |
| 752 | 790 | } |
| @@ -228,6 +228,7 @@ · 227 unmodified lines | ||
| 228 | 228 | #include <linux/kthread.h> |
| 229 | 229 | #include <linux/jiffies.h> |
| 230 | 230 | #include <linux/acpi.h> |
| 231 | +#include <linux/syscore_ops.h> | |
| 231 | 232 | |
| 232 | 233 | #include <asm/system.h> |
| 233 | 234 | #include <asm/uaccess.h> |
| @@ -1238,6 +1239,7 @@ static int suspend(int vetoable) · 1004 unmodified lines | ||
| 1238 | 1239 | |
| 1239 | 1240 | local_irq_disable(); |
| 1240 | 1241 | sysdev_suspend(PMSG_SUSPEND); |
| 1242 | + syscore_suspend(); | |
| 1241 | 1243 | |
| 1242 | 1244 | local_irq_enable(); |
| 1243 | 1245 | |
| @@ -1255,6 +1257,7 @@ static int suspend(int vetoable) · 11 unmodified lines | ||
| 1255 | 1257 | apm_error("suspend", err); |
| 1256 | 1258 | err = (err == APM_SUCCESS) ? 0 : -EIO; |
| 1257 | 1259 | |
| 1260 | + syscore_resume(); | |
| 1258 | 1261 | sysdev_resume(); |
| 1259 | 1262 | local_irq_enable(); |
| 1260 | 1263 | |
| @@ -1280,6 +1283,7 @@ static void standby(void) · 19 unmodified lines | ||
| 1280 | 1283 | |
| 1281 | 1284 | local_irq_disable(); |
| 1282 | 1285 | sysdev_suspend(PMSG_SUSPEND); |
| 1286 | + syscore_suspend(); | |
| 1283 | 1287 | local_irq_enable(); |
| 1284 | 1288 | |
| 1285 | 1289 | err = set_system_power_state(APM_STATE_STANDBY); |
| @@ -1287,6 +1291,7 @@ static void standby(void) · 1 unmodified line | ||
| 1287 | 1291 | apm_error("standby", err); |
| 1288 | 1292 | |
| 1289 | 1293 | local_irq_disable(); |
| 1294 | + syscore_resume(); | |
| 1290 | 1295 | sysdev_resume(); |
| 1291 | 1296 | local_irq_enable(); |
| 1292 | 1297 | |
| @@ -613,7 +613,7 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) · 612 unmodified lines | ||
| 613 | 613 | #endif |
| 614 | 614 | |
| 615 | 615 | /* As a rule processors have APIC timer running in deep C states */ |
| 616 | − if (c->x86 >= 0xf && !cpu_has_amd_erratum(amd_erratum_400)) | |
| 616 | + if (c->x86 > 0xf && !cpu_has_amd_erratum(amd_erratum_400)) | |
| 617 | 617 | set_cpu_cap(c, X86_FEATURE_ARAT); |
| 618 | 618 | |
| 619 | 619 | /* |
| @@ -509,6 +509,7 @@ recurse: · 508 unmodified lines | ||
| 509 | 509 | out_free: |
| 510 | 510 | if (b) { |
| 511 | 511 | kobject_put(&b->kobj); |
| 512 | + list_del(&b->miscj); | |
| 512 | 513 | kfree(b); |
| 513 | 514 | } |
| 514 | 515 | return err; |
| @@ -446,18 +446,20 @@ void intel_init_thermal(struct cpuinfo_x86 *c) · 445 unmodified lines | ||
| 446 | 446 | */ |
| 447 | 447 | rdmsr(MSR_IA32_MISC_ENABLE, l, h); |
| 448 | 448 | |
| 449 | + h = lvtthmr_init; | |
| 449 | 450 | /* |
| 450 | 451 | * The initial value of thermal LVT entries on all APs always reads |
| 451 | 452 | * 0x10000 because APs are woken up by BSP issuing INIT-SIPI-SIPI |
| 452 | 453 | * sequence to them and LVT registers are reset to 0s except for |
| 453 | 454 | * the mask bits which are set to 1s when APs receive INIT IPI. |
| 454 | − * Always restore the value that BIOS has programmed on AP based on | |
| 455 | − * BSP's info we saved since BIOS is always setting the same value | |
| 456 | − * for all threads/cores | |
| 455 | + * If BIOS takes over the thermal interrupt and sets its interrupt | |
| 456 | + * delivery mode to SMI (not fixed), it restores the value that the | |
| 457 | + * BIOS has programmed on AP based on BSP's info we saved since BIOS | |
| 458 | + * is always setting the same value for all threads/cores. | |
| 457 | 459 | */ |
| 458 | − apic_write(APIC_LVTTHMR, lvtthmr_init); | |
| 460 | + if ((h & APIC_DM_FIXED_MASK) != APIC_DM_FIXED) | |
| 461 | + apic_write(APIC_LVTTHMR, lvtthmr_init); | |
| 459 | 462 | |
| 460 | − h = lvtthmr_init; | |
| 461 | 463 | |
| 462 | 464 | if ((l & MSR_IA32_MISC_ENABLE_TM1) && (h & APIC_DM_SMI)) { |
| 463 | 465 | printk(KERN_DEBUG |
| @@ -586,8 +586,12 @@ static int x86_setup_perfctr(struct perf_event *event) · 585 unmodified lines | ||
| 586 | 586 | return -EOPNOTSUPP; |
| 587 | 587 | } |
| 588 | 588 | |
| 589 | + /* | |
| 590 | + * Do not allow config1 (extended registers) to propagate, | |
| 591 | + * there's no sane user-space generalization yet: | |
| 592 | + */ | |
| 589 | 593 | if (attr->type == PERF_TYPE_RAW) |
| 590 | − return x86_pmu_extra_regs(event->attr.config, event); | |
| 594 | + return 0; | |
| 591 | 595 | |
| 592 | 596 | if (attr->type == PERF_TYPE_HW_CACHE) |
| 593 | 597 | return set_ext_hw_attr(hwc, event); |
| @@ -609,8 +613,8 @@ static int x86_setup_perfctr(struct perf_event *event) · 15 unmodified lines | ||
| 609 | 613 | /* |
| 610 | 614 | * Branch tracing: |
| 611 | 615 | */ |
| 612 | − if ((attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS) && | |
| 613 | − (hwc->sample_period == 1)) { | |
| 616 | + if (attr->config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS && | |
| 617 | + !attr->freq && hwc->sample_period == 1) { | |
| 614 | 618 | /* BTS is not supported by this architecture. */ |
| 615 | 619 | if (!x86_pmu.bts_active) |
| 616 | 620 | return -EOPNOTSUPP; |
| @@ -1284,6 +1288,16 @@ static int x86_pmu_handle_irq(struct pt_regs *regs) · 667 unmodified lines | ||
| 1284 | 1288 | |
| 1285 | 1289 | cpuc = &__get_cpu_var(cpu_hw_events); |
| 1286 | 1290 | |
| 1291 | + /* | |
| 1292 | + * Some chipsets need to unmask the LVTPC in a particular spot | |
| 1293 | + * inside the nmi handler. As a result, the unmasking was pushed | |
| 1294 | + * into all the nmi handlers. | |
| 1295 | + * | |
| 1296 | + * This generic handler doesn't seem to have any issues where the | |
| 1297 | + * unmasking occurs so it was left at the top. | |
| 1298 | + */ | |
| 1299 | + apic_write(APIC_LVTPC, APIC_DM_NMI); | |
| 1300 | + | |
| 1287 | 1301 | for (idx = 0; idx < x86_pmu.num_counters; idx++) { |
| 1288 | 1302 | if (!test_bit(idx, cpuc->active_mask)) { |
| 1289 | 1303 | /* |
| @@ -1370,8 +1384,6 @@ perf_event_nmi_handler(struct notifier_block *self, · 80 unmodified lines | ||
| 1370 | 1384 | return NOTIFY_DONE; |
| 1371 | 1385 | } |
| 1372 | 1386 | |
| 1373 | − apic_write(APIC_LVTPC, APIC_DM_NMI); | |
| 1374 | − | |
| 1375 | 1387 | handled = x86_pmu.handle_irq(args->regs); |
| 1376 | 1388 | if (!handled) |
| 1377 | 1389 | return NOTIFY_DONE; |
| @@ -8,7 +8,7 @@ static __initconst const u64 amd_hw_cache_event_ids · 7 unmodified lines | ||
| 8 | 8 | [ C(L1D) ] = { |
| 9 | 9 | [ C(OP_READ) ] = { |
| 10 | 10 | [ C(RESULT_ACCESS) ] = 0x0040, /* Data Cache Accesses */ |
| 11 | − [ C(RESULT_MISS) ] = 0x0041, /* Data Cache Misses */ | |
| 11 | + [ C(RESULT_MISS) ] = 0x0141, /* Data Cache Misses */ | |
| 12 | 12 | }, |
| 13 | 13 | [ C(OP_WRITE) ] = { |
| 14 | 14 | [ C(RESULT_ACCESS) ] = 0x0142, /* Data Cache Refills :system */ |
| @@ -427,7 +427,9 @@ static __initconst const struct x86_pmu amd_pmu = { · 412 unmodified lines | ||
| 427 | 427 | * |
| 428 | 428 | * Exceptions: |
| 429 | 429 | * |
| 430 | + * 0x000 FP PERF_CTL[3], PERF_CTL[5:3] (*) | |
| 430 | 431 | * 0x003 FP PERF_CTL[3] |
| 432 | + * 0x004 FP PERF_CTL[3], PERF_CTL[5:3] (*) | |
| 431 | 433 | * 0x00B FP PERF_CTL[3] |
| 432 | 434 | * 0x00D FP PERF_CTL[3] |
| 433 | 435 | * 0x023 DE PERF_CTL[2:0] |
| @@ -448,6 +450,8 @@ static __initconst const struct x86_pmu amd_pmu = { · 14 unmodified lines | ||
| 448 | 450 | * 0x0DF LS PERF_CTL[5:0] |
| 449 | 451 | * 0x1D6 EX PERF_CTL[5:0] |
| 450 | 452 | * 0x1D8 EX PERF_CTL[5:0] |
| 453 | + * | |
| 454 | + * (*) depending on the umask all FPU counters may be used | |
| 451 | 455 | */ |
| 452 | 456 | |
| 453 | 457 | static struct event_constraint amd_f15_PMC0 = EVENT_CONSTRAINT(0, 0x01, 0); |
| @@ -460,18 +464,28 @@ static struct event_constraint amd_f15_PMC53 = EVENT_CONSTRAINT(0, 0x38, 0); · 6 unmodified lines | ||
| 460 | 464 | static struct event_constraint * |
| 461 | 465 | amd_get_event_constraints_f15h(struct cpu_hw_events *cpuc, struct perf_event *event) |
| 462 | 466 | { |
| 463 | − unsigned int event_code = amd_get_event_code(&event->hw); | |
| 467 | + struct hw_perf_event *hwc = &event->hw; | |
| 468 | + unsigned int event_code = amd_get_event_code(hwc); | |
| 464 | 469 | |
| 465 | 470 | switch (event_code & AMD_EVENT_TYPE_MASK) { |
| 466 | 471 | case AMD_EVENT_FP: |
| 467 | 472 | switch (event_code) { |
| 473 | + case 0x000: | |
| 474 | + if (!(hwc->config & 0x0000F000ULL)) | |
| 475 | + break; | |
| 476 | + if (!(hwc->config & 0x00000F00ULL)) | |
| 477 | + break; | |
| 478 | + return &amd_f15_PMC3; | |
| 479 | + case 0x004: | |
| 480 | + if (hweight_long(hwc->config & ARCH_PERFMON_EVENTSEL_UMASK) <= 1) | |
| 481 | + break; | |
| 482 | + return &amd_f15_PMC3; | |
| 468 | 483 | case 0x003: |
| 469 | 484 | case 0x00B: |
| 470 | 485 | case 0x00D: |
| 471 | 486 | return &amd_f15_PMC3; |
| 472 | − default: | |
| 473 | − return &amd_f15_PMC53; | |
| 474 | 487 | } |
| 488 | + return &amd_f15_PMC53; | |
| 475 | 489 | case AMD_EVENT_LS: |
| 476 | 490 | case AMD_EVENT_DC: |
| 477 | 491 | case AMD_EVENT_EX_LS: |
| @@ -25,7 +25,7 @@ struct intel_percore { · 24 unmodified lines | ||
| 25 | 25 | /* |
| 26 | 26 | * Intel PerfMon, used on Core and later. |
| 27 | 27 | */ |
| 28 | −static const u64 intel_perfmon_event_map[] = | |
| 28 | +static u64 intel_perfmon_event_map[PERF_COUNT_HW_MAX] __read_mostly = | |
| 29 | 29 | { |
| 30 | 30 | [PERF_COUNT_HW_CPU_CYCLES] = 0x003c, |
| 31 | 31 | [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, |
| @@ -184,26 +184,23 @@ static __initconst const u64 snb_hw_cache_event_ids · 152 unmodified lines | ||
| 184 | 184 | }, |
| 185 | 185 | }, |
| 186 | 186 | [ C(LL ) ] = { |
| 187 | − /* | |
| 188 | − * TBD: Need Off-core Response Performance Monitoring support | |
| 189 | − */ | |
| 190 | 187 | [ C(OP_READ) ] = { |
| 191 | − /* OFFCORE_RESPONSE_0.ANY_DATA.LOCAL_CACHE */ | |
| 188 | + /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */ | |
| 192 | 189 | [ C(RESULT_ACCESS) ] = 0x01b7, |
| 193 | − /* OFFCORE_RESPONSE_1.ANY_DATA.ANY_LLC_MISS */ | |
| 194 | − [ C(RESULT_MISS) ] = 0x01bb, | |
| 190 | + /* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */ | |
| 191 | + [ C(RESULT_MISS) ] = 0x01b7, | |
| 195 | 192 | }, |
| 196 | 193 | [ C(OP_WRITE) ] = { |
| 197 | − /* OFFCORE_RESPONSE_0.ANY_RFO.LOCAL_CACHE */ | |
| 194 | + /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */ | |
| 198 | 195 | [ C(RESULT_ACCESS) ] = 0x01b7, |
| 199 | − /* OFFCORE_RESPONSE_1.ANY_RFO.ANY_LLC_MISS */ | |
| 200 | − [ C(RESULT_MISS) ] = 0x01bb, | |
| 196 | + /* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */ | |
| 197 | + [ C(RESULT_MISS) ] = 0x01b7, | |
| 201 | 198 | }, |
| 202 | 199 | [ C(OP_PREFETCH) ] = { |
| 203 | − /* OFFCORE_RESPONSE_0.PREFETCH.LOCAL_CACHE */ | |
| 200 | + /* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */ | |
| 204 | 201 | [ C(RESULT_ACCESS) ] = 0x01b7, |
| 205 | − /* OFFCORE_RESPONSE_1.PREFETCH.ANY_LLC_MISS */ | |
| 206 | − [ C(RESULT_MISS) ] = 0x01bb, | |
| 202 | + /* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */ | |
| 203 | + [ C(RESULT_MISS) ] = 0x01b7, | |
| 207 | 204 | }, |
| 208 | 205 | }, |
| 209 | 206 | [ C(DTLB) ] = { |
| @@ -285,26 +282,26 @@ static __initconst const u64 westmere_hw_cache_event_ids · 75 unmodified lines | ||
| 285 | 282 | }, |
| 286 | 283 | [ C(LL ) ] = { |
| 287 | 284 | [ C(OP_READ) ] = { |
| 288 | − /* OFFCORE_RESPONSE_0.ANY_DATA.LOCAL_CACHE */ | |
| 285 | + /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */ | |
| 289 | 286 | [ C(RESULT_ACCESS) ] = 0x01b7, |
| 290 | − /* OFFCORE_RESPONSE_1.ANY_DATA.ANY_LLC_MISS */ | |
| 291 | − [ C(RESULT_MISS) ] = 0x01bb, | |
| 287 | + /* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */ | |
| 288 | + [ C(RESULT_MISS) ] = 0x01b7, | |
| 292 | 289 | }, |
| 293 | 290 | /* |
| 294 | 291 | * Use RFO, not WRITEBACK, because a write miss would typically occur |
| 295 | 292 | * on RFO. |
| 296 | 293 | */ |
| 297 | 294 | [ C(OP_WRITE) ] = { |
| 298 | − /* OFFCORE_RESPONSE_1.ANY_RFO.LOCAL_CACHE */ | |
| 299 | − [ C(RESULT_ACCESS) ] = 0x01bb, | |
| 300 | − /* OFFCORE_RESPONSE_0.ANY_RFO.ANY_LLC_MISS */ | |
| 295 | + /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */ | |
| 296 | + [ C(RESULT_ACCESS) ] = 0x01b7, | |
| 297 | + /* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */ | |
| 301 | 298 | [ C(RESULT_MISS) ] = 0x01b7, |
| 302 | 299 | }, |
| 303 | 300 | [ C(OP_PREFETCH) ] = { |
| 304 | − /* OFFCORE_RESPONSE_0.PREFETCH.LOCAL_CACHE */ | |
| 301 | + /* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */ | |
| 305 | 302 | [ C(RESULT_ACCESS) ] = 0x01b7, |
| 306 | − /* OFFCORE_RESPONSE_1.PREFETCH.ANY_LLC_MISS */ | |
| 307 | − [ C(RESULT_MISS) ] = 0x01bb, | |
| 303 | + /* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */ | |
| 304 | + [ C(RESULT_MISS) ] = 0x01b7, | |
| 308 | 305 | }, |
| 309 | 306 | }, |
| 310 | 307 | [ C(DTLB) ] = { |
| @@ -352,16 +349,36 @@ static __initconst const u64 westmere_hw_cache_event_ids · 41 unmodified lines | ||
| 352 | 349 | }; |
| 353 | 350 | |
| 354 | 351 | /* |
| 355 | − * OFFCORE_RESPONSE MSR bits (subset), See IA32 SDM Vol 3 30.6.1.3 | |
| 352 | + * Nehalem/Westmere MSR_OFFCORE_RESPONSE bits; | |
| 353 | + * See IA32 SDM Vol 3B 30.6.1.3 | |
| 356 | 354 | */ |
| 357 | 355 | |
| 358 | −#define DMND_DATA_RD (1 << 0) | |
| 359 | −#define DMND_RFO (1 << 1) | |
| 360 | −#define DMND_WB (1 << 3) | |
| 361 | −#define PF_DATA_RD (1 << 4) | |
| 362 | −#define PF_DATA_RFO (1 << 5) | |
| 363 | −#define RESP_UNCORE_HIT (1 << 8) | |
| 364 | −#define RESP_MISS (0xf600) /* non uncore hit */ | |
| 356 | +#define NHM_DMND_DATA_RD (1 << 0) | |
| 357 | +#define NHM_DMND_RFO (1 << 1) | |
| 358 | +#define NHM_DMND_IFETCH (1 << 2) | |
| 359 | +#define NHM_DMND_WB (1 << 3) | |
| 360 | +#define NHM_PF_DATA_RD (1 << 4) | |
| 361 | +#define NHM_PF_DATA_RFO (1 << 5) | |
| 362 | +#define NHM_PF_IFETCH (1 << 6) | |
| 363 | +#define NHM_OFFCORE_OTHER (1 << 7) | |
| 364 | +#define NHM_UNCORE_HIT (1 << 8) | |
| 365 | +#define NHM_OTHER_CORE_HIT_SNP (1 << 9) | |
| 366 | +#define NHM_OTHER_CORE_HITM (1 << 10) | |
| 367 | + /* reserved */ | |
| 368 | +#define NHM_REMOTE_CACHE_FWD (1 << 12) | |
| 369 | +#define NHM_REMOTE_DRAM (1 << 13) | |
| 370 | +#define NHM_LOCAL_DRAM (1 << 14) | |
| 371 | +#define NHM_NON_DRAM (1 << 15) | |
| 372 | + | |
| 373 | +#define NHM_ALL_DRAM (NHM_REMOTE_DRAM|NHM_LOCAL_DRAM) | |
| 374 | + | |
| 375 | +#define NHM_DMND_READ (NHM_DMND_DATA_RD) | |
| 376 | +#define NHM_DMND_WRITE (NHM_DMND_RFO|NHM_DMND_WB) | |
| 377 | +#define NHM_DMND_PREFETCH (NHM_PF_DATA_RD|NHM_PF_DATA_RFO) | |
| 378 | + | |
| 379 | +#define NHM_L3_HIT (NHM_UNCORE_HIT|NHM_OTHER_CORE_HIT_SNP|NHM_OTHER_CORE_HITM) | |
| 380 | +#define NHM_L3_MISS (NHM_NON_DRAM|NHM_ALL_DRAM|NHM_REMOTE_CACHE_FWD) | |
| 381 | +#define NHM_L3_ACCESS (NHM_L3_HIT|NHM_L3_MISS) | |
| 365 | 382 | |
| 366 | 383 | static __initconst const u64 nehalem_hw_cache_extra_regs |
| 367 | 384 | [PERF_COUNT_HW_CACHE_MAX] |
| @@ -370,16 +387,16 @@ static __initconst const u64 nehalem_hw_cache_extra_regs · 2 unmodified lines | ||
| 370 | 387 | { |
| 371 | 388 | [ C(LL ) ] = { |
| 372 | 389 | [ C(OP_READ) ] = { |
| 373 | − [ C(RESULT_ACCESS) ] = DMND_DATA_RD|RESP_UNCORE_HIT, | |
| 374 | − [ C(RESULT_MISS) ] = DMND_DATA_RD|RESP_MISS, | |
| 390 | + [ C(RESULT_ACCESS) ] = NHM_DMND_READ|NHM_L3_ACCESS, | |
| 391 | + [ C(RESULT_MISS) ] = NHM_DMND_READ|NHM_L3_MISS, | |
| 375 | 392 | }, |
| 376 | 393 | [ C(OP_WRITE) ] = { |
| 377 | − [ C(RESULT_ACCESS) ] = DMND_RFO|DMND_WB|RESP_UNCORE_HIT, | |
| 378 | − [ C(RESULT_MISS) ] = DMND_RFO|DMND_WB|RESP_MISS, | |
| 394 | + [ C(RESULT_ACCESS) ] = NHM_DMND_WRITE|NHM_L3_ACCESS, | |
| 395 | + [ C(RESULT_MISS) ] = NHM_DMND_WRITE|NHM_L3_MISS, | |
| 379 | 396 | }, |
| 380 | 397 | [ C(OP_PREFETCH) ] = { |
| 381 | − [ C(RESULT_ACCESS) ] = PF_DATA_RD|PF_DATA_RFO|RESP_UNCORE_HIT, | |
| 382 | − [ C(RESULT_MISS) ] = PF_DATA_RD|PF_DATA_RFO|RESP_MISS, | |
| 398 | + [ C(RESULT_ACCESS) ] = NHM_DMND_PREFETCH|NHM_L3_ACCESS, | |
| 399 | + [ C(RESULT_MISS) ] = NHM_DMND_PREFETCH|NHM_L3_MISS, | |
| 383 | 400 | }, |
| 384 | 401 | } |
| 385 | 402 | }; |
| @@ -391,12 +408,12 @@ static __initconst const u64 nehalem_hw_cache_event_ids · 5 unmodified lines | ||
| 391 | 408 | { |
| 392 | 409 | [ C(L1D) ] = { |
| 393 | 410 | [ C(OP_READ) ] = { |
| 394 | − [ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI */ | |
| 395 | − [ C(RESULT_MISS) ] = 0x0140, /* L1D_CACHE_LD.I_STATE */ | |
| 411 | + [ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS */ | |
| 412 | + [ C(RESULT_MISS) ] = 0x0151, /* L1D.REPL */ | |
| 396 | 413 | }, |
| 397 | 414 | [ C(OP_WRITE) ] = { |
| 398 | − [ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI */ | |
| 399 | − [ C(RESULT_MISS) ] = 0x0141, /* L1D_CACHE_ST.I_STATE */ | |
| 415 | + [ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES */ | |
| 416 | + [ C(RESULT_MISS) ] = 0x0251, /* L1D.M_REPL */ | |
| 400 | 417 | }, |
| 401 | 418 | [ C(OP_PREFETCH) ] = { |
| 402 | 419 | [ C(RESULT_ACCESS) ] = 0x014e, /* L1D_PREFETCH.REQUESTS */ |
| @@ -933,6 +950,16 @@ static int intel_pmu_handle_irq(struct pt_regs *regs) · 530 unmodified lines | ||
| 933 | 950 | |
| 934 | 951 | cpuc = &__get_cpu_var(cpu_hw_events); |
| 935 | 952 | |
| 953 | + /* | |
| 954 | + * Some chipsets need to unmask the LVTPC in a particular spot | |
| 955 | + * inside the nmi handler. As a result, the unmasking was pushed | |
| 956 | + * into all the nmi handlers. | |
| 957 | + * | |
| 958 | + * This handler doesn't seem to have any issues with the unmasking | |
| 959 | + * so it was left at the top. | |
| 960 | + */ | |
| 961 | + apic_write(APIC_LVTPC, APIC_DM_NMI); | |
| 962 | + | |
| 936 | 963 | intel_pmu_disable_all(); |
| 937 | 964 | handled = intel_pmu_drain_bts_buffer(); |
| 938 | 965 | status = intel_pmu_get_status(); |
| @@ -998,6 +1025,9 @@ intel_bts_constraints(struct perf_event *event) · 59 unmodified lines | ||
| 998 | 1025 | struct hw_perf_event *hwc = &event->hw; |
| 999 | 1026 | unsigned int hw_event, bts_event; |
| 1000 | 1027 | |
| 1028 | + if (event->attr.freq) | |
| 1029 | + return NULL; | |
| 1030 | + | |
| 1001 | 1031 | hw_event = hwc->config & INTEL_ARCH_EVENT_MASK; |
| 1002 | 1032 | bts_event = x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS); |
| 1003 | 1033 | |
| @@ -1305,7 +1335,7 @@ static void intel_clovertown_quirks(void) · 301 unmodified lines | ||
| 1305 | 1335 | * AJ106 could possibly be worked around by not allowing LBR |
| 1306 | 1336 | * usage from PEBS, including the fixup. |
| 1307 | 1337 | * AJ68 could possibly be worked around by always programming |
| 1308 | − * a pebs_event_reset[0] value and coping with the lost events. | |
| 1338 | + * a pebs_event_reset[0] value and coping with the lost events. | |
| 1309 | 1339 | * |
| 1310 | 1340 | * But taken together it might just make sense to not enable PEBS on |
| 1311 | 1341 | * these chips. |
| @@ -1409,6 +1439,18 @@ static __init int intel_pmu_init(void) · 97 unmodified lines | ||
| 1409 | 1439 | x86_pmu.percore_constraints = intel_nehalem_percore_constraints; |
| 1410 | 1440 | x86_pmu.enable_all = intel_pmu_nhm_enable_all; |
| 1411 | 1441 | x86_pmu.extra_regs = intel_nehalem_extra_regs; |
| 1442 | + | |
| 1443 | + if (ebx & 0x40) { | |
| 1444 | + /* | |
| 1445 | + * Erratum AAJ80 detected, we work it around by using | |
| 1446 | + * the BR_MISP_EXEC.ANY event. This will over-count | |
| 1447 | + * branch-misses, but it's still much better than the | |
| 1448 | + * architectural event which is often completely bogus: | |
| 1449 | + */ | |
| 1450 | + intel_perfmon_event_map[PERF_COUNT_HW_BRANCH_MISSES] = 0x7f89; | |
| 1451 | + | |
| 1452 | + pr_cont("erratum AAJ80 worked around, "); | |
| 1453 | + } | |
| 1412 | 1454 | pr_cont("Nehalem events, "); |
| 1413 | 1455 | break; |
| 1414 | 1456 | |
| @@ -1425,6 +1467,7 @@ static __init int intel_pmu_init(void) · 10 unmodified lines | ||
| 1425 | 1467 | |
| 1426 | 1468 | case 37: /* 32 nm nehalem, "Clarkdale" */ |
| 1427 | 1469 | case 44: /* 32 nm nehalem, "Gulftown" */ |
| 1470 | + case 47: /* 32 nm Xeon E7 */ | |
| 1428 | 1471 | memcpy(hw_cache_event_ids, westmere_hw_cache_event_ids, |
| 1429 | 1472 | sizeof(hw_cache_event_ids)); |
| 1430 | 1473 | memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs, |
| @@ -947,14 +947,23 @@ static int p4_pmu_handle_irq(struct pt_regs *regs) · 946 unmodified lines | ||
| 947 | 947 | if (!x86_perf_event_set_period(event)) |
| 948 | 948 | continue; |
| 949 | 949 | if (perf_event_overflow(event, 1, &data, regs)) |
| 950 | − p4_pmu_disable_event(event); | |
| 950 | + x86_pmu_stop(event, 0); | |
| 951 | 951 | } |
| 952 | 952 | |
| 953 | − if (handled) { | |
| 954 | − /* p4 quirk: unmask it again */ | |
| 955 | − apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED); | |
| 953 | + if (handled) | |
| 956 | 954 | inc_irq_stat(apic_perf_irqs); |
| 957 | − } | |
| 955 | + | |
| 956 | + /* | |
| 957 | + * When dealing with the unmasking of the LVTPC on P4 perf hw, it has | |
| 958 | + * been observed that the OVF bit flag has to be cleared first _before_ | |
| 959 | + * the LVTPC can be unmasked. | |
| 960 | + * | |
| 961 | + * The reason is the NMI line will continue to be asserted while the OVF | |
| 962 | + * bit is set. This causes a second NMI to generate if the LVTPC is | |
| 963 | + * unmasked before the OVF bit is cleared, leading to unknown NMI | |
| 964 | + * messages. | |
| 965 | + */ | |
| 966 | + apic_write(APIC_LVTPC, APIC_DM_NMI); | |
| 958 | 967 | |
| 959 | 968 | return handled; |
| 960 | 969 | } |
| @@ -391,7 +391,7 @@ static int ioapic_xlate(struct irq_domain *id, const u32 *intspec, u32 intsize, · 390 unmodified lines | ||
| 391 | 391 | |
| 392 | 392 | set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity); |
| 393 | 393 | |
| 394 | − return io_apic_setup_irq_pin(*out_hwirq, cpu_to_node(0), &attr); | |
| 394 | + return io_apic_setup_irq_pin_once(*out_hwirq, cpu_to_node(0), &attr); | |
| 395 | 395 | } |
| 396 | 396 | |
| 397 | 397 | static void __init ioapic_add_ofnode(struct device_node *np) |
| @@ -1183,12 +1183,13 @@ static void __kprobes optimized_callback(struct optimized_kprobe *op, · 1182 unmodified lines | ||
| 1183 | 1183 | struct pt_regs *regs) |
| 1184 | 1184 | { |
| 1185 | 1185 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
| 1186 | + unsigned long flags; | |
| 1186 | 1187 | |
| 1187 | 1188 | /* This is possible if op is under delayed unoptimizing */ |
| 1188 | 1189 | if (kprobe_disabled(&op->kp)) |
| 1189 | 1190 | return; |
| 1190 | 1191 | |
| 1191 | − preempt_disable(); | |
| 1192 | + local_irq_save(flags); | |
| 1192 | 1193 | if (kprobe_running()) { |
| 1193 | 1194 | kprobes_inc_nmissed_count(&op->kp); |
| 1194 | 1195 | } else { |
| @@ -1207,7 +1208,7 @@ static void __kprobes optimized_callback(struct optimized_kprobe *op, · 12 unmodified lines | ||
| 1207 | 1208 | opt_pre_handler(&op->kp, regs); |
| 1208 | 1209 | __this_cpu_write(current_kprobe, NULL); |
| 1209 | 1210 | } |
| 1210 | − preempt_enable_no_resched(); | |
| 1211 | + local_irq_restore(flags); | |
| 1211 | 1212 | } |
| 1212 | 1213 | |
| 1213 | 1214 | static int __kprobes copy_optimized_instructions(u8 *dest, u8 *src) |
| @@ -81,6 +81,9 @@ static u32 gart_unmapped_entry; · 80 unmodified lines | ||
| 81 | 81 | #define AGPEXTERN |
| 82 | 82 | #endif |
| 83 | 83 | |
| 84 | +/* GART can only remap to physical addresses < 1TB */ | |
| 85 | +#define GART_MAX_PHYS_ADDR (1ULL << 40) | |
| 86 | + | |
| 84 | 87 | /* backdoor interface to AGP driver */ |
| 85 | 88 | AGPEXTERN int agp_memory_reserved; |
| 86 | 89 | AGPEXTERN __u32 *agp_gatt_table; |
| @@ -212,9 +215,13 @@ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem, · 125 unmodified lines | ||
| 212 | 215 | size_t size, int dir, unsigned long align_mask) |
| 213 | 216 | { |
| 214 | 217 | unsigned long npages = iommu_num_pages(phys_mem, size, PAGE_SIZE); |
| 215 | − unsigned long iommu_page = alloc_iommu(dev, npages, align_mask); | |
| 218 | + unsigned long iommu_page; | |
| 216 | 219 | int i; |
| 217 | 220 | |
| 221 | + if (unlikely(phys_mem + size > GART_MAX_PHYS_ADDR)) | |
| 222 | + return bad_dma_addr; | |
| 223 | + | |
| 224 | + iommu_page = alloc_iommu(dev, npages, align_mask); | |
| 218 | 225 | if (iommu_page == -1) { |
| 219 | 226 | if (!nonforced_iommu(dev, phys_mem, size)) |
| 220 | 227 | return phys_mem; |
| @@ -608,6 +608,9 @@ static int ptrace_write_dr7(struct task_struct *tsk, unsigned long data) · 607 unmodified lines | ||
| 608 | 608 | unsigned len, type; |
| 609 | 609 | struct perf_event *bp; |
| 610 | 610 | |
| 611 | + if (ptrace_get_breakpoints(tsk) < 0) | |
| 612 | + return -ESRCH; | |
| 613 | + | |
| 611 | 614 | data &= ~DR_CONTROL_RESERVED; |
| 612 | 615 | old_dr7 = ptrace_get_dr7(thread->ptrace_bps); |
| 613 | 616 | restore: |
| @@ -655,6 +658,9 @@ restore: · 41 unmodified lines | ||
| 655 | 658 | } |
| 656 | 659 | goto restore; |
| 657 | 660 | } |
| 661 | + | |
| 662 | + ptrace_put_breakpoints(tsk); | |
| 663 | + | |
| 658 | 664 | return ((orig_ret < 0) ? orig_ret : rc); |
| 659 | 665 | } |
| 660 | 666 | |
| @@ -668,10 +674,17 @@ static unsigned long ptrace_get_debugreg(struct task_struct *tsk, int n) · 7 unmodified lines | ||
| 668 | 674 | |
| 669 | 675 | if (n < HBP_NUM) { |
| 670 | 676 | struct perf_event *bp; |
| 677 | + | |
| 678 | + if (ptrace_get_breakpoints(tsk) < 0) | |
| 679 | + return -ESRCH; | |
| 680 | + | |
| 671 | 681 | bp = thread->ptrace_bps[n]; |
| 672 | 682 | if (!bp) |
| 673 | − return 0; | |
| 674 | − val = bp->hw.info.address; | |
| 683 | + val = 0; | |
| 684 | + else | |
| 685 | + val = bp->hw.info.address; | |
| 686 | + | |
| 687 | + ptrace_put_breakpoints(tsk); | |
| 675 | 688 | } else if (n == 6) { |
| 676 | 689 | val = thread->debugreg6; |
| 677 | 690 | } else if (n == 7) { |
| @@ -686,6 +699,10 @@ static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr, · 8 unmodified lines | ||
| 686 | 699 | struct perf_event *bp; |
| 687 | 700 | struct thread_struct *t = &tsk->thread; |
| 688 | 701 | struct perf_event_attr attr; |
| 702 | + int err = 0; | |
| 703 | + | |
| 704 | + if (ptrace_get_breakpoints(tsk) < 0) | |
| 705 | + return -ESRCH; | |
| 689 | 706 | |
| 690 | 707 | if (!t->ptrace_bps[nr]) { |
| 691 | 708 | ptrace_breakpoint_init(&attr); |
| @@ -709,24 +726,23 @@ static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr, · 17 unmodified lines | ||
| 709 | 726 | * writing for the user. And anyway this is the previous |
| 710 | 727 | * behaviour. |
| 711 | 728 | */ |
| 712 | − if (IS_ERR(bp)) | |
| 713 | − return PTR_ERR(bp); | |
| 729 | + if (IS_ERR(bp)) { | |
| 730 | + err = PTR_ERR(bp); | |
| 731 | + goto put; | |
| 732 | + } | |
| 714 | 733 | |
| 715 | 734 | t->ptrace_bps[nr] = bp; |
| 716 | 735 | } else { |
| 717 | − int err; | |
| 718 | − | |
| 719 | 736 | bp = t->ptrace_bps[nr]; |
| 720 | 737 | |
| 721 | 738 | attr = bp->attr; |
| 722 | 739 | attr.bp_addr = addr; |
| 723 | 740 | err = modify_user_hw_breakpoint(bp, &attr); |
| 724 | − if (err) | |
| 725 | − return err; | |
| 726 | 741 | } |
| 727 | 742 | |
| 728 | − | |
| 729 | − return 0; | |
| 743 | +put: | |
| 744 | + ptrace_put_breakpoints(tsk); | |
| 745 | + return err; | |
| 730 | 746 | } |
| 731 | 747 | |
| 732 | 748 | /* |
| @@ -21,26 +21,26 @@ r_base = . · 20 unmodified lines | ||
| 21 | 21 | /* Get our own relocated address */ |
| 22 | 22 | call 1f |
| 23 | 23 | 1: popl %ebx |
| 24 | − subl $1b, %ebx | |
| 24 | + subl $(1b - r_base), %ebx | |
| 25 | 25 | |
| 26 | 26 | /* Compute the equivalent real-mode segment */ |
| 27 | 27 | movl %ebx, %ecx |
| 28 | 28 | shrl $4, %ecx |
| 29 | 29 | |
| 30 | 30 | /* Patch post-real-mode segment jump */ |
| 31 | − movw dispatch_table(%ebx,%eax,2),%ax | |
| 32 | − movw %ax, 101f(%ebx) | |
| 33 | − movw %cx, 102f(%ebx) | |
| 31 | + movw (dispatch_table - r_base)(%ebx,%eax,2),%ax | |
| 32 | + movw %ax, (101f - r_base)(%ebx) | |
| 33 | + movw %cx, (102f - r_base)(%ebx) | |
| 34 | 34 | |
| 35 | 35 | /* Set up the IDT for real mode. */ |
| 36 | − lidtl machine_real_restart_idt(%ebx) | |
| 36 | + lidtl (machine_real_restart_idt - r_base)(%ebx) | |
| 37 | 37 | |
| 38 | 38 | /* |
| 39 | 39 | * Set up a GDT from which we can load segment descriptors for real |
| 40 | 40 | * mode. The GDT is not used in real mode; it is just needed here to |
| 41 | 41 | * prepare the descriptors. |
| 42 | 42 | */ |
| 43 | − lgdtl machine_real_restart_gdt(%ebx) | |
| 43 | + lgdtl (machine_real_restart_gdt - r_base)(%ebx) | |
| 44 | 44 | |
| 45 | 45 | /* |
| 46 | 46 | * Load the data segment registers with 16-bit compatible values |
| @@ -312,26 +312,6 @@ void __cpuinit smp_store_cpu_info(int id) · 311 unmodified lines | ||
| 312 | 312 | identify_secondary_cpu(c); |
| 313 | 313 | } |
| 314 | 314 | |
| 315 | −static void __cpuinit check_cpu_siblings_on_same_node(int cpu1, int cpu2) | |
| 316 | −{ | |
| 317 | − int node1 = early_cpu_to_node(cpu1); | |
| 318 | − int node2 = early_cpu_to_node(cpu2); | |
| 319 | − | |
| 320 | − /* | |
| 321 | − * Our CPU scheduler assumes all logical cpus in the same physical cpu | |
| 322 | − * share the same node. But, buggy ACPI or NUMA emulation might assign | |
| 323 | − * them to different node. Fix it. | |
| 324 | − */ | |
| 325 | − if (node1 != node2) { | |
| 326 | − pr_warning("CPU %d in node %d and CPU %d in node %d are in the same physical CPU. forcing same node %d\n", | |
| 327 | − cpu1, node1, cpu2, node2, node2); | |
| 328 | − | |
| 329 | − numa_remove_cpu(cpu1); | |
| 330 | − numa_set_node(cpu1, node2); | |
| 331 | − numa_add_cpu(cpu1); | |
| 332 | − } | |
| 333 | −} | |
| 334 | − | |
| 335 | 315 | static void __cpuinit link_thread_siblings(int cpu1, int cpu2) |
| 336 | 316 | { |
| 337 | 317 | cpumask_set_cpu(cpu1, cpu_sibling_mask(cpu2)); |
| @@ -340,7 +320,6 @@ static void __cpuinit link_thread_siblings(int cpu1, int cpu2) · 2 unmodified lines | ||
| 340 | 320 | cpumask_set_cpu(cpu2, cpu_core_mask(cpu1)); |
| 341 | 321 | cpumask_set_cpu(cpu1, cpu_llc_shared_mask(cpu2)); |
| 342 | 322 | cpumask_set_cpu(cpu2, cpu_llc_shared_mask(cpu1)); |
| 343 | − check_cpu_siblings_on_same_node(cpu1, cpu2); | |
| 344 | 323 | } |
| 345 | 324 | |
| 346 | 325 | |
| @@ -382,12 +361,10 @@ void __cpuinit set_cpu_sibling_map(int cpu) · 35 unmodified lines | ||
| 382 | 361 | per_cpu(cpu_llc_id, cpu) == per_cpu(cpu_llc_id, i)) { |
| 383 | 362 | cpumask_set_cpu(i, cpu_llc_shared_mask(cpu)); |
| 384 | 363 | cpumask_set_cpu(cpu, cpu_llc_shared_mask(i)); |
| 385 | − check_cpu_siblings_on_same_node(cpu, i); | |
| 386 | 364 | } |
| 387 | 365 | if (c->phys_proc_id == cpu_data(i).phys_proc_id) { |
| 388 | 366 | cpumask_set_cpu(i, cpu_core_mask(cpu)); |
| 389 | 367 | cpumask_set_cpu(cpu, cpu_core_mask(i)); |
| 390 | − check_cpu_siblings_on_same_node(cpu, i); | |
| 391 | 368 | /* |
| 392 | 369 | * Does this new cpu bringup a new core? |
| 393 | 370 | */ |
| @@ -61,6 +61,10 @@ struct x86_init_ops x86_init __initdata = { · 60 unmodified lines | ||
| 61 | 61 | .banner = default_banner, |
| 62 | 62 | }, |
| 63 | 63 | |
| 64 | + .mapping = { | |
| 65 | + .pagetable_reserve = native_pagetable_reserve, | |
| 66 | + }, | |
| 67 | + | |
| 64 | 68 | .paging = { |
| 65 | 69 | .pagetable_setup_start = native_pagetable_setup_start, |
| 66 | 70 | .pagetable_setup_done = native_pagetable_setup_done, |
| @@ -81,6 +81,11 @@ static void __init find_early_table_space(unsigned long end, int use_pse, · 80 unmodified lines | ||
| 81 | 81 | end, pgt_buf_start << PAGE_SHIFT, pgt_buf_top << PAGE_SHIFT); |
| 82 | 82 | } |
| 83 | 83 | |
| 84 | +void __init native_pagetable_reserve(u64 start, u64 end) | |
| 85 | +{ | |
| 86 | + memblock_x86_reserve_range(start, end, "PGTABLE"); | |
| 87 | +} | |
| 88 | + | |
| 84 | 89 | struct map_range { |
| 85 | 90 | unsigned long start; |
| 86 | 91 | unsigned long end; |
| @@ -272,9 +277,24 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, · 185 unmodified lines | ||
| 272 | 277 | |
| 273 | 278 | __flush_tlb_all(); |
| 274 | 279 | |
| 280 | + /* | |
| 281 | + * Reserve the kernel pagetable pages we used (pgt_buf_start - | |
| 282 | + * pgt_buf_end) and free the other ones (pgt_buf_end - pgt_buf_top) | |
| 283 | + * so that they can be reused for other purposes. | |
| 284 | + * | |
| 285 | + * On native it just means calling memblock_x86_reserve_range, on Xen it | |
| 286 | + * also means marking RW the pagetable pages that we allocated before | |
| 287 | + * but that haven't been used. | |
| 288 | + * | |
| 289 | + * In fact on xen we mark RO the whole range pgt_buf_start - | |
| 290 | + * pgt_buf_top, because we have to make sure that when | |
| 291 | + * init_memory_mapping reaches the pagetable pages area, it maps | |
| 292 | + * RO all the pagetable pages, including the ones that are beyond | |
| 293 | + * pgt_buf_end at that time. | |
| 294 | + */ | |
| 275 | 295 | if (!after_bootmem && pgt_buf_end > pgt_buf_start) |
| 276 | − memblock_x86_reserve_range(pgt_buf_start << PAGE_SHIFT, | |
| 277 | − pgt_buf_end << PAGE_SHIFT, "PGTABLE"); | |
| 296 | + x86_init.mapping.pagetable_reserve(PFN_PHYS(pgt_buf_start), | |
| 297 | + PFN_PHYS(pgt_buf_end)); | |
| 278 | 298 | |
| 279 | 299 | if (!after_bootmem) |
| 280 | 300 | early_memtest(start, end); |
| @@ -213,53 +213,48 @@ int early_cpu_to_node(int cpu) · 212 unmodified lines | ||
| 213 | 213 | return per_cpu(x86_cpu_to_node_map, cpu); |
| 214 | 214 | } |
| 215 | 215 | |
| 216 | −struct cpumask __cpuinit *debug_cpumask_set_cpu(int cpu, int enable) | |
| 216 | +void debug_cpumask_set_cpu(int cpu, int node, bool enable) | |
| 217 | 217 | { |
| 218 | − int node = early_cpu_to_node(cpu); | |
| 219 | 218 | struct cpumask *mask; |
| 220 | 219 | char buf[64]; |
| 221 | 220 | |
| 222 | 221 | if (node == NUMA_NO_NODE) { |
| 223 | 222 | /* early_cpu_to_node() already emits a warning and trace */ |
| 224 | − return NULL; | |
| 223 | + return; | |
| 225 | 224 | } |
| 226 | 225 | mask = node_to_cpumask_map[node]; |
| 227 | 226 | if (!mask) { |
| 228 | 227 | pr_err("node_to_cpumask_map[%i] NULL\n", node); |
| 229 | 228 | dump_stack(); |
| 230 | − return NULL; | |
| 229 | + return; | |
| 231 | 230 | } |
| 232 | 231 | |
| 232 | + if (enable) | |
| 233 | + cpumask_set_cpu(cpu, mask); | |
| 234 | + else | |
| 235 | + cpumask_clear_cpu(cpu, mask); | |
| 236 | + | |
| 233 | 237 | cpulist_scnprintf(buf, sizeof(buf), mask); |
| 234 | 238 | printk(KERN_DEBUG "%s cpu %d node %d: mask now %s\n", |
| 235 | 239 | enable ? "numa_add_cpu" : "numa_remove_cpu", |
| 236 | 240 | cpu, node, buf); |
| 237 | − return mask; | |
| 241 | + return; | |
| 238 | 242 | } |
| 239 | 243 | |
| 240 | 244 | # ifndef CONFIG_NUMA_EMU |
| 241 | −static void __cpuinit numa_set_cpumask(int cpu, int enable) | |
| 245 | +static void __cpuinit numa_set_cpumask(int cpu, bool enable) | |
| 242 | 246 | { |
| 243 | − struct cpumask *mask; | |
| 244 | − | |
| 245 | − mask = debug_cpumask_set_cpu(cpu, enable); | |
| 246 | − if (!mask) | |
| 247 | − return; | |
| 248 | − | |
| 249 | − if (enable) | |
| 250 | − cpumask_set_cpu(cpu, mask); | |
| 251 | − else | |
| 252 | − cpumask_clear_cpu(cpu, mask); | |
| 247 | + debug_cpumask_set_cpu(cpu, early_cpu_to_node(cpu), enable); | |
| 253 | 248 | } |
| 254 | 249 | |
| 255 | 250 | void __cpuinit numa_add_cpu(int cpu) |
| 256 | 251 | { |
| 257 | − numa_set_cpumask(cpu, 1); | |
| 252 | + numa_set_cpumask(cpu, true); | |
| 258 | 253 | } |
| 259 | 254 | |
| 260 | 255 | void __cpuinit numa_remove_cpu(int cpu) |
| 261 | 256 | { |
| 262 | − numa_set_cpumask(cpu, 0); | |
| 257 | + numa_set_cpumask(cpu, false); | |
| 263 | 258 | } |
| 264 | 259 | # endif /* !CONFIG_NUMA_EMU */ |
| 265 | 260 | |
| @@ -306,7 +306,7 @@ int __init numa_cleanup_meminfo(struct numa_meminfo *mi) · 305 unmodified lines | ||
| 306 | 306 | bi->end = min(bi->end, high); |
| 307 | 307 | |
| 308 | 308 | /* and there's no empty block */ |
| 309 | − if (bi->start == bi->end) { | |
| 309 | + if (bi->start >= bi->end) { | |
| 310 | 310 | numa_remove_memblk_from(i--, mi); |
| 311 | 311 | continue; |
| 312 | 312 | } |
| @@ -454,10 +454,9 @@ void __cpuinit numa_remove_cpu(int cpu) · 453 unmodified lines | ||
| 454 | 454 | cpumask_clear_cpu(cpu, node_to_cpumask_map[i]); |
| 455 | 455 | } |
| 456 | 456 | #else /* !CONFIG_DEBUG_PER_CPU_MAPS */ |
| 457 | −static void __cpuinit numa_set_cpumask(int cpu, int enable) | |
| 457 | +static void __cpuinit numa_set_cpumask(int cpu, bool enable) | |
| 458 | 458 | { |
| 459 | − struct cpumask *mask; | |
| 460 | − int nid, physnid, i; | |
| 459 | + int nid, physnid; | |
| 461 | 460 | |
| 462 | 461 | nid = early_cpu_to_node(cpu); |
| 463 | 462 | if (nid == NUMA_NO_NODE) { |
| @@ -467,28 +466,21 @@ static void __cpuinit numa_set_cpumask(int cpu, int enable) · 3 unmodified lines | ||
| 467 | 466 | |
| 468 | 467 | physnid = emu_nid_to_phys[nid]; |
| 469 | 468 | |
| 470 | − for_each_online_node(i) { | |
| 469 | + for_each_online_node(nid) { | |
| 471 | 470 | if (emu_nid_to_phys[nid] != physnid) |
| 472 | 471 | continue; |
| 473 | 472 | |
| 474 | − mask = debug_cpumask_set_cpu(cpu, enable); | |
| 475 | − if (!mask) | |
| 476 | − return; | |
| 477 | − | |
| 478 | − if (enable) | |
| 479 | − cpumask_set_cpu(cpu, mask); | |
| 480 | − else | |
| 481 | − cpumask_clear_cpu(cpu, mask); | |
| 473 | + debug_cpumask_set_cpu(cpu, nid, enable); | |
| 482 | 474 | } |
| 483 | 475 | } |
| 484 | 476 | |
| 485 | 477 | void __cpuinit numa_add_cpu(int cpu) |
| 486 | 478 | { |
| 487 | − numa_set_cpumask(cpu, 1); | |
| 479 | + numa_set_cpumask(cpu, true); | |
| 488 | 480 | } |
| 489 | 481 | |
| 490 | 482 | void __cpuinit numa_remove_cpu(int cpu) |
| 491 | 483 | { |
| 492 | − numa_set_cpumask(cpu, 0); | |
| 484 | + numa_set_cpumask(cpu, false); | |
| 493 | 485 | } |
| 494 | 486 | #endif /* !CONFIG_DEBUG_PER_CPU_MAPS */ |
| @@ -347,7 +347,7 @@ · 346 unmodified lines | ||
| 347 | 347 | "pciclass0c03"; |
| 348 | 348 | |
| 349 | 349 | reg = <0x16800 0x0 0x0 0x0 0x0>; |
| 350 | − interrupts = <22 3>; | |
| 350 | + interrupts = <22 1>; | |
| 351 | 351 | }; |
| 352 | 352 | |
| 353 | 353 | usb@d,1 { |
| @@ -357,7 +357,7 @@ · 3 unmodified lines | ||
| 357 | 357 | "pciclass0c03"; |
| 358 | 358 | |
| 359 | 359 | reg = <0x16900 0x0 0x0 0x0 0x0>; |
| 360 | − interrupts = <22 3>; | |
| 360 | + interrupts = <22 1>; | |
| 361 | 361 | }; |
| 362 | 362 | |
| 363 | 363 | sata@e,0 { |
| @@ -367,7 +367,7 @@ · 3 unmodified lines | ||
| 367 | 367 | "pciclass0106"; |
| 368 | 368 | |
| 369 | 369 | reg = <0x17000 0x0 0x0 0x0 0x0>; |
| 370 | − interrupts = <23 3>; | |
| 370 | + interrupts = <23 1>; | |
| 371 | 371 | }; |
| 372 | 372 | |
| 373 | 373 | flash@f,0 { |
| @@ -699,16 +699,17 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, · 698 unmodified lines | ||
| 699 | 699 | struct mm_struct *mm, |
| 700 | 700 | unsigned long va, unsigned int cpu) |
| 701 | 701 | { |
| 702 | − int tcpu; | |
| 703 | − int uvhub; | |
| 704 | 702 | int locals = 0; |
| 705 | 703 | int remotes = 0; |
| 706 | 704 | int hubs = 0; |
| 705 | + int tcpu; | |
| 706 | + int tpnode; | |
| 707 | 707 | struct bau_desc *bau_desc; |
| 708 | 708 | struct cpumask *flush_mask; |
| 709 | 709 | struct ptc_stats *stat; |
| 710 | 710 | struct bau_control *bcp; |
| 711 | 711 | struct bau_control *tbcp; |
| 712 | + struct hub_and_pnode *hpp; | |
| 712 | 713 | |
| 713 | 714 | /* kernel was booted 'nobau' */ |
| 714 | 715 | if (nobau) |
| @@ -750,11 +751,18 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask, · 35 unmodified lines | ||
| 750 | 751 | bau_desc += UV_ITEMS_PER_DESCRIPTOR * bcp->uvhub_cpu; |
| 751 | 752 | bau_uvhubs_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE); |
| 752 | 753 | |
| 753 | − /* cpu statistics */ | |
| 754 | 754 | for_each_cpu(tcpu, flush_mask) { |
| 755 | − uvhub = uv_cpu_to_blade_id(tcpu); | |
| 756 | − bau_uvhub_set(uvhub, &bau_desc->distribution); | |
| 757 | − if (uvhub == bcp->uvhub) | |
| 755 | + /* | |
| 756 | + * The distribution vector is a bit map of pnodes, relative | |
| 757 | + * to the partition base pnode (and the partition base nasid | |
| 758 | + * in the header). | |
| 759 | + * Translate cpu to pnode and hub using an array stored | |
| 760 | + * in local memory. | |
| 761 | + */ | |
| 762 | + hpp = &bcp->socket_master->target_hub_and_pnode[tcpu]; | |
| 763 | + tpnode = hpp->pnode - bcp->partition_base_pnode; | |
| 764 | + bau_uvhub_set(tpnode, &bau_desc->distribution); | |
| 765 | + if (hpp->uvhub == bcp->uvhub) | |
| 758 | 766 | locals++; |
| 759 | 767 | else |
| 760 | 768 | remotes++; |
| @@ -855,7 +863,7 @@ void uv_bau_message_interrupt(struct pt_regs *regs) · 94 unmodified lines | ||
| 855 | 863 | * an interrupt, but causes an error message to be returned to |
| 856 | 864 | * the sender. |
| 857 | 865 | */ |
| 858 | −static void uv_enable_timeouts(void) | |
| 866 | +static void __init uv_enable_timeouts(void) | |
| 859 | 867 | { |
| 860 | 868 | int uvhub; |
| 861 | 869 | int nuvhubs; |
| @@ -1326,10 +1334,10 @@ static int __init uv_ptc_init(void) · 464 unmodified lines | ||
| 1326 | 1334 | } |
| 1327 | 1335 | |
| 1328 | 1336 | /* |
| 1329 | − * initialize the sending side's sending buffers | |
| 1337 | + * Initialize the sending side's sending buffers. | |
| 1330 | 1338 | */ |
| 1331 | 1339 | static void |
| 1332 | −uv_activation_descriptor_init(int node, int pnode) | |
| 1340 | +uv_activation_descriptor_init(int node, int pnode, int base_pnode) | |
| 1333 | 1341 | { |
| 1334 | 1342 | int i; |
| 1335 | 1343 | int cpu; |
| @@ -1352,11 +1360,11 @@ uv_activation_descriptor_init(int node, int pnode) · 16 unmodified lines | ||
| 1352 | 1360 | n = pa >> uv_nshift; |
| 1353 | 1361 | m = pa & uv_mmask; |
| 1354 | 1362 | |
| 1363 | + /* the 14-bit pnode */ | |
| 1355 | 1364 | uv_write_global_mmr64(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE, |
| 1356 | 1365 | (n << UV_DESC_BASE_PNODE_SHIFT | m)); |
| 1357 | − | |
| 1358 | 1366 | /* |
| 1359 | − * initializing all 8 (UV_ITEMS_PER_DESCRIPTOR) descriptors for each | |
| 1367 | + * Initializing all 8 (UV_ITEMS_PER_DESCRIPTOR) descriptors for each | |
| 1360 | 1368 | * cpu even though we only use the first one; one descriptor can |
| 1361 | 1369 | * describe a broadcast to 256 uv hubs. |
| 1362 | 1370 | */ |
| @@ -1365,12 +1373,13 @@ uv_activation_descriptor_init(int node, int pnode) · 2 unmodified lines | ||
| 1365 | 1373 | memset(bd2, 0, sizeof(struct bau_desc)); |
| 1366 | 1374 | bd2->header.sw_ack_flag = 1; |
| 1367 | 1375 | /* |
| 1368 | − * base_dest_nodeid is the nasid of the first uvhub | |
| 1369 | − * in the partition. The bit map will indicate uvhub numbers, | |
| 1370 | − * which are 0-N in a partition. Pnodes are unique system-wide. | |
| 1376 | + * The base_dest_nasid set in the message header is the nasid | |
| 1377 | + * of the first uvhub in the partition. The bit map will | |
| 1378 | + * indicate destination pnode numbers relative to that base. | |
| 1379 | + * They may not be consecutive if nasid striding is being used. | |
| 1371 | 1380 | */ |
| 1372 | − bd2->header.base_dest_nodeid = UV_PNODE_TO_NASID(uv_partition_base_pnode); | |
| 1373 | − bd2->header.dest_subnodeid = 0x10; /* the LB */ | |
| 1381 | + bd2->header.base_dest_nasid = UV_PNODE_TO_NASID(base_pnode); | |
| 1382 | + bd2->header.dest_subnodeid = UV_LB_SUBNODEID; | |
| 1374 | 1383 | bd2->header.command = UV_NET_ENDPOINT_INTD; |
| 1375 | 1384 | bd2->header.int_both = 1; |
| 1376 | 1385 | /* |
| @@ -1442,7 +1451,7 @@ uv_payload_queue_init(int node, int pnode) · 65 unmodified lines | ||
| 1442 | 1451 | /* |
| 1443 | 1452 | * Initialization of each UV hub's structures |
| 1444 | 1453 | */ |
| 1445 | −static void __init uv_init_uvhub(int uvhub, int vector) | |
| 1454 | +static void __init uv_init_uvhub(int uvhub, int vector, int base_pnode) | |
| 1446 | 1455 | { |
| 1447 | 1456 | int node; |
| 1448 | 1457 | int pnode; |
| @@ -1450,11 +1459,11 @@ static void __init uv_init_uvhub(int uvhub, int vector) · 1 unmodified line | ||
| 1450 | 1459 | |
| 1451 | 1460 | node = uvhub_to_first_node(uvhub); |
| 1452 | 1461 | pnode = uv_blade_to_pnode(uvhub); |
| 1453 | − uv_activation_descriptor_init(node, pnode); | |
| 1462 | + uv_activation_descriptor_init(node, pnode, base_pnode); | |
| 1454 | 1463 | uv_payload_queue_init(node, pnode); |
| 1455 | 1464 | /* |
| 1456 | − * the below initialization can't be in firmware because the | |
| 1457 | − * messaging IRQ will be determined by the OS | |
| 1465 | + * The below initialization can't be in firmware because the | |
| 1466 | + * messaging IRQ will be determined by the OS. | |
| 1458 | 1467 | */ |
| 1459 | 1468 | apicid = uvhub_to_first_apicid(uvhub) | uv_apicid_hibits; |
| 1460 | 1469 | uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG, |
| @@ -1491,10 +1500,11 @@ calculate_destination_timeout(void) · 30 unmodified lines | ||
| 1491 | 1500 | /* |
| 1492 | 1501 | * initialize the bau_control structure for each cpu |
| 1493 | 1502 | */ |
| 1494 | −static int __init uv_init_per_cpu(int nuvhubs) | |
| 1503 | +static int __init uv_init_per_cpu(int nuvhubs, int base_part_pnode) | |
| 1495 | 1504 | { |
| 1496 | 1505 | int i; |
| 1497 | 1506 | int cpu; |
| 1507 | + int tcpu; | |
| 1498 | 1508 | int pnode; |
| 1499 | 1509 | int uvhub; |
| 1500 | 1510 | int have_hmaster; |
| @@ -1528,6 +1538,15 @@ static int __init uv_init_per_cpu(int nuvhubs) · 27 unmodified lines | ||
| 1528 | 1538 | bcp = &per_cpu(bau_control, cpu); |
| 1529 | 1539 | memset(bcp, 0, sizeof(struct bau_control)); |
| 1530 | 1540 | pnode = uv_cpu_hub_info(cpu)->pnode; |
| 1541 | + if ((pnode - base_part_pnode) >= UV_DISTRIBUTION_SIZE) { | |
| 1542 | + printk(KERN_EMERG | |
| 1543 | + "cpu %d pnode %d-%d beyond %d; BAU disabled\n", | |
| 1544 | + cpu, pnode, base_part_pnode, | |
| 1545 | + UV_DISTRIBUTION_SIZE); | |
| 1546 | + return 1; | |
| 1547 | + } | |
| 1548 | + bcp->osnode = cpu_to_node(cpu); | |
| 1549 | + bcp->partition_base_pnode = uv_partition_base_pnode; | |
| 1531 | 1550 | uvhub = uv_cpu_hub_info(cpu)->numa_blade_id; |
| 1532 | 1551 | *(uvhub_mask + (uvhub/8)) |= (1 << (uvhub%8)); |
| 1533 | 1552 | bdp = &uvhub_descs[uvhub]; |
| @@ -1536,7 +1555,7 @@ static int __init uv_init_per_cpu(int nuvhubs) · 2 unmodified lines | ||
| 1536 | 1555 | bdp->pnode = pnode; |
| 1537 | 1556 | /* kludge: 'assuming' one node per socket, and assuming that |
| 1538 | 1557 | disabling a socket just leaves a gap in node numbers */ |
| 1539 | − socket = (cpu_to_node(cpu) & 1); | |
| 1558 | + socket = bcp->osnode & 1; | |
| 1540 | 1559 | bdp->socket_mask |= (1 << socket); |
| 1541 | 1560 | sdp = &bdp->socket[socket]; |
| 1542 | 1561 | sdp->cpu_number[sdp->num_cpus] = cpu; |
| @@ -1585,6 +1604,20 @@ static int __init uv_init_per_cpu(int nuvhubs) · 42 unmodified lines | ||
| 1585 | 1604 | nextsocket: |
| 1586 | 1605 | socket++; |
| 1587 | 1606 | socket_mask = (socket_mask >> 1); |
| 1607 | + /* each socket gets a local array of pnodes/hubs */ | |
| 1608 | + bcp = smaster; | |
| 1609 | + bcp->target_hub_and_pnode = kmalloc_node( | |
| 1610 | + sizeof(struct hub_and_pnode) * | |
| 1611 | + num_possible_cpus(), GFP_KERNEL, bcp->osnode); | |
| 1612 | + memset(bcp->target_hub_and_pnode, 0, | |
| 1613 | + sizeof(struct hub_and_pnode) * | |
| 1614 | + num_possible_cpus()); | |
| 1615 | + for_each_present_cpu(tcpu) { | |
| 1616 | + bcp->target_hub_and_pnode[tcpu].pnode = | |
| 1617 | + uv_cpu_hub_info(tcpu)->pnode; | |
| 1618 | + bcp->target_hub_and_pnode[tcpu].uvhub = | |
| 1619 | + uv_cpu_hub_info(tcpu)->numa_blade_id; | |
| 1620 | + } | |
| 1588 | 1621 | } |
| 1589 | 1622 | } |
| 1590 | 1623 | kfree(uvhub_descs); |
| @@ -1637,21 +1670,22 @@ static int __init uv_bau_init(void) · 46 unmodified lines | ||
| 1637 | 1670 | spin_lock_init(&disable_lock); |
| 1638 | 1671 | congested_cycles = microsec_2_cycles(congested_response_us); |
| 1639 | 1672 | |
| 1640 | − if (uv_init_per_cpu(nuvhubs)) { | |
| 1641 | − nobau = 1; | |
| 1642 | − return 0; | |
| 1643 | − } | |
| 1644 | − | |
| 1645 | 1673 | uv_partition_base_pnode = 0x7fffffff; |
| 1646 | − for (uvhub = 0; uvhub < nuvhubs; uvhub++) | |
| 1674 | + for (uvhub = 0; uvhub < nuvhubs; uvhub++) { | |
| 1647 | 1675 | if (uv_blade_nr_possible_cpus(uvhub) && |
| 1648 | 1676 | (uv_blade_to_pnode(uvhub) < uv_partition_base_pnode)) |
| 1649 | 1677 | uv_partition_base_pnode = uv_blade_to_pnode(uvhub); |
| 1678 | + } | |
| 1679 | + | |
| 1680 | + if (uv_init_per_cpu(nuvhubs, uv_partition_base_pnode)) { | |
| 1681 | + nobau = 1; | |
| 1682 | + return 0; | |
| 1683 | + } | |
| 1650 | 1684 | |
| 1651 | 1685 | vector = UV_BAU_MESSAGE; |
| 1652 | 1686 | for_each_possible_blade(uvhub) |
| 1653 | 1687 | if (uv_blade_nr_possible_cpus(uvhub)) |
| 1654 | − uv_init_uvhub(uvhub, vector); | |
| 1688 | + uv_init_uvhub(uvhub, vector, uv_partition_base_pnode); | |
| 1655 | 1689 | |
| 1656 | 1690 | uv_enable_timeouts(); |
| 1657 | 1691 | alloc_intr_gate(vector, uv_bau_message_intr1); |
| @@ -1275,6 +1275,20 @@ static __init void xen_pagetable_setup_start(pgd_t *base) · 1274 unmodified lines | ||
| 1275 | 1275 | { |
| 1276 | 1276 | } |
| 1277 | 1277 | |
| 1278 | +static __init void xen_mapping_pagetable_reserve(u64 start, u64 end) | |
| 1279 | +{ | |
| 1280 | + /* reserve the range used */ | |
| 1281 | + native_pagetable_reserve(start, end); | |
| 1282 | + | |
| 1283 | + /* set as RW the rest */ | |
| 1284 | + printk(KERN_DEBUG "xen: setting RW the range %llx - %llx\n", end, | |
| 1285 | + PFN_PHYS(pgt_buf_top)); | |
| 1286 | + while (end < PFN_PHYS(pgt_buf_top)) { | |
| 1287 | + make_lowmem_page_readwrite(__va(end)); | |
| 1288 | + end += PAGE_SIZE; | |
| 1289 | + } | |
| 1290 | +} | |
| 1291 | + | |
| 1278 | 1292 | static void xen_post_allocator_init(void); |
| 1279 | 1293 | |
| 1280 | 1294 | static __init void xen_pagetable_setup_done(pgd_t *base) |
| @@ -1473,16 +1487,20 @@ static void xen_pgd_free(struct mm_struct *mm, pgd_t *pgd) · 192 unmodified lines | ||
| 1473 | 1487 | #endif |
| 1474 | 1488 | } |
| 1475 | 1489 | |
| 1490 | +#ifdef CONFIG_X86_32 | |
| 1476 | 1491 | static __init pte_t mask_rw_pte(pte_t *ptep, pte_t pte) |
| 1477 | 1492 | { |
| 1478 | − unsigned long pfn = pte_pfn(pte); | |
| 1479 | − | |
| 1480 | −#ifdef CONFIG_X86_32 | |
| 1481 | 1493 | /* If there's an existing pte, then don't allow _PAGE_RW to be set */ |
| 1482 | 1494 | if (pte_val_ma(*ptep) & _PAGE_PRESENT) |
| 1483 | 1495 | pte = __pte_ma(((pte_val_ma(*ptep) & _PAGE_RW) | ~_PAGE_RW) & |
| 1484 | 1496 | pte_val_ma(pte)); |
| 1485 | −#endif | |
| 1497 | + | |
| 1498 | + return pte; | |
| 1499 | +} | |
| 1500 | +#else /* CONFIG_X86_64 */ | |
| 1501 | +static __init pte_t mask_rw_pte(pte_t *ptep, pte_t pte) | |
| 1502 | +{ | |
| 1503 | + unsigned long pfn = pte_pfn(pte); | |
| 1486 | 1504 | |
| 1487 | 1505 | /* |
| 1488 | 1506 | * If the new pfn is within the range of the newly allocated |
| @@ -1491,12 +1509,13 @@ static __init pte_t mask_rw_pte(pte_t *ptep, pte_t pte) · 2 unmodified lines | ||
| 1491 | 1509 | * it is RO. |
| 1492 | 1510 | */ |
| 1493 | 1511 | if (((!is_early_ioremap_ptep(ptep) && |
| 1494 | − pfn >= pgt_buf_start && pfn < pgt_buf_end)) || | |
| 1512 | + pfn >= pgt_buf_start && pfn < pgt_buf_top)) || | |
| 1495 | 1513 | (is_early_ioremap_ptep(ptep) && pfn != (pgt_buf_end - 1))) |
| 1496 | 1514 | pte = pte_wrprotect(pte); |
| 1497 | 1515 | |
| 1498 | 1516 | return pte; |
| 1499 | 1517 | } |
| 1518 | +#endif /* CONFIG_X86_64 */ | |
| 1500 | 1519 | |
| 1501 | 1520 | /* Init-time set_pte while constructing initial pagetables, which |
| 1502 | 1521 | doesn't allow RO pagetable pages to be remapped RW */ |
| @@ -2100,6 +2119,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = { · 597 unmodified lines | ||
| 2100 | 2119 | |
| 2101 | 2120 | void __init xen_init_mmu_ops(void) |
| 2102 | 2121 | { |
| 2122 | + x86_init.mapping.pagetable_reserve = xen_mapping_pagetable_reserve; | |
| 2103 | 2123 | x86_init.paging.pagetable_setup_start = xen_pagetable_setup_start; |
| 2104 | 2124 | x86_init.paging.pagetable_setup_done = xen_pagetable_setup_done; |
| 2105 | 2125 | pv_mmu_ops = xen_mmu_ops; |
| @@ -227,7 +227,7 @@ char * __init xen_memory_setup(void) · 226 unmodified lines | ||
| 227 | 227 | |
| 228 | 228 | memcpy(map_raw, map, sizeof(map)); |
| 229 | 229 | e820.nr_map = 0; |
| 230 | − xen_extra_mem_start = mem_end; | |
| 230 | + xen_extra_mem_start = max((1ULL << 32), mem_end); | |
| 231 | 231 | for (i = 0; i < memmap.nr_entries; i++) { |
| 232 | 232 | unsigned long long end; |
| 233 | 233 | |
| @@ -64,47 +64,41 @@ asmlinkage void do_IRQ(int irq, struct pt_regs *regs) · 63 unmodified lines | ||
| 64 | 64 | |
| 65 | 65 | int arch_show_interrupts(struct seq_file *p, int prec) |
| 66 | 66 | { |
| 67 | − int j; | |
| 68 | − | |
| 69 | − seq_printf(p, "%*s: ", prec, "NMI"); | |
| 70 | − for_each_online_cpu(j) | |
| 71 | − seq_printf(p, "%10u ", nmi_count(j)); | |
| 72 | − seq_putc(p, '\n'); | |
| 73 | 67 | seq_printf(p, "%*s: ", prec, "ERR"); |
| 74 | 68 | seq_printf(p, "%10u\n", atomic_read(&irq_err_count)); |
| 75 | 69 | return 0; |
| 76 | 70 | } |
| 77 | 71 | |
| 78 | −static void xtensa_irq_mask(struct irq_chip *d) | |
| 72 | +static void xtensa_irq_mask(struct irq_data *d) | |
| 79 | 73 | { |
| 80 | 74 | cached_irq_mask &= ~(1 << d->irq); |
| 81 | 75 | set_sr (cached_irq_mask, INTENABLE); |
| 82 | 76 | } |
| 83 | 77 | |
| 84 | −static void xtensa_irq_unmask(struct irq_chip *d) | |
| 78 | +static void xtensa_irq_unmask(struct irq_data *d) | |
| 85 | 79 | { |
| 86 | 80 | cached_irq_mask |= 1 << d->irq; |
| 87 | 81 | set_sr (cached_irq_mask, INTENABLE); |
| 88 | 82 | } |
| 89 | 83 | |
| 90 | −static void xtensa_irq_enable(struct irq_chip *d) | |
| 84 | +static void xtensa_irq_enable(struct irq_data *d) | |
| 91 | 85 | { |
| 92 | 86 | variant_irq_enable(d->irq); |
| 93 | 87 | xtensa_irq_unmask(d->irq); |
| 94 | 88 | } |
| 95 | 89 | |
| 96 | −static void xtensa_irq_disable(struct irq_chip *d) | |
| 90 | +static void xtensa_irq_disable(struct irq_data *d) | |
| 97 | 91 | { |
| 98 | 92 | xtensa_irq_mask(d->irq); |
| 99 | 93 | variant_irq_disable(d->irq); |
| 100 | 94 | } |
| 101 | 95 | |
| 102 | −static void xtensa_irq_ack(struct irq_chip *d) | |
| 96 | +static void xtensa_irq_ack(struct irq_data *d) | |
| 103 | 97 | { |
| 104 | 98 | set_sr(1 << d->irq, INTCLEAR); |
| 105 | 99 | } |
| 106 | 100 | |
| 107 | −static int xtensa_irq_retrigger(struct irq_chip *d) | |
| 101 | +static int xtensa_irq_retrigger(struct irq_data *d) | |
| 108 | 102 | { |
| 109 | 103 | set_sr (1 << d->irq, INTSET); |
| 110 | 104 | return 1; |
| @@ -114,6 +114,13 @@ struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup) · 113 unmodified lines | ||
| 114 | 114 | } |
| 115 | 115 | EXPORT_SYMBOL_GPL(cgroup_to_blkio_cgroup); |
| 116 | 116 | |
| 117 | +struct blkio_cgroup *task_blkio_cgroup(struct task_struct *tsk) | |
| 118 | +{ | |
| 119 | + return container_of(task_subsys_state(tsk, blkio_subsys_id), | |
| 120 | + struct blkio_cgroup, css); | |
| 121 | +} | |
| 122 | +EXPORT_SYMBOL_GPL(task_blkio_cgroup); | |
| 123 | + | |
| 117 | 124 | static inline void |
| 118 | 125 | blkio_update_group_weight(struct blkio_group *blkg, unsigned int weight) |
| 119 | 126 | { |
| @@ -291,6 +291,7 @@ static inline void blkiocg_set_start_empty_time(struct blkio_group *blkg) {} · 290 unmodified lines | ||
| 291 | 291 | #if defined(CONFIG_BLK_CGROUP) || defined(CONFIG_BLK_CGROUP_MODULE) |
| 292 | 292 | extern struct blkio_cgroup blkio_root_cgroup; |
| 293 | 293 | extern struct blkio_cgroup *cgroup_to_blkio_cgroup(struct cgroup *cgroup); |
| 294 | +extern struct blkio_cgroup *task_blkio_cgroup(struct task_struct *tsk); | |
| 294 | 295 | extern void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg, |
| 295 | 296 | struct blkio_group *blkg, void *key, dev_t dev, |
| 296 | 297 | enum blkio_policy_id plid); |
| @@ -314,6 +315,8 @@ void blkiocg_update_io_remove_stats(struct blkio_group *blkg, · 17 unmodified lines | ||
| 314 | 315 | struct cgroup; |
| 315 | 316 | static inline struct blkio_cgroup * |
| 316 | 317 | cgroup_to_blkio_cgroup(struct cgroup *cgroup) { return NULL; } |
| 318 | +static inline struct blkio_cgroup * | |
| 319 | +task_blkio_cgroup(struct task_struct *tsk) { return NULL; } | |
| 317 | 320 | |
| 318 | 321 | static inline void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg, |
| 319 | 322 | struct blkio_group *blkg, void *key, dev_t dev, |
| @@ -292,7 +292,6 @@ EXPORT_SYMBOL(blk_sync_queue); · 291 unmodified lines | ||
| 292 | 292 | /** |
| 293 | 293 | * __blk_run_queue - run a single device queue |
| 294 | 294 | * @q: The queue to run |
| 295 | − * @force_kblockd: Don't run @q->request_fn directly. Use kblockd. | |
| 296 | 295 | * |
| 297 | 296 | * Description: |
| 298 | 297 | * See @blk_run_queue. This variant must be called with the queue lock |
| @@ -303,15 +302,7 @@ void __blk_run_queue(struct request_queue *q) · 4 unmodified lines | ||
| 303 | 302 | if (unlikely(blk_queue_stopped(q))) |
| 304 | 303 | return; |
| 305 | 304 | |
| 306 | − /* | |
| 307 | − * Only recurse once to avoid overrunning the stack, let the unplug | |
| 308 | − * handling reinvoke the handler shortly if we already got there. | |
| 309 | − */ | |
| 310 | − if (!queue_flag_test_and_set(QUEUE_FLAG_REENTER, q)) { | |
| 311 | − q->request_fn(q); | |
| 312 | − queue_flag_clear(QUEUE_FLAG_REENTER, q); | |
| 313 | − } else | |
| 314 | − queue_delayed_work(kblockd_workqueue, &q->delay_work, 0); | |
| 305 | + q->request_fn(q); | |
| 315 | 306 | } |
| 316 | 307 | EXPORT_SYMBOL(__blk_run_queue); |
| 317 | 308 | |
| @@ -325,9 +316,12 @@ EXPORT_SYMBOL(__blk_run_queue); · 7 unmodified lines | ||
| 325 | 316 | */ |
| 326 | 317 | void blk_run_queue_async(struct request_queue *q) |
| 327 | 318 | { |
| 328 | − if (likely(!blk_queue_stopped(q))) | |
| 319 | + if (likely(!blk_queue_stopped(q))) { | |
| 320 | + __cancel_delayed_work(&q->delay_work); | |
| 329 | 321 | queue_delayed_work(kblockd_workqueue, &q->delay_work, 0); |
| 322 | + } | |
| 330 | 323 | } |
| 324 | +EXPORT_SYMBOL(blk_run_queue_async); | |
| 331 | 325 | |
| 332 | 326 | /** |
| 333 | 327 | * blk_run_queue - run a single device queue |
| @@ -2787,7 +2781,6 @@ void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule) · 2453 unmodified lines | ||
| 2787 | 2781 | |
| 2788 | 2782 | local_irq_restore(flags); |
| 2789 | 2783 | } |
| 2790 | −EXPORT_SYMBOL(blk_flush_plug_list); | |
| 2791 | 2784 | |
| 2792 | 2785 | void blk_finish_plug(struct blk_plug *plug) |
| 2793 | 2786 | { |
| @@ -66,14 +66,14 @@ queue_requests_store(struct request_queue *q, const char *page, size_t count) · 65 unmodified lines | ||
| 66 | 66 | |
| 67 | 67 | if (rl->count[BLK_RW_SYNC] >= q->nr_requests) { |
| 68 | 68 | blk_set_queue_full(q, BLK_RW_SYNC); |
| 69 | − } else if (rl->count[BLK_RW_SYNC]+1 <= q->nr_requests) { | |
| 69 | + } else { | |
| 70 | 70 | blk_clear_queue_full(q, BLK_RW_SYNC); |
| 71 | 71 | wake_up(&rl->wait[BLK_RW_SYNC]); |
| 72 | 72 | } |
| 73 | 73 | |
| 74 | 74 | if (rl->count[BLK_RW_ASYNC] >= q->nr_requests) { |
| 75 | 75 | blk_set_queue_full(q, BLK_RW_ASYNC); |
| 76 | − } else if (rl->count[BLK_RW_ASYNC]+1 <= q->nr_requests) { | |
| 76 | + } else { | |
| 77 | 77 | blk_clear_queue_full(q, BLK_RW_ASYNC); |
| 78 | 78 | wake_up(&rl->wait[BLK_RW_ASYNC]); |
| 79 | 79 | } |
| @@ -509,8 +509,10 @@ int blk_register_queue(struct gendisk *disk) · 429 unmodified lines | ||
| 509 | 509 | return ret; |
| 510 | 510 | |
| 511 | 511 | ret = kobject_add(&q->kobj, kobject_get(&dev->kobj), "%s", "queue"); |
| 512 | − if (ret < 0) | |
| 512 | + if (ret < 0) { | |
| 513 | + blk_trace_remove_sysfs(dev); | |
| 513 | 514 | return ret; |
| 515 | + } | |
| 514 | 516 | |
| 515 | 517 | kobject_uevent(&q->kobj, KOBJ_ADD); |
| 516 | 518 | |
| @@ -160,9 +160,8 @@ static void throtl_put_tg(struct throtl_grp *tg) · 159 unmodified lines | ||
| 160 | 160 | } |
| 161 | 161 | |
| 162 | 162 | static struct throtl_grp * throtl_find_alloc_tg(struct throtl_data *td, |
| 163 | − struct cgroup *cgroup) | |
| 163 | + struct blkio_cgroup *blkcg) | |
| 164 | 164 | { |
| 165 | − struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgroup); | |
| 166 | 165 | struct throtl_grp *tg = NULL; |
| 167 | 166 | void *key = td; |
| 168 | 167 | struct backing_dev_info *bdi = &td->queue->backing_dev_info; |
| @@ -229,12 +228,12 @@ done: · 60 unmodified lines | ||
| 229 | 228 | |
| 230 | 229 | static struct throtl_grp * throtl_get_tg(struct throtl_data *td) |
| 231 | 230 | { |
| 232 | − struct cgroup *cgroup; | |
| 233 | 231 | struct throtl_grp *tg = NULL; |
| 232 | + struct blkio_cgroup *blkcg; | |
| 234 | 233 | |
| 235 | 234 | rcu_read_lock(); |
| 236 | − cgroup = task_cgroup(current, blkio_subsys_id); | |
| 237 | − tg = throtl_find_alloc_tg(td, cgroup); | |
| 235 | + blkcg = task_blkio_cgroup(current); | |
| 236 | + tg = throtl_find_alloc_tg(td, blkcg); | |
| 238 | 237 | if (!tg) |
| 239 | 238 | tg = &td->root_tg; |
| 240 | 239 | rcu_read_unlock(); |
| @@ -22,7 +22,6 @@ void blk_rq_timed_out_timer(unsigned long data); · 21 unmodified lines | ||
| 22 | 22 | void blk_delete_timer(struct request *); |
| 23 | 23 | void blk_add_timer(struct request *); |
| 24 | 24 | void __generic_unplug_device(struct request_queue *); |
| 25 | −void blk_run_queue_async(struct request_queue *q); | |
| 26 | 25 | |
| 27 | 26 | /* |
| 28 | 27 | * Internal atomic flags for request handling |
| @@ -1014,10 +1014,9 @@ void cfq_update_blkio_group_weight(void *key, struct blkio_group *blkg, · 1013 unmodified lines | ||
| 1014 | 1014 | cfqg->needs_update = true; |
| 1015 | 1015 | } |
| 1016 | 1016 | |
| 1017 | −static struct cfq_group * | |
| 1018 | −cfq_find_alloc_cfqg(struct cfq_data *cfqd, struct cgroup *cgroup, int create) | |
| 1017 | +static struct cfq_group * cfq_find_alloc_cfqg(struct cfq_data *cfqd, | |
| 1018 | + struct blkio_cgroup *blkcg, int create) | |
| 1019 | 1019 | { |
| 1020 | − struct blkio_cgroup *blkcg = cgroup_to_blkio_cgroup(cgroup); | |
| 1021 | 1020 | struct cfq_group *cfqg = NULL; |
| 1022 | 1021 | void *key = cfqd; |
| 1023 | 1022 | int i, j; |
| @@ -1079,12 +1078,12 @@ done: · 55 unmodified lines | ||
| 1079 | 1078 | */ |
| 1080 | 1079 | static struct cfq_group *cfq_get_cfqg(struct cfq_data *cfqd, int create) |
| 1081 | 1080 | { |
| 1082 | − struct cgroup *cgroup; | |
| 1081 | + struct blkio_cgroup *blkcg; | |
| 1083 | 1082 | struct cfq_group *cfqg = NULL; |
| 1084 | 1083 | |
| 1085 | 1084 | rcu_read_lock(); |
| 1086 | − cgroup = task_cgroup(current, blkio_subsys_id); | |
| 1087 | − cfqg = cfq_find_alloc_cfqg(cfqd, cgroup, create); | |
| 1085 | + blkcg = task_blkio_cgroup(current); | |
| 1086 | + cfqg = cfq_find_alloc_cfqg(cfqd, blkcg, create); | |
| 1088 | 1087 | if (!cfqg && create) |
| 1089 | 1088 | cfqg = &cfqd->root_group; |
| 1090 | 1089 | rcu_read_unlock(); |
| @@ -2582,28 +2581,20 @@ static void cfq_put_queue(struct cfq_queue *cfqq) · 1491 unmodified lines | ||
| 2582 | 2581 | } |
| 2583 | 2582 | |
| 2584 | 2583 | /* |
| 2585 | − * Must always be called with the rcu_read_lock() held | |
| 2584 | + * Call func for each cic attached to this ioc. | |
| 2586 | 2585 | */ |
| 2587 | 2586 | static void |
| 2588 | −__call_for_each_cic(struct io_context *ioc, | |
| 2589 | − void (*func)(struct io_context *, struct cfq_io_context *)) | |
| 2587 | +call_for_each_cic(struct io_context *ioc, | |
| 2588 | + void (*func)(struct io_context *, struct cfq_io_context *)) | |
| 2590 | 2589 | { |
| 2591 | 2590 | struct cfq_io_context *cic; |
| 2592 | 2591 | struct hlist_node *n; |
| 2593 | 2592 | |
| 2593 | + rcu_read_lock(); | |
| 2594 | + | |
| 2594 | 2595 | hlist_for_each_entry_rcu(cic, n, &ioc->cic_list, cic_list) |
| 2595 | 2596 | func(ioc, cic); |
| 2596 | −} | |
| 2597 | 2597 | |
| 2598 | −/* | |
| 2599 | − * Call func for each cic attached to this ioc. | |
| 2600 | − */ | |
| 2601 | −static void | |
| 2602 | −call_for_each_cic(struct io_context *ioc, | |
| 2603 | − void (*func)(struct io_context *, struct cfq_io_context *)) | |
| 2604 | −{ | |
| 2605 | − rcu_read_lock(); | |
| 2606 | − __call_for_each_cic(ioc, func); | |
| 2607 | 2598 | rcu_read_unlock(); |
| 2608 | 2599 | } |
| 2609 | 2600 | |
| @@ -2664,7 +2655,7 @@ static void cfq_free_io_context(struct io_context *ioc) · 54 unmodified lines | ||
| 2664 | 2655 | * should be ok to iterate over the known list, we will see all cic's |
| 2665 | 2656 | * since no new ones are added. |
| 2666 | 2657 | */ |
| 2667 | − __call_for_each_cic(ioc, cic_free_func); | |
| 2658 | + call_for_each_cic(ioc, cic_free_func); | |
| 2668 | 2659 | } |
| 2669 | 2660 | |
| 2670 | 2661 | static void cfq_put_cooperator(struct cfq_queue *cfqq) |
| @@ -666,7 +666,8 @@ void __elv_add_request(struct request_queue *q, struct request *rq, int where) · 665 unmodified lines | ||
| 666 | 666 | q->boundary_rq = rq; |
| 667 | 667 | } |
| 668 | 668 | } else if (!(rq->cmd_flags & REQ_ELVPRIV) && |
| 669 | − where == ELEVATOR_INSERT_SORT) | |
| 669 | + (where == ELEVATOR_INSERT_SORT || | |
| 670 | + where == ELEVATOR_INSERT_SORT_MERGE)) | |
| 670 | 671 | where = ELEVATOR_INSERT_BACK; |
| 671 | 672 | |
| 672 | 673 | switch (where) { |
| @@ -1588,9 +1588,13 @@ static void disk_events_workfn(struct work_struct *work) · 1587 unmodified lines | ||
| 1588 | 1588 | |
| 1589 | 1589 | spin_unlock_irq(&ev->lock); |
| 1590 | 1590 | |
| 1591 | − /* tell userland about new events */ | |
| 1591 | + /* | |
| 1592 | + * Tell userland about new events. Only the events listed in | |
| 1593 | + * @disk->events are reported. Unlisted events are processed the | |
| 1594 | + * same internally but never get reported to userland. | |
| 1595 | + */ | |
| 1592 | 1596 | for (i = 0; i < ARRAY_SIZE(disk_uevents); i++) |
| 1593 | − if (events & (1 << i)) | |
| 1597 | + if (events & disk->events & (1 << i)) | |
| 1594 | 1598 | envp[nr_events++] = disk_uevents[i]; |
| 1595 | 1599 | |
| 1596 | 1600 | if (nr_events) |
| @@ -943,6 +943,10 @@ static int acpi_bus_get_flags(struct acpi_device *device) · 942 unmodified lines | ||
| 943 | 943 | if (ACPI_SUCCESS(status)) |
| 944 | 944 | device->flags.lockable = 1; |
| 945 | 945 | |
| 946 | + /* Power resources cannot be power manageable. */ | |
| 947 | + if (device->device_type == ACPI_BUS_TYPE_POWER) | |
| 948 | + return 0; | |
| 949 | + | |
| 946 | 950 | /* Presence of _PS0|_PR0 indicates 'power manageable' */ |
| 947 | 951 | status = acpi_get_handle(device->handle, "_PS0", &temp); |
| 948 | 952 | if (ACPI_FAILURE(status)) |
| @@ -150,7 +150,7 @@ static const struct ata_port_info ahci_port_info[] = { · 149 unmodified lines | ||
| 150 | 150 | { |
| 151 | 151 | AHCI_HFLAGS (AHCI_HFLAG_NO_FPDMA_AA | AHCI_HFLAG_NO_PMP | |
| 152 | 152 | AHCI_HFLAG_YES_NCQ), |
| 153 | − .flags = AHCI_FLAG_COMMON, | |
| 153 | + .flags = AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM, | |
| 154 | 154 | .pio_mask = ATA_PIO4, |
| 155 | 155 | .udma_mask = ATA_UDMA6, |
| 156 | 156 | .port_ops = &ahci_ops, |
| @@ -261,6 +261,12 @@ static const struct pci_device_id ahci_pci_tbl[] = { · 104 unmodified lines | ||
| 261 | 261 | { PCI_VDEVICE(INTEL, 0x1d06), board_ahci }, /* PBG RAID */ |
| 262 | 262 | { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* PBG RAID */ |
| 263 | 263 | { PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */ |
| 264 | + { PCI_VDEVICE(INTEL, 0x1e02), board_ahci }, /* Panther Point AHCI */ | |
| 265 | + { PCI_VDEVICE(INTEL, 0x1e03), board_ahci }, /* Panther Point AHCI */ | |
| 266 | + { PCI_VDEVICE(INTEL, 0x1e04), board_ahci }, /* Panther Point RAID */ | |
| 267 | + { PCI_VDEVICE(INTEL, 0x1e05), board_ahci }, /* Panther Point RAID */ | |
| 268 | + { PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */ | |
| 269 | + { PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point RAID */ | |
| 264 | 270 | |
| 265 | 271 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ |
| 266 | 272 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
| @@ -229,6 +229,10 @@ enum { · 228 unmodified lines | ||
| 229 | 229 | EM_CTL_ALHD = (1 << 26), /* Activity LED */ |
| 230 | 230 | EM_CTL_XMT = (1 << 25), /* Transmit Only */ |
| 231 | 231 | EM_CTL_SMB = (1 << 24), /* Single Message Buffer */ |
| 232 | + EM_CTL_SGPIO = (1 << 19), /* SGPIO messages supported */ | |
| 233 | + EM_CTL_SES = (1 << 18), /* SES-2 messages supported */ | |
| 234 | + EM_CTL_SAFTE = (1 << 17), /* SAF-TE messages supported */ | |
| 235 | + EM_CTL_LED = (1 << 16), /* LED messages supported */ | |
| 232 | 236 | |
| 233 | 237 | /* em message type */ |
| 234 | 238 | EM_MSG_TYPE_LED = (1 << 0), /* LED */ |
| @@ -309,6 +309,14 @@ static const struct pci_device_id piix_pci_tbl[] = { · 308 unmodified lines | ||
| 309 | 309 | { 0x8086, 0x1d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, |
| 310 | 310 | /* SATA Controller IDE (PBG) */ |
| 311 | 311 | { 0x8086, 0x1d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, |
| 312 | + /* SATA Controller IDE (Panther Point) */ | |
| 313 | + { 0x8086, 0x1e00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, | |
| 314 | + /* SATA Controller IDE (Panther Point) */ | |
| 315 | + { 0x8086, 0x1e01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, | |
| 316 | + /* SATA Controller IDE (Panther Point) */ | |
| 317 | + { 0x8086, 0x1e08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | |
| 318 | + /* SATA Controller IDE (Panther Point) */ | |
| 319 | + { 0x8086, 0x1e09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | |
| 312 | 320 | { } /* terminate list */ |
| 313 | 321 | }; |
| 314 | 322 | |
| @@ -109,6 +109,8 @@ static ssize_t ahci_read_em_buffer(struct device *dev, · 108 unmodified lines | ||
| 109 | 109 | static ssize_t ahci_store_em_buffer(struct device *dev, |
| 110 | 110 | struct device_attribute *attr, |
| 111 | 111 | const char *buf, size_t size); |
| 112 | +static ssize_t ahci_show_em_supported(struct device *dev, | |
| 113 | + struct device_attribute *attr, char *buf); | |
| 112 | 114 | |
| 113 | 115 | static DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL); |
| 114 | 116 | static DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL); |
| @@ -116,6 +118,7 @@ static DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL); · 1 unmodified line | ||
| 116 | 118 | static DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL); |
| 117 | 119 | static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO, |
| 118 | 120 | ahci_read_em_buffer, ahci_store_em_buffer); |
| 121 | +static DEVICE_ATTR(em_message_supported, S_IRUGO, ahci_show_em_supported, NULL); | |
| 119 | 122 | |
| 120 | 123 | struct device_attribute *ahci_shost_attrs[] = { |
| 121 | 124 | &dev_attr_link_power_management_policy, |
| @@ -126,6 +129,7 @@ struct device_attribute *ahci_shost_attrs[] = { · 4 unmodified lines | ||
| 126 | 129 | &dev_attr_ahci_host_version, |
| 127 | 130 | &dev_attr_ahci_port_cmd, |
| 128 | 131 | &dev_attr_em_buffer, |
| 132 | + &dev_attr_em_message_supported, | |
| 129 | 133 | NULL |
| 130 | 134 | }; |
| 131 | 135 | EXPORT_SYMBOL_GPL(ahci_shost_attrs); |
| @@ -343,6 +347,24 @@ static ssize_t ahci_store_em_buffer(struct device *dev, · 211 unmodified lines | ||
| 343 | 347 | return size; |
| 344 | 348 | } |
| 345 | 349 | |
| 350 | +static ssize_t ahci_show_em_supported(struct device *dev, | |
| 351 | + struct device_attribute *attr, char *buf) | |
| 352 | +{ | |
| 353 | + struct Scsi_Host *shost = class_to_shost(dev); | |
| 354 | + struct ata_port *ap = ata_shost_to_port(shost); | |
| 355 | + struct ahci_host_priv *hpriv = ap->host->private_data; | |
| 356 | + void __iomem *mmio = hpriv->mmio; | |
| 357 | + u32 em_ctl; | |
| 358 | + | |
| 359 | + em_ctl = readl(mmio + HOST_EM_CTL); | |
| 360 | + | |
| 361 | + return sprintf(buf, "%s%s%s%s\n", | |
| 362 | + em_ctl & EM_CTL_LED ? "led " : "", | |
| 363 | + em_ctl & EM_CTL_SAFTE ? "saf-te " : "", | |
| 364 | + em_ctl & EM_CTL_SES ? "ses-2 " : "", | |
| 365 | + em_ctl & EM_CTL_SGPIO ? "sgpio " : ""); | |
| 366 | +} | |
| 367 | + | |
| 346 | 368 | /** |
| 347 | 369 | * ahci_save_initial_config - Save and fixup initial config values |
| 348 | 370 | * @dev: target AHCI device |
| @@ -1897,7 +1919,17 @@ static void ahci_pmp_attach(struct ata_port *ap) · 1548 unmodified lines | ||
| 1897 | 1919 | ahci_enable_fbs(ap); |
| 1898 | 1920 | |
| 1899 | 1921 | pp->intr_mask |= PORT_IRQ_BAD_PMP; |
| 1900 | − writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); | |
| 1922 | + | |
| 1923 | + /* | |
| 1924 | + * We must not change the port interrupt mask register if the | |
| 1925 | + * port is marked frozen, the value in pp->intr_mask will be | |
| 1926 | + * restored later when the port is thawed. | |
| 1927 | + * | |
| 1928 | + * Note that during initialization, the port is marked as | |
| 1929 | + * frozen since the irq handler is not yet registered. | |
| 1930 | + */ | |
| 1931 | + if (!(ap->pflags & ATA_PFLAG_FROZEN)) | |
| 1932 | + writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); | |
| 1901 | 1933 | } |
| 1902 | 1934 | |
| 1903 | 1935 | static void ahci_pmp_detach(struct ata_port *ap) |
| @@ -1913,7 +1945,10 @@ static void ahci_pmp_detach(struct ata_port *ap) · 9 unmodified lines | ||
| 1913 | 1945 | writel(cmd, port_mmio + PORT_CMD); |
| 1914 | 1946 | |
| 1915 | 1947 | pp->intr_mask &= ~PORT_IRQ_BAD_PMP; |
| 1916 | − writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); | |
| 1948 | + | |
| 1949 | + /* see comment above in ahci_pmp_attach() */ | |
| 1950 | + if (!(ap->pflags & ATA_PFLAG_FROZEN)) | |
| 1951 | + writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); | |
| 1917 | 1952 | } |
| 1918 | 1953 | |
| 1919 | 1954 | int ahci_port_resume(struct ata_port *ap) |
| @@ -4139,6 +4139,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { · 4138 unmodified lines | ||
| 4139 | 4139 | */ |
| 4140 | 4140 | { "PIONEER DVD-RW DVRTD08", "1.00", ATA_HORKAGE_NOSETXFER }, |
| 4141 | 4141 | { "PIONEER DVD-RW DVR-212D", "1.28", ATA_HORKAGE_NOSETXFER }, |
| 4142 | + { "PIONEER DVD-RW DVR-216D", "1.08", ATA_HORKAGE_NOSETXFER }, | |
| 4142 | 4143 | |
| 4143 | 4144 | /* End Marker */ |
| 4144 | 4145 | { } |
| @@ -5480,7 +5481,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host) · 1335 unmodified lines | ||
| 5480 | 5481 | if (!ap) |
| 5481 | 5482 | return NULL; |
| 5482 | 5483 | |
| 5483 | − ap->pflags |= ATA_PFLAG_INITIALIZING; | |
| 5484 | + ap->pflags |= ATA_PFLAG_INITIALIZING | ATA_PFLAG_FROZEN; | |
| 5484 | 5485 | ap->lock = &host->lock; |
| 5485 | 5486 | ap->print_id = -1; |
| 5486 | 5487 | ap->host = host; |
| @@ -3316,6 +3316,7 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, · 3315 unmodified lines | ||
| 3316 | 3316 | struct ata_eh_context *ehc = &link->eh_context; |
| 3317 | 3317 | struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL; |
| 3318 | 3318 | enum ata_lpm_policy old_policy = link->lpm_policy; |
| 3319 | + bool no_dipm = link->ap->flags & ATA_FLAG_NO_DIPM; | |
| 3319 | 3320 | unsigned int hints = ATA_LPM_EMPTY | ATA_LPM_HIPM; |
| 3320 | 3321 | unsigned int err_mask; |
| 3321 | 3322 | int rc; |
| @@ -3332,7 +3333,7 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, · 10 unmodified lines | ||
| 3332 | 3333 | */ |
| 3333 | 3334 | ata_for_each_dev(dev, link, ENABLED) { |
| 3334 | 3335 | bool hipm = ata_id_has_hipm(dev->id); |
| 3335 | − bool dipm = ata_id_has_dipm(dev->id); | |
| 3336 | + bool dipm = ata_id_has_dipm(dev->id) && !no_dipm; | |
| 3336 | 3337 | |
| 3337 | 3338 | /* find the first enabled and LPM enabled devices */ |
| 3338 | 3339 | if (!link_dev) |
| @@ -3389,7 +3390,8 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, · 50 unmodified lines | ||
| 3389 | 3390 | |
| 3390 | 3391 | /* host config updated, enable DIPM if transitioning to MIN_POWER */ |
| 3391 | 3392 | ata_for_each_dev(dev, link, ENABLED) { |
| 3392 | − if (policy == ATA_LPM_MIN_POWER && ata_id_has_dipm(dev->id)) { | |
| 3393 | + if (policy == ATA_LPM_MIN_POWER && !no_dipm && | |
| 3394 | + ata_id_has_dipm(dev->id)) { | |
| 3393 | 3395 | err_mask = ata_dev_set_feature(dev, |
| 3394 | 3396 | SETFEATURES_SATA_ENABLE, SATA_DIPM); |
| 3395 | 3397 | if (err_mask && err_mask != AC_ERR_DEV) { |
| @@ -33,11 +33,12 @@ · 32 unmodified lines | ||
| 33 | 33 | |
| 34 | 34 | |
| 35 | 35 | #define DRV_NAME "pata_at91" |
| 36 | −#define DRV_VERSION "0.1" | |
| 36 | +#define DRV_VERSION "0.2" | |
| 37 | 37 | |
| 38 | 38 | #define CF_IDE_OFFSET 0x00c00000 |
| 39 | 39 | #define CF_ALT_IDE_OFFSET 0x00e00000 |
| 40 | 40 | #define CF_IDE_RES_SIZE 0x08 |
| 41 | +#define NCS_RD_PULSE_LIMIT 0x3f /* maximal value for pulse bitfields */ | |
| 41 | 42 | |
| 42 | 43 | struct at91_ide_info { |
| 43 | 44 | unsigned long mode; |
| @@ -49,8 +50,18 @@ struct at91_ide_info { · 5 unmodified lines | ||
| 49 | 50 | void __iomem *alt_addr; |
| 50 | 51 | }; |
| 51 | 52 | |
| 52 | −static const struct ata_timing initial_timing = | |
| 53 | − {XFER_PIO_0, 70, 290, 240, 600, 165, 150, 600, 0}; | |
| 53 | +static const struct ata_timing initial_timing = { | |
| 54 | + .mode = XFER_PIO_0, | |
| 55 | + .setup = 70, | |
| 56 | + .act8b = 290, | |
| 57 | + .rec8b = 240, | |
| 58 | + .cyc8b = 600, | |
| 59 | + .active = 165, | |
| 60 | + .recover = 150, | |
| 61 | + .dmack_hold = 0, | |
| 62 | + .cycle = 600, | |
| 63 | + .udma = 0 | |
| 64 | +}; | |
| 54 | 65 | |
| 55 | 66 | static unsigned long calc_mck_cycles(unsigned long ns, unsigned long mck_hz) |
| 56 | 67 | { |
| @@ -109,6 +120,11 @@ static void set_smc_timing(struct device *dev, · 52 unmodified lines | ||
| 109 | 120 | /* (CS0, CS1, DIR, OE) <= (CFCE1, CFCE2, CFRNW, NCSX) timings */ |
| 110 | 121 | ncs_read_setup = 1; |
| 111 | 122 | ncs_read_pulse = read_cycle - 2; |
| 123 | + if (ncs_read_pulse > NCS_RD_PULSE_LIMIT) { | |
| 124 | + ncs_read_pulse = NCS_RD_PULSE_LIMIT; | |
| 125 | + dev_warn(dev, "ncs_read_pulse limited to maximal value %lu\n", | |
| 126 | + ncs_read_pulse); | |
| 127 | + } | |
| 112 | 128 | |
| 113 | 129 | /* Write timings same as read timings */ |
| 114 | 130 | write_cycle = read_cycle; |
| @@ -2643,16 +2643,19 @@ fore200e_init(struct fore200e* fore200e, struct device *parent) · 2642 unmodified lines | ||
| 2643 | 2643 | } |
| 2644 | 2644 | |
| 2645 | 2645 | #ifdef CONFIG_SBUS |
| 2646 | +static const struct of_device_id fore200e_sba_match[]; | |
| 2646 | 2647 | static int __devinit fore200e_sba_probe(struct platform_device *op) |
| 2647 | 2648 | { |
| 2649 | + const struct of_device_id *match; | |
| 2648 | 2650 | const struct fore200e_bus *bus; |
| 2649 | 2651 | struct fore200e *fore200e; |
| 2650 | 2652 | static int index = 0; |
| 2651 | 2653 | int err; |
| 2652 | 2654 | |
| 2653 | − if (!op->dev.of_match) | |
| 2655 | + match = of_match_device(fore200e_sba_match, &op->dev); | |
| 2656 | + if (!match) | |
| 2654 | 2657 | return -EINVAL; |
| 2655 | − bus = op->dev.of_match->data; | |
| 2658 | + bus = match->data; | |
| 2656 | 2659 | |
| 2657 | 2660 | fore200e = kzalloc(sizeof(struct fore200e), GFP_KERNEL); |
| 2658 | 2661 | if (!fore200e) |
| @@ -63,6 +63,7 @@ void device_pm_init(struct device *dev) · 62 unmodified lines | ||
| 63 | 63 | dev->power.wakeup = NULL; |
| 64 | 64 | spin_lock_init(&dev->power.lock); |
| 65 | 65 | pm_runtime_init(dev); |
| 66 | + INIT_LIST_HEAD(&dev->power.entry); | |
| 66 | 67 | } |
| 67 | 68 | |
| 68 | 69 | /** |
| @@ -258,7 +258,7 @@ void device_set_wakeup_capable(struct device *dev, bool capable) · 257 unmodified lines | ||
| 258 | 258 | if (!!dev->power.can_wakeup == !!capable) |
| 259 | 259 | return; |
| 260 | 260 | |
| 261 | − if (device_is_registered(dev)) { | |
| 261 | + if (device_is_registered(dev) && !list_empty(&dev->power.entry)) { | |
| 262 | 262 | if (capable) { |
| 263 | 263 | if (wakeup_sysfs_add(dev)) |
| 264 | 264 | return; |
| @@ -73,6 +73,7 @@ int syscore_suspend(void) · 72 unmodified lines | ||
| 73 | 73 | |
| 74 | 74 | return ret; |
| 75 | 75 | } |
| 76 | +EXPORT_SYMBOL_GPL(syscore_suspend); | |
| 76 | 77 | |
| 77 | 78 | /** |
| 78 | 79 | * syscore_resume - Execute all the registered system core resume callbacks. |
| @@ -95,6 +96,7 @@ void syscore_resume(void) · 16 unmodified lines | ||
| 95 | 96 | "Interrupts enabled after %pF\n", ops->resume); |
| 96 | 97 | } |
| 97 | 98 | } |
| 99 | +EXPORT_SYMBOL_GPL(syscore_resume); | |
| 98 | 100 | #endif /* CONFIG_PM_SLEEP */ |
| 99 | 101 | |
| 100 | 102 | /** |
| @@ -2547,7 +2547,6 @@ static bool DAC960_RegisterBlockDevice(DAC960_Controller_T *Controller) · 2546 unmodified lines | ||
| 2547 | 2547 | disk->major = MajorNumber; |
| 2548 | 2548 | disk->first_minor = n << DAC960_MaxPartitionsBits; |
| 2549 | 2549 | disk->fops = &DAC960_BlockDeviceOperations; |
| 2550 | − disk->events = DISK_EVENT_MEDIA_CHANGE; | |
| 2551 | 2550 | } |
| 2552 | 2551 | /* |
| 2553 | 2552 | Indicate the Block Device Registration completed successfully, |
| @@ -1736,7 +1736,6 @@ static int __init fd_probe_drives(void) · 1735 unmodified lines | ||
| 1736 | 1736 | disk->major = FLOPPY_MAJOR; |
| 1737 | 1737 | disk->first_minor = drive; |
| 1738 | 1738 | disk->fops = &floppy_fops; |
| 1739 | − disk->events = DISK_EVENT_MEDIA_CHANGE; | |
| 1740 | 1739 | sprintf(disk->disk_name, "fd%d", drive); |
| 1741 | 1740 | disk->private_data = &unit[drive]; |
| 1742 | 1741 | set_capacity(disk, 880*2); |
| @@ -1964,7 +1964,6 @@ static int __init atari_floppy_init (void) · 1963 unmodified lines | ||
| 1964 | 1964 | unit[i].disk->first_minor = i; |
| 1965 | 1965 | sprintf(unit[i].disk->disk_name, "fd%d", i); |
| 1966 | 1966 | unit[i].disk->fops = &floppy_fops; |
| 1967 | − unit[i].disk->events = DISK_EVENT_MEDIA_CHANGE; | |
| 1968 | 1967 | unit[i].disk->private_data = &unit[i]; |
| 1969 | 1968 | unit[i].disk->queue = blk_init_queue(do_fd_request, |
| 1970 | 1969 | &ataflop_lock); |
| @@ -4205,7 +4205,6 @@ static int __init floppy_init(void) · 4204 unmodified lines | ||
| 4205 | 4205 | disks[dr]->major = FLOPPY_MAJOR; |
| 4206 | 4206 | disks[dr]->first_minor = TOMINOR(dr); |
| 4207 | 4207 | disks[dr]->fops = &floppy_fops; |
| 4208 | − disks[dr]->events = DISK_EVENT_MEDIA_CHANGE; | |
| 4209 | 4208 | sprintf(disks[dr]->disk_name, "fd%d", dr); |
| 4210 | 4209 | |
| 4211 | 4210 | init_timer(&motor_off_timer[dr]); |
| @@ -837,7 +837,6 @@ static void pd_probe_drive(struct pd_unit *disk) · 836 unmodified lines | ||
| 837 | 837 | p->fops = &pd_fops; |
| 838 | 838 | p->major = major; |
| 839 | 839 | p->first_minor = (disk - pd) << PD_BITS; |
| 840 | − p->events = DISK_EVENT_MEDIA_CHANGE; | |
| 841 | 840 | disk->gd = p; |
| 842 | 841 | p->private_data = disk; |
| 843 | 842 | p->queue = pd_queue; |
| @@ -294,7 +294,6 @@ static void __init pf_init_units(void) · 293 unmodified lines | ||
| 294 | 294 | disk->first_minor = unit; |
| 295 | 295 | strcpy(disk->disk_name, pf->name); |
| 296 | 296 | disk->fops = &pf_fops; |
| 297 | − disk->events = DISK_EVENT_MEDIA_CHANGE; | |
| 298 | 297 | if (!(*drives[unit])[D_PRT]) |
| 299 | 298 | pf_drive_count++; |
| 300 | 299 | } |
| @@ -92,6 +92,8 @@ struct rbd_client { · 91 unmodified lines | ||
| 92 | 92 | struct list_head node; |
| 93 | 93 | }; |
| 94 | 94 | |
| 95 | +struct rbd_req_coll; | |
| 96 | + | |
| 95 | 97 | /* |
| 96 | 98 | * a single io request |
| 97 | 99 | */ |
| @@ -100,6 +102,24 @@ struct rbd_request { · 2 unmodified lines | ||
| 100 | 102 | struct bio *bio; /* cloned bio */ |
| 101 | 103 | struct page **pages; /* list of used pages */ |
| 102 | 104 | u64 len; |
| 105 | + int coll_index; | |
| 106 | + struct rbd_req_coll *coll; | |
| 107 | +}; | |
| 108 | + | |
| 109 | +struct rbd_req_status { | |
| 110 | + int done; | |
| 111 | + int rc; | |
| 112 | + u64 bytes; | |
| 113 | +}; | |
| 114 | + | |
| 115 | +/* | |
| 116 | + * a collection of requests | |
| 117 | + */ | |
| 118 | +struct rbd_req_coll { | |
| 119 | + int total; | |
| 120 | + int num_done; | |
| 121 | + struct kref kref; | |
| 122 | + struct rbd_req_status status[0]; | |
| 103 | 123 | }; |
| 104 | 124 | |
| 105 | 125 | struct rbd_snap { |
| @@ -416,6 +436,17 @@ static void rbd_put_client(struct rbd_device *rbd_dev) · 310 unmodified lines | ||
| 416 | 436 | rbd_dev->client = NULL; |
| 417 | 437 | } |
| 418 | 438 | |
| 439 | +/* | |
| 440 | + * Destroy requests collection | |
| 441 | + */ | |
| 442 | +static void rbd_coll_release(struct kref *kref) | |
| 443 | +{ | |
| 444 | + struct rbd_req_coll *coll = | |
| 445 | + container_of(kref, struct rbd_req_coll, kref); | |
| 446 | + | |
| 447 | + dout("rbd_coll_release %p\n", coll); | |
| 448 | + kfree(coll); | |
| 449 | +} | |
| 419 | 450 | |
| 420 | 451 | /* |
| 421 | 452 | * Create a new header structure, translate header format from the on-disk |
| @@ -590,6 +621,14 @@ static u64 rbd_get_segment(struct rbd_image_header *header, · 168 unmodified lines | ||
| 590 | 621 | return len; |
| 591 | 622 | } |
| 592 | 623 | |
| 624 | +static int rbd_get_num_segments(struct rbd_image_header *header, | |
| 625 | + u64 ofs, u64 len) | |
| 626 | +{ | |
| 627 | + u64 start_seg = ofs >> header->obj_order; | |
| 628 | + u64 end_seg = (ofs + len - 1) >> header->obj_order; | |
| 629 | + return end_seg - start_seg + 1; | |
| 630 | +} | |
| 631 | + | |
| 593 | 632 | /* |
| 594 | 633 | * bio helpers |
| 595 | 634 | */ |
| @@ -735,6 +774,50 @@ static void rbd_destroy_ops(struct ceph_osd_req_op *ops) · 139 unmodified lines | ||
| 735 | 774 | kfree(ops); |
| 736 | 775 | } |
| 737 | 776 | |
| 777 | +static void rbd_coll_end_req_index(struct request *rq, | |
| 778 | + struct rbd_req_coll *coll, | |
| 779 | + int index, | |
| 780 | + int ret, u64 len) | |
| 781 | +{ | |
| 782 | + struct request_queue *q; | |
| 783 | + int min, max, i; | |
| 784 | + | |
| 785 | + dout("rbd_coll_end_req_index %p index %d ret %d len %lld\n", | |
| 786 | + coll, index, ret, len); | |
| 787 | + | |
| 788 | + if (!rq) | |
| 789 | + return; | |
| 790 | + | |
| 791 | + if (!coll) { | |
| 792 | + blk_end_request(rq, ret, len); | |
| 793 | + return; | |
| 794 | + } | |
| 795 | + | |
| 796 | + q = rq->q; | |
| 797 | + | |
| 798 | + spin_lock_irq(q->queue_lock); | |
| 799 | + coll->status[index].done = 1; | |
| 800 | + coll->status[index].rc = ret; | |
| 801 | + coll->status[index].bytes = len; | |
| 802 | + max = min = coll->num_done; | |
| 803 | + while (max < coll->total && coll->status[max].done) | |
| 804 | + max++; | |
| 805 | + | |
| 806 | + for (i = min; i<max; i++) { | |
| 807 | + __blk_end_request(rq, coll->status[i].rc, | |
| 808 | + coll->status[i].bytes); | |
| 809 | + coll->num_done++; | |
| 810 | + kref_put(&coll->kref, rbd_coll_release); | |
| 811 | + } | |
| 812 | + spin_unlock_irq(q->queue_lock); | |
| 813 | +} | |
| 814 | + | |
| 815 | +static void rbd_coll_end_req(struct rbd_request *req, | |
| 816 | + int ret, u64 len) | |
| 817 | +{ | |
| 818 | + rbd_coll_end_req_index(req->rq, req->coll, req->coll_index, ret, len); | |
| 819 | +} | |
| 820 | + | |
| 738 | 821 | /* |
| 739 | 822 | * Send ceph osd request |
| 740 | 823 | */ |
| @@ -749,6 +832,8 @@ static int rbd_do_request(struct request *rq, · 8 unmodified lines | ||
| 749 | 832 | int flags, |
| 750 | 833 | struct ceph_osd_req_op *ops, |
| 751 | 834 | int num_reply, |
| 835 | + struct rbd_req_coll *coll, | |
| 836 | + int coll_index, | |
| 752 | 837 | void (*rbd_cb)(struct ceph_osd_request *req, |
| 753 | 838 | struct ceph_msg *msg), |
| 754 | 839 | struct ceph_osd_request **linger_req, |
| @@ -763,12 +848,20 @@ static int rbd_do_request(struct request *rq, · 8 unmodified lines | ||
| 763 | 848 | struct ceph_osd_request_head *reqhead; |
| 764 | 849 | struct rbd_image_header *header = &dev->header; |
| 765 | 850 | |
| 766 | − ret = -ENOMEM; | |
| 767 | 851 | req_data = kzalloc(sizeof(*req_data), GFP_NOIO); |
| 768 | − if (!req_data) | |
| 769 | − goto done; | |
| 852 | + if (!req_data) { | |
| 853 | + if (coll) | |
| 854 | + rbd_coll_end_req_index(rq, coll, coll_index, | |
| 855 | + -ENOMEM, len); | |
| 856 | + return -ENOMEM; | |
| 857 | + } | |
| 770 | 858 | |
| 771 | − dout("rbd_do_request len=%lld ofs=%lld\n", len, ofs); | |
| 859 | + if (coll) { | |
| 860 | + req_data->coll = coll; | |
| 861 | + req_data->coll_index = coll_index; | |
| 862 | + } | |
| 863 | + | |
| 864 | + dout("rbd_do_request obj=%s ofs=%lld len=%lld\n", obj, len, ofs); | |
| 772 | 865 | |
| 773 | 866 | down_read(&header->snap_rwsem); |
| 774 | 867 | |
| @@ -777,9 +870,9 @@ static int rbd_do_request(struct request *rq, · 2 unmodified lines | ||
| 777 | 870 | ops, |
| 778 | 871 | false, |
| 779 | 872 | GFP_NOIO, pages, bio); |
| 780 | − if (IS_ERR(req)) { | |
| 873 | + if (!req) { | |
| 781 | 874 | up_read(&header->snap_rwsem); |
| 782 | − ret = PTR_ERR(req); | |
| 875 | + ret = -ENOMEM; | |
| 783 | 876 | goto done_pages; |
| 784 | 877 | } |
| 785 | 878 | |
| @@ -828,7 +921,8 @@ static int rbd_do_request(struct request *rq, · 42 unmodified lines | ||
| 828 | 921 | ret = ceph_osdc_wait_request(&dev->client->osdc, req); |
| 829 | 922 | if (ver) |
| 830 | 923 | *ver = le64_to_cpu(req->r_reassert_version.version); |
| 831 | − dout("reassert_ver=%lld\n", le64_to_cpu(req->r_reassert_version.version)); | |
| 924 | + dout("reassert_ver=%lld\n", | |
| 925 | + le64_to_cpu(req->r_reassert_version.version)); | |
| 832 | 926 | ceph_osdc_put_request(req); |
| 833 | 927 | } |
| 834 | 928 | return ret; |
| @@ -837,10 +931,8 @@ done_err: · 2 unmodified lines | ||
| 837 | 931 | bio_chain_put(req_data->bio); |
| 838 | 932 | ceph_osdc_put_request(req); |
| 839 | 933 | done_pages: |
| 934 | + rbd_coll_end_req(req_data, ret, len); | |
| 840 | 935 | kfree(req_data); |
| 841 | −done: | |
| 842 | − if (rq) | |
| 843 | − blk_end_request(rq, ret, len); | |
| 844 | 936 | return ret; |
| 845 | 937 | } |
| 846 | 938 | |
| @@ -874,7 +966,7 @@ static void rbd_req_cb(struct ceph_osd_request *req, struct ceph_msg *msg) · 27 unmodified lines | ||
| 874 | 966 | bytes = req_data->len; |
| 875 | 967 | } |
| 876 | 968 | |
| 877 | − blk_end_request(req_data->rq, rc, bytes); | |
| 969 | + rbd_coll_end_req(req_data, rc, bytes); | |
| 878 | 970 | |
| 879 | 971 | if (req_data->bio) |
| 880 | 972 | bio_chain_put(req_data->bio); |
| @@ -934,6 +1026,7 @@ static int rbd_req_sync_op(struct rbd_device *dev, · 53 unmodified lines | ||
| 934 | 1026 | flags, |
| 935 | 1027 | ops, |
| 936 | 1028 | 2, |
| 1029 | + NULL, 0, | |
| 937 | 1030 | NULL, |
| 938 | 1031 | linger_req, ver); |
| 939 | 1032 | if (ret < 0) |
| @@ -959,7 +1052,9 @@ static int rbd_do_op(struct request *rq, · 19 unmodified lines | ||
| 959 | 1052 | u64 snapid, |
| 960 | 1053 | int opcode, int flags, int num_reply, |
| 961 | 1054 | u64 ofs, u64 len, |
| 962 | − struct bio *bio) | |
| 1055 | + struct bio *bio, | |
| 1056 | + struct rbd_req_coll *coll, | |
| 1057 | + int coll_index) | |
| 963 | 1058 | { |
| 964 | 1059 | char *seg_name; |
| 965 | 1060 | u64 seg_ofs; |
| @@ -995,7 +1090,10 @@ static int rbd_do_op(struct request *rq, · 29 unmodified lines | ||
| 995 | 1090 | flags, |
| 996 | 1091 | ops, |
| 997 | 1092 | num_reply, |
| 1093 | + coll, coll_index, | |
| 998 | 1094 | rbd_req_cb, 0, NULL); |
| 1095 | + | |
| 1096 | + rbd_destroy_ops(ops); | |
| 999 | 1097 | done: |
| 1000 | 1098 | kfree(seg_name); |
| 1001 | 1099 | return ret; |
| @@ -1008,13 +1106,15 @@ static int rbd_req_write(struct request *rq, · 6 unmodified lines | ||
| 1008 | 1106 | struct rbd_device *rbd_dev, |
| 1009 | 1107 | struct ceph_snap_context *snapc, |
| 1010 | 1108 | u64 ofs, u64 len, |
| 1011 | − struct bio *bio) | |
| 1109 | + struct bio *bio, | |
| 1110 | + struct rbd_req_coll *coll, | |
| 1111 | + int coll_index) | |
| 1012 | 1112 | { |
| 1013 | 1113 | return rbd_do_op(rq, rbd_dev, snapc, CEPH_NOSNAP, |
| 1014 | 1114 | CEPH_OSD_OP_WRITE, |
| 1015 | 1115 | CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK, |
| 1016 | 1116 | 2, |
| 1017 | − ofs, len, bio); | |
| 1117 | + ofs, len, bio, coll, coll_index); | |
| 1018 | 1118 | } |
| 1019 | 1119 | |
| 1020 | 1120 | /* |
| @@ -1024,14 +1124,16 @@ static int rbd_req_read(struct request *rq, · 3 unmodified lines | ||
| 1024 | 1124 | struct rbd_device *rbd_dev, |
| 1025 | 1125 | u64 snapid, |
| 1026 | 1126 | u64 ofs, u64 len, |
| 1027 | − struct bio *bio) | |
| 1127 | + struct bio *bio, | |
| 1128 | + struct rbd_req_coll *coll, | |
| 1129 | + int coll_index) | |
| 1028 | 1130 | { |
| 1029 | 1131 | return rbd_do_op(rq, rbd_dev, NULL, |
| 1030 | 1132 | (snapid ? snapid : CEPH_NOSNAP), |
| 1031 | 1133 | CEPH_OSD_OP_READ, |
| 1032 | 1134 | CEPH_OSD_FLAG_READ, |
| 1033 | 1135 | 2, |
| 1034 | − ofs, len, bio); | |
| 1136 | + ofs, len, bio, coll, coll_index); | |
| 1035 | 1137 | } |
| 1036 | 1138 | |
| 1037 | 1139 | /* |
| @@ -1063,7 +1165,9 @@ static int rbd_req_sync_notify_ack(struct rbd_device *dev, · 25 unmodified lines | ||
| 1063 | 1165 | { |
| 1064 | 1166 | struct ceph_osd_req_op *ops; |
| 1065 | 1167 | struct page **pages = NULL; |
| 1066 | − int ret = rbd_create_rw_ops(&ops, 1, CEPH_OSD_OP_NOTIFY_ACK, 0); | |
| 1168 | + int ret; | |
| 1169 | + | |
| 1170 | + ret = rbd_create_rw_ops(&ops, 1, CEPH_OSD_OP_NOTIFY_ACK, 0); | |
| 1067 | 1171 | if (ret < 0) |
| 1068 | 1172 | return ret; |
| 1069 | 1173 | |
| @@ -1077,6 +1181,7 @@ static int rbd_req_sync_notify_ack(struct rbd_device *dev, · 7 unmodified lines | ||
| 1077 | 1181 | CEPH_OSD_FLAG_READ, |
| 1078 | 1182 | ops, |
| 1079 | 1183 | 1, |
| 1184 | + NULL, 0, | |
| 1080 | 1185 | rbd_simple_req_cb, 0, NULL); |
| 1081 | 1186 | |
| 1082 | 1187 | rbd_destroy_ops(ops); |
| @@ -1274,6 +1379,20 @@ static int rbd_req_sync_exec(struct rbd_device *dev, · 191 unmodified lines | ||
| 1274 | 1379 | return ret; |
| 1275 | 1380 | } |
| 1276 | 1381 | |
| 1382 | +static struct rbd_req_coll *rbd_alloc_coll(int num_reqs) | |
| 1383 | +{ | |
| 1384 | + struct rbd_req_coll *coll = | |
| 1385 | + kzalloc(sizeof(struct rbd_req_coll) + | |
| 1386 | + sizeof(struct rbd_req_status) * num_reqs, | |
| 1387 | + GFP_ATOMIC); | |
| 1388 | + | |
| 1389 | + if (!coll) | |
| 1390 | + return NULL; | |
| 1391 | + coll->total = num_reqs; | |
| 1392 | + kref_init(&coll->kref); | |
| 1393 | + return coll; | |
| 1394 | +} | |
| 1395 | + | |
| 1277 | 1396 | /* |
| 1278 | 1397 | * block device queue callback |
| 1279 | 1398 | */ |
| @@ -1291,6 +1410,8 @@ static void rbd_rq_fn(struct request_queue *q) · 11 unmodified lines | ||
| 1291 | 1410 | bool do_write; |
| 1292 | 1411 | int size, op_size = 0; |
| 1293 | 1412 | u64 ofs; |
| 1413 | + int num_segs, cur_seg = 0; | |
| 1414 | + struct rbd_req_coll *coll; | |
| 1294 | 1415 | |
| 1295 | 1416 | /* peek at request from block layer */ |
| 1296 | 1417 | if (!rq) |
| @@ -1321,6 +1442,14 @@ static void rbd_rq_fn(struct request_queue *q) · 24 unmodified lines | ||
| 1321 | 1442 | do_write ? "write" : "read", |
| 1322 | 1443 | size, blk_rq_pos(rq) * 512ULL); |
| 1323 | 1444 | |
| 1445 | + num_segs = rbd_get_num_segments(&rbd_dev->header, ofs, size); | |
| 1446 | + coll = rbd_alloc_coll(num_segs); | |
| 1447 | + if (!coll) { | |
| 1448 | + spin_lock_irq(q->queue_lock); | |
| 1449 | + __blk_end_request_all(rq, -ENOMEM); | |
| 1450 | + goto next; | |
| 1451 | + } | |
| 1452 | + | |
| 1324 | 1453 | do { |
| 1325 | 1454 | /* a bio clone to be passed down to OSD req */ |
| 1326 | 1455 | dout("rq->bio->bi_vcnt=%d\n", rq->bio->bi_vcnt); |
| @@ -1328,35 +1457,41 @@ static void rbd_rq_fn(struct request_queue *q) · 1 unmodified line | ||
| 1328 | 1457 | rbd_dev->header.block_name, |
| 1329 | 1458 | ofs, size, |
| 1330 | 1459 | NULL, NULL); |
| 1460 | + kref_get(&coll->kref); | |
| 1331 | 1461 | bio = bio_chain_clone(&rq_bio, &next_bio, &bp, |
| 1332 | 1462 | op_size, GFP_ATOMIC); |
| 1333 | 1463 | if (!bio) { |
| 1334 | − spin_lock_irq(q->queue_lock); | |
| 1335 | − __blk_end_request_all(rq, -ENOMEM); | |
| 1336 | − goto next; | |
| 1464 | + rbd_coll_end_req_index(rq, coll, cur_seg, | |
| 1465 | + -ENOMEM, op_size); | |
| 1466 | + goto next_seg; | |
| 1337 | 1467 | } |
| 1338 | 1468 | |
| 1469 | + | |
| 1339 | 1470 | /* init OSD command: write or read */ |
| 1340 | 1471 | if (do_write) |
| 1341 | 1472 | rbd_req_write(rq, rbd_dev, |
| 1342 | 1473 | rbd_dev->header.snapc, |
| 1343 | 1474 | ofs, |
| 1344 | − op_size, bio); | |
| 1475 | + op_size, bio, | |
| 1476 | + coll, cur_seg); | |
| 1345 | 1477 | else |
| 1346 | 1478 | rbd_req_read(rq, rbd_dev, |
| 1347 | 1479 | cur_snap_id(rbd_dev), |
| 1348 | 1480 | ofs, |
| 1349 | − op_size, bio); | |
| 1481 | + op_size, bio, | |
| 1482 | + coll, cur_seg); | |
| 1350 | 1483 | |
| 1484 | +next_seg: | |
| 1351 | 1485 | size -= op_size; |
| 1352 | 1486 | ofs += op_size; |
| 1353 | 1487 | |
| 1488 | + cur_seg++; | |
| 1354 | 1489 | rq_bio = next_bio; |
| 1355 | 1490 | } while (size > 0); |
| 1491 | + kref_put(&coll->kref, rbd_coll_release); | |
| 1356 | 1492 | |
| 1357 | 1493 | if (bp) |
| 1358 | 1494 | bio_pair_release(bp); |
| 1359 | − | |
| 1360 | 1495 | spin_lock_irq(q->queue_lock); |
| 1361 | 1496 | next: |
| 1362 | 1497 | rq = blk_fetch_request(q); |
| @@ -858,7 +858,6 @@ static int __devinit swim_floppy_init(struct swim_priv *swd) · 857 unmodified lines | ||
| 858 | 858 | swd->unit[drive].disk->first_minor = drive; |
| 859 | 859 | sprintf(swd->unit[drive].disk->disk_name, "fd%d", drive); |
| 860 | 860 | swd->unit[drive].disk->fops = &floppy_fops; |
| 861 | − swd->unit[drive].disk->events = DISK_EVENT_MEDIA_CHANGE; | |
| 862 | 861 | swd->unit[drive].disk->private_data = &swd->unit[drive]; |
| 863 | 862 | swd->unit[drive].disk->queue = swd->queue; |
| 864 | 863 | set_capacity(swd->unit[drive].disk, 2880); |
| @@ -1163,7 +1163,6 @@ static int __devinit swim3_attach(struct macio_dev *mdev, const struct of_device · 1162 unmodified lines | ||
| 1163 | 1163 | disk->major = FLOPPY_MAJOR; |
| 1164 | 1164 | disk->first_minor = i; |
| 1165 | 1165 | disk->fops = &floppy_fops; |
| 1166 | − disk->events = DISK_EVENT_MEDIA_CHANGE; | |
| 1167 | 1166 | disk->private_data = &floppy_states[i]; |
| 1168 | 1167 | disk->queue = swim3_queue; |
| 1169 | 1168 | disk->flags |= GENHD_FL_REMOVABLE; |
| @@ -2334,7 +2334,6 @@ static int ub_probe_lun(struct ub_dev *sc, int lnum) · 2333 unmodified lines | ||
| 2334 | 2334 | disk->major = UB_MAJOR; |
| 2335 | 2335 | disk->first_minor = lun->id * UB_PARTS_PER_LUN; |
| 2336 | 2336 | disk->fops = &ub_bd_fops; |
| 2337 | − disk->events = DISK_EVENT_MEDIA_CHANGE; | |
| 2338 | 2337 | disk->private_data = lun; |
| 2339 | 2338 | disk->driverfs_dev = &sc->intf->dev; |
| 2340 | 2339 | |
| @@ -1005,7 +1005,6 @@ static int __devinit ace_setup(struct ace_device *ace) · 1004 unmodified lines | ||
| 1005 | 1005 | ace->gd->major = ace_major; |
| 1006 | 1006 | ace->gd->first_minor = ace->id * ACE_NUM_MINORS; |
| 1007 | 1007 | ace->gd->fops = &ace_fops; |
| 1008 | − ace->gd->events = DISK_EVENT_MEDIA_CHANGE; | |
| 1009 | 1008 | ace->gd->queue = ace->queue; |
| 1010 | 1009 | ace->gd->private_data = ace; |
| 1011 | 1010 | snprintf(ace->gd->disk_name, 32, "xs%c", ace->id + 'a'); |
| @@ -803,7 +803,6 @@ static int __devinit probe_gdrom(struct platform_device *devptr) · 802 unmodified lines | ||
| 803 | 803 | goto probe_fail_cdrom_register; |
| 804 | 804 | } |
| 805 | 805 | gd.disk->fops = &gdrom_bdops; |
| 806 | − gd.disk->events = DISK_EVENT_MEDIA_CHANGE; | |
| 807 | 806 | /* latch on to the interrupt */ |
| 808 | 807 | err = gdrom_set_interrupt_handlers(); |
| 809 | 808 | if (err) |
| @@ -115,6 +115,9 @@ static struct agp_memory *agp_create_user_memory(unsigned long num_agp_pages) · 114 unmodified lines | ||
| 115 | 115 | struct agp_memory *new; |
| 116 | 116 | unsigned long alloc_size = num_agp_pages*sizeof(struct page *); |
| 117 | 117 | |
| 118 | + if (INT_MAX/sizeof(struct page *) < num_agp_pages) | |
| 119 | + return NULL; | |
| 120 | + | |
| 118 | 121 | new = kzalloc(sizeof(struct agp_memory), GFP_KERNEL); |
| 119 | 122 | if (new == NULL) |
| 120 | 123 | return NULL; |
| @@ -234,11 +237,14 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge, · 113 unmodified lines | ||
| 234 | 237 | int scratch_pages; |
| 235 | 238 | struct agp_memory *new; |
| 236 | 239 | size_t i; |
| 240 | + int cur_memory; | |
| 237 | 241 | |
| 238 | 242 | if (!bridge) |
| 239 | 243 | return NULL; |
| 240 | 244 | |
| 241 | − if ((atomic_read(&bridge->current_memory_agp) + page_count) > bridge->max_memory_agp) | |
| 245 | + cur_memory = atomic_read(&bridge->current_memory_agp); | |
| 246 | + if ((cur_memory + page_count > bridge->max_memory_agp) || | |
| 247 | + (cur_memory + page_count < page_count)) | |
| 242 | 248 | return NULL; |
| 243 | 249 | |
| 244 | 250 | if (type >= AGP_USER_TYPES) { |
| @@ -1089,8 +1095,8 @@ int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type) · 844 unmodified lines | ||
| 1089 | 1095 | return -EINVAL; |
| 1090 | 1096 | } |
| 1091 | 1097 | |
| 1092 | − /* AK: could wrap */ | |
| 1093 | − if ((pg_start + mem->page_count) > num_entries) | |
| 1098 | + if (((pg_start + mem->page_count) > num_entries) || | |
| 1099 | + ((pg_start + mem->page_count) < pg_start)) | |
| 1094 | 1100 | return -EINVAL; |
| 1095 | 1101 | |
| 1096 | 1102 | j = pg_start; |
| @@ -1124,7 +1130,7 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type) · 27 unmodified lines | ||
| 1124 | 1130 | { |
| 1125 | 1131 | size_t i; |
| 1126 | 1132 | struct agp_bridge_data *bridge; |
| 1127 | − int mask_type; | |
| 1133 | + int mask_type, num_entries; | |
| 1128 | 1134 | |
| 1129 | 1135 | bridge = mem->bridge; |
| 1130 | 1136 | if (!bridge) |
| @@ -1136,6 +1142,11 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type) · 5 unmodified lines | ||
| 1136 | 1142 | if (type != mem->type) |
| 1137 | 1143 | return -EINVAL; |
| 1138 | 1144 | |
| 1145 | + num_entries = agp_num_entries(); | |
| 1146 | + if (((pg_start + mem->page_count) > num_entries) || | |
| 1147 | + ((pg_start + mem->page_count) < pg_start)) | |
| 1148 | + return -EINVAL; | |
| 1149 | + | |
| 1139 | 1150 | mask_type = bridge->driver->agp_type_to_mask_type(bridge, type); |
| 1140 | 1151 | if (mask_type != 0) { |
| 1141 | 1152 | /* The generic routines know nothing of memory types */ |
| @@ -619,15 +619,18 @@ static void __devinit n2rng_driver_version(void) · 618 unmodified lines | ||
| 619 | 619 | pr_info("%s", version); |
| 620 | 620 | } |
| 621 | 621 | |
| 622 | +static const struct of_device_id n2rng_match[]; | |
| 622 | 623 | static int __devinit n2rng_probe(struct platform_device *op) |
| 623 | 624 | { |
| 625 | + const struct of_device_id *match; | |
| 624 | 626 | int victoria_falls; |
| 625 | 627 | int err = -ENOMEM; |
| 626 | 628 | struct n2rng *np; |
| 627 | 629 | |
| 628 | − if (!op->dev.of_match) | |
| 630 | + match = of_match_device(n2rng_match, &op->dev); | |
| 631 | + if (!match) | |
| 629 | 632 | return -EINVAL; |
| 630 | − victoria_falls = (op->dev.of_match->data != NULL); | |
| 633 | + victoria_falls = (match->data != NULL); | |
| 631 | 634 | |
| 632 | 635 | n2rng_driver_version(); |
| 633 | 636 | np = kzalloc(sizeof(*np), GFP_KERNEL); |
| @@ -2554,9 +2554,11 @@ static struct pci_driver ipmi_pci_driver = { · 2553 unmodified lines | ||
| 2554 | 2554 | }; |
| 2555 | 2555 | #endif /* CONFIG_PCI */ |
| 2556 | 2556 | |
| 2557 | +static struct of_device_id ipmi_match[]; | |
| 2557 | 2558 | static int __devinit ipmi_probe(struct platform_device *dev) |
| 2558 | 2559 | { |
| 2559 | 2560 | #ifdef CONFIG_OF |
| 2561 | + const struct of_device_id *match; | |
| 2560 | 2562 | struct smi_info *info; |
| 2561 | 2563 | struct resource resource; |
| 2562 | 2564 | const __be32 *regsize, *regspacing, *regshift; |
| @@ -2566,7 +2568,8 @@ static int __devinit ipmi_probe(struct platform_device *dev) · 3 unmodified lines | ||
| 2566 | 2568 | |
| 2567 | 2569 | dev_info(&dev->dev, "probing via device tree\n"); |
| 2568 | 2570 | |
| 2569 | − if (!dev->dev.of_match) | |
| 2571 | + match = of_match_device(ipmi_match, &dev->dev); | |
| 2572 | + if (!match) | |
| 2570 | 2573 | return -EINVAL; |
| 2571 | 2574 | |
| 2572 | 2575 | ret = of_address_to_resource(np, 0, &resource); |
| @@ -2601,7 +2604,7 @@ static int __devinit ipmi_probe(struct platform_device *dev) · 28 unmodified lines | ||
| 2601 | 2604 | return -ENOMEM; |
| 2602 | 2605 | } |
| 2603 | 2606 | |
| 2604 | − info->si_type = (enum si_type) dev->dev.of_match->data; | |
| 2607 | + info->si_type = (enum si_type) match->data; | |
| 2605 | 2608 | info->addr_source = SI_DEVICETREE; |
| 2606 | 2609 | info->irq_setup = std_irq_setup; |
| 2607 | 2610 | |
| @@ -1280,18 +1280,7 @@ static void unplug_port(struct port *port) · 1279 unmodified lines | ||
| 1280 | 1280 | spin_lock_irq(&pdrvdata_lock); |
| 1281 | 1281 | list_del(&port->cons.list); |
| 1282 | 1282 | spin_unlock_irq(&pdrvdata_lock); |
| 1283 | −#if 0 | |
| 1284 | − /* | |
| 1285 | − * hvc_remove() not called as removing one hvc port | |
| 1286 | − * results in other hvc ports getting frozen. | |
| 1287 | − * | |
| 1288 | − * Once this is resolved in hvc, this functionality | |
| 1289 | − * will be enabled. Till that is done, the -EPIPE | |
| 1290 | − * return from get_chars() above will help | |
| 1291 | − * hvc_console.c to clean up on ports we remove here. | |
| 1292 | − */ | |
| 1293 | 1283 | hvc_remove(port->cons.hvc); |
| 1294 | −#endif | |
| 1295 | 1284 | } |
| 1296 | 1285 | |
| 1297 | 1286 | /* Remove unused data this port might have received. */ |
| @@ -715,13 +715,13 @@ static int __devexit hwicap_remove(struct device *dev) · 714 unmodified lines | ||
| 715 | 715 | } |
| 716 | 716 | |
| 717 | 717 | #ifdef CONFIG_OF |
| 718 | −static int __devinit hwicap_of_probe(struct platform_device *op) | |
| 718 | +static int __devinit hwicap_of_probe(struct platform_device *op, | |
| 719 | + const struct hwicap_driver_config *config) | |
| 719 | 720 | { |
| 720 | 721 | struct resource res; |
| 721 | 722 | const unsigned int *id; |
| 722 | 723 | const char *family; |
| 723 | 724 | int rc; |
| 724 | − const struct hwicap_driver_config *config = op->dev.of_match->data; | |
| 725 | 725 | const struct config_registers *regs; |
| 726 | 726 | |
| 727 | 727 | |
| @@ -751,20 +751,24 @@ static int __devinit hwicap_of_probe(struct platform_device *op) · 23 unmodified lines | ||
| 751 | 751 | regs); |
| 752 | 752 | } |
| 753 | 753 | #else |
| 754 | −static inline int hwicap_of_probe(struct platform_device *op) | |
| 754 | +static inline int hwicap_of_probe(struct platform_device *op, | |
| 755 | + const struct hwicap_driver_config *config) | |
| 755 | 756 | { |
| 756 | 757 | return -EINVAL; |
| 757 | 758 | } |
| 758 | 759 | #endif /* CONFIG_OF */ |
| 759 | 760 | |
| 761 | +static const struct of_device_id __devinitconst hwicap_of_match[]; | |
| 760 | 762 | static int __devinit hwicap_drv_probe(struct platform_device *pdev) |
| 761 | 763 | { |
| 764 | + const struct of_device_id *match; | |
| 762 | 765 | struct resource *res; |
| 763 | 766 | const struct config_registers *regs; |
| 764 | 767 | const char *family; |
| 765 | 768 | |
| 766 | − if (pdev->dev.of_match) | |
| 767 | − return hwicap_of_probe(pdev); | |
| 769 | + match = of_match_device(hwicap_of_match, &pdev->dev); | |
| 770 | + if (match) | |
| 771 | + return hwicap_of_probe(pdev, match->data); | |
| 768 | 772 | |
| 769 | 773 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 770 | 774 | if (!res) |
| @@ -32,10 +32,9 @@ static DEFINE_MUTEX(clocks_mutex); · 31 unmodified lines | ||
| 32 | 32 | * Then we take the most specific entry - with the following |
| 33 | 33 | * order of precedence: dev+con > dev only > con only. |
| 34 | 34 | */ |
| 35 | −static struct clk *clk_find(const char *dev_id, const char *con_id) | |
| 35 | +static struct clk_lookup *clk_find(const char *dev_id, const char *con_id) | |
| 36 | 36 | { |
| 37 | − struct clk_lookup *p; | |
| 38 | − struct clk *clk = NULL; | |
| 37 | + struct clk_lookup *p, *cl = NULL; | |
| 39 | 38 | int match, best = 0; |
| 40 | 39 | |
| 41 | 40 | list_for_each_entry(p, &clocks, node) { |
| @@ -52,27 +51,27 @@ static struct clk *clk_find(const char *dev_id, const char *con_id) · 10 unmodified lines | ||
| 52 | 51 | } |
| 53 | 52 | |
| 54 | 53 | if (match > best) { |
| 55 | − clk = p->clk; | |
| 54 | + cl = p; | |
| 56 | 55 | if (match != 3) |
| 57 | 56 | best = match; |
| 58 | 57 | else |
| 59 | 58 | break; |
| 60 | 59 | } |
| 61 | 60 | } |
| 62 | − return clk; | |
| 61 | + return cl; | |
| 63 | 62 | } |
| 64 | 63 | |
| 65 | 64 | struct clk *clk_get_sys(const char *dev_id, const char *con_id) |
| 66 | 65 | { |
| 67 | − struct clk *clk; | |
| 66 | + struct clk_lookup *cl; | |
| 68 | 67 | |
| 69 | 68 | mutex_lock(&clocks_mutex); |
| 70 | − clk = clk_find(dev_id, con_id); | |
| 71 | − if (clk && !__clk_get(clk)) | |
| 72 | − clk = NULL; | |
| 69 | + cl = clk_find(dev_id, con_id); | |
| 70 | + if (cl && !__clk_get(cl->clk)) | |
| 71 | + cl = NULL; | |
| 73 | 72 | mutex_unlock(&clocks_mutex); |
| 74 | 73 | |
| 75 | − return clk ? clk : ERR_PTR(-ENOENT); | |
| 74 | + return cl ? cl->clk : ERR_PTR(-ENOENT); | |
| 76 | 75 | } |
| 77 | 76 | EXPORT_SYMBOL(clk_get_sys); |
| 78 | 77 | |
| @@ -142,6 +142,7 @@ static int cn_call_callback(struct sk_buff *skb) · 141 unmodified lines | ||
| 142 | 142 | cbq->callback(msg, nsp); |
| 143 | 143 | kfree_skb(skb); |
| 144 | 144 | cn_queue_release_callback(cbq); |
| 145 | + err = 0; | |
| 145 | 146 | } |
| 146 | 147 | |
| 147 | 148 | return err; |
| @@ -211,8 +211,6 @@ static int amd64_get_scrub_rate(struct mem_ctl_info *mci) · 210 unmodified lines | ||
| 211 | 211 | |
| 212 | 212 | scrubval = scrubval & 0x001F; |
| 213 | 213 | |
| 214 | − amd64_debug("pci-read, sdram scrub control value: %d\n", scrubval); | |
| 215 | − | |
| 216 | 214 | for (i = 0; i < ARRAY_SIZE(scrubrates); i++) { |
| 217 | 215 | if (scrubrates[i].scrubval == scrubval) { |
| 218 | 216 | retval = scrubrates[i].bandwidth; |
| @@ -933,25 +931,74 @@ static int k8_early_channel_count(struct amd64_pvt *pvt) · 714 unmodified lines | ||
| 933 | 931 | /* On F10h and later ErrAddr is MC4_ADDR[47:1] */ |
| 934 | 932 | static u64 get_error_address(struct mce *m) |
| 935 | 933 | { |
| 934 | + struct cpuinfo_x86 *c = &boot_cpu_data; | |
| 935 | + u64 addr; | |
| 936 | 936 | u8 start_bit = 1; |
| 937 | 937 | u8 end_bit = 47; |
| 938 | 938 | |
| 939 | − if (boot_cpu_data.x86 == 0xf) { | |
| 939 | + if (c->x86 == 0xf) { | |
| 940 | 940 | start_bit = 3; |
| 941 | 941 | end_bit = 39; |
| 942 | 942 | } |
| 943 | 943 | |
| 944 | − return m->addr & GENMASK(start_bit, end_bit); | |
| 944 | + addr = m->addr & GENMASK(start_bit, end_bit); | |
| 945 | + | |
| 946 | + /* | |
| 947 | + * Erratum 637 workaround | |
| 948 | + */ | |
| 949 | + if (c->x86 == 0x15) { | |
| 950 | + struct amd64_pvt *pvt; | |
| 951 | + u64 cc6_base, tmp_addr; | |
| 952 | + u32 tmp; | |
| 953 | + u8 mce_nid, intlv_en; | |
| 954 | + | |
| 955 | + if ((addr & GENMASK(24, 47)) >> 24 != 0x00fdf7) | |
| 956 | + return addr; | |
| 957 | + | |
| 958 | + mce_nid = amd_get_nb_id(m->extcpu); | |
| 959 | + pvt = mcis[mce_nid]->pvt_info; | |
| 960 | + | |
| 961 | + amd64_read_pci_cfg(pvt->F1, DRAM_LOCAL_NODE_LIM, &tmp); | |
| 962 | + intlv_en = tmp >> 21 & 0x7; | |
| 963 | + | |
| 964 | + /* add [47:27] + 3 trailing bits */ | |
| 965 | + cc6_base = (tmp & GENMASK(0, 20)) << 3; | |
| 966 | + | |
| 967 | + /* reverse and add DramIntlvEn */ | |
| 968 | + cc6_base |= intlv_en ^ 0x7; | |
| 969 | + | |
| 970 | + /* pin at [47:24] */ | |
| 971 | + cc6_base <<= 24; | |
| 972 | + | |
| 973 | + if (!intlv_en) | |
| 974 | + return cc6_base | (addr & GENMASK(0, 23)); | |
| 975 | + | |
| 976 | + amd64_read_pci_cfg(pvt->F1, DRAM_LOCAL_NODE_BASE, &tmp); | |
| 977 | + | |
| 978 | + /* faster log2 */ | |
| 979 | + tmp_addr = (addr & GENMASK(12, 23)) << __fls(intlv_en + 1); | |
| 980 | + | |
| 981 | + /* OR DramIntlvSel into bits [14:12] */ | |
| 982 | + tmp_addr |= (tmp & GENMASK(21, 23)) >> 9; | |
| 983 | + | |
| 984 | + /* add remaining [11:0] bits from original MC4_ADDR */ | |
| 985 | + tmp_addr |= addr & GENMASK(0, 11); | |
| 986 | + | |
| 987 | + return cc6_base | tmp_addr; | |
| 988 | + } | |
| 989 | + | |
| 990 | + return addr; | |
| 945 | 991 | } |
| 946 | 992 | |
| 947 | 993 | static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range) |
| 948 | 994 | { |
| 995 | + struct cpuinfo_x86 *c = &boot_cpu_data; | |
| 949 | 996 | int off = range << 3; |
| 950 | 997 | |
| 951 | 998 | amd64_read_pci_cfg(pvt->F1, DRAM_BASE_LO + off, &pvt->ranges[range].base.lo); |
| 952 | 999 | amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_LO + off, &pvt->ranges[range].lim.lo); |
| 953 | 1000 | |
| 954 | − if (boot_cpu_data.x86 == 0xf) | |
| 1001 | + if (c->x86 == 0xf) | |
| 955 | 1002 | return; |
| 956 | 1003 | |
| 957 | 1004 | if (!dram_rw(pvt, range)) |
| @@ -959,6 +1006,31 @@ static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range) · 1 unmodified line | ||
| 959 | 1006 | |
| 960 | 1007 | amd64_read_pci_cfg(pvt->F1, DRAM_BASE_HI + off, &pvt->ranges[range].base.hi); |
| 961 | 1008 | amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_HI + off, &pvt->ranges[range].lim.hi); |
| 1009 | + | |
| 1010 | + /* Factor in CC6 save area by reading dst node's limit reg */ | |
| 1011 | + if (c->x86 == 0x15) { | |
| 1012 | + struct pci_dev *f1 = NULL; | |
| 1013 | + u8 nid = dram_dst_node(pvt, range); | |
| 1014 | + u32 llim; | |
| 1015 | + | |
| 1016 | + f1 = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0x18 + nid, 1)); | |
| 1017 | + if (WARN_ON(!f1)) | |
| 1018 | + return; | |
| 1019 | + | |
| 1020 | + amd64_read_pci_cfg(f1, DRAM_LOCAL_NODE_LIM, &llim); | |
| 1021 | + | |
| 1022 | + pvt->ranges[range].lim.lo &= GENMASK(0, 15); | |
| 1023 | + | |
| 1024 | + /* {[39:27],111b} */ | |
| 1025 | + pvt->ranges[range].lim.lo |= ((llim & 0x1fff) << 3 | 0x7) << 16; | |
| 1026 | + | |
| 1027 | + pvt->ranges[range].lim.hi &= GENMASK(0, 7); | |
| 1028 | + | |
| 1029 | + /* [47:40] */ | |
| 1030 | + pvt->ranges[range].lim.hi |= llim >> 13; | |
| 1031 | + | |
| 1032 | + pci_dev_put(f1); | |
| 1033 | + } | |
| 962 | 1034 | } |
| 963 | 1035 | |
| 964 | 1036 | static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr, |
| @@ -1403,12 +1475,8 @@ static int f1x_match_to_this_node(struct amd64_pvt *pvt, unsigned range, · 438 unmodified lines | ||
| 1403 | 1475 | return -EINVAL; |
| 1404 | 1476 | } |
| 1405 | 1477 | |
| 1406 | − if (intlv_en && | |
| 1407 | − (intlv_sel != ((sys_addr >> 12) & intlv_en))) { | |
| 1408 | − amd64_warn("Botched intlv bits, en: 0x%x, sel: 0x%x\n", | |
| 1409 | − intlv_en, intlv_sel); | |
| 1478 | + if (intlv_en && (intlv_sel != ((sys_addr >> 12) & intlv_en))) | |
| 1410 | 1479 | return -EINVAL; |
| 1411 | − } | |
| 1412 | 1480 | |
| 1413 | 1481 | sys_addr = f1x_swap_interleaved_region(pvt, sys_addr); |
| 1414 | 1482 | |
| @@ -196,6 +196,9 @@ · 195 unmodified lines | ||
| 196 | 196 | |
| 197 | 197 | #define DCT_CFG_SEL 0x10C |
| 198 | 198 | |
| 199 | +#define DRAM_LOCAL_NODE_BASE 0x120 | |
| 200 | +#define DRAM_LOCAL_NODE_LIM 0x124 | |
| 201 | + | |
| 199 | 202 | #define DRAM_BASE_HI 0x140 |
| 200 | 203 | #define DRAM_LIMIT_HI 0x144 |
| 201 | 204 | |
| @@ -458,13 +458,13 @@ static ssize_t mci_sdram_scrub_rate_store(struct mem_ctl_info *mci, · 457 unmodified lines | ||
| 458 | 458 | return -EINVAL; |
| 459 | 459 | |
| 460 | 460 | new_bw = mci->set_sdram_scrub_rate(mci, bandwidth); |
| 461 | − if (new_bw >= 0) { | |
| 462 | − edac_printk(KERN_DEBUG, EDAC_MC, "Scrub rate set to %d\n", new_bw); | |
| 463 | − return count; | |
| 461 | + if (new_bw < 0) { | |
| 462 | + edac_printk(KERN_WARNING, EDAC_MC, | |
| 463 | + "Error setting scrub rate to: %lu\n", bandwidth); | |
| 464 | + return -EINVAL; | |
| 464 | 465 | } |
| 465 | 466 | |
| 466 | − edac_printk(KERN_DEBUG, EDAC_MC, "Error setting scrub rate to: %lu\n", bandwidth); | |
| 467 | − return -EINVAL; | |
| 467 | + return count; | |
| 468 | 468 | } |
| 469 | 469 | |
| 470 | 470 | /* |
| @@ -483,7 +483,6 @@ static ssize_t mci_sdram_scrub_rate_show(struct mem_ctl_info *mci, char *data) · 12 unmodified lines | ||
| 483 | 483 | return bandwidth; |
| 484 | 484 | } |
| 485 | 485 | |
| 486 | − edac_printk(KERN_DEBUG, EDAC_MC, "Read scrub rate: %d\n", bandwidth); | |
| 487 | 486 | return sprintf(data, "%d\n", bandwidth); |
| 488 | 487 | } |
| 489 | 488 | |
| @@ -1019,7 +1019,7 @@ ppc4xx_edac_mc_init(struct mem_ctl_info *mci, · 1018 unmodified lines | ||
| 1019 | 1019 | struct ppc4xx_edac_pdata *pdata = NULL; |
| 1020 | 1020 | const struct device_node *np = op->dev.of_node; |
| 1021 | 1021 | |
| 1022 | − if (op->dev.of_match == NULL) | |
| 1022 | + if (of_match_device(ppc4xx_edac_match, &op->dev) == NULL) | |
| 1023 | 1023 | return -EINVAL; |
| 1024 | 1024 | |
| 1025 | 1025 | /* Initial driver pointers and private data */ |
| @@ -2199,7 +2199,6 @@ static int ohci_set_config_rom(struct fw_card *card, · 2198 unmodified lines | ||
| 2199 | 2199 | { |
| 2200 | 2200 | struct fw_ohci *ohci; |
| 2201 | 2201 | unsigned long flags; |
| 2202 | − int ret = -EBUSY; | |
| 2203 | 2202 | __be32 *next_config_rom; |
| 2204 | 2203 | dma_addr_t uninitialized_var(next_config_rom_bus); |
| 2205 | 2204 | |
| @@ -2240,22 +2239,37 @@ static int ohci_set_config_rom(struct fw_card *card, · 34 unmodified lines | ||
| 2240 | 2239 | |
| 2241 | 2240 | spin_lock_irqsave(&ohci->lock, flags); |
| 2242 | 2241 | |
| 2242 | + /* | |
| 2243 | + * If there is not an already pending config_rom update, | |
| 2244 | + * push our new allocation into the ohci->next_config_rom | |
| 2245 | + * and then mark the local variable as null so that we | |
| 2246 | + * won't deallocate the new buffer. | |
| 2247 | + * | |
| 2248 | + * OTOH, if there is a pending config_rom update, just | |
| 2249 | + * use that buffer with the new config_rom data, and | |
| 2250 | + * let this routine free the unused DMA allocation. | |
| 2251 | + */ | |
| 2252 | + | |
| 2243 | 2253 | if (ohci->next_config_rom == NULL) { |
| 2244 | 2254 | ohci->next_config_rom = next_config_rom; |
| 2245 | 2255 | ohci->next_config_rom_bus = next_config_rom_bus; |
| 2256 | + next_config_rom = NULL; | |
| 2257 | + } | |
| 2246 | 2258 | |
| 2247 | − copy_config_rom(ohci->next_config_rom, config_rom, length); | |
| 2259 | + copy_config_rom(ohci->next_config_rom, config_rom, length); | |
| 2248 | 2260 | |
| 2249 | − ohci->next_header = config_rom[0]; | |
| 2250 | − ohci->next_config_rom[0] = 0; | |
| 2261 | + ohci->next_header = config_rom[0]; | |
| 2262 | + ohci->next_config_rom[0] = 0; | |
| 2251 | 2263 | |
| 2252 | − reg_write(ohci, OHCI1394_ConfigROMmap, | |
| 2253 | − ohci->next_config_rom_bus); | |
| 2254 | − ret = 0; | |
| 2255 | − } | |
| 2264 | + reg_write(ohci, OHCI1394_ConfigROMmap, ohci->next_config_rom_bus); | |
| 2256 | 2265 | |
| 2257 | 2266 | spin_unlock_irqrestore(&ohci->lock, flags); |
| 2258 | 2267 | |
| 2268 | + /* If we didn't use the DMA allocation, delete it. */ | |
| 2269 | + if (next_config_rom != NULL) | |
| 2270 | + dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, | |
| 2271 | + next_config_rom, next_config_rom_bus); | |
| 2272 | + | |
| 2259 | 2273 | /* |
| 2260 | 2274 | * Now initiate a bus reset to have the changes take |
| 2261 | 2275 | * effect. We clean up the old config rom memory and DMA |
| @@ -2263,13 +2277,10 @@ static int ohci_set_config_rom(struct fw_card *card, · 1 unmodified line | ||
| 2263 | 2277 | * controller could need to access it before the bus reset |
| 2264 | 2278 | * takes effect. |
| 2265 | 2279 | */ |
| 2266 | − if (ret == 0) | |
| 2267 | − fw_schedule_bus_reset(&ohci->card, true, true); | |
| 2268 | − else | |
| 2269 | − dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, | |
| 2270 | − next_config_rom, next_config_rom_bus); | |
| 2271 | 2280 | |
| 2272 | − return ret; | |
| 2281 | + fw_schedule_bus_reset(&ohci->card, true, true); | |
| 2282 | + | |
| 2283 | + return 0; | |
| 2273 | 2284 | } |
| 2274 | 2285 | |
| 2275 | 2286 | static void ohci_send_request(struct fw_card *card, struct fw_packet *packet) |
| @@ -24,6 +24,7 @@ config DRM_KMS_HELPER · 23 unmodified lines | ||
| 24 | 24 | depends on DRM |
| 25 | 25 | select FB |
| 26 | 26 | select FRAMEBUFFER_CONSOLE if !EXPERT |
| 27 | + select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE | |
| 27 | 28 | help |
| 28 | 29 | FB and CRTC helpers for KMS drivers. |
| 29 | 30 | |
| @@ -342,9 +342,22 @@ int drm_fb_helper_debug_leave(struct fb_info *info) · 341 unmodified lines | ||
| 342 | 342 | } |
| 343 | 343 | EXPORT_SYMBOL(drm_fb_helper_debug_leave); |
| 344 | 344 | |
| 345 | +bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper) | |
| 346 | +{ | |
| 347 | + bool error = false; | |
| 348 | + int i, ret; | |
| 349 | + for (i = 0; i < fb_helper->crtc_count; i++) { | |
| 350 | + struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; | |
| 351 | + ret = drm_crtc_helper_set_config(mode_set); | |
| 352 | + if (ret) | |
| 353 | + error = true; | |
| 354 | + } | |
| 355 | + return error; | |
| 356 | +} | |
| 357 | +EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode); | |
| 358 | + | |
| 345 | 359 | bool drm_fb_helper_force_kernel_mode(void) |
| 346 | 360 | { |
| 347 | − int i = 0; | |
| 348 | 361 | bool ret, error = false; |
| 349 | 362 | struct drm_fb_helper *helper; |
| 350 | 363 | |
| @@ -352,12 +365,12 @@ bool drm_fb_helper_force_kernel_mode(void) · 1 unmodified line | ||
| 352 | 365 | return false; |
| 353 | 366 | |
| 354 | 367 | list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) { |
| 355 | − for (i = 0; i < helper->crtc_count; i++) { | |
| 356 | − struct drm_mode_set *mode_set = &helper->crtc_info[i].mode_set; | |
| 357 | − ret = drm_crtc_helper_set_config(mode_set); | |
| 358 | − if (ret) | |
| 359 | − error = true; | |
| 360 | − } | |
| 368 | + if (helper->dev->switch_power_state == DRM_SWITCH_POWER_OFF) | |
| 369 | + continue; | |
| 370 | + | |
| 371 | + ret = drm_fb_helper_restore_fbdev_mode(helper); | |
| 372 | + if (ret) | |
| 373 | + error = true; | |
| 361 | 374 | } |
| 362 | 375 | return error; |
| 363 | 376 | } |
| @@ -1503,17 +1516,33 @@ bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel) · 1139 unmodified lines | ||
| 1503 | 1516 | } |
| 1504 | 1517 | EXPORT_SYMBOL(drm_fb_helper_initial_config); |
| 1505 | 1518 | |
| 1506 | −bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) | |
| 1519 | +/** | |
| 1520 | + * drm_fb_helper_hotplug_event - respond to a hotplug notification by | |
| 1521 | + * probing all the outputs attached to the fb. | |
| 1522 | + * @fb_helper: the drm_fb_helper | |
| 1523 | + * | |
| 1524 | + * LOCKING: | |
| 1525 | + * Called at runtime, must take mode config lock. | |
| 1526 | + * | |
| 1527 | + * Scan the connectors attached to the fb_helper and try to put together a | |
| 1528 | + * setup after *notification of a change in output configuration. | |
| 1529 | + * | |
| 1530 | + * RETURNS: | |
| 1531 | + * 0 on success and a non-zero error code otherwise. | |
| 1532 | + */ | |
| 1533 | +int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) | |
| 1507 | 1534 | { |
| 1535 | + struct drm_device *dev = fb_helper->dev; | |
| 1508 | 1536 | int count = 0; |
| 1509 | 1537 | u32 max_width, max_height, bpp_sel; |
| 1510 | 1538 | bool bound = false, crtcs_bound = false; |
| 1511 | 1539 | struct drm_crtc *crtc; |
| 1512 | 1540 | |
| 1513 | 1541 | if (!fb_helper->fb) |
| 1514 | − return false; | |
| 1542 | + return 0; | |
| 1515 | 1543 | |
| 1516 | − list_for_each_entry(crtc, &fb_helper->dev->mode_config.crtc_list, head) { | |
| 1544 | + mutex_lock(&dev->mode_config.mutex); | |
| 1545 | + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | |
| 1517 | 1546 | if (crtc->fb) |
| 1518 | 1547 | crtcs_bound = true; |
| 1519 | 1548 | if (crtc->fb == fb_helper->fb) |
| @@ -1522,7 +1551,8 @@ bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) · 2 unmodified lines | ||
| 1522 | 1551 | |
| 1523 | 1552 | if (!bound && crtcs_bound) { |
| 1524 | 1553 | fb_helper->delayed_hotplug = true; |
| 1525 | − return false; | |
| 1554 | + mutex_unlock(&dev->mode_config.mutex); | |
| 1555 | + return 0; | |
| 1526 | 1556 | } |
| 1527 | 1557 | DRM_DEBUG_KMS("\n"); |
| 1528 | 1558 | |
| @@ -1533,6 +1563,7 @@ bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) · 4 unmodified lines | ||
| 1533 | 1563 | count = drm_fb_helper_probe_connector_modes(fb_helper, max_width, |
| 1534 | 1564 | max_height); |
| 1535 | 1565 | drm_setup_crtcs(fb_helper); |
| 1566 | + mutex_unlock(&dev->mode_config.mutex); | |
| 1536 | 1567 | |
| 1537 | 1568 | return drm_fb_helper_single_fb_probe(fb_helper, bpp_sel); |
| 1538 | 1569 | } |
| @@ -932,11 +932,34 @@ EXPORT_SYMBOL(drm_vblank_put); · 931 unmodified lines | ||
| 932 | 932 | |
| 933 | 933 | void drm_vblank_off(struct drm_device *dev, int crtc) |
| 934 | 934 | { |
| 935 | + struct drm_pending_vblank_event *e, *t; | |
| 936 | + struct timeval now; | |
| 935 | 937 | unsigned long irqflags; |
| 938 | + unsigned int seq; | |
| 936 | 939 | |
| 937 | 940 | spin_lock_irqsave(&dev->vbl_lock, irqflags); |
| 938 | 941 | vblank_disable_and_save(dev, crtc); |
| 939 | 942 | DRM_WAKEUP(&dev->vbl_queue[crtc]); |
| 943 | + | |
| 944 | + /* Send any queued vblank events, lest the natives grow disquiet */ | |
| 945 | + seq = drm_vblank_count_and_time(dev, crtc, &now); | |
| 946 | + list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { | |
| 947 | + if (e->pipe != crtc) | |
| 948 | + continue; | |
| 949 | + DRM_DEBUG("Sending premature vblank event on disable: \ | |
| 950 | + wanted %d, current %d\n", | |
| 951 | + e->event.sequence, seq); | |
| 952 | + | |
| 953 | + e->event.sequence = seq; | |
| 954 | + e->event.tv_sec = now.tv_sec; | |
| 955 | + e->event.tv_usec = now.tv_usec; | |
| 956 | + drm_vblank_put(dev, e->pipe); | |
| 957 | + list_move_tail(&e->base.link, &e->base.file_priv->event_list); | |
| 958 | + wake_up_interruptible(&e->base.file_priv->event_wait); | |
| 959 | + trace_drm_vblank_event_delivered(e->base.pid, e->pipe, | |
| 960 | + e->event.sequence); | |
| 961 | + } | |
| 962 | + | |
| 940 | 963 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); |
| 941 | 964 | } |
| 942 | 965 | EXPORT_SYMBOL(drm_vblank_off); |
| @@ -431,7 +431,7 @@ EXPORT_SYMBOL(drm_mm_search_free_in_range); · 430 unmodified lines | ||
| 431 | 431 | void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new) |
| 432 | 432 | { |
| 433 | 433 | list_replace(&old->node_list, &new->node_list); |
| 434 | − list_replace(&old->node_list, &new->hole_stack); | |
| 434 | + list_replace(&old->hole_stack, &new->hole_stack); | |
| 435 | 435 | new->hole_follows = old->hole_follows; |
| 436 | 436 | new->mm = old->mm; |
| 437 | 437 | new->start = old->start; |
| @@ -699,8 +699,8 @@ int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm) · 261 unmodified lines | ||
| 699 | 699 | entry->size); |
| 700 | 700 | total_used += entry->size; |
| 701 | 701 | if (entry->hole_follows) { |
| 702 | − hole_start = drm_mm_hole_node_start(&mm->head_node); | |
| 703 | − hole_end = drm_mm_hole_node_end(&mm->head_node); | |
| 702 | + hole_start = drm_mm_hole_node_start(entry); | |
| 703 | + hole_end = drm_mm_hole_node_end(entry); | |
| 704 | 704 | hole_size = hole_end - hole_start; |
| 705 | 705 | seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n", |
| 706 | 706 | hole_start, hole_end, hole_size); |
| @@ -2207,7 +2207,7 @@ void i915_driver_lastclose(struct drm_device * dev) · 2206 unmodified lines | ||
| 2207 | 2207 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 2208 | 2208 | |
| 2209 | 2209 | if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) { |
| 2210 | − drm_fb_helper_restore(); | |
| 2210 | + intel_fb_restore_mode(dev); | |
| 2211 | 2211 | vga_switcheroo_process_delayed_switch(); |
| 2212 | 2212 | return; |
| 2213 | 2213 | } |
| @@ -49,7 +49,7 @@ module_param_named(panel_ignore_lid, i915_panel_ignore_lid, int, 0600); · 48 unmodified lines | ||
| 49 | 49 | unsigned int i915_powersave = 1; |
| 50 | 50 | module_param_named(powersave, i915_powersave, int, 0600); |
| 51 | 51 | |
| 52 | −unsigned int i915_semaphores = 1; | |
| 52 | +unsigned int i915_semaphores = 0; | |
| 53 | 53 | module_param_named(semaphores, i915_semaphores, int, 0600); |
| 54 | 54 | |
| 55 | 55 | unsigned int i915_enable_rc6 = 0; |
| @@ -3771,8 +3771,11 @@ static bool g4x_compute_wm0(struct drm_device *dev, · 3770 unmodified lines | ||
| 3771 | 3771 | int entries, tlb_miss; |
| 3772 | 3772 | |
| 3773 | 3773 | crtc = intel_get_crtc_for_plane(dev, plane); |
| 3774 | − if (crtc->fb == NULL || !crtc->enabled) | |
| 3774 | + if (crtc->fb == NULL || !crtc->enabled) { | |
| 3775 | + *cursor_wm = cursor->guard_size; | |
| 3776 | + *plane_wm = display->guard_size; | |
| 3775 | 3777 | return false; |
| 3778 | + } | |
| 3776 | 3779 | |
| 3777 | 3780 | htotal = crtc->mode.htotal; |
| 3778 | 3781 | hdisplay = crtc->mode.hdisplay; |
| @@ -5602,9 +5605,9 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) · 1823 unmodified lines | ||
| 5602 | 5605 | intel_clock_t clock; |
| 5603 | 5606 | |
| 5604 | 5607 | if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) |
| 5605 | − fp = FP0(pipe); | |
| 5608 | + fp = I915_READ(FP0(pipe)); | |
| 5606 | 5609 | else |
| 5607 | − fp = FP1(pipe); | |
| 5610 | + fp = I915_READ(FP1(pipe)); | |
| 5608 | 5611 | |
| 5609 | 5612 | clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT; |
| 5610 | 5613 | if (IS_PINEVIEW(dev)) { |
| @@ -6215,36 +6218,6 @@ cleanup_work: · 604 unmodified lines | ||
| 6215 | 6218 | return ret; |
| 6216 | 6219 | } |
| 6217 | 6220 | |
| 6218 | −static void intel_crtc_reset(struct drm_crtc *crtc) | |
| 6219 | −{ | |
| 6220 | − struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | |
| 6221 | − | |
| 6222 | − /* Reset flags back to the 'unknown' status so that they | |
| 6223 | − * will be correctly set on the initial modeset. | |
| 6224 | − */ | |
| 6225 | − intel_crtc->dpms_mode = -1; | |
| 6226 | −} | |
| 6227 | − | |
| 6228 | −static struct drm_crtc_helper_funcs intel_helper_funcs = { | |
| 6229 | − .dpms = intel_crtc_dpms, | |
| 6230 | − .mode_fixup = intel_crtc_mode_fixup, | |
| 6231 | − .mode_set = intel_crtc_mode_set, | |
| 6232 | − .mode_set_base = intel_pipe_set_base, | |
| 6233 | − .mode_set_base_atomic = intel_pipe_set_base_atomic, | |
| 6234 | − .load_lut = intel_crtc_load_lut, | |
| 6235 | − .disable = intel_crtc_disable, | |
| 6236 | −}; | |
| 6237 | − | |
| 6238 | −static const struct drm_crtc_funcs intel_crtc_funcs = { | |
| 6239 | − .reset = intel_crtc_reset, | |
| 6240 | − .cursor_set = intel_crtc_cursor_set, | |
| 6241 | − .cursor_move = intel_crtc_cursor_move, | |
| 6242 | − .gamma_set = intel_crtc_gamma_set, | |
| 6243 | − .set_config = drm_crtc_helper_set_config, | |
| 6244 | − .destroy = intel_crtc_destroy, | |
| 6245 | − .page_flip = intel_crtc_page_flip, | |
| 6246 | −}; | |
| 6247 | − | |
| 6248 | 6221 | static void intel_sanitize_modesetting(struct drm_device *dev, |
| 6249 | 6222 | int pipe, int plane) |
| 6250 | 6223 | { |
| @@ -6281,6 +6254,42 @@ static void intel_sanitize_modesetting(struct drm_device *dev, · 30 unmodified lines | ||
| 6281 | 6254 | intel_disable_pipe(dev_priv, pipe); |
| 6282 | 6255 | } |
| 6283 | 6256 | |
| 6257 | +static void intel_crtc_reset(struct drm_crtc *crtc) | |
| 6258 | +{ | |
| 6259 | + struct drm_device *dev = crtc->dev; | |
| 6260 | + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | |
| 6261 | + | |
| 6262 | + /* Reset flags back to the 'unknown' status so that they | |
| 6263 | + * will be correctly set on the initial modeset. | |
| 6264 | + */ | |
| 6265 | + intel_crtc->dpms_mode = -1; | |
| 6266 | + | |
| 6267 | + /* We need to fix up any BIOS configuration that conflicts with | |
| 6268 | + * our expectations. | |
| 6269 | + */ | |
| 6270 | + intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane); | |
| 6271 | +} | |
| 6272 | + | |
| 6273 | +static struct drm_crtc_helper_funcs intel_helper_funcs = { | |
| 6274 | + .dpms = intel_crtc_dpms, | |
| 6275 | + .mode_fixup = intel_crtc_mode_fixup, | |
| 6276 | + .mode_set = intel_crtc_mode_set, | |
| 6277 | + .mode_set_base = intel_pipe_set_base, | |
| 6278 | + .mode_set_base_atomic = intel_pipe_set_base_atomic, | |
| 6279 | + .load_lut = intel_crtc_load_lut, | |
| 6280 | + .disable = intel_crtc_disable, | |
| 6281 | +}; | |
| 6282 | + | |
| 6283 | +static const struct drm_crtc_funcs intel_crtc_funcs = { | |
| 6284 | + .reset = intel_crtc_reset, | |
| 6285 | + .cursor_set = intel_crtc_cursor_set, | |
| 6286 | + .cursor_move = intel_crtc_cursor_move, | |
| 6287 | + .gamma_set = intel_crtc_gamma_set, | |
| 6288 | + .set_config = drm_crtc_helper_set_config, | |
| 6289 | + .destroy = intel_crtc_destroy, | |
| 6290 | + .page_flip = intel_crtc_page_flip, | |
| 6291 | +}; | |
| 6292 | + | |
| 6284 | 6293 | static void intel_crtc_init(struct drm_device *dev, int pipe) |
| 6285 | 6294 | { |
| 6286 | 6295 | drm_i915_private_t *dev_priv = dev->dev_private; |
| @@ -6330,8 +6339,6 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) · 43 unmodified lines | ||
| 6330 | 6339 | |
| 6331 | 6340 | setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, |
| 6332 | 6341 | (unsigned long)intel_crtc); |
| 6333 | − | |
| 6334 | − intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane); | |
| 6335 | 6342 | } |
| 6336 | 6343 | |
| 6337 | 6344 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
| @@ -6572,8 +6579,10 @@ intel_user_framebuffer_create(struct drm_device *dev, · 234 unmodified lines | ||
| 6572 | 6579 | return ERR_PTR(-ENOENT); |
| 6573 | 6580 | |
| 6574 | 6581 | intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); |
| 6575 | − if (!intel_fb) | |
| 6582 | + if (!intel_fb) { | |
| 6583 | + drm_gem_object_unreference_unlocked(&obj->base); | |
| 6576 | 6584 | return ERR_PTR(-ENOMEM); |
| 6585 | + } | |
| 6577 | 6586 | |
| 6578 | 6587 | ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj); |
| 6579 | 6588 | if (ret) { |
| @@ -1470,7 +1470,8 @@ intel_dp_link_down(struct intel_dp *intel_dp) · 1469 unmodified lines | ||
| 1470 | 1470 | |
| 1471 | 1471 | if (!HAS_PCH_CPT(dev) && |
| 1472 | 1472 | I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { |
| 1473 | − struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc); | |
| 1473 | + struct drm_crtc *crtc = intel_dp->base.base.crtc; | |
| 1474 | + | |
| 1474 | 1475 | /* Hardware workaround: leaving our transcoder select |
| 1475 | 1476 | * set to transcoder B while it's off will prevent the |
| 1476 | 1477 | * corresponding HDMI output on transcoder A. |
| @@ -1485,7 +1486,19 @@ intel_dp_link_down(struct intel_dp *intel_dp) · 8 unmodified lines | ||
| 1485 | 1486 | /* Changes to enable or select take place the vblank |
| 1486 | 1487 | * after being written. |
| 1487 | 1488 | */ |
| 1488 | − intel_wait_for_vblank(dev, intel_crtc->pipe); | |
| 1489 | + if (crtc == NULL) { | |
| 1490 | + /* We can arrive here never having been attached | |
| 1491 | + * to a CRTC, for instance, due to inheriting | |
| 1492 | + * random state from the BIOS. | |
| 1493 | + * | |
| 1494 | + * If the pipe is not running, play safe and | |
| 1495 | + * wait for the clocks to stabilise before | |
| 1496 | + * continuing. | |
| 1497 | + */ | |
| 1498 | + POSTING_READ(intel_dp->output_reg); | |
| 1499 | + msleep(50); | |
| 1500 | + } else | |
| 1501 | + intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe); | |
| 1489 | 1502 | } |
| 1490 | 1503 | |
| 1491 | 1504 | I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); |
| @@ -338,4 +338,5 @@ extern int intel_overlay_attrs(struct drm_device *dev, void *data, · 337 unmodified lines | ||
| 338 | 338 | struct drm_file *file_priv); |
| 339 | 339 | |
| 340 | 340 | extern void intel_fb_output_poll_changed(struct drm_device *dev); |
| 341 | +extern void intel_fb_restore_mode(struct drm_device *dev); | |
| 341 | 342 | #endif /* __INTEL_DRV_H__ */ |
| @@ -264,3 +264,13 @@ void intel_fb_output_poll_changed(struct drm_device *dev) · 263 unmodified lines | ||
| 264 | 264 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 265 | 265 | drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper); |
| 266 | 266 | } |
| 267 | + | |
| 268 | +void intel_fb_restore_mode(struct drm_device *dev) | |
| 269 | +{ | |
| 270 | + int ret; | |
| 271 | + drm_i915_private_t *dev_priv = dev->dev_private; | |
| 272 | + | |
| 273 | + ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper); | |
| 274 | + if (ret) | |
| 275 | + DRM_DEBUG("failed to restore crtc mode\n"); | |
| 276 | +} | |
| @@ -539,6 +539,9 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, · 538 unmodified lines | ||
| 539 | 539 | struct drm_device *dev = dev_priv->dev; |
| 540 | 540 | struct drm_connector *connector = dev_priv->int_lvds_connector; |
| 541 | 541 | |
| 542 | + if (dev->switch_power_state != DRM_SWITCH_POWER_ON) | |
| 543 | + return NOTIFY_OK; | |
| 544 | + | |
| 542 | 545 | /* |
| 543 | 546 | * check and update the status of LVDS connector after receiving |
| 544 | 547 | * the LID nofication event. |
| @@ -1151,10 +1151,10 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, · 1150 unmodified lines | ||
| 1151 | 1151 | (video_levels->blank << TV_BLANK_LEVEL_SHIFT))); |
| 1152 | 1152 | { |
| 1153 | 1153 | int pipeconf_reg = PIPECONF(pipe); |
| 1154 | − int dspcntr_reg = DSPCNTR(pipe); | |
| 1154 | + int dspcntr_reg = DSPCNTR(intel_crtc->plane); | |
| 1155 | 1155 | int pipeconf = I915_READ(pipeconf_reg); |
| 1156 | 1156 | int dspcntr = I915_READ(dspcntr_reg); |
| 1157 | − int dspbase_reg = DSPADDR(pipe); | |
| 1157 | + int dspbase_reg = DSPADDR(intel_crtc->plane); | |
| 1158 | 1158 | int xpos = 0x0, ypos = 0x0; |
| 1159 | 1159 | unsigned int xsize, ysize; |
| 1160 | 1160 | /* Pipe must be off here */ |
| @@ -1378,7 +1378,9 @@ intel_tv_detect(struct drm_connector *connector, bool force) · 217 unmodified lines | ||
| 1378 | 1378 | if (type < 0) |
| 1379 | 1379 | return connector_status_disconnected; |
| 1380 | 1380 | |
| 1381 | + intel_tv->type = type; | |
| 1381 | 1382 | intel_tv_find_better_format(connector); |
| 1383 | + | |
| 1382 | 1384 | return connector_status_connected; |
| 1383 | 1385 | } |
| 1384 | 1386 | |
| @@ -1670,8 +1672,7 @@ intel_tv_init(struct drm_device *dev) · 285 unmodified lines | ||
| 1670 | 1672 | * |
| 1671 | 1673 | * More recent chipsets favour HDMI rather than integrated S-Video. |
| 1672 | 1674 | */ |
| 1673 | − connector->polled = | |
| 1674 | − DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; | |
| 1675 | + connector->polled = DRM_CONNECTOR_POLL_CONNECT; | |
| 1675 | 1676 | |
| 1676 | 1677 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, |
| 1677 | 1678 | DRM_MODE_CONNECTOR_SVIDEO); |
| @@ -83,7 +83,7 @@ nouveau_dma_init(struct nouveau_channel *chan) · 82 unmodified lines | ||
| 83 | 83 | return ret; |
| 84 | 84 | |
| 85 | 85 | /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */ |
| 86 | − ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfd0, 0x1000, | |
| 86 | + ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfe0, 0x1000, | |
| 87 | 87 | &chan->m2mf_ntfy); |
| 88 | 88 | if (ret) |
| 89 | 89 | return ret; |
| @@ -682,6 +682,9 @@ struct drm_nouveau_private { · 681 unmodified lines | ||
| 682 | 682 | /* For PFIFO and PGRAPH. */ |
| 683 | 683 | spinlock_t context_switch_lock; |
| 684 | 684 | |
| 685 | + /* VM/PRAMIN flush, legacy PRAMIN aperture */ | |
| 686 | + spinlock_t vm_lock; | |
| 687 | + | |
| 685 | 688 | /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */ |
| 686 | 689 | struct nouveau_ramht *ramht; |
| 687 | 690 | struct nouveau_gpuobj *ramfc; |
| @@ -181,13 +181,13 @@ nouveau_fbcon_sync(struct fb_info *info) · 180 unmodified lines | ||
| 181 | 181 | OUT_RING (chan, 0); |
| 182 | 182 | } |
| 183 | 183 | |
| 184 | − nouveau_bo_wr32(chan->notifier_bo, chan->m2mf_ntfy + 3, 0xffffffff); | |
| 184 | + nouveau_bo_wr32(chan->notifier_bo, chan->m2mf_ntfy/4 + 3, 0xffffffff); | |
| 185 | 185 | FIRE_RING(chan); |
| 186 | 186 | mutex_unlock(&chan->mutex); |
| 187 | 187 | |
| 188 | 188 | ret = -EBUSY; |
| 189 | 189 | for (i = 0; i < 100000; i++) { |
| 190 | − if (!nouveau_bo_rd32(chan->notifier_bo, chan->m2mf_ntfy + 3)) { | |
| 190 | + if (!nouveau_bo_rd32(chan->notifier_bo, chan->m2mf_ntfy/4 + 3)) { | |
| 191 | 191 | ret = 0; |
| 192 | 192 | break; |
| 193 | 193 | } |
| @@ -152,8 +152,6 @@ nouveau_mem_vram_fini(struct drm_device *dev) · 151 unmodified lines | ||
| 152 | 152 | { |
| 153 | 153 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 154 | 154 | |
| 155 | − nouveau_bo_ref(NULL, &dev_priv->vga_ram); | |
| 156 | − | |
| 157 | 155 | ttm_bo_device_release(&dev_priv->ttm.bdev); |
| 158 | 156 | |
| 159 | 157 | nouveau_ttm_global_release(dev_priv); |
| @@ -398,7 +396,7 @@ nouveau_mem_vram_init(struct drm_device *dev) · 238 unmodified lines | ||
| 398 | 396 | dma_bits = 40; |
| 399 | 397 | } else |
| 400 | 398 | if (drm_pci_device_is_pcie(dev) && |
| 401 | − dev_priv->chipset != 0x40 && | |
| 399 | + dev_priv->chipset > 0x40 && | |
| 402 | 400 | dev_priv->chipset != 0x45) { |
| 403 | 401 | if (pci_dma_supported(dev->pdev, DMA_BIT_MASK(39))) |
| 404 | 402 | dma_bits = 39; |
| @@ -35,19 +35,22 @@ nouveau_notifier_init_channel(struct nouveau_channel *chan) · 34 unmodified lines | ||
| 35 | 35 | { |
| 36 | 36 | struct drm_device *dev = chan->dev; |
| 37 | 37 | struct nouveau_bo *ntfy = NULL; |
| 38 | − uint32_t flags; | |
| 38 | + uint32_t flags, ttmpl; | |
| 39 | 39 | int ret; |
| 40 | 40 | |
| 41 | − if (nouveau_vram_notify) | |
| 41 | + if (nouveau_vram_notify) { | |
| 42 | 42 | flags = NOUVEAU_GEM_DOMAIN_VRAM; |
| 43 | − else | |
| 43 | + ttmpl = TTM_PL_FLAG_VRAM; | |
| 44 | + } else { | |
| 44 | 45 | flags = NOUVEAU_GEM_DOMAIN_GART; |
| 46 | + ttmpl = TTM_PL_FLAG_TT; | |
| 47 | + } | |
| 45 | 48 | |
| 46 | 49 | ret = nouveau_gem_new(dev, NULL, PAGE_SIZE, 0, flags, 0, 0, &ntfy); |
| 47 | 50 | if (ret) |
| 48 | 51 | return ret; |
| 49 | 52 | |
| 50 | − ret = nouveau_bo_pin(ntfy, flags); | |
| 53 | + ret = nouveau_bo_pin(ntfy, ttmpl); | |
| 51 | 54 | if (ret) |
| 52 | 55 | goto out_err; |
| 53 | 56 | |
| @@ -1039,19 +1039,20 @@ nv_ro32(struct nouveau_gpuobj *gpuobj, u32 offset) · 1038 unmodified lines | ||
| 1039 | 1039 | { |
| 1040 | 1040 | struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; |
| 1041 | 1041 | struct drm_device *dev = gpuobj->dev; |
| 1042 | + unsigned long flags; | |
| 1042 | 1043 | |
| 1043 | 1044 | if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { |
| 1044 | 1045 | u64 ptr = gpuobj->vinst + offset; |
| 1045 | 1046 | u32 base = ptr >> 16; |
| 1046 | 1047 | u32 val; |
| 1047 | 1048 | |
| 1048 | − spin_lock(&dev_priv->ramin_lock); | |
| 1049 | + spin_lock_irqsave(&dev_priv->vm_lock, flags); | |
| 1049 | 1050 | if (dev_priv->ramin_base != base) { |
| 1050 | 1051 | dev_priv->ramin_base = base; |
| 1051 | 1052 | nv_wr32(dev, 0x001700, dev_priv->ramin_base); |
| 1052 | 1053 | } |
| 1053 | 1054 | val = nv_rd32(dev, 0x700000 + (ptr & 0xffff)); |
| 1054 | − spin_unlock(&dev_priv->ramin_lock); | |
| 1055 | + spin_unlock_irqrestore(&dev_priv->vm_lock, flags); | |
| 1055 | 1056 | return val; |
| 1056 | 1057 | } |
| 1057 | 1058 | |
| @@ -1063,18 +1064,19 @@ nv_wo32(struct nouveau_gpuobj *gpuobj, u32 offset, u32 val) · 5 unmodified lines | ||
| 1063 | 1064 | { |
| 1064 | 1065 | struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; |
| 1065 | 1066 | struct drm_device *dev = gpuobj->dev; |
| 1067 | + unsigned long flags; | |
| 1066 | 1068 | |
| 1067 | 1069 | if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { |
| 1068 | 1070 | u64 ptr = gpuobj->vinst + offset; |
| 1069 | 1071 | u32 base = ptr >> 16; |
| 1070 | 1072 | |
| 1071 | − spin_lock(&dev_priv->ramin_lock); | |
| 1073 | + spin_lock_irqsave(&dev_priv->vm_lock, flags); | |
| 1072 | 1074 | if (dev_priv->ramin_base != base) { |
| 1073 | 1075 | dev_priv->ramin_base = base; |
| 1074 | 1076 | nv_wr32(dev, 0x001700, dev_priv->ramin_base); |
| 1075 | 1077 | } |
| 1076 | 1078 | nv_wr32(dev, 0x700000 + (ptr & 0xffff), val); |
| 1077 | − spin_unlock(&dev_priv->ramin_lock); | |
| 1079 | + spin_unlock_irqrestore(&dev_priv->vm_lock, flags); | |
| 1078 | 1080 | return; |
| 1079 | 1081 | } |
| 1080 | 1082 | |
| @@ -42,7 +42,8 @@ nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages, · 41 unmodified lines | ||
| 42 | 42 | |
| 43 | 43 | nvbe->nr_pages = 0; |
| 44 | 44 | while (num_pages--) { |
| 45 | − if (dma_addrs[nvbe->nr_pages] != DMA_ERROR_CODE) { | |
| 45 | + /* this code path isn't called and is incorrect anyways */ | |
| 46 | + if (0) { /*dma_addrs[nvbe->nr_pages] != DMA_ERROR_CODE)*/ | |
| 46 | 47 | nvbe->pages[nvbe->nr_pages] = |
| 47 | 48 | dma_addrs[nvbe->nr_pages]; |
| 48 | 49 | nvbe->ttm_alloced[nvbe->nr_pages] = true; |
| @@ -55,6 +56,7 @@ nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages, · 6 unmodified lines | ||
| 55 | 56 | be->func->clear(be); |
| 56 | 57 | return -EFAULT; |
| 57 | 58 | } |
| 59 | + nvbe->ttm_alloced[nvbe->nr_pages] = false; | |
| 58 | 60 | } |
| 59 | 61 | |
| 60 | 62 | nvbe->nr_pages++; |
| @@ -427,7 +429,7 @@ nouveau_sgdma_init(struct drm_device *dev) · 366 unmodified lines | ||
| 427 | 429 | u32 aper_size, align; |
| 428 | 430 | int ret; |
| 429 | 431 | |
| 430 | − if (dev_priv->card_type >= NV_50 || drm_pci_device_is_pcie(dev)) | |
| 432 | + if (dev_priv->card_type >= NV_40 && drm_pci_device_is_pcie(dev)) | |
| 431 | 433 | aper_size = 512 * 1024 * 1024; |
| 432 | 434 | else |
| 433 | 435 | aper_size = 64 * 1024 * 1024; |
| @@ -457,7 +459,7 @@ nouveau_sgdma_init(struct drm_device *dev) · 23 unmodified lines | ||
| 457 | 459 | dev_priv->gart_info.func = &nv50_sgdma_backend; |
| 458 | 460 | } else |
| 459 | 461 | if (drm_pci_device_is_pcie(dev) && |
| 460 | − dev_priv->chipset != 0x40 && dev_priv->chipset != 0x45) { | |
| 462 | + dev_priv->chipset > 0x40 && dev_priv->chipset != 0x45) { | |
| 461 | 463 | if (nv44_graph_class(dev)) { |
| 462 | 464 | dev_priv->gart_info.func = &nv44_sgdma_backend; |
| 463 | 465 | align = 512 * 1024; |
| @@ -608,6 +608,7 @@ nouveau_card_init(struct drm_device *dev) · 607 unmodified lines | ||
| 608 | 608 | spin_lock_init(&dev_priv->channels.lock); |
| 609 | 609 | spin_lock_init(&dev_priv->tile.lock); |
| 610 | 610 | spin_lock_init(&dev_priv->context_switch_lock); |
| 611 | + spin_lock_init(&dev_priv->vm_lock); | |
| 611 | 612 | |
| 612 | 613 | /* Make the CRTCs and I2C buses accessible */ |
| 613 | 614 | ret = engine->display.early_init(dev); |
| @@ -767,6 +768,11 @@ static void nouveau_card_takedown(struct drm_device *dev) · 153 unmodified lines | ||
| 767 | 768 | engine->mc.takedown(dev); |
| 768 | 769 | engine->display.late_takedown(dev); |
| 769 | 770 | |
| 771 | + if (dev_priv->vga_ram) { | |
| 772 | + nouveau_bo_unpin(dev_priv->vga_ram); | |
| 773 | + nouveau_bo_ref(NULL, &dev_priv->vga_ram); | |
| 774 | + } | |
| 775 | + | |
| 770 | 776 | mutex_lock(&dev->struct_mutex); |
| 771 | 777 | ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); |
| 772 | 778 | ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT); |
| @@ -404,23 +404,25 @@ void · 403 unmodified lines | ||
| 404 | 404 | nv50_instmem_flush(struct drm_device *dev) |
| 405 | 405 | { |
| 406 | 406 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 407 | + unsigned long flags; | |
| 407 | 408 | |
| 408 | − spin_lock(&dev_priv->ramin_lock); | |
| 409 | + spin_lock_irqsave(&dev_priv->vm_lock, flags); | |
| 409 | 410 | nv_wr32(dev, 0x00330c, 0x00000001); |
| 410 | 411 | if (!nv_wait(dev, 0x00330c, 0x00000002, 0x00000000)) |
| 411 | 412 | NV_ERROR(dev, "PRAMIN flush timeout\n"); |
| 412 | − spin_unlock(&dev_priv->ramin_lock); | |
| 413 | + spin_unlock_irqrestore(&dev_priv->vm_lock, flags); | |
| 413 | 414 | } |
| 414 | 415 | |
| 415 | 416 | void |
| 416 | 417 | nv84_instmem_flush(struct drm_device *dev) |
| 417 | 418 | { |
| 418 | 419 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 420 | + unsigned long flags; | |
| 419 | 421 | |
| 420 | − spin_lock(&dev_priv->ramin_lock); | |
| 422 | + spin_lock_irqsave(&dev_priv->vm_lock, flags); | |
| 421 | 423 | nv_wr32(dev, 0x070000, 0x00000001); |
| 422 | 424 | if (!nv_wait(dev, 0x070000, 0x00000002, 0x00000000)) |
| 423 | 425 | NV_ERROR(dev, "PRAMIN flush timeout\n"); |
| 424 | − spin_unlock(&dev_priv->ramin_lock); | |
| 426 | + spin_unlock_irqrestore(&dev_priv->vm_lock, flags); | |
| 425 | 427 | } |
| 426 | 428 | |
| @@ -174,10 +174,11 @@ void · 173 unmodified lines | ||
| 174 | 174 | nv50_vm_flush_engine(struct drm_device *dev, int engine) |
| 175 | 175 | { |
| 176 | 176 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 177 | + unsigned long flags; | |
| 177 | 178 | |
| 178 | − spin_lock(&dev_priv->ramin_lock); | |
| 179 | + spin_lock_irqsave(&dev_priv->vm_lock, flags); | |
| 179 | 180 | nv_wr32(dev, 0x100c80, (engine << 16) | 1); |
| 180 | 181 | if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000)) |
| 181 | 182 | NV_ERROR(dev, "vm flush timeout: engine %d\n", engine); |
| 182 | − spin_unlock(&dev_priv->ramin_lock); | |
| 183 | + spin_unlock_irqrestore(&dev_priv->vm_lock, flags); | |
| 183 | 184 | } |
| @@ -104,11 +104,12 @@ nvc0_vm_flush(struct nouveau_vm *vm) · 103 unmodified lines | ||
| 104 | 104 | struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; |
| 105 | 105 | struct drm_device *dev = vm->dev; |
| 106 | 106 | struct nouveau_vm_pgd *vpgd; |
| 107 | + unsigned long flags; | |
| 107 | 108 | u32 engine = (dev_priv->chan_vm == vm) ? 1 : 5; |
| 108 | 109 | |
| 109 | 110 | pinstmem->flush(vm->dev); |
| 110 | 111 | |
| 111 | − spin_lock(&dev_priv->ramin_lock); | |
| 112 | + spin_lock_irqsave(&dev_priv->vm_lock, flags); | |
| 112 | 113 | list_for_each_entry(vpgd, &vm->pgd_list, head) { |
| 113 | 114 | /* looks like maybe a "free flush slots" counter, the |
| 114 | 115 | * faster you write to 0x100cbc to more it decreases |
| @@ -125,5 +126,5 @@ nvc0_vm_flush(struct nouveau_vm *vm) · 10 unmodified lines | ||
| 125 | 126 | nv_rd32(dev, 0x100c80), engine); |
| 126 | 127 | } |
| 127 | 128 | } |
| 128 | − spin_unlock(&dev_priv->ramin_lock); | |
| 129 | + spin_unlock_irqrestore(&dev_priv->vm_lock, flags); | |
| 129 | 130 | } |
| @@ -135,7 +135,7 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base, · 134 unmodified lines | ||
| 135 | 135 | case ATOM_IIO_MOVE_INDEX: |
| 136 | 136 | temp &= |
| 137 | 137 | ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << |
| 138 | − CU8(base + 2)); | |
| 138 | + CU8(base + 3)); | |
| 139 | 139 | temp |= |
| 140 | 140 | ((index >> CU8(base + 2)) & |
| 141 | 141 | (0xFFFFFFFF >> (32 - CU8(base + 1)))) << CU8(base + |
| @@ -145,7 +145,7 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base, · 3 unmodified lines | ||
| 145 | 145 | case ATOM_IIO_MOVE_DATA: |
| 146 | 146 | temp &= |
| 147 | 147 | ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << |
| 148 | − CU8(base + 2)); | |
| 148 | + CU8(base + 3)); | |
| 149 | 149 | temp |= |
| 150 | 150 | ((data >> CU8(base + 2)) & |
| 151 | 151 | (0xFFFFFFFF >> (32 - CU8(base + 1)))) << CU8(base + |
| @@ -155,7 +155,7 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base, · 3 unmodified lines | ||
| 155 | 155 | case ATOM_IIO_MOVE_ATTR: |
| 156 | 156 | temp &= |
| 157 | 157 | ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << |
| 158 | − CU8(base + 2)); | |
| 158 | + CU8(base + 3)); | |
| 159 | 159 | temp |= |
| 160 | 160 | ((ctx-> |
| 161 | 161 | io_attr >> CU8(base + 2)) & (0xFFFFFFFF >> (32 - |
| @@ -532,10 +532,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, · 531 unmodified lines | ||
| 532 | 532 | else |
| 533 | 533 | pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV; |
| 534 | 534 | |
| 535 | − if ((rdev->family == CHIP_R600) || | |
| 536 | − (rdev->family == CHIP_RV610) || | |
| 537 | − (rdev->family == CHIP_RV630) || | |
| 538 | − (rdev->family == CHIP_RV670)) | |
| 535 | + if (rdev->family < CHIP_RV770) | |
| 539 | 536 | pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; |
| 540 | 537 | } else { |
| 541 | 538 | pll->flags |= RADEON_PLL_LEGACY; |
| @@ -565,7 +562,6 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, · 23 unmodified lines | ||
| 565 | 562 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
| 566 | 563 | if (ss_enabled) { |
| 567 | 564 | if (ss->refdiv) { |
| 568 | − pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; | |
| 569 | 565 | pll->flags |= RADEON_PLL_USE_REF_DIV; |
| 570 | 566 | pll->reference_div = ss->refdiv; |
| 571 | 567 | if (ASIC_IS_AVIVO(rdev)) |
| @@ -353,7 +353,7 @@ static u32 evergreen_line_buffer_adjust(struct radeon_device *rdev, · 352 unmodified lines | ||
| 353 | 353 | struct drm_display_mode *mode, |
| 354 | 354 | struct drm_display_mode *other_mode) |
| 355 | 355 | { |
| 356 | − u32 tmp = 0; | |
| 356 | + u32 tmp; | |
| 357 | 357 | /* |
| 358 | 358 | * Line Buffer Setup |
| 359 | 359 | * There are 3 line buffers, each one shared by 2 display controllers. |
| @@ -363,64 +363,63 @@ static u32 evergreen_line_buffer_adjust(struct radeon_device *rdev, · 3 unmodified lines | ||
| 363 | 363 | * first display controller |
| 364 | 364 | * 0 - first half of lb (3840 * 2) |
| 365 | 365 | * 1 - first 3/4 of lb (5760 * 2) |
| 366 | − * 2 - whole lb (7680 * 2) | |
| 366 | + * 2 - whole lb (7680 * 2), other crtc must be disabled | |
| 367 | 367 | * 3 - first 1/4 of lb (1920 * 2) |
| 368 | 368 | * second display controller |
| 369 | 369 | * 4 - second half of lb (3840 * 2) |
| 370 | 370 | * 5 - second 3/4 of lb (5760 * 2) |
| 371 | − * 6 - whole lb (7680 * 2) | |
| 371 | + * 6 - whole lb (7680 * 2), other crtc must be disabled | |
| 372 | 372 | * 7 - last 1/4 of lb (1920 * 2) |
| 373 | 373 | */ |
| 374 | − if (mode && other_mode) { | |
| 375 | − if (mode->hdisplay > other_mode->hdisplay) { | |
| 376 | − if (mode->hdisplay > 2560) | |
| 377 | − tmp = 1; /* 3/4 */ | |
| 378 | − else | |
| 379 | − tmp = 0; /* 1/2 */ | |
| 380 | − } else if (other_mode->hdisplay > mode->hdisplay) { | |
| 381 | − if (other_mode->hdisplay > 2560) | |
| 382 | − tmp = 3; /* 1/4 */ | |
| 383 | − else | |
| 384 | − tmp = 0; /* 1/2 */ | |
| 385 | − } else | |
| 374 | + /* this can get tricky if we have two large displays on a paired group | |
| 375 | + * of crtcs. Ideally for multiple large displays we'd assign them to | |
| 376 | + * non-linked crtcs for maximum line buffer allocation. | |
| 377 | + */ | |
| 378 | + if (radeon_crtc->base.enabled && mode) { | |
| 379 | + if (other_mode) | |
| 386 | 380 | tmp = 0; /* 1/2 */ |
| 387 | − } else if (mode) | |
| 388 | − tmp = 2; /* whole */ | |
| 389 | − else if (other_mode) | |
| 390 | − tmp = 3; /* 1/4 */ | |
| 381 | + else | |
| 382 | + tmp = 2; /* whole */ | |
| 383 | + } else | |
| 384 | + tmp = 0; | |
| 391 | 385 | |
| 392 | 386 | /* second controller of the pair uses second half of the lb */ |
| 393 | 387 | if (radeon_crtc->crtc_id % 2) |
| 394 | 388 | tmp += 4; |
| 395 | 389 | WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset, tmp); |
| 396 | 390 | |
| 397 | − switch (tmp) { | |
| 398 | − case 0: | |
| 399 | − case 4: | |
| 400 | − default: | |
| 401 | − if (ASIC_IS_DCE5(rdev)) | |
| 402 | − return 4096 * 2; | |
| 403 | − else | |
| 404 | − return 3840 * 2; | |
| 405 | − case 1: | |
| 406 | − case 5: | |
| 407 | − if (ASIC_IS_DCE5(rdev)) | |
| 408 | − return 6144 * 2; | |
| 409 | − else | |
| 410 | − return 5760 * 2; | |
| 411 | − case 2: | |
| 412 | − case 6: | |
| 413 | − if (ASIC_IS_DCE5(rdev)) | |
| 414 | − return 8192 * 2; | |
| 415 | − else | |
| 416 | − return 7680 * 2; | |
| 417 | − case 3: | |
| 418 | − case 7: | |
| 419 | − if (ASIC_IS_DCE5(rdev)) | |
| 420 | − return 2048 * 2; | |
| 421 | − else | |
| 422 | − return 1920 * 2; | |
| 391 | + if (radeon_crtc->base.enabled && mode) { | |
| 392 | + switch (tmp) { | |
| 393 | + case 0: | |
| 394 | + case 4: | |
| 395 | + default: | |
| 396 | + if (ASIC_IS_DCE5(rdev)) | |
| 397 | + return 4096 * 2; | |
| 398 | + else | |
| 399 | + return 3840 * 2; | |
| 400 | + case 1: | |
| 401 | + case 5: | |
| 402 | + if (ASIC_IS_DCE5(rdev)) | |
| 403 | + return 6144 * 2; | |
| 404 | + else | |
| 405 | + return 5760 * 2; | |
| 406 | + case 2: | |
| 407 | + case 6: | |
| 408 | + if (ASIC_IS_DCE5(rdev)) | |
| 409 | + return 8192 * 2; | |
| 410 | + else | |
| 411 | + return 7680 * 2; | |
| 412 | + case 3: | |
| 413 | + case 7: | |
| 414 | + if (ASIC_IS_DCE5(rdev)) | |
| 415 | + return 2048 * 2; | |
| 416 | + else | |
| 417 | + return 1920 * 2; | |
| 418 | + } | |
| 423 | 419 | } |
| 420 | + | |
| 421 | + /* controller not enabled, so no lb used */ | |
| 422 | + return 0; | |
| 424 | 423 | } |
| 425 | 424 | |
| 426 | 425 | static u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev) |
| @@ -863,9 +862,15 @@ int evergreen_pcie_gart_enable(struct radeon_device *rdev) · 436 unmodified lines | ||
| 863 | 862 | SYSTEM_ACCESS_MODE_NOT_IN_SYS | |
| 864 | 863 | SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | |
| 865 | 864 | EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); |
| 866 | − WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); | |
| 867 | − WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); | |
| 868 | − WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); | |
| 865 | + if (rdev->flags & RADEON_IS_IGP) { | |
| 866 | + WREG32(FUS_MC_VM_MD_L1_TLB0_CNTL, tmp); | |
| 867 | + WREG32(FUS_MC_VM_MD_L1_TLB1_CNTL, tmp); | |
| 868 | + WREG32(FUS_MC_VM_MD_L1_TLB2_CNTL, tmp); | |
| 869 | + } else { | |
| 870 | + WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); | |
| 871 | + WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); | |
| 872 | + WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); | |
| 873 | + } | |
| 869 | 874 | WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); |
| 870 | 875 | WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); |
| 871 | 876 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); |
| @@ -1775,7 +1780,10 @@ static void evergreen_gpu_init(struct radeon_device *rdev) · 903 unmodified lines | ||
| 1775 | 1780 | |
| 1776 | 1781 | |
| 1777 | 1782 | mc_shared_chmap = RREG32(MC_SHARED_CHMAP); |
| 1778 | − mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); | |
| 1783 | + if (rdev->flags & RADEON_IS_IGP) | |
| 1784 | + mc_arb_ramcfg = RREG32(FUS_MC_ARB_RAMCFG); | |
| 1785 | + else | |
| 1786 | + mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); | |
| 1779 | 1787 | |
| 1780 | 1788 | switch (rdev->config.evergreen.max_tile_pipes) { |
| 1781 | 1789 | case 1: |
| @@ -2581,7 +2589,7 @@ static inline u32 evergreen_get_ih_wptr(struct radeon_device *rdev) · 799 unmodified lines | ||
| 2581 | 2589 | u32 wptr, tmp; |
| 2582 | 2590 | |
| 2583 | 2591 | if (rdev->wb.enabled) |
| 2584 | − wptr = rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]; | |
| 2592 | + wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]); | |
| 2585 | 2593 | else |
| 2586 | 2594 | wptr = RREG32(IH_RB_WPTR); |
| 2587 | 2595 | |
| @@ -2924,11 +2932,6 @@ static int evergreen_startup(struct radeon_device *rdev) · 336 unmodified lines | ||
| 2924 | 2932 | rdev->asic->copy = NULL; |
| 2925 | 2933 | dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); |
| 2926 | 2934 | } |
| 2927 | − /* XXX: ontario has problems blitting to gart at the moment */ | |
| 2928 | − if (rdev->family == CHIP_PALM) { | |
| 2929 | − rdev->asic->copy = NULL; | |
| 2930 | − radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); | |
| 2931 | − } | |
| 2932 | 2935 | |
| 2933 | 2936 | /* allocate wb buffer */ |
| 2934 | 2937 | r = radeon_wb_init(rdev); |
| @@ -200,6 +200,7 @@ · 199 unmodified lines | ||
| 200 | 200 | #define BURSTLENGTH_SHIFT 9 |
| 201 | 201 | #define BURSTLENGTH_MASK 0x00000200 |
| 202 | 202 | #define CHANSIZE_OVERRIDE (1 << 11) |
| 203 | +#define FUS_MC_ARB_RAMCFG 0x2768 | |
| 203 | 204 | #define MC_VM_AGP_TOP 0x2028 |
| 204 | 205 | #define MC_VM_AGP_BOT 0x202C |
| 205 | 206 | #define MC_VM_AGP_BASE 0x2030 |
| @@ -221,6 +222,11 @@ · 15 unmodified lines | ||
| 221 | 222 | #define MC_VM_MD_L1_TLB0_CNTL 0x2654 |
| 222 | 223 | #define MC_VM_MD_L1_TLB1_CNTL 0x2658 |
| 223 | 224 | #define MC_VM_MD_L1_TLB2_CNTL 0x265C |
| 225 | + | |
| 226 | +#define FUS_MC_VM_MD_L1_TLB0_CNTL 0x265C | |
| 227 | +#define FUS_MC_VM_MD_L1_TLB1_CNTL 0x2660 | |
| 228 | +#define FUS_MC_VM_MD_L1_TLB2_CNTL 0x2664 | |
| 229 | + | |
| 224 | 230 | #define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203C |
| 225 | 231 | #define MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038 |
| 226 | 232 | #define MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034 |
| @@ -674,7 +674,7 @@ static void cayman_gpu_init(struct radeon_device *rdev) · 673 unmodified lines | ||
| 674 | 674 | |
| 675 | 675 | cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE); |
| 676 | 676 | cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG); |
| 677 | − cgts_tcc_disable = RREG32(CGTS_TCC_DISABLE); | |
| 677 | + cgts_tcc_disable = 0xff000000; | |
| 678 | 678 | gc_user_rb_backend_disable = RREG32(GC_USER_RB_BACKEND_DISABLE); |
| 679 | 679 | gc_user_shader_pipe_config = RREG32(GC_USER_SHADER_PIPE_CONFIG); |
| 680 | 680 | cgts_user_tcc_disable = RREG32(CGTS_USER_TCC_DISABLE); |
| @@ -871,7 +871,7 @@ static void cayman_gpu_init(struct radeon_device *rdev) · 190 unmodified lines | ||
| 871 | 871 | |
| 872 | 872 | smx_dc_ctl0 = RREG32(SMX_DC_CTL0); |
| 873 | 873 | smx_dc_ctl0 &= ~NUMBER_OF_SETS(0x1ff); |
| 874 | − smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.evergreen.sx_num_of_sets); | |
| 874 | + smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.cayman.sx_num_of_sets); | |
| 875 | 875 | WREG32(SMX_DC_CTL0, smx_dc_ctl0); |
| 876 | 876 | |
| 877 | 877 | WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4) | CRC_SIMD_ID_WADDR_DISABLE); |
| @@ -887,20 +887,20 @@ static void cayman_gpu_init(struct radeon_device *rdev) · 9 unmodified lines | ||
| 887 | 887 | |
| 888 | 888 | WREG32(TA_CNTL_AUX, DISABLE_CUBE_ANISO); |
| 889 | 889 | |
| 890 | − WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_size / 4) - 1) | | |
| 891 | − POSITION_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_pos_size / 4) - 1) | | |
| 892 | − SMX_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_smx_size / 4) - 1))); | |
| 890 | + WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.cayman.sx_max_export_size / 4) - 1) | | |
| 891 | + POSITION_BUFFER_SIZE((rdev->config.cayman.sx_max_export_pos_size / 4) - 1) | | |
| 892 | + SMX_BUFFER_SIZE((rdev->config.cayman.sx_max_export_smx_size / 4) - 1))); | |
| 893 | 893 | |
| 894 | − WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.evergreen.sc_prim_fifo_size) | | |
| 895 | − SC_HIZ_TILE_FIFO_SIZE(rdev->config.evergreen.sc_hiz_tile_fifo_size) | | |
| 896 | − SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.evergreen.sc_earlyz_tile_fifo_size))); | |
| 894 | + WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.cayman.sc_prim_fifo_size) | | |
| 895 | + SC_HIZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_hiz_tile_fifo_size) | | |
| 896 | + SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.cayman.sc_earlyz_tile_fifo_size))); | |
| 897 | 897 | |
| 898 | 898 | |
| 899 | 899 | WREG32(VGT_NUM_INSTANCES, 1); |
| 900 | 900 | |
| 901 | 901 | WREG32(CP_PERFMON_CNTL, 0); |
| 902 | 902 | |
| 903 | − WREG32(SQ_MS_FIFO_SIZES, (CACHE_FIFO_SIZE(16 * rdev->config.evergreen.sq_num_cf_insts) | | |
| 903 | + WREG32(SQ_MS_FIFO_SIZES, (CACHE_FIFO_SIZE(16 * rdev->config.cayman.sq_num_cf_insts) | | |
| 904 | 904 | FETCH_FIFO_HIWATER(0x4) | |
| 905 | 905 | DONE_FIFO_HIWATER(0xe0) | |
| 906 | 906 | ALU_UPDATE_FIFO_HIWATER(0x8))); |
| @@ -3231,7 +3231,7 @@ static inline u32 r600_get_ih_wptr(struct radeon_device *rdev) · 3230 unmodified lines | ||
| 3231 | 3231 | u32 wptr, tmp; |
| 3232 | 3232 | |
| 3233 | 3233 | if (rdev->wb.enabled) |
| 3234 | − wptr = rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]; | |
| 3234 | + wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]); | |
| 3235 | 3235 | else |
| 3236 | 3236 | wptr = RREG32(IH_RB_WPTR); |
| 3237 | 3237 | |
| @@ -431,7 +431,7 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, · 430 unmodified lines | ||
| 431 | 431 | } |
| 432 | 432 | } |
| 433 | 433 | |
| 434 | − /* Acer laptop (Acer TravelMate 5730G) has an HDMI port | |
| 434 | + /* Acer laptop (Acer TravelMate 5730/5730G) has an HDMI port | |
| 435 | 435 | * on the laptop and a DVI port on the docking station and |
| 436 | 436 | * both share the same encoder, hpd pin, and ddc line. |
| 437 | 437 | * So while the bios table is technically correct, |
| @@ -440,7 +440,7 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, · 2 unmodified lines | ||
| 440 | 440 | * with different crtcs which isn't possible on the hardware |
| 441 | 441 | * side and leaves no crtcs for LVDS or VGA. |
| 442 | 442 | */ |
| 443 | − if ((dev->pdev->device == 0x95c4) && | |
| 443 | + if (((dev->pdev->device == 0x95c4) || (dev->pdev->device == 0x9591)) && | |
| 444 | 444 | (dev->pdev->subsystem_vendor == 0x1025) && |
| 445 | 445 | (dev->pdev->subsystem_device == 0x013c)) { |
| 446 | 446 | if ((*connector_type == DRM_MODE_CONNECTOR_DVII) && |
| @@ -1574,9 +1574,17 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct · 1127 unmodified lines | ||
| 1574 | 1574 | ATOM_FAKE_EDID_PATCH_RECORD *fake_edid_record; |
| 1575 | 1575 | ATOM_PANEL_RESOLUTION_PATCH_RECORD *panel_res_record; |
| 1576 | 1576 | bool bad_record = false; |
| 1577 | − u8 *record = (u8 *)(mode_info->atom_context->bios + | |
| 1578 | − data_offset + | |
| 1579 | − le16_to_cpu(lvds_info->info.usModePatchTableOffset)); | |
| 1577 | + u8 *record; | |
| 1578 | + | |
| 1579 | + if ((frev == 1) && (crev < 2)) | |
| 1580 | + /* absolute */ | |
| 1581 | + record = (u8 *)(mode_info->atom_context->bios + | |
| 1582 | + le16_to_cpu(lvds_info->info.usModePatchTableOffset)); | |
| 1583 | + else | |
| 1584 | + /* relative */ | |
| 1585 | + record = (u8 *)(mode_info->atom_context->bios + | |
| 1586 | + data_offset + | |
| 1587 | + le16_to_cpu(lvds_info->info.usModePatchTableOffset)); | |
| 1580 | 1588 | while (*record != ATOM_RECORD_END_TYPE) { |
| 1581 | 1589 | switch (*record) { |
| 1582 | 1590 | case LCD_MODE_PATCH_RECORD_MODE_TYPE: |
| @@ -1599,9 +1607,10 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct · 16 unmodified lines | ||
| 1599 | 1607 | memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0], |
| 1600 | 1608 | fake_edid_record->ucFakeEDIDLength); |
| 1601 | 1609 | |
| 1602 | − if (drm_edid_is_valid(edid)) | |
| 1610 | + if (drm_edid_is_valid(edid)) { | |
| 1603 | 1611 | rdev->mode_info.bios_hardcoded_edid = edid; |
| 1604 | − else | |
| 1612 | + rdev->mode_info.bios_hardcoded_edid_size = edid_size; | |
| 1613 | + } else | |
| 1605 | 1614 | kfree(edid); |
| 1606 | 1615 | } |
| 1607 | 1616 | } |
| @@ -15,6 +15,9 @@ · 14 unmodified lines | ||
| 15 | 15 | #define ATPX_VERSION 0 |
| 16 | 16 | #define ATPX_GPU_PWR 2 |
| 17 | 17 | #define ATPX_MUX_SELECT 3 |
| 18 | +#define ATPX_I2C_MUX_SELECT 4 | |
| 19 | +#define ATPX_SWITCH_START 5 | |
| 20 | +#define ATPX_SWITCH_END 6 | |
| 18 | 21 | |
| 19 | 22 | #define ATPX_INTEGRATED 0 |
| 20 | 23 | #define ATPX_DISCRETE 1 |
| @@ -149,13 +152,35 @@ static int radeon_atpx_switch_mux(acpi_handle handle, int mux_id) · 128 unmodified lines | ||
| 149 | 152 | return radeon_atpx_execute(handle, ATPX_MUX_SELECT, mux_id); |
| 150 | 153 | } |
| 151 | 154 | |
| 155 | +static int radeon_atpx_switch_i2c_mux(acpi_handle handle, int mux_id) | |
| 156 | +{ | |
| 157 | + return radeon_atpx_execute(handle, ATPX_I2C_MUX_SELECT, mux_id); | |
| 158 | +} | |
| 159 | + | |
| 160 | +static int radeon_atpx_switch_start(acpi_handle handle, int gpu_id) | |
| 161 | +{ | |
| 162 | + return radeon_atpx_execute(handle, ATPX_SWITCH_START, gpu_id); | |
| 163 | +} | |
| 164 | + | |
| 165 | +static int radeon_atpx_switch_end(acpi_handle handle, int gpu_id) | |
| 166 | +{ | |
| 167 | + return radeon_atpx_execute(handle, ATPX_SWITCH_END, gpu_id); | |
| 168 | +} | |
| 152 | 169 | |
| 153 | 170 | static int radeon_atpx_switchto(enum vga_switcheroo_client_id id) |
| 154 | 171 | { |
| 172 | + int gpu_id; | |
| 173 | + | |
| 155 | 174 | if (id == VGA_SWITCHEROO_IGD) |
| 156 | − radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, 0); | |
| 175 | + gpu_id = ATPX_INTEGRATED; | |
| 157 | 176 | else |
| 158 | − radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, 1); | |
| 177 | + gpu_id = ATPX_DISCRETE; | |
| 178 | + | |
| 179 | + radeon_atpx_switch_start(radeon_atpx_priv.atpx_handle, gpu_id); | |
| 180 | + radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, gpu_id); | |
| 181 | + radeon_atpx_switch_i2c_mux(radeon_atpx_priv.atpx_handle, gpu_id); | |
| 182 | + radeon_atpx_switch_end(radeon_atpx_priv.atpx_handle, gpu_id); | |
| 183 | + | |
| 159 | 184 | return 0; |
| 160 | 185 | } |
| 161 | 186 | |
| @@ -1199,7 +1199,7 @@ radeon_add_atom_connector(struct drm_device *dev, · 1198 unmodified lines | ||
| 1199 | 1199 | if (router->ddc_valid || router->cd_valid) { |
| 1200 | 1200 | radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info); |
| 1201 | 1201 | if (!radeon_connector->router_bus) |
| 1202 | − goto failed; | |
| 1202 | + DRM_ERROR("Failed to assign router i2c bus! Check dmesg for i2c errors.\n"); | |
| 1203 | 1203 | } |
| 1204 | 1204 | switch (connector_type) { |
| 1205 | 1205 | case DRM_MODE_CONNECTOR_VGA: |
| @@ -1208,7 +1208,7 @@ radeon_add_atom_connector(struct drm_device *dev, · 2 unmodified lines | ||
| 1208 | 1208 | if (i2c_bus->valid) { |
| 1209 | 1209 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
| 1210 | 1210 | if (!radeon_connector->ddc_bus) |
| 1211 | − goto failed; | |
| 1211 | + DRM_ERROR("VGA: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); | |
| 1212 | 1212 | } |
| 1213 | 1213 | radeon_connector->dac_load_detect = true; |
| 1214 | 1214 | drm_connector_attach_property(&radeon_connector->base, |
| @@ -1226,7 +1226,7 @@ radeon_add_atom_connector(struct drm_device *dev, · 11 unmodified lines | ||
| 1226 | 1226 | if (i2c_bus->valid) { |
| 1227 | 1227 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
| 1228 | 1228 | if (!radeon_connector->ddc_bus) |
| 1229 | − goto failed; | |
| 1229 | + DRM_ERROR("DVIA: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); | |
| 1230 | 1230 | } |
| 1231 | 1231 | radeon_connector->dac_load_detect = true; |
| 1232 | 1232 | drm_connector_attach_property(&radeon_connector->base, |
| @@ -1249,7 +1249,7 @@ radeon_add_atom_connector(struct drm_device *dev, · 16 unmodified lines | ||
| 1249 | 1249 | if (i2c_bus->valid) { |
| 1250 | 1250 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
| 1251 | 1251 | if (!radeon_connector->ddc_bus) |
| 1252 | − goto failed; | |
| 1252 | + DRM_ERROR("DVI: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); | |
| 1253 | 1253 | } |
| 1254 | 1254 | subpixel_order = SubPixelHorizontalRGB; |
| 1255 | 1255 | drm_connector_attach_property(&radeon_connector->base, |
| @@ -1290,7 +1290,7 @@ radeon_add_atom_connector(struct drm_device *dev, · 34 unmodified lines | ||
| 1290 | 1290 | if (i2c_bus->valid) { |
| 1291 | 1291 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
| 1292 | 1292 | if (!radeon_connector->ddc_bus) |
| 1293 | − goto failed; | |
| 1293 | + DRM_ERROR("HDMI: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); | |
| 1294 | 1294 | } |
| 1295 | 1295 | drm_connector_attach_property(&radeon_connector->base, |
| 1296 | 1296 | rdev->mode_info.coherent_mode_property, |
| @@ -1329,10 +1329,10 @@ radeon_add_atom_connector(struct drm_device *dev, · 32 unmodified lines | ||
| 1329 | 1329 | else |
| 1330 | 1330 | radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch"); |
| 1331 | 1331 | if (!radeon_dig_connector->dp_i2c_bus) |
| 1332 | − goto failed; | |
| 1332 | + DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n"); | |
| 1333 | 1333 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
| 1334 | 1334 | if (!radeon_connector->ddc_bus) |
| 1335 | − goto failed; | |
| 1335 | + DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); | |
| 1336 | 1336 | } |
| 1337 | 1337 | subpixel_order = SubPixelHorizontalRGB; |
| 1338 | 1338 | drm_connector_attach_property(&radeon_connector->base, |
| @@ -1381,7 +1381,7 @@ radeon_add_atom_connector(struct drm_device *dev, · 42 unmodified lines | ||
| 1381 | 1381 | if (i2c_bus->valid) { |
| 1382 | 1382 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
| 1383 | 1383 | if (!radeon_connector->ddc_bus) |
| 1384 | − goto failed; | |
| 1384 | + DRM_ERROR("LVDS: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); | |
| 1385 | 1385 | } |
| 1386 | 1386 | drm_connector_attach_property(&radeon_connector->base, |
| 1387 | 1387 | dev->mode_config.scaling_mode_property, |
| @@ -1457,7 +1457,7 @@ radeon_add_legacy_connector(struct drm_device *dev, · 69 unmodified lines | ||
| 1457 | 1457 | if (i2c_bus->valid) { |
| 1458 | 1458 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
| 1459 | 1459 | if (!radeon_connector->ddc_bus) |
| 1460 | − goto failed; | |
| 1460 | + DRM_ERROR("VGA: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); | |
| 1461 | 1461 | } |
| 1462 | 1462 | radeon_connector->dac_load_detect = true; |
| 1463 | 1463 | drm_connector_attach_property(&radeon_connector->base, |
| @@ -1475,7 +1475,7 @@ radeon_add_legacy_connector(struct drm_device *dev, · 11 unmodified lines | ||
| 1475 | 1475 | if (i2c_bus->valid) { |
| 1476 | 1476 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
| 1477 | 1477 | if (!radeon_connector->ddc_bus) |
| 1478 | − goto failed; | |
| 1478 | + DRM_ERROR("DVIA: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); | |
| 1479 | 1479 | } |
| 1480 | 1480 | radeon_connector->dac_load_detect = true; |
| 1481 | 1481 | drm_connector_attach_property(&radeon_connector->base, |
| @@ -1493,7 +1493,7 @@ radeon_add_legacy_connector(struct drm_device *dev, · 11 unmodified lines | ||
| 1493 | 1493 | if (i2c_bus->valid) { |
| 1494 | 1494 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
| 1495 | 1495 | if (!radeon_connector->ddc_bus) |
| 1496 | − goto failed; | |
| 1496 | + DRM_ERROR("DVI: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); | |
| 1497 | 1497 | } |
| 1498 | 1498 | if (connector_type == DRM_MODE_CONNECTOR_DVII) { |
| 1499 | 1499 | radeon_connector->dac_load_detect = true; |
| @@ -1538,7 +1538,7 @@ radeon_add_legacy_connector(struct drm_device *dev, · 38 unmodified lines | ||
| 1538 | 1538 | if (i2c_bus->valid) { |
| 1539 | 1539 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
| 1540 | 1540 | if (!radeon_connector->ddc_bus) |
| 1541 | − goto failed; | |
| 1541 | + DRM_ERROR("LVDS: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); | |
| 1542 | 1542 | } |
| 1543 | 1543 | drm_connector_attach_property(&radeon_connector->base, |
| 1544 | 1544 | dev->mode_config.scaling_mode_property, |
| @@ -1567,9 +1567,4 @@ radeon_add_legacy_connector(struct drm_device *dev, · 22 unmodified lines | ||
| 1567 | 1567 | radeon_legacy_backlight_init(radeon_encoder, connector); |
| 1568 | 1568 | } |
| 1569 | 1569 | } |
| 1570 | − return; | |
| 1571 | − | |
| 1572 | −failed: | |
| 1573 | − drm_connector_cleanup(connector); | |
| 1574 | − kfree(connector); | |
| 1575 | 1570 | } |
| @@ -167,9 +167,6 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc, · 166 unmodified lines | ||
| 167 | 167 | return -EINVAL; |
| 168 | 168 | } |
| 169 | 169 | |
| 170 | − radeon_crtc->cursor_width = width; | |
| 171 | − radeon_crtc->cursor_height = height; | |
| 172 | − | |
| 173 | 170 | obj = drm_gem_object_lookup(crtc->dev, file_priv, handle); |
| 174 | 171 | if (!obj) { |
| 175 | 172 | DRM_ERROR("Cannot find cursor object %x for crtc %d\n", handle, radeon_crtc->crtc_id); |
| @@ -180,6 +177,9 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc, · 4 unmodified lines | ||
| 180 | 177 | if (ret) |
| 181 | 178 | goto fail; |
| 182 | 179 | |
| 180 | + radeon_crtc->cursor_width = width; | |
| 181 | + radeon_crtc->cursor_height = height; | |
| 182 | + | |
| 183 | 183 | radeon_lock_cursor(crtc, true); |
| 184 | 184 | /* XXX only 27 bit offset for legacy cursor */ |
| 185 | 185 | radeon_set_cursor(crtc, obj, gpu_addr); |
| @@ -181,9 +181,9 @@ int radeon_gart_bind(struct radeon_device *rdev, unsigned offset, · 180 unmodified lines | ||
| 181 | 181 | p = t / (PAGE_SIZE / RADEON_GPU_PAGE_SIZE); |
| 182 | 182 | |
| 183 | 183 | for (i = 0; i < pages; i++, p++) { |
| 184 | − /* On TTM path, we only use the DMA API if TTM_PAGE_FLAG_DMA32 | |
| 185 | − * is requested. */ | |
| 186 | − if (dma_addr[i] != DMA_ERROR_CODE) { | |
| 184 | + /* we reverted the patch using dma_addr in TTM for now but this | |
| 185 | + * code stops building on alpha so just comment it out for now */ | |
| 186 | + if (0) { /*dma_addr[i] != DMA_ERROR_CODE) */ | |
| 187 | 187 | rdev->gart.ttm_alloced[p] = true; |
| 188 | 188 | rdev->gart.pages_addr[p] = dma_addr[i]; |
| 189 | 189 | } else { |
| @@ -1096,6 +1096,9 @@ void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector) · 1095 unmodified lines | ||
| 1096 | 1096 | if (!radeon_connector->router.ddc_valid) |
| 1097 | 1097 | return; |
| 1098 | 1098 | |
| 1099 | + if (!radeon_connector->router_bus) | |
| 1100 | + return; | |
| 1101 | + | |
| 1099 | 1102 | radeon_i2c_get_byte(radeon_connector->router_bus, |
| 1100 | 1103 | radeon_connector->router.i2c_addr, |
| 1101 | 1104 | 0x3, &val); |
| @@ -1121,6 +1124,9 @@ void radeon_router_select_cd_port(struct radeon_connector *radeon_connector) · 19 unmodified lines | ||
| 1121 | 1124 | if (!radeon_connector->router.cd_valid) |
| 1122 | 1125 | return; |
| 1123 | 1126 | |
| 1127 | + if (!radeon_connector->router_bus) | |
| 1128 | + return; | |
| 1129 | + | |
| 1124 | 1130 | radeon_i2c_get_byte(radeon_connector->router_bus, |
| 1125 | 1131 | radeon_connector->router.i2c_addr, |
| 1126 | 1132 | 0x3, &val); |
| @@ -221,6 +221,22 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) · 220 unmodified lines | ||
| 221 | 221 | return -EINVAL; |
| 222 | 222 | } |
| 223 | 223 | break; |
| 224 | + case RADEON_INFO_NUM_TILE_PIPES: | |
| 225 | + if (rdev->family >= CHIP_CAYMAN) | |
| 226 | + value = rdev->config.cayman.max_tile_pipes; | |
| 227 | + else if (rdev->family >= CHIP_CEDAR) | |
| 228 | + value = rdev->config.evergreen.max_tile_pipes; | |
| 229 | + else if (rdev->family >= CHIP_RV770) | |
| 230 | + value = rdev->config.rv770.max_tile_pipes; | |
| 231 | + else if (rdev->family >= CHIP_R600) | |
| 232 | + value = rdev->config.r600.max_tile_pipes; | |
| 233 | + else { | |
| 234 | + return -EINVAL; | |
| 235 | + } | |
| 236 | + break; | |
| 237 | + case RADEON_INFO_FUSION_GART_WORKING: | |
| 238 | + value = 1; | |
| 239 | + break; | |
| 224 | 240 | default: |
| 225 | 241 | DRM_DEBUG_KMS("Invalid request %d\n", info->request); |
| 226 | 242 | return -EINVAL; |
| @@ -33,6 +33,7 @@ cayman 0x9400 · 32 unmodified lines | ||
| 33 | 33 | 0x00008E48 SQ_EX_ALLOC_TABLE_SLOTS |
| 34 | 34 | 0x00009100 SPI_CONFIG_CNTL |
| 35 | 35 | 0x0000913C SPI_CONFIG_CNTL_1 |
| 36 | +0x00009508 TA_CNTL_AUX | |
| 36 | 37 | 0x00009830 DB_DEBUG |
| 37 | 38 | 0x00009834 DB_DEBUG2 |
| 38 | 39 | 0x00009838 DB_DEBUG3 |
| @@ -46,6 +46,7 @@ evergreen 0x9400 · 45 unmodified lines | ||
| 46 | 46 | 0x00008E48 SQ_EX_ALLOC_TABLE_SLOTS |
| 47 | 47 | 0x00009100 SPI_CONFIG_CNTL |
| 48 | 48 | 0x0000913C SPI_CONFIG_CNTL_1 |
| 49 | +0x00009508 TA_CNTL_AUX | |
| 49 | 50 | 0x00009700 VC_CNTL |
| 50 | 51 | 0x00009714 VC_ENHANCE |
| 51 | 52 | 0x00009830 DB_DEBUG |
| @@ -708,6 +708,7 @@ r600 0x9400 · 707 unmodified lines | ||
| 708 | 708 | 0x00028D0C DB_RENDER_CONTROL |
| 709 | 709 | 0x00028D10 DB_RENDER_OVERRIDE |
| 710 | 710 | 0x0002880C DB_SHADER_CONTROL |
| 711 | +0x00028D28 DB_SRESULTS_COMPARE_STATE0 | |
| 711 | 712 | 0x00028D2C DB_SRESULTS_COMPARE_STATE1 |
| 712 | 713 | 0x00028430 DB_STENCILREFMASK |
| 713 | 714 | 0x00028434 DB_STENCILREFMASK_BF |
| @@ -219,9 +219,6 @@ static int vga_switchto_stage1(struct vga_switcheroo_client *new_client) · 218 unmodified lines | ||
| 219 | 219 | int i; |
| 220 | 220 | struct vga_switcheroo_client *active = NULL; |
| 221 | 221 | |
| 222 | − if (new_client->active == true) | |
| 223 | − return 0; | |
| 224 | − | |
| 225 | 222 | for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) { |
| 226 | 223 | if (vgasr_priv.clients[i].active == true) { |
| 227 | 224 | active = &vgasr_priv.clients[i]; |
| @@ -372,6 +369,9 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf, · 144 unmodified lines | ||
| 372 | 369 | goto out; |
| 373 | 370 | } |
| 374 | 371 | |
| 372 | + if (client->active == true) | |
| 373 | + goto out; | |
| 374 | + | |
| 375 | 375 | /* okay we want a switch - test if devices are willing to switch */ |
| 376 | 376 | can_switch = true; |
| 377 | 377 | for (i = 0; i < VGA_SWITCHEROO_MAX_CLIENTS; i++) { |
| @@ -110,8 +110,7 @@ config SENSORS_ADM1021 · 109 unmodified lines | ||
| 110 | 110 | help |
| 111 | 111 | If you say yes here you get support for Analog Devices ADM1021 |
| 112 | 112 | and ADM1023 sensor chips and clones: Maxim MAX1617 and MAX1617A, |
| 113 | − Genesys Logic GL523SM, National Semiconductor LM84, TI THMC10, | |
| 114 | − and the XEON processor built-in sensor. | |
| 113 | + Genesys Logic GL523SM, National Semiconductor LM84 and TI THMC10. | |
| 115 | 114 | |
| 116 | 115 | This driver can also be built as a module. If so, the module |
| 117 | 116 | will be called adm1021. |
| @@ -618,10 +617,10 @@ config SENSORS_LM90 · 500 unmodified lines | ||
| 618 | 617 | depends on I2C |
| 619 | 618 | help |
| 620 | 619 | If you say yes here you get support for National Semiconductor LM90, |
| 621 | − LM86, LM89 and LM99, Analog Devices ADM1032 and ADT7461, Maxim | |
| 622 | − MAX6646, MAX6647, MAX6648, MAX6649, MAX6657, MAX6658, MAX6659, | |
| 623 | − MAX6680, MAX6681, MAX6692, MAX6695, MAX6696, and Winbond/Nuvoton | |
| 624 | − W83L771W/G/AWG/ASG sensor chips. | |
| 620 | + LM86, LM89 and LM99, Analog Devices ADM1032, ADT7461, and ADT7461A, | |
| 621 | + Maxim MAX6646, MAX6647, MAX6648, MAX6649, MAX6657, MAX6658, MAX6659, | |
| 622 | + MAX6680, MAX6681, MAX6692, MAX6695, MAX6696, ON Semiconductor NCT1008, | |
| 623 | + and Winbond/Nuvoton W83L771W/G/AWG/ASG sensor chips. | |
| 625 | 624 | |
| 626 | 625 | This driver can also be built as a module. If so, the module |
| 627 | 626 | will be called lm90. |
| @@ -1094,6 +1094,7 @@ static struct attribute *lm85_attributes_minctl[] = { · 1093 unmodified lines | ||
| 1094 | 1094 | &sensor_dev_attr_pwm1_auto_pwm_minctl.dev_attr.attr, |
| 1095 | 1095 | &sensor_dev_attr_pwm2_auto_pwm_minctl.dev_attr.attr, |
| 1096 | 1096 | &sensor_dev_attr_pwm3_auto_pwm_minctl.dev_attr.attr, |
| 1097 | + NULL | |
| 1097 | 1098 | }; |
| 1098 | 1099 | |
| 1099 | 1100 | static const struct attribute_group lm85_group_minctl = { |
| @@ -1104,6 +1105,7 @@ static struct attribute *lm85_attributes_temp_off[] = { · 4 unmodified lines | ||
| 1104 | 1105 | &sensor_dev_attr_temp1_auto_temp_off.dev_attr.attr, |
| 1105 | 1106 | &sensor_dev_attr_temp2_auto_temp_off.dev_attr.attr, |
| 1106 | 1107 | &sensor_dev_attr_temp3_auto_temp_off.dev_attr.attr, |
| 1108 | + NULL | |
| 1107 | 1109 | }; |
| 1108 | 1110 | |
| 1109 | 1111 | static const struct attribute_group lm85_group_temp_off = { |
| @@ -1329,11 +1331,11 @@ static int lm85_probe(struct i2c_client *client, · 219 unmodified lines | ||
| 1329 | 1331 | if (data->type != emc6d103s) { |
| 1330 | 1332 | err = sysfs_create_group(&client->dev.kobj, &lm85_group_minctl); |
| 1331 | 1333 | if (err) |
| 1332 | − goto err_kfree; | |
| 1334 | + goto err_remove_files; | |
| 1333 | 1335 | err = sysfs_create_group(&client->dev.kobj, |
| 1334 | 1336 | &lm85_group_temp_off); |
| 1335 | 1337 | if (err) |
| 1336 | − goto err_kfree; | |
| 1338 | + goto err_remove_files; | |
| 1337 | 1339 | } |
| 1338 | 1340 | |
| 1339 | 1341 | /* The ADT7463/68 have an optional VRM 10 mode where pin 21 is used |
| @@ -49,10 +49,10 @@ · 48 unmodified lines | ||
| 49 | 49 | * chips, but support three temperature sensors instead of two. MAX6695 |
| 50 | 50 | * and MAX6696 only differ in the pinout so they can be treated identically. |
| 51 | 51 | * |
| 52 | − * This driver also supports the ADT7461 chip from Analog Devices. | |
| 53 | − * It's supported in both compatibility and extended mode. It is mostly | |
| 54 | − * compatible with LM90 except for a data format difference for the | |
| 55 | − * temperature value registers. | |
| 52 | + * This driver also supports ADT7461 and ADT7461A from Analog Devices as well as | |
| 53 | + * NCT1008 from ON Semiconductor. The chips are supported in both compatibility | |
| 54 | + * and extended mode. They are mostly compatible with LM90 except for a data | |
| 55 | + * format difference for the temperature value registers. | |
| 56 | 56 | * |
| 57 | 57 | * Since the LM90 was the first chipset supported by this driver, most |
| 58 | 58 | * comments will refer to this chipset, but are actually general and |
| @@ -88,9 +88,10 @@ · 29 unmodified lines | ||
| 88 | 88 | * Addresses to scan |
| 89 | 89 | * Address is fully defined internally and cannot be changed except for |
| 90 | 90 | * MAX6659, MAX6680 and MAX6681. |
| 91 | − * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, MAX6649, MAX6657, | |
| 92 | − * MAX6658 and W83L771 have address 0x4c. | |
| 93 | − * ADM1032-2, ADT7461-2, LM89-1, LM99-1 and MAX6646 have address 0x4d. | |
| 91 | + * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, ADT7461A, MAX6649, | |
| 92 | + * MAX6657, MAX6658, NCT1008 and W83L771 have address 0x4c. | |
| 93 | + * ADM1032-2, ADT7461-2, ADT7461A-2, LM89-1, LM99-1, MAX6646, and NCT1008D | |
| 94 | + * have address 0x4d. | |
| 94 | 95 | * MAX6647 has address 0x4e. |
| 95 | 96 | * MAX6659 can have address 0x4c, 0x4d or 0x4e. |
| 96 | 97 | * MAX6680 and MAX6681 can have address 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, |
| @@ -174,6 +175,7 @@ enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680, · 77 unmodified lines | ||
| 174 | 175 | static const struct i2c_device_id lm90_id[] = { |
| 175 | 176 | { "adm1032", adm1032 }, |
| 176 | 177 | { "adt7461", adt7461 }, |
| 178 | + { "adt7461a", adt7461 }, | |
| 177 | 179 | { "lm90", lm90 }, |
| 178 | 180 | { "lm86", lm86 }, |
| 179 | 181 | { "lm89", lm86 }, |
| @@ -188,6 +190,7 @@ static const struct i2c_device_id lm90_id[] = { · 8 unmodified lines | ||
| 188 | 190 | { "max6681", max6680 }, |
| 189 | 191 | { "max6695", max6696 }, |
| 190 | 192 | { "max6696", max6696 }, |
| 193 | + { "nct1008", adt7461 }, | |
| 191 | 194 | { "w83l771", w83l771 }, |
| 192 | 195 | { } |
| 193 | 196 | }; |
| @@ -1153,6 +1156,11 @@ static int lm90_detect(struct i2c_client *new_client, · 959 unmodified lines | ||
| 1153 | 1156 | && (reg_config1 & 0x1B) == 0x00 |
| 1154 | 1157 | && reg_convrate <= 0x0A) { |
| 1155 | 1158 | name = "adt7461"; |
| 1159 | + } else | |
| 1160 | + if (chip_id == 0x57 /* ADT7461A, NCT1008 */ | |
| 1161 | + && (reg_config1 & 0x1B) == 0x00 | |
| 1162 | + && reg_convrate <= 0x0A) { | |
| 1163 | + name = "adt7461a"; | |
| 1156 | 1164 | } |
| 1157 | 1165 | } else |
| 1158 | 1166 | if (man_id == 0x4D) { /* Maxim */ |
| @@ -139,7 +139,6 @@ struct pmbus_data { · 138 unmodified lines | ||
| 139 | 139 | * A single status register covers multiple attributes, |
| 140 | 140 | * so we keep them all together. |
| 141 | 141 | */ |
| 142 | − u8 status_bits; | |
| 143 | 142 | u8 status[PB_NUM_STATUS_REG]; |
| 144 | 143 | |
| 145 | 144 | u8 currpage; |
| @@ -98,7 +98,6 @@ static const struct attribute_group twl4030_madc_group = { · 97 unmodified lines | ||
| 98 | 98 | static int __devinit twl4030_madc_hwmon_probe(struct platform_device *pdev) |
| 99 | 99 | { |
| 100 | 100 | int ret; |
| 101 | − int status; | |
| 102 | 101 | struct device *hwmon; |
| 103 | 102 | |
| 104 | 103 | ret = sysfs_create_group(&pdev->dev.kobj, &twl4030_madc_group); |
| @@ -107,7 +106,7 @@ static int __devinit twl4030_madc_hwmon_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 107 | 106 | hwmon = hwmon_device_register(&pdev->dev); |
| 108 | 107 | if (IS_ERR(hwmon)) { |
| 109 | 108 | dev_err(&pdev->dev, "hwmon_device_register failed.\n"); |
| 110 | − status = PTR_ERR(hwmon); | |
| 109 | + ret = PTR_ERR(hwmon); | |
| 111 | 110 | goto err_reg; |
| 112 | 111 | } |
| 113 | 112 | |
| @@ -134,10 +134,15 @@ · 133 unmodified lines | ||
| 134 | 134 | SMBHSTSTS_BUS_ERR | SMBHSTSTS_DEV_ERR | \ |
| 135 | 135 | SMBHSTSTS_INTR) |
| 136 | 136 | |
| 137 | +/* Older devices have their ID defined in <linux/pci_ids.h> */ | |
| 138 | +#define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22 | |
| 139 | +#define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 | |
| 137 | 140 | /* Patsburg also has three 'Integrated Device Function' SMBus controllers */ |
| 138 | 141 | #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0 0x1d70 |
| 139 | 142 | #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1 0x1d71 |
| 140 | 143 | #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2 0x1d72 |
| 144 | +#define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330 | |
| 145 | +#define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30 | |
| 141 | 146 | |
| 142 | 147 | struct i801_priv { |
| 143 | 148 | struct i2c_adapter adapter; |
| @@ -560,15 +560,18 @@ static struct i2c_adapter mpc_ops = { · 559 unmodified lines | ||
| 560 | 560 | .timeout = HZ, |
| 561 | 561 | }; |
| 562 | 562 | |
| 563 | +static const struct of_device_id mpc_i2c_of_match[]; | |
| 563 | 564 | static int __devinit fsl_i2c_probe(struct platform_device *op) |
| 564 | 565 | { |
| 566 | + const struct of_device_id *match; | |
| 565 | 567 | struct mpc_i2c *i2c; |
| 566 | 568 | const u32 *prop; |
| 567 | 569 | u32 clock = MPC_I2C_CLOCK_LEGACY; |
| 568 | 570 | int result = 0; |
| 569 | 571 | int plen; |
| 570 | 572 | |
| 571 | − if (!op->dev.of_match) | |
| 573 | + match = of_match_device(mpc_i2c_of_match, &op->dev); | |
| 574 | + if (!match) | |
| 572 | 575 | return -EINVAL; |
| 573 | 576 | |
| 574 | 577 | i2c = kzalloc(sizeof(*i2c), GFP_KERNEL); |
| @@ -605,8 +608,8 @@ static int __devinit fsl_i2c_probe(struct platform_device *op) · 30 unmodified lines | ||
| 605 | 608 | clock = *prop; |
| 606 | 609 | } |
| 607 | 610 | |
| 608 | − if (op->dev.of_match->data) { | |
| 609 | − struct mpc_i2c_data *data = op->dev.of_match->data; | |
| 611 | + if (match->data) { | |
| 612 | + struct mpc_i2c_data *data = match->data; | |
| 610 | 613 | data->setup(op->dev.of_node, i2c, clock, data->prescaler); |
| 611 | 614 | } else { |
| 612 | 615 | /* Backwards compatibility */ |
| @@ -1,7 +1,7 @@ | ||
| 1 | 1 | /* ------------------------------------------------------------------------ * |
| 2 | 2 | * i2c-parport.c I2C bus over parallel port * |
| 3 | 3 | * ------------------------------------------------------------------------ * |
| 4 | − Copyright (C) 2003-2010 Jean Delvare <khali@linux-fr.org> | |
| 4 | + Copyright (C) 2003-2011 Jean Delvare <khali@linux-fr.org> | |
| 5 | 5 | |
| 6 | 6 | Based on older i2c-philips-par.c driver |
| 7 | 7 | Copyright (C) 1995-2000 Simon G. Vogl |
| @@ -33,6 +33,8 @@ · 25 unmodified lines | ||
| 33 | 33 | #include <linux/i2c-algo-bit.h> |
| 34 | 34 | #include <linux/i2c-smbus.h> |
| 35 | 35 | #include <linux/slab.h> |
| 36 | +#include <linux/list.h> | |
| 37 | +#include <linux/mutex.h> | |
| 36 | 38 | #include "i2c-parport.h" |
| 37 | 39 | |
| 38 | 40 | /* ----- Device list ------------------------------------------------------ */ |
| @@ -43,10 +45,11 @@ struct i2c_par { · 4 unmodified lines | ||
| 43 | 45 | struct i2c_algo_bit_data algo_data; |
| 44 | 46 | struct i2c_smbus_alert_setup alert_data; |
| 45 | 47 | struct i2c_client *ara; |
| 46 | − struct i2c_par *next; | |
| 48 | + struct list_head node; | |
| 47 | 49 | }; |
| 48 | 50 | |
| 49 | −static struct i2c_par *adapter_list; | |
| 51 | +static LIST_HEAD(adapter_list); | |
| 52 | +static DEFINE_MUTEX(adapter_list_lock); | |
| 50 | 53 | |
| 51 | 54 | /* ----- Low-level parallel port access ----------------------------------- */ |
| 52 | 55 | |
| @@ -228,8 +231,9 @@ static void i2c_parport_attach (struct parport *port) · 175 unmodified lines | ||
| 228 | 231 | } |
| 229 | 232 | |
| 230 | 233 | /* Add the new adapter to the list */ |
| 231 | − adapter->next = adapter_list; | |
| 232 | − adapter_list = adapter; | |
| 234 | + mutex_lock(&adapter_list_lock); | |
| 235 | + list_add_tail(&adapter->node, &adapter_list); | |
| 236 | + mutex_unlock(&adapter_list_lock); | |
| 233 | 237 | return; |
| 234 | 238 | |
| 235 | 239 | ERROR1: |
| @@ -241,11 +245,11 @@ ERROR0: · 5 unmodified lines | ||
| 241 | 245 | |
| 242 | 246 | static void i2c_parport_detach (struct parport *port) |
| 243 | 247 | { |
| 244 | − struct i2c_par *adapter, *prev; | |
| 248 | + struct i2c_par *adapter, *_n; | |
| 245 | 249 | |
| 246 | 250 | /* Walk the list */ |
| 247 | − for (prev = NULL, adapter = adapter_list; adapter; | |
| 248 | − prev = adapter, adapter = adapter->next) { | |
| 251 | + mutex_lock(&adapter_list_lock); | |
| 252 | + list_for_each_entry_safe(adapter, _n, &adapter_list, node) { | |
| 249 | 253 | if (adapter->pdev->port == port) { |
| 250 | 254 | if (adapter->ara) { |
| 251 | 255 | parport_disable_irq(port); |
| @@ -259,14 +263,11 @@ static void i2c_parport_detach (struct parport *port) · 7 unmodified lines | ||
| 259 | 263 | |
| 260 | 264 | parport_release(adapter->pdev); |
| 261 | 265 | parport_unregister_device(adapter->pdev); |
| 262 | − if (prev) | |
| 263 | − prev->next = adapter->next; | |
| 264 | − else | |
| 265 | − adapter_list = adapter->next; | |
| 266 | + list_del(&adapter->node); | |
| 266 | 267 | kfree(adapter); |
| 267 | − return; | |
| 268 | 268 | } |
| 269 | 269 | } |
| 270 | + mutex_unlock(&adapter_list_lock); | |
| 270 | 271 | } |
| 271 | 272 | |
| 272 | 273 | static struct parport_driver i2c_parport_driver = { |
| @@ -65,7 +65,7 @@ static inline void i2c_pnx_arm_timer(struct i2c_pnx_algo_data *alg_data) · 64 unmodified lines | ||
| 65 | 65 | jiffies, expires); |
| 66 | 66 | |
| 67 | 67 | timer->expires = jiffies + expires; |
| 68 | − timer->data = (unsigned long)&alg_data; | |
| 68 | + timer->data = (unsigned long)alg_data; | |
| 69 | 69 | |
| 70 | 70 | add_timer(timer); |
| 71 | 71 | } |
| @@ -79,6 +79,12 @@ int ide_cdrom_drive_status(struct cdrom_device_info *cdi, int slot_nr) · 78 unmodified lines | ||
| 79 | 79 | return CDS_DRIVE_NOT_READY; |
| 80 | 80 | } |
| 81 | 81 | |
| 82 | +/* | |
| 83 | + * ide-cd always generates media changed event if media is missing, which | |
| 84 | + * makes it impossible to use for proper event reporting, so disk->events | |
| 85 | + * is cleared to 0 and the following function is used only to trigger | |
| 86 | + * revalidation and never propagated to userland. | |
| 87 | + */ | |
| 82 | 88 | unsigned int ide_cdrom_check_events_real(struct cdrom_device_info *cdi, |
| 83 | 89 | unsigned int clearing, int slot_nr) |
| 84 | 90 | { |
| @@ -298,6 +298,12 @@ static unsigned int ide_gd_check_events(struct gendisk *disk, · 297 unmodified lines | ||
| 298 | 298 | return 0; |
| 299 | 299 | } |
| 300 | 300 | |
| 301 | + /* | |
| 302 | + * The following is used to force revalidation on the first open on | |
| 303 | + * removeable devices, and never gets reported to userland as | |
| 304 | + * genhd->events is 0. This is intended as removeable ide disk | |
| 305 | + * can't really detect MEDIA_CHANGE events. | |
| 306 | + */ | |
| 301 | 307 | ret = drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED; |
| 302 | 308 | drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; |
| 303 | 309 | |
| @@ -413,7 +419,6 @@ static int ide_gd_probe(ide_drive_t *drive) · 109 unmodified lines | ||
| 413 | 419 | if (drive->dev_flags & IDE_DFLAG_REMOVABLE) |
| 414 | 420 | g->flags = GENHD_FL_REMOVABLE; |
| 415 | 421 | g->fops = &ide_gd_ops; |
| 416 | − g->events = DISK_EVENT_MEDIA_CHANGE; | |
| 417 | 422 | add_disk(g); |
| 418 | 423 | return 0; |
| 419 | 424 | |
| @@ -1799,7 +1799,7 @@ static int qib_6120_setup_reset(struct qib_devdata *dd) · 1798 unmodified lines | ||
| 1799 | 1799 | /* |
| 1800 | 1800 | * Keep chip from being accessed until we are ready. Use |
| 1801 | 1801 | * writeq() directly, to allow the write even though QIB_PRESENT |
| 1802 | − * isn't' set. | |
| 1802 | + * isn't set. | |
| 1803 | 1803 | */ |
| 1804 | 1804 | dd->flags &= ~(QIB_INITTED | QIB_PRESENT); |
| 1805 | 1805 | dd->int_counter = 0; /* so we check interrupts work again */ |
| @@ -2111,7 +2111,7 @@ static int qib_setup_7220_reset(struct qib_devdata *dd) · 2110 unmodified lines | ||
| 2111 | 2111 | /* |
| 2112 | 2112 | * Keep chip from being accessed until we are ready. Use |
| 2113 | 2113 | * writeq() directly, to allow the write even though QIB_PRESENT |
| 2114 | − * isn't' set. | |
| 2114 | + * isn't set. | |
| 2115 | 2115 | */ |
| 2116 | 2116 | dd->flags &= ~(QIB_INITTED | QIB_PRESENT); |
| 2117 | 2117 | dd->int_counter = 0; /* so we check interrupts work again */ |
| @@ -3299,7 +3299,7 @@ static int qib_do_7322_reset(struct qib_devdata *dd) · 3298 unmodified lines | ||
| 3299 | 3299 | /* |
| 3300 | 3300 | * Keep chip from being accessed until we are ready. Use |
| 3301 | 3301 | * writeq() directly, to allow the write even though QIB_PRESENT |
| 3302 | − * isn't' set. | |
| 3302 | + * isn't set. | |
| 3303 | 3303 | */ |
| 3304 | 3304 | dd->flags &= ~(QIB_INITTED | QIB_PRESENT | QIB_BADINTR); |
| 3305 | 3305 | dd->flags |= QIB_DOING_RESET; |
| @@ -281,17 +281,24 @@ struct ser_req { · 280 unmodified lines | ||
| 281 | 281 | u8 command; |
| 282 | 282 | u8 ref_off; |
| 283 | 283 | u16 scratch; |
| 284 | − __be16 sample; | |
| 285 | 284 | struct spi_message msg; |
| 286 | 285 | struct spi_transfer xfer[6]; |
| 286 | + /* | |
| 287 | + * DMA (thus cache coherency maintenance) requires the | |
| 288 | + * transfer buffers to live in their own cache lines. | |
| 289 | + */ | |
| 290 | + __be16 sample ____cacheline_aligned; | |
| 287 | 291 | }; |
| 288 | 292 | |
| 289 | 293 | struct ads7845_ser_req { |
| 290 | 294 | u8 command[3]; |
| 291 | − u8 pwrdown[3]; | |
| 292 | − u8 sample[3]; | |
| 293 | 295 | struct spi_message msg; |
| 294 | 296 | struct spi_transfer xfer[2]; |
| 297 | + /* | |
| 298 | + * DMA (thus cache coherency maintenance) requires the | |
| 299 | + * transfer buffers to live in their own cache lines. | |
| 300 | + */ | |
| 301 | + u8 sample[3] ____cacheline_aligned; | |
| 295 | 302 | }; |
| 296 | 303 | |
| 297 | 304 | static int ads7846_read12_ser(struct device *dev, unsigned command) |
| @@ -68,8 +68,23 @@ struct wm831x_ts { · 67 unmodified lines | ||
| 68 | 68 | unsigned int pd_irq; |
| 69 | 69 | bool pressure; |
| 70 | 70 | bool pen_down; |
| 71 | + struct work_struct pd_data_work; | |
| 71 | 72 | }; |
| 72 | 73 | |
| 74 | +static void wm831x_pd_data_work(struct work_struct *work) | |
| 75 | +{ | |
| 76 | + struct wm831x_ts *wm831x_ts = | |
| 77 | + container_of(work, struct wm831x_ts, pd_data_work); | |
| 78 | + | |
| 79 | + if (wm831x_ts->pen_down) { | |
| 80 | + enable_irq(wm831x_ts->data_irq); | |
| 81 | + dev_dbg(wm831x_ts->wm831x->dev, "IRQ PD->DATA done\n"); | |
| 82 | + } else { | |
| 83 | + enable_irq(wm831x_ts->pd_irq); | |
| 84 | + dev_dbg(wm831x_ts->wm831x->dev, "IRQ DATA->PD done\n"); | |
| 85 | + } | |
| 86 | +} | |
| 87 | + | |
| 73 | 88 | static irqreturn_t wm831x_ts_data_irq(int irq, void *irq_data) |
| 74 | 89 | { |
| 75 | 90 | struct wm831x_ts *wm831x_ts = irq_data; |
| @@ -110,6 +125,9 @@ static irqreturn_t wm831x_ts_data_irq(int irq, void *irq_data) · 34 unmodified lines | ||
| 110 | 125 | } |
| 111 | 126 | |
| 112 | 127 | if (!wm831x_ts->pen_down) { |
| 128 | + /* Switch from data to pen down */ | |
| 129 | + dev_dbg(wm831x->dev, "IRQ DATA->PD\n"); | |
| 130 | + | |
| 113 | 131 | disable_irq_nosync(wm831x_ts->data_irq); |
| 114 | 132 | |
| 115 | 133 | /* Don't need data any more */ |
| @@ -128,6 +146,10 @@ static irqreturn_t wm831x_ts_data_irq(int irq, void *irq_data) · 12 unmodified lines | ||
| 128 | 146 | ABS_PRESSURE, 0); |
| 129 | 147 | |
| 130 | 148 | input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 0); |
| 149 | + | |
| 150 | + schedule_work(&wm831x_ts->pd_data_work); | |
| 151 | + } else { | |
| 152 | + input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 1); | |
| 131 | 153 | } |
| 132 | 154 | |
| 133 | 155 | input_sync(wm831x_ts->input_dev); |
| @@ -141,6 +163,11 @@ static irqreturn_t wm831x_ts_pen_down_irq(int irq, void *irq_data) · 7 unmodified lines | ||
| 141 | 163 | struct wm831x *wm831x = wm831x_ts->wm831x; |
| 142 | 164 | int ena = 0; |
| 143 | 165 | |
| 166 | + if (wm831x_ts->pen_down) | |
| 167 | + return IRQ_HANDLED; | |
| 168 | + | |
| 169 | + disable_irq_nosync(wm831x_ts->pd_irq); | |
| 170 | + | |
| 144 | 171 | /* Start collecting data */ |
| 145 | 172 | if (wm831x_ts->pressure) |
| 146 | 173 | ena |= WM831X_TCH_Z_ENA; |
| @@ -149,14 +176,14 @@ static irqreturn_t wm831x_ts_pen_down_irq(int irq, void *irq_data) · 2 unmodified lines | ||
| 149 | 176 | WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | WM831X_TCH_Z_ENA, |
| 150 | 177 | WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | ena); |
| 151 | 178 | |
| 152 | − input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 1); | |
| 153 | − input_sync(wm831x_ts->input_dev); | |
| 154 | − | |
| 155 | 179 | wm831x_set_bits(wm831x, WM831X_INTERRUPT_STATUS_1, |
| 156 | 180 | WM831X_TCHPD_EINT, WM831X_TCHPD_EINT); |
| 157 | 181 | |
| 158 | 182 | wm831x_ts->pen_down = true; |
| 159 | − enable_irq(wm831x_ts->data_irq); | |
| 183 | + | |
| 184 | + /* Switch from pen down to data */ | |
| 185 | + dev_dbg(wm831x->dev, "IRQ PD->DATA\n"); | |
| 186 | + schedule_work(&wm831x_ts->pd_data_work); | |
| 160 | 187 | |
| 161 | 188 | return IRQ_HANDLED; |
| 162 | 189 | } |
| @@ -182,13 +209,28 @@ static void wm831x_ts_input_close(struct input_dev *idev) · 19 unmodified lines | ||
| 182 | 209 | struct wm831x_ts *wm831x_ts = input_get_drvdata(idev); |
| 183 | 210 | struct wm831x *wm831x = wm831x_ts->wm831x; |
| 184 | 211 | |
| 212 | + /* Shut the controller down, disabling all other functionality too */ | |
| 185 | 213 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1, |
| 186 | − WM831X_TCH_ENA | WM831X_TCH_CVT_ENA | | |
| 187 | − WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | | |
| 188 | − WM831X_TCH_Z_ENA, 0); | |
| 214 | + WM831X_TCH_ENA | WM831X_TCH_X_ENA | | |
| 215 | + WM831X_TCH_Y_ENA | WM831X_TCH_Z_ENA, 0); | |
| 189 | 216 | |
| 190 | − if (wm831x_ts->pen_down) | |
| 217 | + /* Make sure any pending IRQs are done, the above will prevent | |
| 218 | + * new ones firing. | |
| 219 | + */ | |
| 220 | + synchronize_irq(wm831x_ts->data_irq); | |
| 221 | + synchronize_irq(wm831x_ts->pd_irq); | |
| 222 | + | |
| 223 | + /* Make sure the IRQ completion work is quiesced */ | |
| 224 | + flush_work_sync(&wm831x_ts->pd_data_work); | |
| 225 | + | |
| 226 | + /* If we ended up with the pen down then make sure we revert back | |
| 227 | + * to pen detection state for the next time we start up. | |
| 228 | + */ | |
| 229 | + if (wm831x_ts->pen_down) { | |
| 191 | 230 | disable_irq(wm831x_ts->data_irq); |
| 231 | + enable_irq(wm831x_ts->pd_irq); | |
| 232 | + wm831x_ts->pen_down = false; | |
| 233 | + } | |
| 192 | 234 | } |
| 193 | 235 | |
| 194 | 236 | static __devinit int wm831x_ts_probe(struct platform_device *pdev) |
| @@ -198,7 +240,7 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev) · 3 unmodified lines | ||
| 198 | 240 | struct wm831x_pdata *core_pdata = dev_get_platdata(pdev->dev.parent); |
| 199 | 241 | struct wm831x_touch_pdata *pdata = NULL; |
| 200 | 242 | struct input_dev *input_dev; |
| 201 | − int error; | |
| 243 | + int error, irqf; | |
| 202 | 244 | |
| 203 | 245 | if (core_pdata) |
| 204 | 246 | pdata = core_pdata->touch; |
| @@ -212,6 +254,7 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev) · 7 unmodified lines | ||
| 212 | 254 | |
| 213 | 255 | wm831x_ts->wm831x = wm831x; |
| 214 | 256 | wm831x_ts->input_dev = input_dev; |
| 257 | + INIT_WORK(&wm831x_ts->pd_data_work, wm831x_pd_data_work); | |
| 215 | 258 | |
| 216 | 259 | /* |
| 217 | 260 | * If we have a direct IRQ use it, otherwise use the interrupt |
| @@ -270,9 +313,14 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev) · 52 unmodified lines | ||
| 270 | 313 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1, |
| 271 | 314 | WM831X_TCH_RATE_MASK, 6); |
| 272 | 315 | |
| 316 | + if (pdata && pdata->data_irqf) | |
| 317 | + irqf = pdata->data_irqf; | |
| 318 | + else | |
| 319 | + irqf = IRQF_TRIGGER_HIGH; | |
| 320 | + | |
| 273 | 321 | error = request_threaded_irq(wm831x_ts->data_irq, |
| 274 | 322 | NULL, wm831x_ts_data_irq, |
| 275 | − IRQF_ONESHOT, | |
| 323 | + irqf | IRQF_ONESHOT, | |
| 276 | 324 | "Touchscreen data", wm831x_ts); |
| 277 | 325 | if (error) { |
| 278 | 326 | dev_err(&pdev->dev, "Failed to request data IRQ %d: %d\n", |
| @@ -281,9 +329,14 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 281 | 329 | } |
| 282 | 330 | disable_irq(wm831x_ts->data_irq); |
| 283 | 331 | |
| 332 | + if (pdata && pdata->pd_irqf) | |
| 333 | + irqf = pdata->pd_irqf; | |
| 334 | + else | |
| 335 | + irqf = IRQF_TRIGGER_HIGH; | |
| 336 | + | |
| 284 | 337 | error = request_threaded_irq(wm831x_ts->pd_irq, |
| 285 | 338 | NULL, wm831x_ts_pen_down_irq, |
| 286 | − IRQF_ONESHOT, | |
| 339 | + irqf | IRQF_ONESHOT, | |
| 287 | 340 | "Touchscreen pen down", wm831x_ts); |
| 288 | 341 | if (error) { |
| 289 | 342 | dev_err(&pdev->dev, "Failed to request pen down IRQ %d: %d\n", |
| @@ -349,6 +349,7 @@ static const struct i2c_device_id lm3530_id[] = { · 348 unmodified lines | ||
| 349 | 349 | {LM3530_NAME, 0}, |
| 350 | 350 | {} |
| 351 | 351 | }; |
| 352 | +MODULE_DEVICE_TABLE(i2c, lm3530_id); | |
| 352 | 353 | |
| 353 | 354 | static struct i2c_driver lm3530_i2c_driver = { |
| 354 | 355 | .probe = lm3530_probe, |
| @@ -3170,6 +3170,7 @@ level_store(mddev_t *mddev, const char *buf, size_t len) · 3169 unmodified lines | ||
| 3170 | 3170 | mddev->layout = mddev->new_layout; |
| 3171 | 3171 | mddev->chunk_sectors = mddev->new_chunk_sectors; |
| 3172 | 3172 | mddev->delta_disks = 0; |
| 3173 | + mddev->degraded = 0; | |
| 3173 | 3174 | if (mddev->pers->sync_request == NULL) { |
| 3174 | 3175 | /* this is now an array without redundancy, so |
| 3175 | 3176 | * it must always be in_sync |
| @@ -5151,7 +5151,6 @@ static int run(mddev_t *mddev) · 5150 unmodified lines | ||
| 5151 | 5151 | |
| 5152 | 5152 | mddev->queue->backing_dev_info.congested_data = mddev; |
| 5153 | 5153 | mddev->queue->backing_dev_info.congested_fn = raid5_congested; |
| 5154 | − mddev->queue->queue_lock = &conf->device_lock; | |
| 5155 | 5154 | |
| 5156 | 5155 | chunk_size = mddev->chunk_sectors << 9; |
| 5157 | 5156 | blk_queue_io_min(mddev->queue, chunk_size); |
| @@ -5679,6 +5678,7 @@ static void raid5_quiesce(mddev_t *mddev, int state) · 521 unmodified lines | ||
| 5679 | 5678 | static void *raid45_takeover_raid0(mddev_t *mddev, int level) |
| 5680 | 5679 | { |
| 5681 | 5680 | struct raid0_private_data *raid0_priv = mddev->private; |
| 5681 | + sector_t sectors; | |
| 5682 | 5682 | |
| 5683 | 5683 | /* for raid0 takeover only one zone is supported */ |
| 5684 | 5684 | if (raid0_priv->nr_strip_zones > 1) { |
| @@ -5687,6 +5687,9 @@ static void *raid45_takeover_raid0(mddev_t *mddev, int level) · 2 unmodified lines | ||
| 5687 | 5687 | return ERR_PTR(-EINVAL); |
| 5688 | 5688 | } |
| 5689 | 5689 | |
| 5690 | + sectors = raid0_priv->strip_zone[0].zone_end; | |
| 5691 | + sector_div(sectors, raid0_priv->strip_zone[0].nb_dev); | |
| 5692 | + mddev->dev_sectors = sectors; | |
| 5690 | 5693 | mddev->new_level = level; |
| 5691 | 5694 | mddev->new_layout = ALGORITHM_PARITY_N; |
| 5692 | 5695 | mddev->new_chunk_sectors = mddev->chunk_sectors; |
| @@ -533,16 +533,7 @@ int tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq) · 532 unmodified lines | ||
| 533 | 533 | if (tda_fail(ret)) |
| 534 | 534 | goto fail; |
| 535 | 535 | |
| 536 | − regs[R_MPD] = (0x77 & pd); | |
| 537 | − | |
| 538 | − switch (priv->mode) { | |
| 539 | − case TDA18271_ANALOG: | |
| 540 | − regs[R_MPD] &= ~0x08; | |
| 541 | − break; | |
| 542 | − case TDA18271_DIGITAL: | |
| 543 | − regs[R_MPD] |= 0x08; | |
| 544 | − break; | |
| 545 | − } | |
| 536 | + regs[R_MPD] = (0x7f & pd); | |
| 546 | 537 | |
| 547 | 538 | div = ((d * (freq / 1000)) << 7) / 125; |
| 548 | 539 | |
| @@ -579,8 +579,8 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq) · 578 unmodified lines | ||
| 579 | 579 | #define RF3 2 |
| 580 | 580 | u32 rf_default[3]; |
| 581 | 581 | u32 rf_freq[3]; |
| 582 | − u8 prog_cal[3]; | |
| 583 | − u8 prog_tab[3]; | |
| 582 | + s32 prog_cal[3]; | |
| 583 | + s32 prog_tab[3]; | |
| 584 | 584 | |
| 585 | 585 | i = tda18271_lookup_rf_band(fe, &freq, NULL); |
| 586 | 586 | |
| @@ -602,32 +602,33 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq) · 15 unmodified lines | ||
| 602 | 602 | return bcal; |
| 603 | 603 | |
| 604 | 604 | tda18271_calc_rf_cal(fe, &rf_freq[rf]); |
| 605 | − prog_tab[rf] = regs[R_EB14]; | |
| 605 | + prog_tab[rf] = (s32)regs[R_EB14]; | |
| 606 | 606 | |
| 607 | 607 | if (1 == bcal) |
| 608 | − prog_cal[rf] = tda18271_calibrate_rf(fe, rf_freq[rf]); | |
| 608 | + prog_cal[rf] = | |
| 609 | + (s32)tda18271_calibrate_rf(fe, rf_freq[rf]); | |
| 609 | 610 | else |
| 610 | 611 | prog_cal[rf] = prog_tab[rf]; |
| 611 | 612 | |
| 612 | 613 | switch (rf) { |
| 613 | 614 | case RF1: |
| 614 | 615 | map[i].rf_a1 = 0; |
| 615 | − map[i].rf_b1 = (s32)(prog_cal[RF1] - prog_tab[RF1]); | |
| 616 | + map[i].rf_b1 = (prog_cal[RF1] - prog_tab[RF1]); | |
| 616 | 617 | map[i].rf1 = rf_freq[RF1] / 1000; |
| 617 | 618 | break; |
| 618 | 619 | case RF2: |
| 619 | − dividend = (s32)(prog_cal[RF2] - prog_tab[RF2]) - | |
| 620 | − (s32)(prog_cal[RF1] + prog_tab[RF1]); | |
| 620 | + dividend = (prog_cal[RF2] - prog_tab[RF2] - | |
| 621 | + prog_cal[RF1] + prog_tab[RF1]); | |
| 621 | 622 | divisor = (s32)(rf_freq[RF2] - rf_freq[RF1]) / 1000; |
| 622 | 623 | map[i].rf_a1 = (dividend / divisor); |
| 623 | 624 | map[i].rf2 = rf_freq[RF2] / 1000; |
| 624 | 625 | break; |
| 625 | 626 | case RF3: |
| 626 | − dividend = (s32)(prog_cal[RF3] - prog_tab[RF3]) - | |
| 627 | − (s32)(prog_cal[RF2] + prog_tab[RF2]); | |
| 627 | + dividend = (prog_cal[RF3] - prog_tab[RF3] - | |
| 628 | + prog_cal[RF2] + prog_tab[RF2]); | |
| 628 | 629 | divisor = (s32)(rf_freq[RF3] - rf_freq[RF2]) / 1000; |
| 629 | 630 | map[i].rf_a2 = (dividend / divisor); |
| 630 | − map[i].rf_b2 = (s32)(prog_cal[RF2] - prog_tab[RF2]); | |
| 631 | + map[i].rf_b2 = (prog_cal[RF2] - prog_tab[RF2]); | |
| 631 | 632 | map[i].rf3 = rf_freq[RF3] / 1000; |
| 632 | 633 | break; |
| 633 | 634 | default: |
| @@ -229,8 +229,7 @@ static struct tda18271_map tda18271c2_km[] = { · 228 unmodified lines | ||
| 229 | 229 | static struct tda18271_map tda18271_rf_band[] = { |
| 230 | 230 | { .rfmax = 47900, .val = 0x00 }, |
| 231 | 231 | { .rfmax = 61100, .val = 0x01 }, |
| 232 | −/* { .rfmax = 152600, .val = 0x02 }, */ | |
| 233 | − { .rfmax = 121200, .val = 0x02 }, | |
| 232 | + { .rfmax = 152600, .val = 0x02 }, | |
| 234 | 233 | { .rfmax = 164700, .val = 0x03 }, |
| 235 | 234 | { .rfmax = 203500, .val = 0x04 }, |
| 236 | 235 | { .rfmax = 457800, .val = 0x05 }, |
| @@ -448,7 +447,7 @@ static struct tda18271_map tda18271c2_rf_cal[] = { · 211 unmodified lines | ||
| 448 | 447 | { .rfmax = 150000, .val = 0xb0 }, |
| 449 | 448 | { .rfmax = 151000, .val = 0xb1 }, |
| 450 | 449 | { .rfmax = 152000, .val = 0xb7 }, |
| 451 | − { .rfmax = 153000, .val = 0xbd }, | |
| 450 | + { .rfmax = 152600, .val = 0xbd }, | |
| 452 | 451 | { .rfmax = 154000, .val = 0x20 }, |
| 453 | 452 | { .rfmax = 155000, .val = 0x22 }, |
| 454 | 453 | { .rfmax = 156000, .val = 0x24 }, |
| @@ -459,7 +458,7 @@ static struct tda18271_map tda18271c2_rf_cal[] = { · 4 unmodified lines | ||
| 459 | 458 | { .rfmax = 161000, .val = 0x2d }, |
| 460 | 459 | { .rfmax = 163000, .val = 0x2e }, |
| 461 | 460 | { .rfmax = 164000, .val = 0x2f }, |
| 462 | − { .rfmax = 165000, .val = 0x30 }, | |
| 461 | + { .rfmax = 164700, .val = 0x30 }, | |
| 463 | 462 | { .rfmax = 166000, .val = 0x11 }, |
| 464 | 463 | { .rfmax = 167000, .val = 0x12 }, |
| 465 | 464 | { .rfmax = 168000, .val = 0x13 }, |
| @@ -510,7 +509,8 @@ static struct tda18271_map tda18271c2_rf_cal[] = { · 44 unmodified lines | ||
| 510 | 509 | { .rfmax = 236000, .val = 0x1b }, |
| 511 | 510 | { .rfmax = 237000, .val = 0x1c }, |
| 512 | 511 | { .rfmax = 240000, .val = 0x1d }, |
| 513 | − { .rfmax = 242000, .val = 0x1f }, | |
| 512 | + { .rfmax = 242000, .val = 0x1e }, | |
| 513 | + { .rfmax = 244000, .val = 0x1f }, | |
| 514 | 514 | { .rfmax = 247000, .val = 0x20 }, |
| 515 | 515 | { .rfmax = 249000, .val = 0x21 }, |
| 516 | 516 | { .rfmax = 252000, .val = 0x22 }, |
| @@ -624,7 +624,7 @@ static struct tda18271_map tda18271c2_rf_cal[] = { · 107 unmodified lines | ||
| 624 | 624 | { .rfmax = 453000, .val = 0x93 }, |
| 625 | 625 | { .rfmax = 454000, .val = 0x94 }, |
| 626 | 626 | { .rfmax = 456000, .val = 0x96 }, |
| 627 | − { .rfmax = 457000, .val = 0x98 }, | |
| 627 | + { .rfmax = 457800, .val = 0x98 }, | |
| 628 | 628 | { .rfmax = 461000, .val = 0x11 }, |
| 629 | 629 | { .rfmax = 468000, .val = 0x12 }, |
| 630 | 630 | { .rfmax = 472000, .val = 0x13 }, |
| @@ -38,7 +38,7 @@ MODULE_PARM_DESC(debug, · 37 unmodified lines | ||
| 38 | 38 | DEBSTATUS); |
| 39 | 39 | |
| 40 | 40 | #define DRIVER_VERSION "0.1" |
| 41 | −#define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver" | |
| 41 | +#define DRIVER_NAME "flexcop-pci" | |
| 42 | 42 | #define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de>" |
| 43 | 43 | |
| 44 | 44 | struct flexcop_pci { |
| @@ -356,13 +356,15 @@ config DVB_USB_LME2510 · 355 unmodified lines | ||
| 356 | 356 | select DVB_TDA826X if !DVB_FE_CUSTOMISE |
| 357 | 357 | select DVB_STV0288 if !DVB_FE_CUSTOMISE |
| 358 | 358 | select DVB_IX2505V if !DVB_FE_CUSTOMISE |
| 359 | + select DVB_STV0299 if !DVB_FE_CUSTOMISE | |
| 360 | + select DVB_PLL if !DVB_FE_CUSTOMISE | |
| 359 | 361 | help |
| 360 | 362 | Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 . |
| 361 | 363 | |
| 362 | 364 | config DVB_USB_TECHNISAT_USB2 |
| 363 | 365 | tristate "Technisat DVB-S/S2 USB2.0 support" |
| 364 | 366 | depends on DVB_USB |
| 365 | − select DVB_STB0899 if !DVB_FE_CUSTOMISE | |
| 366 | − select DVB_STB6100 if !DVB_FE_CUSTOMISE | |
| 367 | + select DVB_STV090x if !DVB_FE_CUSTOMISE | |
| 368 | + select DVB_STV6110x if !DVB_FE_CUSTOMISE | |
| 367 | 369 | help |
| 368 | 370 | Say Y here to support the Technisat USB2 DVB-S/S2 device |
| @@ -2162,7 +2162,7 @@ struct dibx000_agc_config dib7090_agc_config[2] = { · 2161 unmodified lines | ||
| 2162 | 2162 | .agc1_pt3 = 98, |
| 2163 | 2163 | .agc1_slope1 = 0, |
| 2164 | 2164 | .agc1_slope2 = 167, |
| 2165 | − .agc1_pt1 = 98, | |
| 2165 | + .agc2_pt1 = 98, | |
| 2166 | 2166 | .agc2_pt2 = 255, |
| 2167 | 2167 | .agc2_slope1 = 104, |
| 2168 | 2168 | .agc2_slope2 = 0, |
| @@ -2440,11 +2440,11 @@ static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap) · 271 unmodified lines | ||
| 2440 | 2440 | dib0700_set_i2c_speed(adap->dev, 340); |
| 2441 | 2441 | adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]); |
| 2442 | 2442 | |
| 2443 | − dib7090_slave_reset(adap->fe); | |
| 2444 | − | |
| 2445 | 2443 | if (adap->fe == NULL) |
| 2446 | 2444 | return -ENODEV; |
| 2447 | 2445 | |
| 2446 | + dib7090_slave_reset(adap->fe); | |
| 2447 | + | |
| 2448 | 2448 | return 0; |
| 2449 | 2449 | } |
| 2450 | 2450 | |
| @@ -1520,6 +1520,7 @@ static int init_channel(struct ngene_channel *chan) · 1519 unmodified lines | ||
| 1520 | 1520 | if (dev->ci.en && (io & NGENE_IO_TSOUT)) { |
| 1521 | 1521 | dvb_ca_en50221_init(adapter, dev->ci.en, 0, 1); |
| 1522 | 1522 | set_transfer(chan, 1); |
| 1523 | + chan->dev->channel[2].DataFormatFlags = DF_SWAP32; | |
| 1523 | 1524 | set_transfer(&chan->dev->channel[2], 1); |
| 1524 | 1525 | dvb_register_device(adapter, &chan->ci_dev, |
| 1525 | 1526 | &ngene_dvbdev_ci, (void *) chan, |
| @@ -378,7 +378,6 @@ EXPORT_SYMBOL_GPL(media_entity_create_link); · 377 unmodified lines | ||
| 378 | 378 | |
| 379 | 379 | static int __media_entity_setup_link_notify(struct media_link *link, u32 flags) |
| 380 | 380 | { |
| 381 | − const u32 mask = MEDIA_LNK_FL_ENABLED; | |
| 382 | 381 | int ret; |
| 383 | 382 | |
| 384 | 383 | /* Notify both entities. */ |
| @@ -395,7 +394,7 @@ static int __media_entity_setup_link_notify(struct media_link *link, u32 flags) · 10 unmodified lines | ||
| 395 | 394 | return ret; |
| 396 | 395 | } |
| 397 | 396 | |
| 398 | − link->flags = (link->flags & ~mask) | (flags & mask); | |
| 397 | + link->flags = flags; | |
| 399 | 398 | link->reverse->flags = link->flags; |
| 400 | 399 | |
| 401 | 400 | return 0; |
| @@ -417,6 +416,7 @@ static int __media_entity_setup_link_notify(struct media_link *link, u32 flags) · 15 unmodified lines | ||
| 417 | 416 | */ |
| 418 | 417 | int __media_entity_setup_link(struct media_link *link, u32 flags) |
| 419 | 418 | { |
| 419 | + const u32 mask = MEDIA_LNK_FL_ENABLED; | |
| 420 | 420 | struct media_device *mdev; |
| 421 | 421 | struct media_entity *source, *sink; |
| 422 | 422 | int ret = -EBUSY; |
| @@ -424,6 +424,10 @@ int __media_entity_setup_link(struct media_link *link, u32 flags) · 1 unmodified line | ||
| 424 | 424 | if (link == NULL) |
| 425 | 425 | return -EINVAL; |
| 426 | 426 | |
| 427 | + /* The non-modifiable link flags must not be modified. */ | |
| 428 | + if ((link->flags & ~mask) != (flags & ~mask)) | |
| 429 | + return -EINVAL; | |
| 430 | + | |
| 427 | 431 | if (link->flags & MEDIA_LNK_FL_IMMUTABLE) |
| 428 | 432 | return link->flags == flags ? 0 : -EINVAL; |
| 429 | 433 | |
| @@ -170,7 +170,7 @@ static int fmr2_setfreq(struct fmr2 *dev) · 169 unmodified lines | ||
| 170 | 170 | return 0; |
| 171 | 171 | } |
| 172 | 172 | |
| 173 | −/* !!! not tested, in my card this does't work !!! */ | |
| 173 | +/* !!! not tested, in my card this doesn't work !!! */ | |
| 174 | 174 | static int fmr2_setvolume(struct fmr2 *dev) |
| 175 | 175 | { |
| 176 | 176 | int vol[16] = { 0x021, 0x084, 0x090, 0x104, |
| @@ -376,7 +376,7 @@ static int __devinit saa7706h_probe(struct i2c_client *client, · 375 unmodified lines | ||
| 376 | 376 | v4l_info(client, "chip found @ 0x%02x (%s)\n", |
| 377 | 377 | client->addr << 1, client->adapter->name); |
| 378 | 378 | |
| 379 | − state = kmalloc(sizeof(struct saa7706h_state), GFP_KERNEL); | |
| 379 | + state = kzalloc(sizeof(struct saa7706h_state), GFP_KERNEL); | |
| 380 | 380 | if (state == NULL) |
| 381 | 381 | return -ENOMEM; |
| 382 | 382 | sd = &state->sd; |
| @@ -176,7 +176,7 @@ static int __devinit tef6862_probe(struct i2c_client *client, · 175 unmodified lines | ||
| 176 | 176 | v4l_info(client, "chip found @ 0x%02x (%s)\n", |
| 177 | 177 | client->addr << 1, client->adapter->name); |
| 178 | 178 | |
| 179 | − state = kmalloc(sizeof(struct tef6862_state), GFP_KERNEL); | |
| 179 | + state = kzalloc(sizeof(struct tef6862_state), GFP_KERNEL); | |
| 180 | 180 | if (state == NULL) |
| 181 | 181 | return -ENOMEM; |
| 182 | 182 | state->freq = TEF6862_LO_FREQ; |
| @@ -46,7 +46,7 @@ · 45 unmodified lines | ||
| 46 | 46 | #define MOD_AUTHOR "Jarod Wilson <jarod@wilsonet.com>" |
| 47 | 47 | #define MOD_DESC "Driver for SoundGraph iMON MultiMedia IR/Display" |
| 48 | 48 | #define MOD_NAME "imon" |
| 49 | −#define MOD_VERSION "0.9.2" | |
| 49 | +#define MOD_VERSION "0.9.3" | |
| 50 | 50 | |
| 51 | 51 | #define DISPLAY_MINOR_BASE 144 |
| 52 | 52 | #define DEVICE_NAME "lcd%d" |
| @@ -460,8 +460,9 @@ static int display_close(struct inode *inode, struct file *file) · 407 unmodified lines | ||
| 460 | 460 | } |
| 461 | 461 | |
| 462 | 462 | /** |
| 463 | − * Sends a packet to the device -- this function must be called | |
| 464 | − * with ictx->lock held. | |
| 463 | + * Sends a packet to the device -- this function must be called with | |
| 464 | + * ictx->lock held, or its unlock/lock sequence while waiting for tx | |
| 465 | + * to complete can/will lead to a deadlock. | |
| 465 | 466 | */ |
| 466 | 467 | static int send_packet(struct imon_context *ictx) |
| 467 | 468 | { |
| @@ -991,12 +992,21 @@ static void imon_touch_display_timeout(unsigned long data) · 523 unmodified lines | ||
| 991 | 992 | * the iMON remotes, and those used by the Windows MCE remotes (which is |
| 992 | 993 | * really just RC-6), but only one or the other at a time, as the signals |
| 993 | 994 | * are decoded onboard the receiver. |
| 995 | + * | |
| 996 | + * This function gets called two different ways, one way is from | |
| 997 | + * rc_register_device, for initial protocol selection/setup, and the other is | |
| 998 | + * via a userspace-initiated protocol change request, either by direct sysfs | |
| 999 | + * prodding or by something like ir-keytable. In the rc_register_device case, | |
| 1000 | + * the imon context lock is already held, but when initiated from userspace, | |
| 1001 | + * it is not, so we must acquire it prior to calling send_packet, which | |
| 1002 | + * requires that the lock is held. | |
| 994 | 1003 | */ |
| 995 | 1004 | static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type) |
| 996 | 1005 | { |
| 997 | 1006 | int retval; |
| 998 | 1007 | struct imon_context *ictx = rc->priv; |
| 999 | 1008 | struct device *dev = ictx->dev; |
| 1009 | + bool unlock = false; | |
| 1000 | 1010 | unsigned char ir_proto_packet[] = { |
| 1001 | 1011 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 }; |
| 1002 | 1012 | |
| @@ -1029,6 +1039,11 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type) · 26 unmodified lines | ||
| 1029 | 1039 | |
| 1030 | 1040 | memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet)); |
| 1031 | 1041 | |
| 1042 | + if (!mutex_is_locked(&ictx->lock)) { | |
| 1043 | + unlock = true; | |
| 1044 | + mutex_lock(&ictx->lock); | |
| 1045 | + } | |
| 1046 | + | |
| 1032 | 1047 | retval = send_packet(ictx); |
| 1033 | 1048 | if (retval) |
| 1034 | 1049 | goto out; |
| @@ -1037,6 +1052,9 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type) · 2 unmodified lines | ||
| 1037 | 1052 | ictx->pad_mouse = false; |
| 1038 | 1053 | |
| 1039 | 1054 | out: |
| 1055 | + if (unlock) | |
| 1056 | + mutex_unlock(&ictx->lock); | |
| 1057 | + | |
| 1040 | 1058 | return retval; |
| 1041 | 1059 | } |
| 1042 | 1060 | |
| @@ -2134,6 +2152,7 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf) · 1091 unmodified lines | ||
| 2134 | 2152 | goto rdev_setup_failed; |
| 2135 | 2153 | } |
| 2136 | 2154 | |
| 2155 | + mutex_unlock(&ictx->lock); | |
| 2137 | 2156 | return ictx; |
| 2138 | 2157 | |
| 2139 | 2158 | rdev_setup_failed: |
| @@ -2205,6 +2224,7 @@ static struct imon_context *imon_init_intf1(struct usb_interface *intf, · 65 unmodified lines | ||
| 2205 | 2224 | goto urb_submit_failed; |
| 2206 | 2225 | } |
| 2207 | 2226 | |
| 2227 | + mutex_unlock(&ictx->lock); | |
| 2208 | 2228 | return ictx; |
| 2209 | 2229 | |
| 2210 | 2230 | urb_submit_failed: |
| @@ -2299,6 +2319,8 @@ static int __devinit imon_probe(struct usb_interface *interface, · 88 unmodified lines | ||
| 2299 | 2319 | usb_set_intfdata(interface, ictx); |
| 2300 | 2320 | |
| 2301 | 2321 | if (ifnum == 0) { |
| 2322 | + mutex_lock(&ictx->lock); | |
| 2323 | + | |
| 2302 | 2324 | if (product == 0xffdc && ictx->rf_device) { |
| 2303 | 2325 | sysfs_err = sysfs_create_group(&interface->dev.kobj, |
| 2304 | 2326 | &imon_rf_attr_group); |
| @@ -2309,13 +2331,14 @@ static int __devinit imon_probe(struct usb_interface *interface, · 4 unmodified lines | ||
| 2309 | 2331 | |
| 2310 | 2332 | if (ictx->display_supported) |
| 2311 | 2333 | imon_init_display(ictx, interface); |
| 2334 | + | |
| 2335 | + mutex_unlock(&ictx->lock); | |
| 2312 | 2336 | } |
| 2313 | 2337 | |
| 2314 | 2338 | dev_info(dev, "iMON device (%04x:%04x, intf%d) on " |
| 2315 | 2339 | "usb<%d:%d> initialized\n", vendor, product, ifnum, |
| 2316 | 2340 | usbdev->bus->busnum, usbdev->devnum); |
| 2317 | 2341 | |
| 2318 | − mutex_unlock(&ictx->lock); | |
| 2319 | 2342 | mutex_unlock(&driver_lock); |
| 2320 | 2343 | |
| 2321 | 2344 | return 0; |
| @@ -36,6 +36,7 @@ · 35 unmodified lines | ||
| 36 | 36 | #include <linux/io.h> |
| 37 | 37 | #include <linux/interrupt.h> |
| 38 | 38 | #include <linux/sched.h> |
| 39 | +#include <linux/delay.h> | |
| 39 | 40 | #include <linux/slab.h> |
| 40 | 41 | #include <linux/input.h> |
| 41 | 42 | #include <linux/bitops.h> |
| @@ -220,6 +220,8 @@ static struct usb_device_id mceusb_dev_table[] = { · 219 unmodified lines | ||
| 220 | 220 | { USB_DEVICE(VENDOR_PHILIPS, 0x206c) }, |
| 221 | 221 | /* Philips/Spinel plus IR transceiver for ASUS */ |
| 222 | 222 | { USB_DEVICE(VENDOR_PHILIPS, 0x2088) }, |
| 223 | + /* Philips IR transceiver (Dell branded) */ | |
| 224 | + { USB_DEVICE(VENDOR_PHILIPS, 0x2093) }, | |
| 223 | 225 | /* Realtek MCE IR Receiver and card reader */ |
| 224 | 226 | { USB_DEVICE(VENDOR_REALTEK, 0x0161), |
| 225 | 227 | .driver_info = MULTIFUNCTION }, |
| @@ -707,7 +707,8 @@ static void ir_close(struct input_dev *idev) · 706 unmodified lines | ||
| 707 | 707 | { |
| 708 | 708 | struct rc_dev *rdev = input_get_drvdata(idev); |
| 709 | 709 | |
| 710 | − rdev->close(rdev); | |
| 710 | + if (rdev) | |
| 711 | + rdev->close(rdev); | |
| 711 | 712 | } |
| 712 | 713 | |
| 713 | 714 | /* class for /sys/class/rc */ |
| @@ -733,6 +734,7 @@ static struct { · 19 unmodified lines | ||
| 733 | 734 | { RC_TYPE_SONY, "sony" }, |
| 734 | 735 | { RC_TYPE_RC5_SZ, "rc-5-sz" }, |
| 735 | 736 | { RC_TYPE_LIRC, "lirc" }, |
| 737 | + { RC_TYPE_OTHER, "other" }, | |
| 736 | 738 | }; |
| 737 | 739 | |
| 738 | 740 | #define PROTO_NONE "none" |
| @@ -875,7 +875,7 @@ config MX3_VIDEO · 874 unmodified lines | ||
| 875 | 875 | config VIDEO_MX3 |
| 876 | 876 | tristate "i.MX3x Camera Sensor Interface driver" |
| 877 | 877 | depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA |
| 878 | − select VIDEOBUF_DMA_CONTIG | |
| 878 | + select VIDEOBUF2_DMA_CONTIG | |
| 879 | 879 | select MX3_VIDEO |
| 880 | 880 | ---help--- |
| 881 | 881 | This is a v4l2 driver for the i.MX3x Camera Sensor Interface |
| @@ -350,9 +350,17 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister) · 349 unmodified lines | ||
| 350 | 350 | |
| 351 | 351 | /* No struct video_device, but can have buffers allocated */ |
| 352 | 352 | if (type == CX18_ENC_STREAM_TYPE_IDX) { |
| 353 | + /* If the module params didn't inhibit IDX ... */ | |
| 353 | 354 | if (cx->stream_buffers[type] != 0) { |
| 354 | 355 | cx->stream_buffers[type] = 0; |
| 355 | − cx18_stream_free(&cx->streams[type]); | |
| 356 | + /* | |
| 357 | + * Before calling cx18_stream_free(), | |
| 358 | + * check if the IDX stream was actually set up. | |
| 359 | + * Needed, since the cx18_probe() error path | |
| 360 | + * exits through here as well as normal clean up | |
| 361 | + */ | |
| 362 | + if (cx->streams[type].buffers != 0) | |
| 363 | + cx18_stream_free(&cx->streams[type]); | |
| 356 | 364 | } |
| 357 | 365 | continue; |
| 358 | 366 | } |
| @@ -22,6 +22,7 @@ config VIDEO_CX23885 · 21 unmodified lines | ||
| 22 | 22 | select DVB_CX24116 if !DVB_FE_CUSTOMISE |
| 23 | 23 | select DVB_STV0900 if !DVB_FE_CUSTOMISE |
| 24 | 24 | select DVB_DS3000 if !DVB_FE_CUSTOMISE |
| 25 | + select DVB_STV0367 if !DVB_FE_CUSTOMISE | |
| 25 | 26 | select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE |
| 26 | 27 | select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE |
| 27 | 28 | select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE |
| @@ -524,7 +524,7 @@ void cx88_ir_irq(struct cx88_core *core) · 523 unmodified lines | ||
| 524 | 524 | for (todo = 32; todo > 0; todo -= bits) { |
| 525 | 525 | ev.pulse = samples & 0x80000000 ? false : true; |
| 526 | 526 | bits = min(todo, 32U - fls(ev.pulse ? samples : ~samples)); |
| 527 | − ev.duration = (bits * NSEC_PER_SEC) / (1000 * ir_samplerate); | |
| 527 | + ev.duration = (bits * (NSEC_PER_SEC / 1000)) / ir_samplerate; | |
| 528 | 528 | ir_raw_event_store_with_filter(ir->dev, &ev); |
| 529 | 529 | samples <<= bits; |
| 530 | 530 | } |
| @@ -298,7 +298,7 @@ static unsigned long imx074_query_bus_param(struct soc_camera_device *icd) · 297 unmodified lines | ||
| 298 | 298 | static int imx074_set_bus_param(struct soc_camera_device *icd, |
| 299 | 299 | unsigned long flags) |
| 300 | 300 | { |
| 301 | − return -1; | |
| 301 | + return -EINVAL; | |
| 302 | 302 | } |
| 303 | 303 | |
| 304 | 304 | static struct soc_camera_ops imx074_ops = { |
| @@ -174,7 +174,7 @@ static int m52790_probe(struct i2c_client *client, · 173 unmodified lines | ||
| 174 | 174 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
| 175 | 175 | client->addr << 1, client->adapter->name); |
| 176 | 176 | |
| 177 | − state = kmalloc(sizeof(struct m52790_state), GFP_KERNEL); | |
| 177 | + state = kzalloc(sizeof(struct m52790_state), GFP_KERNEL); | |
| 178 | 178 | if (state == NULL) |
| 179 | 179 | return -ENOMEM; |
| 180 | 180 | |
| @@ -215,20 +215,21 @@ static u32 isp_set_xclk(struct isp_device *isp, u32 xclk, u8 xclksel) · 214 unmodified lines | ||
| 215 | 215 | } |
| 216 | 216 | |
| 217 | 217 | switch (xclksel) { |
| 218 | − case 0: | |
| 218 | + case ISP_XCLK_A: | |
| 219 | 219 | isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL, |
| 220 | 220 | ISPTCTRL_CTRL_DIVA_MASK, |
| 221 | 221 | divisor << ISPTCTRL_CTRL_DIVA_SHIFT); |
| 222 | 222 | dev_dbg(isp->dev, "isp_set_xclk(): cam_xclka set to %d Hz\n", |
| 223 | 223 | currentxclk); |
| 224 | 224 | break; |
| 225 | − case 1: | |
| 225 | + case ISP_XCLK_B: | |
| 226 | 226 | isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL, |
| 227 | 227 | ISPTCTRL_CTRL_DIVB_MASK, |
| 228 | 228 | divisor << ISPTCTRL_CTRL_DIVB_SHIFT); |
| 229 | 229 | dev_dbg(isp->dev, "isp_set_xclk(): cam_xclkb set to %d Hz\n", |
| 230 | 230 | currentxclk); |
| 231 | 231 | break; |
| 232 | + case ISP_XCLK_NONE: | |
| 232 | 233 | default: |
| 233 | 234 | omap3isp_put(isp); |
| 234 | 235 | dev_dbg(isp->dev, "ISP_ERR: isp_set_xclk(): Invalid requested " |
| @@ -237,13 +238,13 @@ static u32 isp_set_xclk(struct isp_device *isp, u32 xclk, u8 xclksel) · 2 unmodified lines | ||
| 237 | 238 | } |
| 238 | 239 | |
| 239 | 240 | /* Do we go from stable whatever to clock? */ |
| 240 | − if (divisor >= 2 && isp->xclk_divisor[xclksel] < 2) | |
| 241 | + if (divisor >= 2 && isp->xclk_divisor[xclksel - 1] < 2) | |
| 241 | 242 | omap3isp_get(isp); |
| 242 | 243 | /* Stopping the clock. */ |
| 243 | − else if (divisor < 2 && isp->xclk_divisor[xclksel] >= 2) | |
| 244 | + else if (divisor < 2 && isp->xclk_divisor[xclksel - 1] >= 2) | |
| 244 | 245 | omap3isp_put(isp); |
| 245 | 246 | |
| 246 | − isp->xclk_divisor[xclksel] = divisor; | |
| 247 | + isp->xclk_divisor[xclksel - 1] = divisor; | |
| 247 | 248 | |
| 248 | 249 | omap3isp_put(isp); |
| 249 | 250 | |
| @@ -285,7 +286,8 @@ static void isp_power_settings(struct isp_device *isp, int idle) · 35 unmodified lines | ||
| 285 | 286 | */ |
| 286 | 287 | void omap3isp_configure_bridge(struct isp_device *isp, |
| 287 | 288 | enum ccdc_input_entity input, |
| 288 | − const struct isp_parallel_platform_data *pdata) | |
| 289 | + const struct isp_parallel_platform_data *pdata, | |
| 290 | + unsigned int shift) | |
| 289 | 291 | { |
| 290 | 292 | u32 ispctrl_val; |
| 291 | 293 | |
| @@ -298,9 +300,9 @@ void omap3isp_configure_bridge(struct isp_device *isp, · 6 unmodified lines | ||
| 298 | 300 | switch (input) { |
| 299 | 301 | case CCDC_INPUT_PARALLEL: |
| 300 | 302 | ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_PARALLEL; |
| 301 | − ispctrl_val |= pdata->data_lane_shift << ISPCTRL_SHIFT_SHIFT; | |
| 302 | 303 | ispctrl_val |= pdata->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT; |
| 303 | 304 | ispctrl_val |= pdata->bridge << ISPCTRL_PAR_BRIDGE_SHIFT; |
| 305 | + shift += pdata->data_lane_shift * 2; | |
| 304 | 306 | break; |
| 305 | 307 | |
| 306 | 308 | case CCDC_INPUT_CSI2A: |
| @@ -319,6 +321,8 @@ void omap3isp_configure_bridge(struct isp_device *isp, · 12 unmodified lines | ||
| 319 | 321 | return; |
| 320 | 322 | } |
| 321 | 323 | |
| 324 | + ispctrl_val |= ((shift/2) << ISPCTRL_SHIFT_SHIFT) & ISPCTRL_SHIFT_MASK; | |
| 325 | + | |
| 322 | 326 | ispctrl_val &= ~ISPCTRL_SYNC_DETECT_MASK; |
| 323 | 327 | ispctrl_val |= ISPCTRL_SYNC_DETECT_VSRISE; |
| 324 | 328 | |
| @@ -658,6 +662,8 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use) · 333 unmodified lines | ||
| 658 | 662 | |
| 659 | 663 | /* Apply power change to connected non-nodes. */ |
| 660 | 664 | ret = isp_pipeline_pm_power(entity, change); |
| 665 | + if (ret < 0) | |
| 666 | + entity->use_count -= change; | |
| 661 | 667 | |
| 662 | 668 | mutex_unlock(&entity->parent->graph_mutex); |
| 663 | 669 | |
| @@ -872,6 +878,9 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe) · 208 unmodified lines | ||
| 872 | 878 | } |
| 873 | 879 | } |
| 874 | 880 | |
| 881 | + if (failure < 0) | |
| 882 | + isp->needs_reset = true; | |
| 883 | + | |
| 875 | 884 | return failure; |
| 876 | 885 | } |
| 877 | 886 | |
| @@ -884,7 +893,8 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe) · 6 unmodified lines | ||
| 884 | 893 | * single-shot or continuous mode. |
| 885 | 894 | * |
| 886 | 895 | * Return 0 if successful, or the return value of the failed video::s_stream |
| 887 | − * operation otherwise. | |
| 896 | + * operation otherwise. The pipeline state is not updated when the operation | |
| 897 | + * fails, except when stopping the pipeline. | |
| 888 | 898 | */ |
| 889 | 899 | int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe, |
| 890 | 900 | enum isp_pipeline_stream_state state) |
| @@ -895,7 +905,9 @@ int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe, · 4 unmodified lines | ||
| 895 | 905 | ret = isp_pipeline_disable(pipe); |
| 896 | 906 | else |
| 897 | 907 | ret = isp_pipeline_enable(pipe, state); |
| 898 | − pipe->stream_state = state; | |
| 908 | + | |
| 909 | + if (ret == 0 || state == ISP_PIPELINE_STREAM_STOPPED) | |
| 910 | + pipe->stream_state = state; | |
| 899 | 911 | |
| 900 | 912 | return ret; |
| 901 | 913 | } |
| @@ -1481,6 +1493,10 @@ void omap3isp_put(struct isp_device *isp) · 579 unmodified lines | ||
| 1481 | 1493 | if (--isp->ref_count == 0) { |
| 1482 | 1494 | isp_disable_interrupts(isp); |
| 1483 | 1495 | isp_save_ctx(isp); |
| 1496 | + if (isp->needs_reset) { | |
| 1497 | + isp_reset(isp); | |
| 1498 | + isp->needs_reset = false; | |
| 1499 | + } | |
| 1484 | 1500 | isp_disable_clocks(isp); |
| 1485 | 1501 | } |
| 1486 | 1502 | mutex_unlock(&isp->isp_mutex); |
| @@ -132,7 +132,6 @@ struct isp_reg { · 131 unmodified lines | ||
| 132 | 132 | |
| 133 | 133 | /** |
| 134 | 134 | * struct isp_parallel_platform_data - Parallel interface platform data |
| 135 | − * @width: Parallel bus width in bits (8, 10, 11 or 12) | |
| 136 | 135 | * @data_lane_shift: Data lane shifter |
| 137 | 136 | * 0 - CAMEXT[13:0] -> CAM[13:0] |
| 138 | 137 | * 1 - CAMEXT[13:2] -> CAM[11:0] |
| @@ -146,7 +145,6 @@ struct isp_reg { · 7 unmodified lines | ||
| 146 | 145 | * ISPCTRL_PAR_BRIDGE_BENDIAN - Big endian |
| 147 | 146 | */ |
| 148 | 147 | struct isp_parallel_platform_data { |
| 149 | − unsigned int width; | |
| 150 | 148 | unsigned int data_lane_shift:2; |
| 151 | 149 | unsigned int clk_pol:1; |
| 152 | 150 | unsigned int bridge:4; |
| @@ -262,6 +260,7 @@ struct isp_device { · 109 unmodified lines | ||
| 262 | 260 | /* ISP Obj */ |
| 263 | 261 | spinlock_t stat_lock; /* common lock for statistic drivers */ |
| 264 | 262 | struct mutex isp_mutex; /* For handling ref_count field */ |
| 263 | + bool needs_reset; | |
| 265 | 264 | int has_context; |
| 266 | 265 | int ref_count; |
| 267 | 266 | unsigned int autoidle; |
| @@ -311,11 +310,12 @@ int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe, · 43 unmodified lines | ||
| 311 | 310 | enum isp_pipeline_stream_state state); |
| 312 | 311 | void omap3isp_configure_bridge(struct isp_device *isp, |
| 313 | 312 | enum ccdc_input_entity input, |
| 314 | − const struct isp_parallel_platform_data *pdata); | |
| 313 | + const struct isp_parallel_platform_data *pdata, | |
| 314 | + unsigned int shift); | |
| 315 | 315 | |
| 316 | −#define ISP_XCLK_NONE -1 | |
| 317 | −#define ISP_XCLK_A 0 | |
| 318 | −#define ISP_XCLK_B 1 | |
| 316 | +#define ISP_XCLK_NONE 0 | |
| 317 | +#define ISP_XCLK_A 1 | |
| 318 | +#define ISP_XCLK_B 2 | |
| 319 | 319 | |
| 320 | 320 | struct isp_device *omap3isp_get(struct isp_device *isp); |
| 321 | 321 | void omap3isp_put(struct isp_device *isp); |
| @@ -43,6 +43,12 @@ __ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, · 42 unmodified lines | ||
| 43 | 43 | |
| 44 | 44 | static const unsigned int ccdc_fmts[] = { |
| 45 | 45 | V4L2_MBUS_FMT_Y8_1X8, |
| 46 | + V4L2_MBUS_FMT_Y10_1X10, | |
| 47 | + V4L2_MBUS_FMT_Y12_1X12, | |
| 48 | + V4L2_MBUS_FMT_SGRBG8_1X8, | |
| 49 | + V4L2_MBUS_FMT_SRGGB8_1X8, | |
| 50 | + V4L2_MBUS_FMT_SBGGR8_1X8, | |
| 51 | + V4L2_MBUS_FMT_SGBRG8_1X8, | |
| 46 | 52 | V4L2_MBUS_FMT_SGRBG10_1X10, |
| 47 | 53 | V4L2_MBUS_FMT_SRGGB10_1X10, |
| 48 | 54 | V4L2_MBUS_FMT_SBGGR10_1X10, |
| @@ -1110,21 +1116,38 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc) · 1061 unmodified lines | ||
| 1110 | 1116 | struct isp_parallel_platform_data *pdata = NULL; |
| 1111 | 1117 | struct v4l2_subdev *sensor; |
| 1112 | 1118 | struct v4l2_mbus_framefmt *format; |
| 1119 | + const struct isp_format_info *fmt_info; | |
| 1120 | + struct v4l2_subdev_format fmt_src; | |
| 1121 | + unsigned int depth_out; | |
| 1122 | + unsigned int depth_in = 0; | |
| 1113 | 1123 | struct media_pad *pad; |
| 1114 | 1124 | unsigned long flags; |
| 1125 | + unsigned int shift; | |
| 1115 | 1126 | u32 syn_mode; |
| 1116 | 1127 | u32 ccdc_pattern; |
| 1117 | 1128 | |
| 1118 | − if (ccdc->input == CCDC_INPUT_PARALLEL) { | |
| 1119 | − pad = media_entity_remote_source(&ccdc->pads[CCDC_PAD_SINK]); | |
| 1120 | − sensor = media_entity_to_v4l2_subdev(pad->entity); | |
| 1129 | + pad = media_entity_remote_source(&ccdc->pads[CCDC_PAD_SINK]); | |
| 1130 | + sensor = media_entity_to_v4l2_subdev(pad->entity); | |
| 1131 | + if (ccdc->input == CCDC_INPUT_PARALLEL) | |
| 1121 | 1132 | pdata = &((struct isp_v4l2_subdevs_group *)sensor->host_priv) |
| 1122 | 1133 | ->bus.parallel; |
| 1134 | + | |
| 1135 | + /* Compute shift value for lane shifter to configure the bridge. */ | |
| 1136 | + fmt_src.pad = pad->index; | |
| 1137 | + fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE; | |
| 1138 | + if (!v4l2_subdev_call(sensor, pad, get_fmt, NULL, &fmt_src)) { | |
| 1139 | + fmt_info = omap3isp_video_format_info(fmt_src.format.code); | |
| 1140 | + depth_in = fmt_info->bpp; | |
| 1123 | 1141 | } |
| 1124 | 1142 | |
| 1125 | − omap3isp_configure_bridge(isp, ccdc->input, pdata); | |
| 1143 | + fmt_info = omap3isp_video_format_info | |
| 1144 | + (isp->isp_ccdc.formats[CCDC_PAD_SINK].code); | |
| 1145 | + depth_out = fmt_info->bpp; | |
| 1146 | + | |
| 1147 | + shift = depth_in - depth_out; | |
| 1148 | + omap3isp_configure_bridge(isp, ccdc->input, pdata, shift); | |
| 1126 | 1149 | |
| 1127 | − ccdc->syncif.datsz = pdata ? pdata->width : 10; | |
| 1150 | + ccdc->syncif.datsz = depth_out; | |
| 1128 | 1151 | ccdc_config_sync_if(ccdc, &ccdc->syncif); |
| 1129 | 1152 | |
| 1130 | 1153 | /* CCDC_PAD_SINK */ |
| @@ -1338,7 +1361,7 @@ static int ccdc_sbl_wait_idle(struct isp_ccdc_device *ccdc, · 207 unmodified lines | ||
| 1338 | 1361 | * @ccdc: Pointer to ISP CCDC device. |
| 1339 | 1362 | * @event: Pointing which event trigger handler |
| 1340 | 1363 | * |
| 1341 | − * Return 1 when the event and stopping request combination is satisfyied, | |
| 1364 | + * Return 1 when the event and stopping request combination is satisfied, | |
| 1342 | 1365 | * zero otherwise. |
| 1343 | 1366 | */ |
| 1344 | 1367 | static int __ccdc_handle_stopping(struct isp_ccdc_device *ccdc, u32 event) |
| @@ -1618,7 +1641,7 @@ static int ccdc_video_queue(struct isp_video *video, struct isp_buffer *buffer) · 273 unmodified lines | ||
| 1618 | 1641 | |
| 1619 | 1642 | ccdc_set_outaddr(ccdc, buffer->isp_addr); |
| 1620 | 1643 | |
| 1621 | − /* We now have a buffer queued on the output, restart the pipeline in | |
| 1644 | + /* We now have a buffer queued on the output, restart the pipeline | |
| 1622 | 1645 | * on the next CCDC interrupt if running in continuous mode (or when |
| 1623 | 1646 | * starting the stream). |
| 1624 | 1647 | */ |
| @@ -755,7 +755,7 @@ static struct preview_update update_attrs[] = { · 754 unmodified lines | ||
| 755 | 755 | * @configs - pointer to update config structure. |
| 756 | 756 | * @config - return pointer to appropriate structure field. |
| 757 | 757 | * @bit - for which feature to return pointers. |
| 758 | − * Return size of coresponding prev_params member | |
| 758 | + * Return size of corresponding prev_params member | |
| 759 | 759 | */ |
| 760 | 760 | static u32 |
| 761 | 761 | __preview_get_ptrs(struct prev_params *params, void **param, |
| @@ -339,7 +339,7 @@ static int isp_video_buffer_prepare_user(struct isp_video_buffer *buf) · 338 unmodified lines | ||
| 339 | 339 | up_read(¤t->mm->mmap_sem); |
| 340 | 340 | |
| 341 | 341 | if (ret != buf->npages) { |
| 342 | − buf->npages = ret; | |
| 342 | + buf->npages = ret < 0 ? 0 : ret; | |
| 343 | 343 | isp_video_buffer_cleanup(buf); |
| 344 | 344 | return -EFAULT; |
| 345 | 345 | } |
| @@ -408,8 +408,8 @@ done: · 62 unmodified lines | ||
| 408 | 408 | * isp_video_buffer_prepare_vm_flags - Get VMA flags for a userspace address |
| 409 | 409 | * |
| 410 | 410 | * This function locates the VMAs for the buffer's userspace address and checks |
| 411 | − * that their flags match. The onlflag that we need to care for at the moment is | |
| 412 | − * VM_PFNMAP. | |
| 411 | + * that their flags match. The only flag that we need to care for at the moment | |
| 412 | + * is VM_PFNMAP. | |
| 413 | 413 | * |
| 414 | 414 | * The buffer vm_flags field is set to the first VMA flags. |
| 415 | 415 | * |
| @@ -714,19 +714,50 @@ static void resizer_print_status(struct isp_res_device *res) · 713 unmodified lines | ||
| 714 | 714 | * iw and ih are the input width and height after cropping. Those equations need |
| 715 | 715 | * to be satisfied exactly for the resizer to work correctly. |
| 716 | 716 | * |
| 717 | − * Reverting the equations, we can compute the resizing ratios with | |
| 717 | + * The equations can't be easily reverted, as the >> 8 operation is not linear. | |
| 718 | + * In addition, not all input sizes can be achieved for a given output size. To | |
| 719 | + * get the highest input size lower than or equal to the requested input size, | |
| 720 | + * we need to compute the highest resizing ratio that satisfies the following | |
| 721 | + * inequality (taking the 4-tap mode width equation as an example) | |
| 722 | + * | |
| 723 | + * iw >= (32 * sph + (ow - 1) * hrsz + 16) >> 8 - 7 | |
| 724 | + * | |
| 725 | + * (where iw is the requested input width) which can be rewritten as | |
| 726 | + * | |
| 727 | + * iw - 7 >= (32 * sph + (ow - 1) * hrsz + 16) >> 8 | |
| 728 | + * (iw - 7) << 8 >= 32 * sph + (ow - 1) * hrsz + 16 - b | |
| 729 | + * ((iw - 7) << 8) + b >= 32 * sph + (ow - 1) * hrsz + 16 | |
| 730 | + * | |
| 731 | + * where b is the value of the 8 least significant bits of the right hand side | |
| 732 | + * expression of the last inequality. The highest resizing ratio value will be | |
| 733 | + * achieved when b is equal to its maximum value of 255. That resizing ratio | |
| 734 | + * value will still satisfy the original inequality, as b will disappear when | |
| 735 | + * the expression will be shifted right by 8. | |
| 736 | + * | |
| 737 | + * The reverted the equations thus become | |
| 718 | 738 | * |
| 719 | 739 | * - 8-phase, 4-tap mode |
| 720 | − * hrsz = ((iw - 7) * 256 - 16 - 32 * sph) / (ow - 1) | |
| 721 | − * vrsz = ((ih - 4) * 256 - 16 - 32 * spv) / (oh - 1) | |
| 740 | + * hrsz = ((iw - 7) * 256 + 255 - 16 - 32 * sph) / (ow - 1) | |
| 741 | + * vrsz = ((ih - 4) * 256 + 255 - 16 - 32 * spv) / (oh - 1) | |
| 722 | 742 | * - 4-phase, 7-tap mode |
| 723 | − * hrsz = ((iw - 7) * 256 - 32 - 64 * sph) / (ow - 1) | |
| 724 | − * vrsz = ((ih - 7) * 256 - 32 - 64 * spv) / (oh - 1) | |
| 743 | + * hrsz = ((iw - 7) * 256 + 255 - 32 - 64 * sph) / (ow - 1) | |
| 744 | + * vrsz = ((ih - 7) * 256 + 255 - 32 - 64 * spv) / (oh - 1) | |
| 725 | 745 | * |
| 726 | − * The ratios are integer values, and must be rounded down to ensure that the | |
| 727 | − * cropped input size is not bigger than the uncropped input size. As the ratio | |
| 728 | − * in 7-tap mode is always smaller than the ratio in 4-tap mode, we can use the | |
| 729 | − * 7-tap mode equations to compute a ratio approximation. | |
| 746 | + * The ratios are integer values, and are rounded down to ensure that the | |
| 747 | + * cropped input size is not bigger than the uncropped input size. | |
| 748 | + * | |
| 749 | + * As the number of phases/taps, used to select the correct equations to compute | |
| 750 | + * the ratio, depends on the ratio, we start with the 4-tap mode equations to | |
| 751 | + * compute an approximation of the ratio, and switch to the 7-tap mode equations | |
| 752 | + * if the approximation is higher than the ratio threshold. | |
| 753 | + * | |
| 754 | + * As the 7-tap mode equations will return a ratio smaller than or equal to the | |
| 755 | + * 4-tap mode equations, the resulting ratio could become lower than or equal to | |
| 756 | + * the ratio threshold. This 'equations loop' isn't an issue as long as the | |
| 757 | + * correct equations are used to compute the final input size. Starting with the | |
| 758 | + * 4-tap mode equations ensure that, in case of values resulting in a 'ratio | |
| 759 | + * loop', the smallest of the ratio values will be used, never exceeding the | |
| 760 | + * requested input size. | |
| 730 | 761 | * |
| 731 | 762 | * We first clamp the output size according to the hardware capabilitie to avoid |
| 732 | 763 | * auto-cropping the input more than required to satisfy the TRM equations. The |
| @@ -775,6 +806,8 @@ static void resizer_calc_ratios(struct isp_res_device *res, · 42 unmodified lines | ||
| 775 | 806 | unsigned int max_width; |
| 776 | 807 | unsigned int max_height; |
| 777 | 808 | unsigned int width_alignment; |
| 809 | + unsigned int width; | |
| 810 | + unsigned int height; | |
| 778 | 811 | |
| 779 | 812 | /* |
| 780 | 813 | * Clamp the output height based on the hardware capabilities and |
| @@ -786,19 +819,22 @@ static void resizer_calc_ratios(struct isp_res_device *res, · 5 unmodified lines | ||
| 786 | 819 | max_height = min_t(unsigned int, max_height, MAX_OUT_HEIGHT); |
| 787 | 820 | output->height = clamp(output->height, min_height, max_height); |
| 788 | 821 | |
| 789 | − ratio->vert = ((input->height - 7) * 256 - 32 - 64 * spv) | |
| 822 | + ratio->vert = ((input->height - 4) * 256 + 255 - 16 - 32 * spv) | |
| 790 | 823 | / (output->height - 1); |
| 824 | + if (ratio->vert > MID_RESIZE_VALUE) | |
| 825 | + ratio->vert = ((input->height - 7) * 256 + 255 - 32 - 64 * spv) | |
| 826 | + / (output->height - 1); | |
| 791 | 827 | ratio->vert = clamp_t(unsigned int, ratio->vert, |
| 792 | 828 | MIN_RESIZE_VALUE, MAX_RESIZE_VALUE); |
| 793 | 829 | |
| 794 | 830 | if (ratio->vert <= MID_RESIZE_VALUE) { |
| 795 | 831 | upscaled_height = (output->height - 1) * ratio->vert |
| 796 | 832 | + 32 * spv + 16; |
| 797 | − input->height = (upscaled_height >> 8) + 4; | |
| 833 | + height = (upscaled_height >> 8) + 4; | |
| 798 | 834 | } else { |
| 799 | 835 | upscaled_height = (output->height - 1) * ratio->vert |
| 800 | 836 | + 64 * spv + 32; |
| 801 | − input->height = (upscaled_height >> 8) + 7; | |
| 837 | + height = (upscaled_height >> 8) + 7; | |
| 802 | 838 | } |
| 803 | 839 | |
| 804 | 840 | /* |
| @@ -854,20 +890,29 @@ static void resizer_calc_ratios(struct isp_res_device *res, · 49 unmodified lines | ||
| 854 | 890 | max_width & ~(width_alignment - 1)); |
| 855 | 891 | output->width = ALIGN(output->width, width_alignment); |
| 856 | 892 | |
| 857 | − ratio->horz = ((input->width - 7) * 256 - 32 - 64 * sph) | |
| 893 | + ratio->horz = ((input->width - 7) * 256 + 255 - 16 - 32 * sph) | |
| 858 | 894 | / (output->width - 1); |
| 895 | + if (ratio->horz > MID_RESIZE_VALUE) | |
| 896 | + ratio->horz = ((input->width - 7) * 256 + 255 - 32 - 64 * sph) | |
| 897 | + / (output->width - 1); | |
| 859 | 898 | ratio->horz = clamp_t(unsigned int, ratio->horz, |
| 860 | 899 | MIN_RESIZE_VALUE, MAX_RESIZE_VALUE); |
| 861 | 900 | |
| 862 | 901 | if (ratio->horz <= MID_RESIZE_VALUE) { |
| 863 | 902 | upscaled_width = (output->width - 1) * ratio->horz |
| 864 | 903 | + 32 * sph + 16; |
| 865 | − input->width = (upscaled_width >> 8) + 7; | |
| 904 | + width = (upscaled_width >> 8) + 7; | |
| 866 | 905 | } else { |
| 867 | 906 | upscaled_width = (output->width - 1) * ratio->horz |
| 868 | 907 | + 64 * sph + 32; |
| 869 | − input->width = (upscaled_width >> 8) + 7; | |
| 908 | + width = (upscaled_width >> 8) + 7; | |
| 870 | 909 | } |
| 910 | + | |
| 911 | + /* Center the new crop rectangle. */ | |
| 912 | + input->left += (input->width - width) / 2; | |
| 913 | + input->top += (input->height - height) / 2; | |
| 914 | + input->width = width; | |
| 915 | + input->height = height; | |
| 871 | 916 | } |
| 872 | 917 | |
| 873 | 918 | /* |
| @@ -131,9 +131,9 @@ struct ispstat { · 130 unmodified lines | ||
| 131 | 131 | struct ispstat_generic_config { |
| 132 | 132 | /* |
| 133 | 133 | * Fields must be in the same order as in: |
| 134 | − * - isph3a_aewb_config | |
| 135 | − * - isph3a_af_config | |
| 136 | − * - isphist_config | |
| 134 | + * - omap3isp_h3a_aewb_config | |
| 135 | + * - omap3isp_h3a_af_config | |
| 136 | + * - omap3isp_hist_config | |
| 137 | 137 | */ |
| 138 | 138 | u32 buf_size; |
| 139 | 139 | u16 config_counter; |
| @@ -47,29 +47,59 @@ · 46 unmodified lines | ||
| 47 | 47 | |
| 48 | 48 | static struct isp_format_info formats[] = { |
| 49 | 49 | { V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8, |
| 50 | − V4L2_MBUS_FMT_Y8_1X8, V4L2_PIX_FMT_GREY, 8, }, | |
| 50 | + V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8, | |
| 51 | + V4L2_PIX_FMT_GREY, 8, }, | |
| 52 | + { V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y10_1X10, | |
| 53 | + V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y8_1X8, | |
| 54 | + V4L2_PIX_FMT_Y10, 10, }, | |
| 55 | + { V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y10_1X10, | |
| 56 | + V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y8_1X8, | |
| 57 | + V4L2_PIX_FMT_Y12, 12, }, | |
| 58 | + { V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8, | |
| 59 | + V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8, | |
| 60 | + V4L2_PIX_FMT_SBGGR8, 8, }, | |
| 61 | + { V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8, | |
| 62 | + V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8, | |
| 63 | + V4L2_PIX_FMT_SGBRG8, 8, }, | |
| 64 | + { V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8, | |
| 65 | + V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8, | |
| 66 | + V4L2_PIX_FMT_SGRBG8, 8, }, | |
| 67 | + { V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8, | |
| 68 | + V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8, | |
| 69 | + V4L2_PIX_FMT_SRGGB8, 8, }, | |
| 51 | 70 | { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, |
| 52 | − V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10DPCM8, 8, }, | |
| 71 | + V4L2_MBUS_FMT_SGRBG10_1X10, 0, | |
| 72 | + V4L2_PIX_FMT_SGRBG10DPCM8, 8, }, | |
| 53 | 73 | { V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR10_1X10, |
| 54 | − V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10, 10, }, | |
| 74 | + V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR8_1X8, | |
| 75 | + V4L2_PIX_FMT_SBGGR10, 10, }, | |
| 55 | 76 | { V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG10_1X10, |
| 56 | − V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10, 10, }, | |
| 77 | + V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG8_1X8, | |
| 78 | + V4L2_PIX_FMT_SGBRG10, 10, }, | |
| 57 | 79 | { V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG10_1X10, |
| 58 | − V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10, 10, }, | |
| 80 | + V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG8_1X8, | |
| 81 | + V4L2_PIX_FMT_SGRBG10, 10, }, | |
| 59 | 82 | { V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB10_1X10, |
| 60 | − V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10, 10, }, | |
| 83 | + V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB8_1X8, | |
| 84 | + V4L2_PIX_FMT_SRGGB10, 10, }, | |
| 61 | 85 | { V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR10_1X10, |
| 62 | − V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SBGGR12, 12, }, | |
| 86 | + V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR8_1X8, | |
| 87 | + V4L2_PIX_FMT_SBGGR12, 12, }, | |
| 63 | 88 | { V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG10_1X10, |
| 64 | − V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12, 12, }, | |
| 89 | + V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG8_1X8, | |
| 90 | + V4L2_PIX_FMT_SGBRG12, 12, }, | |
| 65 | 91 | { V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG10_1X10, |
| 66 | − V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12, 12, }, | |
| 92 | + V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG8_1X8, | |
| 93 | + V4L2_PIX_FMT_SGRBG12, 12, }, | |
| 67 | 94 | { V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB10_1X10, |
| 68 | − V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12, 12, }, | |
| 95 | + V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB8_1X8, | |
| 96 | + V4L2_PIX_FMT_SRGGB12, 12, }, | |
| 69 | 97 | { V4L2_MBUS_FMT_UYVY8_1X16, V4L2_MBUS_FMT_UYVY8_1X16, |
| 70 | − V4L2_MBUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_UYVY, 16, }, | |
| 98 | + V4L2_MBUS_FMT_UYVY8_1X16, 0, | |
| 99 | + V4L2_PIX_FMT_UYVY, 16, }, | |
| 71 | 100 | { V4L2_MBUS_FMT_YUYV8_1X16, V4L2_MBUS_FMT_YUYV8_1X16, |
| 72 | − V4L2_MBUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_YUYV, 16, }, | |
| 101 | + V4L2_MBUS_FMT_YUYV8_1X16, 0, | |
| 102 | + V4L2_PIX_FMT_YUYV, 16, }, | |
| 73 | 103 | }; |
| 74 | 104 | |
| 75 | 105 | const struct isp_format_info * |
| @@ -85,6 +115,37 @@ omap3isp_video_format_info(enum v4l2_mbus_pixelcode code) · 9 unmodified lines | ||
| 85 | 115 | return NULL; |
| 86 | 116 | } |
| 87 | 117 | |
| 118 | +/* | |
| 119 | + * Decide whether desired output pixel code can be obtained with | |
| 120 | + * the lane shifter by shifting the input pixel code. | |
| 121 | + * @in: input pixelcode to shifter | |
| 122 | + * @out: output pixelcode from shifter | |
| 123 | + * @additional_shift: # of bits the sensor's LSB is offset from CAMEXT[0] | |
| 124 | + * | |
| 125 | + * return true if the combination is possible | |
| 126 | + * return false otherwise | |
| 127 | + */ | |
| 128 | +static bool isp_video_is_shiftable(enum v4l2_mbus_pixelcode in, | |
| 129 | + enum v4l2_mbus_pixelcode out, | |
| 130 | + unsigned int additional_shift) | |
| 131 | +{ | |
| 132 | + const struct isp_format_info *in_info, *out_info; | |
| 133 | + | |
| 134 | + if (in == out) | |
| 135 | + return true; | |
| 136 | + | |
| 137 | + in_info = omap3isp_video_format_info(in); | |
| 138 | + out_info = omap3isp_video_format_info(out); | |
| 139 | + | |
| 140 | + if ((in_info->flavor == 0) || (out_info->flavor == 0)) | |
| 141 | + return false; | |
| 142 | + | |
| 143 | + if (in_info->flavor != out_info->flavor) | |
| 144 | + return false; | |
| 145 | + | |
| 146 | + return in_info->bpp - out_info->bpp + additional_shift <= 6; | |
| 147 | +} | |
| 148 | + | |
| 88 | 149 | /* |
| 89 | 150 | * isp_video_mbus_to_pix - Convert v4l2_mbus_framefmt to v4l2_pix_format |
| 90 | 151 | * @video: ISP video instance |
| @@ -235,6 +296,7 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe) · 144 unmodified lines | ||
| 235 | 296 | return -EPIPE; |
| 236 | 297 | |
| 237 | 298 | while (1) { |
| 299 | + unsigned int shifter_link; | |
| 238 | 300 | /* Retrieve the sink format */ |
| 239 | 301 | pad = &subdev->entity.pads[0]; |
| 240 | 302 | if (!(pad->flags & MEDIA_PAD_FL_SINK)) |
| @@ -263,6 +325,10 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe) · 22 unmodified lines | ||
| 263 | 325 | return -ENOSPC; |
| 264 | 326 | } |
| 265 | 327 | |
| 328 | + /* If sink pad is on CCDC, the link has the lane shifter | |
| 329 | + * in the middle of it. */ | |
| 330 | + shifter_link = subdev == &isp->isp_ccdc.subdev; | |
| 331 | + | |
| 266 | 332 | /* Retrieve the source format */ |
| 267 | 333 | pad = media_entity_remote_source(pad); |
| 268 | 334 | if (pad == NULL || |
| @@ -278,10 +344,24 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe) · 9 unmodified lines | ||
| 278 | 344 | return -EPIPE; |
| 279 | 345 | |
| 280 | 346 | /* Check if the two ends match */ |
| 281 | − if (fmt_source.format.code != fmt_sink.format.code || | |
| 282 | − fmt_source.format.width != fmt_sink.format.width || | |
| 347 | + if (fmt_source.format.width != fmt_sink.format.width || | |
| 283 | 348 | fmt_source.format.height != fmt_sink.format.height) |
| 284 | 349 | return -EPIPE; |
| 350 | + | |
| 351 | + if (shifter_link) { | |
| 352 | + unsigned int parallel_shift = 0; | |
| 353 | + if (isp->isp_ccdc.input == CCDC_INPUT_PARALLEL) { | |
| 354 | + struct isp_parallel_platform_data *pdata = | |
| 355 | + &((struct isp_v4l2_subdevs_group *) | |
| 356 | + subdev->host_priv)->bus.parallel; | |
| 357 | + parallel_shift = pdata->data_lane_shift * 2; | |
| 358 | + } | |
| 359 | + if (!isp_video_is_shiftable(fmt_source.format.code, | |
| 360 | + fmt_sink.format.code, | |
| 361 | + parallel_shift)) | |
| 362 | + return -EPIPE; | |
| 363 | + } else if (fmt_source.format.code != fmt_sink.format.code) | |
| 364 | + return -EPIPE; | |
| 285 | 365 | } |
| 286 | 366 | |
| 287 | 367 | return 0; |
| @@ -49,6 +49,8 @@ struct v4l2_pix_format; · 48 unmodified lines | ||
| 49 | 49 | * bits. Identical to @code if the format is 10 bits wide or less. |
| 50 | 50 | * @uncompressed: V4L2 media bus format code for the corresponding uncompressed |
| 51 | 51 | * format. Identical to @code if the format is not DPCM compressed. |
| 52 | + * @flavor: V4L2 media bus format code for the same pixel layout but | |
| 53 | + * shifted to be 8 bits per pixel. =0 if format is not shiftable. | |
| 52 | 54 | * @pixelformat: V4L2 pixel format FCC identifier |
| 53 | 55 | * @bpp: Bits per pixel |
| 54 | 56 | */ |
| @@ -56,6 +58,7 @@ struct isp_format_info { · 1 unmodified line | ||
| 56 | 58 | enum v4l2_mbus_pixelcode code; |
| 57 | 59 | enum v4l2_mbus_pixelcode truncated; |
| 58 | 60 | enum v4l2_mbus_pixelcode uncompressed; |
| 61 | + enum v4l2_mbus_pixelcode flavor; | |
| 59 | 62 | u32 pixelformat; |
| 60 | 63 | unsigned int bpp; |
| 61 | 64 | }; |
| @@ -527,7 +527,7 @@ static int fimc_cap_s_fmt_mplane(struct file *file, void *priv, · 526 unmodified lines | ||
| 527 | 527 | if (ret) |
| 528 | 528 | return ret; |
| 529 | 529 | |
| 530 | − if (vb2_is_streaming(&fimc->vid_cap.vbq) || fimc_capture_active(fimc)) | |
| 530 | + if (vb2_is_busy(&fimc->vid_cap.vbq) || fimc_capture_active(fimc)) | |
| 531 | 531 | return -EBUSY; |
| 532 | 532 | |
| 533 | 533 | frame = &ctx->d_frame; |
| @@ -539,8 +539,10 @@ static int fimc_cap_s_fmt_mplane(struct file *file, void *priv, · 5 unmodified lines | ||
| 539 | 539 | return -EINVAL; |
| 540 | 540 | } |
| 541 | 541 | |
| 542 | − for (i = 0; i < frame->fmt->colplanes; i++) | |
| 543 | − frame->payload[i] = pix->plane_fmt[i].bytesperline * pix->height; | |
| 542 | + for (i = 0; i < frame->fmt->colplanes; i++) { | |
| 543 | + frame->payload[i] = | |
| 544 | + (pix->width * pix->height * frame->fmt->depth[i]) >> 3; | |
| 545 | + } | |
| 544 | 546 | |
| 545 | 547 | /* Output DMA frame pixel size and offsets. */ |
| 546 | 548 | frame->f_width = pix->plane_fmt[0].bytesperline * 8 |
| @@ -361,10 +361,20 @@ static void fimc_capture_irq_handler(struct fimc_dev *fimc) · 360 unmodified lines | ||
| 361 | 361 | { |
| 362 | 362 | struct fimc_vid_cap *cap = &fimc->vid_cap; |
| 363 | 363 | struct fimc_vid_buffer *v_buf; |
| 364 | + struct timeval *tv; | |
| 365 | + struct timespec ts; | |
| 364 | 366 | |
| 365 | 367 | if (!list_empty(&cap->active_buf_q) && |
| 366 | 368 | test_bit(ST_CAPT_RUN, &fimc->state)) { |
| 369 | + ktime_get_real_ts(&ts); | |
| 370 | + | |
| 367 | 371 | v_buf = active_queue_pop(cap); |
| 372 | + | |
| 373 | + tv = &v_buf->vb.v4l2_buf.timestamp; | |
| 374 | + tv->tv_sec = ts.tv_sec; | |
| 375 | + tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC; | |
| 376 | + v_buf->vb.v4l2_buf.sequence = cap->frame_count++; | |
| 377 | + | |
| 368 | 378 | vb2_buffer_done(&v_buf->vb, VB2_BUF_STATE_DONE); |
| 369 | 379 | } |
| 370 | 380 | |
| @@ -758,7 +768,7 @@ static void fimc_unlock(struct vb2_queue *vq) · 387 unmodified lines | ||
| 758 | 768 | mutex_unlock(&ctx->fimc_dev->lock); |
| 759 | 769 | } |
| 760 | 770 | |
| 761 | −struct vb2_ops fimc_qops = { | |
| 771 | +static struct vb2_ops fimc_qops = { | |
| 762 | 772 | .queue_setup = fimc_queue_setup, |
| 763 | 773 | .buf_prepare = fimc_buf_prepare, |
| 764 | 774 | .buf_queue = fimc_buf_queue, |
| @@ -927,23 +937,23 @@ int fimc_vidioc_try_fmt_mplane(struct file *file, void *priv, · 162 unmodified lines | ||
| 927 | 937 | pix->num_planes = fmt->memplanes; |
| 928 | 938 | pix->colorspace = V4L2_COLORSPACE_JPEG; |
| 929 | 939 | |
| 930 | − for (i = 0; i < pix->num_planes; ++i) { | |
| 931 | − int bpl = pix->plane_fmt[i].bytesperline; | |
| 932 | 940 | |
| 933 | − dbg("[%d] bpl: %d, depth: %d, w: %d, h: %d", | |
| 934 | − i, bpl, fmt->depth[i], pix->width, pix->height); | |
| 941 | + for (i = 0; i < pix->num_planes; ++i) { | |
| 942 | + u32 bpl = pix->plane_fmt[i].bytesperline; | |
| 943 | + u32 *sizeimage = &pix->plane_fmt[i].sizeimage; | |
| 935 | 944 | |
| 936 | − if (!bpl || (bpl * 8 / fmt->depth[i]) > pix->width) | |
| 937 | − bpl = (pix->width * fmt->depth[0]) >> 3; | |
| 945 | + if (fmt->colplanes > 1 && (bpl == 0 || bpl < pix->width)) | |
| 946 | + bpl = pix->width; /* Planar */ | |
| 938 | 947 | |
| 939 | − if (!pix->plane_fmt[i].sizeimage) | |
| 940 | − pix->plane_fmt[i].sizeimage = pix->height * bpl; | |
| 948 | + if (fmt->colplanes == 1 && /* Packed */ | |
| 949 | + (bpl == 0 || ((bpl * 8) / fmt->depth[i]) < pix->width)) | |
| 950 | + bpl = (pix->width * fmt->depth[0]) / 8; | |
| 941 | 951 | |
| 942 | − pix->plane_fmt[i].bytesperline = bpl; | |
| 952 | + if (i == 0) /* Same bytesperline for each plane. */ | |
| 953 | + mod_x = bpl; | |
| 943 | 954 | |
| 944 | − dbg("[%d]: bpl: %d, sizeimage: %d", | |
| 945 | − i, pix->plane_fmt[i].bytesperline, | |
| 946 | − pix->plane_fmt[i].sizeimage); | |
| 955 | + pix->plane_fmt[i].bytesperline = mod_x; | |
| 956 | + *sizeimage = (pix->width * pix->height * fmt->depth[i]) / 8; | |
| 947 | 957 | } |
| 948 | 958 | |
| 949 | 959 | return 0; |
| @@ -965,7 +975,7 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *priv, · 15 unmodified lines | ||
| 965 | 975 | |
| 966 | 976 | vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); |
| 967 | 977 | |
| 968 | − if (vb2_is_streaming(vq)) { | |
| 978 | + if (vb2_is_busy(vq)) { | |
| 969 | 979 | v4l2_err(&fimc->m2m.v4l2_dev, "queue (%d) busy\n", f->type); |
| 970 | 980 | return -EBUSY; |
| 971 | 981 | } |
| @@ -985,8 +995,10 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *priv, · 13 unmodified lines | ||
| 985 | 995 | if (!frame->fmt) |
| 986 | 996 | return -EINVAL; |
| 987 | 997 | |
| 988 | − for (i = 0; i < frame->fmt->colplanes; i++) | |
| 989 | − frame->payload[i] = pix->plane_fmt[i].bytesperline * pix->height; | |
| 998 | + for (i = 0; i < frame->fmt->colplanes; i++) { | |
| 999 | + frame->payload[i] = | |
| 1000 | + (pix->width * pix->height * frame->fmt->depth[i]) / 8; | |
| 1001 | + } | |
| 990 | 1002 | |
| 991 | 1003 | frame->f_width = pix->plane_fmt[0].bytesperline * 8 / |
| 992 | 1004 | frame->fmt->depth[0]; |
| @@ -1750,7 +1762,7 @@ static int __devexit fimc_remove(struct platform_device *pdev) · 757 unmodified lines | ||
| 1750 | 1762 | } |
| 1751 | 1763 | |
| 1752 | 1764 | /* Image pixel limits, similar across several FIMC HW revisions. */ |
| 1753 | −static struct fimc_pix_limit s5p_pix_limit[3] = { | |
| 1765 | +static struct fimc_pix_limit s5p_pix_limit[4] = { | |
| 1754 | 1766 | [0] = { |
| 1755 | 1767 | .scaler_en_w = 3264, |
| 1756 | 1768 | .scaler_dis_w = 8192, |
| @@ -1775,6 +1787,14 @@ static struct fimc_pix_limit s5p_pix_limit[3] = { · 18 unmodified lines | ||
| 1775 | 1787 | .out_rot_en_w = 1280, |
| 1776 | 1788 | .out_rot_dis_w = 1920, |
| 1777 | 1789 | }, |
| 1790 | + [3] = { | |
| 1791 | + .scaler_en_w = 1920, | |
| 1792 | + .scaler_dis_w = 8192, | |
| 1793 | + .in_rot_en_h = 1366, | |
| 1794 | + .in_rot_dis_w = 8192, | |
| 1795 | + .out_rot_en_w = 1366, | |
| 1796 | + .out_rot_dis_w = 1920, | |
| 1797 | + }, | |
| 1778 | 1798 | }; |
| 1779 | 1799 | |
| 1780 | 1800 | static struct samsung_fimc_variant fimc0_variant_s5p = { |
| @@ -1827,7 +1847,7 @@ static struct samsung_fimc_variant fimc2_variant_s5pv210 = { · 46 unmodified lines | ||
| 1827 | 1847 | .pix_limit = &s5p_pix_limit[2], |
| 1828 | 1848 | }; |
| 1829 | 1849 | |
| 1830 | −static struct samsung_fimc_variant fimc0_variant_s5pv310 = { | |
| 1850 | +static struct samsung_fimc_variant fimc0_variant_exynos4 = { | |
| 1831 | 1851 | .pix_hoff = 1, |
| 1832 | 1852 | .has_inp_rot = 1, |
| 1833 | 1853 | .has_out_rot = 1, |
| @@ -1840,7 +1860,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = { · 6 unmodified lines | ||
| 1840 | 1860 | .pix_limit = &s5p_pix_limit[1], |
| 1841 | 1861 | }; |
| 1842 | 1862 | |
| 1843 | −static struct samsung_fimc_variant fimc2_variant_s5pv310 = { | |
| 1863 | +static struct samsung_fimc_variant fimc2_variant_exynos4 = { | |
| 1844 | 1864 | .pix_hoff = 1, |
| 1845 | 1865 | .has_cistatus2 = 1, |
| 1846 | 1866 | .has_mainscaler_ext = 1, |
| @@ -1848,7 +1868,7 @@ static struct samsung_fimc_variant fimc2_variant_s5pv310 = { · 1 unmodified line | ||
| 1848 | 1868 | .min_out_pixsize = 16, |
| 1849 | 1869 | .hor_offs_align = 1, |
| 1850 | 1870 | .out_buf_count = 32, |
| 1851 | − .pix_limit = &s5p_pix_limit[2], | |
| 1871 | + .pix_limit = &s5p_pix_limit[3], | |
| 1852 | 1872 | }; |
| 1853 | 1873 | |
| 1854 | 1874 | /* S5PC100 */ |
| @@ -1874,12 +1894,12 @@ static struct samsung_fimc_driverdata fimc_drvdata_s5pv210 = { · 19 unmodified lines | ||
| 1874 | 1894 | }; |
| 1875 | 1895 | |
| 1876 | 1896 | /* S5PV310, S5PC210 */ |
| 1877 | −static struct samsung_fimc_driverdata fimc_drvdata_s5pv310 = { | |
| 1897 | +static struct samsung_fimc_driverdata fimc_drvdata_exynos4 = { | |
| 1878 | 1898 | .variant = { |
| 1879 | − [0] = &fimc0_variant_s5pv310, | |
| 1880 | − [1] = &fimc0_variant_s5pv310, | |
| 1881 | − [2] = &fimc0_variant_s5pv310, | |
| 1882 | − [3] = &fimc2_variant_s5pv310, | |
| 1899 | + [0] = &fimc0_variant_exynos4, | |
| 1900 | + [1] = &fimc0_variant_exynos4, | |
| 1901 | + [2] = &fimc0_variant_exynos4, | |
| 1902 | + [3] = &fimc2_variant_exynos4, | |
| 1883 | 1903 | }, |
| 1884 | 1904 | .num_entities = 4, |
| 1885 | 1905 | .lclk_frequency = 166000000UL, |
| @@ -1893,8 +1913,8 @@ static struct platform_device_id fimc_driver_ids[] = { · 7 unmodified lines | ||
| 1893 | 1913 | .name = "s5pv210-fimc", |
| 1894 | 1914 | .driver_data = (unsigned long)&fimc_drvdata_s5pv210, |
| 1895 | 1915 | }, { |
| 1896 | − .name = "s5pv310-fimc", | |
| 1897 | − .driver_data = (unsigned long)&fimc_drvdata_s5pv310, | |
| 1916 | + .name = "exynos4-fimc", | |
| 1917 | + .driver_data = (unsigned long)&fimc_drvdata_exynos4, | |
| 1898 | 1918 | }, |
| 1899 | 1919 | {}, |
| 1900 | 1920 | }; |
| @@ -922,7 +922,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int · 921 unmodified lines | ||
| 922 | 922 | /* Try 2560x1920, 1280x960, 640x480, 320x240 */ |
| 923 | 923 | mf.width = 2560 >> shift; |
| 924 | 924 | mf.height = 1920 >> shift; |
| 925 | − ret = v4l2_device_call_until_err(sd->v4l2_dev, 0, video, | |
| 925 | + ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, | |
| 926 | 926 | s_mbus_fmt, &mf); |
| 927 | 927 | if (ret < 0) |
| 928 | 928 | return ret; |
| @@ -1224,7 +1224,7 @@ static int client_s_fmt(struct soc_camera_device *icd, · 295 unmodified lines | ||
| 1224 | 1224 | struct v4l2_cropcap cap; |
| 1225 | 1225 | int ret; |
| 1226 | 1226 | |
| 1227 | − ret = v4l2_device_call_until_err(sd->v4l2_dev, 0, video, | |
| 1227 | + ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, | |
| 1228 | 1228 | s_mbus_fmt, mf); |
| 1229 | 1229 | if (ret < 0) |
| 1230 | 1230 | return ret; |
| @@ -1254,7 +1254,7 @@ static int client_s_fmt(struct soc_camera_device *icd, · 23 unmodified lines | ||
| 1254 | 1254 | tmp_h = min(2 * tmp_h, max_height); |
| 1255 | 1255 | mf->width = tmp_w; |
| 1256 | 1256 | mf->height = tmp_h; |
| 1257 | − ret = v4l2_device_call_until_err(sd->v4l2_dev, 0, video, | |
| 1257 | + ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, | |
| 1258 | 1258 | s_mbus_fmt, mf); |
| 1259 | 1259 | dev_geo(dev, "Camera scaled to %ux%u\n", |
| 1260 | 1260 | mf->width, mf->height); |
| @@ -1658,7 +1658,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, · 397 unmodified lines | ||
| 1658 | 1658 | mf.code = xlate->code; |
| 1659 | 1659 | mf.colorspace = pix->colorspace; |
| 1660 | 1660 | |
| 1661 | − ret = v4l2_device_call_until_err(sd->v4l2_dev, 0, video, try_mbus_fmt, &mf); | |
| 1661 | + ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, try_mbus_fmt, &mf); | |
| 1662 | 1662 | if (ret < 0) |
| 1663 | 1663 | return ret; |
| 1664 | 1664 | |
| @@ -1682,7 +1682,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, · 17 unmodified lines | ||
| 1682 | 1682 | */ |
| 1683 | 1683 | mf.width = 2560; |
| 1684 | 1684 | mf.height = 1920; |
| 1685 | − ret = v4l2_device_call_until_err(sd->v4l2_dev, 0, video, | |
| 1685 | + ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, | |
| 1686 | 1686 | try_mbus_fmt, &mf); |
| 1687 | 1687 | if (ret < 0) { |
| 1688 | 1688 | /* Shouldn't actually happen... */ |
| @@ -38,6 +38,8 @@ struct sh_csi2 { · 37 unmodified lines | ||
| 38 | 38 | void __iomem *base; |
| 39 | 39 | struct platform_device *pdev; |
| 40 | 40 | struct sh_csi2_client_config *client; |
| 41 | + unsigned long (*query_bus_param)(struct soc_camera_device *); | |
| 42 | + int (*set_bus_param)(struct soc_camera_device *, unsigned long); | |
| 41 | 43 | }; |
| 42 | 44 | |
| 43 | 45 | static int sh_csi2_try_fmt(struct v4l2_subdev *sd, |
| @@ -208,6 +210,7 @@ static int sh_csi2_notify(struct notifier_block *nb, · 164 unmodified lines | ||
| 208 | 210 | case BUS_NOTIFY_BOUND_DRIVER: |
| 209 | 211 | snprintf(priv->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s%s", |
| 210 | 212 | dev_name(v4l2_dev->dev), ".mipi-csi"); |
| 213 | + priv->subdev.grp_id = (long)icd; | |
| 211 | 214 | ret = v4l2_device_register_subdev(v4l2_dev, &priv->subdev); |
| 212 | 215 | dev_dbg(dev, "%s(%p): ret(register_subdev) = %d\n", __func__, priv, ret); |
| 213 | 216 | if (ret < 0) |
| @@ -215,6 +218,8 @@ static int sh_csi2_notify(struct notifier_block *nb, · 1 unmodified line | ||
| 215 | 218 | |
| 216 | 219 | priv->client = pdata->clients + i; |
| 217 | 220 | |
| 221 | + priv->set_bus_param = icd->ops->set_bus_param; | |
| 222 | + priv->query_bus_param = icd->ops->query_bus_param; | |
| 218 | 223 | icd->ops->set_bus_param = sh_csi2_set_bus_param; |
| 219 | 224 | icd->ops->query_bus_param = sh_csi2_query_bus_param; |
| 220 | 225 | |
| @@ -226,8 +231,10 @@ static int sh_csi2_notify(struct notifier_block *nb, · 5 unmodified lines | ||
| 226 | 231 | priv->client = NULL; |
| 227 | 232 | |
| 228 | 233 | /* Driver is about to be unbound */ |
| 229 | − icd->ops->set_bus_param = NULL; | |
| 230 | − icd->ops->query_bus_param = NULL; | |
| 234 | + icd->ops->set_bus_param = priv->set_bus_param; | |
| 235 | + icd->ops->query_bus_param = priv->query_bus_param; | |
| 236 | + priv->set_bus_param = NULL; | |
| 237 | + priv->query_bus_param = NULL; | |
| 231 | 238 | |
| 232 | 239 | v4l2_device_unregister_subdev(&priv->subdev); |
| 233 | 240 | |
| @@ -136,11 +136,50 @@ unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl, · 135 unmodified lines | ||
| 136 | 136 | } |
| 137 | 137 | EXPORT_SYMBOL(soc_camera_apply_sensor_flags); |
| 138 | 138 | |
| 139 | +#define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \ | |
| 140 | + ((x) >> 24) & 0xff | |
| 141 | + | |
| 142 | +static int soc_camera_try_fmt(struct soc_camera_device *icd, | |
| 143 | + struct v4l2_format *f) | |
| 144 | +{ | |
| 145 | + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | |
| 146 | + struct v4l2_pix_format *pix = &f->fmt.pix; | |
| 147 | + int ret; | |
| 148 | + | |
| 149 | + dev_dbg(&icd->dev, "TRY_FMT(%c%c%c%c, %ux%u)\n", | |
| 150 | + pixfmtstr(pix->pixelformat), pix->width, pix->height); | |
| 151 | + | |
| 152 | + pix->bytesperline = 0; | |
| 153 | + pix->sizeimage = 0; | |
| 154 | + | |
| 155 | + ret = ici->ops->try_fmt(icd, f); | |
| 156 | + if (ret < 0) | |
| 157 | + return ret; | |
| 158 | + | |
| 159 | + if (!pix->sizeimage) { | |
| 160 | + if (!pix->bytesperline) { | |
| 161 | + const struct soc_camera_format_xlate *xlate; | |
| 162 | + | |
| 163 | + xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); | |
| 164 | + if (!xlate) | |
| 165 | + return -EINVAL; | |
| 166 | + | |
| 167 | + ret = soc_mbus_bytes_per_line(pix->width, | |
| 168 | + xlate->host_fmt); | |
| 169 | + if (ret > 0) | |
| 170 | + pix->bytesperline = ret; | |
| 171 | + } | |
| 172 | + if (pix->bytesperline) | |
| 173 | + pix->sizeimage = pix->bytesperline * pix->height; | |
| 174 | + } | |
| 175 | + | |
| 176 | + return 0; | |
| 177 | +} | |
| 178 | + | |
| 139 | 179 | static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv, |
| 140 | 180 | struct v4l2_format *f) |
| 141 | 181 | { |
| 142 | 182 | struct soc_camera_device *icd = file->private_data; |
| 143 | − struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | |
| 144 | 183 | |
| 145 | 184 | WARN_ON(priv != file->private_data); |
| 146 | 185 | |
| @@ -149,7 +188,7 @@ static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv, · 2 unmodified lines | ||
| 149 | 188 | return -EINVAL; |
| 150 | 189 | |
| 151 | 190 | /* limit format to hardware capabilities */ |
| 152 | − return ici->ops->try_fmt(icd, f); | |
| 191 | + return soc_camera_try_fmt(icd, f); | |
| 153 | 192 | } |
| 154 | 193 | |
| 155 | 194 | static int soc_camera_enum_input(struct file *file, void *priv, |
| @@ -362,9 +401,6 @@ static void soc_camera_free_user_formats(struct soc_camera_device *icd) · 206 unmodified lines | ||
| 362 | 401 | icd->user_formats = NULL; |
| 363 | 402 | } |
| 364 | 403 | |
| 365 | −#define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \ | |
| 366 | − ((x) >> 24) & 0xff | |
| 367 | − | |
| 368 | 404 | /* Called with .vb_lock held, or from the first open(2), see comment there */ |
| 369 | 405 | static int soc_camera_set_fmt(struct soc_camera_device *icd, |
| 370 | 406 | struct v4l2_format *f) |
| @@ -377,7 +413,7 @@ static int soc_camera_set_fmt(struct soc_camera_device *icd, · 6 unmodified lines | ||
| 377 | 413 | pixfmtstr(pix->pixelformat), pix->width, pix->height); |
| 378 | 414 | |
| 379 | 415 | /* We always call try_fmt() before set_fmt() or set_crop() */ |
| 380 | − ret = ici->ops->try_fmt(icd, f); | |
| 416 | + ret = soc_camera_try_fmt(icd, f); | |
| 381 | 417 | if (ret < 0) |
| 382 | 418 | return ret; |
| 383 | 419 | |
| @@ -996,10 +1032,11 @@ static void soc_camera_free_i2c(struct soc_camera_device *icd) · 612 unmodified lines | ||
| 996 | 1032 | { |
| 997 | 1033 | struct i2c_client *client = |
| 998 | 1034 | to_i2c_client(to_soc_camera_control(icd)); |
| 1035 | + struct i2c_adapter *adap = client->adapter; | |
| 999 | 1036 | dev_set_drvdata(&icd->dev, NULL); |
| 1000 | 1037 | v4l2_device_unregister_subdev(i2c_get_clientdata(client)); |
| 1001 | 1038 | i2c_unregister_device(client); |
| 1002 | − i2c_put_adapter(client->adapter); | |
| 1039 | + i2c_put_adapter(adap); | |
| 1003 | 1040 | } |
| 1004 | 1041 | #else |
| 1005 | 1042 | #define soc_camera_init_i2c(icd, icl) (-ENODEV) |
| @@ -1071,6 +1108,9 @@ static int soc_camera_probe(struct device *dev) · 65 unmodified lines | ||
| 1071 | 1108 | } |
| 1072 | 1109 | } |
| 1073 | 1110 | |
| 1111 | + sd = soc_camera_to_subdev(icd); | |
| 1112 | + sd->grp_id = (long)icd; | |
| 1113 | + | |
| 1074 | 1114 | /* At this point client .probe() should have run already */ |
| 1075 | 1115 | ret = soc_camera_init_user_formats(icd); |
| 1076 | 1116 | if (ret < 0) |
| @@ -1092,7 +1132,6 @@ static int soc_camera_probe(struct device *dev) · 15 unmodified lines | ||
| 1092 | 1132 | goto evidstart; |
| 1093 | 1133 | |
| 1094 | 1134 | /* Try to improve our guess of a reasonable window format */ |
| 1095 | − sd = soc_camera_to_subdev(icd); | |
| 1096 | 1135 | if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) { |
| 1097 | 1136 | icd->user_width = mf.width; |
| 1098 | 1137 | icd->user_height = mf.height; |
| @@ -171,7 +171,7 @@ static int tda9840_probe(struct i2c_client *client, · 170 unmodified lines | ||
| 171 | 171 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
| 172 | 172 | client->addr << 1, client->adapter->name); |
| 173 | 173 | |
| 174 | − sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); | |
| 174 | + sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); | |
| 175 | 175 | if (sd == NULL) |
| 176 | 176 | return -ENOMEM; |
| 177 | 177 | v4l2_i2c_subdev_init(sd, client, &tda9840_ops); |
| @@ -152,7 +152,7 @@ static int tea6415c_probe(struct i2c_client *client, · 151 unmodified lines | ||
| 152 | 152 | |
| 153 | 153 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
| 154 | 154 | client->addr << 1, client->adapter->name); |
| 155 | − sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); | |
| 155 | + sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); | |
| 156 | 156 | if (sd == NULL) |
| 157 | 157 | return -ENOMEM; |
| 158 | 158 | v4l2_i2c_subdev_init(sd, client, &tea6415c_ops); |
| @@ -125,7 +125,7 @@ static int tea6420_probe(struct i2c_client *client, · 124 unmodified lines | ||
| 125 | 125 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
| 126 | 126 | client->addr << 1, client->adapter->name); |
| 127 | 127 | |
| 128 | − sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); | |
| 128 | + sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); | |
| 129 | 129 | if (sd == NULL) |
| 130 | 130 | return -ENOMEM; |
| 131 | 131 | v4l2_i2c_subdev_init(sd, client, &tea6420_ops); |
| @@ -230,7 +230,7 @@ static int upd64031a_probe(struct i2c_client *client, · 229 unmodified lines | ||
| 230 | 230 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
| 231 | 231 | client->addr << 1, client->adapter->name); |
| 232 | 232 | |
| 233 | − state = kmalloc(sizeof(struct upd64031a_state), GFP_KERNEL); | |
| 233 | + state = kzalloc(sizeof(struct upd64031a_state), GFP_KERNEL); | |
| 234 | 234 | if (state == NULL) |
| 235 | 235 | return -ENOMEM; |
| 236 | 236 | sd = &state->sd; |
| @@ -202,7 +202,7 @@ static int upd64083_probe(struct i2c_client *client, · 201 unmodified lines | ||
| 202 | 202 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
| 203 | 203 | client->addr << 1, client->adapter->name); |
| 204 | 204 | |
| 205 | − state = kmalloc(sizeof(struct upd64083_state), GFP_KERNEL); | |
| 205 | + state = kzalloc(sizeof(struct upd64083_state), GFP_KERNEL); | |
| 206 | 206 | if (state == NULL) |
| 207 | 207 | return -ENOMEM; |
| 208 | 208 | sd = &state->sd; |
| @@ -389,7 +389,8 @@ static int v4l2_open(struct inode *inode, struct file *filp) · 388 unmodified lines | ||
| 389 | 389 | video_get(vdev); |
| 390 | 390 | mutex_unlock(&videodev_lock); |
| 391 | 391 | #if defined(CONFIG_MEDIA_CONTROLLER) |
| 392 | − if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) { | |
| 392 | + if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && | |
| 393 | + vdev->vfl_type != VFL_TYPE_SUBDEV) { | |
| 393 | 394 | entity = media_entity_get(&vdev->entity); |
| 394 | 395 | if (!entity) { |
| 395 | 396 | ret = -EBUSY; |
| @@ -415,7 +416,8 @@ err: · 19 unmodified lines | ||
| 415 | 416 | /* decrease the refcount in case of an error */ |
| 416 | 417 | if (ret) { |
| 417 | 418 | #if defined(CONFIG_MEDIA_CONTROLLER) |
| 418 | − if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) | |
| 419 | + if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && | |
| 420 | + vdev->vfl_type != VFL_TYPE_SUBDEV) | |
| 419 | 421 | media_entity_put(entity); |
| 420 | 422 | #endif |
| 421 | 423 | video_put(vdev); |
| @@ -437,7 +439,8 @@ static int v4l2_release(struct inode *inode, struct file *filp) · 15 unmodified lines | ||
| 437 | 439 | mutex_unlock(vdev->lock); |
| 438 | 440 | } |
| 439 | 441 | #if defined(CONFIG_MEDIA_CONTROLLER) |
| 440 | − if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) | |
| 442 | + if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && | |
| 443 | + vdev->vfl_type != VFL_TYPE_SUBDEV) | |
| 441 | 444 | media_entity_put(&vdev->entity); |
| 442 | 445 | #endif |
| 443 | 446 | /* decrease the refcount unconditionally since the release() |
| @@ -686,7 +689,8 @@ int __video_register_device(struct video_device *vdev, int type, int nr, · 242 unmodified lines | ||
| 686 | 689 | |
| 687 | 690 | #if defined(CONFIG_MEDIA_CONTROLLER) |
| 688 | 691 | /* Part 5: Register the entity. */ |
| 689 | − if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) { | |
| 692 | + if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && | |
| 693 | + vdev->vfl_type != VFL_TYPE_SUBDEV) { | |
| 690 | 694 | vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L; |
| 691 | 695 | vdev->entity.name = vdev->name; |
| 692 | 696 | vdev->entity.v4l.major = VIDEO_MAJOR; |
| @@ -733,7 +737,8 @@ void video_unregister_device(struct video_device *vdev) · 40 unmodified lines | ||
| 733 | 737 | return; |
| 734 | 738 | |
| 735 | 739 | #if defined(CONFIG_MEDIA_CONTROLLER) |
| 736 | − if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) | |
| 740 | + if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && | |
| 741 | + vdev->vfl_type != VFL_TYPE_SUBDEV) | |
| 737 | 742 | media_device_unregister_entity(&vdev->entity); |
| 738 | 743 | #endif |
| 739 | 744 | |
| @@ -155,8 +155,10 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, · 154 unmodified lines | ||
| 155 | 155 | sd->v4l2_dev = v4l2_dev; |
| 156 | 156 | if (sd->internal_ops && sd->internal_ops->registered) { |
| 157 | 157 | err = sd->internal_ops->registered(sd); |
| 158 | − if (err) | |
| 158 | + if (err) { | |
| 159 | + module_put(sd->owner); | |
| 159 | 160 | return err; |
| 161 | + } | |
| 160 | 162 | } |
| 161 | 163 | |
| 162 | 164 | /* This just returns 0 if either of the two args is NULL */ |
| @@ -164,6 +166,7 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, · 1 unmodified line | ||
| 164 | 166 | if (err) { |
| 165 | 167 | if (sd->internal_ops && sd->internal_ops->unregistered) |
| 166 | 168 | sd->internal_ops->unregistered(sd); |
| 169 | + module_put(sd->owner); | |
| 167 | 170 | return err; |
| 168 | 171 | } |
| 169 | 172 | |
| @@ -155,25 +155,25 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) · 154 unmodified lines | ||
| 155 | 155 | |
| 156 | 156 | switch (cmd) { |
| 157 | 157 | case VIDIOC_QUERYCTRL: |
| 158 | − return v4l2_subdev_queryctrl(sd, arg); | |
| 158 | + return v4l2_queryctrl(sd->ctrl_handler, arg); | |
| 159 | 159 | |
| 160 | 160 | case VIDIOC_QUERYMENU: |
| 161 | − return v4l2_subdev_querymenu(sd, arg); | |
| 161 | + return v4l2_querymenu(sd->ctrl_handler, arg); | |
| 162 | 162 | |
| 163 | 163 | case VIDIOC_G_CTRL: |
| 164 | − return v4l2_subdev_g_ctrl(sd, arg); | |
| 164 | + return v4l2_g_ctrl(sd->ctrl_handler, arg); | |
| 165 | 165 | |
| 166 | 166 | case VIDIOC_S_CTRL: |
| 167 | − return v4l2_subdev_s_ctrl(sd, arg); | |
| 167 | + return v4l2_s_ctrl(sd->ctrl_handler, arg); | |
| 168 | 168 | |
| 169 | 169 | case VIDIOC_G_EXT_CTRLS: |
| 170 | − return v4l2_subdev_g_ext_ctrls(sd, arg); | |
| 170 | + return v4l2_g_ext_ctrls(sd->ctrl_handler, arg); | |
| 171 | 171 | |
| 172 | 172 | case VIDIOC_S_EXT_CTRLS: |
| 173 | − return v4l2_subdev_s_ext_ctrls(sd, arg); | |
| 173 | + return v4l2_s_ext_ctrls(sd->ctrl_handler, arg); | |
| 174 | 174 | |
| 175 | 175 | case VIDIOC_TRY_EXT_CTRLS: |
| 176 | − return v4l2_subdev_try_ext_ctrls(sd, arg); | |
| 176 | + return v4l2_try_ext_ctrls(sd->ctrl_handler, arg); | |
| 177 | 177 | |
| 178 | 178 | case VIDIOC_DQEVENT: |
| 179 | 179 | if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS)) |
| @@ -300,7 +300,7 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q, · 299 unmodified lines | ||
| 300 | 300 | |
| 301 | 301 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
| 302 | 302 | retval = remap_pfn_range(vma, vma->vm_start, |
| 303 | − PFN_DOWN(virt_to_phys(mem->vaddr)), | |
| 303 | + mem->dma_handle >> PAGE_SHIFT, | |
| 304 | 304 | size, vma->vm_page_prot); |
| 305 | 305 | if (retval) { |
| 306 | 306 | dev_err(q->dev, "mmap: remap failed with error %d. ", retval); |
| @@ -37,6 +37,9 @@ module_param(debug, int, 0644); · 36 unmodified lines | ||
| 37 | 37 | #define call_qop(q, op, args...) \ |
| 38 | 38 | (((q)->ops->op) ? ((q)->ops->op(args)) : 0) |
| 39 | 39 | |
| 40 | +#define V4L2_BUFFER_STATE_FLAGS (V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | \ | |
| 41 | + V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR) | |
| 42 | + | |
| 40 | 43 | /** |
| 41 | 44 | * __vb2_buf_mem_alloc() - allocate video memory for the given buffer |
| 42 | 45 | */ |
| @@ -51,7 +54,7 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb, · 8 unmodified lines | ||
| 51 | 54 | for (plane = 0; plane < vb->num_planes; ++plane) { |
| 52 | 55 | mem_priv = call_memop(q, plane, alloc, q->alloc_ctx[plane], |
| 53 | 56 | plane_sizes[plane]); |
| 54 | − if (!mem_priv) | |
| 57 | + if (IS_ERR_OR_NULL(mem_priv)) | |
| 55 | 58 | goto free; |
| 56 | 59 | |
| 57 | 60 | /* Associate allocator private data with this plane */ |
| @@ -284,7 +287,7 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) · 226 unmodified lines | ||
| 284 | 287 | struct vb2_queue *q = vb->vb2_queue; |
| 285 | 288 | int ret = 0; |
| 286 | 289 | |
| 287 | − /* Copy back data such as timestamp, input, etc. */ | |
| 290 | + /* Copy back data such as timestamp, flags, input, etc. */ | |
| 288 | 291 | memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m)); |
| 289 | 292 | b->input = vb->v4l2_buf.input; |
| 290 | 293 | b->reserved = vb->v4l2_buf.reserved; |
| @@ -313,7 +316,10 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) · 22 unmodified lines | ||
| 313 | 316 | b->m.userptr = vb->v4l2_planes[0].m.userptr; |
| 314 | 317 | } |
| 315 | 318 | |
| 316 | − b->flags = 0; | |
| 319 | + /* | |
| 320 | + * Clear any buffer state related flags. | |
| 321 | + */ | |
| 322 | + b->flags &= ~V4L2_BUFFER_STATE_FLAGS; | |
| 317 | 323 | |
| 318 | 324 | switch (vb->state) { |
| 319 | 325 | case VB2_BUF_STATE_QUEUED: |
| @@ -519,6 +525,7 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) · 199 unmodified lines | ||
| 519 | 525 | num_buffers = min_t(unsigned int, req->count, VIDEO_MAX_FRAME); |
| 520 | 526 | memset(plane_sizes, 0, sizeof(plane_sizes)); |
| 521 | 527 | memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx)); |
| 528 | + q->memory = req->memory; | |
| 522 | 529 | |
| 523 | 530 | /* |
| 524 | 531 | * Ask the driver how many buffers and planes per buffer it requires. |
| @@ -560,8 +567,6 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) · 35 unmodified lines | ||
| 560 | 567 | ret = num_buffers; |
| 561 | 568 | } |
| 562 | 569 | |
| 563 | − q->memory = req->memory; | |
| 564 | − | |
| 565 | 570 | /* |
| 566 | 571 | * Return the number of successfully allocated buffers |
| 567 | 572 | * to the userspace. |
| @@ -715,6 +720,8 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b, · 147 unmodified lines | ||
| 715 | 720 | |
| 716 | 721 | vb->v4l2_buf.field = b->field; |
| 717 | 722 | vb->v4l2_buf.timestamp = b->timestamp; |
| 723 | + vb->v4l2_buf.input = b->input; | |
| 724 | + vb->v4l2_buf.flags = b->flags & ~V4L2_BUFFER_STATE_FLAGS; | |
| 718 | 725 | |
| 719 | 726 | return 0; |
| 720 | 727 | } |
| @@ -46,7 +46,7 @@ static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size) · 45 unmodified lines | ||
| 46 | 46 | GFP_KERNEL); |
| 47 | 47 | if (!buf->vaddr) { |
| 48 | 48 | dev_err(conf->dev, "dma_alloc_coherent of size %ld failed\n", |
| 49 | − buf->size); | |
| 49 | + size); | |
| 50 | 50 | kfree(buf); |
| 51 | 51 | return ERR_PTR(-ENOMEM); |
| 52 | 52 | } |
| @@ -1000,7 +1000,6 @@ static struct i2o_block_device *i2o_block_device_alloc(void) · 999 unmodified lines | ||
| 1000 | 1000 | gd->major = I2O_MAJOR; |
| 1001 | 1001 | gd->queue = queue; |
| 1002 | 1002 | gd->fops = &i2o_block_fops; |
| 1003 | − gd->events = DISK_EVENT_MEDIA_CHANGE; | |
| 1004 | 1003 | gd->private_data = dev; |
| 1005 | 1004 | |
| 1006 | 1005 | dev->gd = gd; |
| @@ -144,7 +144,7 @@ static void asic3_irq_demux(unsigned int irq, struct irq_desc *desc) · 143 unmodified lines | ||
| 144 | 144 | int iter, i; |
| 145 | 145 | unsigned long flags; |
| 146 | 146 | |
| 147 | − data->chip->irq_ack(irq_data); | |
| 147 | + data->chip->irq_ack(data); | |
| 148 | 148 | |
| 149 | 149 | for (iter = 0 ; iter < MAX_ASIC_ISR_LOOPS; iter++) { |
| 150 | 150 | u32 status; |
| @@ -25,7 +25,6 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <linux/dma-mapping.h> |
| 26 | 26 | #include <linux/spinlock.h> |
| 27 | 27 | #include <linux/gpio.h> |
| 28 | −#include <linux/regulator/consumer.h> | |
| 29 | 28 | #include <plat/usb.h> |
| 30 | 29 | |
| 31 | 30 | #define USBHS_DRIVER_NAME "usbhs-omap" |
| @@ -700,8 +699,7 @@ static int usbhs_enable(struct device *dev) · 668 unmodified lines | ||
| 700 | 699 | dev_dbg(dev, "starting TI HSUSB Controller\n"); |
| 701 | 700 | if (!pdata) { |
| 702 | 701 | dev_dbg(dev, "missing platform_data\n"); |
| 703 | − ret = -ENODEV; | |
| 704 | − goto end_enable; | |
| 702 | + return -ENODEV; | |
| 705 | 703 | } |
| 706 | 704 | |
| 707 | 705 | spin_lock_irqsave(&omap->lock, flags); |
| @@ -719,14 +717,14 @@ static int usbhs_enable(struct device *dev) · 11 unmodified lines | ||
| 719 | 717 | gpio_request(pdata->ehci_data->reset_gpio_port[0], |
| 720 | 718 | "USB1 PHY reset"); |
| 721 | 719 | gpio_direction_output |
| 722 | − (pdata->ehci_data->reset_gpio_port[0], 1); | |
| 720 | + (pdata->ehci_data->reset_gpio_port[0], 0); | |
| 723 | 721 | } |
| 724 | 722 | |
| 725 | 723 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) { |
| 726 | 724 | gpio_request(pdata->ehci_data->reset_gpio_port[1], |
| 727 | 725 | "USB2 PHY reset"); |
| 728 | 726 | gpio_direction_output |
| 729 | − (pdata->ehci_data->reset_gpio_port[1], 1); | |
| 727 | + (pdata->ehci_data->reset_gpio_port[1], 0); | |
| 730 | 728 | } |
| 731 | 729 | |
| 732 | 730 | /* Hold the PHY in RESET for enough time till DIR is high */ |
| @@ -906,16 +904,17 @@ static int usbhs_enable(struct device *dev) · 173 unmodified lines | ||
| 906 | 904 | |
| 907 | 905 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) |
| 908 | 906 | gpio_set_value |
| 909 | − (pdata->ehci_data->reset_gpio_port[0], 0); | |
| 907 | + (pdata->ehci_data->reset_gpio_port[0], 1); | |
| 910 | 908 | |
| 911 | 909 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) |
| 912 | 910 | gpio_set_value |
| 913 | − (pdata->ehci_data->reset_gpio_port[1], 0); | |
| 911 | + (pdata->ehci_data->reset_gpio_port[1], 1); | |
| 914 | 912 | } |
| 915 | 913 | |
| 916 | 914 | end_count: |
| 917 | 915 | omap->count++; |
| 918 | − goto end_enable; | |
| 916 | + spin_unlock_irqrestore(&omap->lock, flags); | |
| 917 | + return 0; | |
| 919 | 918 | |
| 920 | 919 | err_tll: |
| 921 | 920 | if (pdata->ehci_data->phy_reset) { |
| @@ -931,8 +930,6 @@ err_tll: · 9 unmodified lines | ||
| 931 | 930 | clk_disable(omap->usbhost_fs_fck); |
| 932 | 931 | clk_disable(omap->usbhost_hs_fck); |
| 933 | 932 | clk_disable(omap->usbhost_ick); |
| 934 | − | |
| 935 | −end_enable: | |
| 936 | 933 | spin_unlock_irqrestore(&omap->lock, flags); |
| 937 | 934 | return ret; |
| 938 | 935 | } |
| @@ -447,12 +447,13 @@ static int __init load_twl4030_script(struct twl4030_script *tscript, · 446 unmodified lines | ||
| 447 | 447 | if (err) |
| 448 | 448 | goto out; |
| 449 | 449 | } |
| 450 | − if (tscript->flags & TWL4030_SLEEP_SCRIPT) | |
| 450 | + if (tscript->flags & TWL4030_SLEEP_SCRIPT) { | |
| 451 | 451 | if (order) |
| 452 | 452 | pr_warning("TWL4030: Bad order of scripts (sleep "\ |
| 453 | 453 | "script before wakeup) Leads to boot"\ |
| 454 | 454 | "failure on some boards\n"); |
| 455 | 455 | err = twl4030_config_sleep_sequence(address); |
| 456 | + } | |
| 456 | 457 | out: |
| 457 | 458 | return err; |
| 458 | 459 | } |
| @@ -284,6 +284,7 @@ int mmc_add_card(struct mmc_card *card) · 283 unmodified lines | ||
| 284 | 284 | type = "SD-combo"; |
| 285 | 285 | if (mmc_card_blockaddr(card)) |
| 286 | 286 | type = "SDHC-combo"; |
| 287 | + break; | |
| 287 | 288 | default: |
| 288 | 289 | type = "?"; |
| 289 | 290 | break; |
| @@ -832,7 +832,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) · 831 unmodified lines | ||
| 832 | 832 | return IRQ_HANDLED; |
| 833 | 833 | } |
| 834 | 834 | |
| 835 | − if (end_command) | |
| 835 | + if (end_command && host->cmd) | |
| 836 | 836 | mmc_omap_cmd_done(host, host->cmd); |
| 837 | 837 | if (host->data != NULL) { |
| 838 | 838 | if (transfer_error) |
| @@ -124,8 +124,10 @@ static bool __devinit sdhci_of_wp_inverted(struct device_node *np) · 123 unmodified lines | ||
| 124 | 124 | #endif |
| 125 | 125 | } |
| 126 | 126 | |
| 127 | +static const struct of_device_id sdhci_of_match[]; | |
| 127 | 128 | static int __devinit sdhci_of_probe(struct platform_device *ofdev) |
| 128 | 129 | { |
| 130 | + const struct of_device_id *match; | |
| 129 | 131 | struct device_node *np = ofdev->dev.of_node; |
| 130 | 132 | struct sdhci_of_data *sdhci_of_data; |
| 131 | 133 | struct sdhci_host *host; |
| @@ -134,9 +136,10 @@ static int __devinit sdhci_of_probe(struct platform_device *ofdev) · 2 unmodified lines | ||
| 134 | 136 | int size; |
| 135 | 137 | int ret; |
| 136 | 138 | |
| 137 | − if (!ofdev->dev.of_match) | |
| 139 | + match = of_match_device(sdhci_of_match, &ofdev->dev); | |
| 140 | + if (!match) | |
| 138 | 141 | return -EINVAL; |
| 139 | − sdhci_of_data = ofdev->dev.of_match->data; | |
| 142 | + sdhci_of_data = match->data; | |
| 140 | 143 | |
| 141 | 144 | if (!of_device_is_available(np)) |
| 142 | 145 | return -ENODEV; |
| @@ -957,6 +957,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( · 956 unmodified lines | ||
| 957 | 957 | host->ioaddr = pci_ioremap_bar(pdev, bar); |
| 958 | 958 | if (!host->ioaddr) { |
| 959 | 959 | dev_err(&pdev->dev, "failed to remap registers\n"); |
| 960 | + ret = -ENOMEM; | |
| 960 | 961 | goto release; |
| 961 | 962 | } |
| 962 | 963 | |
| @@ -1334,6 +1334,13 @@ static void sdhci_tasklet_finish(unsigned long param) · 1333 unmodified lines | ||
| 1334 | 1334 | |
| 1335 | 1335 | host = (struct sdhci_host*)param; |
| 1336 | 1336 | |
| 1337 | + /* | |
| 1338 | + * If this tasklet gets rescheduled while running, it will | |
| 1339 | + * be run again afterwards but without any active request. | |
| 1340 | + */ | |
| 1341 | + if (!host->mrq) | |
| 1342 | + return; | |
| 1343 | + | |
| 1337 | 1344 | spin_lock_irqsave(&host->lock, flags); |
| 1338 | 1345 | |
| 1339 | 1346 | del_timer(&host->timer); |
| @@ -1345,7 +1352,7 @@ static void sdhci_tasklet_finish(unsigned long param) · 5 unmodified lines | ||
| 1345 | 1352 | * upon error conditions. |
| 1346 | 1353 | */ |
| 1347 | 1354 | if (!(host->flags & SDHCI_DEVICE_DEAD) && |
| 1348 | − (mrq->cmd->error || | |
| 1355 | + ((mrq->cmd && mrq->cmd->error) || | |
| 1349 | 1356 | (mrq->data && (mrq->data->error || |
| 1350 | 1357 | (mrq->data->stop && mrq->data->stop->error))) || |
| 1351 | 1358 | (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST))) { |
| @@ -728,15 +728,15 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) · 727 unmodified lines | ||
| 728 | 728 | tmio_mmc_set_clock(host, ios->clock); |
| 729 | 729 | |
| 730 | 730 | /* Power sequence - OFF -> UP -> ON */ |
| 731 | − if (ios->power_mode == MMC_POWER_OFF || !ios->clock) { | |
| 731 | + if (ios->power_mode == MMC_POWER_UP) { | |
| 732 | + /* power up SD bus */ | |
| 733 | + if (host->set_pwr) | |
| 734 | + host->set_pwr(host->pdev, 1); | |
| 735 | + } else if (ios->power_mode == MMC_POWER_OFF || !ios->clock) { | |
| 732 | 736 | /* power down SD bus */ |
| 733 | 737 | if (ios->power_mode == MMC_POWER_OFF && host->set_pwr) |
| 734 | 738 | host->set_pwr(host->pdev, 0); |
| 735 | 739 | tmio_mmc_clk_stop(host); |
| 736 | − } else if (ios->power_mode == MMC_POWER_UP) { | |
| 737 | − /* power up SD bus */ | |
| 738 | − if (host->set_pwr) | |
| 739 | − host->set_pwr(host->pdev, 1); | |
| 740 | 740 | } else { |
| 741 | 741 | /* start bus clock */ |
| 742 | 742 | tmio_mmc_clk_start(host); |
| @@ -214,11 +214,13 @@ static void __devinit of_free_probes(const char **probes) · 213 unmodified lines | ||
| 214 | 214 | } |
| 215 | 215 | #endif |
| 216 | 216 | |
| 217 | +static struct of_device_id of_flash_match[]; | |
| 217 | 218 | static int __devinit of_flash_probe(struct platform_device *dev) |
| 218 | 219 | { |
| 219 | 220 | #ifdef CONFIG_MTD_PARTITIONS |
| 220 | 221 | const char **part_probe_types; |
| 221 | 222 | #endif |
| 223 | + const struct of_device_id *match; | |
| 222 | 224 | struct device_node *dp = dev->dev.of_node; |
| 223 | 225 | struct resource res; |
| 224 | 226 | struct of_flash *info; |
| @@ -232,9 +234,10 @@ static int __devinit of_flash_probe(struct platform_device *dev) · 7 unmodified lines | ||
| 232 | 234 | struct mtd_info **mtd_list = NULL; |
| 233 | 235 | resource_size_t res_size; |
| 234 | 236 | |
| 235 | − if (!dev->dev.of_match) | |
| 237 | + match = of_match_device(of_flash_match, &dev->dev); | |
| 238 | + if (!match) | |
| 236 | 239 | return -EINVAL; |
| 237 | − probe_type = dev->dev.of_match->data; | |
| 240 | + probe_type = match->data; | |
| 238 | 241 | |
| 239 | 242 | reg_tuple_size = (of_n_addr_cells(dp) + of_n_size_cells(dp)) * sizeof(u32); |
| 240 | 243 | |
| @@ -400,7 +400,7 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr) · 399 unmodified lines | ||
| 400 | 400 | doc200x_hwcontrol(mtd, 0, NAND_CTRL_ALE | NAND_CTRL_CHANGE); |
| 401 | 401 | doc200x_hwcontrol(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); |
| 402 | 402 | |
| 403 | − /* We can't' use dev_ready here, but at least we wait for the | |
| 403 | + /* We can't use dev_ready here, but at least we wait for the | |
| 404 | 404 | * command to complete |
| 405 | 405 | */ |
| 406 | 406 | udelay(50); |
| @@ -2536,7 +2536,7 @@ config S6GMAC · 2535 unmodified lines | ||
| 2536 | 2536 | source "drivers/net/stmmac/Kconfig" |
| 2537 | 2537 | |
| 2538 | 2538 | config PCH_GBE |
| 2539 | − tristate "PCH Gigabit Ethernet" | |
| 2539 | + tristate "Intel EG20T PCH / OKI SEMICONDUCTOR ML7223 IOH GbE" | |
| 2540 | 2540 | depends on PCI |
| 2541 | 2541 | select MII |
| 2542 | 2542 | ---help--- |
| @@ -2548,6 +2548,12 @@ config PCH_GBE · 5 unmodified lines | ||
| 2548 | 2548 | to Gigabit Ethernet. |
| 2549 | 2549 | This driver enables Gigabit Ethernet function. |
| 2550 | 2550 | |
| 2551 | + This driver also can be used for OKI SEMICONDUCTOR IOH(Input/ | |
| 2552 | + Output Hub), ML7223. | |
| 2553 | + ML7223 IOH is for MP(Media Phone) use. | |
| 2554 | + ML7223 is companion chip for Intel Atom E6xx series. | |
| 2555 | + ML7223 is completely compatible for Intel EG20T PCH. | |
| 2556 | + | |
| 2551 | 2557 | endif # NETDEV_1000 |
| 2552 | 2558 | |
| 2553 | 2559 | # |
| @@ -144,7 +144,7 @@ obj-$(CONFIG_NE3210) += ne3210.o 8390.o · 143 unmodified lines | ||
| 144 | 144 | obj-$(CONFIG_SB1250_MAC) += sb1250-mac.o |
| 145 | 145 | obj-$(CONFIG_B44) += b44.o |
| 146 | 146 | obj-$(CONFIG_FORCEDETH) += forcedeth.o |
| 147 | −obj-$(CONFIG_NE_H8300) += ne-h8300.o 8390.o | |
| 147 | +obj-$(CONFIG_NE_H8300) += ne-h8300.o | |
| 148 | 148 | obj-$(CONFIG_AX88796) += ax88796.o |
| 149 | 149 | obj-$(CONFIG_BCM63XX_ENET) += bcm63xx_enet.o |
| 150 | 150 | obj-$(CONFIG_FTMAC100) += ftmac100.o |
| @@ -219,7 +219,7 @@ obj-$(CONFIG_SC92031) += sc92031.o · 68 unmodified lines | ||
| 219 | 219 | obj-$(CONFIG_LP486E) += lp486e.o |
| 220 | 220 | |
| 221 | 221 | obj-$(CONFIG_ETH16I) += eth16i.o |
| 222 | −obj-$(CONFIG_ZORRO8390) += zorro8390.o 8390.o | |
| 222 | +obj-$(CONFIG_ZORRO8390) += zorro8390.o | |
| 223 | 223 | obj-$(CONFIG_HPLANCE) += hplance.o 7990.o |
| 224 | 224 | obj-$(CONFIG_MVME147_NET) += mvme147.o 7990.o |
| 225 | 225 | obj-$(CONFIG_EQUALIZER) += eql.o |
| @@ -231,7 +231,7 @@ obj-$(CONFIG_SGI_IOC3_ETH) += ioc3-eth.o · 5 unmodified lines | ||
| 231 | 231 | obj-$(CONFIG_DECLANCE) += declance.o |
| 232 | 232 | obj-$(CONFIG_ATARILANCE) += atarilance.o |
| 233 | 233 | obj-$(CONFIG_A2065) += a2065.o |
| 234 | −obj-$(CONFIG_HYDRA) += hydra.o 8390.o | |
| 234 | +obj-$(CONFIG_HYDRA) += hydra.o | |
| 235 | 235 | obj-$(CONFIG_ARIADNE) += ariadne.o |
| 236 | 236 | obj-$(CONFIG_CS89x0) += cs89x0.o |
| 237 | 237 | obj-$(CONFIG_MACSONIC) += macsonic.o |
| @@ -106,7 +106,7 @@ MODULE_DESCRIPTION ("AMD8111 based 10/100 Ethernet Controller. Driver Version "M · 105 unmodified lines | ||
| 106 | 106 | MODULE_LICENSE("GPL"); |
| 107 | 107 | MODULE_DEVICE_TABLE(pci, amd8111e_pci_tbl); |
| 108 | 108 | module_param_array(speed_duplex, int, NULL, 0); |
| 109 | −MODULE_PARM_DESC(speed_duplex, "Set device speed and duplex modes, 0: Auto Negotitate, 1: 10Mbps Half Duplex, 2: 10Mbps Full Duplex, 3: 100Mbps Half Duplex, 4: 100Mbps Full Duplex"); | |
| 109 | +MODULE_PARM_DESC(speed_duplex, "Set device speed and duplex modes, 0: Auto Negotiate, 1: 10Mbps Half Duplex, 2: 10Mbps Full Duplex, 3: 100Mbps Half Duplex, 4: 100Mbps Full Duplex"); | |
| 110 | 110 | module_param_array(coalesce, bool, NULL, 0); |
| 111 | 111 | MODULE_PARM_DESC(coalesce, "Enable or Disable interrupt coalescing, 1: Enable, 0: Disable"); |
| 112 | 112 | module_param_array(dynamic_ipg, bool, NULL, 0); |
| @@ -527,7 +527,7 @@ static void __init etherh_banner(void) · 526 unmodified lines | ||
| 527 | 527 | * Read the ethernet address string from the on board rom. |
| 528 | 528 | * This is an ascii string... |
| 529 | 529 | */ |
| 530 | −static int __init etherh_addr(char *addr, struct expansion_card *ec) | |
| 530 | +static int __devinit etherh_addr(char *addr, struct expansion_card *ec) | |
| 531 | 531 | { |
| 532 | 532 | struct in_chunk_dir cd; |
| 533 | 533 | char *s; |
| @@ -655,7 +655,7 @@ static const struct net_device_ops etherh_netdev_ops = { · 121 unmodified lines | ||
| 655 | 655 | static u32 etherh_regoffsets[16]; |
| 656 | 656 | static u32 etherm_regoffsets[16]; |
| 657 | 657 | |
| 658 | −static int __init | |
| 658 | +static int __devinit | |
| 659 | 659 | etherh_probe(struct expansion_card *ec, const struct ecard_id *id) |
| 660 | 660 | { |
| 661 | 661 | const struct etherh_data *data = id->data; |
| @@ -566,9 +566,9 @@ struct atl1c_adapter { · 565 unmodified lines | ||
| 566 | 566 | #define __AT_TESTING 0x0001 |
| 567 | 567 | #define __AT_RESETTING 0x0002 |
| 568 | 568 | #define __AT_DOWN 0x0003 |
| 569 | − u8 work_event; | |
| 570 | −#define ATL1C_WORK_EVENT_RESET 0x01 | |
| 571 | −#define ATL1C_WORK_EVENT_LINK_CHANGE 0x02 | |
| 569 | + unsigned long work_event; | |
| 570 | +#define ATL1C_WORK_EVENT_RESET 0 | |
| 571 | +#define ATL1C_WORK_EVENT_LINK_CHANGE 1 | |
| 572 | 572 | u32 msg_enable; |
| 573 | 573 | |
| 574 | 574 | bool have_msi; |
| @@ -325,7 +325,7 @@ static void atl1c_link_chg_event(struct atl1c_adapter *adapter) · 324 unmodified lines | ||
| 325 | 325 | } |
| 326 | 326 | } |
| 327 | 327 | |
| 328 | − adapter->work_event |= ATL1C_WORK_EVENT_LINK_CHANGE; | |
| 328 | + set_bit(ATL1C_WORK_EVENT_LINK_CHANGE, &adapter->work_event); | |
| 329 | 329 | schedule_work(&adapter->common_task); |
| 330 | 330 | } |
| 331 | 331 | |
| @@ -337,20 +337,16 @@ static void atl1c_common_task(struct work_struct *work) · 5 unmodified lines | ||
| 337 | 337 | adapter = container_of(work, struct atl1c_adapter, common_task); |
| 338 | 338 | netdev = adapter->netdev; |
| 339 | 339 | |
| 340 | − if (adapter->work_event & ATL1C_WORK_EVENT_RESET) { | |
| 341 | − adapter->work_event &= ~ATL1C_WORK_EVENT_RESET; | |
| 340 | + if (test_and_clear_bit(ATL1C_WORK_EVENT_RESET, &adapter->work_event)) { | |
| 342 | 341 | netif_device_detach(netdev); |
| 343 | 342 | atl1c_down(adapter); |
| 344 | 343 | atl1c_up(adapter); |
| 345 | 344 | netif_device_attach(netdev); |
| 346 | − return; | |
| 347 | 345 | } |
| 348 | 346 | |
| 349 | − if (adapter->work_event & ATL1C_WORK_EVENT_LINK_CHANGE) { | |
| 350 | − adapter->work_event &= ~ATL1C_WORK_EVENT_LINK_CHANGE; | |
| 347 | + if (test_and_clear_bit(ATL1C_WORK_EVENT_LINK_CHANGE, | |
| 348 | + &adapter->work_event)) | |
| 351 | 349 | atl1c_check_link_status(adapter); |
| 352 | − } | |
| 353 | − return; | |
| 354 | 350 | } |
| 355 | 351 | |
| 356 | 352 | |
| @@ -369,7 +365,7 @@ static void atl1c_tx_timeout(struct net_device *netdev) · 12 unmodified lines | ||
| 369 | 365 | struct atl1c_adapter *adapter = netdev_priv(netdev); |
| 370 | 366 | |
| 371 | 367 | /* Do the reset outside of interrupt context */ |
| 372 | − adapter->work_event |= ATL1C_WORK_EVENT_RESET; | |
| 368 | + set_bit(ATL1C_WORK_EVENT_RESET, &adapter->work_event); | |
| 373 | 369 | schedule_work(&adapter->common_task); |
| 374 | 370 | } |
| 375 | 371 | |
| @@ -213,7 +213,7 @@ struct be_rx_stats { · 212 unmodified lines | ||
| 213 | 213 | |
| 214 | 214 | struct be_rx_compl_info { |
| 215 | 215 | u32 rss_hash; |
| 216 | − u16 vid; | |
| 216 | + u16 vlan_tag; | |
| 217 | 217 | u16 pkt_size; |
| 218 | 218 | u16 rxq_idx; |
| 219 | 219 | u16 mac_id; |
| @@ -132,7 +132,7 @@ static void be_async_grp5_pvid_state_process(struct be_adapter *adapter, · 131 unmodified lines | ||
| 132 | 132 | struct be_async_event_grp5_pvid_state *evt) |
| 133 | 133 | { |
| 134 | 134 | if (evt->enabled) |
| 135 | − adapter->pvid = evt->tag; | |
| 135 | + adapter->pvid = le16_to_cpu(evt->tag); | |
| 136 | 136 | else |
| 137 | 137 | adapter->pvid = 0; |
| 138 | 138 | } |
| @@ -1018,7 +1018,8 @@ static void be_rx_compl_process(struct be_adapter *adapter, · 1017 unmodified lines | ||
| 1018 | 1018 | kfree_skb(skb); |
| 1019 | 1019 | return; |
| 1020 | 1020 | } |
| 1021 | − vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, rxcp->vid); | |
| 1021 | + vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, | |
| 1022 | + rxcp->vlan_tag); | |
| 1022 | 1023 | } else { |
| 1023 | 1024 | netif_receive_skb(skb); |
| 1024 | 1025 | } |
| @@ -1076,7 +1077,8 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, · 51 unmodified lines | ||
| 1076 | 1077 | if (likely(!rxcp->vlanf)) |
| 1077 | 1078 | napi_gro_frags(&eq_obj->napi); |
| 1078 | 1079 | else |
| 1079 | − vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, rxcp->vid); | |
| 1080 | + vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, | |
| 1081 | + rxcp->vlan_tag); | |
| 1080 | 1082 | } |
| 1081 | 1083 | |
| 1082 | 1084 | static void be_parse_rx_compl_v1(struct be_adapter *adapter, |
| @@ -1102,7 +1104,8 @@ static void be_parse_rx_compl_v1(struct be_adapter *adapter, · 19 unmodified lines | ||
| 1102 | 1104 | rxcp->pkt_type = |
| 1103 | 1105 | AMAP_GET_BITS(struct amap_eth_rx_compl_v1, cast_enc, compl); |
| 1104 | 1106 | rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtm, compl); |
| 1105 | − rxcp->vid = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vlan_tag, compl); | |
| 1107 | + rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vlan_tag, | |
| 1108 | + compl); | |
| 1106 | 1109 | } |
| 1107 | 1110 | |
| 1108 | 1111 | static void be_parse_rx_compl_v0(struct be_adapter *adapter, |
| @@ -1128,7 +1131,8 @@ static void be_parse_rx_compl_v0(struct be_adapter *adapter, · 19 unmodified lines | ||
| 1128 | 1131 | rxcp->pkt_type = |
| 1129 | 1132 | AMAP_GET_BITS(struct amap_eth_rx_compl_v0, cast_enc, compl); |
| 1130 | 1133 | rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtm, compl); |
| 1131 | − rxcp->vid = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vlan_tag, compl); | |
| 1134 | + rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vlan_tag, | |
| 1135 | + compl); | |
| 1132 | 1136 | } |
| 1133 | 1137 | |
| 1134 | 1138 | static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo) |
| @@ -1155,9 +1159,11 @@ static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo) · 20 unmodified lines | ||
| 1155 | 1159 | rxcp->vlanf = 0; |
| 1156 | 1160 | |
| 1157 | 1161 | if (!lancer_chip(adapter)) |
| 1158 | − rxcp->vid = swab16(rxcp->vid); | |
| 1162 | + rxcp->vlan_tag = swab16(rxcp->vlan_tag); | |
| 1159 | 1163 | |
| 1160 | − if ((adapter->pvid == rxcp->vid) && !adapter->vlan_tag[rxcp->vid]) | |
| 1164 | + if (((adapter->pvid & VLAN_VID_MASK) == | |
| 1165 | + (rxcp->vlan_tag & VLAN_VID_MASK)) && | |
| 1166 | + !adapter->vlan_tag[rxcp->vlan_tag]) | |
| 1161 | 1167 | rxcp->vlanf = 0; |
| 1162 | 1168 | |
| 1163 | 1169 | /* As the compl has been parsed, reset it; we wont touch it again */ |
| @@ -1873,6 +1879,7 @@ static void be_worker(struct work_struct *work) · 709 unmodified lines | ||
| 1873 | 1879 | be_detect_dump_ue(adapter); |
| 1874 | 1880 | |
| 1875 | 1881 | reschedule: |
| 1882 | + adapter->work_counter++; | |
| 1876 | 1883 | schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000)); |
| 1877 | 1884 | } |
| 1878 | 1885 | |
| @@ -38,6 +38,8 @@ · 37 unmodified lines | ||
| 38 | 38 | #define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc)) |
| 39 | 39 | #define bfa_ioc_notify_fail(__ioc) \ |
| 40 | 40 | ((__ioc)->ioc_hwif->ioc_notify_fail(__ioc)) |
| 41 | +#define bfa_ioc_sync_start(__ioc) \ | |
| 42 | + ((__ioc)->ioc_hwif->ioc_sync_start(__ioc)) | |
| 41 | 43 | #define bfa_ioc_sync_join(__ioc) \ |
| 42 | 44 | ((__ioc)->ioc_hwif->ioc_sync_join(__ioc)) |
| 43 | 45 | #define bfa_ioc_sync_leave(__ioc) \ |
| @@ -602,7 +604,7 @@ bfa_iocpf_sm_fwcheck(struct bfa_iocpf *iocpf, enum iocpf_event event) · 558 unmodified lines | ||
| 602 | 604 | switch (event) { |
| 603 | 605 | case IOCPF_E_SEMLOCKED: |
| 604 | 606 | if (bfa_ioc_firmware_lock(ioc)) { |
| 605 | − if (bfa_ioc_sync_complete(ioc)) { | |
| 607 | + if (bfa_ioc_sync_start(ioc)) { | |
| 606 | 608 | iocpf->retry_count = 0; |
| 607 | 609 | bfa_ioc_sync_join(ioc); |
| 608 | 610 | bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit); |
| @@ -1314,7 +1316,7 @@ bfa_nw_ioc_fwver_cmp(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr) · 705 unmodified lines | ||
| 1314 | 1316 | * execution context (driver/bios) must match. |
| 1315 | 1317 | */ |
| 1316 | 1318 | static bool |
| 1317 | −bfa_ioc_fwver_valid(struct bfa_ioc *ioc) | |
| 1319 | +bfa_ioc_fwver_valid(struct bfa_ioc *ioc, u32 boot_env) | |
| 1318 | 1320 | { |
| 1319 | 1321 | struct bfi_ioc_image_hdr fwhdr, *drv_fwhdr; |
| 1320 | 1322 | |
| @@ -1325,7 +1327,7 @@ bfa_ioc_fwver_valid(struct bfa_ioc *ioc) · 4 unmodified lines | ||
| 1325 | 1327 | if (fwhdr.signature != drv_fwhdr->signature) |
| 1326 | 1328 | return false; |
| 1327 | 1329 | |
| 1328 | − if (fwhdr.exec != drv_fwhdr->exec) | |
| 1330 | + if (swab32(fwhdr.param) != boot_env) | |
| 1329 | 1331 | return false; |
| 1330 | 1332 | |
| 1331 | 1333 | return bfa_nw_ioc_fwver_cmp(ioc, &fwhdr); |
| @@ -1352,9 +1354,12 @@ bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force) · 20 unmodified lines | ||
| 1352 | 1354 | { |
| 1353 | 1355 | enum bfi_ioc_state ioc_fwstate; |
| 1354 | 1356 | bool fwvalid; |
| 1357 | + u32 boot_env; | |
| 1355 | 1358 | |
| 1356 | 1359 | ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate); |
| 1357 | 1360 | |
| 1361 | + boot_env = BFI_BOOT_LOADER_OS; | |
| 1362 | + | |
| 1358 | 1363 | if (force) |
| 1359 | 1364 | ioc_fwstate = BFI_IOC_UNINIT; |
| 1360 | 1365 | |
| @@ -1362,10 +1367,10 @@ bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force) · 1 unmodified line | ||
| 1362 | 1367 | * check if firmware is valid |
| 1363 | 1368 | */ |
| 1364 | 1369 | fwvalid = (ioc_fwstate == BFI_IOC_UNINIT) ? |
| 1365 | − false : bfa_ioc_fwver_valid(ioc); | |
| 1370 | + false : bfa_ioc_fwver_valid(ioc, boot_env); | |
| 1366 | 1371 | |
| 1367 | 1372 | if (!fwvalid) { |
| 1368 | − bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, ioc->pcidev.device_id); | |
| 1373 | + bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, boot_env); | |
| 1369 | 1374 | return; |
| 1370 | 1375 | } |
| 1371 | 1376 | |
| @@ -1396,7 +1401,7 @@ bfa_ioc_hwinit(struct bfa_ioc *ioc, bool force) · 24 unmodified lines | ||
| 1396 | 1401 | /** |
| 1397 | 1402 | * Initialize the h/w for any other states. |
| 1398 | 1403 | */ |
| 1399 | − bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, ioc->pcidev.device_id); | |
| 1404 | + bfa_ioc_boot(ioc, BFI_BOOT_TYPE_NORMAL, boot_env); | |
| 1400 | 1405 | } |
| 1401 | 1406 | |
| 1402 | 1407 | void |
| @@ -1506,7 +1511,7 @@ bfa_ioc_hb_stop(struct bfa_ioc *ioc) · 103 unmodified lines | ||
| 1506 | 1511 | */ |
| 1507 | 1512 | static void |
| 1508 | 1513 | bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type, |
| 1509 | − u32 boot_param) | |
| 1514 | + u32 boot_env) | |
| 1510 | 1515 | { |
| 1511 | 1516 | u32 *fwimg; |
| 1512 | 1517 | u32 pgnum, pgoff; |
| @@ -1558,10 +1563,10 @@ bfa_ioc_download_fw(struct bfa_ioc *ioc, u32 boot_type, · 45 unmodified lines | ||
| 1558 | 1563 | /* |
| 1559 | 1564 | * Set boot type and boot param at the end. |
| 1560 | 1565 | */ |
| 1561 | − writel((swab32(swab32(boot_type))), ((ioc->ioc_regs.smem_page_start) | |
| 1566 | + writel(boot_type, ((ioc->ioc_regs.smem_page_start) | |
| 1562 | 1567 | + (BFI_BOOT_TYPE_OFF))); |
| 1563 | − writel((swab32(swab32(boot_param))), ((ioc->ioc_regs.smem_page_start) | |
| 1564 | − + (BFI_BOOT_PARAM_OFF))); | |
| 1568 | + writel(boot_env, ((ioc->ioc_regs.smem_page_start) | |
| 1569 | + + (BFI_BOOT_LOADER_OFF))); | |
| 1565 | 1570 | } |
| 1566 | 1571 | |
| 1567 | 1572 | static void |
| @@ -1721,7 +1726,7 @@ bfa_ioc_pll_init(struct bfa_ioc *ioc) · 153 unmodified lines | ||
| 1721 | 1726 | * as the entry vector. |
| 1722 | 1727 | */ |
| 1723 | 1728 | static void |
| 1724 | −bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type, u32 boot_param) | |
| 1729 | +bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type, u32 boot_env) | |
| 1725 | 1730 | { |
| 1726 | 1731 | void __iomem *rb; |
| 1727 | 1732 | |
| @@ -1734,7 +1739,7 @@ bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type, u32 boot_param) · 6 unmodified lines | ||
| 1734 | 1739 | * Initialize IOC state of all functions on a chip reset. |
| 1735 | 1740 | */ |
| 1736 | 1741 | rb = ioc->pcidev.pci_bar_kva; |
| 1737 | − if (boot_param == BFI_BOOT_TYPE_MEMTEST) { | |
| 1742 | + if (boot_type == BFI_BOOT_TYPE_MEMTEST) { | |
| 1738 | 1743 | writel(BFI_IOC_MEMTEST, (rb + BFA_IOC0_STATE_REG)); |
| 1739 | 1744 | writel(BFI_IOC_MEMTEST, (rb + BFA_IOC1_STATE_REG)); |
| 1740 | 1745 | } else { |
| @@ -1743,7 +1748,7 @@ bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type, u32 boot_param) · 2 unmodified lines | ||
| 1743 | 1748 | } |
| 1744 | 1749 | |
| 1745 | 1750 | bfa_ioc_msgflush(ioc); |
| 1746 | − bfa_ioc_download_fw(ioc, boot_type, boot_param); | |
| 1751 | + bfa_ioc_download_fw(ioc, boot_type, boot_env); | |
| 1747 | 1752 | |
| 1748 | 1753 | /** |
| 1749 | 1754 | * Enable interrupts just before starting LPU |
| @@ -194,6 +194,7 @@ struct bfa_ioc_hwif { · 193 unmodified lines | ||
| 194 | 194 | bool msix); |
| 195 | 195 | void (*ioc_notify_fail) (struct bfa_ioc *ioc); |
| 196 | 196 | void (*ioc_ownership_reset) (struct bfa_ioc *ioc); |
| 197 | + bool (*ioc_sync_start) (struct bfa_ioc *ioc); | |
| 197 | 198 | void (*ioc_sync_join) (struct bfa_ioc *ioc); |
| 198 | 199 | void (*ioc_sync_leave) (struct bfa_ioc *ioc); |
| 199 | 200 | void (*ioc_sync_ack) (struct bfa_ioc *ioc); |
| @@ -41,6 +41,7 @@ static void bfa_ioc_ct_map_port(struct bfa_ioc *ioc); · 40 unmodified lines | ||
| 41 | 41 | static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc *ioc, bool msix); |
| 42 | 42 | static void bfa_ioc_ct_notify_fail(struct bfa_ioc *ioc); |
| 43 | 43 | static void bfa_ioc_ct_ownership_reset(struct bfa_ioc *ioc); |
| 44 | +static bool bfa_ioc_ct_sync_start(struct bfa_ioc *ioc); | |
| 44 | 45 | static void bfa_ioc_ct_sync_join(struct bfa_ioc *ioc); |
| 45 | 46 | static void bfa_ioc_ct_sync_leave(struct bfa_ioc *ioc); |
| 46 | 47 | static void bfa_ioc_ct_sync_ack(struct bfa_ioc *ioc); |
| @@ -63,6 +64,7 @@ bfa_nw_ioc_set_ct_hwif(struct bfa_ioc *ioc) · 16 unmodified lines | ||
| 63 | 64 | nw_hwif_ct.ioc_isr_mode_set = bfa_ioc_ct_isr_mode_set; |
| 64 | 65 | nw_hwif_ct.ioc_notify_fail = bfa_ioc_ct_notify_fail; |
| 65 | 66 | nw_hwif_ct.ioc_ownership_reset = bfa_ioc_ct_ownership_reset; |
| 67 | + nw_hwif_ct.ioc_sync_start = bfa_ioc_ct_sync_start; | |
| 66 | 68 | nw_hwif_ct.ioc_sync_join = bfa_ioc_ct_sync_join; |
| 67 | 69 | nw_hwif_ct.ioc_sync_leave = bfa_ioc_ct_sync_leave; |
| 68 | 70 | nw_hwif_ct.ioc_sync_ack = bfa_ioc_ct_sync_ack; |
| @@ -342,6 +344,32 @@ bfa_ioc_ct_ownership_reset(struct bfa_ioc *ioc) · 273 unmodified lines | ||
| 342 | 344 | bfa_nw_ioc_hw_sem_release(ioc); |
| 343 | 345 | } |
| 344 | 346 | |
| 347 | +/** | |
| 348 | + * Synchronized IOC failure processing routines | |
| 349 | + */ | |
| 350 | +static bool | |
| 351 | +bfa_ioc_ct_sync_start(struct bfa_ioc *ioc) | |
| 352 | +{ | |
| 353 | + u32 r32 = readl(ioc->ioc_regs.ioc_fail_sync); | |
| 354 | + u32 sync_reqd = bfa_ioc_ct_get_sync_reqd(r32); | |
| 355 | + | |
| 356 | + /* | |
| 357 | + * Driver load time. If the sync required bit for this PCI fn | |
| 358 | + * is set, it is due to an unclean exit by the driver for this | |
| 359 | + * PCI fn in the previous incarnation. Whoever comes here first | |
| 360 | + * should clean it up, no matter which PCI fn. | |
| 361 | + */ | |
| 362 | + | |
| 363 | + if (sync_reqd & bfa_ioc_ct_sync_pos(ioc)) { | |
| 364 | + writel(0, ioc->ioc_regs.ioc_fail_sync); | |
| 365 | + writel(1, ioc->ioc_regs.ioc_usage_reg); | |
| 366 | + writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate); | |
| 367 | + writel(BFI_IOC_UNINIT, ioc->ioc_regs.alt_ioc_fwstate); | |
| 368 | + return true; | |
| 369 | + } | |
| 370 | + | |
| 371 | + return bfa_ioc_ct_sync_complete(ioc); | |
| 372 | +} | |
| 345 | 373 | /** |
| 346 | 374 | * Synchronized IOC failure processing routines |
| 347 | 375 | */ |
| @@ -184,12 +184,14 @@ enum bfi_mclass { · 183 unmodified lines | ||
| 184 | 184 | #define BFI_IOC_MSGLEN_MAX 32 /* 32 bytes */ |
| 185 | 185 | |
| 186 | 186 | #define BFI_BOOT_TYPE_OFF 8 |
| 187 | −#define BFI_BOOT_PARAM_OFF 12 | |
| 187 | +#define BFI_BOOT_LOADER_OFF 12 | |
| 188 | 188 | |
| 189 | −#define BFI_BOOT_TYPE_NORMAL 0 /* param is device id */ | |
| 189 | +#define BFI_BOOT_TYPE_NORMAL 0 | |
| 190 | 190 | #define BFI_BOOT_TYPE_FLASH 1 |
| 191 | 191 | #define BFI_BOOT_TYPE_MEMTEST 2 |
| 192 | 192 | |
| 193 | +#define BFI_BOOT_LOADER_OS 0 | |
| 194 | + | |
| 193 | 195 | #define BFI_BOOT_MEMTEST_RES_ADDR 0x900 |
| 194 | 196 | #define BFI_BOOT_MEMTEST_RES_SIG 0xA0A1A2A3 |
| 195 | 197 | |
| @@ -1837,7 +1837,6 @@ bnad_setup_rx(struct bnad *bnad, uint rx_id) · 1836 unmodified lines | ||
| 1837 | 1837 | /* Initialize the Rx event handlers */ |
| 1838 | 1838 | rx_cbfn.rcb_setup_cbfn = bnad_cb_rcb_setup; |
| 1839 | 1839 | rx_cbfn.rcb_destroy_cbfn = bnad_cb_rcb_destroy; |
| 1840 | − rx_cbfn.rcb_destroy_cbfn = NULL; | |
| 1841 | 1840 | rx_cbfn.ccb_setup_cbfn = bnad_cb_ccb_setup; |
| 1842 | 1841 | rx_cbfn.ccb_destroy_cbfn = bnad_cb_ccb_destroy; |
| 1843 | 1842 | rx_cbfn.rx_cleanup_cbfn = bnad_cb_rx_cleanup; |
| @@ -8413,6 +8413,8 @@ bnx2_remove_one(struct pci_dev *pdev) · 8412 unmodified lines | ||
| 8413 | 8413 | |
| 8414 | 8414 | unregister_netdev(dev); |
| 8415 | 8415 | |
| 8416 | + del_timer_sync(&bp->timer); | |
| 8417 | + | |
| 8416 | 8418 | if (bp->mips_firmware) |
| 8417 | 8419 | release_firmware(bp->mips_firmware); |
| 8418 | 8420 | if (bp->rv2p_firmware) |
| @@ -2019,15 +2019,23 @@ static inline void bnx2x_set_pbd_gso(struct sk_buff *skb, · 2018 unmodified lines | ||
| 2019 | 2019 | static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb, |
| 2020 | 2020 | u32 *parsing_data, u32 xmit_type) |
| 2021 | 2021 | { |
| 2022 | − *parsing_data |= ((tcp_hdrlen(skb)/4) << | |
| 2023 | − ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT) & | |
| 2024 | − ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW; | |
| 2022 | + *parsing_data |= | |
| 2023 | + ((((u8 *)skb_transport_header(skb) - skb->data) >> 1) << | |
| 2024 | + ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT) & | |
| 2025 | + ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W; | |
| 2025 | 2026 | |
| 2026 | − *parsing_data |= ((((u8 *)tcp_hdr(skb) - skb->data) / 2) << | |
| 2027 | − ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT) & | |
| 2028 | − ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W; | |
| 2027 | + if (xmit_type & XMIT_CSUM_TCP) { | |
| 2028 | + *parsing_data |= ((tcp_hdrlen(skb) / 4) << | |
| 2029 | + ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT) & | |
| 2030 | + ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW; | |
| 2029 | 2031 | |
| 2030 | − return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data; | |
| 2032 | + return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data; | |
| 2033 | + } else | |
| 2034 | + /* We support checksum offload for TCP and UDP only. | |
| 2035 | + * No need to pass the UDP header length - it's a constant. | |
| 2036 | + */ | |
| 2037 | + return skb_transport_header(skb) + | |
| 2038 | + sizeof(struct udphdr) - skb->data; | |
| 2031 | 2039 | } |
| 2032 | 2040 | |
| 2033 | 2041 | /** |
| @@ -2043,7 +2051,7 @@ static inline u8 bnx2x_set_pbd_csum(struct bnx2x *bp, struct sk_buff *skb, · 9 unmodified lines | ||
| 2043 | 2051 | struct eth_tx_parse_bd_e1x *pbd, |
| 2044 | 2052 | u32 xmit_type) |
| 2045 | 2053 | { |
| 2046 | − u8 hlen = (skb_network_header(skb) - skb->data) / 2; | |
| 2054 | + u8 hlen = (skb_network_header(skb) - skb->data) >> 1; | |
| 2047 | 2055 | |
| 2048 | 2056 | /* for now NS flag is not used in Linux */ |
| 2049 | 2057 | pbd->global_data = |
| @@ -2051,9 +2059,15 @@ static inline u8 bnx2x_set_pbd_csum(struct bnx2x *bp, struct sk_buff *skb, · 1 unmodified line | ||
| 2051 | 2059 | ETH_TX_PARSE_BD_E1X_LLC_SNAP_EN_SHIFT)); |
| 2052 | 2060 | |
| 2053 | 2061 | pbd->ip_hlen_w = (skb_transport_header(skb) - |
| 2054 | − skb_network_header(skb)) / 2; | |
| 2062 | + skb_network_header(skb)) >> 1; | |
| 2055 | 2063 | |
| 2056 | − hlen += pbd->ip_hlen_w + tcp_hdrlen(skb) / 2; | |
| 2064 | + hlen += pbd->ip_hlen_w; | |
| 2065 | + | |
| 2066 | + /* We support checksum offload for TCP and UDP only */ | |
| 2067 | + if (xmit_type & XMIT_CSUM_TCP) | |
| 2068 | + hlen += tcp_hdrlen(skb) / 2; | |
| 2069 | + else | |
| 2070 | + hlen += sizeof(struct udphdr) / 2; | |
| 2057 | 2071 | |
| 2058 | 2072 | pbd->total_hlen_w = cpu_to_le16(hlen); |
| 2059 | 2073 | hlen = hlen*2; |
| @@ -2114,19 +2114,18 @@ static int bnx2x_phys_id(struct net_device *dev, u32 data) · 2113 unmodified lines | ||
| 2114 | 2114 | for (i = 0; i < (data * 2); i++) { |
| 2115 | 2115 | if ((i % 2) == 0) |
| 2116 | 2116 | bnx2x_set_led(&bp->link_params, &bp->link_vars, |
| 2117 | − LED_MODE_OPER, SPEED_1000); | |
| 2117 | + LED_MODE_ON, SPEED_1000); | |
| 2118 | 2118 | else |
| 2119 | 2119 | bnx2x_set_led(&bp->link_params, &bp->link_vars, |
| 2120 | − LED_MODE_OFF, 0); | |
| 2120 | + LED_MODE_FRONT_PANEL_OFF, 0); | |
| 2121 | 2121 | |
| 2122 | 2122 | msleep_interruptible(500); |
| 2123 | 2123 | if (signal_pending(current)) |
| 2124 | 2124 | break; |
| 2125 | 2125 | } |
| 2126 | 2126 | |
| 2127 | − if (bp->link_vars.link_up) | |
| 2128 | − bnx2x_set_led(&bp->link_params, &bp->link_vars, LED_MODE_OPER, | |
| 2129 | − bp->link_vars.line_speed); | |
| 2127 | + bnx2x_set_led(&bp->link_params, &bp->link_vars, | |
| 2128 | + LED_MODE_OPER, bp->link_vars.line_speed); | |
| 2130 | 2129 | |
| 2131 | 2130 | return 0; |
| 2132 | 2131 | } |
| @@ -1482,8 +1482,11 @@ static struct aggregator *ad_agg_selection_test(struct aggregator *best, · 1481 unmodified lines | ||
| 1482 | 1482 | |
| 1483 | 1483 | static int agg_device_up(const struct aggregator *agg) |
| 1484 | 1484 | { |
| 1485 | − return (netif_running(agg->slave->dev) && | |
| 1486 | − netif_carrier_ok(agg->slave->dev)); | |
| 1485 | + struct port *port = agg->lag_ports; | |
| 1486 | + if (!port) | |
| 1487 | + return 0; | |
| 1488 | + return (netif_running(port->slave->dev) && | |
| 1489 | + netif_carrier_ok(port->slave->dev)); | |
| 1487 | 1490 | } |
| 1488 | 1491 | |
| 1489 | 1492 | /** |
| @@ -39,7 +39,7 @@ · 38 unmodified lines | ||
| 39 | 39 | |
| 40 | 40 | typedef struct mac_addr { |
| 41 | 41 | u8 mac_addr_value[ETH_ALEN]; |
| 42 | −} mac_addr_t; | |
| 42 | +} __packed mac_addr_t; | |
| 43 | 43 | |
| 44 | 44 | enum { |
| 45 | 45 | BOND_AD_STABLE = 0, |
| @@ -134,12 +134,12 @@ typedef struct lacpdu { · 88 unmodified lines | ||
| 134 | 134 | u8 tlv_type_terminator; // = terminator |
| 135 | 135 | u8 terminator_length; // = 0 |
| 136 | 136 | u8 reserved_50[50]; // = 0 |
| 137 | −} lacpdu_t; | |
| 137 | +} __packed lacpdu_t; | |
| 138 | 138 | |
| 139 | 139 | typedef struct lacpdu_header { |
| 140 | 140 | struct ethhdr hdr; |
| 141 | 141 | struct lacpdu lacpdu; |
| 142 | −} lacpdu_header_t; | |
| 142 | +} __packed lacpdu_header_t; | |
| 143 | 143 | |
| 144 | 144 | // Marker Protocol Data Unit(PDU) structure(43.5.3.2 in the 802.3ad standard) |
| 145 | 145 | typedef struct bond_marker { |
| @@ -155,12 +155,12 @@ typedef struct bond_marker { · 9 unmodified lines | ||
| 155 | 155 | u8 tlv_type_terminator; // = 0x00 |
| 156 | 156 | u8 terminator_length; // = 0x00 |
| 157 | 157 | u8 reserved_90[90]; // = 0 |
| 158 | −} bond_marker_t; | |
| 158 | +} __packed bond_marker_t; | |
| 159 | 159 | |
| 160 | 160 | typedef struct bond_marker_header { |
| 161 | 161 | struct ethhdr hdr; |
| 162 | 162 | struct bond_marker marker; |
| 163 | −} bond_marker_header_t; | |
| 163 | +} __packed bond_marker_header_t; | |
| 164 | 164 | |
| 165 | 165 | #pragma pack() |
| 166 | 166 | |
| @@ -176,7 +176,7 @@ static int tlb_initialize(struct bonding *bond) · 175 unmodified lines | ||
| 176 | 176 | bond_info->tx_hashtbl = new_hashtbl; |
| 177 | 177 | |
| 178 | 178 | for (i = 0; i < TLB_HASH_TABLE_SIZE; i++) { |
| 179 | − tlb_init_table_entry(&bond_info->tx_hashtbl[i], 1); | |
| 179 | + tlb_init_table_entry(&bond_info->tx_hashtbl[i], 0); | |
| 180 | 180 | } |
| 181 | 181 | |
| 182 | 182 | _unlock_tx_hashtbl(bond); |
| @@ -701,7 +701,7 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond) · 518 unmodified lines | ||
| 701 | 701 | */ |
| 702 | 702 | rlb_choose_channel(skb, bond); |
| 703 | 703 | |
| 704 | − /* The ARP relpy packets must be delayed so that | |
| 704 | + /* The ARP reply packets must be delayed so that | |
| 705 | 705 | * they can cancel out the influence of the ARP request. |
| 706 | 706 | */ |
| 707 | 707 | bond->alb_info.rlb_update_delay_counter = RLB_UPDATE_DELAY; |
| @@ -1042,7 +1042,7 @@ static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *sla · 334 unmodified lines | ||
| 1042 | 1042 | * |
| 1043 | 1043 | * If the permanent hw address of @slave is @bond's hw address, we need to |
| 1044 | 1044 | * find a different hw address to give @slave, that isn't in use by any other |
| 1045 | − * slave in the bond. This address must be, of course, one of the premanent | |
| 1045 | + * slave in the bond. This address must be, of course, one of the permanent | |
| 1046 | 1046 | * addresses of the other slaves. |
| 1047 | 1047 | * |
| 1048 | 1048 | * We go over the slave list, and for each slave there we compare its |
| @@ -75,7 +75,7 @@ struct tlb_client_info { · 74 unmodified lines | ||
| 75 | 75 | * gave this entry index. |
| 76 | 76 | */ |
| 77 | 77 | u32 tx_bytes; /* Each Client accumulates the BytesTx that |
| 78 | − * were tranmitted to it, and after each | |
| 78 | + * were transmitted to it, and after each | |
| 79 | 79 | * CallBack the LoadHistory is divided |
| 80 | 80 | * by the balance interval |
| 81 | 81 | */ |
| @@ -122,7 +122,6 @@ struct tlb_slave_info { · 40 unmodified lines | ||
| 122 | 122 | }; |
| 123 | 123 | |
| 124 | 124 | struct alb_bond_info { |
| 125 | − struct timer_list alb_timer; | |
| 126 | 125 | struct tlb_client_info *tx_hashtbl; /* Dynamically allocated */ |
| 127 | 126 | spinlock_t tx_hashtbl_lock; |
| 128 | 127 | u32 unbalanced_load; |
| @@ -140,7 +139,6 @@ struct alb_bond_info { · 11 unmodified lines | ||
| 140 | 139 | struct slave *next_rx_slave;/* next slave to be assigned |
| 141 | 140 | * to a new rx client for |
| 142 | 141 | */ |
| 143 | − u32 rlb_interval_counter; | |
| 144 | 142 | u8 primary_is_promisc; /* boolean */ |
| 145 | 143 | u32 rlb_promisc_timeout_counter;/* counts primary |
| 146 | 144 | * promiscuity time |
| @@ -247,8 +247,10 @@ static u32 __devinit mpc512x_can_get_clock(struct platform_device *ofdev, · 246 unmodified lines | ||
| 247 | 247 | } |
| 248 | 248 | #endif /* CONFIG_PPC_MPC512x */ |
| 249 | 249 | |
| 250 | +static struct of_device_id mpc5xxx_can_table[]; | |
| 250 | 251 | static int __devinit mpc5xxx_can_probe(struct platform_device *ofdev) |
| 251 | 252 | { |
| 253 | + const struct of_device_id *match; | |
| 252 | 254 | struct mpc5xxx_can_data *data; |
| 253 | 255 | struct device_node *np = ofdev->dev.of_node; |
| 254 | 256 | struct net_device *dev; |
| @@ -258,9 +260,10 @@ static int __devinit mpc5xxx_can_probe(struct platform_device *ofdev) · 3 unmodified lines | ||
| 258 | 260 | int irq, mscan_clksrc = 0; |
| 259 | 261 | int err = -ENOMEM; |
| 260 | 262 | |
| 261 | − if (!ofdev->dev.of_match) | |
| 263 | + match = of_match_device(mpc5xxx_can_table, &ofdev->dev); | |
| 264 | + if (!match) | |
| 262 | 265 | return -EINVAL; |
| 263 | − data = (struct mpc5xxx_can_data *)of_dev->dev.of_match->data; | |
| 266 | + data = match->data; | |
| 264 | 267 | |
| 265 | 268 | base = of_iomap(np, 0); |
| 266 | 269 | if (!base) { |
| @@ -346,10 +346,10 @@ static void sja1000_rx(struct net_device *dev) · 345 unmodified lines | ||
| 346 | 346 | | (priv->read_reg(priv, REG_ID2) >> 5); |
| 347 | 347 | } |
| 348 | 348 | |
| 349 | + cf->can_dlc = get_can_dlc(fi & 0x0F); | |
| 349 | 350 | if (fi & FI_RTR) { |
| 350 | 351 | id |= CAN_RTR_FLAG; |
| 351 | 352 | } else { |
| 352 | − cf->can_dlc = get_can_dlc(fi & 0x0F); | |
| 353 | 353 | for (i = 0; i < cf->can_dlc; i++) |
| 354 | 354 | cf->data[i] = priv->read_reg(priv, dreg++); |
| 355 | 355 | } |
| @@ -583,7 +583,9 @@ static int slcan_open(struct tty_struct *tty) · 582 unmodified lines | ||
| 583 | 583 | /* Done. We have linked the TTY line to a channel. */ |
| 584 | 584 | rtnl_unlock(); |
| 585 | 585 | tty->receive_room = 65536; /* We don't flow control */ |
| 586 | − return sl->dev->base_addr; | |
| 586 | + | |
| 587 | + /* TTY layer expects 0 on success */ | |
| 588 | + return 0; | |
| 587 | 589 | |
| 588 | 590 | err_free_chan: |
| 589 | 591 | sl->tty = NULL; |
| @@ -55,15 +55,20 @@ static int ehea_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) · 54 unmodified lines | ||
| 55 | 55 | cmd->duplex = -1; |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | − cmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_1000baseT_Full | |
| 59 | − | SUPPORTED_100baseT_Full | SUPPORTED_100baseT_Half | |
| 60 | − | SUPPORTED_10baseT_Full | SUPPORTED_10baseT_Half | |
| 61 | − | SUPPORTED_Autoneg | SUPPORTED_FIBRE); | |
| 62 | − | |
| 63 | − cmd->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_Autoneg | |
| 64 | − | ADVERTISED_FIBRE); | |
| 58 | + if (cmd->speed == SPEED_10000) { | |
| 59 | + cmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE); | |
| 60 | + cmd->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE); | |
| 61 | + cmd->port = PORT_FIBRE; | |
| 62 | + } else { | |
| 63 | + cmd->supported = (SUPPORTED_1000baseT_Full | SUPPORTED_100baseT_Full | |
| 64 | + | SUPPORTED_100baseT_Half | SUPPORTED_10baseT_Full | |
| 65 | + | SUPPORTED_10baseT_Half | SUPPORTED_Autoneg | |
| 66 | + | SUPPORTED_TP); | |
| 67 | + cmd->advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg | |
| 68 | + | ADVERTISED_TP); | |
| 69 | + cmd->port = PORT_TP; | |
| 70 | + } | |
| 65 | 71 | |
| 66 | − cmd->port = PORT_FIBRE; | |
| 67 | 72 | cmd->autoneg = port->autoneg == 1 ? AUTONEG_ENABLE : AUTONEG_DISABLE; |
| 68 | 73 | |
| 69 | 74 | return 0; |
| @@ -2688,9 +2688,6 @@ static int ehea_open(struct net_device *dev) · 2687 unmodified lines | ||
| 2688 | 2688 | netif_start_queue(dev); |
| 2689 | 2689 | } |
| 2690 | 2690 | |
| 2691 | − init_waitqueue_head(&port->swqe_avail_wq); | |
| 2692 | − init_waitqueue_head(&port->restart_wq); | |
| 2693 | − | |
| 2694 | 2691 | mutex_unlock(&port->port_lock); |
| 2695 | 2692 | |
| 2696 | 2693 | return ret; |
| @@ -3040,11 +3037,14 @@ static void ehea_rereg_mrs(void) · 343 unmodified lines | ||
| 3040 | 3037 | |
| 3041 | 3038 | if (dev->flags & IFF_UP) { |
| 3042 | 3039 | mutex_lock(&port->port_lock); |
| 3043 | − port_napi_enable(port); | |
| 3044 | 3040 | ret = ehea_restart_qps(dev); |
| 3045 | − check_sqs(port); | |
| 3046 | − if (!ret) | |
| 3041 | + if (!ret) { | |
| 3042 | + check_sqs(port); | |
| 3043 | + port_napi_enable(port); | |
| 3047 | 3044 | netif_wake_queue(dev); |
| 3045 | + } else { | |
| 3046 | + netdev_err(dev, "Unable to restart QPS\n"); | |
| 3047 | + } | |
| 3048 | 3048 | mutex_unlock(&port->port_lock); |
| 3049 | 3049 | } |
| 3050 | 3050 | } |
| @@ -3273,6 +3273,9 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, · 222 unmodified lines | ||
| 3273 | 3273 | |
| 3274 | 3274 | INIT_WORK(&port->reset_task, ehea_reset_port); |
| 3275 | 3275 | |
| 3276 | + init_waitqueue_head(&port->swqe_avail_wq); | |
| 3277 | + init_waitqueue_head(&port->restart_wq); | |
| 3278 | + | |
| 3276 | 3279 | ret = register_netdev(dev); |
| 3277 | 3280 | if (ret) { |
| 3278 | 3281 | pr_err("register_netdev failed. ret=%d\n", ret); |
| @@ -998,8 +998,10 @@ static const struct net_device_ops fs_enet_netdev_ops = { · 997 unmodified lines | ||
| 998 | 998 | #endif |
| 999 | 999 | }; |
| 1000 | 1000 | |
| 1001 | +static struct of_device_id fs_enet_match[]; | |
| 1001 | 1002 | static int __devinit fs_enet_probe(struct platform_device *ofdev) |
| 1002 | 1003 | { |
| 1004 | + const struct of_device_id *match; | |
| 1003 | 1005 | struct net_device *ndev; |
| 1004 | 1006 | struct fs_enet_private *fep; |
| 1005 | 1007 | struct fs_platform_info *fpi; |
| @@ -1007,14 +1009,15 @@ static int __devinit fs_enet_probe(struct platform_device *ofdev) · 1 unmodified line | ||
| 1007 | 1009 | const u8 *mac_addr; |
| 1008 | 1010 | int privsize, len, ret = -ENODEV; |
| 1009 | 1011 | |
| 1010 | − if (!ofdev->dev.of_match) | |
| 1012 | + match = of_match_device(fs_enet_match, &ofdev->dev); | |
| 1013 | + if (!match) | |
| 1011 | 1014 | return -EINVAL; |
| 1012 | 1015 | |
| 1013 | 1016 | fpi = kzalloc(sizeof(*fpi), GFP_KERNEL); |
| 1014 | 1017 | if (!fpi) |
| 1015 | 1018 | return -ENOMEM; |
| 1016 | 1019 | |
| 1017 | − if (!IS_FEC(ofdev->dev.of_match)) { | |
| 1020 | + if (!IS_FEC(match)) { | |
| 1018 | 1021 | data = of_get_property(ofdev->dev.of_node, "fsl,cpm-command", &len); |
| 1019 | 1022 | if (!data || len != 4) |
| 1020 | 1023 | goto out_free_fpi; |
| @@ -1049,7 +1052,7 @@ static int __devinit fs_enet_probe(struct platform_device *ofdev) · 28 unmodified lines | ||
| 1049 | 1052 | fep->dev = &ofdev->dev; |
| 1050 | 1053 | fep->ndev = ndev; |
| 1051 | 1054 | fep->fpi = fpi; |
| 1052 | − fep->ops = ofdev->dev.of_match->data; | |
| 1055 | + fep->ops = match->data; | |
| 1053 | 1056 | |
| 1054 | 1057 | ret = fep->ops->setup_data(ndev); |
| 1055 | 1058 | if (ret) |
| @@ -226,8 +226,8 @@ static void set_multicast_finish(struct net_device *dev) · 225 unmodified lines | ||
| 226 | 226 | } |
| 227 | 227 | |
| 228 | 228 | FC(fecp, r_cntrl, FEC_RCNTRL_PROM); |
| 229 | − FW(fecp, hash_table_high, fep->fec.hthi); | |
| 230 | − FW(fecp, hash_table_low, fep->fec.htlo); | |
| 229 | + FW(fecp, grp_hash_table_high, fep->fec.hthi); | |
| 230 | + FW(fecp, grp_hash_table_low, fep->fec.htlo); | |
| 231 | 231 | } |
| 232 | 232 | |
| 233 | 233 | static void set_multicast_list(struct net_device *dev) |
| @@ -273,8 +273,8 @@ static void restart(struct net_device *dev) · 39 unmodified lines | ||
| 273 | 273 | /* |
| 274 | 274 | * Reset all multicast. |
| 275 | 275 | */ |
| 276 | − FW(fecp, hash_table_high, fep->fec.hthi); | |
| 277 | − FW(fecp, hash_table_low, fep->fec.htlo); | |
| 276 | + FW(fecp, grp_hash_table_high, fep->fec.hthi); | |
| 277 | + FW(fecp, grp_hash_table_low, fep->fec.htlo); | |
| 278 | 278 | |
| 279 | 279 | /* |
| 280 | 280 | * Set maximum receive buffer size. |
| @@ -101,17 +101,20 @@ static int fs_enet_fec_mii_reset(struct mii_bus *bus) · 100 unmodified lines | ||
| 101 | 101 | return 0; |
| 102 | 102 | } |
| 103 | 103 | |
| 104 | +static struct of_device_id fs_enet_mdio_fec_match[]; | |
| 104 | 105 | static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev) |
| 105 | 106 | { |
| 107 | + const struct of_device_id *match; | |
| 106 | 108 | struct resource res; |
| 107 | 109 | struct mii_bus *new_bus; |
| 108 | 110 | struct fec_info *fec; |
| 109 | 111 | int (*get_bus_freq)(struct device_node *); |
| 110 | 112 | int ret = -ENOMEM, clock, speed; |
| 111 | 113 | |
| 112 | − if (!ofdev->dev.of_match) | |
| 114 | + match = of_match_device(fs_enet_mdio_fec_match, &ofdev->dev); | |
| 115 | + if (!match) | |
| 113 | 116 | return -EINVAL; |
| 114 | − get_bus_freq = ofdev->dev.of_match->data; | |
| 117 | + get_bus_freq = match->data; | |
| 115 | 118 | |
| 116 | 119 | new_bus = mdiobus_alloc(); |
| 117 | 120 | if (!new_bus) |
| @@ -139,11 +139,11 @@ static int ftmac100_reset(struct ftmac100 *priv) · 138 unmodified lines | ||
| 139 | 139 | * that hardware reset completed (what the f*ck). |
| 140 | 140 | * We still need to wait for a while. |
| 141 | 141 | */ |
| 142 | − usleep_range(500, 1000); | |
| 142 | + udelay(500); | |
| 143 | 143 | return 0; |
| 144 | 144 | } |
| 145 | 145 | |
| 146 | − usleep_range(1000, 10000); | |
| 146 | + udelay(1000); | |
| 147 | 147 | } |
| 148 | 148 | |
| 149 | 149 | netdev_err(netdev, "software reset failed\n"); |
| @@ -772,7 +772,7 @@ static int ftmac100_mdio_read(struct net_device *netdev, int phy_id, int reg) · 622 unmodified lines | ||
| 772 | 772 | if ((phycr & FTMAC100_PHYCR_MIIRD) == 0) |
| 773 | 773 | return phycr & FTMAC100_PHYCR_MIIRDATA; |
| 774 | 774 | |
| 775 | − usleep_range(100, 1000); | |
| 775 | + udelay(100); | |
| 776 | 776 | } |
| 777 | 777 | |
| 778 | 778 | netdev_err(netdev, "mdio read timed out\n"); |
| @@ -801,7 +801,7 @@ static void ftmac100_mdio_write(struct net_device *netdev, int phy_id, int reg, · 22 unmodified lines | ||
| 801 | 801 | if ((phycr & FTMAC100_PHYCR_MIIWR) == 0) |
| 802 | 802 | return; |
| 803 | 803 | |
| 804 | − usleep_range(100, 1000); | |
| 804 | + udelay(100); | |
| 805 | 805 | } |
| 806 | 806 | |
| 807 | 807 | netdev_err(netdev, "mdio write timed out\n"); |
| @@ -98,15 +98,15 @@ static const struct net_device_ops hydra_netdev_ops = { · 97 unmodified lines | ||
| 98 | 98 | .ndo_open = hydra_open, |
| 99 | 99 | .ndo_stop = hydra_close, |
| 100 | 100 | |
| 101 | − .ndo_start_xmit = ei_start_xmit, | |
| 102 | − .ndo_tx_timeout = ei_tx_timeout, | |
| 103 | − .ndo_get_stats = ei_get_stats, | |
| 104 | − .ndo_set_multicast_list = ei_set_multicast_list, | |
| 101 | + .ndo_start_xmit = __ei_start_xmit, | |
| 102 | + .ndo_tx_timeout = __ei_tx_timeout, | |
| 103 | + .ndo_get_stats = __ei_get_stats, | |
| 104 | + .ndo_set_multicast_list = __ei_set_multicast_list, | |
| 105 | 105 | .ndo_validate_addr = eth_validate_addr, |
| 106 | − .ndo_set_mac_address = eth_mac_addr, | |
| 106 | + .ndo_set_mac_address = eth_mac_addr, | |
| 107 | 107 | .ndo_change_mtu = eth_change_mtu, |
| 108 | 108 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 109 | − .ndo_poll_controller = ei_poll, | |
| 109 | + .ndo_poll_controller = __ei_poll, | |
| 110 | 110 | #endif |
| 111 | 111 | }; |
| 112 | 112 | |
| @@ -125,7 +125,7 @@ static int __devinit hydra_init(struct zorro_dev *z) · 12 unmodified lines | ||
| 125 | 125 | 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, |
| 126 | 126 | }; |
| 127 | 127 | |
| 128 | − dev = alloc_ei_netdev(); | |
| 128 | + dev = ____alloc_ei_netdev(0); | |
| 129 | 129 | if (!dev) |
| 130 | 130 | return -ENOMEM; |
| 131 | 131 | |
| @@ -173,7 +173,8 @@ static void loopback_setup(struct net_device *dev) · 172 unmodified lines | ||
| 173 | 173 | | NETIF_F_RXCSUM |
| 174 | 174 | | NETIF_F_HIGHDMA |
| 175 | 175 | | NETIF_F_LLTX |
| 176 | − | NETIF_F_NETNS_LOCAL; | |
| 176 | + | NETIF_F_NETNS_LOCAL | |
| 177 | + | NETIF_F_VLAN_CHALLENGED; | |
| 177 | 178 | dev->ethtool_ops = &loopback_ethtool_ops; |
| 178 | 179 | dev->header_ops = ð_header_ops; |
| 179 | 180 | dev->netdev_ops = &loopback_ops; |
| @@ -49,6 +49,10 @@ static u32 mii_get_an(struct mii_if_info *mii, u16 addr) · 48 unmodified lines | ||
| 49 | 49 | result |= ADVERTISED_100baseT_Half; |
| 50 | 50 | if (advert & ADVERTISE_100FULL) |
| 51 | 51 | result |= ADVERTISED_100baseT_Full; |
| 52 | + if (advert & ADVERTISE_PAUSE_CAP) | |
| 53 | + result |= ADVERTISED_Pause; | |
| 54 | + if (advert & ADVERTISE_PAUSE_ASYM) | |
| 55 | + result |= ADVERTISED_Asym_Pause; | |
| 52 | 56 | |
| 53 | 57 | return result; |
| 54 | 58 | } |
| @@ -860,6 +860,9 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, · 859 unmodified lines | ||
| 860 | 860 | prev_eedata = eedata; |
| 861 | 861 | } |
| 862 | 862 | |
| 863 | + /* Store MAC Address in perm_addr */ | |
| 864 | + memcpy(dev->perm_addr, dev->dev_addr, ETH_ALEN); | |
| 865 | + | |
| 863 | 866 | dev->base_addr = (unsigned long __force) ioaddr; |
| 864 | 867 | dev->irq = irq; |
| 865 | 868 | |
| @@ -167,7 +167,7 @@ static void cleanup_card(struct net_device *dev) · 166 unmodified lines | ||
| 167 | 167 | #ifndef MODULE |
| 168 | 168 | struct net_device * __init ne_probe(int unit) |
| 169 | 169 | { |
| 170 | − struct net_device *dev = alloc_ei_netdev(); | |
| 170 | + struct net_device *dev = ____alloc_ei_netdev(0); | |
| 171 | 171 | int err; |
| 172 | 172 | |
| 173 | 173 | if (!dev) |
| @@ -197,15 +197,15 @@ static const struct net_device_ops ne_netdev_ops = { · 23 unmodified lines | ||
| 197 | 197 | .ndo_open = ne_open, |
| 198 | 198 | .ndo_stop = ne_close, |
| 199 | 199 | |
| 200 | − .ndo_start_xmit = ei_start_xmit, | |
| 201 | − .ndo_tx_timeout = ei_tx_timeout, | |
| 202 | − .ndo_get_stats = ei_get_stats, | |
| 203 | − .ndo_set_multicast_list = ei_set_multicast_list, | |
| 200 | + .ndo_start_xmit = __ei_start_xmit, | |
| 201 | + .ndo_tx_timeout = __ei_tx_timeout, | |
| 202 | + .ndo_get_stats = __ei_get_stats, | |
| 203 | + .ndo_set_multicast_list = __ei_set_multicast_list, | |
| 204 | 204 | .ndo_validate_addr = eth_validate_addr, |
| 205 | − .ndo_set_mac_address = eth_mac_addr, | |
| 205 | + .ndo_set_mac_address = eth_mac_addr, | |
| 206 | 206 | .ndo_change_mtu = eth_change_mtu, |
| 207 | 207 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 208 | − .ndo_poll_controller = ei_poll, | |
| 208 | + .ndo_poll_controller = __ei_poll, | |
| 209 | 209 | #endif |
| 210 | 210 | }; |
| 211 | 211 | |
| @@ -637,7 +637,7 @@ int init_module(void) · 425 unmodified lines | ||
| 637 | 637 | int err; |
| 638 | 638 | |
| 639 | 639 | for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { |
| 640 | − struct net_device *dev = alloc_ei_netdev(); | |
| 640 | + struct net_device *dev = ____alloc_ei_netdev(0); | |
| 641 | 641 | if (!dev) |
| 642 | 642 | break; |
| 643 | 643 | if (io[this_dev]) { |
| @@ -671,6 +671,7 @@ static int netconsole_netdev_event(struct notifier_block *this, · 670 unmodified lines | ||
| 671 | 671 | goto done; |
| 672 | 672 | |
| 673 | 673 | spin_lock_irqsave(&target_list_lock, flags); |
| 674 | +restart: | |
| 674 | 675 | list_for_each_entry(nt, &target_list, list) { |
| 675 | 676 | netconsole_target_get(nt); |
| 676 | 677 | if (nt->np.dev == dev) { |
| @@ -683,9 +684,16 @@ static int netconsole_netdev_event(struct notifier_block *this, · 6 unmodified lines | ||
| 683 | 684 | * rtnl_lock already held |
| 684 | 685 | */ |
| 685 | 686 | if (nt->np.dev) { |
| 687 | + spin_unlock_irqrestore( | |
| 688 | + &target_list_lock, | |
| 689 | + flags); | |
| 686 | 690 | __netpoll_cleanup(&nt->np); |
| 691 | + spin_lock_irqsave(&target_list_lock, | |
| 692 | + flags); | |
| 687 | 693 | dev_put(nt->np.dev); |
| 688 | 694 | nt->np.dev = NULL; |
| 695 | + netconsole_target_put(nt); | |
| 696 | + goto restart; | |
| 689 | 697 | } |
| 690 | 698 | /* Fall through */ |
| 691 | 699 | case NETDEV_GOING_DOWN: |
| @@ -174,7 +174,7 @@ · 173 unmodified lines | ||
| 174 | 174 | |
| 175 | 175 | #define MAX_NUM_CARDS 4 |
| 176 | 176 | |
| 177 | −#define MAX_BUFFERS_PER_CMD 32 | |
| 177 | +#define NETXEN_MAX_FRAGS_PER_TX 14 | |
| 178 | 178 | #define MAX_TSO_HEADER_DESC 2 |
| 179 | 179 | #define MGMT_CMD_DESC_RESV 4 |
| 180 | 180 | #define TX_STOP_THRESH ((MAX_SKB_FRAGS >> 2) + MAX_TSO_HEADER_DESC \ |
| @@ -558,7 +558,7 @@ struct netxen_recv_crb { · 377 unmodified lines | ||
| 558 | 558 | */ |
| 559 | 559 | struct netxen_cmd_buffer { |
| 560 | 560 | struct sk_buff *skb; |
| 561 | − struct netxen_skb_frag frag_array[MAX_BUFFERS_PER_CMD + 1]; | |
| 561 | + struct netxen_skb_frag frag_array[MAX_SKB_FRAGS + 1]; | |
| 562 | 562 | u32 frag_count; |
| 563 | 563 | }; |
| 564 | 564 | |
| @@ -1844,6 +1844,8 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) · 1843 unmodified lines | ||
| 1844 | 1844 | struct cmd_desc_type0 *hwdesc, *first_desc; |
| 1845 | 1845 | struct pci_dev *pdev; |
| 1846 | 1846 | int i, k; |
| 1847 | + int delta = 0; | |
| 1848 | + struct skb_frag_struct *frag; | |
| 1847 | 1849 | |
| 1848 | 1850 | u32 producer; |
| 1849 | 1851 | int frag_count, no_of_desc; |
| @@ -1851,6 +1853,21 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) · 1 unmodified line | ||
| 1851 | 1853 | |
| 1852 | 1854 | frag_count = skb_shinfo(skb)->nr_frags + 1; |
| 1853 | 1855 | |
| 1856 | + /* 14 frags supported for normal packet and | |
| 1857 | + * 32 frags supported for TSO packet | |
| 1858 | + */ | |
| 1859 | + if (!skb_is_gso(skb) && frag_count > NETXEN_MAX_FRAGS_PER_TX) { | |
| 1860 | + | |
| 1861 | + for (i = 0; i < (frag_count - NETXEN_MAX_FRAGS_PER_TX); i++) { | |
| 1862 | + frag = &skb_shinfo(skb)->frags[i]; | |
| 1863 | + delta += frag->size; | |
| 1864 | + } | |
| 1865 | + | |
| 1866 | + if (!__pskb_pull_tail(skb, delta)) | |
| 1867 | + goto drop_packet; | |
| 1868 | + | |
| 1869 | + frag_count = 1 + skb_shinfo(skb)->nr_frags; | |
| 1870 | + } | |
| 1854 | 1871 | /* 4 fragments per cmd des */ |
| 1855 | 1872 | no_of_desc = (frag_count + 3) >> 2; |
| 1856 | 1873 | |
| @@ -34,6 +34,10 @@ const char pch_driver_version[] = DRV_VERSION; · 33 unmodified lines | ||
| 34 | 34 | #define PCH_GBE_COPYBREAK_DEFAULT 256 |
| 35 | 35 | #define PCH_GBE_PCI_BAR 1 |
| 36 | 36 | |
| 37 | +/* Macros for ML7223 */ | |
| 38 | +#define PCI_VENDOR_ID_ROHM 0x10db | |
| 39 | +#define PCI_DEVICE_ID_ROHM_ML7223_GBE 0x8013 | |
| 40 | + | |
| 37 | 41 | #define PCH_GBE_TX_WEIGHT 64 |
| 38 | 42 | #define PCH_GBE_RX_WEIGHT 64 |
| 39 | 43 | #define PCH_GBE_RX_BUFFER_WRITE 16 |
| @@ -43,8 +47,7 @@ const char pch_driver_version[] = DRV_VERSION; · 3 unmodified lines | ||
| 43 | 47 | |
| 44 | 48 | #define PCH_GBE_MAC_RGMII_CTRL_SETTING ( \ |
| 45 | 49 | PCH_GBE_CHIP_TYPE_INTERNAL | \ |
| 46 | − PCH_GBE_RGMII_MODE_RGMII | \ | |
| 47 | − PCH_GBE_CRS_SEL \ | |
| 50 | + PCH_GBE_RGMII_MODE_RGMII \ | |
| 48 | 51 | ) |
| 49 | 52 | |
| 50 | 53 | /* Ethertype field values */ |
| @@ -1494,12 +1497,11 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter, · 1443 unmodified lines | ||
| 1494 | 1497 | /* Write meta date of skb */ |
| 1495 | 1498 | skb_put(skb, length); |
| 1496 | 1499 | skb->protocol = eth_type_trans(skb, netdev); |
| 1497 | − if ((tcp_ip_status & PCH_GBE_RXD_ACC_STAT_TCPIPOK) == | |
| 1498 | − PCH_GBE_RXD_ACC_STAT_TCPIPOK) { | |
| 1499 | − skb->ip_summed = CHECKSUM_UNNECESSARY; | |
| 1500 | − } else { | |
| 1500 | + if (tcp_ip_status & PCH_GBE_RXD_ACC_STAT_TCPIPOK) | |
| 1501 | 1501 | skb->ip_summed = CHECKSUM_NONE; |
| 1502 | − } | |
| 1502 | + else | |
| 1503 | + skb->ip_summed = CHECKSUM_UNNECESSARY; | |
| 1504 | + | |
| 1503 | 1505 | napi_gro_receive(&adapter->napi, skb); |
| 1504 | 1506 | (*work_done)++; |
| 1505 | 1507 | pr_debug("Receive skb->ip_summed: %d length: %d\n", |
| @@ -2420,6 +2422,13 @@ static DEFINE_PCI_DEVICE_TABLE(pch_gbe_pcidev_id) = { · 914 unmodified lines | ||
| 2420 | 2422 | .class = (PCI_CLASS_NETWORK_ETHERNET << 8), |
| 2421 | 2423 | .class_mask = (0xFFFF00) |
| 2422 | 2424 | }, |
| 2425 | + {.vendor = PCI_VENDOR_ID_ROHM, | |
| 2426 | + .device = PCI_DEVICE_ID_ROHM_ML7223_GBE, | |
| 2427 | + .subvendor = PCI_ANY_ID, | |
| 2428 | + .subdevice = PCI_ANY_ID, | |
| 2429 | + .class = (PCI_CLASS_NETWORK_ETHERNET << 8), | |
| 2430 | + .class_mask = (0xFFFF00) | |
| 2431 | + }, | |
| 2423 | 2432 | /* required last entry */ |
| 2424 | 2433 | {0} |
| 2425 | 2434 | }; |
| @@ -99,6 +99,7 @@ · 98 unmodified lines | ||
| 99 | 99 | #define TX_UDPV6_PKT 0x0c |
| 100 | 100 | |
| 101 | 101 | /* Tx defines */ |
| 102 | +#define QLCNIC_MAX_FRAGS_PER_TX 14 | |
| 102 | 103 | #define MAX_TSO_HEADER_DESC 2 |
| 103 | 104 | #define MGMT_CMD_DESC_RESV 4 |
| 104 | 105 | #define TX_STOP_THRESH ((MAX_SKB_FRAGS >> 2) + MAX_TSO_HEADER_DESC \ |
| @@ -2099,6 +2099,7 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) · 2098 unmodified lines | ||
| 2099 | 2099 | struct cmd_desc_type0 *hwdesc, *first_desc; |
| 2100 | 2100 | struct pci_dev *pdev; |
| 2101 | 2101 | struct ethhdr *phdr; |
| 2102 | + int delta = 0; | |
| 2102 | 2103 | int i, k; |
| 2103 | 2104 | |
| 2104 | 2105 | u32 producer; |
| @@ -2118,6 +2119,19 @@ qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) · 13 unmodified lines | ||
| 2118 | 2119 | } |
| 2119 | 2120 | |
| 2120 | 2121 | frag_count = skb_shinfo(skb)->nr_frags + 1; |
| 2122 | + /* 14 frags supported for normal packet and | |
| 2123 | + * 32 frags supported for TSO packet | |
| 2124 | + */ | |
| 2125 | + if (!skb_is_gso(skb) && frag_count > QLCNIC_MAX_FRAGS_PER_TX) { | |
| 2126 | + | |
| 2127 | + for (i = 0; i < (frag_count - QLCNIC_MAX_FRAGS_PER_TX); i++) | |
| 2128 | + delta += skb_shinfo(skb)->frags[i].size; | |
| 2129 | + | |
| 2130 | + if (!__pskb_pull_tail(skb, delta)) | |
| 2131 | + goto drop_packet; | |
| 2132 | + | |
| 2133 | + frag_count = 1 + skb_shinfo(skb)->nr_frags; | |
| 2134 | + } | |
| 2121 | 2135 | |
| 2122 | 2136 | /* 4 fragments per cmd des */ |
| 2123 | 2137 | no_of_desc = (frag_count + 3) >> 2; |
| @@ -170,6 +170,16 @@ static const struct { · 169 unmodified lines | ||
| 170 | 170 | }; |
| 171 | 171 | #undef _R |
| 172 | 172 | |
| 173 | +static const struct rtl_firmware_info { | |
| 174 | + int mac_version; | |
| 175 | + const char *fw_name; | |
| 176 | +} rtl_firmware_infos[] = { | |
| 177 | + { .mac_version = RTL_GIGA_MAC_VER_25, .fw_name = FIRMWARE_8168D_1 }, | |
| 178 | + { .mac_version = RTL_GIGA_MAC_VER_26, .fw_name = FIRMWARE_8168D_2 }, | |
| 179 | + { .mac_version = RTL_GIGA_MAC_VER_29, .fw_name = FIRMWARE_8105E_1 }, | |
| 180 | + { .mac_version = RTL_GIGA_MAC_VER_30, .fw_name = FIRMWARE_8105E_1 } | |
| 181 | +}; | |
| 182 | + | |
| 173 | 183 | enum cfg_version { |
| 174 | 184 | RTL_CFG_0 = 0x00, |
| 175 | 185 | RTL_CFG_1, |
| @@ -565,6 +575,7 @@ struct rtl8169_private { · 389 unmodified lines | ||
| 565 | 575 | u32 saved_wolopts; |
| 566 | 576 | |
| 567 | 577 | const struct firmware *fw; |
| 578 | +#define RTL_FIRMWARE_UNKNOWN ERR_PTR(-EAGAIN); | |
| 568 | 579 | }; |
| 569 | 580 | |
| 570 | 581 | MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); |
| @@ -1789,25 +1800,26 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw) · 1218 unmodified lines | ||
| 1789 | 1800 | |
| 1790 | 1801 | static void rtl_release_firmware(struct rtl8169_private *tp) |
| 1791 | 1802 | { |
| 1792 | − release_firmware(tp->fw); | |
| 1793 | − tp->fw = NULL; | |
| 1803 | + if (!IS_ERR_OR_NULL(tp->fw)) | |
| 1804 | + release_firmware(tp->fw); | |
| 1805 | + tp->fw = RTL_FIRMWARE_UNKNOWN; | |
| 1794 | 1806 | } |
| 1795 | 1807 | |
| 1796 | −static int rtl_apply_firmware(struct rtl8169_private *tp, const char *fw_name) | |
| 1808 | +static void rtl_apply_firmware(struct rtl8169_private *tp) | |
| 1797 | 1809 | { |
| 1798 | − const struct firmware **fw = &tp->fw; | |
| 1799 | − int rc = !*fw; | |
| 1800 | − | |
| 1801 | − if (rc) { | |
| 1802 | − rc = request_firmware(fw, fw_name, &tp->pci_dev->dev); | |
| 1803 | − if (rc < 0) | |
| 1804 | − goto out; | |
| 1805 | − } | |
| 1810 | + const struct firmware *fw = tp->fw; | |
| 1806 | 1811 | |
| 1807 | 1812 | /* TODO: release firmware once rtl_phy_write_fw signals failures. */ |
| 1808 | − rtl_phy_write_fw(tp, *fw); | |
| 1809 | −out: | |
| 1810 | − return rc; | |
| 1813 | + if (!IS_ERR_OR_NULL(fw)) | |
| 1814 | + rtl_phy_write_fw(tp, fw); | |
| 1815 | +} | |
| 1816 | + | |
| 1817 | +static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val) | |
| 1818 | +{ | |
| 1819 | + if (rtl_readphy(tp, reg) != val) | |
| 1820 | + netif_warn(tp, hw, tp->dev, "chipset not ready for firmware\n"); | |
| 1821 | + else | |
| 1822 | + rtl_apply_firmware(tp); | |
| 1811 | 1823 | } |
| 1812 | 1824 | |
| 1813 | 1825 | static void rtl8169s_hw_phy_config(struct rtl8169_private *tp) |
| @@ -2246,10 +2258,8 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp) · 432 unmodified lines | ||
| 2246 | 2258 | |
| 2247 | 2259 | rtl_writephy(tp, 0x1f, 0x0005); |
| 2248 | 2260 | rtl_writephy(tp, 0x05, 0x001b); |
| 2249 | − if ((rtl_readphy(tp, 0x06) != 0xbf00) || | |
| 2250 | − (rtl_apply_firmware(tp, FIRMWARE_8168D_1) < 0)) { | |
| 2251 | − netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n"); | |
| 2252 | − } | |
| 2261 | + | |
| 2262 | + rtl_apply_firmware_cond(tp, MII_EXPANSION, 0xbf00); | |
| 2253 | 2263 | |
| 2254 | 2264 | rtl_writephy(tp, 0x1f, 0x0000); |
| 2255 | 2265 | } |
| @@ -2351,10 +2361,8 @@ static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp) · 95 unmodified lines | ||
| 2351 | 2361 | |
| 2352 | 2362 | rtl_writephy(tp, 0x1f, 0x0005); |
| 2353 | 2363 | rtl_writephy(tp, 0x05, 0x001b); |
| 2354 | − if ((rtl_readphy(tp, 0x06) != 0xb300) || | |
| 2355 | − (rtl_apply_firmware(tp, FIRMWARE_8168D_2) < 0)) { | |
| 2356 | − netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n"); | |
| 2357 | − } | |
| 2364 | + | |
| 2365 | + rtl_apply_firmware_cond(tp, MII_EXPANSION, 0xb300); | |
| 2358 | 2366 | |
| 2359 | 2367 | rtl_writephy(tp, 0x1f, 0x0000); |
| 2360 | 2368 | } |
| @@ -2474,8 +2482,7 @@ static void rtl8105e_hw_phy_config(struct rtl8169_private *tp) · 113 unmodified lines | ||
| 2474 | 2482 | rtl_writephy(tp, 0x18, 0x0310); |
| 2475 | 2483 | msleep(100); |
| 2476 | 2484 | |
| 2477 | − if (rtl_apply_firmware(tp, FIRMWARE_8105E_1) < 0) | |
| 2478 | − netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n"); | |
| 2485 | + rtl_apply_firmware(tp); | |
| 2479 | 2486 | |
| 2480 | 2487 | rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); |
| 2481 | 2488 | } |
| @@ -3237,6 +3244,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) · 755 unmodified lines | ||
| 3237 | 3244 | tp->timer.data = (unsigned long) dev; |
| 3238 | 3245 | tp->timer.function = rtl8169_phy_timer; |
| 3239 | 3246 | |
| 3247 | + tp->fw = RTL_FIRMWARE_UNKNOWN; | |
| 3248 | + | |
| 3240 | 3249 | rc = register_netdev(dev); |
| 3241 | 3250 | if (rc < 0) |
| 3242 | 3251 | goto err_out_msi_4; |
| @@ -3288,10 +3297,10 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) · 45 unmodified lines | ||
| 3288 | 3297 | |
| 3289 | 3298 | cancel_delayed_work_sync(&tp->task); |
| 3290 | 3299 | |
| 3291 | − rtl_release_firmware(tp); | |
| 3292 | − | |
| 3293 | 3300 | unregister_netdev(dev); |
| 3294 | 3301 | |
| 3302 | + rtl_release_firmware(tp); | |
| 3303 | + | |
| 3295 | 3304 | if (pci_dev_run_wake(pdev)) |
| 3296 | 3305 | pm_runtime_get_noresume(&pdev->dev); |
| 3297 | 3306 | |
| @@ -3303,6 +3312,37 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) · 5 unmodified lines | ||
| 3303 | 3312 | pci_set_drvdata(pdev, NULL); |
| 3304 | 3313 | } |
| 3305 | 3314 | |
| 3315 | +static void rtl_request_firmware(struct rtl8169_private *tp) | |
| 3316 | +{ | |
| 3317 | + int i; | |
| 3318 | + | |
| 3319 | + /* Return early if the firmware is already loaded / cached. */ | |
| 3320 | + if (!IS_ERR(tp->fw)) | |
| 3321 | + goto out; | |
| 3322 | + | |
| 3323 | + for (i = 0; i < ARRAY_SIZE(rtl_firmware_infos); i++) { | |
| 3324 | + const struct rtl_firmware_info *info = rtl_firmware_infos + i; | |
| 3325 | + | |
| 3326 | + if (info->mac_version == tp->mac_version) { | |
| 3327 | + const char *name = info->fw_name; | |
| 3328 | + int rc; | |
| 3329 | + | |
| 3330 | + rc = request_firmware(&tp->fw, name, &tp->pci_dev->dev); | |
| 3331 | + if (rc < 0) { | |
| 3332 | + netif_warn(tp, ifup, tp->dev, "unable to load " | |
| 3333 | + "firmware patch %s (%d)\n", name, rc); | |
| 3334 | + goto out_disable_request_firmware; | |
| 3335 | + } | |
| 3336 | + goto out; | |
| 3337 | + } | |
| 3338 | + } | |
| 3339 | + | |
| 3340 | +out_disable_request_firmware: | |
| 3341 | + tp->fw = NULL; | |
| 3342 | +out: | |
| 3343 | + return; | |
| 3344 | +} | |
| 3345 | + | |
| 3306 | 3346 | static int rtl8169_open(struct net_device *dev) |
| 3307 | 3347 | { |
| 3308 | 3348 | struct rtl8169_private *tp = netdev_priv(dev); |
| @@ -3334,11 +3374,13 @@ static int rtl8169_open(struct net_device *dev) · 25 unmodified lines | ||
| 3334 | 3374 | |
| 3335 | 3375 | smp_mb(); |
| 3336 | 3376 | |
| 3377 | + rtl_request_firmware(tp); | |
| 3378 | + | |
| 3337 | 3379 | retval = request_irq(dev->irq, rtl8169_interrupt, |
| 3338 | 3380 | (tp->features & RTL_FEATURE_MSI) ? 0 : IRQF_SHARED, |
| 3339 | 3381 | dev->name, dev); |
| 3340 | 3382 | if (retval < 0) |
| 3341 | − goto err_release_ring_2; | |
| 3383 | + goto err_release_fw_2; | |
| 3342 | 3384 | |
| 3343 | 3385 | napi_enable(&tp->napi); |
| 3344 | 3386 | |
| @@ -3359,7 +3401,8 @@ static int rtl8169_open(struct net_device *dev) · 14 unmodified lines | ||
| 3359 | 3401 | out: |
| 3360 | 3402 | return retval; |
| 3361 | 3403 | |
| 3362 | −err_release_ring_2: | |
| 3404 | +err_release_fw_2: | |
| 3405 | + rtl_release_firmware(tp); | |
| 3363 | 3406 | rtl8169_rx_clear(tp); |
| 3364 | 3407 | err_free_rx_1: |
| 3365 | 3408 | dma_free_coherent(&pdev->dev, R8169_RX_RING_BYTES, tp->RxDescArray, |
| @@ -328,7 +328,8 @@ static int efx_poll(struct napi_struct *napi, int budget) · 327 unmodified lines | ||
| 328 | 328 | * processing to finish, then directly poll (and ack ) the eventq. |
| 329 | 329 | * Finally reenable NAPI and interrupts. |
| 330 | 330 | * |
| 331 | − * Since we are touching interrupts the caller should hold the suspend lock | |
| 331 | + * This is for use only during a loopback self-test. It must not | |
| 332 | + * deliver any packets up the stack as this can result in deadlock. | |
| 332 | 333 | */ |
| 333 | 334 | void efx_process_channel_now(struct efx_channel *channel) |
| 334 | 335 | { |
| @@ -336,6 +337,7 @@ void efx_process_channel_now(struct efx_channel *channel) · 1 unmodified line | ||
| 336 | 337 | |
| 337 | 338 | BUG_ON(channel->channel >= efx->n_channels); |
| 338 | 339 | BUG_ON(!channel->enabled); |
| 340 | + BUG_ON(!efx->loopback_selftest); | |
| 339 | 341 | |
| 340 | 342 | /* Disable interrupts and wait for ISRs to complete */ |
| 341 | 343 | efx_nic_disable_interrupts(efx); |
| @@ -1436,7 +1438,7 @@ static void efx_start_all(struct efx_nic *efx) · 1094 unmodified lines | ||
| 1436 | 1438 | * restart the transmit interface early so the watchdog timer stops */ |
| 1437 | 1439 | efx_start_port(efx); |
| 1438 | 1440 | |
| 1439 | − if (efx_dev_registered(efx)) | |
| 1441 | + if (efx_dev_registered(efx) && !efx->port_inhibited) | |
| 1440 | 1442 | netif_tx_wake_all_queues(efx->net_dev); |
| 1441 | 1443 | |
| 1442 | 1444 | efx_for_each_channel(channel, efx) |
| @@ -152,6 +152,7 @@ static inline void efx_reado(struct efx_nic *efx, efx_oword_t *value, · 151 unmodified lines | ||
| 152 | 152 | |
| 153 | 153 | spin_lock_irqsave(&efx->biu_lock, flags); |
| 154 | 154 | value->u32[0] = _efx_readd(efx, reg + 0); |
| 155 | + rmb(); | |
| 155 | 156 | value->u32[1] = _efx_readd(efx, reg + 4); |
| 156 | 157 | value->u32[2] = _efx_readd(efx, reg + 8); |
| 157 | 158 | value->u32[3] = _efx_readd(efx, reg + 12); |
| @@ -174,6 +175,7 @@ static inline void efx_sram_readq(struct efx_nic *efx, void __iomem *membase, · 16 unmodified lines | ||
| 174 | 175 | value->u64[0] = (__force __le64)__raw_readq(membase + addr); |
| 175 | 176 | #else |
| 176 | 177 | value->u32[0] = (__force __le32)__raw_readl(membase + addr); |
| 178 | + rmb(); | |
| 177 | 179 | value->u32[1] = (__force __le32)__raw_readl(membase + addr + 4); |
| 178 | 180 | #endif |
| 179 | 181 | spin_unlock_irqrestore(&efx->biu_lock, flags); |
| @@ -50,6 +50,20 @@ static inline struct efx_mcdi_iface *efx_mcdi(struct efx_nic *efx) · 49 unmodified lines | ||
| 50 | 50 | return &nic_data->mcdi; |
| 51 | 51 | } |
| 52 | 52 | |
| 53 | +static inline void | |
| 54 | +efx_mcdi_readd(struct efx_nic *efx, efx_dword_t *value, unsigned reg) | |
| 55 | +{ | |
| 56 | + struct siena_nic_data *nic_data = efx->nic_data; | |
| 57 | + value->u32[0] = (__force __le32)__raw_readl(nic_data->mcdi_smem + reg); | |
| 58 | +} | |
| 59 | + | |
| 60 | +static inline void | |
| 61 | +efx_mcdi_writed(struct efx_nic *efx, const efx_dword_t *value, unsigned reg) | |
| 62 | +{ | |
| 63 | + struct siena_nic_data *nic_data = efx->nic_data; | |
| 64 | + __raw_writel((__force u32)value->u32[0], nic_data->mcdi_smem + reg); | |
| 65 | +} | |
| 66 | + | |
| 53 | 67 | void efx_mcdi_init(struct efx_nic *efx) |
| 54 | 68 | { |
| 55 | 69 | struct efx_mcdi_iface *mcdi; |
| @@ -70,8 +84,8 @@ static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd, · 14 unmodified lines | ||
| 70 | 84 | const u8 *inbuf, size_t inlen) |
| 71 | 85 | { |
| 72 | 86 | struct efx_mcdi_iface *mcdi = efx_mcdi(efx); |
| 73 | − unsigned pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx); | |
| 74 | − unsigned doorbell = FR_CZ_MC_TREG_SMEM + MCDI_DOORBELL(efx); | |
| 87 | + unsigned pdu = MCDI_PDU(efx); | |
| 88 | + unsigned doorbell = MCDI_DOORBELL(efx); | |
| 75 | 89 | unsigned int i; |
| 76 | 90 | efx_dword_t hdr; |
| 77 | 91 | u32 xflags, seqno; |
| @@ -92,30 +106,28 @@ static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd, · 14 unmodified lines | ||
| 92 | 106 | MCDI_HEADER_SEQ, seqno, |
| 93 | 107 | MCDI_HEADER_XFLAGS, xflags); |
| 94 | 108 | |
| 95 | − efx_writed(efx, &hdr, pdu); | |
| 109 | + efx_mcdi_writed(efx, &hdr, pdu); | |
| 96 | 110 | |
| 97 | − for (i = 0; i < inlen; i += 4) { | |
| 98 | − _efx_writed(efx, *((__le32 *)(inbuf + i)), pdu + 4 + i); | |
| 99 | − /* use wmb() within loop to inhibit write combining */ | |
| 100 | − wmb(); | |
| 101 | − } | |
| 111 | + for (i = 0; i < inlen; i += 4) | |
| 112 | + efx_mcdi_writed(efx, (const efx_dword_t *)(inbuf + i), | |
| 113 | + pdu + 4 + i); | |
| 102 | 114 | |
| 103 | 115 | /* ring the doorbell with a distinctive value */ |
| 104 | − _efx_writed(efx, (__force __le32) 0x45789abc, doorbell); | |
| 105 | − wmb(); | |
| 116 | + EFX_POPULATE_DWORD_1(hdr, EFX_DWORD_0, 0x45789abc); | |
| 117 | + efx_mcdi_writed(efx, &hdr, doorbell); | |
| 106 | 118 | } |
| 107 | 119 | |
| 108 | 120 | static void efx_mcdi_copyout(struct efx_nic *efx, u8 *outbuf, size_t outlen) |
| 109 | 121 | { |
| 110 | 122 | struct efx_mcdi_iface *mcdi = efx_mcdi(efx); |
| 111 | − unsigned int pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx); | |
| 123 | + unsigned int pdu = MCDI_PDU(efx); | |
| 112 | 124 | int i; |
| 113 | 125 | |
| 114 | 126 | BUG_ON(atomic_read(&mcdi->state) == MCDI_STATE_QUIESCENT); |
| 115 | 127 | BUG_ON(outlen & 3 || outlen >= 0x100); |
| 116 | 128 | |
| 117 | 129 | for (i = 0; i < outlen; i += 4) |
| 118 | − *((__le32 *)(outbuf + i)) = _efx_readd(efx, pdu + 4 + i); | |
| 130 | + efx_mcdi_readd(efx, (efx_dword_t *)(outbuf + i), pdu + 4 + i); | |
| 119 | 131 | } |
| 120 | 132 | |
| 121 | 133 | static int efx_mcdi_poll(struct efx_nic *efx) |
| @@ -123,7 +135,7 @@ static int efx_mcdi_poll(struct efx_nic *efx) · 1 unmodified line | ||
| 123 | 135 | struct efx_mcdi_iface *mcdi = efx_mcdi(efx); |
| 124 | 136 | unsigned int time, finish; |
| 125 | 137 | unsigned int respseq, respcmd, error; |
| 126 | − unsigned int pdu = FR_CZ_MC_TREG_SMEM + MCDI_PDU(efx); | |
| 138 | + unsigned int pdu = MCDI_PDU(efx); | |
| 127 | 139 | unsigned int rc, spins; |
| 128 | 140 | efx_dword_t reg; |
| 129 | 141 | |
| @@ -149,8 +161,7 @@ static int efx_mcdi_poll(struct efx_nic *efx) · 19 unmodified lines | ||
| 149 | 161 | |
| 150 | 162 | time = get_seconds(); |
| 151 | 163 | |
| 152 | − rmb(); | |
| 153 | − efx_readd(efx, ®, pdu); | |
| 164 | + efx_mcdi_readd(efx, ®, pdu); | |
| 154 | 165 | |
| 155 | 166 | /* All 1's indicates that shared memory is in reset (and is |
| 156 | 167 | * not a valid header). Wait for it to come out reset before |
| @@ -177,7 +188,7 @@ static int efx_mcdi_poll(struct efx_nic *efx) · 20 unmodified lines | ||
| 177 | 188 | respseq, mcdi->seqno); |
| 178 | 189 | rc = EIO; |
| 179 | 190 | } else if (error) { |
| 180 | − efx_readd(efx, ®, pdu + 4); | |
| 191 | + efx_mcdi_readd(efx, ®, pdu + 4); | |
| 181 | 192 | switch (EFX_DWORD_FIELD(reg, EFX_DWORD_0)) { |
| 182 | 193 | #define TRANSLATE_ERROR(name) \ |
| 183 | 194 | case MC_CMD_ERR_ ## name: \ |
| @@ -211,21 +222,21 @@ out: · 27 unmodified lines | ||
| 211 | 222 | /* Test and clear MC-rebooted flag for this port/function */ |
| 212 | 223 | int efx_mcdi_poll_reboot(struct efx_nic *efx) |
| 213 | 224 | { |
| 214 | − unsigned int addr = FR_CZ_MC_TREG_SMEM + MCDI_REBOOT_FLAG(efx); | |
| 225 | + unsigned int addr = MCDI_REBOOT_FLAG(efx); | |
| 215 | 226 | efx_dword_t reg; |
| 216 | 227 | uint32_t value; |
| 217 | 228 | |
| 218 | 229 | if (efx_nic_rev(efx) < EFX_REV_SIENA_A0) |
| 219 | 230 | return false; |
| 220 | 231 | |
| 221 | − efx_readd(efx, ®, addr); | |
| 232 | + efx_mcdi_readd(efx, ®, addr); | |
| 222 | 233 | value = EFX_DWORD_FIELD(reg, EFX_DWORD_0); |
| 223 | 234 | |
| 224 | 235 | if (value == 0) |
| 225 | 236 | return 0; |
| 226 | 237 | |
| 227 | 238 | EFX_ZERO_DWORD(reg); |
| 228 | − efx_writed(efx, ®, addr); | |
| 239 | + efx_mcdi_writed(efx, ®, addr); | |
| 229 | 240 | |
| 230 | 241 | if (value == MC_STATUS_DWORD_ASSERT) |
| 231 | 242 | return -EINTR; |
| @@ -330,7 +330,6 @@ enum efx_rx_alloc_method { · 329 unmodified lines | ||
| 330 | 330 | * @eventq_mask: Event queue pointer mask |
| 331 | 331 | * @eventq_read_ptr: Event queue read pointer |
| 332 | 332 | * @last_eventq_read_ptr: Last event queue read pointer value. |
| 333 | − * @magic_count: Event queue test event count | |
| 334 | 333 | * @irq_count: Number of IRQs since last adaptive moderation decision |
| 335 | 334 | * @irq_mod_score: IRQ moderation score |
| 336 | 335 | * @rx_alloc_level: Watermark based heuristic counter for pushing descriptors |
| @@ -360,7 +359,6 @@ struct efx_channel { · 23 unmodified lines | ||
| 360 | 359 | unsigned int eventq_mask; |
| 361 | 360 | unsigned int eventq_read_ptr; |
| 362 | 361 | unsigned int last_eventq_read_ptr; |
| 363 | − unsigned int magic_count; | |
| 364 | 362 | |
| 365 | 363 | unsigned int irq_count; |
| 366 | 364 | unsigned int irq_mod_score; |
| @@ -84,7 +84,8 @@ static inline void efx_write_buf_tbl(struct efx_nic *efx, efx_qword_t *value, · 83 unmodified lines | ||
| 84 | 84 | static inline efx_qword_t *efx_event(struct efx_channel *channel, |
| 85 | 85 | unsigned int index) |
| 86 | 86 | { |
| 87 | − return ((efx_qword_t *) (channel->eventq.addr)) + index; | |
| 87 | + return ((efx_qword_t *) (channel->eventq.addr)) + | |
| 88 | + (index & channel->eventq_mask); | |
| 88 | 89 | } |
| 89 | 90 | |
| 90 | 91 | /* See if an event is present |
| @@ -673,7 +674,8 @@ void efx_nic_eventq_read_ack(struct efx_channel *channel) · 582 unmodified lines | ||
| 673 | 674 | efx_dword_t reg; |
| 674 | 675 | struct efx_nic *efx = channel->efx; |
| 675 | 676 | |
| 676 | − EFX_POPULATE_DWORD_1(reg, FRF_AZ_EVQ_RPTR, channel->eventq_read_ptr); | |
| 677 | + EFX_POPULATE_DWORD_1(reg, FRF_AZ_EVQ_RPTR, | |
| 678 | + channel->eventq_read_ptr & channel->eventq_mask); | |
| 677 | 679 | efx_writed_table(efx, ®, efx->type->evq_rptr_tbl_base, |
| 678 | 680 | channel->channel); |
| 679 | 681 | } |
| @@ -908,7 +910,7 @@ efx_handle_generated_event(struct efx_channel *channel, efx_qword_t *event) · 228 unmodified lines | ||
| 908 | 910 | |
| 909 | 911 | code = EFX_QWORD_FIELD(*event, FSF_AZ_DRV_GEN_EV_MAGIC); |
| 910 | 912 | if (code == EFX_CHANNEL_MAGIC_TEST(channel)) |
| 911 | − ++channel->magic_count; | |
| 913 | + ; /* ignore */ | |
| 912 | 914 | else if (code == EFX_CHANNEL_MAGIC_FILL(channel)) |
| 913 | 915 | /* The queue must be empty, so we won't receive any rx |
| 914 | 916 | * events, so efx_process_channel() won't refill the |
| @@ -1015,8 +1017,7 @@ int efx_nic_process_eventq(struct efx_channel *channel, int budget) · 100 unmodified lines | ||
| 1015 | 1017 | /* Clear this event by marking it all ones */ |
| 1016 | 1018 | EFX_SET_QWORD(*p_event); |
| 1017 | 1019 | |
| 1018 | − /* Increment read pointer */ | |
| 1019 | − read_ptr = (read_ptr + 1) & channel->eventq_mask; | |
| 1020 | + ++read_ptr; | |
| 1020 | 1021 | |
| 1021 | 1022 | ev_code = EFX_QWORD_FIELD(event, FSF_AZ_EV_CODE); |
| 1022 | 1023 | |
| @@ -1060,6 +1061,13 @@ out: · 37 unmodified lines | ||
| 1060 | 1061 | return spent; |
| 1061 | 1062 | } |
| 1062 | 1063 | |
| 1064 | +/* Check whether an event is present in the eventq at the current | |
| 1065 | + * read pointer. Only useful for self-test. | |
| 1066 | + */ | |
| 1067 | +bool efx_nic_event_present(struct efx_channel *channel) | |
| 1068 | +{ | |
| 1069 | + return efx_event_present(efx_event(channel, channel->eventq_read_ptr)); | |
| 1070 | +} | |
| 1063 | 1071 | |
| 1064 | 1072 | /* Allocate buffer table entries for event queue */ |
| 1065 | 1073 | int efx_nic_probe_eventq(struct efx_channel *channel) |
| @@ -1165,7 +1173,7 @@ static void efx_poll_flush_events(struct efx_nic *efx) · 99 unmodified lines | ||
| 1165 | 1173 | struct efx_tx_queue *tx_queue; |
| 1166 | 1174 | struct efx_rx_queue *rx_queue; |
| 1167 | 1175 | unsigned int read_ptr = channel->eventq_read_ptr; |
| 1168 | − unsigned int end_ptr = (read_ptr - 1) & channel->eventq_mask; | |
| 1176 | + unsigned int end_ptr = read_ptr + channel->eventq_mask - 1; | |
| 1169 | 1177 | |
| 1170 | 1178 | do { |
| 1171 | 1179 | efx_qword_t *event = efx_event(channel, read_ptr); |
| @@ -1205,7 +1213,7 @@ static void efx_poll_flush_events(struct efx_nic *efx) · 33 unmodified lines | ||
| 1205 | 1213 | * it's ok to throw away every non-flush event */ |
| 1206 | 1214 | EFX_SET_QWORD(*event); |
| 1207 | 1215 | |
| 1208 | − read_ptr = (read_ptr + 1) & channel->eventq_mask; | |
| 1216 | + ++read_ptr; | |
| 1209 | 1217 | } while (read_ptr != end_ptr); |
| 1210 | 1218 | |
| 1211 | 1219 | channel->eventq_read_ptr = read_ptr; |
| @@ -1929,6 +1937,13 @@ void efx_nic_get_regs(struct efx_nic *efx, void *buf) · 717 unmodified lines | ||
| 1929 | 1937 | |
| 1930 | 1938 | size = min_t(size_t, table->step, 16); |
| 1931 | 1939 | |
| 1940 | + if (table->offset >= efx->type->mem_map_size) { | |
| 1941 | + /* No longer mapped; return dummy data */ | |
| 1942 | + memcpy(buf, "\xde\xc0\xad\xde", 4); | |
| 1943 | + buf += table->rows * size; | |
| 1944 | + continue; | |
| 1945 | + } | |
| 1946 | + | |
| 1932 | 1947 | for (i = 0; i < table->rows; i++) { |
| 1933 | 1948 | switch (table->step) { |
| 1934 | 1949 | case 4: /* 32-bit register or SRAM */ |
| @@ -143,10 +143,12 @@ static inline struct falcon_board *falcon_board(struct efx_nic *efx) · 142 unmodified lines | ||
| 143 | 143 | /** |
| 144 | 144 | * struct siena_nic_data - Siena NIC state |
| 145 | 145 | * @mcdi: Management-Controller-to-Driver Interface |
| 146 | + * @mcdi_smem: MCDI shared memory mapping. The mapping is always uncacheable. | |
| 146 | 147 | * @wol_filter_id: Wake-on-LAN packet filter id |
| 147 | 148 | */ |
| 148 | 149 | struct siena_nic_data { |
| 149 | 150 | struct efx_mcdi_iface mcdi; |
| 151 | + void __iomem *mcdi_smem; | |
| 150 | 152 | int wol_filter_id; |
| 151 | 153 | }; |
| 152 | 154 | |
| @@ -184,6 +186,7 @@ extern void efx_nic_fini_eventq(struct efx_channel *channel); · 31 unmodified lines | ||
| 184 | 186 | extern void efx_nic_remove_eventq(struct efx_channel *channel); |
| 185 | 187 | extern int efx_nic_process_eventq(struct efx_channel *channel, int rx_quota); |
| 186 | 188 | extern void efx_nic_eventq_read_ack(struct efx_channel *channel); |
| 189 | +extern bool efx_nic_event_present(struct efx_channel *channel); | |
| 187 | 190 | |
| 188 | 191 | /* MAC/PHY */ |
| 189 | 192 | extern void falcon_drain_tx_fifo(struct efx_nic *efx); |
| @@ -131,8 +131,6 @@ static int efx_test_chip(struct efx_nic *efx, struct efx_self_tests *tests) · 130 unmodified lines | ||
| 131 | 131 | static int efx_test_interrupts(struct efx_nic *efx, |
| 132 | 132 | struct efx_self_tests *tests) |
| 133 | 133 | { |
| 134 | − struct efx_channel *channel; | |
| 135 | − | |
| 136 | 134 | netif_dbg(efx, drv, efx->net_dev, "testing interrupts\n"); |
| 137 | 135 | tests->interrupt = -1; |
| 138 | 136 | |
| @@ -140,15 +138,6 @@ static int efx_test_interrupts(struct efx_nic *efx, · 1 unmodified line | ||
| 140 | 138 | efx->last_irq_cpu = -1; |
| 141 | 139 | smp_wmb(); |
| 142 | 140 | |
| 143 | − /* ACK each interrupting event queue. Receiving an interrupt due to | |
| 144 | − * traffic before a test event is raised is considered a pass */ | |
| 145 | − efx_for_each_channel(channel, efx) { | |
| 146 | − if (channel->work_pending) | |
| 147 | − efx_process_channel_now(channel); | |
| 148 | − if (efx->last_irq_cpu >= 0) | |
| 149 | − goto success; | |
| 150 | − } | |
| 151 | − | |
| 152 | 141 | efx_nic_generate_interrupt(efx); |
| 153 | 142 | |
| 154 | 143 | /* Wait for arrival of test interrupt. */ |
| @@ -173,13 +162,13 @@ static int efx_test_eventq_irq(struct efx_channel *channel, · 18 unmodified lines | ||
| 173 | 162 | struct efx_self_tests *tests) |
| 174 | 163 | { |
| 175 | 164 | struct efx_nic *efx = channel->efx; |
| 176 | − unsigned int magic_count, count; | |
| 165 | + unsigned int read_ptr, count; | |
| 177 | 166 | |
| 178 | 167 | tests->eventq_dma[channel->channel] = -1; |
| 179 | 168 | tests->eventq_int[channel->channel] = -1; |
| 180 | 169 | tests->eventq_poll[channel->channel] = -1; |
| 181 | 170 | |
| 182 | − magic_count = channel->magic_count; | |
| 171 | + read_ptr = channel->eventq_read_ptr; | |
| 183 | 172 | channel->efx->last_irq_cpu = -1; |
| 184 | 173 | smp_wmb(); |
| 185 | 174 | |
| @@ -190,10 +179,7 @@ static int efx_test_eventq_irq(struct efx_channel *channel, · 4 unmodified lines | ||
| 190 | 179 | do { |
| 191 | 180 | schedule_timeout_uninterruptible(HZ / 100); |
| 192 | 181 | |
| 193 | − if (channel->work_pending) | |
| 194 | − efx_process_channel_now(channel); | |
| 195 | − | |
| 196 | − if (channel->magic_count != magic_count) | |
| 182 | + if (ACCESS_ONCE(channel->eventq_read_ptr) != read_ptr) | |
| 197 | 183 | goto eventq_ok; |
| 198 | 184 | } while (++count < 2); |
| 199 | 185 | |
| @@ -211,8 +197,7 @@ static int efx_test_eventq_irq(struct efx_channel *channel, · 11 unmodified lines | ||
| 211 | 197 | } |
| 212 | 198 | |
| 213 | 199 | /* Check to see if event was received even if interrupt wasn't */ |
| 214 | − efx_process_channel_now(channel); | |
| 215 | − if (channel->magic_count != magic_count) { | |
| 200 | + if (efx_nic_event_present(channel)) { | |
| 216 | 201 | netif_err(efx, drv, efx->net_dev, |
| 217 | 202 | "channel %d event was generated, but " |
| 218 | 203 | "failed to trigger an interrupt\n", channel->channel); |
| @@ -770,6 +755,8 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests, · 551 unmodified lines | ||
| 770 | 755 | __efx_reconfigure_port(efx); |
| 771 | 756 | mutex_unlock(&efx->mac_lock); |
| 772 | 757 | |
| 758 | + netif_tx_wake_all_queues(efx->net_dev); | |
| 759 | + | |
| 773 | 760 | return rc_test; |
| 774 | 761 | } |
| 775 | 762 | |
| @@ -220,12 +220,26 @@ static int siena_probe_nic(struct efx_nic *efx) · 219 unmodified lines | ||
| 220 | 220 | efx_reado(efx, ®, FR_AZ_CS_DEBUG); |
| 221 | 221 | efx->net_dev->dev_id = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1; |
| 222 | 222 | |
| 223 | + /* Initialise MCDI */ | |
| 224 | + nic_data->mcdi_smem = ioremap_nocache(efx->membase_phys + | |
| 225 | + FR_CZ_MC_TREG_SMEM, | |
| 226 | + FR_CZ_MC_TREG_SMEM_STEP * | |
| 227 | + FR_CZ_MC_TREG_SMEM_ROWS); | |
| 228 | + if (!nic_data->mcdi_smem) { | |
| 229 | + netif_err(efx, probe, efx->net_dev, | |
| 230 | + "could not map MCDI at %llx+%x\n", | |
| 231 | + (unsigned long long)efx->membase_phys + | |
| 232 | + FR_CZ_MC_TREG_SMEM, | |
| 233 | + FR_CZ_MC_TREG_SMEM_STEP * FR_CZ_MC_TREG_SMEM_ROWS); | |
| 234 | + rc = -ENOMEM; | |
| 235 | + goto fail1; | |
| 236 | + } | |
| 223 | 237 | efx_mcdi_init(efx); |
| 224 | 238 | |
| 225 | 239 | /* Recover from a failed assertion before probing */ |
| 226 | 240 | rc = efx_mcdi_handle_assertion(efx); |
| 227 | 241 | if (rc) |
| 228 | − goto fail1; | |
| 242 | + goto fail2; | |
| 229 | 243 | |
| 230 | 244 | /* Let the BMC know that the driver is now in charge of link and |
| 231 | 245 | * filter settings. We must do this before we reset the NIC */ |
| @@ -280,6 +294,7 @@ fail4: · 48 unmodified lines | ||
| 280 | 294 | fail3: |
| 281 | 295 | efx_mcdi_drv_attach(efx, false, NULL); |
| 282 | 296 | fail2: |
| 297 | + iounmap(nic_data->mcdi_smem); | |
| 283 | 298 | fail1: |
| 284 | 299 | kfree(efx->nic_data); |
| 285 | 300 | return rc; |
| @@ -359,6 +374,8 @@ static int siena_init_nic(struct efx_nic *efx) · 73 unmodified lines | ||
| 359 | 374 | |
| 360 | 375 | static void siena_remove_nic(struct efx_nic *efx) |
| 361 | 376 | { |
| 377 | + struct siena_nic_data *nic_data = efx->nic_data; | |
| 378 | + | |
| 362 | 379 | efx_nic_free_buffer(efx, &efx->irq_status); |
| 363 | 380 | |
| 364 | 381 | siena_reset_hw(efx, RESET_TYPE_ALL); |
| @@ -368,7 +385,8 @@ static void siena_remove_nic(struct efx_nic *efx) · 3 unmodified lines | ||
| 368 | 385 | efx_mcdi_drv_attach(efx, false, NULL); |
| 369 | 386 | |
| 370 | 387 | /* Tear down the private nic state */ |
| 371 | − kfree(efx->nic_data); | |
| 388 | + iounmap(nic_data->mcdi_smem); | |
| 389 | + kfree(nic_data); | |
| 372 | 390 | efx->nic_data = NULL; |
| 373 | 391 | } |
| 374 | 392 | |
| @@ -606,8 +624,7 @@ struct efx_nic_type siena_a0_nic_type = { · 231 unmodified lines | ||
| 606 | 624 | .default_mac_ops = &efx_mcdi_mac_operations, |
| 607 | 625 | |
| 608 | 626 | .revision = EFX_REV_SIENA_A0, |
| 609 | − .mem_map_size = (FR_CZ_MC_TREG_SMEM + | |
| 610 | − FR_CZ_MC_TREG_SMEM_STEP * FR_CZ_MC_TREG_SMEM_ROWS), | |
| 627 | + .mem_map_size = FR_CZ_MC_TREG_SMEM, /* MC_TREG_SMEM mapped separately */ | |
| 611 | 628 | .txd_ptr_tbl_base = FR_BZ_TX_DESC_PTR_TBL, |
| 612 | 629 | .rxd_ptr_tbl_base = FR_BZ_RX_DESC_PTR_TBL, |
| 613 | 630 | .buf_tbl_base = FR_BZ_BUF_FULL_TBL, |
| @@ -435,7 +435,8 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) · 434 unmodified lines | ||
| 435 | 435 | * queue state. */ |
| 436 | 436 | smp_mb(); |
| 437 | 437 | if (unlikely(netif_tx_queue_stopped(tx_queue->core_txq)) && |
| 438 | − likely(efx->port_enabled)) { | |
| 438 | + likely(efx->port_enabled) && | |
| 439 | + likely(!efx->port_inhibited)) { | |
| 439 | 440 | fill_level = tx_queue->insert_count - tx_queue->read_count; |
| 440 | 441 | if (fill_level < EFX_TXQ_THRESHOLD(efx)) { |
| 441 | 442 | EFX_BUG_ON_PARANOID(!efx_dev_registered(efx)); |
| @@ -240,7 +240,8 @@ static const struct ethtool_ops sis900_ethtool_ops; · 239 unmodified lines | ||
| 240 | 240 | * @net_dev: the net device to get address for |
| 241 | 241 | * |
| 242 | 242 | * Older SiS900 and friends, use EEPROM to store MAC address. |
| 243 | − * MAC address is read from read_eeprom() into @net_dev->dev_addr. | |
| 243 | + * MAC address is read from read_eeprom() into @net_dev->dev_addr and | |
| 244 | + * @net_dev->perm_addr. | |
| 244 | 245 | */ |
| 245 | 246 | |
| 246 | 247 | static int __devinit sis900_get_mac_addr(struct pci_dev * pci_dev, struct net_device *net_dev) |
| @@ -261,6 +262,9 @@ static int __devinit sis900_get_mac_addr(struct pci_dev * pci_dev, struct net_de · 14 unmodified lines | ||
| 261 | 262 | for (i = 0; i < 3; i++) |
| 262 | 263 | ((u16 *)(net_dev->dev_addr))[i] = read_eeprom(ioaddr, i+EEPROMMACAddr); |
| 263 | 264 | |
| 265 | + /* Store MAC Address in perm_addr */ | |
| 266 | + memcpy(net_dev->perm_addr, net_dev->dev_addr, ETH_ALEN); | |
| 267 | + | |
| 264 | 268 | return 1; |
| 265 | 269 | } |
| 266 | 270 | |
| @@ -271,7 +275,8 @@ static int __devinit sis900_get_mac_addr(struct pci_dev * pci_dev, struct net_de · 4 unmodified lines | ||
| 271 | 275 | * |
| 272 | 276 | * SiS630E model, use APC CMOS RAM to store MAC address. |
| 273 | 277 | * APC CMOS RAM is accessed through ISA bridge. |
| 274 | − * MAC address is read into @net_dev->dev_addr. | |
| 278 | + * MAC address is read into @net_dev->dev_addr and | |
| 279 | + * @net_dev->perm_addr. | |
| 275 | 280 | */ |
| 276 | 281 | |
| 277 | 282 | static int __devinit sis630e_get_mac_addr(struct pci_dev * pci_dev, |
| @@ -296,6 +301,10 @@ static int __devinit sis630e_get_mac_addr(struct pci_dev * pci_dev, · 18 unmodified lines | ||
| 296 | 301 | outb(0x09 + i, 0x70); |
| 297 | 302 | ((u8 *)(net_dev->dev_addr))[i] = inb(0x71); |
| 298 | 303 | } |
| 304 | + | |
| 305 | + /* Store MAC Address in perm_addr */ | |
| 306 | + memcpy(net_dev->perm_addr, net_dev->dev_addr, ETH_ALEN); | |
| 307 | + | |
| 299 | 308 | pci_write_config_byte(isa_bridge, 0x48, reg & ~0x40); |
| 300 | 309 | pci_dev_put(isa_bridge); |
| 301 | 310 | |
| @@ -310,7 +319,7 @@ static int __devinit sis630e_get_mac_addr(struct pci_dev * pci_dev, · 8 unmodified lines | ||
| 310 | 319 | * |
| 311 | 320 | * SiS635 model, set MAC Reload Bit to load Mac address from APC |
| 312 | 321 | * to rfdr. rfdr is accessed through rfcr. MAC address is read into |
| 313 | − * @net_dev->dev_addr. | |
| 322 | + * @net_dev->dev_addr and @net_dev->perm_addr. | |
| 314 | 323 | */ |
| 315 | 324 | |
| 316 | 325 | static int __devinit sis635_get_mac_addr(struct pci_dev * pci_dev, |
| @@ -334,6 +343,9 @@ static int __devinit sis635_get_mac_addr(struct pci_dev * pci_dev, · 17 unmodified lines | ||
| 334 | 343 | *( ((u16 *)net_dev->dev_addr) + i) = inw(ioaddr + rfdr); |
| 335 | 344 | } |
| 336 | 345 | |
| 346 | + /* Store MAC Address in perm_addr */ | |
| 347 | + memcpy(net_dev->perm_addr, net_dev->dev_addr, ETH_ALEN); | |
| 348 | + | |
| 337 | 349 | /* enable packet filtering */ |
| 338 | 350 | outl(rfcrSave | RFEN, rfcr + ioaddr); |
| 339 | 351 | |
| @@ -353,7 +365,7 @@ static int __devinit sis635_get_mac_addr(struct pci_dev * pci_dev, · 13 unmodified lines | ||
| 353 | 365 | * EEDONE signal to refuse EEPROM access by LAN. |
| 354 | 366 | * The EEPROM map of SiS962 or SiS963 is different to SiS900. |
| 355 | 367 | * The signature field in SiS962 or SiS963 spec is meaningless. |
| 356 | − * MAC address is read into @net_dev->dev_addr. | |
| 368 | + * MAC address is read into @net_dev->dev_addr and @net_dev->perm_addr. | |
| 357 | 369 | */ |
| 358 | 370 | |
| 359 | 371 | static int __devinit sis96x_get_mac_addr(struct pci_dev * pci_dev, |
| @@ -372,6 +384,9 @@ static int __devinit sis96x_get_mac_addr(struct pci_dev * pci_dev, · 12 unmodified lines | ||
| 372 | 384 | for (i = 0; i < 3; i++) |
| 373 | 385 | ((u16 *)(net_dev->dev_addr))[i] = read_eeprom(ioaddr, i+EEPROMMACAddr); |
| 374 | 386 | |
| 387 | + /* Store MAC Address in perm_addr */ | |
| 388 | + memcpy(net_dev->perm_addr, net_dev->dev_addr, ETH_ALEN); | |
| 389 | + | |
| 375 | 390 | outl(EEDONE, ee_addr); |
| 376 | 391 | return 1; |
| 377 | 392 | } else { |
| @@ -853,7 +853,9 @@ static int slip_open(struct tty_struct *tty) · 852 unmodified lines | ||
| 853 | 853 | /* Done. We have linked the TTY line to a channel. */ |
| 854 | 854 | rtnl_unlock(); |
| 855 | 855 | tty->receive_room = 65536; /* We don't flow control */ |
| 856 | − return sl->dev->base_addr; | |
| 856 | + | |
| 857 | + /* TTY layer expects 0 on success */ | |
| 858 | + return 0; | |
| 857 | 859 | |
| 858 | 860 | err_free_bufs: |
| 859 | 861 | sl_free_bufs(sl); |
| @@ -26,9 +26,9 @@ · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | #undef DWMAC_DMA_DEBUG |
| 28 | 28 | #ifdef DWMAC_DMA_DEBUG |
| 29 | −#define DBG(fmt, args...) printk(fmt, ## args) | |
| 29 | +#define DWMAC_LIB_DBG(fmt, args...) printk(fmt, ## args) | |
| 30 | 30 | #else |
| 31 | −#define DBG(fmt, args...) do { } while (0) | |
| 31 | +#define DWMAC_LIB_DBG(fmt, args...) do { } while (0) | |
| 32 | 32 | #endif |
| 33 | 33 | |
| 34 | 34 | /* CSR1 enables the transmit DMA to check for new descriptor */ |
| @@ -152,7 +152,7 @@ int dwmac_dma_interrupt(void __iomem *ioaddr, · 117 unmodified lines | ||
| 152 | 152 | /* read the status register (CSR5) */ |
| 153 | 153 | u32 intr_status = readl(ioaddr + DMA_STATUS); |
| 154 | 154 | |
| 155 | − DBG(INFO, "%s: [CSR5: 0x%08x]\n", __func__, intr_status); | |
| 155 | + DWMAC_LIB_DBG(KERN_INFO "%s: [CSR5: 0x%08x]\n", __func__, intr_status); | |
| 156 | 156 | #ifdef DWMAC_DMA_DEBUG |
| 157 | 157 | /* It displays the DMA process states (CSR5 register) */ |
| 158 | 158 | show_tx_process_state(intr_status); |
| @@ -160,43 +160,43 @@ int dwmac_dma_interrupt(void __iomem *ioaddr, · 1 unmodified line | ||
| 160 | 160 | #endif |
| 161 | 161 | /* ABNORMAL interrupts */ |
| 162 | 162 | if (unlikely(intr_status & DMA_STATUS_AIS)) { |
| 163 | − DBG(INFO, "CSR5[15] DMA ABNORMAL IRQ: "); | |
| 163 | + DWMAC_LIB_DBG(KERN_INFO "CSR5[15] DMA ABNORMAL IRQ: "); | |
| 164 | 164 | if (unlikely(intr_status & DMA_STATUS_UNF)) { |
| 165 | − DBG(INFO, "transmit underflow\n"); | |
| 165 | + DWMAC_LIB_DBG(KERN_INFO "transmit underflow\n"); | |
| 166 | 166 | ret = tx_hard_error_bump_tc; |
| 167 | 167 | x->tx_undeflow_irq++; |
| 168 | 168 | } |
| 169 | 169 | if (unlikely(intr_status & DMA_STATUS_TJT)) { |
| 170 | − DBG(INFO, "transmit jabber\n"); | |
| 170 | + DWMAC_LIB_DBG(KERN_INFO "transmit jabber\n"); | |
| 171 | 171 | x->tx_jabber_irq++; |
| 172 | 172 | } |
| 173 | 173 | if (unlikely(intr_status & DMA_STATUS_OVF)) { |
| 174 | − DBG(INFO, "recv overflow\n"); | |
| 174 | + DWMAC_LIB_DBG(KERN_INFO "recv overflow\n"); | |
| 175 | 175 | x->rx_overflow_irq++; |
| 176 | 176 | } |
| 177 | 177 | if (unlikely(intr_status & DMA_STATUS_RU)) { |
| 178 | − DBG(INFO, "receive buffer unavailable\n"); | |
| 178 | + DWMAC_LIB_DBG(KERN_INFO "receive buffer unavailable\n"); | |
| 179 | 179 | x->rx_buf_unav_irq++; |
| 180 | 180 | } |
| 181 | 181 | if (unlikely(intr_status & DMA_STATUS_RPS)) { |
| 182 | − DBG(INFO, "receive process stopped\n"); | |
| 182 | + DWMAC_LIB_DBG(KERN_INFO "receive process stopped\n"); | |
| 183 | 183 | x->rx_process_stopped_irq++; |
| 184 | 184 | } |
| 185 | 185 | if (unlikely(intr_status & DMA_STATUS_RWT)) { |
| 186 | − DBG(INFO, "receive watchdog\n"); | |
| 186 | + DWMAC_LIB_DBG(KERN_INFO "receive watchdog\n"); | |
| 187 | 187 | x->rx_watchdog_irq++; |
| 188 | 188 | } |
| 189 | 189 | if (unlikely(intr_status & DMA_STATUS_ETI)) { |
| 190 | − DBG(INFO, "transmit early interrupt\n"); | |
| 190 | + DWMAC_LIB_DBG(KERN_INFO "transmit early interrupt\n"); | |
| 191 | 191 | x->tx_early_irq++; |
| 192 | 192 | } |
| 193 | 193 | if (unlikely(intr_status & DMA_STATUS_TPS)) { |
| 194 | − DBG(INFO, "transmit process stopped\n"); | |
| 194 | + DWMAC_LIB_DBG(KERN_INFO "transmit process stopped\n"); | |
| 195 | 195 | x->tx_process_stopped_irq++; |
| 196 | 196 | ret = tx_hard_error; |
| 197 | 197 | } |
| 198 | 198 | if (unlikely(intr_status & DMA_STATUS_FBI)) { |
| 199 | − DBG(INFO, "fatal bus error\n"); | |
| 199 | + DWMAC_LIB_DBG(KERN_INFO "fatal bus error\n"); | |
| 200 | 200 | x->fatal_bus_error_irq++; |
| 201 | 201 | ret = tx_hard_error; |
| 202 | 202 | } |
| @@ -215,7 +215,7 @@ int dwmac_dma_interrupt(void __iomem *ioaddr, · 12 unmodified lines | ||
| 215 | 215 | /* Clear the interrupt by writing a logic 1 to the CSR5[15-0] */ |
| 216 | 216 | writel((intr_status & 0x1ffff), ioaddr + DMA_STATUS); |
| 217 | 217 | |
| 218 | − DBG(INFO, "\n\n"); | |
| 218 | + DWMAC_LIB_DBG(KERN_INFO "\n\n"); | |
| 219 | 219 | return ret; |
| 220 | 220 | } |
| 221 | 221 | |
| @@ -750,7 +750,6 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv) · 749 unmodified lines | ||
| 750 | 750 | priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); |
| 751 | 751 | priv->xstats.threshold = tc; |
| 752 | 752 | } |
| 753 | − stmmac_tx_err(priv); | |
| 754 | 753 | } else if (unlikely(status == tx_hard_error)) |
| 755 | 754 | stmmac_tx_err(priv); |
| 756 | 755 | } |
| @@ -781,21 +780,6 @@ static int stmmac_open(struct net_device *dev) · 24 unmodified lines | ||
| 781 | 780 | |
| 782 | 781 | stmmac_verify_args(); |
| 783 | 782 | |
| 784 | − ret = stmmac_init_phy(dev); | |
| 785 | − if (unlikely(ret)) { | |
| 786 | − pr_err("%s: Cannot attach to PHY (error: %d)\n", __func__, ret); | |
| 787 | − return ret; | |
| 788 | − } | |
| 789 | − | |
| 790 | − /* Request the IRQ lines */ | |
| 791 | − ret = request_irq(dev->irq, stmmac_interrupt, | |
| 792 | − IRQF_SHARED, dev->name, dev); | |
| 793 | − if (unlikely(ret < 0)) { | |
| 794 | − pr_err("%s: ERROR: allocating the IRQ %d (error: %d)\n", | |
| 795 | − __func__, dev->irq, ret); | |
| 796 | − return ret; | |
| 797 | − } | |
| 798 | − | |
| 799 | 783 | #ifdef CONFIG_STMMAC_TIMER |
| 800 | 784 | priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL); |
| 801 | 785 | if (unlikely(priv->tm == NULL)) { |
| @@ -814,6 +798,11 @@ static int stmmac_open(struct net_device *dev) · 12 unmodified lines | ||
| 814 | 798 | } else |
| 815 | 799 | priv->tm->enable = 1; |
| 816 | 800 | #endif |
| 801 | + ret = stmmac_init_phy(dev); | |
| 802 | + if (unlikely(ret)) { | |
| 803 | + pr_err("%s: Cannot attach to PHY (error: %d)\n", __func__, ret); | |
| 804 | + goto open_error; | |
| 805 | + } | |
| 817 | 806 | |
| 818 | 807 | /* Create and initialize the TX/RX descriptors chains. */ |
| 819 | 808 | priv->dma_tx_size = STMMAC_ALIGN(dma_txsize); |
| @@ -822,12 +811,11 @@ static int stmmac_open(struct net_device *dev) · 2 unmodified lines | ||
| 822 | 811 | init_dma_desc_rings(dev); |
| 823 | 812 | |
| 824 | 813 | /* DMA initialization and SW reset */ |
| 825 | − if (unlikely(priv->hw->dma->init(priv->ioaddr, priv->plat->pbl, | |
| 826 | − priv->dma_tx_phy, | |
| 827 | − priv->dma_rx_phy) < 0)) { | |
| 828 | − | |
| 814 | + ret = priv->hw->dma->init(priv->ioaddr, priv->plat->pbl, | |
| 815 | + priv->dma_tx_phy, priv->dma_rx_phy); | |
| 816 | + if (ret < 0) { | |
| 829 | 817 | pr_err("%s: DMA initialization failed\n", __func__); |
| 830 | − return -1; | |
| 818 | + goto open_error; | |
| 831 | 819 | } |
| 832 | 820 | |
| 833 | 821 | /* Copy the MAC addr into the HW */ |
| @@ -848,6 +836,15 @@ static int stmmac_open(struct net_device *dev) · 14 unmodified lines | ||
| 848 | 836 | writel(0xffffffff, priv->ioaddr + MMC_HIGH_INTR_MASK); |
| 849 | 837 | writel(0xffffffff, priv->ioaddr + MMC_LOW_INTR_MASK); |
| 850 | 838 | |
| 839 | + /* Request the IRQ lines */ | |
| 840 | + ret = request_irq(dev->irq, stmmac_interrupt, | |
| 841 | + IRQF_SHARED, dev->name, dev); | |
| 842 | + if (unlikely(ret < 0)) { | |
| 843 | + pr_err("%s: ERROR: allocating the IRQ %d (error: %d)\n", | |
| 844 | + __func__, dev->irq, ret); | |
| 845 | + goto open_error; | |
| 846 | + } | |
| 847 | + | |
| 851 | 848 | /* Enable the MAC Rx/Tx */ |
| 852 | 849 | stmmac_enable_mac(priv->ioaddr); |
| 853 | 850 | |
| @@ -878,7 +875,17 @@ static int stmmac_open(struct net_device *dev) · 24 unmodified lines | ||
| 878 | 875 | napi_enable(&priv->napi); |
| 879 | 876 | skb_queue_head_init(&priv->rx_recycle); |
| 880 | 877 | netif_start_queue(dev); |
| 878 | + | |
| 881 | 879 | return 0; |
| 880 | + | |
| 881 | +open_error: | |
| 882 | +#ifdef CONFIG_STMMAC_TIMER | |
| 883 | + kfree(priv->tm); | |
| 884 | +#endif | |
| 885 | + if (priv->phydev) | |
| 886 | + phy_disconnect(priv->phydev); | |
| 887 | + | |
| 888 | + return ret; | |
| 882 | 889 | } |
| 883 | 890 | |
| 884 | 891 | /** |
| @@ -3237,15 +3237,18 @@ static void happy_meal_pci_exit(void) · 3236 unmodified lines | ||
| 3237 | 3237 | #endif |
| 3238 | 3238 | |
| 3239 | 3239 | #ifdef CONFIG_SBUS |
| 3240 | +static const struct of_device_id hme_sbus_match[]; | |
| 3240 | 3241 | static int __devinit hme_sbus_probe(struct platform_device *op) |
| 3241 | 3242 | { |
| 3243 | + const struct of_device_id *match; | |
| 3242 | 3244 | struct device_node *dp = op->dev.of_node; |
| 3243 | 3245 | const char *model = of_get_property(dp, "model", NULL); |
| 3244 | 3246 | int is_qfe; |
| 3245 | 3247 | |
| 3246 | − if (!op->dev.of_match) | |
| 3248 | + match = of_match_device(hme_sbus_match, &op->dev); | |
| 3249 | + if (!match) | |
| 3247 | 3250 | return -EINVAL; |
| 3248 | − is_qfe = (op->dev.of_match->data != NULL); | |
| 3251 | + is_qfe = (match->data != NULL); | |
| 3249 | 3252 | |
| 3250 | 3253 | if (!is_qfe && model && !strcmp(model, "SUNW,sbus-qfe")) |
| 3251 | 3254 | is_qfe = 1; |
| @@ -12327,8 +12327,10 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) · 12326 unmodified lines | ||
| 12327 | 12327 | if (val & VCPU_CFGSHDW_ASPM_DBNC) |
| 12328 | 12328 | tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND; |
| 12329 | 12329 | if ((val & VCPU_CFGSHDW_WOL_ENABLE) && |
| 12330 | − (val & VCPU_CFGSHDW_WOL_MAGPKT)) | |
| 12330 | + (val & VCPU_CFGSHDW_WOL_MAGPKT)) { | |
| 12331 | 12331 | tp->tg3_flags |= TG3_FLAG_WOL_ENABLE; |
| 12332 | + device_set_wakeup_enable(&tp->pdev->dev, true); | |
| 12333 | + } | |
| 12332 | 12334 | goto done; |
| 12333 | 12335 | } |
| 12334 | 12336 | |
| @@ -12461,8 +12463,10 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) · 126 unmodified lines | ||
| 12461 | 12463 | tp->tg3_flags &= ~TG3_FLAG_WOL_CAP; |
| 12462 | 12464 | |
| 12463 | 12465 | if ((tp->tg3_flags & TG3_FLAG_WOL_CAP) && |
| 12464 | − (nic_cfg & NIC_SRAM_DATA_CFG_WOL_ENABLE)) | |
| 12466 | + (nic_cfg & NIC_SRAM_DATA_CFG_WOL_ENABLE)) { | |
| 12465 | 12467 | tp->tg3_flags |= TG3_FLAG_WOL_ENABLE; |
| 12468 | + device_set_wakeup_enable(&tp->pdev->dev, true); | |
| 12469 | + } | |
| 12466 | 12470 | |
| 12467 | 12471 | if (cfg2 & (1 << 17)) |
| 12468 | 12472 | tp->phy_flags |= TG3_PHYFLG_CAPACITIVE_COUPLING; |
| @@ -1251,7 +1251,7 @@ static netdev_tx_t xl_xmit(struct sk_buff *skb, struct net_device *dev) · 1250 unmodified lines | ||
| 1251 | 1251 | /* |
| 1252 | 1252 | * The NIC has told us that a packet has been downloaded onto the card, we must |
| 1253 | 1253 | * find out which packet it has done, clear the skb and information for the packet |
| 1254 | − * then advance around the ring for all tranmitted packets | |
| 1254 | + * then advance around the ring for all transmitted packets | |
| 1255 | 1255 | */ |
| 1256 | 1256 | |
| 1257 | 1257 | static void xl_dn_comp(struct net_device *dev) |
| @@ -1568,7 +1568,7 @@ static void xl_arb_cmd(struct net_device *dev) · 310 unmodified lines | ||
| 1568 | 1568 | if (lan_status_diff & LSC_SOFT_ERR) |
| 1569 | 1569 | printk(KERN_WARNING "%s: Adapter transmitted Soft Error Report Mac Frame\n",dev->name); |
| 1570 | 1570 | if (lan_status_diff & LSC_TRAN_BCN) |
| 1571 | − printk(KERN_INFO "%s: We are tranmitting the beacon, aaah\n",dev->name); | |
| 1571 | + printk(KERN_INFO "%s: We are transmitting the beacon, aaah\n",dev->name); | |
| 1572 | 1572 | if (lan_status_diff & LSC_SS) |
| 1573 | 1573 | printk(KERN_INFO "%s: Single Station on the ring\n", dev->name); |
| 1574 | 1574 | if (lan_status_diff & LSC_RING_REC) |
| @@ -1675,7 +1675,7 @@ drop_frame: · 1674 unmodified lines | ||
| 1675 | 1675 | if (lan_status_diff & LSC_SOFT_ERR) |
| 1676 | 1676 | printk(KERN_WARNING "%s: Adapter transmitted Soft Error Report Mac Frame\n", dev->name); |
| 1677 | 1677 | if (lan_status_diff & LSC_TRAN_BCN) |
| 1678 | − printk(KERN_INFO "%s: We are tranmitting the beacon, aaah\n", dev->name); | |
| 1678 | + printk(KERN_INFO "%s: We are transmitting the beacon, aaah\n", dev->name); | |
| 1679 | 1679 | if (lan_status_diff & LSC_SS) |
| 1680 | 1680 | printk(KERN_INFO "%s: Single Station on the ring\n", dev->name); |
| 1681 | 1681 | if (lan_status_diff & LSC_RING_REC) |
| @@ -1500,7 +1500,7 @@ drop_frame: · 1499 unmodified lines | ||
| 1500 | 1500 | if (lan_status_diff & LSC_SOFT_ERR) |
| 1501 | 1501 | printk(KERN_WARNING "%s: Adapter transmitted Soft Error Report Mac Frame\n",dev->name); |
| 1502 | 1502 | if (lan_status_diff & LSC_TRAN_BCN) |
| 1503 | − printk(KERN_INFO "%s: We are tranmitting the beacon, aaah\n",dev->name); | |
| 1503 | + printk(KERN_INFO "%s: We are transmitting the beacon, aaah\n",dev->name); | |
| 1504 | 1504 | if (lan_status_diff & LSC_SS) |
| 1505 | 1505 | printk(KERN_INFO "%s: Single Station on the ring\n", dev->name); |
| 1506 | 1506 | if (lan_status_diff & LSC_RING_REC) |
| @@ -460,7 +460,7 @@ static const struct driver_info cdc_info = { · 459 unmodified lines | ||
| 460 | 460 | .manage_power = cdc_manage_power, |
| 461 | 461 | }; |
| 462 | 462 | |
| 463 | −static const struct driver_info mbm_info = { | |
| 463 | +static const struct driver_info wwan_info = { | |
| 464 | 464 | .description = "Mobile Broadband Network Device", |
| 465 | 465 | .flags = FLAG_WWAN, |
| 466 | 466 | .bind = usbnet_cdc_bind, |
| @@ -471,6 +471,7 @@ static const struct driver_info mbm_info = { · 4 unmodified lines | ||
| 471 | 471 | |
| 472 | 472 | /*-------------------------------------------------------------------------*/ |
| 473 | 473 | |
| 474 | +#define HUAWEI_VENDOR_ID 0x12D1 | |
| 474 | 475 | |
| 475 | 476 | static const struct usb_device_id products [] = { |
| 476 | 477 | /* |
| @@ -566,7 +567,7 @@ static const struct usb_device_id products [] = { · 89 unmodified lines | ||
| 566 | 567 | { |
| 567 | 568 | USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM, |
| 568 | 569 | USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), |
| 569 | − .driver_info = 0, | |
| 570 | + .driver_info = (unsigned long)&wwan_info, | |
| 570 | 571 | }, |
| 571 | 572 | |
| 572 | 573 | /* |
| @@ -587,8 +588,17 @@ static const struct usb_device_id products [] = { · 14 unmodified lines | ||
| 587 | 588 | }, { |
| 588 | 589 | USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM, |
| 589 | 590 | USB_CDC_PROTO_NONE), |
| 590 | − .driver_info = (unsigned long)&mbm_info, | |
| 591 | + .driver_info = (unsigned long)&wwan_info, | |
| 591 | 592 | |
| 593 | +}, { | |
| 594 | + /* Various Huawei modems with a network port like the UMG1831 */ | |
| 595 | + .match_flags = USB_DEVICE_ID_MATCH_VENDOR | |
| 596 | + | USB_DEVICE_ID_MATCH_INT_INFO, | |
| 597 | + .idVendor = HUAWEI_VENDOR_ID, | |
| 598 | + .bInterfaceClass = USB_CLASS_COMM, | |
| 599 | + .bInterfaceSubClass = USB_CDC_SUBCLASS_ETHERNET, | |
| 600 | + .bInterfaceProtocol = 255, | |
| 601 | + .driver_info = (unsigned long)&wwan_info, | |
| 592 | 602 | }, |
| 593 | 603 | { }, // END |
| 594 | 604 | }; |
| @@ -54,13 +54,13 @@ · 53 unmodified lines | ||
| 54 | 54 | #include <linux/usb/usbnet.h> |
| 55 | 55 | #include <linux/usb/cdc.h> |
| 56 | 56 | |
| 57 | −#define DRIVER_VERSION "7-Feb-2011" | |
| 57 | +#define DRIVER_VERSION "23-Apr-2011" | |
| 58 | 58 | |
| 59 | 59 | /* CDC NCM subclass 3.2.1 */ |
| 60 | 60 | #define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10 |
| 61 | 61 | |
| 62 | 62 | /* Maximum NTB length */ |
| 63 | −#define CDC_NCM_NTB_MAX_SIZE_TX 16384 /* bytes */ | |
| 63 | +#define CDC_NCM_NTB_MAX_SIZE_TX (16384 + 4) /* bytes, must be short terminated */ | |
| 64 | 64 | #define CDC_NCM_NTB_MAX_SIZE_RX 16384 /* bytes */ |
| 65 | 65 | |
| 66 | 66 | /* Minimum value for MaxDatagramSize, ch. 6.2.9 */ |
| @@ -65,6 +65,7 @@ · 64 unmodified lines | ||
| 65 | 65 | #define IPHETH_USBINTF_PROTO 1 |
| 66 | 66 | |
| 67 | 67 | #define IPHETH_BUF_SIZE 1516 |
| 68 | +#define IPHETH_IP_ALIGN 2 /* padding at front of URB */ | |
| 68 | 69 | #define IPHETH_TX_TIMEOUT (5 * HZ) |
| 69 | 70 | |
| 70 | 71 | #define IPHETH_INTFNUM 2 |
| @@ -202,18 +203,21 @@ static void ipheth_rcvbulk_callback(struct urb *urb) · 131 unmodified lines | ||
| 202 | 203 | return; |
| 203 | 204 | } |
| 204 | 205 | |
| 205 | − len = urb->actual_length; | |
| 206 | − buf = urb->transfer_buffer; | |
| 206 | + if (urb->actual_length <= IPHETH_IP_ALIGN) { | |
| 207 | + dev->net->stats.rx_length_errors++; | |
| 208 | + return; | |
| 209 | + } | |
| 210 | + len = urb->actual_length - IPHETH_IP_ALIGN; | |
| 211 | + buf = urb->transfer_buffer + IPHETH_IP_ALIGN; | |
| 207 | 212 | |
| 208 | − skb = dev_alloc_skb(NET_IP_ALIGN + len); | |
| 213 | + skb = dev_alloc_skb(len); | |
| 209 | 214 | if (!skb) { |
| 210 | 215 | err("%s: dev_alloc_skb: -ENOMEM", __func__); |
| 211 | 216 | dev->net->stats.rx_dropped++; |
| 212 | 217 | return; |
| 213 | 218 | } |
| 214 | 219 | |
| 215 | − skb_reserve(skb, NET_IP_ALIGN); | |
| 216 | − memcpy(skb_put(skb, len), buf + NET_IP_ALIGN, len - NET_IP_ALIGN); | |
| 220 | + memcpy(skb_put(skb, len), buf, len); | |
| 217 | 221 | skb->dev = dev->net; |
| 218 | 222 | skb->protocol = eth_type_trans(skb, dev->net); |
| 219 | 223 | |
| @@ -730,7 +730,7 @@ static int smsc95xx_phy_initialize(struct usbnet *dev) · 729 unmodified lines | ||
| 730 | 730 | msleep(10); |
| 731 | 731 | bmcr = smsc95xx_mdio_read(dev->net, dev->mii.phy_id, MII_BMCR); |
| 732 | 732 | timeout++; |
| 733 | − } while ((bmcr & MII_BMCR) && (timeout < 100)); | |
| 733 | + } while ((bmcr & BMCR_RESET) && (timeout < 100)); | |
| 734 | 734 | |
| 735 | 735 | if (timeout >= 100) { |
| 736 | 736 | netdev_warn(dev->net, "timeout on PHY Reset"); |
| @@ -645,6 +645,7 @@ int usbnet_stop (struct net_device *net) · 644 unmodified lines | ||
| 645 | 645 | struct driver_info *info = dev->driver_info; |
| 646 | 646 | int retval; |
| 647 | 647 | |
| 648 | + clear_bit(EVENT_DEV_OPEN, &dev->flags); | |
| 648 | 649 | netif_stop_queue (net); |
| 649 | 650 | |
| 650 | 651 | netif_info(dev, ifdown, dev->net, |
| @@ -736,6 +737,7 @@ int usbnet_open (struct net_device *net) · 85 unmodified lines | ||
| 736 | 737 | } |
| 737 | 738 | } |
| 738 | 739 | |
| 740 | + set_bit(EVENT_DEV_OPEN, &dev->flags); | |
| 739 | 741 | netif_start_queue (net); |
| 740 | 742 | netif_info(dev, ifup, dev->net, |
| 741 | 743 | "open: enable queueing (rx %d, tx %d) mtu %d %s framing\n", |
| @@ -1259,6 +1261,9 @@ void usbnet_disconnect (struct usb_interface *intf) · 517 unmodified lines | ||
| 1259 | 1261 | if (dev->driver_info->unbind) |
| 1260 | 1262 | dev->driver_info->unbind (dev, intf); |
| 1261 | 1263 | |
| 1264 | + usb_kill_urb(dev->interrupt); | |
| 1265 | + usb_free_urb(dev->interrupt); | |
| 1266 | + | |
| 1262 | 1267 | free_netdev(net); |
| 1263 | 1268 | usb_put_dev (xdev); |
| 1264 | 1269 | } |
| @@ -1498,6 +1503,10 @@ int usbnet_resume (struct usb_interface *intf) · 233 unmodified lines | ||
| 1498 | 1503 | int retval; |
| 1499 | 1504 | |
| 1500 | 1505 | if (!--dev->suspend_count) { |
| 1506 | + /* resume interrupt URBs */ | |
| 1507 | + if (dev->interrupt && test_bit(EVENT_DEV_OPEN, &dev->flags)) | |
| 1508 | + usb_submit_urb(dev->interrupt, GFP_NOIO); | |
| 1509 | + | |
| 1501 | 1510 | spin_lock_irq(&dev->txq.lock); |
| 1502 | 1511 | while ((res = usb_get_from_anchor(&dev->deferred))) { |
| 1503 | 1512 | |
| @@ -1516,9 +1525,12 @@ int usbnet_resume (struct usb_interface *intf) · 12 unmodified lines | ||
| 1516 | 1525 | smp_mb(); |
| 1517 | 1526 | clear_bit(EVENT_DEV_ASLEEP, &dev->flags); |
| 1518 | 1527 | spin_unlock_irq(&dev->txq.lock); |
| 1519 | − if (!(dev->txq.qlen >= TX_QLEN(dev))) | |
| 1520 | − netif_start_queue(dev->net); | |
| 1521 | − tasklet_schedule (&dev->bh); | |
| 1528 | + | |
| 1529 | + if (test_bit(EVENT_DEV_OPEN, &dev->flags)) { | |
| 1530 | + if (!(dev->txq.qlen >= TX_QLEN(dev))) | |
| 1531 | + netif_start_queue(dev->net); | |
| 1532 | + tasklet_schedule (&dev->bh); | |
| 1533 | + } | |
| 1522 | 1534 | } |
| 1523 | 1535 | return 0; |
| 1524 | 1536 | } |
| @@ -403,6 +403,17 @@ static int veth_newlink(struct net *src_net, struct net_device *dev, · 402 unmodified lines | ||
| 403 | 403 | if (tb[IFLA_ADDRESS] == NULL) |
| 404 | 404 | random_ether_addr(dev->dev_addr); |
| 405 | 405 | |
| 406 | + if (tb[IFLA_IFNAME]) | |
| 407 | + nla_strlcpy(dev->name, tb[IFLA_IFNAME], IFNAMSIZ); | |
| 408 | + else | |
| 409 | + snprintf(dev->name, IFNAMSIZ, DRV_NAME "%%d"); | |
| 410 | + | |
| 411 | + if (strchr(dev->name, '%')) { | |
| 412 | + err = dev_alloc_name(dev, dev->name); | |
| 413 | + if (err < 0) | |
| 414 | + goto err_alloc_name; | |
| 415 | + } | |
| 416 | + | |
| 406 | 417 | err = register_netdevice(dev); |
| 407 | 418 | if (err < 0) |
| 408 | 419 | goto err_register_dev; |
| @@ -422,6 +433,7 @@ static int veth_newlink(struct net *src_net, struct net_device *dev, · 13 unmodified lines | ||
| 422 | 433 | |
| 423 | 434 | err_register_dev: |
| 424 | 435 | /* nothing to do */ |
| 436 | +err_alloc_name: | |
| 425 | 437 | err_configure_peer: |
| 426 | 438 | unregister_netdevice(peer); |
| 427 | 439 | return err; |
| @@ -178,6 +178,7 @@ static void · 177 unmodified lines | ||
| 178 | 178 | vmxnet3_process_events(struct vmxnet3_adapter *adapter) |
| 179 | 179 | { |
| 180 | 180 | int i; |
| 181 | + unsigned long flags; | |
| 181 | 182 | u32 events = le32_to_cpu(adapter->shared->ecr); |
| 182 | 183 | if (!events) |
| 183 | 184 | return; |
| @@ -190,10 +191,10 @@ vmxnet3_process_events(struct vmxnet3_adapter *adapter) · 6 unmodified lines | ||
| 190 | 191 | |
| 191 | 192 | /* Check if there is an error on xmit/recv queues */ |
| 192 | 193 | if (events & (VMXNET3_ECR_TQERR | VMXNET3_ECR_RQERR)) { |
| 193 | − spin_lock(&adapter->cmd_lock); | |
| 194 | + spin_lock_irqsave(&adapter->cmd_lock, flags); | |
| 194 | 195 | VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, |
| 195 | 196 | VMXNET3_CMD_GET_QUEUE_STATUS); |
| 196 | − spin_unlock(&adapter->cmd_lock); | |
| 197 | + spin_unlock_irqrestore(&adapter->cmd_lock, flags); | |
| 197 | 198 | |
| 198 | 199 | for (i = 0; i < adapter->num_tx_queues; i++) |
| 199 | 200 | if (adapter->tqd_start[i].status.stopped) |
| @@ -2733,13 +2734,14 @@ static void · 2533 unmodified lines | ||
| 2733 | 2734 | vmxnet3_alloc_intr_resources(struct vmxnet3_adapter *adapter) |
| 2734 | 2735 | { |
| 2735 | 2736 | u32 cfg; |
| 2737 | + unsigned long flags; | |
| 2736 | 2738 | |
| 2737 | 2739 | /* intr settings */ |
| 2738 | − spin_lock(&adapter->cmd_lock); | |
| 2740 | + spin_lock_irqsave(&adapter->cmd_lock, flags); | |
| 2739 | 2741 | VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD, |
| 2740 | 2742 | VMXNET3_CMD_GET_CONF_INTR); |
| 2741 | 2743 | cfg = VMXNET3_READ_BAR1_REG(adapter, VMXNET3_REG_CMD); |
| 2742 | − spin_unlock(&adapter->cmd_lock); | |
| 2744 | + spin_unlock_irqrestore(&adapter->cmd_lock, flags); | |
| 2743 | 2745 | adapter->intr.type = cfg & 0x3; |
| 2744 | 2746 | adapter->intr.mask_mode = (cfg >> 2) & 0x3; |
| 2745 | 2747 | |
| @@ -311,6 +311,9 @@ vmxnet3_set_flags(struct net_device *netdev, u32 data) · 310 unmodified lines | ||
| 311 | 311 | /* toggle the LRO feature*/ |
| 312 | 312 | netdev->features ^= NETIF_F_LRO; |
| 313 | 313 | |
| 314 | + /* Update private LRO flag */ | |
| 315 | + adapter->lro = lro_requested; | |
| 316 | + | |
| 314 | 317 | /* update harware LRO capability accordingly */ |
| 315 | 318 | if (lro_requested) |
| 316 | 319 | adapter->shared->devRead.misc.uptFeatures |= |
| @@ -1040,7 +1040,7 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, · 1039 unmodified lines | ||
| 1040 | 1040 | } |
| 1041 | 1041 | |
| 1042 | 1042 | ret = ath9k_htc_hw_init(hif_dev->htc_handle, |
| 1043 | − &hif_dev->udev->dev, hif_dev->device_id, | |
| 1043 | + &interface->dev, hif_dev->device_id, | |
| 1044 | 1044 | hif_dev->udev->product, id->driver_info); |
| 1045 | 1045 | if (ret) { |
| 1046 | 1046 | ret = -EINVAL; |
| @@ -1158,7 +1158,7 @@ fail_resume: · 111 unmodified lines | ||
| 1158 | 1158 | #endif |
| 1159 | 1159 | |
| 1160 | 1160 | static struct usb_driver ath9k_hif_usb_driver = { |
| 1161 | − .name = "ath9k_hif_usb", | |
| 1161 | + .name = KBUILD_MODNAME, | |
| 1162 | 1162 | .probe = ath9k_hif_usb_probe, |
| 1163 | 1163 | .disconnect = ath9k_hif_usb_disconnect, |
| 1164 | 1164 | #ifdef CONFIG_PM |
| @@ -1254,15 +1254,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, · 1253 unmodified lines | ||
| 1254 | 1254 | ah->txchainmask = common->tx_chainmask; |
| 1255 | 1255 | ah->rxchainmask = common->rx_chainmask; |
| 1256 | 1256 | |
| 1257 | − if ((common->bus_ops->ath_bus_type != ATH_USB) && !ah->chip_fullsleep) { | |
| 1258 | − ath9k_hw_abortpcurecv(ah); | |
| 1259 | − if (!ath9k_hw_stopdmarecv(ah)) { | |
| 1260 | − ath_dbg(common, ATH_DBG_XMIT, | |
| 1261 | − "Failed to stop receive dma\n"); | |
| 1262 | − bChannelChange = false; | |
| 1263 | − } | |
| 1264 | − } | |
| 1265 | − | |
| 1266 | 1257 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) |
| 1267 | 1258 | return -EIO; |
| 1268 | 1259 | |
| @@ -751,28 +751,47 @@ void ath9k_hw_abortpcurecv(struct ath_hw *ah) · 750 unmodified lines | ||
| 751 | 751 | } |
| 752 | 752 | EXPORT_SYMBOL(ath9k_hw_abortpcurecv); |
| 753 | 753 | |
| 754 | −bool ath9k_hw_stopdmarecv(struct ath_hw *ah) | |
| 754 | +bool ath9k_hw_stopdmarecv(struct ath_hw *ah, bool *reset) | |
| 755 | 755 | { |
| 756 | 756 | #define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */ |
| 757 | 757 | #define AH_RX_TIME_QUANTUM 100 /* usec */ |
| 758 | 758 | struct ath_common *common = ath9k_hw_common(ah); |
| 759 | + u32 mac_status, last_mac_status = 0; | |
| 759 | 760 | int i; |
| 760 | 761 | |
| 762 | + /* Enable access to the DMA observation bus */ | |
| 763 | + REG_WRITE(ah, AR_MACMISC, | |
| 764 | + ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) | | |
| 765 | + (AR_MACMISC_MISC_OBS_BUS_1 << | |
| 766 | + AR_MACMISC_MISC_OBS_BUS_MSB_S))); | |
| 767 | + | |
| 761 | 768 | REG_WRITE(ah, AR_CR, AR_CR_RXD); |
| 762 | 769 | |
| 763 | 770 | /* Wait for rx enable bit to go low */ |
| 764 | 771 | for (i = AH_RX_STOP_DMA_TIMEOUT / AH_TIME_QUANTUM; i != 0; i--) { |
| 765 | 772 | if ((REG_READ(ah, AR_CR) & AR_CR_RXE) == 0) |
| 766 | 773 | break; |
| 774 | + | |
| 775 | + if (!AR_SREV_9300_20_OR_LATER(ah)) { | |
| 776 | + mac_status = REG_READ(ah, AR_DMADBG_7) & 0x7f0; | |
| 777 | + if (mac_status == 0x1c0 && mac_status == last_mac_status) { | |
| 778 | + *reset = true; | |
| 779 | + break; | |
| 780 | + } | |
| 781 | + | |
| 782 | + last_mac_status = mac_status; | |
| 783 | + } | |
| 784 | + | |
| 767 | 785 | udelay(AH_TIME_QUANTUM); |
| 768 | 786 | } |
| 769 | 787 | |
| 770 | 788 | if (i == 0) { |
| 771 | 789 | ath_err(common, |
| 772 | − "DMA failed to stop in %d ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n", | |
| 790 | + "DMA failed to stop in %d ms AR_CR=0x%08x AR_DIAG_SW=0x%08x DMADBG_7=0x%08x\n", | |
| 773 | 791 | AH_RX_STOP_DMA_TIMEOUT / 1000, |
| 774 | 792 | REG_READ(ah, AR_CR), |
| 775 | − REG_READ(ah, AR_DIAG_SW)); | |
| 793 | + REG_READ(ah, AR_DIAG_SW), | |
| 794 | + REG_READ(ah, AR_DMADBG_7)); | |
| 776 | 795 | return false; |
| 777 | 796 | } else { |
| 778 | 797 | return true; |
| @@ -695,7 +695,7 @@ bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set); · 694 unmodified lines | ||
| 695 | 695 | void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp); |
| 696 | 696 | void ath9k_hw_startpcureceive(struct ath_hw *ah, bool is_scanning); |
| 697 | 697 | void ath9k_hw_abortpcurecv(struct ath_hw *ah); |
| 698 | −bool ath9k_hw_stopdmarecv(struct ath_hw *ah); | |
| 698 | +bool ath9k_hw_stopdmarecv(struct ath_hw *ah, bool *reset); | |
| 699 | 699 | int ath9k_hw_beaconq_setup(struct ath_hw *ah); |
| 700 | 700 | |
| 701 | 701 | /* Interrupt Handling */ |
| @@ -1376,7 +1376,6 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, · 1375 unmodified lines | ||
| 1376 | 1376 | |
| 1377 | 1377 | ath9k_calculate_iter_data(hw, vif, &iter_data); |
| 1378 | 1378 | |
| 1379 | − ath9k_ps_wakeup(sc); | |
| 1380 | 1379 | /* Set BSSID mask. */ |
| 1381 | 1380 | memcpy(common->bssidmask, iter_data.mask, ETH_ALEN); |
| 1382 | 1381 | ath_hw_setbssidmask(common); |
| @@ -1411,7 +1410,6 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, · 28 unmodified lines | ||
| 1411 | 1410 | } |
| 1412 | 1411 | |
| 1413 | 1412 | ath9k_hw_set_interrupts(ah, ah->imask); |
| 1414 | − ath9k_ps_restore(sc); | |
| 1415 | 1413 | |
| 1416 | 1414 | /* Set up ANI */ |
| 1417 | 1415 | if ((iter_data.naps + iter_data.nadhocs) > 0) { |
| @@ -1457,6 +1455,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, · 39 unmodified lines | ||
| 1457 | 1455 | struct ath_vif *avp = (void *)vif->drv_priv; |
| 1458 | 1456 | int ret = 0; |
| 1459 | 1457 | |
| 1458 | + ath9k_ps_wakeup(sc); | |
| 1460 | 1459 | mutex_lock(&sc->mutex); |
| 1461 | 1460 | |
| 1462 | 1461 | switch (vif->type) { |
| @@ -1503,6 +1502,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, · 40 unmodified lines | ||
| 1503 | 1502 | ath9k_do_vif_add_setup(hw, vif); |
| 1504 | 1503 | out: |
| 1505 | 1504 | mutex_unlock(&sc->mutex); |
| 1505 | + ath9k_ps_restore(sc); | |
| 1506 | 1506 | return ret; |
| 1507 | 1507 | } |
| 1508 | 1508 | |
| @@ -1517,6 +1517,7 @@ static int ath9k_change_interface(struct ieee80211_hw *hw, · 8 unmodified lines | ||
| 1517 | 1517 | |
| 1518 | 1518 | ath_dbg(common, ATH_DBG_CONFIG, "Change Interface\n"); |
| 1519 | 1519 | mutex_lock(&sc->mutex); |
| 1520 | + ath9k_ps_wakeup(sc); | |
| 1520 | 1521 | |
| 1521 | 1522 | /* See if new interface type is valid. */ |
| 1522 | 1523 | if ((new_type == NL80211_IFTYPE_ADHOC) && |
| @@ -1546,6 +1547,7 @@ static int ath9k_change_interface(struct ieee80211_hw *hw, · 23 unmodified lines | ||
| 1546 | 1547 | |
| 1547 | 1548 | ath9k_do_vif_add_setup(hw, vif); |
| 1548 | 1549 | out: |
| 1550 | + ath9k_ps_restore(sc); | |
| 1549 | 1551 | mutex_unlock(&sc->mutex); |
| 1550 | 1552 | return ret; |
| 1551 | 1553 | } |
| @@ -1558,6 +1560,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, · 6 unmodified lines | ||
| 1558 | 1560 | |
| 1559 | 1561 | ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n"); |
| 1560 | 1562 | |
| 1563 | + ath9k_ps_wakeup(sc); | |
| 1561 | 1564 | mutex_lock(&sc->mutex); |
| 1562 | 1565 | |
| 1563 | 1566 | sc->nvifs--; |
| @@ -1569,6 +1572,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, · 5 unmodified lines | ||
| 1569 | 1572 | ath9k_calculate_summary_state(hw, NULL); |
| 1570 | 1573 | |
| 1571 | 1574 | mutex_unlock(&sc->mutex); |
| 1575 | + ath9k_ps_restore(sc); | |
| 1572 | 1576 | } |
| 1573 | 1577 | |
| 1574 | 1578 | static void ath9k_enable_ps(struct ath_softc *sc) |
| @@ -1809,6 +1813,7 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, · 234 unmodified lines | ||
| 1809 | 1813 | |
| 1810 | 1814 | txq = sc->tx.txq_map[queue]; |
| 1811 | 1815 | |
| 1816 | + ath9k_ps_wakeup(sc); | |
| 1812 | 1817 | mutex_lock(&sc->mutex); |
| 1813 | 1818 | |
| 1814 | 1819 | memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); |
| @@ -1832,6 +1837,7 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue, · 17 unmodified lines | ||
| 1832 | 1837 | ath_beaconq_config(sc); |
| 1833 | 1838 | |
| 1834 | 1839 | mutex_unlock(&sc->mutex); |
| 1840 | + ath9k_ps_restore(sc); | |
| 1835 | 1841 | |
| 1836 | 1842 | return ret; |
| 1837 | 1843 | } |
| @@ -1894,6 +1900,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, · 56 unmodified lines | ||
| 1894 | 1900 | int slottime; |
| 1895 | 1901 | int error; |
| 1896 | 1902 | |
| 1903 | + ath9k_ps_wakeup(sc); | |
| 1897 | 1904 | mutex_lock(&sc->mutex); |
| 1898 | 1905 | |
| 1899 | 1906 | if (changed & BSS_CHANGED_BSSID) { |
| @@ -1994,6 +2001,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, · 94 unmodified lines | ||
| 1994 | 2001 | } |
| 1995 | 2002 | |
| 1996 | 2003 | mutex_unlock(&sc->mutex); |
| 2004 | + ath9k_ps_restore(sc); | |
| 1997 | 2005 | } |
| 1998 | 2006 | |
| 1999 | 2007 | static u64 ath9k_get_tsf(struct ieee80211_hw *hw) |
| @@ -2133,6 +2141,8 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) · 133 unmodified lines | ||
| 2133 | 2141 | static void ath9k_flush(struct ieee80211_hw *hw, bool drop) |
| 2134 | 2142 | { |
| 2135 | 2143 | struct ath_softc *sc = hw->priv; |
| 2144 | + struct ath_hw *ah = sc->sc_ah; | |
| 2145 | + struct ath_common *common = ath9k_hw_common(ah); | |
| 2136 | 2146 | int timeout = 200; /* ms */ |
| 2137 | 2147 | int i, j; |
| 2138 | 2148 | |
| @@ -2141,6 +2151,12 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) · 2 unmodified lines | ||
| 2141 | 2151 | |
| 2142 | 2152 | cancel_delayed_work_sync(&sc->tx_complete_work); |
| 2143 | 2153 | |
| 2154 | + if (sc->sc_flags & SC_OP_INVALID) { | |
| 2155 | + ath_dbg(common, ATH_DBG_ANY, "Device not present\n"); | |
| 2156 | + mutex_unlock(&sc->mutex); | |
| 2157 | + return; | |
| 2158 | + } | |
| 2159 | + | |
| 2144 | 2160 | if (drop) |
| 2145 | 2161 | timeout = 1; |
| 2146 | 2162 | |
| @@ -486,12 +486,12 @@ start_recv: · 485 unmodified lines | ||
| 486 | 486 | bool ath_stoprecv(struct ath_softc *sc) |
| 487 | 487 | { |
| 488 | 488 | struct ath_hw *ah = sc->sc_ah; |
| 489 | − bool stopped; | |
| 489 | + bool stopped, reset = false; | |
| 490 | 490 | |
| 491 | 491 | spin_lock_bh(&sc->rx.rxbuflock); |
| 492 | 492 | ath9k_hw_abortpcurecv(ah); |
| 493 | 493 | ath9k_hw_setrxfilter(ah, 0); |
| 494 | − stopped = ath9k_hw_stopdmarecv(ah); | |
| 494 | + stopped = ath9k_hw_stopdmarecv(ah, &reset); | |
| 495 | 495 | |
| 496 | 496 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) |
| 497 | 497 | ath_edma_stop_recv(sc); |
| @@ -506,7 +506,7 @@ bool ath_stoprecv(struct ath_softc *sc) · 8 unmodified lines | ||
| 506 | 506 | "confusing the DMA engine when we start RX up\n"); |
| 507 | 507 | ATH_DBG_WARN_ON_ONCE(!stopped); |
| 508 | 508 | } |
| 509 | − return stopped; | |
| 509 | + return stopped && !reset; | |
| 510 | 510 | } |
| 511 | 511 | |
| 512 | 512 | void ath_flushrecv(struct ath_softc *sc) |
| @@ -195,6 +195,7 @@ static struct reg_dmn_pair_mapping regDomainPairs[] = { · 194 unmodified lines | ||
| 195 | 195 | {APL9_WORLD, CTL_ETSI, CTL_ETSI}, |
| 196 | 196 | |
| 197 | 197 | {APL3_FCCA, CTL_FCC, CTL_FCC}, |
| 198 | + {APL7_FCCA, CTL_FCC, CTL_FCC}, | |
| 198 | 199 | {APL1_ETSIC, CTL_FCC, CTL_ETSI}, |
| 199 | 200 | {APL2_ETSIC, CTL_FCC, CTL_ETSI}, |
| 200 | 201 | {APL2_APLD, CTL_FCC, NO_CTL}, |
| @@ -72,6 +72,7 @@ MODULE_FIRMWARE("b43/ucode11.fw"); · 71 unmodified lines | ||
| 72 | 72 | MODULE_FIRMWARE("b43/ucode13.fw"); |
| 73 | 73 | MODULE_FIRMWARE("b43/ucode14.fw"); |
| 74 | 74 | MODULE_FIRMWARE("b43/ucode15.fw"); |
| 75 | +MODULE_FIRMWARE("b43/ucode16_mimo.fw"); | |
| 75 | 76 | MODULE_FIRMWARE("b43/ucode5.fw"); |
| 76 | 77 | MODULE_FIRMWARE("b43/ucode9.fw"); |
| 77 | 78 | |
| @@ -1,6 +1,5 @@ | ||
| 1 | 1 | config IWLWIFI_LEGACY |
| 2 | − tristate "Intel Wireless Wifi legacy devices" | |
| 3 | − depends on PCI && MAC80211 | |
| 2 | + tristate | |
| 4 | 3 | select FW_LOADER |
| 5 | 4 | select NEW_LEDS |
| 6 | 5 | select LEDS_CLASS |
| @@ -65,7 +64,8 @@ endmenu · 58 unmodified lines | ||
| 65 | 64 | |
| 66 | 65 | config IWL4965 |
| 67 | 66 | tristate "Intel Wireless WiFi 4965AGN (iwl4965)" |
| 68 | − depends on IWLWIFI_LEGACY | |
| 67 | + depends on PCI && MAC80211 | |
| 68 | + select IWLWIFI_LEGACY | |
| 69 | 69 | ---help--- |
| 70 | 70 | This option enables support for |
| 71 | 71 | |
| @@ -92,7 +92,8 @@ config IWL4965 · 20 unmodified lines | ||
| 92 | 92 | |
| 93 | 93 | config IWL3945 |
| 94 | 94 | tristate "Intel PRO/Wireless 3945ABG/BG Network Connection (iwl3945)" |
| 95 | − depends on IWLWIFI_LEGACY | |
| 95 | + depends on PCI && MAC80211 | |
| 96 | + select IWLWIFI_LEGACY | |
| 96 | 97 | ---help--- |
| 97 | 98 | Select to build the driver supporting the: |
| 98 | 99 | |
| @@ -74,8 +74,6 @@ · 73 unmodified lines | ||
| 74 | 74 | /* RSSI to dBm */ |
| 75 | 75 | #define IWL39_RSSI_OFFSET 95 |
| 76 | 76 | |
| 77 | −#define IWL_DEFAULT_TX_POWER 0x0F | |
| 78 | − | |
| 79 | 77 | /* |
| 80 | 78 | * EEPROM related constants, enums, and structures. |
| 81 | 79 | */ |
| @@ -804,9 +804,6 @@ struct iwl4965_scd_bc_tbl { · 803 unmodified lines | ||
| 804 | 804 | |
| 805 | 805 | #define IWL4965_DEFAULT_TX_RETRY 15 |
| 806 | 806 | |
| 807 | −/* Limit range of txpower output target to be between these values */ | |
| 808 | −#define IWL4965_TX_POWER_TARGET_POWER_MIN (0) /* 0 dBm: 1 milliwatt */ | |
| 809 | − | |
| 810 | 807 | /* EEPROM */ |
| 811 | 808 | #define IWL4965_FIRST_AMPDU_QUEUE 10 |
| 812 | 809 | |
| @@ -316,12 +316,18 @@ int iwl4965_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) · 315 unmodified lines | ||
| 316 | 316 | |
| 317 | 317 | hdr_len = ieee80211_hdrlen(fc); |
| 318 | 318 | |
| 319 | − /* Find index into station table for destination station */ | |
| 320 | − sta_id = iwl_legacy_sta_id_or_broadcast(priv, ctx, info->control.sta); | |
| 321 | − if (sta_id == IWL_INVALID_STATION) { | |
| 322 | − IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", | |
| 323 | − hdr->addr1); | |
| 324 | − goto drop_unlock; | |
| 319 | + /* For management frames use broadcast id to do not break aggregation */ | |
| 320 | + if (!ieee80211_is_data(fc)) | |
| 321 | + sta_id = ctx->bcast_sta_id; | |
| 322 | + else { | |
| 323 | + /* Find index into station table for destination station */ | |
| 324 | + sta_id = iwl_legacy_sta_id_or_broadcast(priv, ctx, info->control.sta); | |
| 325 | + | |
| 326 | + if (sta_id == IWL_INVALID_STATION) { | |
| 327 | + IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", | |
| 328 | + hdr->addr1); | |
| 329 | + goto drop_unlock; | |
| 330 | + } | |
| 325 | 331 | } |
| 326 | 332 | |
| 327 | 333 | IWL_DEBUG_TX(priv, "station Id %d\n", sta_id); |
| @@ -1127,12 +1133,16 @@ int iwl4965_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) · 799 unmodified lines | ||
| 1127 | 1133 | q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd)) { |
| 1128 | 1134 | |
| 1129 | 1135 | tx_info = &txq->txb[txq->q.read_ptr]; |
| 1130 | − iwl4965_tx_status(priv, tx_info, | |
| 1131 | − txq_id >= IWL4965_FIRST_AMPDU_QUEUE); | |
| 1136 | + | |
| 1137 | + if (WARN_ON_ONCE(tx_info->skb == NULL)) | |
| 1138 | + continue; | |
| 1132 | 1139 | |
| 1133 | 1140 | hdr = (struct ieee80211_hdr *)tx_info->skb->data; |
| 1134 | − if (hdr && ieee80211_is_data_qos(hdr->frame_control)) | |
| 1141 | + if (ieee80211_is_data_qos(hdr->frame_control)) | |
| 1135 | 1142 | nfreed++; |
| 1143 | + | |
| 1144 | + iwl4965_tx_status(priv, tx_info, | |
| 1145 | + txq_id >= IWL4965_FIRST_AMPDU_QUEUE); | |
| 1136 | 1146 | tx_info->skb = NULL; |
| 1137 | 1147 | |
| 1138 | 1148 | priv->cfg->ops->lib->txq_free_tfd(priv, txq); |
| @@ -160,6 +160,7 @@ int iwl_legacy_init_geos(struct iwl_priv *priv) · 159 unmodified lines | ||
| 160 | 160 | struct ieee80211_channel *geo_ch; |
| 161 | 161 | struct ieee80211_rate *rates; |
| 162 | 162 | int i = 0; |
| 163 | + s8 max_tx_power = 0; | |
| 163 | 164 | |
| 164 | 165 | if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || |
| 165 | 166 | priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { |
| @@ -235,8 +236,8 @@ int iwl_legacy_init_geos(struct iwl_priv *priv) · 69 unmodified lines | ||
| 235 | 236 | |
| 236 | 237 | geo_ch->flags |= ch->ht40_extension_channel; |
| 237 | 238 | |
| 238 | − if (ch->max_power_avg > priv->tx_power_device_lmt) | |
| 239 | − priv->tx_power_device_lmt = ch->max_power_avg; | |
| 239 | + if (ch->max_power_avg > max_tx_power) | |
| 240 | + max_tx_power = ch->max_power_avg; | |
| 240 | 241 | } else { |
| 241 | 242 | geo_ch->flags |= IEEE80211_CHAN_DISABLED; |
| 242 | 243 | } |
| @@ -249,6 +250,10 @@ int iwl_legacy_init_geos(struct iwl_priv *priv) · 6 unmodified lines | ||
| 249 | 250 | geo_ch->flags); |
| 250 | 251 | } |
| 251 | 252 | |
| 253 | + priv->tx_power_device_lmt = max_tx_power; | |
| 254 | + priv->tx_power_user_lmt = max_tx_power; | |
| 255 | + priv->tx_power_next = max_tx_power; | |
| 256 | + | |
| 252 | 257 | if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && |
| 253 | 258 | priv->cfg->sku & IWL_SKU_A) { |
| 254 | 259 | IWL_INFO(priv, "Incorrectly detected BG card as ABG. " |
| @@ -1124,11 +1129,11 @@ int iwl_legacy_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) · 869 unmodified lines | ||
| 1124 | 1129 | if (!priv->cfg->ops->lib->send_tx_power) |
| 1125 | 1130 | return -EOPNOTSUPP; |
| 1126 | 1131 | |
| 1127 | − if (tx_power < IWL4965_TX_POWER_TARGET_POWER_MIN) { | |
| 1132 | + /* 0 dBm mean 1 milliwatt */ | |
| 1133 | + if (tx_power < 0) { | |
| 1128 | 1134 | IWL_WARN(priv, |
| 1129 | − "Requested user TXPOWER %d below lower limit %d.\n", | |
| 1130 | − tx_power, | |
| 1131 | − IWL4965_TX_POWER_TARGET_POWER_MIN); | |
| 1135 | + "Requested user TXPOWER %d below 1 mW.\n", | |
| 1136 | + tx_power); | |
| 1132 | 1137 | return -EINVAL; |
| 1133 | 1138 | } |
| 1134 | 1139 | |
| @@ -2150,6 +2155,13 @@ int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed) · 1015 unmodified lines | ||
| 2150 | 2155 | goto set_ch_out; |
| 2151 | 2156 | } |
| 2152 | 2157 | |
| 2158 | + if (priv->iw_mode == NL80211_IFTYPE_ADHOC && | |
| 2159 | + !iwl_legacy_is_channel_ibss(ch_info)) { | |
| 2160 | + IWL_DEBUG_MAC80211(priv, "leave - not IBSS channel\n"); | |
| 2161 | + ret = -EINVAL; | |
| 2162 | + goto set_ch_out; | |
| 2163 | + } | |
| 2164 | + | |
| 2153 | 2165 | spin_lock_irqsave(&priv->lock, flags); |
| 2154 | 2166 | |
| 2155 | 2167 | for_each_context(priv, ctx) { |
| @@ -1411,6 +1411,12 @@ iwl_legacy_is_channel_passive(const struct iwl_channel_info *ch) · 1410 unmodified lines | ||
| 1411 | 1411 | return (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) ? 1 : 0; |
| 1412 | 1412 | } |
| 1413 | 1413 | |
| 1414 | +static inline int | |
| 1415 | +iwl_legacy_is_channel_ibss(const struct iwl_channel_info *ch) | |
| 1416 | +{ | |
| 1417 | + return (ch->flags & EEPROM_CHANNEL_IBSS) ? 1 : 0; | |
| 1418 | +} | |
| 1419 | + | |
| 1414 | 1420 | static inline void |
| 1415 | 1421 | __iwl_legacy_free_pages(struct iwl_priv *priv, struct page *page) |
| 1416 | 1422 | { |
| @@ -471,13 +471,6 @@ int iwl_legacy_init_channel_map(struct iwl_priv *priv) · 470 unmodified lines | ||
| 471 | 471 | flags & EEPROM_CHANNEL_RADAR)) |
| 472 | 472 | ? "" : "not "); |
| 473 | 473 | |
| 474 | − /* Set the tx_power_user_lmt to the highest power | |
| 475 | − * supported by any channel */ | |
| 476 | − if (eeprom_ch_info[ch].max_power_avg > | |
| 477 | − priv->tx_power_user_lmt) | |
| 478 | − priv->tx_power_user_lmt = | |
| 479 | − eeprom_ch_info[ch].max_power_avg; | |
| 480 | − | |
| 481 | 474 | ch_info++; |
| 482 | 475 | } |
| 483 | 476 | } |
| @@ -48,8 +48,21 @@ module_param(led_mode, int, S_IRUGO); · 47 unmodified lines | ||
| 48 | 48 | MODULE_PARM_DESC(led_mode, "0=system default, " |
| 49 | 49 | "1=On(RF On)/Off(RF Off), 2=blinking"); |
| 50 | 50 | |
| 51 | +/* Throughput OFF time(ms) ON time (ms) | |
| 52 | + * >300 25 25 | |
| 53 | + * >200 to 300 40 40 | |
| 54 | + * >100 to 200 55 55 | |
| 55 | + * >70 to 100 65 65 | |
| 56 | + * >50 to 70 75 75 | |
| 57 | + * >20 to 50 85 85 | |
| 58 | + * >10 to 20 95 95 | |
| 59 | + * >5 to 10 110 110 | |
| 60 | + * >1 to 5 130 130 | |
| 61 | + * >0 to 1 167 167 | |
| 62 | + * <=0 SOLID ON | |
| 63 | + */ | |
| 51 | 64 | static const struct ieee80211_tpt_blink iwl_blink[] = { |
| 52 | − { .throughput = 0 * 1024 - 1, .blink_time = 334 }, | |
| 65 | + { .throughput = 0, .blink_time = 334 }, | |
| 53 | 66 | { .throughput = 1 * 1024 - 1, .blink_time = 260 }, |
| 54 | 67 | { .throughput = 5 * 1024 - 1, .blink_time = 220 }, |
| 55 | 68 | { .throughput = 10 * 1024 - 1, .blink_time = 190 }, |
| @@ -101,6 +114,11 @@ static int iwl_legacy_led_cmd(struct iwl_priv *priv, · 45 unmodified lines | ||
| 101 | 114 | if (priv->blink_on == on && priv->blink_off == off) |
| 102 | 115 | return 0; |
| 103 | 116 | |
| 117 | + if (off == 0) { | |
| 118 | + /* led is SOLID_ON */ | |
| 119 | + on = IWL_LED_SOLID; | |
| 120 | + } | |
| 121 | + | |
| 104 | 122 | IWL_DEBUG_LED(priv, "Led blink time compensation=%u\n", |
| 105 | 123 | priv->cfg->base_params->led_compensation); |
| 106 | 124 | led_cmd.on = iwl_legacy_blink_compensation(priv, on, |
| @@ -3825,10 +3825,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv) · 3824 unmodified lines | ||
| 3825 | 3825 | priv->force_reset[IWL_FW_RESET].reset_duration = |
| 3826 | 3826 | IWL_DELAY_NEXT_FORCE_FW_RELOAD; |
| 3827 | 3827 | |
| 3828 | − | |
| 3829 | − priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER; | |
| 3830 | − priv->tx_power_next = IWL_DEFAULT_TX_POWER; | |
| 3831 | − | |
| 3832 | 3828 | if (eeprom->version < EEPROM_3945_EEPROM_VERSION) { |
| 3833 | 3829 | IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n", |
| 3834 | 3830 | eeprom->version); |
| @@ -2984,15 +2984,15 @@ static void iwl4965_bg_txpower_work(struct work_struct *work) · 2983 unmodified lines | ||
| 2984 | 2984 | struct iwl_priv *priv = container_of(work, struct iwl_priv, |
| 2985 | 2985 | txpower_work); |
| 2986 | 2986 | |
| 2987 | + mutex_lock(&priv->mutex); | |
| 2988 | + | |
| 2987 | 2989 | /* If a scan happened to start before we got here |
| 2988 | 2990 | * then just return; the statistics notification will |
| 2989 | 2991 | * kick off another scheduled work to compensate for |
| 2990 | 2992 | * any temperature delta we missed here. */ |
| 2991 | 2993 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || |
| 2992 | 2994 | test_bit(STATUS_SCANNING, &priv->status)) |
| 2993 | − return; | |
| 2994 | − | |
| 2995 | − mutex_lock(&priv->mutex); | |
| 2995 | + goto out; | |
| 2996 | 2996 | |
| 2997 | 2997 | /* Regardless of if we are associated, we must reconfigure the |
| 2998 | 2998 | * TX power since frames can be sent on non-radar channels while |
| @@ -3002,7 +3002,7 @@ static void iwl4965_bg_txpower_work(struct work_struct *work) · 3 unmodified lines | ||
| 3002 | 3002 | /* Update last_temperature to keep is_calib_needed from running |
| 3003 | 3003 | * when it isn't needed... */ |
| 3004 | 3004 | priv->last_temperature = priv->temperature; |
| 3005 | − | |
| 3005 | +out: | |
| 3006 | 3006 | mutex_unlock(&priv->mutex); |
| 3007 | 3007 | } |
| 3008 | 3008 | |
| @@ -3140,12 +3140,6 @@ static int iwl4965_init_drv(struct iwl_priv *priv) · 131 unmodified lines | ||
| 3140 | 3140 | |
| 3141 | 3141 | iwl_legacy_init_scan_params(priv); |
| 3142 | 3142 | |
| 3143 | − /* Set the tx_power_user_lmt to the lowest power level | |
| 3144 | − * this value will get overwritten by channel max power avg | |
| 3145 | − * from eeprom */ | |
| 3146 | − priv->tx_power_user_lmt = IWL4965_TX_POWER_TARGET_POWER_MIN; | |
| 3147 | − priv->tx_power_next = IWL4965_TX_POWER_TARGET_POWER_MIN; | |
| 3148 | − | |
| 3149 | 3143 | ret = iwl_legacy_init_channel_map(priv); |
| 3150 | 3144 | if (ret) { |
| 3151 | 3145 | IWL_ERR(priv, "initializing regulatory failed: %d\n", ret); |
| @@ -530,6 +530,9 @@ static struct iwl_ht_params iwl5000_ht_params = { · 529 unmodified lines | ||
| 530 | 530 | struct iwl_cfg iwl5300_agn_cfg = { |
| 531 | 531 | .name = "Intel(R) Ultimate N WiFi Link 5300 AGN", |
| 532 | 532 | IWL_DEVICE_5000, |
| 533 | + /* at least EEPROM 0x11A has wrong info */ | |
| 534 | + .valid_tx_ant = ANT_ABC, /* .cfg overwrite */ | |
| 535 | + .valid_rx_ant = ANT_ABC, /* .cfg overwrite */ | |
| 533 | 536 | .ht_params = &iwl5000_ht_params, |
| 534 | 537 | }; |
| 535 | 538 | |
| @@ -335,7 +335,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) · 334 unmodified lines | ||
| 335 | 335 | struct ieee80211_channel *channel = conf->channel; |
| 336 | 336 | const struct iwl_channel_info *ch_info; |
| 337 | 337 | int ret = 0; |
| 338 | − bool ht_changed[NUM_IWL_RXON_CTX] = {}; | |
| 339 | 338 | |
| 340 | 339 | IWL_DEBUG_MAC80211(priv, "changed %#x", changed); |
| 341 | 340 | |
| @@ -383,10 +382,8 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) · 41 unmodified lines | ||
| 383 | 382 | |
| 384 | 383 | for_each_context(priv, ctx) { |
| 385 | 384 | /* Configure HT40 channels */ |
| 386 | − if (ctx->ht.enabled != conf_is_ht(conf)) { | |
| 385 | + if (ctx->ht.enabled != conf_is_ht(conf)) | |
| 387 | 386 | ctx->ht.enabled = conf_is_ht(conf); |
| 388 | − ht_changed[ctx->ctxid] = true; | |
| 389 | − } | |
| 390 | 387 | |
| 391 | 388 | if (ctx->ht.enabled) { |
| 392 | 389 | if (conf_is_ht40_minus(conf)) { |
| @@ -455,8 +452,6 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) · 62 unmodified lines | ||
| 455 | 452 | if (!memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) |
| 456 | 453 | continue; |
| 457 | 454 | iwlagn_commit_rxon(priv, ctx); |
| 458 | − if (ht_changed[ctx->ctxid]) | |
| 459 | − iwlagn_update_qos(priv, ctx); | |
| 460 | 455 | } |
| 461 | 456 | out: |
| 462 | 457 | mutex_unlock(&priv->mutex); |
| @@ -568,12 +568,17 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) · 567 unmodified lines | ||
| 568 | 568 | |
| 569 | 569 | hdr_len = ieee80211_hdrlen(fc); |
| 570 | 570 | |
| 571 | − /* Find index into station table for destination station */ | |
| 572 | − sta_id = iwl_sta_id_or_broadcast(priv, ctx, info->control.sta); | |
| 573 | − if (sta_id == IWL_INVALID_STATION) { | |
| 574 | − IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", | |
| 575 | − hdr->addr1); | |
| 576 | − goto drop_unlock; | |
| 571 | + /* For management frames use broadcast id to do not break aggregation */ | |
| 572 | + if (!ieee80211_is_data(fc)) | |
| 573 | + sta_id = ctx->bcast_sta_id; | |
| 574 | + else { | |
| 575 | + /* Find index into station table for destination station */ | |
| 576 | + sta_id = iwl_sta_id_or_broadcast(priv, ctx, info->control.sta); | |
| 577 | + if (sta_id == IWL_INVALID_STATION) { | |
| 578 | + IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", | |
| 579 | + hdr->addr1); | |
| 580 | + goto drop_unlock; | |
| 581 | + } | |
| 577 | 582 | } |
| 578 | 583 | |
| 579 | 584 | IWL_DEBUG_TX(priv, "station Id %d\n", sta_id); |
| @@ -1224,12 +1229,16 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) · 644 unmodified lines | ||
| 1224 | 1229 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { |
| 1225 | 1230 | |
| 1226 | 1231 | tx_info = &txq->txb[txq->q.read_ptr]; |
| 1227 | − iwlagn_tx_status(priv, tx_info, | |
| 1228 | − txq_id >= IWLAGN_FIRST_AMPDU_QUEUE); | |
| 1232 | + | |
| 1233 | + if (WARN_ON_ONCE(tx_info->skb == NULL)) | |
| 1234 | + continue; | |
| 1229 | 1235 | |
| 1230 | 1236 | hdr = (struct ieee80211_hdr *)tx_info->skb->data; |
| 1231 | − if (hdr && ieee80211_is_data_qos(hdr->frame_control)) | |
| 1237 | + if (ieee80211_is_data_qos(hdr->frame_control)) | |
| 1232 | 1238 | nfreed++; |
| 1239 | + | |
| 1240 | + iwlagn_tx_status(priv, tx_info, | |
| 1241 | + txq_id >= IWLAGN_FIRST_AMPDU_QUEUE); | |
| 1233 | 1242 | tx_info->skb = NULL; |
| 1234 | 1243 | |
| 1235 | 1244 | if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl) |
| @@ -1339,8 +1339,8 @@ int lbs_execute_next_command(struct lbs_private *priv) · 1338 unmodified lines | ||
| 1339 | 1339 | cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) { |
| 1340 | 1340 | lbs_deb_host( |
| 1341 | 1341 | "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n"); |
| 1342 | − list_del(&cmdnode->list); | |
| 1343 | 1342 | spin_lock_irqsave(&priv->driver_lock, flags); |
| 1343 | + list_del(&cmdnode->list); | |
| 1344 | 1344 | lbs_complete_command(priv, cmdnode, 0); |
| 1345 | 1345 | spin_unlock_irqrestore(&priv->driver_lock, flags); |
| 1346 | 1346 | |
| @@ -1352,8 +1352,8 @@ int lbs_execute_next_command(struct lbs_private *priv) · 5 unmodified lines | ||
| 1352 | 1352 | (priv->psstate == PS_STATE_PRE_SLEEP)) { |
| 1353 | 1353 | lbs_deb_host( |
| 1354 | 1354 | "EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep\n"); |
| 1355 | − list_del(&cmdnode->list); | |
| 1356 | 1355 | spin_lock_irqsave(&priv->driver_lock, flags); |
| 1356 | + list_del(&cmdnode->list); | |
| 1357 | 1357 | lbs_complete_command(priv, cmdnode, 0); |
| 1358 | 1358 | spin_unlock_irqrestore(&priv->driver_lock, flags); |
| 1359 | 1359 | priv->needtowakeup = 1; |
| @@ -1366,7 +1366,9 @@ int lbs_execute_next_command(struct lbs_private *priv) · 6 unmodified lines | ||
| 1366 | 1366 | "EXEC_NEXT_CMD: sending EXIT_PS\n"); |
| 1367 | 1367 | } |
| 1368 | 1368 | } |
| 1369 | + spin_lock_irqsave(&priv->driver_lock, flags); | |
| 1369 | 1370 | list_del(&cmdnode->list); |
| 1371 | + spin_unlock_irqrestore(&priv->driver_lock, flags); | |
| 1370 | 1372 | lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n", |
| 1371 | 1373 | le16_to_cpu(cmd->command)); |
| 1372 | 1374 | lbs_submit_command(priv, cmdnode); |
| @@ -137,6 +137,7 @@ struct mwl8k_tx_queue { · 136 unmodified lines | ||
| 137 | 137 | struct mwl8k_priv { |
| 138 | 138 | struct ieee80211_hw *hw; |
| 139 | 139 | struct pci_dev *pdev; |
| 140 | + int irq; | |
| 140 | 141 | |
| 141 | 142 | struct mwl8k_device_info *device_info; |
| 142 | 143 | |
| @@ -3761,9 +3762,11 @@ static int mwl8k_start(struct ieee80211_hw *hw) · 3618 unmodified lines | ||
| 3761 | 3762 | rc = request_irq(priv->pdev->irq, mwl8k_interrupt, |
| 3762 | 3763 | IRQF_SHARED, MWL8K_NAME, hw); |
| 3763 | 3764 | if (rc) { |
| 3765 | + priv->irq = -1; | |
| 3764 | 3766 | wiphy_err(hw->wiphy, "failed to register IRQ handler\n"); |
| 3765 | 3767 | return -EIO; |
| 3766 | 3768 | } |
| 3769 | + priv->irq = priv->pdev->irq; | |
| 3767 | 3770 | |
| 3768 | 3771 | /* Enable TX reclaim and RX tasklets. */ |
| 3769 | 3772 | tasklet_enable(&priv->poll_tx_task); |
| @@ -3800,6 +3803,7 @@ static int mwl8k_start(struct ieee80211_hw *hw) · 30 unmodified lines | ||
| 3800 | 3803 | if (rc) { |
| 3801 | 3804 | iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); |
| 3802 | 3805 | free_irq(priv->pdev->irq, hw); |
| 3806 | + priv->irq = -1; | |
| 3803 | 3807 | tasklet_disable(&priv->poll_tx_task); |
| 3804 | 3808 | tasklet_disable(&priv->poll_rx_task); |
| 3805 | 3809 | } |
| @@ -3818,7 +3822,10 @@ static void mwl8k_stop(struct ieee80211_hw *hw) · 12 unmodified lines | ||
| 3818 | 3822 | |
| 3819 | 3823 | /* Disable interrupts */ |
| 3820 | 3824 | iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); |
| 3821 | − free_irq(priv->pdev->irq, hw); | |
| 3825 | + if (priv->irq != -1) { | |
| 3826 | + free_irq(priv->pdev->irq, hw); | |
| 3827 | + priv->irq = -1; | |
| 3828 | + } | |
| 3822 | 3829 | |
| 3823 | 3830 | /* Stop finalize join worker */ |
| 3824 | 3831 | cancel_work_sync(&priv->finalize_join_worker); |
| @@ -703,7 +703,7 @@ void p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb) · 702 unmodified lines | ||
| 703 | 703 | struct p54_tx_info *p54info; |
| 704 | 704 | struct p54_hdr *hdr; |
| 705 | 705 | struct p54_tx_data *txhdr; |
| 706 | − unsigned int padding, len, extra_len; | |
| 706 | + unsigned int padding, len, extra_len = 0; | |
| 707 | 707 | int i, j, ridx; |
| 708 | 708 | u16 hdr_flags = 0, aid = 0; |
| 709 | 709 | u8 rate, queue = 0, crypt_offset = 0; |
| @@ -126,7 +126,7 @@ static int __devinit zorro8390_init_one(struct zorro_dev *z, · 125 unmodified lines | ||
| 126 | 126 | |
| 127 | 127 | board = z->resource.start; |
| 128 | 128 | ioaddr = board+cards[i].offset; |
| 129 | − dev = alloc_ei_netdev(); | |
| 129 | + dev = ____alloc_ei_netdev(0); | |
| 130 | 130 | if (!dev) |
| 131 | 131 | return -ENOMEM; |
| 132 | 132 | if (!request_mem_region(ioaddr, NE_IO_EXTENT*2, DRV_NAME)) { |
| @@ -146,15 +146,15 @@ static int __devinit zorro8390_init_one(struct zorro_dev *z, · 13 unmodified lines | ||
| 146 | 146 | static const struct net_device_ops zorro8390_netdev_ops = { |
| 147 | 147 | .ndo_open = zorro8390_open, |
| 148 | 148 | .ndo_stop = zorro8390_close, |
| 149 | − .ndo_start_xmit = ei_start_xmit, | |
| 150 | − .ndo_tx_timeout = ei_tx_timeout, | |
| 151 | − .ndo_get_stats = ei_get_stats, | |
| 152 | − .ndo_set_multicast_list = ei_set_multicast_list, | |
| 149 | + .ndo_start_xmit = __ei_start_xmit, | |
| 150 | + .ndo_tx_timeout = __ei_tx_timeout, | |
| 151 | + .ndo_get_stats = __ei_get_stats, | |
| 152 | + .ndo_set_multicast_list = __ei_set_multicast_list, | |
| 153 | 153 | .ndo_validate_addr = eth_validate_addr, |
| 154 | 154 | .ndo_set_mac_address = eth_mac_addr, |
| 155 | 155 | .ndo_change_mtu = eth_change_mtu, |
| 156 | 156 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 157 | − .ndo_poll_controller = ei_poll, | |
| 157 | + .ndo_poll_controller = __ei_poll, | |
| 158 | 158 | #endif |
| 159 | 159 | }; |
| 160 | 160 | |
| @@ -2550,7 +2550,6 @@ static int __devinit sio_ite_8872_probe(struct pci_dev *pdev, int autoirq, · 2549 unmodified lines | ||
| 2550 | 2550 | const struct parport_pc_via_data *via) |
| 2551 | 2551 | { |
| 2552 | 2552 | short inta_addr[6] = { 0x2A0, 0x2C0, 0x220, 0x240, 0x1E0 }; |
| 2553 | − struct resource *base_res; | |
| 2554 | 2553 | u32 ite8872set; |
| 2555 | 2554 | u32 ite8872_lpt, ite8872_lpthi; |
| 2556 | 2555 | u8 ite8872_irq, type; |
| @@ -2561,8 +2560,7 @@ static int __devinit sio_ite_8872_probe(struct pci_dev *pdev, int autoirq, · 4 unmodified lines | ||
| 2561 | 2560 | |
| 2562 | 2561 | /* make sure which one chip */ |
| 2563 | 2562 | for (i = 0; i < 5; i++) { |
| 2564 | − base_res = request_region(inta_addr[i], 32, "it887x"); | |
| 2565 | − if (base_res) { | |
| 2563 | + if (request_region(inta_addr[i], 32, "it887x")) { | |
| 2566 | 2564 | int test; |
| 2567 | 2565 | pci_write_config_dword(pdev, 0x60, |
| 2568 | 2566 | 0xe5000000 | inta_addr[i]); |
| @@ -2571,7 +2569,7 @@ static int __devinit sio_ite_8872_probe(struct pci_dev *pdev, int autoirq, · 2 unmodified lines | ||
| 2571 | 2569 | test = inb(inta_addr[i]); |
| 2572 | 2570 | if (test != 0xff) |
| 2573 | 2571 | break; |
| 2574 | − release_region(inta_addr[i], 0x8); | |
| 2572 | + release_region(inta_addr[i], 32); | |
| 2575 | 2573 | } |
| 2576 | 2574 | } |
| 2577 | 2575 | if (i >= 5) { |
| @@ -2635,7 +2633,7 @@ static int __devinit sio_ite_8872_probe(struct pci_dev *pdev, int autoirq, · 57 unmodified lines | ||
| 2635 | 2633 | /* |
| 2636 | 2634 | * Release the resource so that parport_pc_probe_port can get it. |
| 2637 | 2635 | */ |
| 2638 | − release_resource(base_res); | |
| 2636 | + release_region(inta_addr[i], 32); | |
| 2639 | 2637 | if (parport_pc_probe_port(ite8872_lpt, ite8872_lpthi, |
| 2640 | 2638 | irq, PARPORT_DMA_NONE, &pdev->dev, 0)) { |
| 2641 | 2639 | printk(KERN_INFO |
| @@ -88,4 +88,6 @@ config PCI_IOAPIC · 87 unmodified lines | ||
| 88 | 88 | depends on HOTPLUG |
| 89 | 89 | default y |
| 90 | 90 | |
| 91 | −select NLS if (DMI || ACPI) | |
| 91 | +config PCI_LABEL | |
| 92 | + def_bool y if (DMI || ACPI) | |
| 93 | + select NLS | |
| @@ -56,10 +56,10 @@ obj-$(CONFIG_TILE) += setup-bus.o setup-irq.o · 55 unmodified lines | ||
| 56 | 56 | # ACPI Related PCI FW Functions |
| 57 | 57 | # ACPI _DSM provided firmware instance and string name |
| 58 | 58 | # |
| 59 | −obj-$(CONFIG_ACPI) += pci-acpi.o pci-label.o | |
| 59 | +obj-$(CONFIG_ACPI) += pci-acpi.o | |
| 60 | 60 | |
| 61 | 61 | # SMBIOS provided firmware instance and labels |
| 62 | −obj-$(CONFIG_DMI) += pci-label.o | |
| 62 | +obj-$(CONFIG_PCI_LABEL) += pci-label.o | |
| 63 | 63 | |
| 64 | 64 | # Cardbus & CompactPCI use setup-bus |
| 65 | 65 | obj-$(CONFIG_HOTPLUG) += setup-bus.o |
| @@ -1299,7 +1299,7 @@ static void iommu_detach_domain(struct dmar_domain *domain, · 1298 unmodified lines | ||
| 1299 | 1299 | static struct iova_domain reserved_iova_list; |
| 1300 | 1300 | static struct lock_class_key reserved_rbtree_key; |
| 1301 | 1301 | |
| 1302 | −static void dmar_init_reserved_ranges(void) | |
| 1302 | +static int dmar_init_reserved_ranges(void) | |
| 1303 | 1303 | { |
| 1304 | 1304 | struct pci_dev *pdev = NULL; |
| 1305 | 1305 | struct iova *iova; |
| @@ -1313,8 +1313,10 @@ static void dmar_init_reserved_ranges(void) · 7 unmodified lines | ||
| 1313 | 1313 | /* IOAPIC ranges shouldn't be accessed by DMA */ |
| 1314 | 1314 | iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START), |
| 1315 | 1315 | IOVA_PFN(IOAPIC_RANGE_END)); |
| 1316 | − if (!iova) | |
| 1316 | + if (!iova) { | |
| 1317 | 1317 | printk(KERN_ERR "Reserve IOAPIC range failed\n"); |
| 1318 | + return -ENODEV; | |
| 1319 | + } | |
| 1318 | 1320 | |
| 1319 | 1321 | /* Reserve all PCI MMIO to avoid peer-to-peer access */ |
| 1320 | 1322 | for_each_pci_dev(pdev) { |
| @@ -1327,11 +1329,13 @@ static void dmar_init_reserved_ranges(void) · 6 unmodified lines | ||
| 1327 | 1329 | iova = reserve_iova(&reserved_iova_list, |
| 1328 | 1330 | IOVA_PFN(r->start), |
| 1329 | 1331 | IOVA_PFN(r->end)); |
| 1330 | − if (!iova) | |
| 1332 | + if (!iova) { | |
| 1331 | 1333 | printk(KERN_ERR "Reserve iova failed\n"); |
| 1334 | + return -ENODEV; | |
| 1335 | + } | |
| 1332 | 1336 | } |
| 1333 | 1337 | } |
| 1334 | − | |
| 1338 | + return 0; | |
| 1335 | 1339 | } |
| 1336 | 1340 | |
| 1337 | 1341 | static void domain_reserve_special_ranges(struct dmar_domain *domain) |
| @@ -1835,7 +1839,7 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) · 497 unmodified lines | ||
| 1835 | 1839 | |
| 1836 | 1840 | ret = iommu_attach_domain(domain, iommu); |
| 1837 | 1841 | if (ret) { |
| 1838 | − domain_exit(domain); | |
| 1842 | + free_domain_mem(domain); | |
| 1839 | 1843 | goto error; |
| 1840 | 1844 | } |
| 1841 | 1845 | |
| @@ -2213,7 +2217,7 @@ static int __init iommu_prepare_static_identity_mapping(int hw) · 371 unmodified lines | ||
| 2213 | 2217 | return 0; |
| 2214 | 2218 | } |
| 2215 | 2219 | |
| 2216 | −int __init init_dmars(void) | |
| 2220 | +static int __init init_dmars(int force_on) | |
| 2217 | 2221 | { |
| 2218 | 2222 | struct dmar_drhd_unit *drhd; |
| 2219 | 2223 | struct dmar_rmrr_unit *rmrr; |
| @@ -2393,8 +2397,15 @@ int __init init_dmars(void) · 173 unmodified lines | ||
| 2393 | 2397 | * enable translation |
| 2394 | 2398 | */ |
| 2395 | 2399 | for_each_drhd_unit(drhd) { |
| 2396 | − if (drhd->ignored) | |
| 2400 | + if (drhd->ignored) { | |
| 2401 | + /* | |
| 2402 | + * we always have to disable PMRs or DMA may fail on | |
| 2403 | + * this device | |
| 2404 | + */ | |
| 2405 | + if (force_on) | |
| 2406 | + iommu_disable_protect_mem_regions(drhd->iommu); | |
| 2397 | 2407 | continue; |
| 2408 | + } | |
| 2398 | 2409 | iommu = drhd->iommu; |
| 2399 | 2410 | |
| 2400 | 2411 | iommu_flush_write_buffer(iommu); |
| @@ -3240,9 +3251,15 @@ static int device_notifier(struct notifier_block *nb, · 839 unmodified lines | ||
| 3240 | 3251 | if (!domain) |
| 3241 | 3252 | return 0; |
| 3242 | 3253 | |
| 3243 | − if (action == BUS_NOTIFY_UNBOUND_DRIVER && !iommu_pass_through) | |
| 3254 | + if (action == BUS_NOTIFY_UNBOUND_DRIVER && !iommu_pass_through) { | |
| 3244 | 3255 | domain_remove_one_dev_info(domain, pdev); |
| 3245 | 3256 | |
| 3257 | + if (!(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) && | |
| 3258 | + !(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY) && | |
| 3259 | + list_empty(&domain->devices)) | |
| 3260 | + domain_exit(domain); | |
| 3261 | + } | |
| 3262 | + | |
| 3246 | 3263 | return 0; |
| 3247 | 3264 | } |
| 3248 | 3265 | |
| @@ -3277,12 +3294,21 @@ int __init intel_iommu_init(void) · 28 unmodified lines | ||
| 3277 | 3294 | if (no_iommu || dmar_disabled) |
| 3278 | 3295 | return -ENODEV; |
| 3279 | 3296 | |
| 3280 | − iommu_init_mempool(); | |
| 3281 | − dmar_init_reserved_ranges(); | |
| 3297 | + if (iommu_init_mempool()) { | |
| 3298 | + if (force_on) | |
| 3299 | + panic("tboot: Failed to initialize iommu memory\n"); | |
| 3300 | + return -ENODEV; | |
| 3301 | + } | |
| 3302 | + | |
| 3303 | + if (dmar_init_reserved_ranges()) { | |
| 3304 | + if (force_on) | |
| 3305 | + panic("tboot: Failed to reserve iommu ranges\n"); | |
| 3306 | + return -ENODEV; | |
| 3307 | + } | |
| 3282 | 3308 | |
| 3283 | 3309 | init_no_remapping_devices(); |
| 3284 | 3310 | |
| 3285 | − ret = init_dmars(); | |
| 3311 | + ret = init_dmars(force_on); | |
| 3286 | 3312 | if (ret) { |
| 3287 | 3313 | if (force_on) |
| 3288 | 3314 | panic("tboot: Failed to initialize DMARs\n"); |
| @@ -3391,6 +3417,11 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain, · 102 unmodified lines | ||
| 3391 | 3417 | domain->iommu_count--; |
| 3392 | 3418 | domain_update_iommu_cap(domain); |
| 3393 | 3419 | spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags); |
| 3420 | + | |
| 3421 | + spin_lock_irqsave(&iommu->lock, tmp_flags); | |
| 3422 | + clear_bit(domain->id, iommu->domain_ids); | |
| 3423 | + iommu->domains[domain->id] = NULL; | |
| 3424 | + spin_unlock_irqrestore(&iommu->lock, tmp_flags); | |
| 3394 | 3425 | } |
| 3395 | 3426 | |
| 3396 | 3427 | spin_unlock_irqrestore(&device_domain_lock, flags); |
| @@ -3607,9 +3638,9 @@ static int intel_iommu_attach_device(struct iommu_domain *domain, · 210 unmodified lines | ||
| 3607 | 3638 | |
| 3608 | 3639 | pte = dmar_domain->pgd; |
| 3609 | 3640 | if (dma_pte_present(pte)) { |
| 3610 | − free_pgtable_page(dmar_domain->pgd); | |
| 3611 | 3641 | dmar_domain->pgd = (struct dma_pte *) |
| 3612 | 3642 | phys_to_virt(dma_pte_addr(pte)); |
| 3643 | + free_pgtable_page(pte); | |
| 3613 | 3644 | } |
| 3614 | 3645 | dmar_domain->agaw--; |
| 3615 | 3646 | } |
| @@ -579,7 +579,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, · 578 unmodified lines | ||
| 579 | 579 | } |
| 580 | 580 | size0 = calculate_iosize(size, min_size, size1, |
| 581 | 581 | resource_size(b_res), 4096); |
| 582 | − size1 = !add_size? size0: | |
| 582 | + size1 = (!add_head || (add_head && !add_size)) ? size0 : | |
| 583 | 583 | calculate_iosize(size, min_size+add_size, size1, |
| 584 | 584 | resource_size(b_res), 4096); |
| 585 | 585 | if (!size0 && !size1) { |
| @@ -677,7 +677,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, · 91 unmodified lines | ||
| 677 | 677 | align += aligns[order]; |
| 678 | 678 | } |
| 679 | 679 | size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align); |
| 680 | − size1 = !add_size ? size : | |
| 680 | + size1 = (!add_head || (add_head && !add_size)) ? size0 : | |
| 681 | 681 | calculate_memsize(size, min_size+add_size, 0, |
| 682 | 682 | resource_size(b_res), min_align); |
| 683 | 683 | if (!size0 && !size1) { |
| @@ -173,7 +173,7 @@ static int pcmcia_access_config(struct pcmcia_device *p_dev, · 172 unmodified lines | ||
| 173 | 173 | c = p_dev->function_config; |
| 174 | 174 | |
| 175 | 175 | if (!(c->state & CONFIG_LOCKED)) { |
| 176 | − dev_dbg(&p_dev->dev, "Configuration isn't't locked\n"); | |
| 176 | + dev_dbg(&p_dev->dev, "Configuration isn't locked\n"); | |
| 177 | 177 | mutex_unlock(&s->ops_mutex); |
| 178 | 178 | return -EACCES; |
| 179 | 179 | } |
| @@ -585,8 +585,9 @@ static bool eeepc_wlan_rfkill_blocked(struct eeepc_laptop *eeepc) · 584 unmodified lines | ||
| 585 | 585 | return true; |
| 586 | 586 | } |
| 587 | 587 | |
| 588 | −static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc) | |
| 588 | +static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) | |
| 589 | 589 | { |
| 590 | + struct pci_dev *port; | |
| 590 | 591 | struct pci_dev *dev; |
| 591 | 592 | struct pci_bus *bus; |
| 592 | 593 | bool blocked = eeepc_wlan_rfkill_blocked(eeepc); |
| @@ -599,9 +600,16 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc) · 6 unmodified lines | ||
| 599 | 600 | mutex_lock(&eeepc->hotplug_lock); |
| 600 | 601 | |
| 601 | 602 | if (eeepc->hotplug_slot) { |
| 602 | − bus = pci_find_bus(0, 1); | |
| 603 | + port = acpi_get_pci_dev(handle); | |
| 604 | + if (!port) { | |
| 605 | + pr_warning("Unable to find port\n"); | |
| 606 | + goto out_unlock; | |
| 607 | + } | |
| 608 | + | |
| 609 | + bus = port->subordinate; | |
| 610 | + | |
| 603 | 611 | if (!bus) { |
| 604 | − pr_warning("Unable to find PCI bus 1?\n"); | |
| 612 | + pr_warning("Unable to find PCI bus?\n"); | |
| 605 | 613 | goto out_unlock; |
| 606 | 614 | } |
| 607 | 615 | |
| @@ -609,6 +617,7 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc) · 1 unmodified line | ||
| 609 | 617 | pr_err("Unable to read PCI config space?\n"); |
| 610 | 618 | goto out_unlock; |
| 611 | 619 | } |
| 620 | + | |
| 612 | 621 | absent = (l == 0xffffffff); |
| 613 | 622 | |
| 614 | 623 | if (blocked != absent) { |
| @@ -647,6 +656,17 @@ out_unlock: · 32 unmodified lines | ||
| 647 | 656 | mutex_unlock(&eeepc->hotplug_lock); |
| 648 | 657 | } |
| 649 | 658 | |
| 659 | +static void eeepc_rfkill_hotplug_update(struct eeepc_laptop *eeepc, char *node) | |
| 660 | +{ | |
| 661 | + acpi_status status = AE_OK; | |
| 662 | + acpi_handle handle; | |
| 663 | + | |
| 664 | + status = acpi_get_handle(NULL, node, &handle); | |
| 665 | + | |
| 666 | + if (ACPI_SUCCESS(status)) | |
| 667 | + eeepc_rfkill_hotplug(eeepc, handle); | |
| 668 | +} | |
| 669 | + | |
| 650 | 670 | static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) |
| 651 | 671 | { |
| 652 | 672 | struct eeepc_laptop *eeepc = data; |
| @@ -654,7 +674,7 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) · 1 unmodified line | ||
| 654 | 674 | if (event != ACPI_NOTIFY_BUS_CHECK) |
| 655 | 675 | return; |
| 656 | 676 | |
| 657 | − eeepc_rfkill_hotplug(eeepc); | |
| 677 | + eeepc_rfkill_hotplug(eeepc, handle); | |
| 658 | 678 | } |
| 659 | 679 | |
| 660 | 680 | static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc, |
| @@ -672,6 +692,11 @@ static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc, · 11 unmodified lines | ||
| 672 | 692 | eeepc); |
| 673 | 693 | if (ACPI_FAILURE(status)) |
| 674 | 694 | pr_warning("Failed to register notify on %s\n", node); |
| 695 | + /* | |
| 696 | + * Refresh pci hotplug in case the rfkill state was | |
| 697 | + * changed during setup. | |
| 698 | + */ | |
| 699 | + eeepc_rfkill_hotplug(eeepc, handle); | |
| 675 | 700 | } else |
| 676 | 701 | return -ENODEV; |
| 677 | 702 | |
| @@ -693,6 +718,12 @@ static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc, · 15 unmodified lines | ||
| 693 | 718 | if (ACPI_FAILURE(status)) |
| 694 | 719 | pr_err("Error removing rfkill notify handler %s\n", |
| 695 | 720 | node); |
| 721 | + /* | |
| 722 | + * Refresh pci hotplug in case the rfkill | |
| 723 | + * state was changed after | |
| 724 | + * eeepc_unregister_rfkill_notifier() | |
| 725 | + */ | |
| 726 | + eeepc_rfkill_hotplug(eeepc, handle); | |
| 696 | 727 | } |
| 697 | 728 | } |
| 698 | 729 | |
| @@ -816,11 +847,7 @@ static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc) · 117 unmodified lines | ||
| 816 | 847 | rfkill_destroy(eeepc->wlan_rfkill); |
| 817 | 848 | eeepc->wlan_rfkill = NULL; |
| 818 | 849 | } |
| 819 | − /* | |
| 820 | − * Refresh pci hotplug in case the rfkill state was changed after | |
| 821 | − * eeepc_unregister_rfkill_notifier() | |
| 822 | − */ | |
| 823 | − eeepc_rfkill_hotplug(eeepc); | |
| 850 | + | |
| 824 | 851 | if (eeepc->hotplug_slot) |
| 825 | 852 | pci_hp_deregister(eeepc->hotplug_slot); |
| 826 | 853 | |
| @@ -889,11 +916,6 @@ static int eeepc_rfkill_init(struct eeepc_laptop *eeepc) · 62 unmodified lines | ||
| 889 | 916 | eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5"); |
| 890 | 917 | eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6"); |
| 891 | 918 | eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7"); |
| 892 | − /* | |
| 893 | − * Refresh pci hotplug in case the rfkill state was changed during | |
| 894 | − * setup. | |
| 895 | − */ | |
| 896 | − eeepc_rfkill_hotplug(eeepc); | |
| 897 | 919 | |
| 898 | 920 | exit: |
| 899 | 921 | if (result && result != -ENODEV) |
| @@ -928,8 +950,11 @@ static int eeepc_hotk_restore(struct device *device) · 28 unmodified lines | ||
| 928 | 950 | struct eeepc_laptop *eeepc = dev_get_drvdata(device); |
| 929 | 951 | |
| 930 | 952 | /* Refresh both wlan rfkill state and pci hotplug */ |
| 931 | − if (eeepc->wlan_rfkill) | |
| 932 | − eeepc_rfkill_hotplug(eeepc); | |
| 953 | + if (eeepc->wlan_rfkill) { | |
| 954 | + eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P5"); | |
| 955 | + eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P6"); | |
| 956 | + eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P7"); | |
| 957 | + } | |
| 933 | 958 | |
| 934 | 959 | if (eeepc->bluetooth_rfkill) |
| 935 | 960 | rfkill_set_sw_state(eeepc->bluetooth_rfkill, |
| @@ -934,6 +934,14 @@ static ssize_t sony_nc_sysfs_store(struct device *dev, · 933 unmodified lines | ||
| 934 | 934 | /* |
| 935 | 935 | * Backlight device |
| 936 | 936 | */ |
| 937 | +struct sony_backlight_props { | |
| 938 | + struct backlight_device *dev; | |
| 939 | + int handle; | |
| 940 | + u8 offset; | |
| 941 | + u8 maxlvl; | |
| 942 | +}; | |
| 943 | +struct sony_backlight_props sony_bl_props; | |
| 944 | + | |
| 937 | 945 | static int sony_backlight_update_status(struct backlight_device *bd) |
| 938 | 946 | { |
| 939 | 947 | return acpi_callsetfunc(sony_nc_acpi_handle, "SBRT", |
| @@ -954,21 +962,26 @@ static int sony_nc_get_brightness_ng(struct backlight_device *bd) · 14 unmodified lines | ||
| 954 | 962 | { |
| 955 | 963 | int result; |
| 956 | 964 | int *handle = (int *)bl_get_data(bd); |
| 965 | + struct sony_backlight_props *sdev = | |
| 966 | + (struct sony_backlight_props *)bl_get_data(bd); | |
| 957 | 967 | |
| 958 | − sony_call_snc_handle(*handle, 0x0200, &result); | |
| 968 | + sony_call_snc_handle(sdev->handle, 0x0200, &result); | |
| 959 | 969 | |
| 960 | − return result & 0xff; | |
| 970 | + return (result & 0xff) - sdev->offset; | |
| 961 | 971 | } |
| 962 | 972 | |
| 963 | 973 | static int sony_nc_update_status_ng(struct backlight_device *bd) |
| 964 | 974 | { |
| 965 | 975 | int value, result; |
| 966 | 976 | int *handle = (int *)bl_get_data(bd); |
| 977 | + struct sony_backlight_props *sdev = | |
| 978 | + (struct sony_backlight_props *)bl_get_data(bd); | |
| 967 | 979 | |
| 968 | − value = bd->props.brightness; | |
| 969 | − sony_call_snc_handle(*handle, 0x0100 | (value << 16), &result); | |
| 980 | + value = bd->props.brightness + sdev->offset; | |
| 981 | + if (sony_call_snc_handle(sdev->handle, 0x0100 | (value << 16), &result)) | |
| 982 | + return -EIO; | |
| 970 | 983 | |
| 971 | − return sony_nc_get_brightness_ng(bd); | |
| 984 | + return value; | |
| 972 | 985 | } |
| 973 | 986 | |
| 974 | 987 | static const struct backlight_ops sony_backlight_ops = { |
| @@ -981,8 +994,6 @@ static const struct backlight_ops sony_backlight_ng_ops = { · 6 unmodified lines | ||
| 981 | 994 | .update_status = sony_nc_update_status_ng, |
| 982 | 995 | .get_brightness = sony_nc_get_brightness_ng, |
| 983 | 996 | }; |
| 984 | −static int backlight_ng_handle; | |
| 985 | −static struct backlight_device *sony_backlight_device; | |
| 986 | 997 | |
| 987 | 998 | /* |
| 988 | 999 | * New SNC-only Vaios event mapping to driver known keys |
| @@ -1549,6 +1560,75 @@ static void sony_nc_kbd_backlight_resume(void) · 560 unmodified lines | ||
| 1549 | 1560 | &ignore); |
| 1550 | 1561 | } |
| 1551 | 1562 | |
| 1563 | +static void sony_nc_backlight_ng_read_limits(int handle, | |
| 1564 | + struct sony_backlight_props *props) | |
| 1565 | +{ | |
| 1566 | + int offset; | |
| 1567 | + acpi_status status; | |
| 1568 | + u8 brlvl, i; | |
| 1569 | + u8 min = 0xff, max = 0x00; | |
| 1570 | + struct acpi_object_list params; | |
| 1571 | + union acpi_object in_obj; | |
| 1572 | + union acpi_object *lvl_enum; | |
| 1573 | + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | |
| 1574 | + | |
| 1575 | + props->handle = handle; | |
| 1576 | + props->offset = 0; | |
| 1577 | + props->maxlvl = 0xff; | |
| 1578 | + | |
| 1579 | + offset = sony_find_snc_handle(handle); | |
| 1580 | + if (offset < 0) | |
| 1581 | + return; | |
| 1582 | + | |
| 1583 | + /* try to read the boundaries from ACPI tables, if we fail the above | |
| 1584 | + * defaults should be reasonable | |
| 1585 | + */ | |
| 1586 | + params.count = 1; | |
| 1587 | + params.pointer = &in_obj; | |
| 1588 | + in_obj.type = ACPI_TYPE_INTEGER; | |
| 1589 | + in_obj.integer.value = offset; | |
| 1590 | + status = acpi_evaluate_object(sony_nc_acpi_handle, "SN06", ¶ms, | |
| 1591 | + &buffer); | |
| 1592 | + if (ACPI_FAILURE(status)) | |
| 1593 | + return; | |
| 1594 | + | |
| 1595 | + lvl_enum = (union acpi_object *) buffer.pointer; | |
| 1596 | + if (!lvl_enum) { | |
| 1597 | + pr_err("No SN06 return object."); | |
| 1598 | + return; | |
| 1599 | + } | |
| 1600 | + if (lvl_enum->type != ACPI_TYPE_BUFFER) { | |
| 1601 | + pr_err("Invalid SN06 return object 0x%.2x\n", | |
| 1602 | + lvl_enum->type); | |
| 1603 | + goto out_invalid; | |
| 1604 | + } | |
| 1605 | + | |
| 1606 | + /* the buffer lists brightness levels available, brightness levels are | |
| 1607 | + * from 0 to 8 in the array, other values are used by ALS control. | |
| 1608 | + */ | |
| 1609 | + for (i = 0; i < 9 && i < lvl_enum->buffer.length; i++) { | |
| 1610 | + | |
| 1611 | + brlvl = *(lvl_enum->buffer.pointer + i); | |
| 1612 | + dprintk("Brightness level: %d\n", brlvl); | |
| 1613 | + | |
| 1614 | + if (!brlvl) | |
| 1615 | + break; | |
| 1616 | + | |
| 1617 | + if (brlvl > max) | |
| 1618 | + max = brlvl; | |
| 1619 | + if (brlvl < min) | |
| 1620 | + min = brlvl; | |
| 1621 | + } | |
| 1622 | + props->offset = min; | |
| 1623 | + props->maxlvl = max; | |
| 1624 | + dprintk("Brightness levels: min=%d max=%d\n", props->offset, | |
| 1625 | + props->maxlvl); | |
| 1626 | + | |
| 1627 | +out_invalid: | |
| 1628 | + kfree(buffer.pointer); | |
| 1629 | + return; | |
| 1630 | +} | |
| 1631 | + | |
| 1552 | 1632 | static void sony_nc_backlight_setup(void) |
| 1553 | 1633 | { |
| 1554 | 1634 | acpi_handle unused; |
| @@ -1557,14 +1637,14 @@ static void sony_nc_backlight_setup(void) · 2 unmodified lines | ||
| 1557 | 1637 | struct backlight_properties props; |
| 1558 | 1638 | |
| 1559 | 1639 | if (sony_find_snc_handle(0x12f) != -1) { |
| 1560 | − backlight_ng_handle = 0x12f; | |
| 1561 | 1640 | ops = &sony_backlight_ng_ops; |
| 1562 | − max_brightness = 0xff; | |
| 1641 | + sony_nc_backlight_ng_read_limits(0x12f, &sony_bl_props); | |
| 1642 | + max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; | |
| 1563 | 1643 | |
| 1564 | 1644 | } else if (sony_find_snc_handle(0x137) != -1) { |
| 1565 | − backlight_ng_handle = 0x137; | |
| 1566 | 1645 | ops = &sony_backlight_ng_ops; |
| 1567 | − max_brightness = 0xff; | |
| 1646 | + sony_nc_backlight_ng_read_limits(0x137, &sony_bl_props); | |
| 1647 | + max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; | |
| 1568 | 1648 | |
| 1569 | 1649 | } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", |
| 1570 | 1650 | &unused))) { |
| @@ -1577,22 +1657,22 @@ static void sony_nc_backlight_setup(void) · 6 unmodified lines | ||
| 1577 | 1657 | memset(&props, 0, sizeof(struct backlight_properties)); |
| 1578 | 1658 | props.type = BACKLIGHT_PLATFORM; |
| 1579 | 1659 | props.max_brightness = max_brightness; |
| 1580 | − sony_backlight_device = backlight_device_register("sony", NULL, | |
| 1581 | − &backlight_ng_handle, | |
| 1582 | − ops, &props); | |
| 1660 | + sony_bl_props.dev = backlight_device_register("sony", NULL, | |
| 1661 | + &sony_bl_props, | |
| 1662 | + ops, &props); | |
| 1583 | 1663 | |
| 1584 | − if (IS_ERR(sony_backlight_device)) { | |
| 1585 | − pr_warning(DRV_PFX "unable to register backlight device\n"); | |
| 1586 | − sony_backlight_device = NULL; | |
| 1664 | + if (IS_ERR(sony_bl_props.dev)) { | |
| 1665 | + pr_warn(DRV_PFX "unable to register backlight device\n"); | |
| 1666 | + sony_bl_props.dev = NULL; | |
| 1587 | 1667 | } else |
| 1588 | − sony_backlight_device->props.brightness = | |
| 1589 | − ops->get_brightness(sony_backlight_device); | |
| 1668 | + sony_bl_props.dev->props.brightness = | |
| 1669 | + ops->get_brightness(sony_bl_props.dev); | |
| 1590 | 1670 | } |
| 1591 | 1671 | |
| 1592 | 1672 | static void sony_nc_backlight_cleanup(void) |
| 1593 | 1673 | { |
| 1594 | − if (sony_backlight_device) | |
| 1595 | − backlight_device_unregister(sony_backlight_device); | |
| 1674 | + if (sony_bl_props.dev) | |
| 1675 | + backlight_device_unregister(sony_bl_props.dev); | |
| 1596 | 1676 | } |
| 1597 | 1677 | |
| 1598 | 1678 | static int sony_nc_add(struct acpi_device *device) |
| @@ -2590,7 +2670,7 @@ static long sonypi_misc_ioctl(struct file *fp, unsigned int cmd, · 991 unmodified lines | ||
| 2590 | 2670 | mutex_lock(&spic_dev.lock); |
| 2591 | 2671 | switch (cmd) { |
| 2592 | 2672 | case SONYPI_IOCGBRT: |
| 2593 | − if (sony_backlight_device == NULL) { | |
| 2673 | + if (sony_bl_props.dev == NULL) { | |
| 2594 | 2674 | ret = -EIO; |
| 2595 | 2675 | break; |
| 2596 | 2676 | } |
| @@ -2603,7 +2683,7 @@ static long sonypi_misc_ioctl(struct file *fp, unsigned int cmd, · 6 unmodified lines | ||
| 2603 | 2683 | ret = -EFAULT; |
| 2604 | 2684 | break; |
| 2605 | 2685 | case SONYPI_IOCSBRT: |
| 2606 | − if (sony_backlight_device == NULL) { | |
| 2686 | + if (sony_bl_props.dev == NULL) { | |
| 2607 | 2687 | ret = -EIO; |
| 2608 | 2688 | break; |
| 2609 | 2689 | } |
| @@ -2617,8 +2697,8 @@ static long sonypi_misc_ioctl(struct file *fp, unsigned int cmd, · 7 unmodified lines | ||
| 2617 | 2697 | break; |
| 2618 | 2698 | } |
| 2619 | 2699 | /* sync the backlight device status */ |
| 2620 | − sony_backlight_device->props.brightness = | |
| 2621 | − sony_backlight_get_brightness(sony_backlight_device); | |
| 2700 | + sony_bl_props.dev->props.brightness = | |
| 2701 | + sony_backlight_get_brightness(sony_bl_props.dev); | |
| 2622 | 2702 | break; |
| 2623 | 2703 | case SONYPI_IOCGBAT1CAP: |
| 2624 | 2704 | if (ec_read16(SONYPI_BAT1_FULL, &val16)) { |
| @@ -128,7 +128,8 @@ enum { · 127 unmodified lines | ||
| 128 | 128 | }; |
| 129 | 129 | |
| 130 | 130 | /* ACPI HIDs */ |
| 131 | −#define TPACPI_ACPI_HKEY_HID "IBM0068" | |
| 131 | +#define TPACPI_ACPI_IBM_HKEY_HID "IBM0068" | |
| 132 | +#define TPACPI_ACPI_LENOVO_HKEY_HID "LEN0068" | |
| 132 | 133 | #define TPACPI_ACPI_EC_HID "PNP0C09" |
| 133 | 134 | |
| 134 | 135 | /* Input IDs */ |
| @@ -3879,7 +3880,8 @@ errexit: · 3744 unmodified lines | ||
| 3879 | 3880 | } |
| 3880 | 3881 | |
| 3881 | 3882 | static const struct acpi_device_id ibm_htk_device_ids[] = { |
| 3882 | − {TPACPI_ACPI_HKEY_HID, 0}, | |
| 3883 | + {TPACPI_ACPI_IBM_HKEY_HID, 0}, | |
| 3884 | + {TPACPI_ACPI_LENOVO_HKEY_HID, 0}, | |
| 3883 | 3885 | {"", 0}, |
| 3884 | 3886 | }; |
| 3885 | 3887 | |
| @@ -95,6 +95,9 @@ idtg2_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, · 94 unmodified lines | ||
| 95 | 95 | else |
| 96 | 96 | table++; |
| 97 | 97 | |
| 98 | + if (route_port == RIO_INVALID_ROUTE) | |
| 99 | + route_port = IDT_DEFAULT_ROUTE; | |
| 100 | + | |
| 98 | 101 | rio_mport_write_config_32(mport, destid, hopcount, |
| 99 | 102 | LOCAL_RTE_CONF_DESTID_SEL, table); |
| 100 | 103 | |
| @@ -411,6 +414,12 @@ static int idtg2_switch_init(struct rio_dev *rdev, int do_enum) · 310 unmodified lines | ||
| 411 | 414 | rdev->rswitch->em_handle = idtg2_em_handler; |
| 412 | 415 | rdev->rswitch->sw_sysfs = idtg2_sysfs; |
| 413 | 416 | |
| 417 | + if (do_enum) { | |
| 418 | + /* Ensure that default routing is disabled on startup */ | |
| 419 | + rio_write_config_32(rdev, | |
| 420 | + RIO_STD_RTE_DEFAULT_PORT, IDT_NO_ROUTE); | |
| 421 | + } | |
| 422 | + | |
| 414 | 423 | return 0; |
| 415 | 424 | } |
| 416 | 425 | |
| @@ -26,6 +26,9 @@ idtcps_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, · 25 unmodified lines | ||
| 26 | 26 | { |
| 27 | 27 | u32 result; |
| 28 | 28 | |
| 29 | + if (route_port == RIO_INVALID_ROUTE) | |
| 30 | + route_port = CPS_DEFAULT_ROUTE; | |
| 31 | + | |
| 29 | 32 | if (table == RIO_GLOBAL_TABLE) { |
| 30 | 33 | rio_mport_write_config_32(mport, destid, hopcount, |
| 31 | 34 | RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid); |
| @@ -130,6 +133,9 @@ static int idtcps_switch_init(struct rio_dev *rdev, int do_enum) · 98 unmodified lines | ||
| 130 | 133 | /* set TVAL = ~50us */ |
| 131 | 134 | rio_write_config_32(rdev, |
| 132 | 135 | rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x8e << 8); |
| 136 | + /* Ensure that default routing is disabled on startup */ | |
| 137 | + rio_write_config_32(rdev, | |
| 138 | + RIO_STD_RTE_DEFAULT_PORT, CPS_NO_ROUTE); | |
| 133 | 139 | } |
| 134 | 140 | |
| 135 | 141 | return 0; |
| @@ -303,6 +303,12 @@ static int tsi57x_switch_init(struct rio_dev *rdev, int do_enum) · 302 unmodified lines | ||
| 303 | 303 | rdev->rswitch->em_init = tsi57x_em_init; |
| 304 | 304 | rdev->rswitch->em_handle = tsi57x_em_handler; |
| 305 | 305 | |
| 306 | + if (do_enum) { | |
| 307 | + /* Ensure that default routing is disabled on startup */ | |
| 308 | + rio_write_config_32(rdev, RIO_STD_RTE_DEFAULT_PORT, | |
| 309 | + RIO_INVALID_ROUTE); | |
| 310 | + } | |
| 311 | + | |
| 306 | 312 | return 0; |
| 307 | 313 | } |
| 308 | 314 | |
| @@ -220,6 +220,7 @@ static int __init coh901331_probe(struct platform_device *pdev) · 219 unmodified lines | ||
| 220 | 220 | } |
| 221 | 221 | clk_disable(rtap->clk); |
| 222 | 222 | |
| 223 | + platform_set_drvdata(pdev, rtap); | |
| 223 | 224 | rtap->rtc = rtc_device_register("coh901331", &pdev->dev, &coh901331_ops, |
| 224 | 225 | THIS_MODULE); |
| 225 | 226 | if (IS_ERR(rtap->rtc)) { |
| @@ -227,11 +228,10 @@ static int __init coh901331_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 227 | 228 | goto out_no_rtc; |
| 228 | 229 | } |
| 229 | 230 | |
| 230 | − platform_set_drvdata(pdev, rtap); | |
| 231 | − | |
| 232 | 231 | return 0; |
| 233 | 232 | |
| 234 | 233 | out_no_rtc: |
| 234 | + platform_set_drvdata(pdev, NULL); | |
| 235 | 235 | out_no_clk_enable: |
| 236 | 236 | clk_put(rtap->clk); |
| 237 | 237 | out_no_clk: |
| @@ -524,6 +524,8 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) · 523 unmodified lines | ||
| 524 | 524 | goto fail2; |
| 525 | 525 | } |
| 526 | 526 | |
| 527 | + platform_set_drvdata(pdev, davinci_rtc); | |
| 528 | + | |
| 527 | 529 | davinci_rtc->rtc = rtc_device_register(pdev->name, &pdev->dev, |
| 528 | 530 | &davinci_rtc_ops, THIS_MODULE); |
| 529 | 531 | if (IS_ERR(davinci_rtc->rtc)) { |
| @@ -553,8 +555,6 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) · 23 unmodified lines | ||
| 553 | 555 | |
| 554 | 556 | rtcss_write(davinci_rtc, PRTCSS_RTC_CCTRL_CAEN, PRTCSS_RTC_CCTRL); |
| 555 | 557 | |
| 556 | − platform_set_drvdata(pdev, davinci_rtc); | |
| 557 | − | |
| 558 | 558 | device_init_wakeup(&pdev->dev, 0); |
| 559 | 559 | |
| 560 | 560 | return 0; |
| @@ -562,6 +562,7 @@ static int __init davinci_rtc_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 562 | 562 | fail4: |
| 563 | 563 | rtc_device_unregister(davinci_rtc->rtc); |
| 564 | 564 | fail3: |
| 565 | + platform_set_drvdata(pdev, NULL); | |
| 565 | 566 | iounmap(davinci_rtc->base); |
| 566 | 567 | fail2: |
| 567 | 568 | release_mem_region(davinci_rtc->pbase, davinci_rtc->base_size); |
| @@ -355,6 +355,7 @@ static int __devinit ds1286_probe(struct platform_device *pdev) · 354 unmodified lines | ||
| 355 | 355 | goto out; |
| 356 | 356 | } |
| 357 | 357 | spin_lock_init(&priv->lock); |
| 358 | + platform_set_drvdata(pdev, priv); | |
| 358 | 359 | rtc = rtc_device_register("ds1286", &pdev->dev, |
| 359 | 360 | &ds1286_ops, THIS_MODULE); |
| 360 | 361 | if (IS_ERR(rtc)) { |
| @@ -362,7 +363,6 @@ static int __devinit ds1286_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 362 | 363 | goto out; |
| 363 | 364 | } |
| 364 | 365 | priv->rtc = rtc; |
| 365 | − platform_set_drvdata(pdev, priv); | |
| 366 | 366 | return 0; |
| 367 | 367 | |
| 368 | 368 | out: |
| @@ -151,6 +151,7 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev) · 150 unmodified lines | ||
| 151 | 151 | return -ENXIO; |
| 152 | 152 | |
| 153 | 153 | pdev->dev.platform_data = ep93xx_rtc; |
| 154 | + platform_set_drvdata(pdev, rtc); | |
| 154 | 155 | |
| 155 | 156 | rtc = rtc_device_register(pdev->name, |
| 156 | 157 | &pdev->dev, &ep93xx_rtc_ops, THIS_MODULE); |
| @@ -159,8 +160,6 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 159 | 160 | goto exit; |
| 160 | 161 | } |
| 161 | 162 | |
| 162 | − platform_set_drvdata(pdev, rtc); | |
| 163 | − | |
| 164 | 163 | err = sysfs_create_group(&pdev->dev.kobj, &ep93xx_rtc_sysfs_files); |
| 165 | 164 | if (err) |
| 166 | 165 | goto fail; |
| @@ -168,9 +167,9 @@ static int __init ep93xx_rtc_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 168 | 167 | return 0; |
| 169 | 168 | |
| 170 | 169 | fail: |
| 171 | − platform_set_drvdata(pdev, NULL); | |
| 172 | 170 | rtc_device_unregister(rtc); |
| 173 | 171 | exit: |
| 172 | + platform_set_drvdata(pdev, NULL); | |
| 174 | 173 | pdev->dev.platform_data = NULL; |
| 175 | 174 | return err; |
| 176 | 175 | } |
| @@ -783,6 +783,9 @@ static int m41t80_probe(struct i2c_client *client, · 782 unmodified lines | ||
| 783 | 783 | goto exit; |
| 784 | 784 | } |
| 785 | 785 | |
| 786 | + clientdata->features = id->driver_data; | |
| 787 | + i2c_set_clientdata(client, clientdata); | |
| 788 | + | |
| 786 | 789 | rtc = rtc_device_register(client->name, &client->dev, |
| 787 | 790 | &m41t80_rtc_ops, THIS_MODULE); |
| 788 | 791 | if (IS_ERR(rtc)) { |
| @@ -792,8 +795,6 @@ static int m41t80_probe(struct i2c_client *client, · 3 unmodified lines | ||
| 792 | 795 | } |
| 793 | 796 | |
| 794 | 797 | clientdata->rtc = rtc; |
| 795 | − clientdata->features = id->driver_data; | |
| 796 | − i2c_set_clientdata(client, clientdata); | |
| 797 | 798 | |
| 798 | 799 | /* Make sure HT (Halt Update) bit is cleared */ |
| 799 | 800 | rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_HOUR); |
| @@ -257,6 +257,10 @@ static int __devinit max8925_rtc_probe(struct platform_device *pdev) · 256 unmodified lines | ||
| 257 | 257 | goto out_irq; |
| 258 | 258 | } |
| 259 | 259 | |
| 260 | + dev_set_drvdata(&pdev->dev, info); | |
| 261 | + /* XXX - isn't this redundant? */ | |
| 262 | + platform_set_drvdata(pdev, info); | |
| 263 | + | |
| 260 | 264 | info->rtc_dev = rtc_device_register("max8925-rtc", &pdev->dev, |
| 261 | 265 | &max8925_rtc_ops, THIS_MODULE); |
| 262 | 266 | ret = PTR_ERR(info->rtc_dev); |
| @@ -265,11 +269,9 @@ static int __devinit max8925_rtc_probe(struct platform_device *pdev) · 2 unmodified lines | ||
| 265 | 269 | goto out_rtc; |
| 266 | 270 | } |
| 267 | 271 | |
| 268 | − dev_set_drvdata(&pdev->dev, info); | |
| 269 | − platform_set_drvdata(pdev, info); | |
| 270 | − | |
| 271 | 272 | return 0; |
| 272 | 273 | out_rtc: |
| 274 | + platform_set_drvdata(pdev, NULL); | |
| 273 | 275 | free_irq(chip->irq_base + MAX8925_IRQ_RTC_ALARM0, info); |
| 274 | 276 | out_irq: |
| 275 | 277 | kfree(info); |
| @@ -265,6 +265,8 @@ static int __devinit max8998_rtc_probe(struct platform_device *pdev) · 264 unmodified lines | ||
| 265 | 265 | info->rtc = max8998->rtc; |
| 266 | 266 | info->irq = max8998->irq_base + MAX8998_IRQ_ALARM0; |
| 267 | 267 | |
| 268 | + platform_set_drvdata(pdev, info); | |
| 269 | + | |
| 268 | 270 | info->rtc_dev = rtc_device_register("max8998-rtc", &pdev->dev, |
| 269 | 271 | &max8998_rtc_ops, THIS_MODULE); |
| 270 | 272 | |
| @@ -274,8 +276,6 @@ static int __devinit max8998_rtc_probe(struct platform_device *pdev) · 3 unmodified lines | ||
| 274 | 276 | goto out_rtc; |
| 275 | 277 | } |
| 276 | 278 | |
| 277 | − platform_set_drvdata(pdev, info); | |
| 278 | − | |
| 279 | 279 | ret = request_threaded_irq(info->irq, NULL, max8998_rtc_alarm_irq, 0, |
| 280 | 280 | "rtc-alarm0", info); |
| 281 | 281 | |
| @@ -293,6 +293,7 @@ static int __devinit max8998_rtc_probe(struct platform_device *pdev) · 11 unmodified lines | ||
| 293 | 293 | return 0; |
| 294 | 294 | |
| 295 | 295 | out_rtc: |
| 296 | + platform_set_drvdata(pdev, NULL); | |
| 296 | 297 | kfree(info); |
| 297 | 298 | return ret; |
| 298 | 299 | } |
| @@ -349,11 +349,15 @@ static int __devinit mc13xxx_rtc_probe(struct platform_device *pdev) · 348 unmodified lines | ||
| 349 | 349 | if (ret) |
| 350 | 350 | goto err_alarm_irq_request; |
| 351 | 351 | |
| 352 | + mc13xxx_unlock(mc13xxx); | |
| 353 | + | |
| 352 | 354 | priv->rtc = rtc_device_register(pdev->name, |
| 353 | 355 | &pdev->dev, &mc13xxx_rtc_ops, THIS_MODULE); |
| 354 | 356 | if (IS_ERR(priv->rtc)) { |
| 355 | 357 | ret = PTR_ERR(priv->rtc); |
| 356 | 358 | |
| 359 | + mc13xxx_lock(mc13xxx); | |
| 360 | + | |
| 357 | 361 | mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_TODA, priv); |
| 358 | 362 | err_alarm_irq_request: |
| 359 | 363 | |
| @@ -365,12 +369,12 @@ err_reset_irq_status: · 5 unmodified lines | ||
| 365 | 369 | mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_RTCRST, priv); |
| 366 | 370 | err_reset_irq_request: |
| 367 | 371 | |
| 372 | + mc13xxx_unlock(mc13xxx); | |
| 373 | + | |
| 368 | 374 | platform_set_drvdata(pdev, NULL); |
| 369 | 375 | kfree(priv); |
| 370 | 376 | } |
| 371 | 377 | |
| 372 | − mc13xxx_unlock(mc13xxx); | |
| 373 | − | |
| 374 | 378 | return ret; |
| 375 | 379 | } |
| 376 | 380 | |
| @@ -214,6 +214,7 @@ static int __init msm6242_rtc_probe(struct platform_device *dev) · 213 unmodified lines | ||
| 214 | 214 | error = -ENOMEM; |
| 215 | 215 | goto out_free_priv; |
| 216 | 216 | } |
| 217 | + platform_set_drvdata(dev, priv); | |
| 217 | 218 | |
| 218 | 219 | rtc = rtc_device_register("rtc-msm6242", &dev->dev, &msm6242_rtc_ops, |
| 219 | 220 | THIS_MODULE); |
| @@ -223,10 +224,10 @@ static int __init msm6242_rtc_probe(struct platform_device *dev) · 3 unmodified lines | ||
| 223 | 224 | } |
| 224 | 225 | |
| 225 | 226 | priv->rtc = rtc; |
| 226 | − platform_set_drvdata(dev, priv); | |
| 227 | 227 | return 0; |
| 228 | 228 | |
| 229 | 229 | out_unmap: |
| 230 | + platform_set_drvdata(dev, NULL); | |
| 230 | 231 | iounmap(priv->regs); |
| 231 | 232 | out_free_priv: |
| 232 | 233 | kfree(priv); |
| @@ -418,14 +418,6 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) · 417 unmodified lines | ||
| 418 | 418 | goto exit_put_clk; |
| 419 | 419 | } |
| 420 | 420 | |
| 421 | − rtc = rtc_device_register(pdev->name, &pdev->dev, &mxc_rtc_ops, | |
| 422 | − THIS_MODULE); | |
| 423 | − if (IS_ERR(rtc)) { | |
| 424 | − ret = PTR_ERR(rtc); | |
| 425 | − goto exit_put_clk; | |
| 426 | − } | |
| 427 | − | |
| 428 | − pdata->rtc = rtc; | |
| 429 | 421 | platform_set_drvdata(pdev, pdata); |
| 430 | 422 | |
| 431 | 423 | /* Configure and enable the RTC */ |
| @@ -438,8 +430,19 @@ static int __init mxc_rtc_probe(struct platform_device *pdev) · 6 unmodified lines | ||
| 438 | 430 | pdata->irq = -1; |
| 439 | 431 | } |
| 440 | 432 | |
| 433 | + rtc = rtc_device_register(pdev->name, &pdev->dev, &mxc_rtc_ops, | |
| 434 | + THIS_MODULE); | |
| 435 | + if (IS_ERR(rtc)) { | |
| 436 | + ret = PTR_ERR(rtc); | |
| 437 | + goto exit_clr_drvdata; | |
| 438 | + } | |
| 439 | + | |
| 440 | + pdata->rtc = rtc; | |
| 441 | + | |
| 441 | 442 | return 0; |
| 442 | 443 | |
| 444 | +exit_clr_drvdata: | |
| 445 | + platform_set_drvdata(pdev, NULL); | |
| 443 | 446 | exit_put_clk: |
| 444 | 447 | clk_disable(pdata->clk); |
| 445 | 448 | clk_put(pdata->clk); |
| @@ -394,7 +394,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev) · 393 unmodified lines | ||
| 394 | 394 | return 0; |
| 395 | 395 | |
| 396 | 396 | fail2: |
| 397 | − free_irq(omap_rtc_timer, NULL); | |
| 397 | + free_irq(omap_rtc_timer, rtc); | |
| 398 | 398 | fail1: |
| 399 | 399 | rtc_device_unregister(rtc); |
| 400 | 400 | fail0: |
| @@ -151,6 +151,8 @@ static int __devinit pcap_rtc_probe(struct platform_device *pdev) · 150 unmodified lines | ||
| 151 | 151 | |
| 152 | 152 | pcap_rtc->pcap = dev_get_drvdata(pdev->dev.parent); |
| 153 | 153 | |
| 154 | + platform_set_drvdata(pdev, pcap_rtc); | |
| 155 | + | |
| 154 | 156 | pcap_rtc->rtc = rtc_device_register("pcap", &pdev->dev, |
| 155 | 157 | &pcap_rtc_ops, THIS_MODULE); |
| 156 | 158 | if (IS_ERR(pcap_rtc->rtc)) { |
| @@ -158,7 +160,6 @@ static int __devinit pcap_rtc_probe(struct platform_device *pdev) · 1 unmodified line | ||
| 158 | 160 | goto fail_rtc; |
| 159 | 161 | } |
| 160 | 162 | |
| 161 | − platform_set_drvdata(pdev, pcap_rtc); | |
| 162 | 163 | |
| 163 | 164 | timer_irq = pcap_to_irq(pcap_rtc->pcap, PCAP_IRQ_1HZ); |
| 164 | 165 | alarm_irq = pcap_to_irq(pcap_rtc->pcap, PCAP_IRQ_TODA); |
| @@ -177,6 +178,7 @@ fail_alarm: · 12 unmodified lines | ||
| 177 | 178 | fail_timer: |
| 178 | 179 | rtc_device_unregister(pcap_rtc->rtc); |
| 179 | 180 | fail_rtc: |
| 181 | + platform_set_drvdata(pdev, NULL); | |
| 180 | 182 | kfree(pcap_rtc); |
| 181 | 183 | return err; |
| 182 | 184 | } |
| @@ -249,15 +249,15 @@ static int __init rp5c01_rtc_probe(struct platform_device *dev) · 248 unmodified lines | ||
| 249 | 249 | |
| 250 | 250 | spin_lock_init(&priv->lock); |
| 251 | 251 | |
| 252 | + platform_set_drvdata(dev, priv); | |
| 253 | + | |
| 252 | 254 | rtc = rtc_device_register("rtc-rp5c01", &dev->dev, &rp5c01_rtc_ops, |
| 253 | 255 | THIS_MODULE); |
| 254 | 256 | if (IS_ERR(rtc)) { |
| 255 | 257 | error = PTR_ERR(rtc); |
| 256 | 258 | goto out_unmap; |
| 257 | 259 | } |
| 258 | − | |
| 259 | 260 | priv->rtc = rtc; |
| 260 | − platform_set_drvdata(dev, priv); | |
| 261 | 261 | |
| 262 | 262 | error = sysfs_create_bin_file(&dev->dev.kobj, &priv->nvram_attr); |
| 263 | 263 | if (error) |
| @@ -268,6 +268,7 @@ static int __init rp5c01_rtc_probe(struct platform_device *dev) · 4 unmodified lines | ||
| 268 | 268 | out_unregister: |
| 269 | 269 | rtc_device_unregister(rtc); |
| 270 | 270 | out_unmap: |
| 271 | + platform_set_drvdata(dev, NULL); | |
| 271 | 272 | iounmap(priv->regs); |
| 272 | 273 | out_free_priv: |
| 273 | 274 | kfree(priv); |
| @@ -46,6 +46,7 @@ static struct clk *rtc_clk; · 45 unmodified lines | ||
| 46 | 46 | static void __iomem *s3c_rtc_base; |
| 47 | 47 | static int s3c_rtc_alarmno = NO_IRQ; |
| 48 | 48 | static int s3c_rtc_tickno = NO_IRQ; |
| 49 | +static bool wake_en; | |
| 49 | 50 | static enum s3c_cpu_type s3c_rtc_cpu_type; |
| 50 | 51 | |
| 51 | 52 | static DEFINE_SPINLOCK(s3c_rtc_pie_lock); |
| @@ -562,8 +563,12 @@ static int s3c_rtc_suspend(struct platform_device *pdev, pm_message_t state) · 510 unmodified lines | ||
| 562 | 563 | } |
| 563 | 564 | s3c_rtc_enable(pdev, 0); |
| 564 | 565 | |
| 565 | − if (device_may_wakeup(&pdev->dev)) | |
| 566 | − enable_irq_wake(s3c_rtc_alarmno); | |
| 566 | + if (device_may_wakeup(&pdev->dev) && !wake_en) { | |
| 567 | + if (enable_irq_wake(s3c_rtc_alarmno) == 0) | |
| 568 | + wake_en = true; | |
| 569 | + else | |
| 570 | + dev_err(&pdev->dev, "enable_irq_wake failed\n"); | |
| 571 | + } | |
| 567 | 572 | |
| 568 | 573 | return 0; |
| 569 | 574 | } |
| @@ -579,8 +584,10 @@ static int s3c_rtc_resume(struct platform_device *pdev) · 9 unmodified lines | ||
| 579 | 584 | writew(tmp | ticnt_en_save, s3c_rtc_base + S3C2410_RTCCON); |
| 580 | 585 | } |
| 581 | 586 | |
| 582 | − if (device_may_wakeup(&pdev->dev)) | |
| 587 | + if (device_may_wakeup(&pdev->dev) && wake_en) { | |
| 583 | 588 | disable_irq_wake(s3c_rtc_alarmno); |
| 589 | + wake_en = false; | |
| 590 | + } | |
| 584 | 591 | |
| 585 | 592 | return 0; |
| 586 | 593 | } |
| @@ -1742,11 +1742,20 @@ int dasd_sleep_on_interruptible(struct dasd_ccw_req *cqr) · 1741 unmodified lines | ||
| 1742 | 1742 | static inline int _dasd_term_running_cqr(struct dasd_device *device) |
| 1743 | 1743 | { |
| 1744 | 1744 | struct dasd_ccw_req *cqr; |
| 1745 | + int rc; | |
| 1745 | 1746 | |
| 1746 | 1747 | if (list_empty(&device->ccw_queue)) |
| 1747 | 1748 | return 0; |
| 1748 | 1749 | cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, devlist); |
| 1749 | − return device->discipline->term_IO(cqr); | |
| 1750 | + rc = device->discipline->term_IO(cqr); | |
| 1751 | + if (!rc) | |
| 1752 | + /* | |
| 1753 | + * CQR terminated because a more important request is pending. | |
| 1754 | + * Undo decreasing of retry counter because this is | |
| 1755 | + * not an error case. | |
| 1756 | + */ | |
| 1757 | + cqr->retries++; | |
| 1758 | + return rc; | |
| 1750 | 1759 | } |
| 1751 | 1760 | |
| 1752 | 1761 | int dasd_sleep_on_immediatly(struct dasd_ccw_req *cqr) |
| @@ -2314,15 +2323,14 @@ static void dasd_flush_request_queue(struct dasd_block *block) · 561 unmodified lines | ||
| 2314 | 2323 | |
| 2315 | 2324 | static int dasd_open(struct block_device *bdev, fmode_t mode) |
| 2316 | 2325 | { |
| 2317 | − struct dasd_block *block = bdev->bd_disk->private_data; | |
| 2318 | 2326 | struct dasd_device *base; |
| 2319 | 2327 | int rc; |
| 2320 | 2328 | |
| 2321 | − if (!block) | |
| 2329 | + base = dasd_device_from_gendisk(bdev->bd_disk); | |
| 2330 | + if (!base) | |
| 2322 | 2331 | return -ENODEV; |
| 2323 | 2332 | |
| 2324 | − base = block->base; | |
| 2325 | − atomic_inc(&block->open_count); | |
| 2333 | + atomic_inc(&base->block->open_count); | |
| 2326 | 2334 | if (test_bit(DASD_FLAG_OFFLINE, &base->flags)) { |
| 2327 | 2335 | rc = -ENODEV; |
| 2328 | 2336 | goto unlock; |
| @@ -2355,21 +2363,28 @@ static int dasd_open(struct block_device *bdev, fmode_t mode) · 26 unmodified lines | ||
| 2355 | 2363 | goto out; |
| 2356 | 2364 | } |
| 2357 | 2365 | |
| 2366 | + dasd_put_device(base); | |
| 2358 | 2367 | return 0; |
| 2359 | 2368 | |
| 2360 | 2369 | out: |
| 2361 | 2370 | module_put(base->discipline->owner); |
| 2362 | 2371 | unlock: |
| 2363 | − atomic_dec(&block->open_count); | |
| 2372 | + atomic_dec(&base->block->open_count); | |
| 2373 | + dasd_put_device(base); | |
| 2364 | 2374 | return rc; |
| 2365 | 2375 | } |
| 2366 | 2376 | |
| 2367 | 2377 | static int dasd_release(struct gendisk *disk, fmode_t mode) |
| 2368 | 2378 | { |
| 2369 | − struct dasd_block *block = disk->private_data; | |
| 2379 | + struct dasd_device *base; | |
| 2370 | 2380 | |
| 2371 | − atomic_dec(&block->open_count); | |
| 2372 | − module_put(block->base->discipline->owner); | |
| 2381 | + base = dasd_device_from_gendisk(disk); | |
| 2382 | + if (!base) | |
| 2383 | + return -ENODEV; | |
| 2384 | + | |
| 2385 | + atomic_dec(&base->block->open_count); | |
| 2386 | + module_put(base->discipline->owner); | |
| 2387 | + dasd_put_device(base); | |
| 2373 | 2388 | return 0; |
| 2374 | 2389 | } |
| 2375 | 2390 | |
| @@ -2378,20 +2393,20 @@ static int dasd_release(struct gendisk *disk, fmode_t mode) · 2 unmodified lines | ||
| 2378 | 2393 | */ |
| 2379 | 2394 | static int dasd_getgeo(struct block_device *bdev, struct hd_geometry *geo) |
| 2380 | 2395 | { |
| 2381 | − struct dasd_block *block; | |
| 2382 | 2396 | struct dasd_device *base; |
| 2383 | 2397 | |
| 2384 | − block = bdev->bd_disk->private_data; | |
| 2385 | − if (!block) | |
| 2398 | + base = dasd_device_from_gendisk(bdev->bd_disk); | |
| 2399 | + if (!base) | |
| 2386 | 2400 | return -ENODEV; |
| 2387 | − base = block->base; | |
| 2388 | 2401 | |
| 2389 | 2402 | if (!base->discipline || |
| 2390 | − !base->discipline->fill_geometry) | |
| 2403 | + !base->discipline->fill_geometry) { | |
| 2404 | + dasd_put_device(base); | |
| 2391 | 2405 | return -EINVAL; |
| 2392 | − | |
| 2393 | − base->discipline->fill_geometry(block, geo); | |
| 2394 | − geo->start = get_start_sect(bdev) >> block->s2b_shift; | |
| 2406 | + } | |
| 2407 | + base->discipline->fill_geometry(base->block, geo); | |
| 2408 | + geo->start = get_start_sect(bdev) >> base->block->s2b_shift; | |
| 2409 | + dasd_put_device(base); | |
| 2395 | 2410 | return 0; |
| 2396 | 2411 | } |
| 2397 | 2412 | |
| @@ -2528,7 +2543,6 @@ void dasd_generic_remove(struct ccw_device *cdev) · 130 unmodified lines | ||
| 2528 | 2543 | dasd_set_target_state(device, DASD_STATE_NEW); |
| 2529 | 2544 | /* dasd_delete_device destroys the device reference. */ |
| 2530 | 2545 | block = device->block; |
| 2531 | − device->block = NULL; | |
| 2532 | 2546 | dasd_delete_device(device); |
| 2533 | 2547 | /* |
| 2534 | 2548 | * life cycle of block is bound to device, so delete it after |
| @@ -2650,7 +2664,6 @@ int dasd_generic_set_offline(struct ccw_device *cdev) · 115 unmodified lines | ||
| 2650 | 2664 | dasd_set_target_state(device, DASD_STATE_NEW); |
| 2651 | 2665 | /* dasd_delete_device destroys the device reference. */ |
| 2652 | 2666 | block = device->block; |
| 2653 | − device->block = NULL; | |
| 2654 | 2667 | dasd_delete_device(device); |
| 2655 | 2668 | /* |
| 2656 | 2669 | * life cycle of block is bound to device, so delete it after |
| @@ -674,6 +674,36 @@ dasd_device_from_cdev(struct ccw_device *cdev) · 673 unmodified lines | ||
| 674 | 674 | return device; |
| 675 | 675 | } |
| 676 | 676 | |
| 677 | +void dasd_add_link_to_gendisk(struct gendisk *gdp, struct dasd_device *device) | |
| 678 | +{ | |
| 679 | + struct dasd_devmap *devmap; | |
| 680 | + | |
| 681 | + devmap = dasd_find_busid(dev_name(&device->cdev->dev)); | |
| 682 | + if (IS_ERR(devmap)) | |
| 683 | + return; | |
| 684 | + spin_lock(&dasd_devmap_lock); | |
| 685 | + gdp->private_data = devmap; | |
| 686 | + spin_unlock(&dasd_devmap_lock); | |
| 687 | +} | |
| 688 | + | |
| 689 | +struct dasd_device *dasd_device_from_gendisk(struct gendisk *gdp) | |
| 690 | +{ | |
| 691 | + struct dasd_device *device; | |
| 692 | + struct dasd_devmap *devmap; | |
| 693 | + | |
| 694 | + if (!gdp->private_data) | |
| 695 | + return NULL; | |
| 696 | + device = NULL; | |
| 697 | + spin_lock(&dasd_devmap_lock); | |
| 698 | + devmap = gdp->private_data; | |
| 699 | + if (devmap && devmap->device) { | |
| 700 | + device = devmap->device; | |
| 701 | + dasd_get_device(device); | |
| 702 | + } | |
| 703 | + spin_unlock(&dasd_devmap_lock); | |
| 704 | + return device; | |
| 705 | +} | |
| 706 | + | |
| 677 | 707 | /* |
| 678 | 708 | * SECTION: files in sysfs |
| 679 | 709 | */ |
| @@ -239,7 +239,6 @@ static void dasd_ext_handler(unsigned int ext_int_code, · 238 unmodified lines | ||
| 239 | 239 | addr_t ip; |
| 240 | 240 | int rc; |
| 241 | 241 | |
| 242 | − kstat_cpu(smp_processor_id()).irqs[EXTINT_DSD]++; | |
| 243 | 242 | switch (ext_int_code >> 24) { |
| 244 | 243 | case DASD_DIAG_CODE_31BIT: |
| 245 | 244 | ip = (addr_t) param32; |
| @@ -250,6 +249,7 @@ static void dasd_ext_handler(unsigned int ext_int_code, · 4 unmodified lines | ||
| 250 | 249 | default: |
| 251 | 250 | return; |
| 252 | 251 | } |
| 252 | + kstat_cpu(smp_processor_id()).irqs[EXTINT_DSD]++; | |
| 253 | 253 | if (!ip) { /* no intparm: unsolicited interrupt */ |
| 254 | 254 | DBF_EVENT(DBF_NOTICE, "%s", "caught unsolicited " |
| 255 | 255 | "interrupt"); |
| @@ -2037,7 +2037,7 @@ static void dasd_eckd_check_for_device_change(struct dasd_device *device, · 2036 unmodified lines | ||
| 2037 | 2037 | return; |
| 2038 | 2038 | |
| 2039 | 2039 | /* summary unit check */ |
| 2040 | − if ((sense[7] == 0x0D) && | |
| 2040 | + if ((sense[27] & DASD_SENSE_BIT_0) && (sense[7] == 0x0D) && | |
| 2041 | 2041 | (scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK)) { |
| 2042 | 2042 | dasd_alias_handle_summary_unit_check(device, irb); |
| 2043 | 2043 | return; |
| @@ -2053,7 +2053,8 @@ static void dasd_eckd_check_for_device_change(struct dasd_device *device, · 9 unmodified lines | ||
| 2053 | 2053 | /* loss of device reservation is handled via base devices only |
| 2054 | 2054 | * as alias devices may be used with several bases |
| 2055 | 2055 | */ |
| 2056 | − if (device->block && (sense[7] == 0x3F) && | |
| 2056 | + if (device->block && (sense[27] & DASD_SENSE_BIT_0) && | |
| 2057 | + (sense[7] == 0x3F) && | |
| 2057 | 2058 | (scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK) && |
| 2058 | 2059 | test_bit(DASD_FLAG_IS_RESERVED, &device->flags)) { |
| 2059 | 2060 | if (device->features & DASD_FEATURE_FAILONSLCK) |
| @@ -73,7 +73,7 @@ int dasd_gendisk_alloc(struct dasd_block *block) · 72 unmodified lines | ||
| 73 | 73 | if (base->features & DASD_FEATURE_READONLY || |
| 74 | 74 | test_bit(DASD_FLAG_DEVICE_RO, &base->flags)) |
| 75 | 75 | set_disk_ro(gdp, 1); |
| 76 | − gdp->private_data = block; | |
| 76 | + dasd_add_link_to_gendisk(gdp, base); | |
| 77 | 77 | gdp->queue = block->request_queue; |
| 78 | 78 | block->gdp = gdp; |
| 79 | 79 | set_capacity(block->gdp, 0); |
| @@ -686,6 +686,9 @@ struct dasd_device *dasd_device_from_cdev(struct ccw_device *); · 685 unmodified lines | ||
| 686 | 686 | struct dasd_device *dasd_device_from_cdev_locked(struct ccw_device *); |
| 687 | 687 | struct dasd_device *dasd_device_from_devindex(int); |
| 688 | 688 | |
| 689 | +void dasd_add_link_to_gendisk(struct gendisk *, struct dasd_device *); | |
| 690 | +struct dasd_device *dasd_device_from_gendisk(struct gendisk *); | |
| 691 | + | |
| 689 | 692 | int dasd_parse(void); |
| 690 | 693 | int dasd_busid_known(const char *); |
| 691 | 694 | |
| @@ -42,16 +42,22 @@ dasd_ioctl_api_version(void __user *argp) · 41 unmodified lines | ||
| 42 | 42 | static int |
| 43 | 43 | dasd_ioctl_enable(struct block_device *bdev) |
| 44 | 44 | { |
| 45 | − struct dasd_block *block = bdev->bd_disk->private_data; | |
| 45 | + struct dasd_device *base; | |
| 46 | 46 | |
| 47 | 47 | if (!capable(CAP_SYS_ADMIN)) |
| 48 | 48 | return -EACCES; |
| 49 | 49 | |
| 50 | − dasd_enable_device(block->base); | |
| 50 | + base = dasd_device_from_gendisk(bdev->bd_disk); | |
| 51 | + if (!base) | |
| 52 | + return -ENODEV; | |
| 53 | + | |
| 54 | + dasd_enable_device(base); | |
| 51 | 55 | /* Formatting the dasd device can change the capacity. */ |
| 52 | 56 | mutex_lock(&bdev->bd_mutex); |
| 53 | − i_size_write(bdev->bd_inode, (loff_t)get_capacity(block->gdp) << 9); | |
| 57 | + i_size_write(bdev->bd_inode, | |
| 58 | + (loff_t)get_capacity(base->block->gdp) << 9); | |
| 54 | 59 | mutex_unlock(&bdev->bd_mutex); |
| 60 | + dasd_put_device(base); | |
| 55 | 61 | return 0; |
| 56 | 62 | } |
| 57 | 63 | |
| @@ -62,11 +68,14 @@ dasd_ioctl_enable(struct block_device *bdev) · 4 unmodified lines | ||
| 62 | 68 | static int |
| 63 | 69 | dasd_ioctl_disable(struct block_device *bdev) |
| 64 | 70 | { |
| 65 | − struct dasd_block *block = bdev->bd_disk->private_data; | |
| 71 | + struct dasd_device *base; | |
| 66 | 72 | |
| 67 | 73 | if (!capable(CAP_SYS_ADMIN)) |
| 68 | 74 | return -EACCES; |
| 69 | 75 | |
| 76 | + base = dasd_device_from_gendisk(bdev->bd_disk); | |
| 77 | + if (!base) | |
| 78 | + return -ENODEV; | |
| 70 | 79 | /* |
| 71 | 80 | * Man this is sick. We don't do a real disable but only downgrade |
| 72 | 81 | * the device to DASD_STATE_BASIC. The reason is that dasdfmt uses |
| @@ -75,7 +84,7 @@ dasd_ioctl_disable(struct block_device *bdev) · 2 unmodified lines | ||
| 75 | 84 | * using the BIODASDFMT ioctl. Therefore the correct state for the |
| 76 | 85 | * device is DASD_STATE_BASIC that allows to do basic i/o. |
| 77 | 86 | */ |
| 78 | − dasd_set_target_state(block->base, DASD_STATE_BASIC); | |
| 87 | + dasd_set_target_state(base, DASD_STATE_BASIC); | |
| 79 | 88 | /* |
| 80 | 89 | * Set i_size to zero, since read, write, etc. check against this |
| 81 | 90 | * value. |
| @@ -83,6 +92,7 @@ dasd_ioctl_disable(struct block_device *bdev) · 1 unmodified line | ||
| 83 | 92 | mutex_lock(&bdev->bd_mutex); |
| 84 | 93 | i_size_write(bdev->bd_inode, 0); |
| 85 | 94 | mutex_unlock(&bdev->bd_mutex); |
| 95 | + dasd_put_device(base); | |
| 86 | 96 | return 0; |
| 87 | 97 | } |
| 88 | 98 | |
| @@ -191,26 +201,36 @@ static int dasd_format(struct dasd_block *block, struct format_data_t *fdata) · 102 unmodified lines | ||
| 191 | 201 | static int |
| 192 | 202 | dasd_ioctl_format(struct block_device *bdev, void __user *argp) |
| 193 | 203 | { |
| 194 | − struct dasd_block *block = bdev->bd_disk->private_data; | |
| 204 | + struct dasd_device *base; | |
| 195 | 205 | struct format_data_t fdata; |
| 206 | + int rc; | |
| 196 | 207 | |
| 197 | 208 | if (!capable(CAP_SYS_ADMIN)) |
| 198 | 209 | return -EACCES; |
| 199 | 210 | if (!argp) |
| 200 | 211 | return -EINVAL; |
| 201 | − | |
| 202 | − if (block->base->features & DASD_FEATURE_READONLY || | |
| 203 | − test_bit(DASD_FLAG_DEVICE_RO, &block->base->flags)) | |
| 212 | + base = dasd_device_from_gendisk(bdev->bd_disk); | |
| 213 | + if (!base) | |
| 214 | + return -ENODEV; | |
| 215 | + if (base->features & DASD_FEATURE_READONLY || | |
| 216 | + test_bit(DASD_FLAG_DEVICE_RO, &base->flags)) { | |
| 217 | + dasd_put_device(base); | |
| 204 | 218 | return -EROFS; |
| 205 | − if (copy_from_user(&fdata, argp, sizeof(struct format_data_t))) | |
| 219 | + } | |
| 220 | + if (copy_from_user(&fdata, argp, sizeof(struct format_data_t))) { | |
| 221 | + dasd_put_device(base); | |
| 206 | 222 | return -EFAULT; |
| 223 | + } | |
| 207 | 224 | if (bdev != bdev->bd_contains) { |
| 208 | 225 | pr_warning("%s: The specified DASD is a partition and cannot " |
| 209 | 226 | "be formatted\n", |
| 210 | − dev_name(&block->base->cdev->dev)); | |
| 227 | + dev_name(&base->cdev->dev)); | |
| 228 | + dasd_put_device(base); | |
| 211 | 229 | return -EINVAL; |
| 212 | 230 | } |
| 213 | − return dasd_format(block, &fdata); | |
| 231 | + rc = dasd_format(base->block, &fdata); | |
| 232 | + dasd_put_device(base); | |
| 233 | + return rc; | |
| 214 | 234 | } |
| 215 | 235 | |
| 216 | 236 | #ifdef CONFIG_DASD_PROFILE |
| @@ -340,8 +360,8 @@ static int dasd_ioctl_information(struct dasd_block *block, · 123 unmodified lines | ||
| 340 | 360 | static int |
| 341 | 361 | dasd_ioctl_set_ro(struct block_device *bdev, void __user *argp) |
| 342 | 362 | { |
| 343 | − struct dasd_block *block = bdev->bd_disk->private_data; | |
| 344 | − int intval; | |
| 363 | + struct dasd_device *base; | |
| 364 | + int intval, rc; | |
| 345 | 365 | |
| 346 | 366 | if (!capable(CAP_SYS_ADMIN)) |
| 347 | 367 | return -EACCES; |
| @@ -350,10 +370,17 @@ dasd_ioctl_set_ro(struct block_device *bdev, void __user *argp) · 2 unmodified lines | ||
| 350 | 370 | return -EINVAL; |
| 351 | 371 | if (get_user(intval, (int __user *)argp)) |
| 352 | 372 | return -EFAULT; |
| 353 | − if (!intval && test_bit(DASD_FLAG_DEVICE_RO, &block->base->flags)) | |
| 373 | + base = dasd_device_from_gendisk(bdev->bd_disk); | |
| 374 | + if (!base) | |
| 375 | + return -ENODEV; | |
| 376 | + if (!intval && test_bit(DASD_FLAG_DEVICE_RO, &base->flags)) { | |
| 377 | + dasd_put_device(base); | |
| 354 | 378 | return -EROFS; |
| 379 | + } | |
| 355 | 380 | set_disk_ro(bdev->bd_disk, intval); |
| 356 | − return dasd_set_feature(block->base->cdev, DASD_FEATURE_READONLY, intval); | |
| 381 | + rc = dasd_set_feature(base->cdev, DASD_FEATURE_READONLY, intval); | |
| 382 | + dasd_put_device(base); | |
| 383 | + return rc; | |
| 357 | 384 | } |
| 358 | 385 | |
| 359 | 386 | static int dasd_ioctl_readall_cmb(struct dasd_block *block, unsigned int cmd, |
| @@ -372,59 +399,78 @@ static int dasd_ioctl_readall_cmb(struct dasd_block *block, unsigned int cmd, · 12 unmodified lines | ||
| 372 | 399 | int dasd_ioctl(struct block_device *bdev, fmode_t mode, |
| 373 | 400 | unsigned int cmd, unsigned long arg) |
| 374 | 401 | { |
| 375 | − struct dasd_block *block = bdev->bd_disk->private_data; | |
| 402 | + struct dasd_block *block; | |
| 403 | + struct dasd_device *base; | |
| 376 | 404 | void __user *argp; |
| 405 | + int rc; | |
| 377 | 406 | |
| 378 | 407 | if (is_compat_task()) |
| 379 | 408 | argp = compat_ptr(arg); |
| 380 | 409 | else |
| 381 | 410 | argp = (void __user *)arg; |
| 382 | 411 | |
| 383 | − if (!block) | |
| 384 | − return -ENODEV; | |
| 385 | − | |
| 386 | 412 | if ((_IOC_DIR(cmd) != _IOC_NONE) && !arg) { |
| 387 | 413 | PRINT_DEBUG("empty data ptr"); |
| 388 | 414 | return -EINVAL; |
| 389 | 415 | } |
| 390 | 416 | |
| 417 | + base = dasd_device_from_gendisk(bdev->bd_disk); | |
| 418 | + if (!base) | |
| 419 | + return -ENODEV; | |
| 420 | + block = base->block; | |
| 421 | + rc = 0; | |
| 391 | 422 | switch (cmd) { |
| 392 | 423 | case BIODASDDISABLE: |
| 393 | − return dasd_ioctl_disable(bdev); | |
| 424 | + rc = dasd_ioctl_disable(bdev); | |
| 425 | + break; | |
| 394 | 426 | case BIODASDENABLE: |
| 395 | − return dasd_ioctl_enable(bdev); | |
| 427 | + rc = dasd_ioctl_enable(bdev); | |
| 428 | + break; | |
| 396 | 429 | case BIODASDQUIESCE: |
| 397 | − return dasd_ioctl_quiesce(block); | |
| 430 | + rc = dasd_ioctl_quiesce(block); | |
| 431 | + break; | |
| 398 | 432 | case BIODASDRESUME: |
| 399 | − return dasd_ioctl_resume(block); | |
| 433 | + rc = dasd_ioctl_resume(block); | |
| 434 | + break; | |
| 400 | 435 | case BIODASDFMT: |
| 401 | − return dasd_ioctl_format(bdev, argp); | |
| 436 | + rc = dasd_ioctl_format(bdev, argp); | |
| 437 | + break; | |
| 402 | 438 | case BIODASDINFO: |
| 403 | − return dasd_ioctl_information(block, cmd, argp); | |
| 439 | + rc = dasd_ioctl_information(block, cmd, argp); | |
| 440 | + break; | |
| 404 | 441 | case BIODASDINFO2: |
| 405 | − return dasd_ioctl_information(block, cmd, argp); | |
| 442 | + rc = dasd_ioctl_information(block, cmd, argp); | |
| 443 | + break; | |
| 406 | 444 | case BIODASDPRRD: |
| 407 | − return dasd_ioctl_read_profile(block, argp); | |
| 445 | + rc = dasd_ioctl_read_profile(block, argp); | |
| 446 | + break; | |
| 408 | 447 | case BIODASDPRRST: |
| 409 | − return dasd_ioctl_reset_profile(block); | |
| 448 | + rc = dasd_ioctl_reset_profile(block); | |
| 449 | + break; | |
| 410 | 450 | case BLKROSET: |
| 411 | − return dasd_ioctl_set_ro(bdev, argp); | |
| 451 | + rc = dasd_ioctl_set_ro(bdev, argp); | |
| 452 | + break; | |
| 412 | 453 | case DASDAPIVER: |
| 413 | − return dasd_ioctl_api_version(argp); | |
| 454 | + rc = dasd_ioctl_api_version(argp); | |
| 455 | + break; | |
| 414 | 456 | case BIODASDCMFENABLE: |
| 415 | − return enable_cmf(block->base->cdev); | |
| 457 | + rc = enable_cmf(base->cdev); | |
| 458 | + break; | |
| 416 | 459 | case BIODASDCMFDISABLE: |
| 417 | − return disable_cmf(block->base->cdev); | |
| 460 | + rc = disable_cmf(base->cdev); | |
| 461 | + break; | |
| 418 | 462 | case BIODASDREADALLCMB: |
| 419 | − return dasd_ioctl_readall_cmb(block, cmd, argp); | |
| 463 | + rc = dasd_ioctl_readall_cmb(block, cmd, argp); | |
| 464 | + break; | |
| 420 | 465 | default: |
| 421 | 466 | /* if the discipline has an ioctl method try it. */ |
| 422 | − if (block->base->discipline->ioctl) { | |
| 423 | − int rval = block->base->discipline->ioctl(block, cmd, argp); | |
| 424 | − if (rval != -ENOIOCTLCMD) | |
| 425 | − return rval; | |
| 426 | − } | |
| 427 | − | |
| 428 | − return -EINVAL; | |
| 467 | + if (base->discipline->ioctl) { | |
| 468 | + rc = base->discipline->ioctl(block, cmd, argp); | |
| 469 | + if (rc == -ENOIOCTLCMD) | |
| 470 | + rc = -EINVAL; | |
| 471 | + } else | |
| 472 | + rc = -EINVAL; | |
| 429 | 473 | } |
| 474 | + dasd_put_device(base); | |
| 475 | + return rc; | |
| 430 | 476 | } |
| @@ -518,6 +518,8 @@ static void __init insert_increment(u16 rn, int standby, int assigned) · 517 unmodified lines | ||
| 518 | 518 | return; |
| 519 | 519 | new_incr->rn = rn; |
| 520 | 520 | new_incr->standby = standby; |
| 521 | + if (!standby) | |
| 522 | + new_incr->usecount = 1; | |
| 521 | 523 | last_rn = 0; |
| 522 | 524 | prev = &sclp_mem_list; |
| 523 | 525 | list_for_each_entry(incr, &sclp_mem_list, list) { |
| @@ -236,7 +236,6 @@ tapeblock_setup_device(struct tape_device * device) · 235 unmodified lines | ||
| 236 | 236 | disk->major = tapeblock_major; |
| 237 | 237 | disk->first_minor = device->first_minor; |
| 238 | 238 | disk->fops = &tapeblock_fops; |
| 239 | − disk->events = DISK_EVENT_MEDIA_CHANGE; | |
| 240 | 239 | disk->private_data = tape_get_device(device); |
| 241 | 240 | disk->queue = blkdat->request_queue; |
| 242 | 241 | set_capacity(disk, 0); |
| @@ -407,8 +407,11 @@ static inline void account_sbals(struct qdio_q *q, int count) · 406 unmodified lines | ||
| 407 | 407 | q->q_stats.nr_sbals[pos]++; |
| 408 | 408 | } |
| 409 | 409 | |
| 410 | −static void announce_buffer_error(struct qdio_q *q, int count) | |
| 410 | +static void process_buffer_error(struct qdio_q *q, int count) | |
| 411 | 411 | { |
| 412 | + unsigned char state = (q->is_input_q) ? SLSB_P_INPUT_NOT_INIT : | |
| 413 | + SLSB_P_OUTPUT_NOT_INIT; | |
| 414 | + | |
| 412 | 415 | q->qdio_error |= QDIO_ERROR_SLSB_STATE; |
| 413 | 416 | |
| 414 | 417 | /* special handling for no target buffer empty */ |
| @@ -426,6 +429,12 @@ static void announce_buffer_error(struct qdio_q *q, int count) · 11 unmodified lines | ||
| 426 | 429 | DBF_ERROR("F14:%2x F15:%2x", |
| 427 | 430 | q->sbal[q->first_to_check]->element[14].flags & 0xff, |
| 428 | 431 | q->sbal[q->first_to_check]->element[15].flags & 0xff); |
| 432 | + | |
| 433 | + /* | |
| 434 | + * Interrupts may be avoided as long as the error is present | |
| 435 | + * so change the buffer state immediately to avoid starvation. | |
| 436 | + */ | |
| 437 | + set_buf_states(q, q->first_to_check, state, count); | |
| 429 | 438 | } |
| 430 | 439 | |
| 431 | 440 | static inline void inbound_primed(struct qdio_q *q, int count) |
| @@ -506,8 +515,7 @@ static int get_inbound_buffer_frontier(struct qdio_q *q) · 74 unmodified lines | ||
| 506 | 515 | account_sbals(q, count); |
| 507 | 516 | break; |
| 508 | 517 | case SLSB_P_INPUT_ERROR: |
| 509 | − announce_buffer_error(q, count); | |
| 510 | − /* process the buffer, the upper layer will take care of it */ | |
| 518 | + process_buffer_error(q, count); | |
| 511 | 519 | q->first_to_check = add_buf(q->first_to_check, count); |
| 512 | 520 | atomic_sub(count, &q->nr_buf_used); |
| 513 | 521 | if (q->irq_ptr->perf_stat_enabled) |
| @@ -677,8 +685,7 @@ static int get_outbound_buffer_frontier(struct qdio_q *q) · 163 unmodified lines | ||
| 677 | 685 | account_sbals(q, count); |
| 678 | 686 | break; |
| 679 | 687 | case SLSB_P_OUTPUT_ERROR: |
| 680 | − announce_buffer_error(q, count); | |
| 681 | − /* process the buffer, the upper layer will take care of it */ | |
| 688 | + process_buffer_error(q, count); | |
| 682 | 689 | q->first_to_check = add_buf(q->first_to_check, count); |
| 683 | 690 | atomic_sub(count, &q->nr_buf_used); |
| 684 | 691 | if (q->irq_ptr->perf_stat_enabled) |
| @@ -381,10 +381,10 @@ static void kvm_extint_handler(unsigned int ext_int_code, · 380 unmodified lines | ||
| 381 | 381 | u16 subcode; |
| 382 | 382 | u32 param; |
| 383 | 383 | |
| 384 | − kstat_cpu(smp_processor_id()).irqs[EXTINT_VRT]++; | |
| 385 | 384 | subcode = ext_int_code >> 16; |
| 386 | 385 | if ((subcode & 0xff00) != VIRTIO_SUBCODE_64) |
| 387 | 386 | return; |
| 387 | + kstat_cpu(smp_processor_id()).irqs[EXTINT_VRT]++; | |
| 388 | 388 | |
| 389 | 389 | /* The LSB might be overloaded, we have to mask it */ |
| 390 | 390 | vq = (struct virtqueue *)(param64 & ~1UL); |
| @@ -394,12 +394,14 @@ int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data) · 393 unmodified lines | ||
| 394 | 394 | unsigned long flags; |
| 395 | 395 | struct scsi_device *sdev; |
| 396 | 396 | struct scsi_device_handler *scsi_dh = NULL; |
| 397 | + struct device *dev = NULL; | |
| 397 | 398 | |
| 398 | 399 | spin_lock_irqsave(q->queue_lock, flags); |
| 399 | 400 | sdev = q->queuedata; |
| 400 | 401 | if (sdev && sdev->scsi_dh_data) |
| 401 | 402 | scsi_dh = sdev->scsi_dh_data->scsi_dh; |
| 402 | − if (!scsi_dh || !get_device(&sdev->sdev_gendev) || | |
| 403 | + dev = get_device(&sdev->sdev_gendev); | |
| 404 | + if (!scsi_dh || !dev || | |
| 403 | 405 | sdev->sdev_state == SDEV_CANCEL || |
| 404 | 406 | sdev->sdev_state == SDEV_DEL) |
| 405 | 407 | err = SCSI_DH_NOSYS; |
| @@ -410,12 +412,13 @@ int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data) · 4 unmodified lines | ||
| 410 | 412 | if (err) { |
| 411 | 413 | if (fn) |
| 412 | 414 | fn(data, err); |
| 413 | − return err; | |
| 415 | + goto out; | |
| 414 | 416 | } |
| 415 | 417 | |
| 416 | 418 | if (scsi_dh->activate) |
| 417 | 419 | err = scsi_dh->activate(sdev, fn, data); |
| 418 | − put_device(&sdev->sdev_gendev); | |
| 420 | +out: | |
| 421 | + put_device(dev); | |
| 419 | 422 | return err; |
| 420 | 423 | } |
| 421 | 424 | EXPORT_SYMBOL_GPL(scsi_dh_activate); |
| @@ -688,6 +688,13 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, · 687 unmodified lines | ||
| 688 | 688 | goto out; |
| 689 | 689 | } |
| 690 | 690 | |
| 691 | + /* Check for overflow and wraparound */ | |
| 692 | + if (karg.data_sge_offset * 4 > ioc->request_sz || | |
| 693 | + karg.data_sge_offset > (UINT_MAX / 4)) { | |
| 694 | + ret = -EINVAL; | |
| 695 | + goto out; | |
| 696 | + } | |
| 697 | + | |
| 691 | 698 | /* copy in request message frame from user */ |
| 692 | 699 | if (copy_from_user(mpi_request, mf, karg.data_sge_offset*4)) { |
| 693 | 700 | printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, __LINE__, |
| @@ -1963,7 +1970,7 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state) · 1269 unmodified lines | ||
| 1963 | 1970 | Mpi2DiagBufferPostReply_t *mpi_reply; |
| 1964 | 1971 | int rc, i; |
| 1965 | 1972 | u8 buffer_type; |
| 1966 | − unsigned long timeleft; | |
| 1973 | + unsigned long timeleft, request_size, copy_size; | |
| 1967 | 1974 | u16 smid; |
| 1968 | 1975 | u16 ioc_status; |
| 1969 | 1976 | u8 issue_reset = 0; |
| @@ -1999,6 +2006,8 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state) · 29 unmodified lines | ||
| 1999 | 2006 | return -ENOMEM; |
| 2000 | 2007 | } |
| 2001 | 2008 | |
| 2009 | + request_size = ioc->diag_buffer_sz[buffer_type]; | |
| 2010 | + | |
| 2002 | 2011 | if ((karg.starting_offset % 4) || (karg.bytes_to_read % 4)) { |
| 2003 | 2012 | printk(MPT2SAS_ERR_FMT "%s: either the starting_offset " |
| 2004 | 2013 | "or bytes_to_read are not 4 byte aligned\n", ioc->name, |
| @@ -2006,13 +2015,23 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state) · 1 unmodified line | ||
| 2006 | 2015 | return -EINVAL; |
| 2007 | 2016 | } |
| 2008 | 2017 | |
| 2018 | + if (karg.starting_offset > request_size) | |
| 2019 | + return -EINVAL; | |
| 2020 | + | |
| 2009 | 2021 | diag_data = (void *)(request_data + karg.starting_offset); |
| 2010 | 2022 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: diag_buffer(%p), " |
| 2011 | 2023 | "offset(%d), sz(%d)\n", ioc->name, __func__, |
| 2012 | 2024 | diag_data, karg.starting_offset, karg.bytes_to_read)); |
| 2013 | 2025 | |
| 2026 | + /* Truncate data on requests that are too large */ | |
| 2027 | + if ((diag_data + karg.bytes_to_read < diag_data) || | |
| 2028 | + (diag_data + karg.bytes_to_read > request_data + request_size)) | |
| 2029 | + copy_size = request_size - karg.starting_offset; | |
| 2030 | + else | |
| 2031 | + copy_size = karg.bytes_to_read; | |
| 2032 | + | |
| 2014 | 2033 | if (copy_to_user((void __user *)uarg->diagnostic_data, |
| 2015 | − diag_data, karg.bytes_to_read)) { | |
| 2034 | + diag_data, copy_size)) { | |
| 2016 | 2035 | printk(MPT2SAS_ERR_FMT "%s: Unable to write " |
| 2017 | 2036 | "mpt_diag_read_buffer_t data @ %p\n", ioc->name, |
| 2018 | 2037 | __func__, diag_data); |
| @@ -3814,6 +3814,9 @@ static long pmcraid_ioctl_passthrough( · 3813 unmodified lines | ||
| 3814 | 3814 | rc = -EFAULT; |
| 3815 | 3815 | goto out_free_buffer; |
| 3816 | 3816 | } |
| 3817 | + } else if (request_size < 0) { | |
| 3818 | + rc = -EINVAL; | |
| 3819 | + goto out_free_buffer; | |
| 3817 | 3820 | } |
| 3818 | 3821 | |
| 3819 | 3822 | /* check if we have any additional command parameters */ |
| @@ -1292,8 +1292,10 @@ static struct scsi_host_template qpti_template = { · 1291 unmodified lines | ||
| 1292 | 1292 | .use_clustering = ENABLE_CLUSTERING, |
| 1293 | 1293 | }; |
| 1294 | 1294 | |
| 1295 | +static const struct of_device_id qpti_match[]; | |
| 1295 | 1296 | static int __devinit qpti_sbus_probe(struct platform_device *op) |
| 1296 | 1297 | { |
| 1298 | + const struct of_device_id *match; | |
| 1297 | 1299 | struct scsi_host_template *tpnt; |
| 1298 | 1300 | struct device_node *dp = op->dev.of_node; |
| 1299 | 1301 | struct Scsi_Host *host; |
| @@ -1301,9 +1303,10 @@ static int __devinit qpti_sbus_probe(struct platform_device *op) · 1 unmodified line | ||
| 1301 | 1303 | static int nqptis; |
| 1302 | 1304 | const char *fcode; |
| 1303 | 1305 | |
| 1304 | − if (!op->dev.of_match) | |
| 1306 | + match = of_match_device(qpti_match, &op->dev); | |
| 1307 | + if (!match) | |
| 1305 | 1308 | return -EINVAL; |
| 1306 | − tpnt = op->dev.of_match->data; | |
| 1309 | + tpnt = match->data; | |
| 1307 | 1310 | |
| 1308 | 1311 | /* Sometimes Antares cards come up not completely |
| 1309 | 1312 | * setup, and we get a report of a zero IRQ. |
| @@ -74,8 +74,6 @@ struct kmem_cache *scsi_sdb_cache; · 73 unmodified lines | ||
| 74 | 74 | */ |
| 75 | 75 | #define SCSI_QUEUE_DELAY 3 |
| 76 | 76 | |
| 77 | −static void scsi_run_queue(struct request_queue *q); | |
| 78 | − | |
| 79 | 77 | /* |
| 80 | 78 | * Function: scsi_unprep_request() |
| 81 | 79 | * |
| @@ -161,7 +159,7 @@ static int __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, int unbusy) · 79 unmodified lines | ||
| 161 | 159 | blk_requeue_request(q, cmd->request); |
| 162 | 160 | spin_unlock_irqrestore(q->queue_lock, flags); |
| 163 | 161 | |
| 164 | − scsi_run_queue(q); | |
| 162 | + kblockd_schedule_work(q, &device->requeue_work); | |
| 165 | 163 | |
| 166 | 164 | return 0; |
| 167 | 165 | } |
| @@ -400,10 +398,15 @@ static inline int scsi_host_is_busy(struct Scsi_Host *shost) · 232 unmodified lines | ||
| 400 | 398 | static void scsi_run_queue(struct request_queue *q) |
| 401 | 399 | { |
| 402 | 400 | struct scsi_device *sdev = q->queuedata; |
| 403 | − struct Scsi_Host *shost = sdev->host; | |
| 401 | + struct Scsi_Host *shost; | |
| 404 | 402 | LIST_HEAD(starved_list); |
| 405 | 403 | unsigned long flags; |
| 406 | 404 | |
| 405 | + /* if the device is dead, sdev will be NULL, so no queue to run */ | |
| 406 | + if (!sdev) | |
| 407 | + return; | |
| 408 | + | |
| 409 | + shost = sdev->host; | |
| 407 | 410 | if (scsi_target(sdev)->single_lun) |
| 408 | 411 | scsi_single_lun_run(sdev); |
| 409 | 412 | |
| @@ -411,8 +414,6 @@ static void scsi_run_queue(struct request_queue *q) · 1 unmodified line | ||
| 411 | 414 | list_splice_init(&shost->starved_list, &starved_list); |
| 412 | 415 | |
| 413 | 416 | while (!list_empty(&starved_list)) { |
| 414 | − int flagset; | |
| 415 | − | |
| 416 | 417 | /* |
| 417 | 418 | * As long as shost is accepting commands and we have |
| 418 | 419 | * starved queues, call blk_run_queue. scsi_request_fn |
| @@ -436,18 +437,9 @@ static void scsi_run_queue(struct request_queue *q) · 17 unmodified lines | ||
| 436 | 437 | } |
| 437 | 438 | |
| 438 | 439 | spin_unlock(shost->host_lock); |
| 439 | − | |
| 440 | 440 | spin_lock(sdev->request_queue->queue_lock); |
| 441 | − flagset = test_bit(QUEUE_FLAG_REENTER, &q->queue_flags) && | |
| 442 | − !test_bit(QUEUE_FLAG_REENTER, | |
| 443 | − &sdev->request_queue->queue_flags); | |
| 444 | − if (flagset) | |
| 445 | − queue_flag_set(QUEUE_FLAG_REENTER, sdev->request_queue); | |
| 446 | 441 | __blk_run_queue(sdev->request_queue); |
| 447 | − if (flagset) | |
| 448 | − queue_flag_clear(QUEUE_FLAG_REENTER, sdev->request_queue); | |
| 449 | 442 | spin_unlock(sdev->request_queue->queue_lock); |
| 450 | − | |
| 451 | 443 | spin_lock(shost->host_lock); |
| 452 | 444 | } |
| 453 | 445 | /* put any unprocessed entries back */ |
| @@ -457,6 +449,16 @@ static void scsi_run_queue(struct request_queue *q) · 3 unmodified lines | ||
| 457 | 449 | blk_run_queue(q); |
| 458 | 450 | } |
| 459 | 451 | |
| 452 | +void scsi_requeue_run_queue(struct work_struct *work) | |
| 453 | +{ | |
| 454 | + struct scsi_device *sdev; | |
| 455 | + struct request_queue *q; | |
| 456 | + | |
| 457 | + sdev = container_of(work, struct scsi_device, requeue_work); | |
| 458 | + q = sdev->request_queue; | |
| 459 | + scsi_run_queue(q); | |
| 460 | +} | |
| 461 | + | |
| 460 | 462 | /* |
| 461 | 463 | * Function: scsi_requeue_command() |
| 462 | 464 | * |
| @@ -242,6 +242,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, · 241 unmodified lines | ||
| 242 | 242 | int display_failure_msg = 1, ret; |
| 243 | 243 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); |
| 244 | 244 | extern void scsi_evt_thread(struct work_struct *work); |
| 245 | + extern void scsi_requeue_run_queue(struct work_struct *work); | |
| 245 | 246 | |
| 246 | 247 | sdev = kzalloc(sizeof(*sdev) + shost->transportt->device_size, |
| 247 | 248 | GFP_ATOMIC); |
| @@ -264,6 +265,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, · 16 unmodified lines | ||
| 264 | 265 | INIT_LIST_HEAD(&sdev->event_list); |
| 265 | 266 | spin_lock_init(&sdev->list_lock); |
| 266 | 267 | INIT_WORK(&sdev->event_work, scsi_evt_thread); |
| 268 | + INIT_WORK(&sdev->requeue_work, scsi_requeue_run_queue); | |
| 267 | 269 | |
| 268 | 270 | sdev->sdev_gendev.parent = get_device(&starget->dev); |
| 269 | 271 | sdev->sdev_target = starget; |
| @@ -322,14 +322,8 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work) · 321 unmodified lines | ||
| 322 | 322 | kfree(evt); |
| 323 | 323 | } |
| 324 | 324 | |
| 325 | − if (sdev->request_queue) { | |
| 326 | − sdev->request_queue->queuedata = NULL; | |
| 327 | − /* user context needed to free queue */ | |
| 328 | − scsi_free_queue(sdev->request_queue); | |
| 329 | − /* temporary expedient, try to catch use of queue lock | |
| 330 | − * after free of sdev */ | |
| 331 | − sdev->request_queue = NULL; | |
| 332 | − } | |
| 325 | + /* NULL queue means the device can't be used */ | |
| 326 | + sdev->request_queue = NULL; | |
| 333 | 327 | |
| 334 | 328 | scsi_target_reap(scsi_target(sdev)); |
| 335 | 329 | |
| @@ -937,6 +931,12 @@ void __scsi_remove_device(struct scsi_device *sdev) · 601 unmodified lines | ||
| 937 | 931 | if (sdev->host->hostt->slave_destroy) |
| 938 | 932 | sdev->host->hostt->slave_destroy(sdev); |
| 939 | 933 | transport_destroy_device(dev); |
| 934 | + | |
| 935 | + /* cause the request function to reject all I/O requests */ | |
| 936 | + sdev->request_queue->queuedata = NULL; | |
| 937 | + | |
| 938 | + /* Freeing the queue signals to block that we're done */ | |
| 939 | + scsi_free_queue(sdev->request_queue); | |
| 940 | 940 | put_device(dev); |
| 941 | 941 | } |
| 942 | 942 | |
| @@ -3816,28 +3816,17 @@ fail_host_msg: · 3815 unmodified lines | ||
| 3816 | 3816 | static void |
| 3817 | 3817 | fc_bsg_goose_queue(struct fc_rport *rport) |
| 3818 | 3818 | { |
| 3819 | − int flagset; | |
| 3820 | − unsigned long flags; | |
| 3821 | − | |
| 3822 | 3819 | if (!rport->rqst_q) |
| 3823 | 3820 | return; |
| 3824 | 3821 | |
| 3822 | + /* | |
| 3823 | + * This get/put dance makes no sense | |
| 3824 | + */ | |
| 3825 | 3825 | get_device(&rport->dev); |
| 3826 | − | |
| 3827 | − spin_lock_irqsave(rport->rqst_q->queue_lock, flags); | |
| 3828 | − flagset = test_bit(QUEUE_FLAG_REENTER, &rport->rqst_q->queue_flags) && | |
| 3829 | − !test_bit(QUEUE_FLAG_REENTER, &rport->rqst_q->queue_flags); | |
| 3830 | − if (flagset) | |
| 3831 | − queue_flag_set(QUEUE_FLAG_REENTER, rport->rqst_q); | |
| 3832 | − __blk_run_queue(rport->rqst_q); | |
| 3833 | − if (flagset) | |
| 3834 | − queue_flag_clear(QUEUE_FLAG_REENTER, rport->rqst_q); | |
| 3835 | − spin_unlock_irqrestore(rport->rqst_q->queue_lock, flags); | |
| 3836 | − | |
| 3826 | + blk_run_queue_async(rport->rqst_q); | |
| 3837 | 3827 | put_device(&rport->dev); |
| 3838 | 3828 | } |
| 3839 | 3829 | |
| 3840 | − | |
| 3841 | 3830 | /** |
| 3842 | 3831 | * fc_bsg_rport_dispatch - process rport bsg requests and dispatch to LLDD |
| 3843 | 3832 | * @q: rport request queue |
| @@ -2288,7 +2288,3 @@ err_dev: · 2287 unmodified lines | ||
| 2288 | 2288 | free_netdev(dev); |
| 2289 | 2289 | return NULL; |
| 2290 | 2290 | } |
| 2291 | − | |
| 2292 | −EXPORT_SYMBOL(init_ft1000_card); | |
| 2293 | −EXPORT_SYMBOL(stop_ft1000_card); | |
| 2294 | −EXPORT_SYMBOL(flarion_ft1000_cnt); | |
| @@ -214,6 +214,3 @@ void ft1000CleanupProc(struct net_device *dev) · 213 unmodified lines | ||
| 214 | 214 | remove_proc_entry(FT1000_PROC, init_net.proc_net); |
| 215 | 215 | unregister_netdevice_notifier(&ft1000_netdev_notifier); |
| 216 | 216 | } |
| 217 | − | |
| 218 | −EXPORT_SYMBOL(ft1000InitProc); | |
| 219 | −EXPORT_SYMBOL(ft1000CleanupProc); | |
| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | config DRM_PSB |
| 2 | 2 | tristate "Intel GMA500 KMS Framebuffer" |
| 3 | − depends on DRM && PCI | |
| 3 | + depends on DRM && PCI && X86 | |
| 4 | 4 | select FB_CFB_COPYAREA |
| 5 | 5 | select FB_CFB_FILLRECT |
| 6 | 6 | select FB_CFB_IMAGEBLIT |
| @@ -28,6 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| 29 | 29 | |
| 30 | 30 | #include <linux/pci.h> |
| 31 | +#include <linux/delay.h> | |
| 31 | 32 | #include <linux/file.h> |
| 32 | 33 | #include <asm/mrst.h> |
| 33 | 34 | #include <sound/pcm.h> |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| 30 | 30 | |
| 31 | 31 | #include <linux/pci.h> |
| 32 | +#include <linux/delay.h> | |
| 32 | 33 | #include <linux/file.h> |
| 33 | 34 | #include "intel_sst.h" |
| 34 | 35 | #include "intelmid_snd_control.h" |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | ||
| 12 | 12 | */ |
| 13 | 13 | #include <linux/cs5535.h> |
| 14 | 14 | #include <linux/gpio.h> |
| 15 | +#include <linux/delay.h> | |
| 15 | 16 | #include <asm/olpc.h> |
| 16 | 17 | |
| 17 | 18 | #include "olpc_dcon.h" |
| @@ -444,7 +444,7 @@ int RTMPCheckRxError(struct rt_rtmp_adapter *pAd, · 443 unmodified lines | ||
| 444 | 444 | return (NDIS_STATUS_FAILURE); |
| 445 | 445 | } |
| 446 | 446 | } |
| 447 | − /* Drop not U2M frames, can't's drop here because we will drop beacon in this case */ | |
| 447 | + /* Drop not U2M frames, can't drop here because we will drop beacon in this case */ | |
| 448 | 448 | /* I am kind of doubting the U2M bit operation */ |
| 449 | 449 | /* if (pRxD->U2M == 0) */ |
| 450 | 450 | /* return(NDIS_STATUS_FAILURE); */ |
| @@ -860,7 +860,7 @@ int RTMPCheckRxError(struct rt_rtmp_adapter *pAd, · 859 unmodified lines | ||
| 860 | 860 | DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n")); |
| 861 | 861 | return NDIS_STATUS_FAILURE; |
| 862 | 862 | } |
| 863 | − /* Drop not U2M frames, can't's drop here because we will drop beacon in this case */ | |
| 863 | + /* Drop not U2M frames, can't drop here because we will drop beacon in this case */ | |
| 864 | 864 | /* I am kind of doubting the U2M bit operation */ |
| 865 | 865 | /* if (pRxD->U2M == 0) */ |
| 866 | 866 | /* return(NDIS_STATUS_FAILURE); */ |
| @@ -28,7 +28,7 @@ · 27 unmodified lines | ||
| 28 | 28 | |
| 29 | 29 | #define RTSX_STOR "rts_pstor: " |
| 30 | 30 | |
| 31 | −#if CONFIG_RTS_PSTOR_DEBUG | |
| 31 | +#ifdef CONFIG_RTS_PSTOR_DEBUG | |
| 32 | 32 | #define RTSX_DEBUGP(x...) printk(KERN_DEBUG RTSX_STOR x) |
| 33 | 33 | #define RTSX_DEBUGPN(x...) printk(KERN_DEBUG x) |
| 34 | 34 | #define RTSX_DEBUGPX(x...) printk(x) |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | #include <linux/blkdev.h> |
| 24 | 24 | #include <linux/kthread.h> |
| 25 | 25 | #include <linux/sched.h> |
| 26 | +#include <linux/vmalloc.h> | |
| 26 | 27 | |
| 27 | 28 | #include "rtsx.h" |
| 28 | 29 | #include "rtsx_transport.h" |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | #include <linux/kthread.h> |
| 25 | 25 | #include <linux/sched.h> |
| 26 | 26 | #include <linux/workqueue.h> |
| 27 | +#include <linux/vmalloc.h> | |
| 27 | 28 | |
| 28 | 29 | #include "rtsx.h" |
| 29 | 30 | #include "rtsx_transport.h" |
| @@ -1311,11 +1312,11 @@ void rtsx_polling_func(struct rtsx_chip *chip) · 1281 unmodified lines | ||
| 1311 | 1312 | |
| 1312 | 1313 | #ifdef SUPPORT_OCP |
| 1313 | 1314 | if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { |
| 1314 | − #if CONFIG_RTS_PSTOR_DEBUG | |
| 1315 | +#ifdef CONFIG_RTS_PSTOR_DEBUG | |
| 1315 | 1316 | if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER | MS_OC_NOW | MS_OC_EVER)) { |
| 1316 | 1317 | RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", chip->ocp_stat); |
| 1317 | 1318 | } |
| 1318 | − #endif | |
| 1319 | +#endif | |
| 1319 | 1320 | |
| 1320 | 1321 | if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { |
| 1321 | 1322 | if (chip->card_exist & SD_CARD) { |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | #include <linux/blkdev.h> |
| 24 | 24 | #include <linux/kthread.h> |
| 25 | 25 | #include <linux/sched.h> |
| 26 | +#include <linux/vmalloc.h> | |
| 26 | 27 | |
| 27 | 28 | #include "rtsx.h" |
| 28 | 29 | #include "rtsx_transport.h" |
| @@ -909,7 +909,7 @@ static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir) · 908 unmodified lines | ||
| 909 | 909 | RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET); |
| 910 | 910 | RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, 0); |
| 911 | 911 | } else { |
| 912 | −#if CONFIG_RTS_PSTOR_DEBUG | |
| 912 | +#ifdef CONFIG_RTS_PSTOR_DEBUG | |
| 913 | 913 | rtsx_read_register(chip, SD_VP_CTL, &val); |
| 914 | 914 | RTSX_DEBUGP("SD_VP_CTL: 0x%x\n", val); |
| 915 | 915 | rtsx_read_register(chip, SD_DCMPS_CTL, &val); |
| @@ -958,7 +958,7 @@ static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir) · 42 unmodified lines | ||
| 958 | 958 | return STATUS_SUCCESS; |
| 959 | 959 | |
| 960 | 960 | Fail: |
| 961 | −#if CONFIG_RTS_PSTOR_DEBUG | |
| 961 | +#ifdef CONFIG_RTS_PSTOR_DEBUG | |
| 962 | 962 | rtsx_read_register(chip, SD_VP_CTL, &val); |
| 963 | 963 | RTSX_DEBUGP("SD_VP_CTL: 0x%x\n", val); |
| 964 | 964 | rtsx_read_register(chip, SD_DCMPS_CTL, &val); |
| @@ -82,7 +82,7 @@ do { \ · 81 unmodified lines | ||
| 82 | 82 | #define TRACE_GOTO(chip, label) goto label |
| 83 | 83 | #endif |
| 84 | 84 | |
| 85 | −#if CONFIG_RTS_PSTOR_DEBUG | |
| 85 | +#ifdef CONFIG_RTS_PSTOR_DEBUG | |
| 86 | 86 | static inline void rtsx_dump(u8 *buf, int buf_len) |
| 87 | 87 | { |
| 88 | 88 | int i; |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | ||
| 23 | 23 | #include <linux/blkdev.h> |
| 24 | 24 | #include <linux/kthread.h> |
| 25 | 25 | #include <linux/sched.h> |
| 26 | +#include <linux/vmalloc.h> | |
| 26 | 27 | |
| 27 | 28 | #include "rtsx.h" |
| 28 | 29 | #include "rtsx_transport.h" |
| @@ -2,6 +2,7 @@ config SOLO6X10 · 1 unmodified line | ||
| 2 | 2 | tristate "Softlogic 6x10 MPEG codec cards" |
| 3 | 3 | depends on PCI && VIDEO_DEV && SND && I2C |
| 4 | 4 | select VIDEOBUF_DMA_SG |
| 5 | + select SND_PCM | |
| 5 | 6 | ---help--- |
| 6 | 7 | This driver supports the Softlogic based MPEG-4 and h.264 codec |
| 7 | 8 | codec cards. |
| @@ -653,7 +653,7 @@ static int SBD_setup_device(struct spectra_nand_dev *dev, int which) · 652 unmodified lines | ||
| 653 | 653 | } |
| 654 | 654 | dev->queue->queuedata = dev; |
| 655 | 655 | |
| 656 | − /* As Linux block layer does't support >4KB hardware sector, */ | |
| 656 | + /* As Linux block layer doesn't support >4KB hardware sector, */ | |
| 657 | 657 | /* Here we force report 512 byte hardware sector size to Kernel */ |
| 658 | 658 | blk_queue_logical_block_size(dev->queue, 512); |
| 659 | 659 | |
| @@ -718,7 +718,7 @@ static void dload_symbols(struct dload_state *dlthis) · 717 unmodified lines | ||
| 718 | 718 | * as a temporary for .dllview record construction. |
| 719 | 719 | * Allocate storage for the whole table. Add 1 to the section count |
| 720 | 720 | * in case a trampoline section is auto-generated as well as the |
| 721 | − * size of the trampoline section name so DLLView does't get lost. | |
| 721 | + * size of the trampoline section name so DLLView doesn't get lost. | |
| 722 | 722 | */ |
| 723 | 723 | |
| 724 | 724 | siz = sym_count * sizeof(struct local_symbol); |
| @@ -978,7 +978,7 @@ static void sx_change_speed(struct specialix_board *bp, · 977 unmodified lines | ||
| 978 | 978 | spin_lock_irqsave(&bp->lock, flags); |
| 979 | 979 | sx_out(bp, CD186x_CAR, port_No(port)); |
| 980 | 980 | |
| 981 | − /* The Specialix board does't implement the RTS lines. | |
| 981 | + /* The Specialix board doesn't implement the RTS lines. | |
| 982 | 982 | They are used to set the IRQ level. Don't touch them. */ |
| 983 | 983 | if (sx_crtscts(tty)) |
| 984 | 984 | port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS); |
| @@ -876,8 +876,10 @@ static void vhci_shutdown_connection(struct usbip_device *ud) · 875 unmodified lines | ||
| 876 | 876 | } |
| 877 | 877 | |
| 878 | 878 | /* kill threads related to this sdev, if v.c. exists */ |
| 879 | − kthread_stop(vdev->ud.tcp_rx); | |
| 880 | − kthread_stop(vdev->ud.tcp_tx); | |
| 879 | + if (vdev->ud.tcp_rx) | |
| 880 | + kthread_stop(vdev->ud.tcp_rx); | |
| 881 | + if (vdev->ud.tcp_tx) | |
| 882 | + kthread_stop(vdev->ud.tcp_tx); | |
| 881 | 883 | |
| 882 | 884 | usbip_uinfo("stop threads\n"); |
| 883 | 885 | |
| @@ -949,9 +951,6 @@ static void vhci_device_init(struct vhci_device *vdev) · 65 unmodified lines | ||
| 949 | 951 | { |
| 950 | 952 | memset(vdev, 0, sizeof(*vdev)); |
| 951 | 953 | |
| 952 | − vdev->ud.tcp_rx = kthread_create(vhci_rx_loop, &vdev->ud, "vhci_rx"); | |
| 953 | − vdev->ud.tcp_tx = kthread_create(vhci_tx_loop, &vdev->ud, "vhci_tx"); | |
| 954 | − | |
| 955 | 954 | vdev->ud.side = USBIP_VHCI; |
| 956 | 955 | vdev->ud.status = VDEV_ST_NULL; |
| 957 | 956 | /* vdev->ud.lock = SPIN_LOCK_UNLOCKED; */ |
| @@ -1139,7 +1138,7 @@ static int vhci_hcd_probe(struct platform_device *pdev) · 181 unmodified lines | ||
| 1139 | 1138 | usbip_uerr("create hcd failed\n"); |
| 1140 | 1139 | return -ENOMEM; |
| 1141 | 1140 | } |
| 1142 | − | |
| 1141 | + hcd->has_tt = 1; | |
| 1143 | 1142 | |
| 1144 | 1143 | /* this is private data for vhci_hcd */ |
| 1145 | 1144 | the_controller = hcd_to_vhci(hcd); |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | #include "vhci.h" |
| 22 | 22 | |
| 23 | 23 | #include <linux/in.h> |
| 24 | +#include <linux/kthread.h> | |
| 24 | 25 | |
| 25 | 26 | /* TODO: refine locking ?*/ |
| 26 | 27 | |
| @@ -220,13 +221,13 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, · 193 unmodified lines | ||
| 220 | 221 | vdev->ud.tcp_socket = socket; |
| 221 | 222 | vdev->ud.status = VDEV_ST_NOTASSIGNED; |
| 222 | 223 | |
| 223 | − wake_up_process(vdev->ud.tcp_rx); | |
| 224 | − wake_up_process(vdev->ud.tcp_tx); | |
| 225 | − | |
| 226 | 224 | spin_unlock(&vdev->ud.lock); |
| 227 | 225 | spin_unlock(&the_controller->lock); |
| 228 | 226 | /* end the lock */ |
| 229 | 227 | |
| 228 | + vdev->ud.tcp_rx = kthread_run(vhci_rx_loop, &vdev->ud, "vhci_rx"); | |
| 229 | + vdev->ud.tcp_tx = kthread_run(vhci_tx_loop, &vdev->ud, "vhci_tx"); | |
| 230 | + | |
| 230 | 231 | rh_port_connect(rhport, speed); |
| 231 | 232 | |
| 232 | 233 | return count; |
| @@ -273,7 +273,7 @@ exit: · 272 unmodified lines | ||
| 273 | 273 | } |
| 274 | 274 | |
| 275 | 275 | int prism2_set_default_key(struct wiphy *wiphy, struct net_device *dev, |
| 276 | − u8 key_index) | |
| 276 | + u8 key_index, bool unicast, bool multicast) | |
| 277 | 277 | { |
| 278 | 278 | wlandevice_t *wlandev = dev->ml_priv; |
| 279 | 279 | |
| @@ -1658,8 +1658,12 @@ static void gsm_queue(struct gsm_mux *gsm) · 1657 unmodified lines | ||
| 1658 | 1658 | |
| 1659 | 1659 | if ((gsm->control & ~PF) == UI) |
| 1660 | 1660 | gsm->fcs = gsm_fcs_add_block(gsm->fcs, gsm->buf, gsm->len); |
| 1661 | − /* generate final CRC with received FCS */ | |
| 1662 | − gsm->fcs = gsm_fcs_add(gsm->fcs, gsm->received_fcs); | |
| 1661 | + if (gsm->encoding == 0){ | |
| 1662 | + /* WARNING: gsm->received_fcs is used for gsm->encoding = 0 only. | |
| 1663 | + In this case it contain the last piece of data | |
| 1664 | + required to generate final CRC */ | |
| 1665 | + gsm->fcs = gsm_fcs_add(gsm->fcs, gsm->received_fcs); | |
| 1666 | + } | |
| 1663 | 1667 | if (gsm->fcs != GOOD_FCS) { |
| 1664 | 1668 | gsm->bad_fcs++; |
| 1665 | 1669 | if (debug & 4) |
| @@ -382,12 +382,13 @@ static void imx_start_tx(struct uart_port *port) · 381 unmodified lines | ||
| 382 | 382 | static irqreturn_t imx_rtsint(int irq, void *dev_id) |
| 383 | 383 | { |
| 384 | 384 | struct imx_port *sport = dev_id; |
| 385 | − unsigned int val = readl(sport->port.membase + USR1) & USR1_RTSS; | |
| 385 | + unsigned int val; | |
| 386 | 386 | unsigned long flags; |
| 387 | 387 | |
| 388 | 388 | spin_lock_irqsave(&sport->port.lock, flags); |
| 389 | 389 | |
| 390 | 390 | writel(USR1_RTSD, sport->port.membase + USR1); |
| 391 | + val = readl(sport->port.membase + USR1) & USR1_RTSS; | |
| 391 | 392 | uart_handle_cts_change(&sport->port, !!val); |
| 392 | 393 | wake_up_interruptible(&sport->port.state->port.delta_msr_wait); |
| 393 | 394 | |
| @@ -80,14 +80,17 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, · 79 unmodified lines | ||
| 80 | 80 | /* |
| 81 | 81 | * Try to register a serial port |
| 82 | 82 | */ |
| 83 | +static struct of_device_id of_platform_serial_table[]; | |
| 83 | 84 | static int __devinit of_platform_serial_probe(struct platform_device *ofdev) |
| 84 | 85 | { |
| 86 | + const struct of_device_id *match; | |
| 85 | 87 | struct of_serial_info *info; |
| 86 | 88 | struct uart_port port; |
| 87 | 89 | int port_type; |
| 88 | 90 | int ret; |
| 89 | 91 | |
| 90 | − if (!ofdev->dev.of_match) | |
| 92 | + match = of_match_device(of_platform_serial_table, &ofdev->dev); | |
| 93 | + if (!match) | |
| 91 | 94 | return -EINVAL; |
| 92 | 95 | |
| 93 | 96 | if (of_find_property(ofdev->dev.of_node, "used-by-rtas", NULL)) |
| @@ -97,7 +100,7 @@ static int __devinit of_platform_serial_probe(struct platform_device *ofdev) · 3 unmodified lines | ||
| 97 | 100 | if (info == NULL) |
| 98 | 101 | return -ENOMEM; |
| 99 | 102 | |
| 100 | − port_type = (unsigned long)ofdev->dev.of_match->data; | |
| 103 | + port_type = (unsigned long)match->data; | |
| 101 | 104 | ret = of_platform_serial_setup(ofdev, port_type, &port); |
| 102 | 105 | if (ret) |
| 103 | 106 | goto out; |
| @@ -2539,15 +2539,18 @@ static void qe_udc_release(struct device *dev) · 2538 unmodified lines | ||
| 2539 | 2539 | } |
| 2540 | 2540 | |
| 2541 | 2541 | /* Driver probe functions */ |
| 2542 | +static const struct of_device_id qe_udc_match[]; | |
| 2542 | 2543 | static int __devinit qe_udc_probe(struct platform_device *ofdev) |
| 2543 | 2544 | { |
| 2545 | + const struct of_device_id *match; | |
| 2544 | 2546 | struct device_node *np = ofdev->dev.of_node; |
| 2545 | 2547 | struct qe_ep *ep; |
| 2546 | 2548 | unsigned int ret = 0; |
| 2547 | 2549 | unsigned int i; |
| 2548 | 2550 | const void *prop; |
| 2549 | 2551 | |
| 2550 | − if (!ofdev->dev.of_match) | |
| 2552 | + match = of_match_device(qe_udc_match, &ofdev->dev); | |
| 2553 | + if (!match) | |
| 2551 | 2554 | return -EINVAL; |
| 2552 | 2555 | |
| 2553 | 2556 | prop = of_get_property(np, "mode", NULL); |
| @@ -2561,7 +2564,7 @@ static int __devinit qe_udc_probe(struct platform_device *ofdev) · 7 unmodified lines | ||
| 2561 | 2564 | return -ENOMEM; |
| 2562 | 2565 | } |
| 2563 | 2566 | |
| 2564 | − udc_controller->soc_type = (unsigned long)ofdev->dev.of_match->data; | |
| 2567 | + udc_controller->soc_type = (unsigned long)match->data; | |
| 2565 | 2568 | udc_controller->usb_regs = of_iomap(np, 0); |
| 2566 | 2569 | if (!udc_controller->usb_regs) { |
| 2567 | 2570 | ret = -ENOMEM; |
| @@ -40,6 +40,7 @@ · 39 unmodified lines | ||
| 40 | 40 | #include <linux/slab.h> |
| 41 | 41 | #include <linux/usb/ulpi.h> |
| 42 | 42 | #include <plat/usb.h> |
| 43 | +#include <linux/regulator/consumer.h> | |
| 43 | 44 | |
| 44 | 45 | /* EHCI Register Set */ |
| 45 | 46 | #define EHCI_INSNREG04 (0xA0) |
| @@ -118,6 +119,8 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) · 72 unmodified lines | ||
| 118 | 119 | struct ehci_hcd *omap_ehci; |
| 119 | 120 | int ret = -ENODEV; |
| 120 | 121 | int irq; |
| 122 | + int i; | |
| 123 | + char supply[7]; | |
| 121 | 124 | |
| 122 | 125 | if (usb_disabled()) |
| 123 | 126 | return -ENODEV; |
| @@ -158,6 +161,23 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) · 34 unmodified lines | ||
| 158 | 161 | hcd->rsrc_len = resource_size(res); |
| 159 | 162 | hcd->regs = regs; |
| 160 | 163 | |
| 164 | + /* get ehci regulator and enable */ | |
| 165 | + for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) { | |
| 166 | + if (pdata->port_mode[i] != OMAP_EHCI_PORT_MODE_PHY) { | |
| 167 | + pdata->regulator[i] = NULL; | |
| 168 | + continue; | |
| 169 | + } | |
| 170 | + snprintf(supply, sizeof(supply), "hsusb%d", i); | |
| 171 | + pdata->regulator[i] = regulator_get(dev, supply); | |
| 172 | + if (IS_ERR(pdata->regulator[i])) { | |
| 173 | + pdata->regulator[i] = NULL; | |
| 174 | + dev_dbg(dev, | |
| 175 | + "failed to get ehci port%d regulator\n", i); | |
| 176 | + } else { | |
| 177 | + regulator_enable(pdata->regulator[i]); | |
| 178 | + } | |
| 179 | + } | |
| 180 | + | |
| 161 | 181 | ret = omap_usbhs_enable(dev); |
| 162 | 182 | if (ret) { |
| 163 | 183 | dev_err(dev, "failed to start usbhs with err %d\n", ret); |
| @@ -1633,6 +1633,7 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) · 1632 unmodified lines | ||
| 1633 | 1633 | ints[i].qh = NULL; |
| 1634 | 1634 | ints[i].qtd = NULL; |
| 1635 | 1635 | |
| 1636 | + urb->status = status; | |
| 1636 | 1637 | isp1760_urb_done(hcd, urb); |
| 1637 | 1638 | if (qtd) |
| 1638 | 1639 | pe(hcd, qh, qtd); |
| @@ -777,7 +777,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd) · 776 unmodified lines | ||
| 777 | 777 | if (t1 != t2) |
| 778 | 778 | xhci_writel(xhci, t2, port_array[port_index]); |
| 779 | 779 | |
| 780 | − if (DEV_HIGHSPEED(t1)) { | |
| 780 | + if (hcd->speed != HCD_USB3) { | |
| 781 | 781 | /* enable remote wake up for USB 2.0 */ |
| 782 | 782 | u32 __iomem *addr; |
| 783 | 783 | u32 tmp; |
| @@ -866,6 +866,21 @@ int xhci_bus_resume(struct usb_hcd *hcd) · 82 unmodified lines | ||
| 866 | 866 | temp |= PORT_LINK_STROBE | XDEV_U0; |
| 867 | 867 | xhci_writel(xhci, temp, port_array[port_index]); |
| 868 | 868 | } |
| 869 | + /* wait for the port to enter U0 and report port link | |
| 870 | + * state change. | |
| 871 | + */ | |
| 872 | + spin_unlock_irqrestore(&xhci->lock, flags); | |
| 873 | + msleep(20); | |
| 874 | + spin_lock_irqsave(&xhci->lock, flags); | |
| 875 | + | |
| 876 | + /* Clear PLC */ | |
| 877 | + temp = xhci_readl(xhci, port_array[port_index]); | |
| 878 | + if (temp & PORT_PLC) { | |
| 879 | + temp = xhci_port_state_to_neutral(temp); | |
| 880 | + temp |= PORT_PLC; | |
| 881 | + xhci_writel(xhci, temp, port_array[port_index]); | |
| 882 | + } | |
| 883 | + | |
| 869 | 884 | slot_id = xhci_find_slot_id_by_port(hcd, |
| 870 | 885 | xhci, port_index + 1); |
| 871 | 886 | if (slot_id) |
| @@ -873,7 +888,7 @@ int xhci_bus_resume(struct usb_hcd *hcd) · 1 unmodified line | ||
| 873 | 888 | } else |
| 874 | 889 | xhci_writel(xhci, temp, port_array[port_index]); |
| 875 | 890 | |
| 876 | − if (DEV_HIGHSPEED(temp)) { | |
| 891 | + if (hcd->speed != HCD_USB3) { | |
| 877 | 892 | /* disable remote wake up for USB 2.0 */ |
| 878 | 893 | u32 __iomem *addr; |
| 879 | 894 | u32 tmp; |
| @@ -1887,11 +1887,9 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, · 1886 unmodified lines | ||
| 1887 | 1887 | otg_set_vbus(musb->xceiv, 1); |
| 1888 | 1888 | |
| 1889 | 1889 | hcd->self.uses_pio_for_control = 1; |
| 1890 | − | |
| 1891 | − if (musb->xceiv->last_event == USB_EVENT_NONE) | |
| 1892 | − pm_runtime_put(musb->controller); | |
| 1893 | − | |
| 1894 | 1890 | } |
| 1891 | + if (musb->xceiv->last_event == USB_EVENT_NONE) | |
| 1892 | + pm_runtime_put(musb->controller); | |
| 1895 | 1893 | |
| 1896 | 1894 | return 0; |
| 1897 | 1895 | |
| @@ -270,7 +270,7 @@ static int musb_otg_notifications(struct notifier_block *nb, · 269 unmodified lines | ||
| 270 | 270 | DBG(4, "VBUS Disconnect\n"); |
| 271 | 271 | |
| 272 | 272 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC |
| 273 | − if (is_otg_enabled(musb)) | |
| 273 | + if (is_otg_enabled(musb) || is_peripheral_enabled(musb)) | |
| 274 | 274 | if (musb->gadget_driver) |
| 275 | 275 | #endif |
| 276 | 276 | { |
| @@ -66,7 +66,7 @@ · 65 unmodified lines | ||
| 66 | 66 | * have. Allow 1% either way on the nominal for TVs. |
| 67 | 67 | */ |
| 68 | 68 | #define NR_MONTYPES 6 |
| 69 | −static struct fb_monspecs monspecs[NR_MONTYPES] __initdata = { | |
| 69 | +static struct fb_monspecs monspecs[NR_MONTYPES] __devinitdata = { | |
| 70 | 70 | { /* TV */ |
| 71 | 71 | .hfmin = 15469, |
| 72 | 72 | .hfmax = 15781, |
| @@ -873,7 +873,7 @@ static struct fb_ops acornfb_ops = { · 800 unmodified lines | ||
| 873 | 873 | /* |
| 874 | 874 | * Everything after here is initialisation!!! |
| 875 | 875 | */ |
| 876 | −static struct fb_videomode modedb[] __initdata = { | |
| 876 | +static struct fb_videomode modedb[] __devinitdata = { | |
| 877 | 877 | { /* 320x256 @ 50Hz */ |
| 878 | 878 | NULL, 50, 320, 256, 125000, 92, 62, 35, 19, 38, 2, |
| 879 | 879 | FB_SYNC_COMP_HIGH_ACT, |
| @@ -925,8 +925,7 @@ static struct fb_videomode modedb[] __initdata = { · 45 unmodified lines | ||
| 925 | 925 | } |
| 926 | 926 | }; |
| 927 | 927 | |
| 928 | −static struct fb_videomode __initdata | |
| 929 | −acornfb_default_mode = { | |
| 928 | +static struct fb_videomode acornfb_default_mode __devinitdata = { | |
| 930 | 929 | .name = NULL, |
| 931 | 930 | .refresh = 60, |
| 932 | 931 | .xres = 640, |
| @@ -942,7 +941,7 @@ acornfb_default_mode = { · 9 unmodified lines | ||
| 942 | 941 | .vmode = FB_VMODE_NONINTERLACED |
| 943 | 942 | }; |
| 944 | 943 | |
| 945 | −static void __init acornfb_init_fbinfo(void) | |
| 944 | +static void __devinit acornfb_init_fbinfo(void) | |
| 946 | 945 | { |
| 947 | 946 | static int first = 1; |
| 948 | 947 | |
| @@ -1018,8 +1017,7 @@ static void __init acornfb_init_fbinfo(void) · 69 unmodified lines | ||
| 1018 | 1017 | * size can optionally be followed by 'M' or 'K' for |
| 1019 | 1018 | * MB or KB respectively. |
| 1020 | 1019 | */ |
| 1021 | −static void __init | |
| 1022 | −acornfb_parse_mon(char *opt) | |
| 1020 | +static void __devinit acornfb_parse_mon(char *opt) | |
| 1023 | 1021 | { |
| 1024 | 1022 | char *p = opt; |
| 1025 | 1023 | |
| @@ -1066,8 +1064,7 @@ bad: · 40 unmodified lines | ||
| 1066 | 1064 | current_par.montype = -1; |
| 1067 | 1065 | } |
| 1068 | 1066 | |
| 1069 | −static void __init | |
| 1070 | −acornfb_parse_montype(char *opt) | |
| 1067 | +static void __devinit acornfb_parse_montype(char *opt) | |
| 1071 | 1068 | { |
| 1072 | 1069 | current_par.montype = -2; |
| 1073 | 1070 | |
| @@ -1108,8 +1105,7 @@ acornfb_parse_montype(char *opt) · 34 unmodified lines | ||
| 1108 | 1105 | } |
| 1109 | 1106 | } |
| 1110 | 1107 | |
| 1111 | −static void __init | |
| 1112 | −acornfb_parse_dram(char *opt) | |
| 1108 | +static void __devinit acornfb_parse_dram(char *opt) | |
| 1113 | 1109 | { |
| 1114 | 1110 | unsigned int size; |
| 1115 | 1111 | |
| @@ -1134,15 +1130,14 @@ acornfb_parse_dram(char *opt) · 18 unmodified lines | ||
| 1134 | 1130 | static struct options { |
| 1135 | 1131 | char *name; |
| 1136 | 1132 | void (*parse)(char *opt); |
| 1137 | −} opt_table[] __initdata = { | |
| 1133 | +} opt_table[] __devinitdata = { | |
| 1138 | 1134 | { "mon", acornfb_parse_mon }, |
| 1139 | 1135 | { "montype", acornfb_parse_montype }, |
| 1140 | 1136 | { "dram", acornfb_parse_dram }, |
| 1141 | 1137 | { NULL, NULL } |
| 1142 | 1138 | }; |
| 1143 | 1139 | |
| 1144 | −int __init | |
| 1145 | −acornfb_setup(char *options) | |
| 1140 | +static int __devinit acornfb_setup(char *options) | |
| 1146 | 1141 | { |
| 1147 | 1142 | struct options *optp; |
| 1148 | 1143 | char *opt; |
| @@ -1179,8 +1174,7 @@ acornfb_setup(char *options) · 30 unmodified lines | ||
| 1179 | 1174 | * Detect type of monitor connected |
| 1180 | 1175 | * For now, we just assume SVGA |
| 1181 | 1176 | */ |
| 1182 | −static int __init | |
| 1183 | −acornfb_detect_monitortype(void) | |
| 1177 | +static int __devinit acornfb_detect_monitortype(void) | |
| 1184 | 1178 | { |
| 1185 | 1179 | return 4; |
| 1186 | 1180 | } |
| @@ -42,9 +42,34 @@ · 41 unmodified lines | ||
| 42 | 42 | |
| 43 | 43 | #define FBPIXMAPSIZE (1024 * 8) |
| 44 | 44 | |
| 45 | +static DEFINE_MUTEX(registration_lock); | |
| 45 | 46 | struct fb_info *registered_fb[FB_MAX] __read_mostly; |
| 46 | 47 | int num_registered_fb __read_mostly; |
| 47 | 48 | |
| 49 | +static struct fb_info *get_fb_info(unsigned int idx) | |
| 50 | +{ | |
| 51 | + struct fb_info *fb_info; | |
| 52 | + | |
| 53 | + if (idx >= FB_MAX) | |
| 54 | + return ERR_PTR(-ENODEV); | |
| 55 | + | |
| 56 | + mutex_lock(®istration_lock); | |
| 57 | + fb_info = registered_fb[idx]; | |
| 58 | + if (fb_info) | |
| 59 | + atomic_inc(&fb_info->count); | |
| 60 | + mutex_unlock(®istration_lock); | |
| 61 | + | |
| 62 | + return fb_info; | |
| 63 | +} | |
| 64 | + | |
| 65 | +static void put_fb_info(struct fb_info *fb_info) | |
| 66 | +{ | |
| 67 | + if (!atomic_dec_and_test(&fb_info->count)) | |
| 68 | + return; | |
| 69 | + if (fb_info->fbops->fb_destroy) | |
| 70 | + fb_info->fbops->fb_destroy(fb_info); | |
| 71 | +} | |
| 72 | + | |
| 48 | 73 | int lock_fb_info(struct fb_info *info) |
| 49 | 74 | { |
| 50 | 75 | mutex_lock(&info->lock); |
| @@ -647,6 +672,7 @@ int fb_show_logo(struct fb_info *info, int rotate) { return 0; } · 596 unmodified lines | ||
| 647 | 672 | |
| 648 | 673 | static void *fb_seq_start(struct seq_file *m, loff_t *pos) |
| 649 | 674 | { |
| 675 | + mutex_lock(®istration_lock); | |
| 650 | 676 | return (*pos < FB_MAX) ? pos : NULL; |
| 651 | 677 | } |
| 652 | 678 | |
| @@ -658,6 +684,7 @@ static void *fb_seq_next(struct seq_file *m, void *v, loff_t *pos) · 5 unmodified lines | ||
| 658 | 684 | |
| 659 | 685 | static void fb_seq_stop(struct seq_file *m, void *v) |
| 660 | 686 | { |
| 687 | + mutex_unlock(®istration_lock); | |
| 661 | 688 | } |
| 662 | 689 | |
| 663 | 690 | static int fb_seq_show(struct seq_file *m, void *v) |
| @@ -690,13 +717,30 @@ static const struct file_operations fb_proc_fops = { · 26 unmodified lines | ||
| 690 | 717 | .release = seq_release, |
| 691 | 718 | }; |
| 692 | 719 | |
| 693 | −static ssize_t | |
| 694 | −fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |
| 720 | +/* | |
| 721 | + * We hold a reference to the fb_info in file->private_data, | |
| 722 | + * but if the current registered fb has changed, we don't | |
| 723 | + * actually want to use it. | |
| 724 | + * | |
| 725 | + * So look up the fb_info using the inode minor number, | |
| 726 | + * and just verify it against the reference we have. | |
| 727 | + */ | |
| 728 | +static struct fb_info *file_fb_info(struct file *file) | |
| 695 | 729 | { |
| 696 | − unsigned long p = *ppos; | |
| 697 | 730 | struct inode *inode = file->f_path.dentry->d_inode; |
| 698 | 731 | int fbidx = iminor(inode); |
| 699 | 732 | struct fb_info *info = registered_fb[fbidx]; |
| 733 | + | |
| 734 | + if (info != file->private_data) | |
| 735 | + info = NULL; | |
| 736 | + return info; | |
| 737 | +} | |
| 738 | + | |
| 739 | +static ssize_t | |
| 740 | +fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |
| 741 | +{ | |
| 742 | + unsigned long p = *ppos; | |
| 743 | + struct fb_info *info = file_fb_info(file); | |
| 700 | 744 | u8 *buffer, *dst; |
| 701 | 745 | u8 __iomem *src; |
| 702 | 746 | int c, cnt = 0, err = 0; |
| @@ -761,9 +805,7 @@ static ssize_t · 58 unmodified lines | ||
| 761 | 805 | fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) |
| 762 | 806 | { |
| 763 | 807 | unsigned long p = *ppos; |
| 764 | − struct inode *inode = file->f_path.dentry->d_inode; | |
| 765 | − int fbidx = iminor(inode); | |
| 766 | − struct fb_info *info = registered_fb[fbidx]; | |
| 808 | + struct fb_info *info = file_fb_info(file); | |
| 767 | 809 | u8 *buffer, *src; |
| 768 | 810 | u8 __iomem *dst; |
| 769 | 811 | int c, cnt = 0, err = 0; |
| @@ -1141,10 +1183,10 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, · 371 unmodified lines | ||
| 1141 | 1183 | |
| 1142 | 1184 | static long fb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
| 1143 | 1185 | { |
| 1144 | − struct inode *inode = file->f_path.dentry->d_inode; | |
| 1145 | − int fbidx = iminor(inode); | |
| 1146 | − struct fb_info *info = registered_fb[fbidx]; | |
| 1186 | + struct fb_info *info = file_fb_info(file); | |
| 1147 | 1187 | |
| 1188 | + if (!info) | |
| 1189 | + return -ENODEV; | |
| 1148 | 1190 | return do_fb_ioctl(info, cmd, arg); |
| 1149 | 1191 | } |
| 1150 | 1192 | |
| @@ -1265,12 +1307,13 @@ static int fb_get_fscreeninfo(struct fb_info *info, unsigned int cmd, · 114 unmodified lines | ||
| 1265 | 1307 | static long fb_compat_ioctl(struct file *file, unsigned int cmd, |
| 1266 | 1308 | unsigned long arg) |
| 1267 | 1309 | { |
| 1268 | − struct inode *inode = file->f_path.dentry->d_inode; | |
| 1269 | − int fbidx = iminor(inode); | |
| 1270 | − struct fb_info *info = registered_fb[fbidx]; | |
| 1271 | − struct fb_ops *fb = info->fbops; | |
| 1310 | + struct fb_info *info = file_fb_info(file); | |
| 1311 | + struct fb_ops *fb; | |
| 1272 | 1312 | long ret = -ENOIOCTLCMD; |
| 1273 | 1313 | |
| 1314 | + if (!info) | |
| 1315 | + return -ENODEV; | |
| 1316 | + fb = info->fbops; | |
| 1274 | 1317 | switch(cmd) { |
| 1275 | 1318 | case FBIOGET_VSCREENINFO: |
| 1276 | 1319 | case FBIOPUT_VSCREENINFO: |
| @@ -1303,16 +1346,18 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd, · 26 unmodified lines | ||
| 1303 | 1346 | static int |
| 1304 | 1347 | fb_mmap(struct file *file, struct vm_area_struct * vma) |
| 1305 | 1348 | { |
| 1306 | − int fbidx = iminor(file->f_path.dentry->d_inode); | |
| 1307 | − struct fb_info *info = registered_fb[fbidx]; | |
| 1308 | − struct fb_ops *fb = info->fbops; | |
| 1349 | + struct fb_info *info = file_fb_info(file); | |
| 1350 | + struct fb_ops *fb; | |
| 1309 | 1351 | unsigned long off; |
| 1310 | 1352 | unsigned long start; |
| 1311 | 1353 | u32 len; |
| 1312 | 1354 | |
| 1355 | + if (!info) | |
| 1356 | + return -ENODEV; | |
| 1313 | 1357 | if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) |
| 1314 | 1358 | return -EINVAL; |
| 1315 | 1359 | off = vma->vm_pgoff << PAGE_SHIFT; |
| 1360 | + fb = info->fbops; | |
| 1316 | 1361 | if (!fb) |
| 1317 | 1362 | return -ENODEV; |
| 1318 | 1363 | mutex_lock(&info->mm_lock); |
| @@ -1361,14 +1406,16 @@ __releases(&info->lock) · 42 unmodified lines | ||
| 1361 | 1406 | struct fb_info *info; |
| 1362 | 1407 | int res = 0; |
| 1363 | 1408 | |
| 1364 | − if (fbidx >= FB_MAX) | |
| 1365 | − return -ENODEV; | |
| 1366 | − info = registered_fb[fbidx]; | |
| 1367 | − if (!info) | |
| 1409 | + info = get_fb_info(fbidx); | |
| 1410 | + if (!info) { | |
| 1368 | 1411 | request_module("fb%d", fbidx); |
| 1369 | − info = registered_fb[fbidx]; | |
| 1370 | − if (!info) | |
| 1371 | − return -ENODEV; | |
| 1412 | + info = get_fb_info(fbidx); | |
| 1413 | + if (!info) | |
| 1414 | + return -ENODEV; | |
| 1415 | + } | |
| 1416 | + if (IS_ERR(info)) | |
| 1417 | + return PTR_ERR(info); | |
| 1418 | + | |
| 1372 | 1419 | mutex_lock(&info->lock); |
| 1373 | 1420 | if (!try_module_get(info->fbops->owner)) { |
| 1374 | 1421 | res = -ENODEV; |
| @@ -1386,6 +1433,8 @@ __releases(&info->lock) · 11 unmodified lines | ||
| 1386 | 1433 | #endif |
| 1387 | 1434 | out: |
| 1388 | 1435 | mutex_unlock(&info->lock); |
| 1436 | + if (res) | |
| 1437 | + put_fb_info(info); | |
| 1389 | 1438 | return res; |
| 1390 | 1439 | } |
| 1391 | 1440 | |
| @@ -1401,6 +1450,7 @@ __releases(&info->lock) · 9 unmodified lines | ||
| 1401 | 1450 | info->fbops->fb_release(info,1); |
| 1402 | 1451 | module_put(info->fbops->owner); |
| 1403 | 1452 | mutex_unlock(&info->lock); |
| 1453 | + put_fb_info(info); | |
| 1404 | 1454 | return 0; |
| 1405 | 1455 | } |
| 1406 | 1456 | |
| @@ -1487,8 +1537,10 @@ static bool fb_do_apertures_overlap(struct apertures_struct *gena, · 80 unmodified lines | ||
| 1487 | 1537 | return false; |
| 1488 | 1538 | } |
| 1489 | 1539 | |
| 1540 | +static int do_unregister_framebuffer(struct fb_info *fb_info); | |
| 1541 | + | |
| 1490 | 1542 | #define VGA_FB_PHYS 0xA0000 |
| 1491 | −void remove_conflicting_framebuffers(struct apertures_struct *a, | |
| 1543 | +static void do_remove_conflicting_framebuffers(struct apertures_struct *a, | |
| 1492 | 1544 | const char *name, bool primary) |
| 1493 | 1545 | { |
| 1494 | 1546 | int i; |
| @@ -1510,43 +1562,32 @@ void remove_conflicting_framebuffers(struct apertures_struct *a, · 15 unmodified lines | ||
| 1510 | 1562 | printk(KERN_INFO "fb: conflicting fb hw usage " |
| 1511 | 1563 | "%s vs %s - removing generic driver\n", |
| 1512 | 1564 | name, registered_fb[i]->fix.id); |
| 1513 | − unregister_framebuffer(registered_fb[i]); | |
| 1565 | + do_unregister_framebuffer(registered_fb[i]); | |
| 1514 | 1566 | } |
| 1515 | 1567 | } |
| 1516 | 1568 | } |
| 1517 | −EXPORT_SYMBOL(remove_conflicting_framebuffers); | |
| 1518 | 1569 | |
| 1519 | −/** | |
| 1520 | − * register_framebuffer - registers a frame buffer device | |
| 1521 | − * @fb_info: frame buffer info structure | |
| 1522 | − * | |
| 1523 | − * Registers a frame buffer device @fb_info. | |
| 1524 | − * | |
| 1525 | − * Returns negative errno on error, or zero for success. | |
| 1526 | − * | |
| 1527 | − */ | |
| 1528 | − | |
| 1529 | −int | |
| 1530 | −register_framebuffer(struct fb_info *fb_info) | |
| 1570 | +static int do_register_framebuffer(struct fb_info *fb_info) | |
| 1531 | 1571 | { |
| 1532 | 1572 | int i; |
| 1533 | 1573 | struct fb_event event; |
| 1534 | 1574 | struct fb_videomode mode; |
| 1535 | 1575 | |
| 1536 | − if (num_registered_fb == FB_MAX) | |
| 1537 | − return -ENXIO; | |
| 1538 | − | |
| 1539 | 1576 | if (fb_check_foreignness(fb_info)) |
| 1540 | 1577 | return -ENOSYS; |
| 1541 | 1578 | |
| 1542 | − remove_conflicting_framebuffers(fb_info->apertures, fb_info->fix.id, | |
| 1579 | + do_remove_conflicting_framebuffers(fb_info->apertures, fb_info->fix.id, | |
| 1543 | 1580 | fb_is_primary_device(fb_info)); |
| 1544 | 1581 | |
| 1582 | + if (num_registered_fb == FB_MAX) | |
| 1583 | + return -ENXIO; | |
| 1584 | + | |
| 1545 | 1585 | num_registered_fb++; |
| 1546 | 1586 | for (i = 0 ; i < FB_MAX; i++) |
| 1547 | 1587 | if (!registered_fb[i]) |
| 1548 | 1588 | break; |
| 1549 | 1589 | fb_info->node = i; |
| 1590 | + atomic_set(&fb_info->count, 1); | |
| 1550 | 1591 | mutex_init(&fb_info->lock); |
| 1551 | 1592 | mutex_init(&fb_info->mm_lock); |
| 1552 | 1593 | |
| @@ -1592,36 +1633,14 @@ register_framebuffer(struct fb_info *fb_info) · 39 unmodified lines | ||
| 1592 | 1633 | return 0; |
| 1593 | 1634 | } |
| 1594 | 1635 | |
| 1595 | − | |
| 1596 | −/** | |
| 1597 | − * unregister_framebuffer - releases a frame buffer device | |
| 1598 | − * @fb_info: frame buffer info structure | |
| 1599 | − * | |
| 1600 | − * Unregisters a frame buffer device @fb_info. | |
| 1601 | − * | |
| 1602 | − * Returns negative errno on error, or zero for success. | |
| 1603 | − * | |
| 1604 | − * This function will also notify the framebuffer console | |
| 1605 | − * to release the driver. | |
| 1606 | − * | |
| 1607 | − * This is meant to be called within a driver's module_exit() | |
| 1608 | − * function. If this is called outside module_exit(), ensure | |
| 1609 | − * that the driver implements fb_open() and fb_release() to | |
| 1610 | − * check that no processes are using the device. | |
| 1611 | − */ | |
| 1612 | − | |
| 1613 | −int | |
| 1614 | −unregister_framebuffer(struct fb_info *fb_info) | |
| 1636 | +static int do_unregister_framebuffer(struct fb_info *fb_info) | |
| 1615 | 1637 | { |
| 1616 | 1638 | struct fb_event event; |
| 1617 | 1639 | int i, ret = 0; |
| 1618 | 1640 | |
| 1619 | 1641 | i = fb_info->node; |
| 1620 | − if (!registered_fb[i]) { | |
| 1621 | − ret = -EINVAL; | |
| 1622 | − goto done; | |
| 1623 | − } | |
| 1624 | − | |
| 1642 | + if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info) | |
| 1643 | + return -EINVAL; | |
| 1625 | 1644 | |
| 1626 | 1645 | if (!lock_fb_info(fb_info)) |
| 1627 | 1646 | return -ENODEV; |
| @@ -1629,16 +1648,14 @@ unregister_framebuffer(struct fb_info *fb_info) · 1 unmodified line | ||
| 1629 | 1648 | ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event); |
| 1630 | 1649 | unlock_fb_info(fb_info); |
| 1631 | 1650 | |
| 1632 | − if (ret) { | |
| 1633 | − ret = -EINVAL; | |
| 1634 | − goto done; | |
| 1635 | − } | |
| 1651 | + if (ret) | |
| 1652 | + return -EINVAL; | |
| 1636 | 1653 | |
| 1637 | 1654 | if (fb_info->pixmap.addr && |
| 1638 | 1655 | (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) |
| 1639 | 1656 | kfree(fb_info->pixmap.addr); |
| 1640 | 1657 | fb_destroy_modelist(&fb_info->modelist); |
| 1641 | − registered_fb[i]=NULL; | |
| 1658 | + registered_fb[i] = NULL; | |
| 1642 | 1659 | num_registered_fb--; |
| 1643 | 1660 | fb_cleanup_device(fb_info); |
| 1644 | 1661 | device_destroy(fb_class, MKDEV(FB_MAJOR, i)); |
| @@ -1646,9 +1663,65 @@ unregister_framebuffer(struct fb_info *fb_info) · 1 unmodified line | ||
| 1646 | 1663 | fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); |
| 1647 | 1664 | |
| 1648 | 1665 | /* this may free fb info */ |
| 1649 | − if (fb_info->fbops->fb_destroy) | |
| 1650 | − fb_info->fbops->fb_destroy(fb_info); | |
| 1651 | −done: | |
| 1666 | + put_fb_info(fb_info); | |
| 1667 | + return 0; | |
| 1668 | +} | |
| 1669 | + | |
| 1670 | +void remove_conflicting_framebuffers(struct apertures_struct *a, | |
| 1671 | + const char *name, bool primary) | |
| 1672 | +{ | |
| 1673 | + mutex_lock(®istration_lock); | |
| 1674 | + do_remove_conflicting_framebuffers(a, name, primary); | |
| 1675 | + mutex_unlock(®istration_lock); | |
| 1676 | +} | |
| 1677 | +EXPORT_SYMBOL(remove_conflicting_framebuffers); | |
| 1678 | + | |
| 1679 | +/** | |
| 1680 | + * register_framebuffer - registers a frame buffer device | |
| 1681 | + * @fb_info: frame buffer info structure | |
| 1682 | + * | |
| 1683 | + * Registers a frame buffer device @fb_info. | |
| 1684 | + * | |
| 1685 | + * Returns negative errno on error, or zero for success. | |
| 1686 | + * | |
| 1687 | + */ | |
| 1688 | +int | |
| 1689 | +register_framebuffer(struct fb_info *fb_info) | |
| 1690 | +{ | |
| 1691 | + int ret; | |
| 1692 | + | |
| 1693 | + mutex_lock(®istration_lock); | |
| 1694 | + ret = do_register_framebuffer(fb_info); | |
| 1695 | + mutex_unlock(®istration_lock); | |
| 1696 | + | |
| 1697 | + return ret; | |
| 1698 | +} | |
| 1699 | + | |
| 1700 | +/** | |
| 1701 | + * unregister_framebuffer - releases a frame buffer device | |
| 1702 | + * @fb_info: frame buffer info structure | |
| 1703 | + * | |
| 1704 | + * Unregisters a frame buffer device @fb_info. | |
| 1705 | + * | |
| 1706 | + * Returns negative errno on error, or zero for success. | |
| 1707 | + * | |
| 1708 | + * This function will also notify the framebuffer console | |
| 1709 | + * to release the driver. | |
| 1710 | + * | |
| 1711 | + * This is meant to be called within a driver's module_exit() | |
| 1712 | + * function. If this is called outside module_exit(), ensure | |
| 1713 | + * that the driver implements fb_open() and fb_release() to | |
| 1714 | + * check that no processes are using the device. | |
| 1715 | + */ | |
| 1716 | +int | |
| 1717 | +unregister_framebuffer(struct fb_info *fb_info) | |
| 1718 | +{ | |
| 1719 | + int ret; | |
| 1720 | + | |
| 1721 | + mutex_lock(®istration_lock); | |
| 1722 | + ret = do_unregister_framebuffer(fb_info); | |
| 1723 | + mutex_unlock(®istration_lock); | |
| 1724 | + | |
| 1652 | 1725 | return ret; |
| 1653 | 1726 | } |
| 1654 | 1727 | |
| @@ -590,15 +590,10 @@ static struct virtio_config_ops virtio_pci_config_ops = { · 589 unmodified lines | ||
| 590 | 590 | |
| 591 | 591 | static void virtio_pci_release_dev(struct device *_d) |
| 592 | 592 | { |
| 593 | − struct virtio_device *dev = container_of(_d, struct virtio_device, dev); | |
| 593 | + struct virtio_device *dev = container_of(_d, struct virtio_device, | |
| 594 | + dev); | |
| 594 | 595 | struct virtio_pci_device *vp_dev = to_vp_device(dev); |
| 595 | − struct pci_dev *pci_dev = vp_dev->pci_dev; | |
| 596 | 596 | |
| 597 | − vp_del_vqs(dev); | |
| 598 | − pci_set_drvdata(pci_dev, NULL); | |
| 599 | − pci_iounmap(pci_dev, vp_dev->ioaddr); | |
| 600 | − pci_release_regions(pci_dev); | |
| 601 | − pci_disable_device(pci_dev); | |
| 602 | 597 | kfree(vp_dev); |
| 603 | 598 | } |
| 604 | 599 | |
| @@ -681,6 +676,12 @@ static void __devexit virtio_pci_remove(struct pci_dev *pci_dev) · 76 unmodified lines | ||
| 681 | 676 | struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); |
| 682 | 677 | |
| 683 | 678 | unregister_virtio_device(&vp_dev->vdev); |
| 679 | + | |
| 680 | + vp_del_vqs(&vp_dev->vdev); | |
| 681 | + pci_set_drvdata(pci_dev, NULL); | |
| 682 | + pci_iounmap(pci_dev, vp_dev->ioaddr); | |
| 683 | + pci_release_regions(pci_dev); | |
| 684 | + pci_disable_device(pci_dev); | |
| 684 | 685 | } |
| 685 | 686 | |
| 686 | 687 | #ifdef CONFIG_PM |
| @@ -371,6 +371,7 @@ void *virtqueue_detach_unused_buf(struct virtqueue *_vq) · 370 unmodified lines | ||
| 371 | 371 | /* detach_buf clears data, so grab it now. */ |
| 372 | 372 | buf = vq->data[i]; |
| 373 | 373 | detach_buf(vq, i); |
| 374 | + vq->vring.avail->idx--; | |
| 374 | 375 | END_USE(vq); |
| 375 | 376 | return buf; |
| 376 | 377 | } |
| @@ -35,6 +35,7 @@ · 34 unmodified lines | ||
| 35 | 35 | * document number 324645-001, 324646-001: Cougar Point (CPT) |
| 36 | 36 | * document number TBD : Patsburg (PBG) |
| 37 | 37 | * document number TBD : DH89xxCC |
| 38 | + * document number TBD : Panther Point | |
| 38 | 39 | */ |
| 39 | 40 | |
| 40 | 41 | /* |
| @@ -153,6 +154,38 @@ enum iTCO_chipsets { · 112 unmodified lines | ||
| 153 | 154 | TCO_PBG1, /* Patsburg */ |
| 154 | 155 | TCO_PBG2, /* Patsburg */ |
| 155 | 156 | TCO_DH89XXCC, /* DH89xxCC */ |
| 157 | + TCO_PPT0, /* Panther Point */ | |
| 158 | + TCO_PPT1, /* Panther Point */ | |
| 159 | + TCO_PPT2, /* Panther Point */ | |
| 160 | + TCO_PPT3, /* Panther Point */ | |
| 161 | + TCO_PPT4, /* Panther Point */ | |
| 162 | + TCO_PPT5, /* Panther Point */ | |
| 163 | + TCO_PPT6, /* Panther Point */ | |
| 164 | + TCO_PPT7, /* Panther Point */ | |
| 165 | + TCO_PPT8, /* Panther Point */ | |
| 166 | + TCO_PPT9, /* Panther Point */ | |
| 167 | + TCO_PPT10, /* Panther Point */ | |
| 168 | + TCO_PPT11, /* Panther Point */ | |
| 169 | + TCO_PPT12, /* Panther Point */ | |
| 170 | + TCO_PPT13, /* Panther Point */ | |
| 171 | + TCO_PPT14, /* Panther Point */ | |
| 172 | + TCO_PPT15, /* Panther Point */ | |
| 173 | + TCO_PPT16, /* Panther Point */ | |
| 174 | + TCO_PPT17, /* Panther Point */ | |
| 175 | + TCO_PPT18, /* Panther Point */ | |
| 176 | + TCO_PPT19, /* Panther Point */ | |
| 177 | + TCO_PPT20, /* Panther Point */ | |
| 178 | + TCO_PPT21, /* Panther Point */ | |
| 179 | + TCO_PPT22, /* Panther Point */ | |
| 180 | + TCO_PPT23, /* Panther Point */ | |
| 181 | + TCO_PPT24, /* Panther Point */ | |
| 182 | + TCO_PPT25, /* Panther Point */ | |
| 183 | + TCO_PPT26, /* Panther Point */ | |
| 184 | + TCO_PPT27, /* Panther Point */ | |
| 185 | + TCO_PPT28, /* Panther Point */ | |
| 186 | + TCO_PPT29, /* Panther Point */ | |
| 187 | + TCO_PPT30, /* Panther Point */ | |
| 188 | + TCO_PPT31, /* Panther Point */ | |
| 156 | 189 | }; |
| 157 | 190 | |
| 158 | 191 | static struct { |
| @@ -244,6 +277,38 @@ static struct { · 85 unmodified lines | ||
| 244 | 277 | {"Patsburg", 2}, |
| 245 | 278 | {"Patsburg", 2}, |
| 246 | 279 | {"DH89xxCC", 2}, |
| 280 | + {"Panther Point", 2}, | |
| 281 | + {"Panther Point", 2}, | |
| 282 | + {"Panther Point", 2}, | |
| 283 | + {"Panther Point", 2}, | |
| 284 | + {"Panther Point", 2}, | |
| 285 | + {"Panther Point", 2}, | |
| 286 | + {"Panther Point", 2}, | |
| 287 | + {"Panther Point", 2}, | |
| 288 | + {"Panther Point", 2}, | |
| 289 | + {"Panther Point", 2}, | |
| 290 | + {"Panther Point", 2}, | |
| 291 | + {"Panther Point", 2}, | |
| 292 | + {"Panther Point", 2}, | |
| 293 | + {"Panther Point", 2}, | |
| 294 | + {"Panther Point", 2}, | |
| 295 | + {"Panther Point", 2}, | |
| 296 | + {"Panther Point", 2}, | |
| 297 | + {"Panther Point", 2}, | |
| 298 | + {"Panther Point", 2}, | |
| 299 | + {"Panther Point", 2}, | |
| 300 | + {"Panther Point", 2}, | |
| 301 | + {"Panther Point", 2}, | |
| 302 | + {"Panther Point", 2}, | |
| 303 | + {"Panther Point", 2}, | |
| 304 | + {"Panther Point", 2}, | |
| 305 | + {"Panther Point", 2}, | |
| 306 | + {"Panther Point", 2}, | |
| 307 | + {"Panther Point", 2}, | |
| 308 | + {"Panther Point", 2}, | |
| 309 | + {"Panther Point", 2}, | |
| 310 | + {"Panther Point", 2}, | |
| 311 | + {"Panther Point", 2}, | |
| 247 | 312 | {NULL, 0} |
| 248 | 313 | }; |
| 249 | 314 | |
| @@ -363,6 +428,38 @@ static DEFINE_PCI_DEVICE_TABLE(iTCO_wdt_pci_tbl) = { · 113 unmodified lines | ||
| 363 | 428 | { ITCO_PCI_DEVICE(0x1d40, TCO_PBG1)}, |
| 364 | 429 | { ITCO_PCI_DEVICE(0x1d41, TCO_PBG2)}, |
| 365 | 430 | { ITCO_PCI_DEVICE(0x2310, TCO_DH89XXCC)}, |
| 431 | + { ITCO_PCI_DEVICE(0x1e40, TCO_PPT0)}, | |
| 432 | + { ITCO_PCI_DEVICE(0x1e41, TCO_PPT1)}, | |
| 433 | + { ITCO_PCI_DEVICE(0x1e42, TCO_PPT2)}, | |
| 434 | + { ITCO_PCI_DEVICE(0x1e43, TCO_PPT3)}, | |
| 435 | + { ITCO_PCI_DEVICE(0x1e44, TCO_PPT4)}, | |
| 436 | + { ITCO_PCI_DEVICE(0x1e45, TCO_PPT5)}, | |
| 437 | + { ITCO_PCI_DEVICE(0x1e46, TCO_PPT6)}, | |
| 438 | + { ITCO_PCI_DEVICE(0x1e47, TCO_PPT7)}, | |
| 439 | + { ITCO_PCI_DEVICE(0x1e48, TCO_PPT8)}, | |
| 440 | + { ITCO_PCI_DEVICE(0x1e49, TCO_PPT9)}, | |
| 441 | + { ITCO_PCI_DEVICE(0x1e4a, TCO_PPT10)}, | |
| 442 | + { ITCO_PCI_DEVICE(0x1e4b, TCO_PPT11)}, | |
| 443 | + { ITCO_PCI_DEVICE(0x1e4c, TCO_PPT12)}, | |
| 444 | + { ITCO_PCI_DEVICE(0x1e4d, TCO_PPT13)}, | |
| 445 | + { ITCO_PCI_DEVICE(0x1e4e, TCO_PPT14)}, | |
| 446 | + { ITCO_PCI_DEVICE(0x1e4f, TCO_PPT15)}, | |
| 447 | + { ITCO_PCI_DEVICE(0x1e50, TCO_PPT16)}, | |
| 448 | + { ITCO_PCI_DEVICE(0x1e51, TCO_PPT17)}, | |
| 449 | + { ITCO_PCI_DEVICE(0x1e52, TCO_PPT18)}, | |
| 450 | + { ITCO_PCI_DEVICE(0x1e53, TCO_PPT19)}, | |
| 451 | + { ITCO_PCI_DEVICE(0x1e54, TCO_PPT20)}, | |
| 452 | + { ITCO_PCI_DEVICE(0x1e55, TCO_PPT21)}, | |
| 453 | + { ITCO_PCI_DEVICE(0x1e56, TCO_PPT22)}, | |
| 454 | + { ITCO_PCI_DEVICE(0x1e57, TCO_PPT23)}, | |
| 455 | + { ITCO_PCI_DEVICE(0x1e58, TCO_PPT24)}, | |
| 456 | + { ITCO_PCI_DEVICE(0x1e59, TCO_PPT25)}, | |
| 457 | + { ITCO_PCI_DEVICE(0x1e5a, TCO_PPT26)}, | |
| 458 | + { ITCO_PCI_DEVICE(0x1e5b, TCO_PPT27)}, | |
| 459 | + { ITCO_PCI_DEVICE(0x1e5c, TCO_PPT28)}, | |
| 460 | + { ITCO_PCI_DEVICE(0x1e5d, TCO_PPT29)}, | |
| 461 | + { ITCO_PCI_DEVICE(0x1e5e, TCO_PPT30)}, | |
| 462 | + { ITCO_PCI_DEVICE(0x1e5f, TCO_PPT31)}, | |
| 366 | 463 | { 0, }, /* End of list */ |
| 367 | 464 | }; |
| 368 | 465 | MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); |
| @@ -185,17 +185,20 @@ static struct miscdevice mpc8xxx_wdt_miscdev = { · 184 unmodified lines | ||
| 185 | 185 | .fops = &mpc8xxx_wdt_fops, |
| 186 | 186 | }; |
| 187 | 187 | |
| 188 | +static const struct of_device_id mpc8xxx_wdt_match[]; | |
| 188 | 189 | static int __devinit mpc8xxx_wdt_probe(struct platform_device *ofdev) |
| 189 | 190 | { |
| 190 | 191 | int ret; |
| 192 | + const struct of_device_id *match; | |
| 191 | 193 | struct device_node *np = ofdev->dev.of_node; |
| 192 | 194 | struct mpc8xxx_wdt_type *wdt_type; |
| 193 | 195 | u32 freq = fsl_get_sys_freq(); |
| 194 | 196 | bool enabled; |
| 195 | 197 | |
| 196 | − if (!ofdev->dev.of_match) | |
| 198 | + match = of_match_device(mpc8xxx_wdt_match, &ofdev->dev); | |
| 199 | + if (!match) | |
| 197 | 200 | return -EINVAL; |
| 198 | − wdt_type = ofdev->dev.of_match->data; | |
| 201 | + wdt_type = match->data; | |
| 199 | 202 | |
| 200 | 203 | if (!freq || freq == -1) |
| 201 | 204 | return -EINVAL; |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <linux/sysrq.h> |
| 9 | 9 | #include <linux/stop_machine.h> |
| 10 | 10 | #include <linux/freezer.h> |
| 11 | +#include <linux/syscore_ops.h> | |
| 11 | 12 | |
| 12 | 13 | #include <xen/xen.h> |
| 13 | 14 | #include <xen/xenbus.h> |
| @@ -70,8 +71,13 @@ static int xen_suspend(void *data) · 56 unmodified lines | ||
| 70 | 71 | BUG_ON(!irqs_disabled()); |
| 71 | 72 | |
| 72 | 73 | err = sysdev_suspend(PMSG_FREEZE); |
| 74 | + if (!err) { | |
| 75 | + err = syscore_suspend(); | |
| 76 | + if (err) | |
| 77 | + sysdev_resume(); | |
| 78 | + } | |
| 73 | 79 | if (err) { |
| 74 | − printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n", | |
| 80 | + printk(KERN_ERR "xen_suspend: system core suspend failed: %d\n", | |
| 75 | 81 | err); |
| 76 | 82 | return err; |
| 77 | 83 | } |
| @@ -95,6 +101,7 @@ static int xen_suspend(void *data) · 17 unmodified lines | ||
| 95 | 101 | xen_timer_resume(); |
| 96 | 102 | } |
| 97 | 103 | |
| 104 | + syscore_resume(); | |
| 98 | 105 | sysdev_resume(); |
| 99 | 106 | |
| 100 | 107 | return 0; |
| @@ -178,12 +178,13 @@ static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name, · 177 unmodified lines | ||
| 178 | 178 | |
| 179 | 179 | if (value) { |
| 180 | 180 | acl = posix_acl_from_xattr(value, size); |
| 181 | + if (IS_ERR(acl)) | |
| 182 | + return PTR_ERR(acl); | |
| 183 | + | |
| 181 | 184 | if (acl) { |
| 182 | 185 | ret = posix_acl_valid(acl); |
| 183 | 186 | if (ret) |
| 184 | 187 | goto out; |
| 185 | − } else if (IS_ERR(acl)) { | |
| 186 | − return PTR_ERR(acl); | |
| 187 | 188 | } |
| 188 | 189 | } |
| 189 | 190 | |
| @@ -718,7 +718,7 @@ struct btrfs_space_info { · 717 unmodified lines | ||
| 718 | 718 | u64 total_bytes; /* total bytes in the space, |
| 719 | 719 | this doesn't take mirrors into account */ |
| 720 | 720 | u64 bytes_used; /* total bytes used, |
| 721 | − this does't take mirrors into account */ | |
| 721 | + this doesn't take mirrors into account */ | |
| 722 | 722 | u64 bytes_pinned; /* total bytes pinned, will be freed when the |
| 723 | 723 | transaction finishes */ |
| 724 | 724 | u64 bytes_reserved; /* total bytes the allocator has reserved for |
| @@ -2824,6 +2824,7 @@ static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans, · 2823 unmodified lines | ||
| 2824 | 2824 | |
| 2825 | 2825 | spin_lock(&delayed_refs->lock); |
| 2826 | 2826 | if (delayed_refs->num_entries == 0) { |
| 2827 | + spin_unlock(&delayed_refs->lock); | |
| 2827 | 2828 | printk(KERN_INFO "delayed_refs has NO entry\n"); |
| 2828 | 2829 | return ret; |
| 2829 | 2830 | } |
| @@ -8059,6 +8059,10 @@ static noinline int relocate_one_extent(struct btrfs_root *extent_root, · 8058 unmodified lines | ||
| 8059 | 8059 | u64 group_start = group->key.objectid; |
| 8060 | 8060 | new_extents = kmalloc(sizeof(*new_extents), |
| 8061 | 8061 | GFP_NOFS); |
| 8062 | + if (!new_extents) { | |
| 8063 | + ret = -ENOMEM; | |
| 8064 | + goto out; | |
| 8065 | + } | |
| 8062 | 8066 | nr_extents = 1; |
| 8063 | 8067 | ret = get_new_locations(reloc_inode, |
| 8064 | 8068 | extent_key, |
| @@ -8852,23 +8856,38 @@ out: · 787 unmodified lines | ||
| 8852 | 8856 | int btrfs_init_space_info(struct btrfs_fs_info *fs_info) |
| 8853 | 8857 | { |
| 8854 | 8858 | struct btrfs_space_info *space_info; |
| 8859 | + struct btrfs_super_block *disk_super; | |
| 8860 | + u64 features; | |
| 8861 | + u64 flags; | |
| 8862 | + int mixed = 0; | |
| 8855 | 8863 | int ret; |
| 8856 | 8864 | |
| 8857 | − ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_SYSTEM, 0, 0, | |
| 8858 | − &space_info); | |
| 8859 | − if (ret) | |
| 8860 | − return ret; | |
| 8865 | + disk_super = &fs_info->super_copy; | |
| 8866 | + if (!btrfs_super_root(disk_super)) | |
| 8867 | + return 1; | |
| 8861 | 8868 | |
| 8862 | − ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA, 0, 0, | |
| 8863 | − &space_info); | |
| 8864 | − if (ret) | |
| 8865 | − return ret; | |
| 8869 | + features = btrfs_super_incompat_flags(disk_super); | |
| 8870 | + if (features & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS) | |
| 8871 | + mixed = 1; | |
| 8866 | 8872 | |
| 8867 | − ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_DATA, 0, 0, | |
| 8868 | − &space_info); | |
| 8873 | + flags = BTRFS_BLOCK_GROUP_SYSTEM; | |
| 8874 | + ret = update_space_info(fs_info, flags, 0, 0, &space_info); | |
| 8869 | 8875 | if (ret) |
| 8870 | − return ret; | |
| 8876 | + goto out; | |
| 8871 | 8877 | |
| 8878 | + if (mixed) { | |
| 8879 | + flags = BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_DATA; | |
| 8880 | + ret = update_space_info(fs_info, flags, 0, 0, &space_info); | |
| 8881 | + } else { | |
| 8882 | + flags = BTRFS_BLOCK_GROUP_METADATA; | |
| 8883 | + ret = update_space_info(fs_info, flags, 0, 0, &space_info); | |
| 8884 | + if (ret) | |
| 8885 | + goto out; | |
| 8886 | + | |
| 8887 | + flags = BTRFS_BLOCK_GROUP_DATA; | |
| 8888 | + ret = update_space_info(fs_info, flags, 0, 0, &space_info); | |
| 8889 | + } | |
| 8890 | +out: | |
| 8872 | 8891 | return ret; |
| 8873 | 8892 | } |
| 8874 | 8893 | |
| @@ -2681,7 +2681,7 @@ int extent_readpages(struct extent_io_tree *tree, · 2680 unmodified lines | ||
| 2681 | 2681 | prefetchw(&page->flags); |
| 2682 | 2682 | list_del(&page->lru); |
| 2683 | 2683 | if (!add_to_page_cache_lru(page, mapping, |
| 2684 | − page->index, GFP_KERNEL)) { | |
| 2684 | + page->index, GFP_NOFS)) { | |
| 2685 | 2685 | __extent_read_full_page(tree, page, get_extent, |
| 2686 | 2686 | &bio, 0, &bio_flags); |
| 2687 | 2687 | } |
| @@ -1768,10 +1768,13 @@ void btrfs_remove_free_space_cache(struct btrfs_block_group_cache *block_group) · 1767 unmodified lines | ||
| 1768 | 1768 | |
| 1769 | 1769 | while ((node = rb_last(&block_group->free_space_offset)) != NULL) { |
| 1770 | 1770 | info = rb_entry(node, struct btrfs_free_space, offset_index); |
| 1771 | − unlink_free_space(block_group, info); | |
| 1772 | − if (info->bitmap) | |
| 1773 | − kfree(info->bitmap); | |
| 1774 | − kmem_cache_free(btrfs_free_space_cachep, info); | |
| 1771 | + if (!info->bitmap) { | |
| 1772 | + unlink_free_space(block_group, info); | |
| 1773 | + kmem_cache_free(btrfs_free_space_cachep, info); | |
| 1774 | + } else { | |
| 1775 | + free_bitmap(block_group, info); | |
| 1776 | + } | |
| 1777 | + | |
| 1775 | 1778 | if (need_resched()) { |
| 1776 | 1779 | spin_unlock(&block_group->tree_lock); |
| 1777 | 1780 | cond_resched(); |
| @@ -2301,7 +2304,7 @@ int btrfs_trim_block_group(struct btrfs_block_group_cache *block_group, · 523 unmodified lines | ||
| 2301 | 2304 | start = entry->offset; |
| 2302 | 2305 | bytes = min(entry->bytes, end - start); |
| 2303 | 2306 | unlink_free_space(block_group, entry); |
| 2304 | − kfree(entry); | |
| 2307 | + kmem_cache_free(btrfs_free_space_cachep, entry); | |
| 2305 | 2308 | } |
| 2306 | 2309 | |
| 2307 | 2310 | spin_unlock(&block_group->tree_lock); |
| @@ -954,6 +954,7 @@ static int cow_file_range_async(struct inode *inode, struct page *locked_page, · 953 unmodified lines | ||
| 954 | 954 | 1, 0, NULL, GFP_NOFS); |
| 955 | 955 | while (start < end) { |
| 956 | 956 | async_cow = kmalloc(sizeof(*async_cow), GFP_NOFS); |
| 957 | + BUG_ON(!async_cow); | |
| 957 | 958 | async_cow->inode = inode; |
| 958 | 959 | async_cow->root = root; |
| 959 | 960 | async_cow->locked_page = locked_page; |
| @@ -4731,9 +4732,10 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, · 3771 unmodified lines | ||
| 4731 | 4732 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, |
| 4732 | 4733 | dentry->d_name.len, dir->i_ino, objectid, |
| 4733 | 4734 | BTRFS_I(dir)->block_group, mode, &index); |
| 4734 | − err = PTR_ERR(inode); | |
| 4735 | − if (IS_ERR(inode)) | |
| 4735 | + if (IS_ERR(inode)) { | |
| 4736 | + err = PTR_ERR(inode); | |
| 4736 | 4737 | goto out_unlock; |
| 4738 | + } | |
| 4737 | 4739 | |
| 4738 | 4740 | err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); |
| 4739 | 4741 | if (err) { |
| @@ -4792,9 +4794,10 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, · 52 unmodified lines | ||
| 4792 | 4794 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, |
| 4793 | 4795 | dentry->d_name.len, dir->i_ino, objectid, |
| 4794 | 4796 | BTRFS_I(dir)->block_group, mode, &index); |
| 4795 | − err = PTR_ERR(inode); | |
| 4796 | − if (IS_ERR(inode)) | |
| 4797 | + if (IS_ERR(inode)) { | |
| 4798 | + err = PTR_ERR(inode); | |
| 4797 | 4799 | goto out_unlock; |
| 4800 | + } | |
| 4798 | 4801 | |
| 4799 | 4802 | err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); |
| 4800 | 4803 | if (err) { |
| @@ -4999,6 +5002,8 @@ static noinline int uncompress_inline(struct btrfs_path *path, · 198 unmodified lines | ||
| 4999 | 5002 | inline_size = btrfs_file_extent_inline_item_len(leaf, |
| 5000 | 5003 | btrfs_item_nr(leaf, path->slots[0])); |
| 5001 | 5004 | tmp = kmalloc(inline_size, GFP_NOFS); |
| 5005 | + if (!tmp) | |
| 5006 | + return -ENOMEM; | |
| 5002 | 5007 | ptr = btrfs_file_extent_inline_start(item); |
| 5003 | 5008 | |
| 5004 | 5009 | read_extent_buffer(leaf, tmp, ptr, inline_size); |
| @@ -6036,7 +6041,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, · 1031 unmodified lines | ||
| 6036 | 6041 | ret = btrfs_map_block(map_tree, READ, start_sector << 9, |
| 6037 | 6042 | &map_length, NULL, 0); |
| 6038 | 6043 | if (ret) { |
| 6039 | − bio_put(bio); | |
| 6044 | + bio_put(orig_bio); | |
| 6040 | 6045 | return -EIO; |
| 6041 | 6046 | } |
| 6042 | 6047 | |
| @@ -7273,9 +7278,10 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, · 1230 unmodified lines | ||
| 7273 | 7278 | dentry->d_name.len, dir->i_ino, objectid, |
| 7274 | 7279 | BTRFS_I(dir)->block_group, S_IFLNK|S_IRWXUGO, |
| 7275 | 7280 | &index); |
| 7276 | − err = PTR_ERR(inode); | |
| 7277 | − if (IS_ERR(inode)) | |
| 7281 | + if (IS_ERR(inode)) { | |
| 7282 | + err = PTR_ERR(inode); | |
| 7278 | 7283 | goto out_unlock; |
| 7284 | + } | |
| 7279 | 7285 | |
| 7280 | 7286 | err = btrfs_init_inode_security(trans, inode, dir, &dentry->d_name); |
| 7281 | 7287 | if (err) { |
| @@ -81,6 +81,13 @@ static unsigned int btrfs_flags_to_ioctl(unsigned int flags) · 80 unmodified lines | ||
| 81 | 81 | iflags |= FS_NOATIME_FL; |
| 82 | 82 | if (flags & BTRFS_INODE_DIRSYNC) |
| 83 | 83 | iflags |= FS_DIRSYNC_FL; |
| 84 | + if (flags & BTRFS_INODE_NODATACOW) | |
| 85 | + iflags |= FS_NOCOW_FL; | |
| 86 | + | |
| 87 | + if ((flags & BTRFS_INODE_COMPRESS) && !(flags & BTRFS_INODE_NOCOMPRESS)) | |
| 88 | + iflags |= FS_COMPR_FL; | |
| 89 | + else if (flags & BTRFS_INODE_NOCOMPRESS) | |
| 90 | + iflags |= FS_NOCOMP_FL; | |
| 84 | 91 | |
| 85 | 92 | return iflags; |
| 86 | 93 | } |
| @@ -144,16 +151,13 @@ static int check_flags(unsigned int flags) · 57 unmodified lines | ||
| 144 | 151 | if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \ |
| 145 | 152 | FS_NOATIME_FL | FS_NODUMP_FL | \ |
| 146 | 153 | FS_SYNC_FL | FS_DIRSYNC_FL | \ |
| 147 | − FS_NOCOMP_FL | FS_COMPR_FL | \ | |
| 148 | − FS_NOCOW_FL | FS_COW_FL)) | |
| 154 | + FS_NOCOMP_FL | FS_COMPR_FL | | |
| 155 | + FS_NOCOW_FL)) | |
| 149 | 156 | return -EOPNOTSUPP; |
| 150 | 157 | |
| 151 | 158 | if ((flags & FS_NOCOMP_FL) && (flags & FS_COMPR_FL)) |
| 152 | 159 | return -EINVAL; |
| 153 | 160 | |
| 154 | − if ((flags & FS_NOCOW_FL) && (flags & FS_COW_FL)) | |
| 155 | − return -EINVAL; | |
| 156 | − | |
| 157 | 161 | return 0; |
| 158 | 162 | } |
| 159 | 163 | |
| @@ -218,6 +222,10 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) · 58 unmodified lines | ||
| 218 | 222 | ip->flags |= BTRFS_INODE_DIRSYNC; |
| 219 | 223 | else |
| 220 | 224 | ip->flags &= ~BTRFS_INODE_DIRSYNC; |
| 225 | + if (flags & FS_NOCOW_FL) | |
| 226 | + ip->flags |= BTRFS_INODE_NODATACOW; | |
| 227 | + else | |
| 228 | + ip->flags &= ~BTRFS_INODE_NODATACOW; | |
| 221 | 229 | |
| 222 | 230 | /* |
| 223 | 231 | * The COMPRESS flag can only be changed by users, while the NOCOMPRESS |
| @@ -230,11 +238,9 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) · 6 unmodified lines | ||
| 230 | 238 | } else if (flags & FS_COMPR_FL) { |
| 231 | 239 | ip->flags |= BTRFS_INODE_COMPRESS; |
| 232 | 240 | ip->flags &= ~BTRFS_INODE_NOCOMPRESS; |
| 241 | + } else { | |
| 242 | + ip->flags &= ~(BTRFS_INODE_COMPRESS | BTRFS_INODE_NOCOMPRESS); | |
| 233 | 243 | } |
| 234 | − if (flags & FS_NOCOW_FL) | |
| 235 | − ip->flags |= BTRFS_INODE_NODATACOW; | |
| 236 | − else if (flags & FS_COW_FL) | |
| 237 | − ip->flags &= ~BTRFS_INODE_NODATACOW; | |
| 238 | 244 | |
| 239 | 245 | trans = btrfs_join_transaction(root, 1); |
| 240 | 246 | BUG_ON(IS_ERR(trans)); |
| @@ -2209,8 +2209,10 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans, · 2208 unmodified lines | ||
| 2209 | 2209 | |
| 2210 | 2210 | log = root->log_root; |
| 2211 | 2211 | path = btrfs_alloc_path(); |
| 2212 | − if (!path) | |
| 2213 | − return -ENOMEM; | |
| 2212 | + if (!path) { | |
| 2213 | + err = -ENOMEM; | |
| 2214 | + goto out_unlock; | |
| 2215 | + } | |
| 2214 | 2216 | |
| 2215 | 2217 | di = btrfs_lookup_dir_item(trans, log, path, dir->i_ino, |
| 2216 | 2218 | name, name_len, -1); |
| @@ -2271,6 +2273,7 @@ int btrfs_del_dir_entries_in_log(struct btrfs_trans_handle *trans, · 54 unmodified lines | ||
| 2271 | 2273 | } |
| 2272 | 2274 | fail: |
| 2273 | 2275 | btrfs_free_path(path); |
| 2276 | +out_unlock: | |
| 2274 | 2277 | mutex_unlock(&BTRFS_I(dir)->log_mutex); |
| 2275 | 2278 | if (ret == -ENOSPC) { |
| 2276 | 2279 | root->fs_info->last_trans_log_full_commit = trans->transid; |
| @@ -155,6 +155,15 @@ static noinline int run_scheduled_bios(struct btrfs_device *device) · 154 unmodified lines | ||
| 155 | 155 | unsigned long limit; |
| 156 | 156 | unsigned long last_waited = 0; |
| 157 | 157 | int force_reg = 0; |
| 158 | + struct blk_plug plug; | |
| 159 | + | |
| 160 | + /* | |
| 161 | + * this function runs all the bios we've collected for | |
| 162 | + * a particular device. We don't want to wander off to | |
| 163 | + * another device without first sending all of these down. | |
| 164 | + * So, setup a plug here and finish it off before we return | |
| 165 | + */ | |
| 166 | + blk_start_plug(&plug); | |
| 158 | 167 | |
| 159 | 168 | bdi = blk_get_backing_dev_info(device->bdev); |
| 160 | 169 | fs_info = device->dev_root->fs_info; |
| @@ -294,6 +303,7 @@ loop_lock: · 133 unmodified lines | ||
| 294 | 303 | spin_unlock(&device->io_lock); |
| 295 | 304 | |
| 296 | 305 | done: |
| 306 | + blk_finish_plug(&plug); | |
| 297 | 307 | return 0; |
| 298 | 308 | } |
| 299 | 309 | |
| @@ -775,6 +775,13 @@ get_more_pages: · 774 unmodified lines | ||
| 775 | 775 | ci->i_truncate_seq, |
| 776 | 776 | ci->i_truncate_size, |
| 777 | 777 | &inode->i_mtime, true, 1, 0); |
| 778 | + | |
| 779 | + if (!req) { | |
| 780 | + rc = -ENOMEM; | |
| 781 | + unlock_page(page); | |
| 782 | + break; | |
| 783 | + } | |
| 784 | + | |
| 778 | 785 | max_pages = req->r_num_pages; |
| 779 | 786 | |
| 780 | 787 | alloc_page_vec(fsc, req); |
| @@ -819,7 +819,7 @@ int __ceph_caps_used(struct ceph_inode_info *ci) · 818 unmodified lines | ||
| 819 | 819 | used |= CEPH_CAP_FILE_CACHE; |
| 820 | 820 | if (ci->i_wr_ref) |
| 821 | 821 | used |= CEPH_CAP_FILE_WR; |
| 822 | − if (ci->i_wrbuffer_ref) | |
| 822 | + if (ci->i_wb_ref || ci->i_wrbuffer_ref) | |
| 823 | 823 | used |= CEPH_CAP_FILE_BUFFER; |
| 824 | 824 | return used; |
| 825 | 825 | } |
| @@ -1331,10 +1331,11 @@ static void ceph_flush_snaps(struct ceph_inode_info *ci) · 505 unmodified lines | ||
| 1331 | 1331 | } |
| 1332 | 1332 | |
| 1333 | 1333 | /* |
| 1334 | − * Mark caps dirty. If inode is newly dirty, add to the global dirty | |
| 1335 | − * list. | |
| 1334 | + * Mark caps dirty. If inode is newly dirty, return the dirty flags. | |
| 1335 | + * Caller is then responsible for calling __mark_inode_dirty with the | |
| 1336 | + * returned flags value. | |
| 1336 | 1337 | */ |
| 1337 | −void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask) | |
| 1338 | +int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask) | |
| 1338 | 1339 | { |
| 1339 | 1340 | struct ceph_mds_client *mdsc = |
| 1340 | 1341 | ceph_sb_to_client(ci->vfs_inode.i_sb)->mdsc; |
| @@ -1357,7 +1358,7 @@ void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask) · 16 unmodified lines | ||
| 1357 | 1358 | list_add(&ci->i_dirty_item, &mdsc->cap_dirty); |
| 1358 | 1359 | spin_unlock(&mdsc->cap_dirty_lock); |
| 1359 | 1360 | if (ci->i_flushing_caps == 0) { |
| 1360 | − igrab(inode); | |
| 1361 | + ihold(inode); | |
| 1361 | 1362 | dirty |= I_DIRTY_SYNC; |
| 1362 | 1363 | } |
| 1363 | 1364 | } |
| @@ -1365,9 +1366,8 @@ void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask) · 1 unmodified line | ||
| 1365 | 1366 | if (((was | ci->i_flushing_caps) & CEPH_CAP_FILE_BUFFER) && |
| 1366 | 1367 | (mask & CEPH_CAP_FILE_BUFFER)) |
| 1367 | 1368 | dirty |= I_DIRTY_DATASYNC; |
| 1368 | − if (dirty) | |
| 1369 | − __mark_inode_dirty(inode, dirty); | |
| 1370 | 1369 | __cap_delay_requeue(mdsc, ci); |
| 1370 | + return dirty; | |
| 1371 | 1371 | } |
| 1372 | 1372 | |
| 1373 | 1373 | /* |
| @@ -1990,11 +1990,11 @@ static void __take_cap_refs(struct ceph_inode_info *ci, int got) · 616 unmodified lines | ||
| 1990 | 1990 | if (got & CEPH_CAP_FILE_WR) |
| 1991 | 1991 | ci->i_wr_ref++; |
| 1992 | 1992 | if (got & CEPH_CAP_FILE_BUFFER) { |
| 1993 | − if (ci->i_wrbuffer_ref == 0) | |
| 1994 | − igrab(&ci->vfs_inode); | |
| 1995 | − ci->i_wrbuffer_ref++; | |
| 1996 | − dout("__take_cap_refs %p wrbuffer %d -> %d (?)\n", | |
| 1997 | − &ci->vfs_inode, ci->i_wrbuffer_ref-1, ci->i_wrbuffer_ref); | |
| 1993 | + if (ci->i_wb_ref == 0) | |
| 1994 | + ihold(&ci->vfs_inode); | |
| 1995 | + ci->i_wb_ref++; | |
| 1996 | + dout("__take_cap_refs %p wb %d -> %d (?)\n", | |
| 1997 | + &ci->vfs_inode, ci->i_wb_ref-1, ci->i_wb_ref); | |
| 1998 | 1998 | } |
| 1999 | 1999 | } |
| 2000 | 2000 | |
| @@ -2169,12 +2169,12 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had) · 168 unmodified lines | ||
| 2169 | 2169 | if (--ci->i_rdcache_ref == 0) |
| 2170 | 2170 | last++; |
| 2171 | 2171 | if (had & CEPH_CAP_FILE_BUFFER) { |
| 2172 | − if (--ci->i_wrbuffer_ref == 0) { | |
| 2172 | + if (--ci->i_wb_ref == 0) { | |
| 2173 | 2173 | last++; |
| 2174 | 2174 | put++; |
| 2175 | 2175 | } |
| 2176 | − dout("put_cap_refs %p wrbuffer %d -> %d (?)\n", | |
| 2177 | − inode, ci->i_wrbuffer_ref+1, ci->i_wrbuffer_ref); | |
| 2176 | + dout("put_cap_refs %p wb %d -> %d (?)\n", | |
| 2177 | + inode, ci->i_wb_ref+1, ci->i_wb_ref); | |
| 2178 | 2178 | } |
| 2179 | 2179 | if (had & CEPH_CAP_FILE_WR) |
| 2180 | 2180 | if (--ci->i_wr_ref == 0) { |
| @@ -734,9 +734,12 @@ retry_snap: · 733 unmodified lines | ||
| 734 | 734 | } |
| 735 | 735 | } |
| 736 | 736 | if (ret >= 0) { |
| 737 | + int dirty; | |
| 737 | 738 | spin_lock(&inode->i_lock); |
| 738 | − __ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR); | |
| 739 | + dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_FILE_WR); | |
| 739 | 740 | spin_unlock(&inode->i_lock); |
| 741 | + if (dirty) | |
| 742 | + __mark_inode_dirty(inode, dirty); | |
| 740 | 743 | } |
| 741 | 744 | |
| 742 | 745 | out: |
| @@ -355,6 +355,7 @@ struct inode *ceph_alloc_inode(struct super_block *sb) · 354 unmodified lines | ||
| 355 | 355 | ci->i_rd_ref = 0; |
| 356 | 356 | ci->i_rdcache_ref = 0; |
| 357 | 357 | ci->i_wr_ref = 0; |
| 358 | + ci->i_wb_ref = 0; | |
| 358 | 359 | ci->i_wrbuffer_ref = 0; |
| 359 | 360 | ci->i_wrbuffer_ref_head = 0; |
| 360 | 361 | ci->i_shared_gen = 0; |
| @@ -1567,6 +1568,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) · 1206 unmodified lines | ||
| 1567 | 1568 | int release = 0, dirtied = 0; |
| 1568 | 1569 | int mask = 0; |
| 1569 | 1570 | int err = 0; |
| 1571 | + int inode_dirty_flags = 0; | |
| 1570 | 1572 | |
| 1571 | 1573 | if (ceph_snap(inode) != CEPH_NOSNAP) |
| 1572 | 1574 | return -EROFS; |
| @@ -1725,13 +1727,16 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) · 152 unmodified lines | ||
| 1725 | 1727 | dout("setattr %p ATTR_FILE ... hrm!\n", inode); |
| 1726 | 1728 | |
| 1727 | 1729 | if (dirtied) { |
| 1728 | − __ceph_mark_dirty_caps(ci, dirtied); | |
| 1730 | + inode_dirty_flags = __ceph_mark_dirty_caps(ci, dirtied); | |
| 1729 | 1731 | inode->i_ctime = CURRENT_TIME; |
| 1730 | 1732 | } |
| 1731 | 1733 | |
| 1732 | 1734 | release &= issued; |
| 1733 | 1735 | spin_unlock(&inode->i_lock); |
| 1734 | 1736 | |
| 1737 | + if (inode_dirty_flags) | |
| 1738 | + __mark_inode_dirty(inode, inode_dirty_flags); | |
| 1739 | + | |
| 1735 | 1740 | if (mask) { |
| 1736 | 1741 | req->r_inode = igrab(inode); |
| 1737 | 1742 | req->r_inode_drop = release; |
| @@ -3304,8 +3304,8 @@ static void con_put(struct ceph_connection *con) · 3303 unmodified lines | ||
| 3304 | 3304 | { |
| 3305 | 3305 | struct ceph_mds_session *s = con->private; |
| 3306 | 3306 | |
| 3307 | + dout("mdsc con_put %p (%d)\n", s, atomic_read(&s->s_ref) - 1); | |
| 3307 | 3308 | ceph_put_mds_session(s); |
| 3308 | − dout("mdsc con_put %p (%d)\n", s, atomic_read(&s->s_ref)); | |
| 3309 | 3309 | } |
| 3310 | 3310 | |
| 3311 | 3311 | /* |
| @@ -206,7 +206,7 @@ void ceph_put_snap_realm(struct ceph_mds_client *mdsc, · 205 unmodified lines | ||
| 206 | 206 | up_write(&mdsc->snap_rwsem); |
| 207 | 207 | } else { |
| 208 | 208 | spin_lock(&mdsc->snap_empty_lock); |
| 209 | − list_add(&mdsc->snap_empty, &realm->empty_item); | |
| 209 | + list_add(&realm->empty_item, &mdsc->snap_empty); | |
| 210 | 210 | spin_unlock(&mdsc->snap_empty_lock); |
| 211 | 211 | } |
| 212 | 212 | } |
| @@ -293,7 +293,7 @@ struct ceph_inode_info { · 292 unmodified lines | ||
| 293 | 293 | |
| 294 | 294 | /* held references to caps */ |
| 295 | 295 | int i_pin_ref; |
| 296 | − int i_rd_ref, i_rdcache_ref, i_wr_ref; | |
| 296 | + int i_rd_ref, i_rdcache_ref, i_wr_ref, i_wb_ref; | |
| 297 | 297 | int i_wrbuffer_ref, i_wrbuffer_ref_head; |
| 298 | 298 | u32 i_shared_gen; /* increment each time we get FILE_SHARED */ |
| 299 | 299 | u32 i_rdcache_gen; /* incremented each time we get FILE_CACHE. */ |
| @@ -506,7 +506,7 @@ static inline int __ceph_caps_dirty(struct ceph_inode_info *ci) · 206 unmodified lines | ||
| 506 | 506 | { |
| 507 | 507 | return ci->i_dirty_caps | ci->i_flushing_caps; |
| 508 | 508 | } |
| 509 | −extern void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask); | |
| 509 | +extern int __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask); | |
| 510 | 510 | |
| 511 | 511 | extern int ceph_caps_revoking(struct ceph_inode_info *ci, int mask); |
| 512 | 512 | extern int __ceph_caps_used(struct ceph_inode_info *ci); |
| @@ -703,6 +703,7 @@ int ceph_setxattr(struct dentry *dentry, const char *name, · 702 unmodified lines | ||
| 703 | 703 | struct ceph_inode_xattr *xattr = NULL; |
| 704 | 704 | int issued; |
| 705 | 705 | int required_blob_size; |
| 706 | + int dirty; | |
| 706 | 707 | |
| 707 | 708 | if (ceph_snap(inode) != CEPH_NOSNAP) |
| 708 | 709 | return -EROFS; |
| @@ -763,11 +764,12 @@ retry: · 54 unmodified lines | ||
| 763 | 764 | dout("setxattr %p issued %s\n", inode, ceph_cap_string(issued)); |
| 764 | 765 | err = __set_xattr(ci, newname, name_len, newval, |
| 765 | 766 | val_len, 1, 1, 1, &xattr); |
| 766 | − __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL); | |
| 767 | + dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL); | |
| 767 | 768 | ci->i_xattrs.dirty = true; |
| 768 | 769 | inode->i_ctime = CURRENT_TIME; |
| 769 | 770 | spin_unlock(&inode->i_lock); |
| 770 | − | |
| 771 | + if (dirty) | |
| 772 | + __mark_inode_dirty(inode, dirty); | |
| 771 | 773 | return err; |
| 772 | 774 | |
| 773 | 775 | do_sync: |
| @@ -810,6 +812,7 @@ int ceph_removexattr(struct dentry *dentry, const char *name) · 36 unmodified lines | ||
| 810 | 812 | struct ceph_vxattr_cb *vxattrs = ceph_inode_vxattrs(inode); |
| 811 | 813 | int issued; |
| 812 | 814 | int err; |
| 815 | + int dirty; | |
| 813 | 816 | |
| 814 | 817 | if (ceph_snap(inode) != CEPH_NOSNAP) |
| 815 | 818 | return -EROFS; |
| @@ -833,12 +836,13 @@ int ceph_removexattr(struct dentry *dentry, const char *name) · 17 unmodified lines | ||
| 833 | 836 | goto do_sync; |
| 834 | 837 | |
| 835 | 838 | err = __remove_xattr_by_name(ceph_inode(inode), name); |
| 836 | − __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL); | |
| 839 | + dirty = __ceph_mark_dirty_caps(ci, CEPH_CAP_XATTR_EXCL); | |
| 837 | 840 | ci->i_xattrs.dirty = true; |
| 838 | 841 | inode->i_ctime = CURRENT_TIME; |
| 839 | 842 | |
| 840 | 843 | spin_unlock(&inode->i_lock); |
| 841 | − | |
| 844 | + if (dirty) | |
| 845 | + __mark_inode_dirty(inode, dirty); | |
| 842 | 846 | return err; |
| 843 | 847 | do_sync: |
| 844 | 848 | spin_unlock(&inode->i_lock); |
| @@ -277,6 +277,7 @@ cifsConvertToUCS(__le16 *target, const char *source, int srclen, · 276 unmodified lines | ||
| 277 | 277 | |
| 278 | 278 | for (i = 0, j = 0; i < srclen; j++) { |
| 279 | 279 | src_char = source[i]; |
| 280 | + charlen = 1; | |
| 280 | 281 | switch (src_char) { |
| 281 | 282 | case 0: |
| 282 | 283 | put_unaligned(0, &target[j]); |
| @@ -316,16 +317,13 @@ cifsConvertToUCS(__le16 *target, const char *source, int srclen, · 33 unmodified lines | ||
| 316 | 317 | dst_char = cpu_to_le16(0x003f); |
| 317 | 318 | charlen = 1; |
| 318 | 319 | } |
| 319 | − /* | |
| 320 | − * character may take more than one byte in the source | |
| 321 | − * string, but will take exactly two bytes in the | |
| 322 | − * target string | |
| 323 | − */ | |
| 324 | − i += charlen; | |
| 325 | − continue; | |
| 326 | 320 | } |
| 321 | + /* | |
| 322 | + * character may take more than one byte in the source string, | |
| 323 | + * but will take exactly two bytes in the target string | |
| 324 | + */ | |
| 325 | + i += charlen; | |
| 327 | 326 | put_unaligned(dst_char, &target[j]); |
| 328 | − i++; /* move to next char in source string */ | |
| 329 | 327 | } |
| 330 | 328 | |
| 331 | 329 | ctoUCS_out: |
| @@ -274,7 +274,8 @@ static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB) · 273 unmodified lines | ||
| 274 | 274 | char *data_area_of_target; |
| 275 | 275 | char *data_area_of_buf2; |
| 276 | 276 | int remaining; |
| 277 | − __u16 byte_count, total_data_size, total_in_buf, total_in_buf2; | |
| 277 | + unsigned int byte_count, total_in_buf; | |
| 278 | + __u16 total_data_size, total_in_buf2; | |
| 278 | 279 | |
| 279 | 280 | total_data_size = get_unaligned_le16(&pSMBt->t2_rsp.TotalDataCount); |
| 280 | 281 | |
| @@ -287,7 +288,7 @@ static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB) · 6 unmodified lines | ||
| 287 | 288 | remaining = total_data_size - total_in_buf; |
| 288 | 289 | |
| 289 | 290 | if (remaining < 0) |
| 290 | − return -EINVAL; | |
| 291 | + return -EPROTO; | |
| 291 | 292 | |
| 292 | 293 | if (remaining == 0) /* nothing to do, ignore */ |
| 293 | 294 | return 0; |
| @@ -308,20 +309,29 @@ static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB) · 14 unmodified lines | ||
| 308 | 309 | data_area_of_target += total_in_buf; |
| 309 | 310 | |
| 310 | 311 | /* copy second buffer into end of first buffer */ |
| 311 | − memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2); | |
| 312 | 312 | total_in_buf += total_in_buf2; |
| 313 | + /* is the result too big for the field? */ | |
| 314 | + if (total_in_buf > USHRT_MAX) | |
| 315 | + return -EPROTO; | |
| 313 | 316 | put_unaligned_le16(total_in_buf, &pSMBt->t2_rsp.DataCount); |
| 317 | + | |
| 318 | + /* fix up the BCC */ | |
| 314 | 319 | byte_count = get_bcc_le(pTargetSMB); |
| 315 | 320 | byte_count += total_in_buf2; |
| 321 | + /* is the result too big for the field? */ | |
| 322 | + if (byte_count > USHRT_MAX) | |
| 323 | + return -EPROTO; | |
| 316 | 324 | put_bcc_le(byte_count, pTargetSMB); |
| 317 | 325 | |
| 318 | 326 | byte_count = pTargetSMB->smb_buf_length; |
| 319 | 327 | byte_count += total_in_buf2; |
| 320 | − | |
| 321 | − /* BB also add check that we are not beyond maximum buffer size */ | |
| 322 | − | |
| 328 | + /* don't allow buffer to overflow */ | |
| 329 | + if (byte_count > CIFSMaxBufSize) | |
| 330 | + return -ENOBUFS; | |
| 323 | 331 | pTargetSMB->smb_buf_length = byte_count; |
| 324 | 332 | |
| 333 | + memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2); | |
| 334 | + | |
| 325 | 335 | if (remaining == total_in_buf2) { |
| 326 | 336 | cFYI(1, "found the last secondary response"); |
| 327 | 337 | return 0; /* we are done */ |
| @@ -607,59 +617,63 @@ incomplete_rcv: · 279 unmodified lines | ||
| 607 | 617 | list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { |
| 608 | 618 | mid_entry = list_entry(tmp, struct mid_q_entry, qhead); |
| 609 | 619 | |
| 610 | − if ((mid_entry->mid == smb_buffer->Mid) && | |
| 611 | − (mid_entry->midState == MID_REQUEST_SUBMITTED) && | |
| 612 | − (mid_entry->command == smb_buffer->Command)) { | |
| 613 | − if (length == 0 && | |
| 614 | − check2ndT2(smb_buffer, server->maxBuf) > 0) { | |
| 615 | − /* We have a multipart transact2 resp */ | |
| 616 | − isMultiRsp = true; | |
| 617 | − if (mid_entry->resp_buf) { | |
| 618 | − /* merge response - fix up 1st*/ | |
| 619 | − if (coalesce_t2(smb_buffer, | |
| 620 | − mid_entry->resp_buf)) { | |
| 621 | − mid_entry->multiRsp = | |
| 622 | − true; | |
| 623 | − break; | |
| 624 | − } else { | |
| 625 | − /* all parts received */ | |
| 626 | − mid_entry->multiEnd = | |
| 627 | − true; | |
| 628 | − goto multi_t2_fnd; | |
| 629 | − } | |
| 620 | + if (mid_entry->mid != smb_buffer->Mid || | |
| 621 | + mid_entry->midState != MID_REQUEST_SUBMITTED || | |
| 622 | + mid_entry->command != smb_buffer->Command) { | |
| 623 | + mid_entry = NULL; | |
| 624 | + continue; | |
| 625 | + } | |
| 626 | + | |
| 627 | + if (length == 0 && | |
| 628 | + check2ndT2(smb_buffer, server->maxBuf) > 0) { | |
| 629 | + /* We have a multipart transact2 resp */ | |
| 630 | + isMultiRsp = true; | |
| 631 | + if (mid_entry->resp_buf) { | |
| 632 | + /* merge response - fix up 1st*/ | |
| 633 | + length = coalesce_t2(smb_buffer, | |
| 634 | + mid_entry->resp_buf); | |
| 635 | + if (length > 0) { | |
| 636 | + length = 0; | |
| 637 | + mid_entry->multiRsp = true; | |
| 638 | + break; | |
| 630 | 639 | } else { |
| 631 | − if (!isLargeBuf) { | |
| 632 | − cERROR(1, "1st trans2 resp needs bigbuf"); | |
| 633 | − /* BB maybe we can fix this up, switch | |
| 634 | − to already allocated large buffer? */ | |
| 635 | − } else { | |
| 636 | − /* Have first buffer */ | |
| 637 | − mid_entry->resp_buf = | |
| 638 | − smb_buffer; | |
| 639 | − mid_entry->largeBuf = | |
| 640 | − true; | |
| 641 | − bigbuf = NULL; | |
| 642 | − } | |
| 640 | + /* all parts received or | |
| 641 | + * packet is malformed | |
| 642 | + */ | |
| 643 | + mid_entry->multiEnd = true; | |
| 644 | + goto multi_t2_fnd; | |
| 645 | + } | |
| 646 | + } else { | |
| 647 | + if (!isLargeBuf) { | |
| 648 | + /* | |
| 649 | + * FIXME: switch to already | |
| 650 | + * allocated largebuf? | |
| 651 | + */ | |
| 652 | + cERROR(1, "1st trans2 resp " | |
| 653 | + "needs bigbuf"); | |
| 654 | + } else { | |
| 655 | + /* Have first buffer */ | |
| 656 | + mid_entry->resp_buf = | |
| 657 | + smb_buffer; | |
| 658 | + mid_entry->largeBuf = true; | |
| 659 | + bigbuf = NULL; | |
| 643 | 660 | } |
| 644 | − break; | |
| 645 | 661 | } |
| 646 | − mid_entry->resp_buf = smb_buffer; | |
| 647 | − mid_entry->largeBuf = isLargeBuf; | |
| 662 | + break; | |
| 663 | + } | |
| 664 | + mid_entry->resp_buf = smb_buffer; | |
| 665 | + mid_entry->largeBuf = isLargeBuf; | |
| 648 | 666 | multi_t2_fnd: |
| 649 | − if (length == 0) | |
| 650 | − mid_entry->midState = | |
| 651 | − MID_RESPONSE_RECEIVED; | |
| 652 | − else | |
| 653 | − mid_entry->midState = | |
| 654 | − MID_RESPONSE_MALFORMED; | |
| 667 | + if (length == 0) | |
| 668 | + mid_entry->midState = MID_RESPONSE_RECEIVED; | |
| 669 | + else | |
| 670 | + mid_entry->midState = MID_RESPONSE_MALFORMED; | |
| 655 | 671 | #ifdef CONFIG_CIFS_STATS2 |
| 656 | − mid_entry->when_received = jiffies; | |
| 672 | + mid_entry->when_received = jiffies; | |
| 657 | 673 | #endif |
| 658 | − list_del_init(&mid_entry->qhead); | |
| 659 | − mid_entry->callback(mid_entry); | |
| 660 | − break; | |
| 661 | − } | |
| 662 | − mid_entry = NULL; | |
| 674 | + list_del_init(&mid_entry->qhead); | |
| 675 | + mid_entry->callback(mid_entry); | |
| 676 | + break; | |
| 663 | 677 | } |
| 664 | 678 | spin_unlock(&GlobalMid_Lock); |
| 665 | 679 | |
| @@ -807,8 +821,7 @@ static int · 141 unmodified lines | ||
| 807 | 821 | cifs_parse_mount_options(char *options, const char *devname, |
| 808 | 822 | struct smb_vol *vol) |
| 809 | 823 | { |
| 810 | − char *value; | |
| 811 | − char *data; | |
| 824 | + char *value, *data, *end; | |
| 812 | 825 | unsigned int temp_len, i, j; |
| 813 | 826 | char separator[2]; |
| 814 | 827 | short int override_uid = -1; |
| @@ -851,6 +864,7 @@ cifs_parse_mount_options(char *options, const char *devname, · 36 unmodified lines | ||
| 851 | 864 | if (!options) |
| 852 | 865 | return 1; |
| 853 | 866 | |
| 867 | + end = options + strlen(options); | |
| 854 | 868 | if (strncmp(options, "sep=", 4) == 0) { |
| 855 | 869 | if (options[4] != 0) { |
| 856 | 870 | separator[0] = options[4]; |
| @@ -916,6 +930,7 @@ cifs_parse_mount_options(char *options, const char *devname, · 59 unmodified lines | ||
| 916 | 930 | the only illegal character in a password is null */ |
| 917 | 931 | |
| 918 | 932 | if ((value[temp_len] == 0) && |
| 933 | + (value + temp_len < end) && | |
| 919 | 934 | (value[temp_len+1] == separator[0])) { |
| 920 | 935 | /* reinsert comma */ |
| 921 | 936 | value[temp_len] = separator[0]; |
| @@ -2658,6 +2673,11 @@ is_path_accessible(int xid, struct cifsTconInfo *tcon, · 1736 unmodified lines | ||
| 2658 | 2673 | 0 /* not legacy */, cifs_sb->local_nls, |
| 2659 | 2674 | cifs_sb->mnt_cifs_flags & |
| 2660 | 2675 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
| 2676 | + | |
| 2677 | + if (rc == -EOPNOTSUPP || rc == -EINVAL) | |
| 2678 | + rc = SMBQueryInformation(xid, tcon, full_path, pfile_info, | |
| 2679 | + cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | |
| 2680 | + CIFS_MOUNT_MAP_SPECIAL_CHR); | |
| 2661 | 2681 | kfree(pfile_info); |
| 2662 | 2682 | return rc; |
| 2663 | 2683 | } |
| @@ -276,7 +276,7 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses, · 275 unmodified lines | ||
| 276 | 276 | } |
| 277 | 277 | |
| 278 | 278 | static void |
| 279 | −decode_unicode_ssetup(char **pbcc_area, __u16 bleft, struct cifsSesInfo *ses, | |
| 279 | +decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses, | |
| 280 | 280 | const struct nls_table *nls_cp) |
| 281 | 281 | { |
| 282 | 282 | int len; |
| @@ -284,19 +284,6 @@ decode_unicode_ssetup(char **pbcc_area, __u16 bleft, struct cifsSesInfo *ses, · 1 unmodified line | ||
| 284 | 284 | |
| 285 | 285 | cFYI(1, "bleft %d", bleft); |
| 286 | 286 | |
| 287 | − /* | |
| 288 | − * Windows servers do not always double null terminate their final | |
| 289 | − * Unicode string. Check to see if there are an uneven number of bytes | |
| 290 | − * left. If so, then add an extra NULL pad byte to the end of the | |
| 291 | − * response. | |
| 292 | − * | |
| 293 | − * See section 2.7.2 in "Implementing CIFS" for details | |
| 294 | − */ | |
| 295 | − if (bleft % 2) { | |
| 296 | − data[bleft] = 0; | |
| 297 | − ++bleft; | |
| 298 | − } | |
| 299 | − | |
| 300 | 287 | kfree(ses->serverOS); |
| 301 | 288 | ses->serverOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp); |
| 302 | 289 | cFYI(1, "serverOS=%s", ses->serverOS); |
| @@ -929,7 +916,9 @@ ssetup_ntlmssp_authenticate: · 626 unmodified lines | ||
| 929 | 916 | } |
| 930 | 917 | |
| 931 | 918 | /* BB check if Unicode and decode strings */ |
| 932 | − if (smb_buf->Flags2 & SMBFLG2_UNICODE) { | |
| 919 | + if (bytes_remaining == 0) { | |
| 920 | + /* no string area to decode, do nothing */ | |
| 921 | + } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) { | |
| 933 | 922 | /* unicode string area must be word-aligned */ |
| 934 | 923 | if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) { |
| 935 | 924 | ++bcc_ptr; |
| @@ -53,11 +53,14 @@ DEFINE_SPINLOCK(configfs_dirent_lock); · 52 unmodified lines | ||
| 53 | 53 | static void configfs_d_iput(struct dentry * dentry, |
| 54 | 54 | struct inode * inode) |
| 55 | 55 | { |
| 56 | − struct configfs_dirent * sd = dentry->d_fsdata; | |
| 56 | + struct configfs_dirent *sd = dentry->d_fsdata; | |
| 57 | 57 | |
| 58 | 58 | if (sd) { |
| 59 | 59 | BUG_ON(sd->s_dentry != dentry); |
| 60 | + /* Coordinate with configfs_readdir */ | |
| 61 | + spin_lock(&configfs_dirent_lock); | |
| 60 | 62 | sd->s_dentry = NULL; |
| 63 | + spin_unlock(&configfs_dirent_lock); | |
| 61 | 64 | configfs_put(sd); |
| 62 | 65 | } |
| 63 | 66 | iput(inode); |
| @@ -689,7 +692,8 @@ static int create_default_group(struct config_group *parent_group, · 625 unmodified lines | ||
| 689 | 692 | sd = child->d_fsdata; |
| 690 | 693 | sd->s_type |= CONFIGFS_USET_DEFAULT; |
| 691 | 694 | } else { |
| 692 | − d_delete(child); | |
| 695 | + BUG_ON(child->d_inode); | |
| 696 | + d_drop(child); | |
| 693 | 697 | dput(child); |
| 694 | 698 | } |
| 695 | 699 | } |
| @@ -1545,7 +1549,7 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir · 849 unmodified lines | ||
| 1545 | 1549 | struct configfs_dirent * parent_sd = dentry->d_fsdata; |
| 1546 | 1550 | struct configfs_dirent *cursor = filp->private_data; |
| 1547 | 1551 | struct list_head *p, *q = &cursor->s_sibling; |
| 1548 | − ino_t ino; | |
| 1552 | + ino_t ino = 0; | |
| 1549 | 1553 | int i = filp->f_pos; |
| 1550 | 1554 | |
| 1551 | 1555 | switch (i) { |
| @@ -1573,6 +1577,7 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir · 21 unmodified lines | ||
| 1573 | 1577 | struct configfs_dirent *next; |
| 1574 | 1578 | const char * name; |
| 1575 | 1579 | int len; |
| 1580 | + struct inode *inode = NULL; | |
| 1576 | 1581 | |
| 1577 | 1582 | next = list_entry(p, struct configfs_dirent, |
| 1578 | 1583 | s_sibling); |
| @@ -1581,9 +1586,28 @@ static int configfs_readdir(struct file * filp, void * dirent, filldir_t filldir · 2 unmodified lines | ||
| 1581 | 1586 | |
| 1582 | 1587 | name = configfs_get_name(next); |
| 1583 | 1588 | len = strlen(name); |
| 1584 | − if (next->s_dentry) | |
| 1585 | − ino = next->s_dentry->d_inode->i_ino; | |
| 1586 | − else | |
| 1589 | + | |
| 1590 | + /* | |
| 1591 | + * We'll have a dentry and an inode for | |
| 1592 | + * PINNED items and for open attribute | |
| 1593 | + * files. We lock here to prevent a race | |
| 1594 | + * with configfs_d_iput() clearing | |
| 1595 | + * s_dentry before calling iput(). | |
| 1596 | + * | |
| 1597 | + * Why do we go to the trouble? If | |
| 1598 | + * someone has an attribute file open, | |
| 1599 | + * the inode number should match until | |
| 1600 | + * they close it. Beyond that, we don't | |
| 1601 | + * care. | |
| 1602 | + */ | |
| 1603 | + spin_lock(&configfs_dirent_lock); | |
| 1604 | + dentry = next->s_dentry; | |
| 1605 | + if (dentry) | |
| 1606 | + inode = dentry->d_inode; | |
| 1607 | + if (inode) | |
| 1608 | + ino = inode->i_ino; | |
| 1609 | + spin_unlock(&configfs_dirent_lock); | |
| 1610 | + if (!inode) | |
| 1587 | 1611 | ino = iunique(configfs_sb, 2); |
| 1588 | 1612 | |
| 1589 | 1613 | if (filldir(dirent, name, len, filp->f_pos, ino, |
| @@ -1683,7 +1707,8 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys) · 93 unmodified lines | ||
| 1683 | 1707 | err = configfs_attach_group(sd->s_element, &group->cg_item, |
| 1684 | 1708 | dentry); |
| 1685 | 1709 | if (err) { |
| 1686 | − d_delete(dentry); | |
| 1710 | + BUG_ON(dentry->d_inode); | |
| 1711 | + d_drop(dentry); | |
| 1687 | 1712 | dput(dentry); |
| 1688 | 1713 | } else { |
| 1689 | 1714 | spin_lock(&configfs_dirent_lock); |
| @@ -99,12 +99,9 @@ static struct kmem_cache *dentry_cache __read_mostly; · 98 unmodified lines | ||
| 99 | 99 | static unsigned int d_hash_mask __read_mostly; |
| 100 | 100 | static unsigned int d_hash_shift __read_mostly; |
| 101 | 101 | |
| 102 | −struct dcache_hash_bucket { | |
| 103 | − struct hlist_bl_head head; | |
| 104 | −}; | |
| 105 | −static struct dcache_hash_bucket *dentry_hashtable __read_mostly; | |
| 102 | +static struct hlist_bl_head *dentry_hashtable __read_mostly; | |
| 106 | 103 | |
| 107 | −static inline struct dcache_hash_bucket *d_hash(struct dentry *parent, | |
| 104 | +static inline struct hlist_bl_head *d_hash(struct dentry *parent, | |
| 108 | 105 | unsigned long hash) |
| 109 | 106 | { |
| 110 | 107 | hash += ((unsigned long) parent ^ GOLDEN_RATIO_PRIME) / L1_CACHE_BYTES; |
| @@ -112,16 +109,6 @@ static inline struct dcache_hash_bucket *d_hash(struct dentry *parent, · 1 unmodified line | ||
| 112 | 109 | return dentry_hashtable + (hash & D_HASHMASK); |
| 113 | 110 | } |
| 114 | 111 | |
| 115 | −static inline void spin_lock_bucket(struct dcache_hash_bucket *b) | |
| 116 | −{ | |
| 117 | − bit_spin_lock(0, (unsigned long *)&b->head.first); | |
| 118 | −} | |
| 119 | − | |
| 120 | −static inline void spin_unlock_bucket(struct dcache_hash_bucket *b) | |
| 121 | −{ | |
| 122 | − __bit_spin_unlock(0, (unsigned long *)&b->head.first); | |
| 123 | −} | |
| 124 | − | |
| 125 | 112 | /* Statistics gathering. */ |
| 126 | 113 | struct dentry_stat_t dentry_stat = { |
| 127 | 114 | .age_limit = 45, |
| @@ -167,8 +154,8 @@ static void d_free(struct dentry *dentry) · 39 unmodified lines | ||
| 167 | 154 | if (dentry->d_op && dentry->d_op->d_release) |
| 168 | 155 | dentry->d_op->d_release(dentry); |
| 169 | 156 | |
| 170 | − /* if dentry was never inserted into hash, immediate free is OK */ | |
| 171 | − if (hlist_bl_unhashed(&dentry->d_hash)) | |
| 157 | + /* if dentry was never visible to RCU, immediate free is OK */ | |
| 158 | + if (!(dentry->d_flags & DCACHE_RCUACCESS)) | |
| 172 | 159 | __d_free(&dentry->d_u.d_rcu); |
| 173 | 160 | else |
| 174 | 161 | call_rcu(&dentry->d_u.d_rcu, __d_free); |
| @@ -330,28 +317,19 @@ static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent) · 155 unmodified lines | ||
| 330 | 317 | */ |
| 331 | 318 | void __d_drop(struct dentry *dentry) |
| 332 | 319 | { |
| 333 | − if (!(dentry->d_flags & DCACHE_UNHASHED)) { | |
| 334 | − if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED)) { | |
| 335 | − bit_spin_lock(0, | |
| 336 | − (unsigned long *)&dentry->d_sb->s_anon.first); | |
| 337 | − dentry->d_flags |= DCACHE_UNHASHED; | |
| 338 | − hlist_bl_del_init(&dentry->d_hash); | |
| 339 | − __bit_spin_unlock(0, | |
| 340 | − (unsigned long *)&dentry->d_sb->s_anon.first); | |
| 341 | − } else { | |
| 342 | − struct dcache_hash_bucket *b; | |
| 320 | + if (!d_unhashed(dentry)) { | |
| 321 | + struct hlist_bl_head *b; | |
| 322 | + if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED)) | |
| 323 | + b = &dentry->d_sb->s_anon; | |
| 324 | + else | |
| 343 | 325 | b = d_hash(dentry->d_parent, dentry->d_name.hash); |
| 344 | − spin_lock_bucket(b); | |
| 345 | − /* | |
| 346 | − * We may not actually need to put DCACHE_UNHASHED | |
| 347 | − * manipulations under the hash lock, but follow | |
| 348 | − * the principle of least surprise. | |
| 349 | − */ | |
| 350 | − dentry->d_flags |= DCACHE_UNHASHED; | |
| 351 | − hlist_bl_del_rcu(&dentry->d_hash); | |
| 352 | − spin_unlock_bucket(b); | |
| 353 | − dentry_rcuwalk_barrier(dentry); | |
| 354 | − } | |
| 326 | + | |
| 327 | + hlist_bl_lock(b); | |
| 328 | + __hlist_bl_del(&dentry->d_hash); | |
| 329 | + dentry->d_hash.pprev = NULL; | |
| 330 | + hlist_bl_unlock(b); | |
| 331 | + | |
| 332 | + dentry_rcuwalk_barrier(dentry); | |
| 355 | 333 | } |
| 356 | 334 | } |
| 357 | 335 | EXPORT_SYMBOL(__d_drop); |
| @@ -1304,7 +1282,7 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name) · 946 unmodified lines | ||
| 1304 | 1282 | dname[name->len] = 0; |
| 1305 | 1283 | |
| 1306 | 1284 | dentry->d_count = 1; |
| 1307 | − dentry->d_flags = DCACHE_UNHASHED; | |
| 1285 | + dentry->d_flags = 0; | |
| 1308 | 1286 | spin_lock_init(&dentry->d_lock); |
| 1309 | 1287 | seqcount_init(&dentry->d_seq); |
| 1310 | 1288 | dentry->d_inode = NULL; |
| @@ -1606,10 +1584,9 @@ struct dentry *d_obtain_alias(struct inode *inode) · 295 unmodified lines | ||
| 1606 | 1584 | tmp->d_inode = inode; |
| 1607 | 1585 | tmp->d_flags |= DCACHE_DISCONNECTED; |
| 1608 | 1586 | list_add(&tmp->d_alias, &inode->i_dentry); |
| 1609 | − bit_spin_lock(0, (unsigned long *)&tmp->d_sb->s_anon.first); | |
| 1610 | − tmp->d_flags &= ~DCACHE_UNHASHED; | |
| 1587 | + hlist_bl_lock(&tmp->d_sb->s_anon); | |
| 1611 | 1588 | hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon); |
| 1612 | − __bit_spin_unlock(0, (unsigned long *)&tmp->d_sb->s_anon.first); | |
| 1589 | + hlist_bl_unlock(&tmp->d_sb->s_anon); | |
| 1613 | 1590 | spin_unlock(&tmp->d_lock); |
| 1614 | 1591 | spin_unlock(&inode->i_lock); |
| 1615 | 1592 | security_d_instantiate(tmp, inode); |
| @@ -1789,7 +1766,7 @@ struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name, · 173 unmodified lines | ||
| 1789 | 1766 | unsigned int len = name->len; |
| 1790 | 1767 | unsigned int hash = name->hash; |
| 1791 | 1768 | const unsigned char *str = name->name; |
| 1792 | − struct dcache_hash_bucket *b = d_hash(parent, hash); | |
| 1769 | + struct hlist_bl_head *b = d_hash(parent, hash); | |
| 1793 | 1770 | struct hlist_bl_node *node; |
| 1794 | 1771 | struct dentry *dentry; |
| 1795 | 1772 | |
| @@ -1813,7 +1790,7 @@ struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name, · 17 unmodified lines | ||
| 1813 | 1790 | * |
| 1814 | 1791 | * See Documentation/filesystems/path-lookup.txt for more details. |
| 1815 | 1792 | */ |
| 1816 | − hlist_bl_for_each_entry_rcu(dentry, node, &b->head, d_hash) { | |
| 1793 | + hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) { | |
| 1817 | 1794 | struct inode *i; |
| 1818 | 1795 | const char *tname; |
| 1819 | 1796 | int tlen; |
| @@ -1908,7 +1885,7 @@ struct dentry *__d_lookup(struct dentry *parent, struct qstr *name) · 88 unmodified lines | ||
| 1908 | 1885 | unsigned int len = name->len; |
| 1909 | 1886 | unsigned int hash = name->hash; |
| 1910 | 1887 | const unsigned char *str = name->name; |
| 1911 | − struct dcache_hash_bucket *b = d_hash(parent, hash); | |
| 1888 | + struct hlist_bl_head *b = d_hash(parent, hash); | |
| 1912 | 1889 | struct hlist_bl_node *node; |
| 1913 | 1890 | struct dentry *found = NULL; |
| 1914 | 1891 | struct dentry *dentry; |
| @@ -1935,7 +1912,7 @@ struct dentry *__d_lookup(struct dentry *parent, struct qstr *name) · 20 unmodified lines | ||
| 1935 | 1912 | */ |
| 1936 | 1913 | rcu_read_lock(); |
| 1937 | 1914 | |
| 1938 | − hlist_bl_for_each_entry_rcu(dentry, node, &b->head, d_hash) { | |
| 1915 | + hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) { | |
| 1939 | 1916 | const char *tname; |
| 1940 | 1917 | int tlen; |
| 1941 | 1918 | |
| @@ -2086,13 +2063,13 @@ again: · 144 unmodified lines | ||
| 2086 | 2063 | } |
| 2087 | 2064 | EXPORT_SYMBOL(d_delete); |
| 2088 | 2065 | |
| 2089 | −static void __d_rehash(struct dentry * entry, struct dcache_hash_bucket *b) | |
| 2066 | +static void __d_rehash(struct dentry * entry, struct hlist_bl_head *b) | |
| 2090 | 2067 | { |
| 2091 | 2068 | BUG_ON(!d_unhashed(entry)); |
| 2092 | − spin_lock_bucket(b); | |
| 2093 | − entry->d_flags &= ~DCACHE_UNHASHED; | |
| 2094 | − hlist_bl_add_head_rcu(&entry->d_hash, &b->head); | |
| 2095 | − spin_unlock_bucket(b); | |
| 2069 | + hlist_bl_lock(b); | |
| 2070 | + entry->d_flags |= DCACHE_RCUACCESS; | |
| 2071 | + hlist_bl_add_head_rcu(&entry->d_hash, b); | |
| 2072 | + hlist_bl_unlock(b); | |
| 2096 | 2073 | } |
| 2097 | 2074 | |
| 2098 | 2075 | static void _d_rehash(struct dentry * entry) |
| @@ -3025,7 +3002,7 @@ static void __init dcache_init_early(void) · 926 unmodified lines | ||
| 3025 | 3002 | |
| 3026 | 3003 | dentry_hashtable = |
| 3027 | 3004 | alloc_large_system_hash("Dentry cache", |
| 3028 | − sizeof(struct dcache_hash_bucket), | |
| 3005 | + sizeof(struct hlist_bl_head), | |
| 3029 | 3006 | dhash_entries, |
| 3030 | 3007 | 13, |
| 3031 | 3008 | HASH_EARLY, |
| @@ -3034,7 +3011,7 @@ static void __init dcache_init_early(void) · 2 unmodified lines | ||
| 3034 | 3011 | 0); |
| 3035 | 3012 | |
| 3036 | 3013 | for (loop = 0; loop < (1 << d_hash_shift); loop++) |
| 3037 | − INIT_HLIST_BL_HEAD(&dentry_hashtable[loop].head); | |
| 3014 | + INIT_HLIST_BL_HEAD(dentry_hashtable + loop); | |
| 3038 | 3015 | } |
| 3039 | 3016 | |
| 3040 | 3017 | static void __init dcache_init(void) |
| @@ -3057,7 +3034,7 @@ static void __init dcache_init(void) · 16 unmodified lines | ||
| 3057 | 3034 | |
| 3058 | 3035 | dentry_hashtable = |
| 3059 | 3036 | alloc_large_system_hash("Dentry cache", |
| 3060 | − sizeof(struct dcache_hash_bucket), | |
| 3037 | + sizeof(struct hlist_bl_head), | |
| 3061 | 3038 | dhash_entries, |
| 3062 | 3039 | 13, |
| 3063 | 3040 | 0, |
| @@ -3066,7 +3043,7 @@ static void __init dcache_init(void) · 2 unmodified lines | ||
| 3066 | 3043 | 0); |
| 3067 | 3044 | |
| 3068 | 3045 | for (loop = 0; loop < (1 << d_hash_shift); loop++) |
| 3069 | − INIT_HLIST_BL_HEAD(&dentry_hashtable[loop].head); | |
| 3046 | + INIT_HLIST_BL_HEAD(dentry_hashtable + loop); | |
| 3070 | 3047 | } |
| 3071 | 3048 | |
| 3072 | 3049 | /* SLAB cache for __getname() consumers */ |
| @@ -1452,6 +1452,25 @@ static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat) · 1451 unmodified lines | ||
| 1452 | 1452 | crypt_stat->metadata_size = ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; |
| 1453 | 1453 | } |
| 1454 | 1454 | |
| 1455 | +void ecryptfs_i_size_init(const char *page_virt, struct inode *inode) | |
| 1456 | +{ | |
| 1457 | + struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | |
| 1458 | + struct ecryptfs_crypt_stat *crypt_stat; | |
| 1459 | + u64 file_size; | |
| 1460 | + | |
| 1461 | + crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; | |
| 1462 | + mount_crypt_stat = | |
| 1463 | + &ecryptfs_superblock_to_private(inode->i_sb)->mount_crypt_stat; | |
| 1464 | + if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { | |
| 1465 | + file_size = i_size_read(ecryptfs_inode_to_lower(inode)); | |
| 1466 | + if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | |
| 1467 | + file_size += crypt_stat->metadata_size; | |
| 1468 | + } else | |
| 1469 | + file_size = get_unaligned_be64(page_virt); | |
| 1470 | + i_size_write(inode, (loff_t)file_size); | |
| 1471 | + crypt_stat->flags |= ECRYPTFS_I_SIZE_INITIALIZED; | |
| 1472 | +} | |
| 1473 | + | |
| 1455 | 1474 | /** |
| 1456 | 1475 | * ecryptfs_read_headers_virt |
| 1457 | 1476 | * @page_virt: The virtual address into which to read the headers |
| @@ -1482,6 +1501,8 @@ static int ecryptfs_read_headers_virt(char *page_virt, · 24 unmodified lines | ||
| 1482 | 1501 | rc = -EINVAL; |
| 1483 | 1502 | goto out; |
| 1484 | 1503 | } |
| 1504 | + if (!(crypt_stat->flags & ECRYPTFS_I_SIZE_INITIALIZED)) | |
| 1505 | + ecryptfs_i_size_init(page_virt, ecryptfs_dentry->d_inode); | |
| 1485 | 1506 | offset += MAGIC_ECRYPTFS_MARKER_SIZE_BYTES; |
| 1486 | 1507 | rc = ecryptfs_process_flags(crypt_stat, (page_virt + offset), |
| 1487 | 1508 | &bytes_read); |
| @@ -269,6 +269,7 @@ struct ecryptfs_crypt_stat { · 268 unmodified lines | ||
| 269 | 269 | #define ECRYPTFS_ENCFN_USE_MOUNT_FNEK 0x00000800 |
| 270 | 270 | #define ECRYPTFS_ENCFN_USE_FEK 0x00001000 |
| 271 | 271 | #define ECRYPTFS_UNLINK_SIGS 0x00002000 |
| 272 | +#define ECRYPTFS_I_SIZE_INITIALIZED 0x00004000 | |
| 272 | 273 | u32 flags; |
| 273 | 274 | unsigned int file_version; |
| 274 | 275 | size_t iv_bytes; |
| @@ -295,6 +296,8 @@ struct ecryptfs_crypt_stat { · 20 unmodified lines | ||
| 295 | 296 | struct ecryptfs_inode_info { |
| 296 | 297 | struct inode vfs_inode; |
| 297 | 298 | struct inode *wii_inode; |
| 299 | + struct mutex lower_file_mutex; | |
| 300 | + atomic_t lower_file_count; | |
| 298 | 301 | struct file *lower_file; |
| 299 | 302 | struct ecryptfs_crypt_stat crypt_stat; |
| 300 | 303 | }; |
| @@ -626,6 +629,7 @@ struct ecryptfs_open_req { · 325 unmodified lines | ||
| 626 | 629 | int ecryptfs_interpose(struct dentry *hidden_dentry, |
| 627 | 630 | struct dentry *this_dentry, struct super_block *sb, |
| 628 | 631 | u32 flags); |
| 632 | +void ecryptfs_i_size_init(const char *page_virt, struct inode *inode); | |
| 629 | 633 | int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, |
| 630 | 634 | struct dentry *lower_dentry, |
| 631 | 635 | struct inode *ecryptfs_dir_inode); |
| @@ -757,7 +761,8 @@ int ecryptfs_privileged_open(struct file **lower_file, · 125 unmodified lines | ||
| 757 | 761 | struct dentry *lower_dentry, |
| 758 | 762 | struct vfsmount *lower_mnt, |
| 759 | 763 | const struct cred *cred); |
| 760 | −int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry); | |
| 764 | +int ecryptfs_get_lower_file(struct dentry *ecryptfs_dentry); | |
| 765 | +void ecryptfs_put_lower_file(struct inode *inode); | |
| 761 | 766 | int |
| 762 | 767 | ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, |
| 763 | 768 | size_t *packet_size, |
| @@ -191,10 +191,10 @@ static int ecryptfs_open(struct inode *inode, struct file *file) · 190 unmodified lines | ||
| 191 | 191 | | ECRYPTFS_ENCRYPTED); |
| 192 | 192 | } |
| 193 | 193 | mutex_unlock(&crypt_stat->cs_mutex); |
| 194 | − rc = ecryptfs_init_persistent_file(ecryptfs_dentry); | |
| 194 | + rc = ecryptfs_get_lower_file(ecryptfs_dentry); | |
| 195 | 195 | if (rc) { |
| 196 | 196 | printk(KERN_ERR "%s: Error attempting to initialize " |
| 197 | − "the persistent file for the dentry with name " | |
| 197 | + "the lower file for the dentry with name " | |
| 198 | 198 | "[%s]; rc = [%d]\n", __func__, |
| 199 | 199 | ecryptfs_dentry->d_name.name, rc); |
| 200 | 200 | goto out_free; |
| @@ -202,9 +202,9 @@ static int ecryptfs_open(struct inode *inode, struct file *file) · 1 unmodified line | ||
| 202 | 202 | if ((ecryptfs_inode_to_private(inode)->lower_file->f_flags & O_ACCMODE) |
| 203 | 203 | == O_RDONLY && (file->f_flags & O_ACCMODE) != O_RDONLY) { |
| 204 | 204 | rc = -EPERM; |
| 205 | − printk(KERN_WARNING "%s: Lower persistent file is RO; eCryptfs " | |
| 205 | + printk(KERN_WARNING "%s: Lower file is RO; eCryptfs " | |
| 206 | 206 | "file must hence be opened RO\n", __func__); |
| 207 | − goto out_free; | |
| 207 | + goto out_put; | |
| 208 | 208 | } |
| 209 | 209 | ecryptfs_set_file_lower( |
| 210 | 210 | file, ecryptfs_inode_to_private(inode)->lower_file); |
| @@ -232,10 +232,11 @@ static int ecryptfs_open(struct inode *inode, struct file *file) · 21 unmodified lines | ||
| 232 | 232 | "Plaintext passthrough mode is not " |
| 233 | 233 | "enabled; returning -EIO\n"); |
| 234 | 234 | mutex_unlock(&crypt_stat->cs_mutex); |
| 235 | − goto out_free; | |
| 235 | + goto out_put; | |
| 236 | 236 | } |
| 237 | 237 | rc = 0; |
| 238 | − crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); | |
| 238 | + crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED | |
| 239 | + | ECRYPTFS_ENCRYPTED); | |
| 239 | 240 | mutex_unlock(&crypt_stat->cs_mutex); |
| 240 | 241 | goto out; |
| 241 | 242 | } |
| @@ -245,6 +246,8 @@ static int ecryptfs_open(struct inode *inode, struct file *file) · 3 unmodified lines | ||
| 245 | 246 | "[0x%.16lx] size: [0x%.16llx]\n", inode, inode->i_ino, |
| 246 | 247 | (unsigned long long)i_size_read(inode)); |
| 247 | 248 | goto out; |
| 249 | +out_put: | |
| 250 | + ecryptfs_put_lower_file(inode); | |
| 248 | 251 | out_free: |
| 249 | 252 | kmem_cache_free(ecryptfs_file_info_cache, |
| 250 | 253 | ecryptfs_file_to_private(file)); |
| @@ -254,17 +257,13 @@ out: · 3 unmodified lines | ||
| 254 | 257 | |
| 255 | 258 | static int ecryptfs_flush(struct file *file, fl_owner_t td) |
| 256 | 259 | { |
| 257 | − int rc = 0; | |
| 258 | − struct file *lower_file = NULL; | |
| 259 | − | |
| 260 | − lower_file = ecryptfs_file_to_lower(file); | |
| 261 | − if (lower_file->f_op && lower_file->f_op->flush) | |
| 262 | − rc = lower_file->f_op->flush(lower_file, td); | |
| 263 | − return rc; | |
| 260 | + return file->f_mode & FMODE_WRITE | |
| 261 | + ? filemap_write_and_wait(file->f_mapping) : 0; | |
| 264 | 262 | } |
| 265 | 263 | |
| 266 | 264 | static int ecryptfs_release(struct inode *inode, struct file *file) |
| 267 | 265 | { |
| 266 | + ecryptfs_put_lower_file(inode); | |
| 268 | 267 | kmem_cache_free(ecryptfs_file_info_cache, |
| 269 | 268 | ecryptfs_file_to_private(file)); |
| 270 | 269 | return 0; |
| @@ -168,19 +168,18 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) · 167 unmodified lines | ||
| 168 | 168 | "context; rc = [%d]\n", rc); |
| 169 | 169 | goto out; |
| 170 | 170 | } |
| 171 | − rc = ecryptfs_init_persistent_file(ecryptfs_dentry); | |
| 171 | + rc = ecryptfs_get_lower_file(ecryptfs_dentry); | |
| 172 | 172 | if (rc) { |
| 173 | 173 | printk(KERN_ERR "%s: Error attempting to initialize " |
| 174 | − "the persistent file for the dentry with name " | |
| 174 | + "the lower file for the dentry with name " | |
| 175 | 175 | "[%s]; rc = [%d]\n", __func__, |
| 176 | 176 | ecryptfs_dentry->d_name.name, rc); |
| 177 | 177 | goto out; |
| 178 | 178 | } |
| 179 | 179 | rc = ecryptfs_write_metadata(ecryptfs_dentry); |
| 180 | − if (rc) { | |
| 180 | + if (rc) | |
| 181 | 181 | printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc); |
| 182 | − goto out; | |
| 183 | − } | |
| 182 | + ecryptfs_put_lower_file(ecryptfs_dentry->d_inode); | |
| 184 | 183 | out: |
| 185 | 184 | return rc; |
| 186 | 185 | } |
| @@ -226,11 +225,9 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, · 39 unmodified lines | ||
| 226 | 225 | struct dentry *lower_dir_dentry; |
| 227 | 226 | struct vfsmount *lower_mnt; |
| 228 | 227 | struct inode *lower_inode; |
| 229 | − struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | |
| 230 | 228 | struct ecryptfs_crypt_stat *crypt_stat; |
| 231 | 229 | char *page_virt = NULL; |
| 232 | − u64 file_size; | |
| 233 | − int rc = 0; | |
| 230 | + int put_lower = 0, rc = 0; | |
| 234 | 231 | |
| 235 | 232 | lower_dir_dentry = lower_dentry->d_parent; |
| 236 | 233 | lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt( |
| @@ -277,14 +274,15 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, · 40 unmodified lines | ||
| 277 | 274 | rc = -ENOMEM; |
| 278 | 275 | goto out; |
| 279 | 276 | } |
| 280 | − rc = ecryptfs_init_persistent_file(ecryptfs_dentry); | |
| 277 | + rc = ecryptfs_get_lower_file(ecryptfs_dentry); | |
| 281 | 278 | if (rc) { |
| 282 | 279 | printk(KERN_ERR "%s: Error attempting to initialize " |
| 283 | − "the persistent file for the dentry with name " | |
| 280 | + "the lower file for the dentry with name " | |
| 284 | 281 | "[%s]; rc = [%d]\n", __func__, |
| 285 | 282 | ecryptfs_dentry->d_name.name, rc); |
| 286 | 283 | goto out_free_kmem; |
| 287 | 284 | } |
| 285 | + put_lower = 1; | |
| 288 | 286 | crypt_stat = &ecryptfs_inode_to_private( |
| 289 | 287 | ecryptfs_dentry->d_inode)->crypt_stat; |
| 290 | 288 | /* TODO: lock for crypt_stat comparison */ |
| @@ -302,18 +300,7 @@ int ecryptfs_lookup_and_interpose_lower(struct dentry *ecryptfs_dentry, · 11 unmodified lines | ||
| 302 | 300 | } |
| 303 | 301 | crypt_stat->flags |= ECRYPTFS_METADATA_IN_XATTR; |
| 304 | 302 | } |
| 305 | − mount_crypt_stat = &ecryptfs_superblock_to_private( | |
| 306 | − ecryptfs_dentry->d_sb)->mount_crypt_stat; | |
| 307 | − if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { | |
| 308 | − if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | |
| 309 | − file_size = (crypt_stat->metadata_size | |
| 310 | − + i_size_read(lower_dentry->d_inode)); | |
| 311 | − else | |
| 312 | − file_size = i_size_read(lower_dentry->d_inode); | |
| 313 | − } else { | |
| 314 | − file_size = get_unaligned_be64(page_virt); | |
| 315 | − } | |
| 316 | − i_size_write(ecryptfs_dentry->d_inode, (loff_t)file_size); | |
| 303 | + ecryptfs_i_size_init(page_virt, ecryptfs_dentry->d_inode); | |
| 317 | 304 | out_free_kmem: |
| 318 | 305 | kmem_cache_free(ecryptfs_header_cache_2, page_virt); |
| 319 | 306 | goto out; |
| @@ -322,6 +309,8 @@ out_put: · 2 unmodified lines | ||
| 322 | 309 | mntput(lower_mnt); |
| 323 | 310 | d_drop(ecryptfs_dentry); |
| 324 | 311 | out: |
| 312 | + if (put_lower) | |
| 313 | + ecryptfs_put_lower_file(ecryptfs_dentry->d_inode); | |
| 325 | 314 | return rc; |
| 326 | 315 | } |
| 327 | 316 | |
| @@ -538,8 +527,6 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) · 210 unmodified lines | ||
| 538 | 527 | dget(lower_dentry); |
| 539 | 528 | rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry); |
| 540 | 529 | dput(lower_dentry); |
| 541 | − if (!rc) | |
| 542 | − d_delete(lower_dentry); | |
| 543 | 530 | fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode); |
| 544 | 531 | dir->i_nlink = lower_dir_dentry->d_inode->i_nlink; |
| 545 | 532 | unlock_dir(lower_dir_dentry); |
| @@ -610,8 +597,8 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, · 64 unmodified lines | ||
| 610 | 597 | fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); |
| 611 | 598 | out_lock: |
| 612 | 599 | unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); |
| 613 | − dput(lower_new_dentry->d_parent); | |
| 614 | − dput(lower_old_dentry->d_parent); | |
| 600 | + dput(lower_new_dir_dentry); | |
| 601 | + dput(lower_old_dir_dentry); | |
| 615 | 602 | dput(lower_new_dentry); |
| 616 | 603 | dput(lower_old_dentry); |
| 617 | 604 | return rc; |
| @@ -759,8 +746,11 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, · 141 unmodified lines | ||
| 759 | 746 | |
| 760 | 747 | if (unlikely((ia->ia_size == i_size))) { |
| 761 | 748 | lower_ia->ia_valid &= ~ATTR_SIZE; |
| 762 | − goto out; | |
| 749 | + return 0; | |
| 763 | 750 | } |
| 751 | + rc = ecryptfs_get_lower_file(dentry); | |
| 752 | + if (rc) | |
| 753 | + return rc; | |
| 764 | 754 | crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; |
| 765 | 755 | /* Switch on growing or shrinking file */ |
| 766 | 756 | if (ia->ia_size > i_size) { |
| @@ -838,6 +828,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia, · 71 unmodified lines | ||
| 838 | 828 | lower_ia->ia_valid &= ~ATTR_SIZE; |
| 839 | 829 | } |
| 840 | 830 | out: |
| 831 | + ecryptfs_put_lower_file(inode); | |
| 841 | 832 | return rc; |
| 842 | 833 | } |
| 843 | 834 | |
| @@ -913,7 +904,13 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) · 69 unmodified lines | ||
| 913 | 904 | |
| 914 | 905 | mount_crypt_stat = &ecryptfs_superblock_to_private( |
| 915 | 906 | dentry->d_sb)->mount_crypt_stat; |
| 907 | + rc = ecryptfs_get_lower_file(dentry); | |
| 908 | + if (rc) { | |
| 909 | + mutex_unlock(&crypt_stat->cs_mutex); | |
| 910 | + goto out; | |
| 911 | + } | |
| 916 | 912 | rc = ecryptfs_read_metadata(dentry); |
| 913 | + ecryptfs_put_lower_file(inode); | |
| 917 | 914 | if (rc) { |
| 918 | 915 | if (!(mount_crypt_stat->flags |
| 919 | 916 | & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { |
| @@ -927,10 +924,17 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) · 7 unmodified lines | ||
| 927 | 924 | goto out; |
| 928 | 925 | } |
| 929 | 926 | rc = 0; |
| 930 | − crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); | |
| 927 | + crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED | |
| 928 | + | ECRYPTFS_ENCRYPTED); | |
| 931 | 929 | } |
| 932 | 930 | } |
| 933 | 931 | mutex_unlock(&crypt_stat->cs_mutex); |
| 932 | + if (S_ISREG(inode->i_mode)) { | |
| 933 | + rc = filemap_write_and_wait(inode->i_mapping); | |
| 934 | + if (rc) | |
| 935 | + goto out; | |
| 936 | + fsstack_copy_attr_all(inode, lower_inode); | |
| 937 | + } | |
| 934 | 938 | memcpy(&lower_ia, ia, sizeof(lower_ia)); |
| 935 | 939 | if (ia->ia_valid & ATTR_FILE) |
| 936 | 940 | lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file); |
| @@ -44,7 +44,7 @@ static struct task_struct *ecryptfs_kthread; · 43 unmodified lines | ||
| 44 | 44 | * @ignored: ignored |
| 45 | 45 | * |
| 46 | 46 | * The eCryptfs kernel thread that has the responsibility of getting |
| 47 | − * the lower persistent file with RW permissions. | |
| 47 | + * the lower file with RW permissions. | |
| 48 | 48 | * |
| 49 | 49 | * Returns zero on success; non-zero otherwise |
| 50 | 50 | */ |
| @@ -141,8 +141,8 @@ int ecryptfs_privileged_open(struct file **lower_file, · 90 unmodified lines | ||
| 141 | 141 | int rc = 0; |
| 142 | 142 | |
| 143 | 143 | /* Corresponding dput() and mntput() are done when the |
| 144 | − * persistent file is fput() when the eCryptfs inode is | |
| 145 | − * destroyed. */ | |
| 144 | + * lower file is fput() when all eCryptfs files for the inode are | |
| 145 | + * released. */ | |
| 146 | 146 | dget(lower_dentry); |
| 147 | 147 | mntget(lower_mnt); |
| 148 | 148 | flags |= IS_RDONLY(lower_dentry->d_inode) ? O_RDONLY : O_RDWR; |
| @@ -96,7 +96,7 @@ void __ecryptfs_printk(const char *fmt, ...) · 95 unmodified lines | ||
| 96 | 96 | } |
| 97 | 97 | |
| 98 | 98 | /** |
| 99 | − * ecryptfs_init_persistent_file | |
| 99 | + * ecryptfs_init_lower_file | |
| 100 | 100 | * @ecryptfs_dentry: Fully initialized eCryptfs dentry object, with |
| 101 | 101 | * the lower dentry and the lower mount set |
| 102 | 102 | * |
| @@ -104,42 +104,70 @@ void __ecryptfs_printk(const char *fmt, ...) · 1 unmodified line | ||
| 104 | 104 | * inode. All I/O operations to the lower inode occur through that |
| 105 | 105 | * file. When the first eCryptfs dentry that interposes with the first |
| 106 | 106 | * lower dentry for that inode is created, this function creates the |
| 107 | − * persistent file struct and associates it with the eCryptfs | |
| 108 | − * inode. When the eCryptfs inode is destroyed, the file is closed. | |
| 107 | + * lower file struct and associates it with the eCryptfs | |
| 108 | + * inode. When all eCryptfs files associated with the inode are released, the | |
| 109 | + * file is closed. | |
| 109 | 110 | * |
| 110 | − * The persistent file will be opened with read/write permissions, if | |
| 111 | + * The lower file will be opened with read/write permissions, if | |
| 111 | 112 | * possible. Otherwise, it is opened read-only. |
| 112 | 113 | * |
| 113 | − * This function does nothing if a lower persistent file is already | |
| 114 | + * This function does nothing if a lower file is already | |
| 114 | 115 | * associated with the eCryptfs inode. |
| 115 | 116 | * |
| 116 | 117 | * Returns zero on success; non-zero otherwise |
| 117 | 118 | */ |
| 118 | −int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) | |
| 119 | +static int ecryptfs_init_lower_file(struct dentry *dentry, | |
| 120 | + struct file **lower_file) | |
| 119 | 121 | { |
| 120 | 122 | const struct cred *cred = current_cred(); |
| 121 | − struct ecryptfs_inode_info *inode_info = | |
| 122 | − ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); | |
| 123 | − int rc = 0; | |
| 123 | + struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | |
| 124 | + struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); | |
| 125 | + int rc; | |
| 124 | 126 | |
| 125 | − if (!inode_info->lower_file) { | |
| 126 | − struct dentry *lower_dentry; | |
| 127 | − struct vfsmount *lower_mnt = | |
| 128 | − ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry); | |
| 127 | + rc = ecryptfs_privileged_open(lower_file, lower_dentry, lower_mnt, | |
| 128 | + cred); | |
| 129 | + if (rc) { | |
| 130 | + printk(KERN_ERR "Error opening lower file " | |
| 131 | + "for lower_dentry [0x%p] and lower_mnt [0x%p]; " | |
| 132 | + "rc = [%d]\n", lower_dentry, lower_mnt, rc); | |
| 133 | + (*lower_file) = NULL; | |
| 134 | + } | |
| 135 | + return rc; | |
| 136 | +} | |
| 129 | 137 | |
| 130 | − lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); | |
| 131 | − rc = ecryptfs_privileged_open(&inode_info->lower_file, | |
| 132 | − lower_dentry, lower_mnt, cred); | |
| 133 | − if (rc) { | |
| 134 | − printk(KERN_ERR "Error opening lower persistent file " | |
| 135 | − "for lower_dentry [0x%p] and lower_mnt [0x%p]; " | |
| 136 | − "rc = [%d]\n", lower_dentry, lower_mnt, rc); | |
| 137 | − inode_info->lower_file = NULL; | |
| 138 | − } | |
| 138 | +int ecryptfs_get_lower_file(struct dentry *dentry) | |
| 139 | +{ | |
| 140 | + struct ecryptfs_inode_info *inode_info = | |
| 141 | + ecryptfs_inode_to_private(dentry->d_inode); | |
| 142 | + int count, rc = 0; | |
| 143 | + | |
| 144 | + mutex_lock(&inode_info->lower_file_mutex); | |
| 145 | + count = atomic_inc_return(&inode_info->lower_file_count); | |
| 146 | + if (WARN_ON_ONCE(count < 1)) | |
| 147 | + rc = -EINVAL; | |
| 148 | + else if (count == 1) { | |
| 149 | + rc = ecryptfs_init_lower_file(dentry, | |
| 150 | + &inode_info->lower_file); | |
| 151 | + if (rc) | |
| 152 | + atomic_set(&inode_info->lower_file_count, 0); | |
| 139 | 153 | } |
| 154 | + mutex_unlock(&inode_info->lower_file_mutex); | |
| 140 | 155 | return rc; |
| 141 | 156 | } |
| 142 | 157 | |
| 158 | +void ecryptfs_put_lower_file(struct inode *inode) | |
| 159 | +{ | |
| 160 | + struct ecryptfs_inode_info *inode_info; | |
| 161 | + | |
| 162 | + inode_info = ecryptfs_inode_to_private(inode); | |
| 163 | + if (atomic_dec_and_mutex_lock(&inode_info->lower_file_count, | |
| 164 | + &inode_info->lower_file_mutex)) { | |
| 165 | + fput(inode_info->lower_file); | |
| 166 | + inode_info->lower_file = NULL; | |
| 167 | + mutex_unlock(&inode_info->lower_file_mutex); | |
| 168 | + } | |
| 169 | +} | |
| 170 | + | |
| 143 | 171 | static struct inode *ecryptfs_get_inode(struct inode *lower_inode, |
| 144 | 172 | struct super_block *sb) |
| 145 | 173 | { |
| @@ -55,6 +55,8 @@ static struct inode *ecryptfs_alloc_inode(struct super_block *sb) · 54 unmodified lines | ||
| 55 | 55 | if (unlikely(!inode_info)) |
| 56 | 56 | goto out; |
| 57 | 57 | ecryptfs_init_crypt_stat(&inode_info->crypt_stat); |
| 58 | + mutex_init(&inode_info->lower_file_mutex); | |
| 59 | + atomic_set(&inode_info->lower_file_count, 0); | |
| 58 | 60 | inode_info->lower_file = NULL; |
| 59 | 61 | inode = &inode_info->vfs_inode; |
| 60 | 62 | out: |
| @@ -77,8 +79,7 @@ static void ecryptfs_i_callback(struct rcu_head *head) · 16 unmodified lines | ||
| 77 | 79 | * |
| 78 | 80 | * This is used during the final destruction of the inode. All |
| 79 | 81 | * allocation of memory related to the inode, including allocated |
| 80 | − * memory in the crypt_stat struct, will be released here. This | |
| 81 | − * function also fput()'s the persistent file for the lower inode. | |
| 82 | + * memory in the crypt_stat struct, will be released here. | |
| 82 | 83 | * There should be no chance that this deallocation will be missed. |
| 83 | 84 | */ |
| 84 | 85 | static void ecryptfs_destroy_inode(struct inode *inode) |
| @@ -86,16 +87,7 @@ static void ecryptfs_destroy_inode(struct inode *inode) · 1 unmodified line | ||
| 86 | 87 | struct ecryptfs_inode_info *inode_info; |
| 87 | 88 | |
| 88 | 89 | inode_info = ecryptfs_inode_to_private(inode); |
| 89 | − if (inode_info->lower_file) { | |
| 90 | − struct dentry *lower_dentry = | |
| 91 | − inode_info->lower_file->f_dentry; | |
| 92 | − | |
| 93 | − BUG_ON(!lower_dentry); | |
| 94 | − if (lower_dentry->d_inode) { | |
| 95 | − fput(inode_info->lower_file); | |
| 96 | − inode_info->lower_file = NULL; | |
| 97 | − } | |
| 98 | − } | |
| 90 | + BUG_ON(inode_info->lower_file); | |
| 99 | 91 | ecryptfs_destroy_crypt_stat(&inode_info->crypt_stat); |
| 100 | 92 | call_rcu(&inode->i_rcu, ecryptfs_i_callback); |
| 101 | 93 | } |
| @@ -9,6 +9,7 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <linux/module.h> |
| 10 | 10 | #include <linux/fs.h> |
| 11 | 11 | #include <linux/mm.h> |
| 12 | +#include <linux/mmzone.h> | |
| 12 | 13 | #include <linux/time.h> |
| 13 | 14 | #include <linux/sched.h> |
| 14 | 15 | #include <linux/slab.h> |
| @@ -39,14 +40,17 @@ int sysctl_nr_open_max = 1024 * 1024; /* raised later */ · 24 unmodified lines | ||
| 39 | 40 | */ |
| 40 | 41 | static DEFINE_PER_CPU(struct fdtable_defer, fdtable_defer_list); |
| 41 | 42 | |
| 42 | −static inline void *alloc_fdmem(unsigned int size) | |
| 43 | +static void *alloc_fdmem(unsigned int size) | |
| 43 | 44 | { |
| 44 | − void *data; | |
| 45 | − | |
| 46 | − data = kmalloc(size, GFP_KERNEL|__GFP_NOWARN); | |
| 47 | − if (data != NULL) | |
| 48 | − return data; | |
| 49 | − | |
| 45 | + /* | |
| 46 | + * Very large allocations can stress page reclaim, so fall back to | |
| 47 | + * vmalloc() if the allocation size will be considered "large" by the VM. | |
| 48 | + */ | |
| 49 | + if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) { | |
| 50 | + void *data = kmalloc(size, GFP_KERNEL|__GFP_NOWARN); | |
| 51 | + if (data != NULL) | |
| 52 | + return data; | |
| 53 | + } | |
| 50 | 54 | return vmalloc(size); |
| 51 | 55 | } |
| 52 | 56 | |
| @@ -174,7 +174,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) · 173 unmodified lines | ||
| 174 | 174 | if (!inode) |
| 175 | 175 | return 0; |
| 176 | 176 | |
| 177 | − if (nd->flags & LOOKUP_RCU) | |
| 177 | + if (nd && (nd->flags & LOOKUP_RCU)) | |
| 178 | 178 | return -ECHILD; |
| 179 | 179 | |
| 180 | 180 | fc = get_fuse_conn(inode); |
| @@ -884,8 +884,8 @@ static int gfs2_write_end(struct file *file, struct address_space *mapping, · 883 unmodified lines | ||
| 884 | 884 | } |
| 885 | 885 | |
| 886 | 886 | brelse(dibh); |
| 887 | − gfs2_trans_end(sdp); | |
| 888 | 887 | failed: |
| 888 | + gfs2_trans_end(sdp); | |
| 889 | 889 | if (al) { |
| 890 | 890 | gfs2_inplace_release(ip); |
| 891 | 891 | gfs2_quota_unlock(ip); |
| @@ -1506,7 +1506,7 @@ struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name) · 1505 unmodified lines | ||
| 1506 | 1506 | inode = gfs2_inode_lookup(dir->i_sb, |
| 1507 | 1507 | be16_to_cpu(dent->de_type), |
| 1508 | 1508 | be64_to_cpu(dent->de_inum.no_addr), |
| 1509 | − be64_to_cpu(dent->de_inum.no_formal_ino)); | |
| 1509 | + be64_to_cpu(dent->de_inum.no_formal_ino), 0); | |
| 1510 | 1510 | brelse(bh); |
| 1511 | 1511 | return inode; |
| 1512 | 1512 | } |
| @@ -617,18 +617,51 @@ static ssize_t gfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov, · 616 unmodified lines | ||
| 617 | 617 | return generic_file_aio_write(iocb, iov, nr_segs, pos); |
| 618 | 618 | } |
| 619 | 619 | |
| 620 | −static void empty_write_end(struct page *page, unsigned from, | |
| 621 | − unsigned to) | |
| 620 | +static int empty_write_end(struct page *page, unsigned from, | |
| 621 | + unsigned to, int mode) | |
| 622 | 622 | { |
| 623 | − struct gfs2_inode *ip = GFS2_I(page->mapping->host); | |
| 623 | + struct inode *inode = page->mapping->host; | |
| 624 | + struct gfs2_inode *ip = GFS2_I(inode); | |
| 625 | + struct buffer_head *bh; | |
| 626 | + unsigned offset, blksize = 1 << inode->i_blkbits; | |
| 627 | + pgoff_t end_index = i_size_read(inode) >> PAGE_CACHE_SHIFT; | |
| 624 | 628 | |
| 625 | 629 | zero_user(page, from, to-from); |
| 626 | 630 | mark_page_accessed(page); |
| 627 | 631 | |
| 628 | − if (!gfs2_is_writeback(ip)) | |
| 629 | − gfs2_page_add_databufs(ip, page, from, to); | |
| 632 | + if (page->index < end_index || !(mode & FALLOC_FL_KEEP_SIZE)) { | |
| 633 | + if (!gfs2_is_writeback(ip)) | |
| 634 | + gfs2_page_add_databufs(ip, page, from, to); | |
| 635 | + | |
| 636 | + block_commit_write(page, from, to); | |
| 637 | + return 0; | |
| 638 | + } | |
| 639 | + | |
| 640 | + offset = 0; | |
| 641 | + bh = page_buffers(page); | |
| 642 | + while (offset < to) { | |
| 643 | + if (offset >= from) { | |
| 644 | + set_buffer_uptodate(bh); | |
| 645 | + mark_buffer_dirty(bh); | |
| 646 | + clear_buffer_new(bh); | |
| 647 | + write_dirty_buffer(bh, WRITE); | |
| 648 | + } | |
| 649 | + offset += blksize; | |
| 650 | + bh = bh->b_this_page; | |
| 651 | + } | |
| 630 | 652 | |
| 631 | − block_commit_write(page, from, to); | |
| 653 | + offset = 0; | |
| 654 | + bh = page_buffers(page); | |
| 655 | + while (offset < to) { | |
| 656 | + if (offset >= from) { | |
| 657 | + wait_on_buffer(bh); | |
| 658 | + if (!buffer_uptodate(bh)) | |
| 659 | + return -EIO; | |
| 660 | + } | |
| 661 | + offset += blksize; | |
| 662 | + bh = bh->b_this_page; | |
| 663 | + } | |
| 664 | + return 0; | |
| 632 | 665 | } |
| 633 | 666 | |
| 634 | 667 | static int needs_empty_write(sector_t block, struct inode *inode) |
| @@ -643,7 +676,8 @@ static int needs_empty_write(sector_t block, struct inode *inode) · 8 unmodified lines | ||
| 643 | 676 | return !buffer_mapped(&bh_map); |
| 644 | 677 | } |
| 645 | 678 | |
| 646 | −static int write_empty_blocks(struct page *page, unsigned from, unsigned to) | |
| 679 | +static int write_empty_blocks(struct page *page, unsigned from, unsigned to, | |
| 680 | + int mode) | |
| 647 | 681 | { |
| 648 | 682 | struct inode *inode = page->mapping->host; |
| 649 | 683 | unsigned start, end, next, blksize; |
| @@ -668,7 +702,9 @@ static int write_empty_blocks(struct page *page, unsigned from, unsigned to) · 18 unmodified lines | ||
| 668 | 702 | gfs2_block_map); |
| 669 | 703 | if (unlikely(ret)) |
| 670 | 704 | return ret; |
| 671 | − empty_write_end(page, start, end); | |
| 705 | + ret = empty_write_end(page, start, end, mode); | |
| 706 | + if (unlikely(ret)) | |
| 707 | + return ret; | |
| 672 | 708 | end = 0; |
| 673 | 709 | } |
| 674 | 710 | start = next; |
| @@ -682,7 +718,9 @@ static int write_empty_blocks(struct page *page, unsigned from, unsigned to) · 7 unmodified lines | ||
| 682 | 718 | ret = __block_write_begin(page, start, end - start, gfs2_block_map); |
| 683 | 719 | if (unlikely(ret)) |
| 684 | 720 | return ret; |
| 685 | − empty_write_end(page, start, end); | |
| 721 | + ret = empty_write_end(page, start, end, mode); | |
| 722 | + if (unlikely(ret)) | |
| 723 | + return ret; | |
| 686 | 724 | } |
| 687 | 725 | |
| 688 | 726 | return 0; |
| @@ -731,7 +769,7 @@ static int fallocate_chunk(struct inode *inode, loff_t offset, loff_t len, · 42 unmodified lines | ||
| 731 | 769 | |
| 732 | 770 | if (curr == end) |
| 733 | 771 | to = end_offset; |
| 734 | − error = write_empty_blocks(page, from, to); | |
| 772 | + error = write_empty_blocks(page, from, to, mode); | |
| 735 | 773 | if (!error && offset + to > inode->i_size && |
| 736 | 774 | !(mode & FALLOC_FL_KEEP_SIZE)) { |
| 737 | 775 | i_size_write(inode, offset + to); |
| @@ -93,14 +93,12 @@ static unsigned int gl_hash(const struct gfs2_sbd *sdp, · 92 unmodified lines | ||
| 93 | 93 | |
| 94 | 94 | static inline void spin_lock_bucket(unsigned int hash) |
| 95 | 95 | { |
| 96 | − struct hlist_bl_head *bl = &gl_hash_table[hash]; | |
| 97 | − bit_spin_lock(0, (unsigned long *)bl); | |
| 96 | + hlist_bl_lock(&gl_hash_table[hash]); | |
| 98 | 97 | } |
| 99 | 98 | |
| 100 | 99 | static inline void spin_unlock_bucket(unsigned int hash) |
| 101 | 100 | { |
| 102 | − struct hlist_bl_head *bl = &gl_hash_table[hash]; | |
| 103 | − __bit_spin_unlock(0, (unsigned long *)bl); | |
| 101 | + hlist_bl_unlock(&gl_hash_table[hash]); | |
| 104 | 102 | } |
| 105 | 103 | |
| 106 | 104 | static void gfs2_glock_dealloc(struct rcu_head *rcu) |
| @@ -385,6 +385,10 @@ static int trans_go_demote_ok(const struct gfs2_glock *gl) · 384 unmodified lines | ||
| 385 | 385 | static void iopen_go_callback(struct gfs2_glock *gl) |
| 386 | 386 | { |
| 387 | 387 | struct gfs2_inode *ip = (struct gfs2_inode *)gl->gl_object; |
| 388 | + struct gfs2_sbd *sdp = gl->gl_sbd; | |
| 389 | + | |
| 390 | + if (sdp->sd_vfs->s_flags & MS_RDONLY) | |
| 391 | + return; | |
| 388 | 392 | |
| 389 | 393 | if (gl->gl_demote_state == LM_ST_UNLOCKED && |
| 390 | 394 | gl->gl_state == LM_ST_SHARED && ip) { |
| @@ -40,37 +40,61 @@ struct gfs2_inum_range_host { · 39 unmodified lines | ||
| 40 | 40 | u64 ir_length; |
| 41 | 41 | }; |
| 42 | 42 | |
| 43 | +struct gfs2_skip_data { | |
| 44 | + u64 no_addr; | |
| 45 | + int skipped; | |
| 46 | + int non_block; | |
| 47 | +}; | |
| 48 | + | |
| 43 | 49 | static int iget_test(struct inode *inode, void *opaque) |
| 44 | 50 | { |
| 45 | 51 | struct gfs2_inode *ip = GFS2_I(inode); |
| 46 | − u64 *no_addr = opaque; | |
| 52 | + struct gfs2_skip_data *data = opaque; | |
| 47 | 53 | |
| 48 | − if (ip->i_no_addr == *no_addr) | |
| 54 | + if (ip->i_no_addr == data->no_addr) { | |
| 55 | + if (data->non_block && | |
| 56 | + inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) { | |
| 57 | + data->skipped = 1; | |
| 58 | + return 0; | |
| 59 | + } | |
| 49 | 60 | return 1; |
| 50 | − | |
| 61 | + } | |
| 51 | 62 | return 0; |
| 52 | 63 | } |
| 53 | 64 | |
| 54 | 65 | static int iget_set(struct inode *inode, void *opaque) |
| 55 | 66 | { |
| 56 | 67 | struct gfs2_inode *ip = GFS2_I(inode); |
| 57 | − u64 *no_addr = opaque; | |
| 68 | + struct gfs2_skip_data *data = opaque; | |
| 58 | 69 | |
| 59 | − inode->i_ino = (unsigned long)*no_addr; | |
| 60 | − ip->i_no_addr = *no_addr; | |
| 70 | + if (data->skipped) | |
| 71 | + return -ENOENT; | |
| 72 | + inode->i_ino = (unsigned long)(data->no_addr); | |
| 73 | + ip->i_no_addr = data->no_addr; | |
| 61 | 74 | return 0; |
| 62 | 75 | } |
| 63 | 76 | |
| 64 | 77 | struct inode *gfs2_ilookup(struct super_block *sb, u64 no_addr) |
| 65 | 78 | { |
| 66 | 79 | unsigned long hash = (unsigned long)no_addr; |
| 67 | − return ilookup5(sb, hash, iget_test, &no_addr); | |
| 80 | + struct gfs2_skip_data data; | |
| 81 | + | |
| 82 | + data.no_addr = no_addr; | |
| 83 | + data.skipped = 0; | |
| 84 | + data.non_block = 0; | |
| 85 | + return ilookup5(sb, hash, iget_test, &data); | |
| 68 | 86 | } |
| 69 | 87 | |
| 70 | −static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr) | |
| 88 | +static struct inode *gfs2_iget(struct super_block *sb, u64 no_addr, | |
| 89 | + int non_block) | |
| 71 | 90 | { |
| 91 | + struct gfs2_skip_data data; | |
| 72 | 92 | unsigned long hash = (unsigned long)no_addr; |
| 73 | − return iget5_locked(sb, hash, iget_test, iget_set, &no_addr); | |
| 93 | + | |
| 94 | + data.no_addr = no_addr; | |
| 95 | + data.skipped = 0; | |
| 96 | + data.non_block = non_block; | |
| 97 | + return iget5_locked(sb, hash, iget_test, iget_set, &data); | |
| 74 | 98 | } |
| 75 | 99 | |
| 76 | 100 | /** |
| @@ -111,19 +135,20 @@ static void gfs2_set_iop(struct inode *inode) · 34 unmodified lines | ||
| 111 | 135 | * @sb: The super block |
| 112 | 136 | * @no_addr: The inode number |
| 113 | 137 | * @type: The type of the inode |
| 138 | + * non_block: Can we block on inodes that are being freed? | |
| 114 | 139 | * |
| 115 | 140 | * Returns: A VFS inode, or an error |
| 116 | 141 | */ |
| 117 | 142 | |
| 118 | 143 | struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, |
| 119 | − u64 no_addr, u64 no_formal_ino) | |
| 144 | + u64 no_addr, u64 no_formal_ino, int non_block) | |
| 120 | 145 | { |
| 121 | 146 | struct inode *inode; |
| 122 | 147 | struct gfs2_inode *ip; |
| 123 | 148 | struct gfs2_glock *io_gl = NULL; |
| 124 | 149 | int error; |
| 125 | 150 | |
| 126 | − inode = gfs2_iget(sb, no_addr); | |
| 151 | + inode = gfs2_iget(sb, no_addr, non_block); | |
| 127 | 152 | ip = GFS2_I(inode); |
| 128 | 153 | |
| 129 | 154 | if (!inode) |
| @@ -185,11 +210,12 @@ struct inode *gfs2_lookup_by_inum(struct gfs2_sbd *sdp, u64 no_addr, · 55 unmodified lines | ||
| 185 | 210 | { |
| 186 | 211 | struct super_block *sb = sdp->sd_vfs; |
| 187 | 212 | struct gfs2_holder i_gh; |
| 188 | − struct inode *inode; | |
| 213 | + struct inode *inode = NULL; | |
| 189 | 214 | int error; |
| 190 | 215 | |
| 216 | + /* Must not read in block until block type is verified */ | |
| 191 | 217 | error = gfs2_glock_nq_num(sdp, no_addr, &gfs2_inode_glops, |
| 192 | − LM_ST_SHARED, LM_FLAG_ANY, &i_gh); | |
| 218 | + LM_ST_EXCLUSIVE, GL_SKIP, &i_gh); | |
| 193 | 219 | if (error) |
| 194 | 220 | return ERR_PTR(error); |
| 195 | 221 | |
| @@ -197,7 +223,7 @@ struct inode *gfs2_lookup_by_inum(struct gfs2_sbd *sdp, u64 no_addr, · 1 unmodified line | ||
| 197 | 223 | if (error) |
| 198 | 224 | goto fail; |
| 199 | 225 | |
| 200 | − inode = gfs2_inode_lookup(sb, DT_UNKNOWN, no_addr, 0); | |
| 226 | + inode = gfs2_inode_lookup(sb, DT_UNKNOWN, no_addr, 0, 1); | |
| 201 | 227 | if (IS_ERR(inode)) |
| 202 | 228 | goto fail; |
| 203 | 229 | |
| @@ -843,7 +869,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, · 639 unmodified lines | ||
| 843 | 869 | goto fail_gunlock2; |
| 844 | 870 | |
| 845 | 871 | inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode), inum.no_addr, |
| 846 | − inum.no_formal_ino); | |
| 872 | + inum.no_formal_ino, 0); | |
| 847 | 873 | if (IS_ERR(inode)) |
| 848 | 874 | goto fail_gunlock2; |
| 849 | 875 | |
| @@ -97,7 +97,8 @@ err: · 96 unmodified lines | ||
| 97 | 97 | } |
| 98 | 98 | |
| 99 | 99 | extern struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, |
| 100 | − u64 no_addr, u64 no_formal_ino); | |
| 100 | + u64 no_addr, u64 no_formal_ino, | |
| 101 | + int non_block); | |
| 101 | 102 | extern struct inode *gfs2_lookup_by_inum(struct gfs2_sbd *sdp, u64 no_addr, |
| 102 | 103 | u64 *no_formal_ino, |
| 103 | 104 | unsigned int blktype); |
| @@ -430,7 +430,7 @@ static int gfs2_lookup_root(struct super_block *sb, struct dentry **dptr, · 429 unmodified lines | ||
| 430 | 430 | struct dentry *dentry; |
| 431 | 431 | struct inode *inode; |
| 432 | 432 | |
| 433 | − inode = gfs2_inode_lookup(sb, DT_DIR, no_addr, 0); | |
| 433 | + inode = gfs2_inode_lookup(sb, DT_DIR, no_addr, 0, 0); | |
| 434 | 434 | if (IS_ERR(inode)) { |
| 435 | 435 | fs_err(sdp, "can't read in %s inode: %ld\n", name, PTR_ERR(inode)); |
| 436 | 436 | return PTR_ERR(inode); |
| @@ -945,7 +945,7 @@ static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip · 944 unmodified lines | ||
| 945 | 945 | /* rgblk_search can return a block < goal, so we need to |
| 946 | 946 | keep it marching forward. */ |
| 947 | 947 | no_addr = block + rgd->rd_data0; |
| 948 | − goal++; | |
| 948 | + goal = max(block + 1, goal + 1); | |
| 949 | 949 | if (*last_unlinked != NO_BLOCK && no_addr <= *last_unlinked) |
| 950 | 950 | continue; |
| 951 | 951 | if (no_addr == skip) |
| @@ -971,7 +971,7 @@ static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip · 19 unmodified lines | ||
| 971 | 971 | found++; |
| 972 | 972 | |
| 973 | 973 | /* Limit reclaim to sensible number of tasks */ |
| 974 | − if (found > 2*NR_CPUS) | |
| 974 | + if (found > NR_CPUS) | |
| 975 | 975 | return; |
| 976 | 976 | } |
| 977 | 977 | |
| @@ -1318,15 +1318,17 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt) · 1317 unmodified lines | ||
| 1318 | 1318 | |
| 1319 | 1319 | static void gfs2_evict_inode(struct inode *inode) |
| 1320 | 1320 | { |
| 1321 | − struct gfs2_sbd *sdp = inode->i_sb->s_fs_info; | |
| 1321 | + struct super_block *sb = inode->i_sb; | |
| 1322 | + struct gfs2_sbd *sdp = sb->s_fs_info; | |
| 1322 | 1323 | struct gfs2_inode *ip = GFS2_I(inode); |
| 1323 | 1324 | struct gfs2_holder gh; |
| 1324 | 1325 | int error; |
| 1325 | 1326 | |
| 1326 | − if (inode->i_nlink) | |
| 1327 | + if (inode->i_nlink || (sb->s_flags & MS_RDONLY)) | |
| 1327 | 1328 | goto out; |
| 1328 | 1329 | |
| 1329 | − error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | |
| 1330 | + /* Must not read inode block until block type has been verified */ | |
| 1331 | + error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, &gh); | |
| 1330 | 1332 | if (unlikely(error)) { |
| 1331 | 1333 | gfs2_glock_dq_uninit(&ip->i_iopen_gh); |
| 1332 | 1334 | goto out; |
| @@ -1336,6 +1338,12 @@ static void gfs2_evict_inode(struct inode *inode) · 3 unmodified lines | ||
| 1336 | 1338 | if (error) |
| 1337 | 1339 | goto out_truncate; |
| 1338 | 1340 | |
| 1341 | + if (test_bit(GIF_INVALID, &ip->i_flags)) { | |
| 1342 | + error = gfs2_inode_refresh(ip); | |
| 1343 | + if (error) | |
| 1344 | + goto out_truncate; | |
| 1345 | + } | |
| 1346 | + | |
| 1339 | 1347 | ip->i_iopen_gh.gh_flags |= GL_NOCACHE; |
| 1340 | 1348 | gfs2_glock_dq_wait(&ip->i_iopen_gh); |
| 1341 | 1349 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh); |
| @@ -1,7 +1,6 @@ | ||
| 1 | 1 | config HPFS_FS |
| 2 | 2 | tristate "OS/2 HPFS file system support" |
| 3 | 3 | depends on BLOCK |
| 4 | − depends on BROKEN || !PREEMPT | |
| 5 | 4 | help |
| 6 | 5 | OS/2 is IBM's operating system for PC's, the same as Warp, and HPFS |
| 7 | 6 | is the file system used for organizing files on OS/2 hard disk |
| @@ -8,8 +8,6 @@ · 7 unmodified lines | ||
| 8 | 8 | |
| 9 | 9 | #include "hpfs_fn.h" |
| 10 | 10 | |
| 11 | −static int hpfs_alloc_if_possible_nolock(struct super_block *s, secno sec); | |
| 12 | − | |
| 13 | 11 | /* |
| 14 | 12 | * Check if a sector is allocated in bitmap |
| 15 | 13 | * This is really slow. Turned on only if chk==2 |
| @@ -18,9 +16,9 @@ static int hpfs_alloc_if_possible_nolock(struct super_block *s, secno sec); · 2 unmodified lines | ||
| 18 | 16 | static int chk_if_allocated(struct super_block *s, secno sec, char *msg) |
| 19 | 17 | { |
| 20 | 18 | struct quad_buffer_head qbh; |
| 21 | − unsigned *bmp; | |
| 19 | + u32 *bmp; | |
| 22 | 20 | if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "chk"))) goto fail; |
| 23 | − if ((bmp[(sec & 0x3fff) >> 5] >> (sec & 0x1f)) & 1) { | |
| 21 | + if ((cpu_to_le32(bmp[(sec & 0x3fff) >> 5]) >> (sec & 0x1f)) & 1) { | |
| 24 | 22 | hpfs_error(s, "sector '%s' - %08x not allocated in bitmap", msg, sec); |
| 25 | 23 | goto fail1; |
| 26 | 24 | } |
| @@ -28,7 +26,7 @@ static int chk_if_allocated(struct super_block *s, secno sec, char *msg) · 1 unmodified line | ||
| 28 | 26 | if (sec >= hpfs_sb(s)->sb_dirband_start && sec < hpfs_sb(s)->sb_dirband_start + hpfs_sb(s)->sb_dirband_size) { |
| 29 | 27 | unsigned ssec = (sec - hpfs_sb(s)->sb_dirband_start) / 4; |
| 30 | 28 | if (!(bmp = hpfs_map_dnode_bitmap(s, &qbh))) goto fail; |
| 31 | − if ((bmp[ssec >> 5] >> (ssec & 0x1f)) & 1) { | |
| 29 | + if ((le32_to_cpu(bmp[ssec >> 5]) >> (ssec & 0x1f)) & 1) { | |
| 32 | 30 | hpfs_error(s, "sector '%s' - %08x not allocated in directory bitmap", msg, sec); |
| 33 | 31 | goto fail1; |
| 34 | 32 | } |
| @@ -75,7 +73,6 @@ static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigne · 40 unmodified lines | ||
| 75 | 73 | hpfs_error(s, "Bad allocation size: %d", n); |
| 76 | 74 | return 0; |
| 77 | 75 | } |
| 78 | − lock_super(s); | |
| 79 | 76 | if (bs != ~0x3fff) { |
| 80 | 77 | if (!(bmp = hpfs_map_bitmap(s, near >> 14, &qbh, "aib"))) goto uls; |
| 81 | 78 | } else { |
| @@ -85,10 +82,6 @@ static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigne · 3 unmodified lines | ||
| 85 | 82 | ret = bs + nr; |
| 86 | 83 | goto rt; |
| 87 | 84 | } |
| 88 | − /*if (!tstbits(bmp, nr + n, n + forward)) { | |
| 89 | − ret = bs + nr + n; | |
| 90 | − goto rt; | |
| 91 | − }*/ | |
| 92 | 85 | q = nr + n; b = 0; |
| 93 | 86 | while ((a = tstbits(bmp, q, n + forward)) != 0) { |
| 94 | 87 | q += a; |
| @@ -105,14 +98,14 @@ static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigne · 10 unmodified lines | ||
| 105 | 98 | goto rt; |
| 106 | 99 | } |
| 107 | 100 | nr >>= 5; |
| 108 | − /*for (i = nr + 1; i != nr; i++, i &= 0x1ff) {*/ | |
| 101 | + /*for (i = nr + 1; i != nr; i++, i &= 0x1ff) */ | |
| 109 | 102 | i = nr; |
| 110 | 103 | do { |
| 111 | − if (!bmp[i]) goto cont; | |
| 112 | − if (n + forward >= 0x3f && bmp[i] != -1) goto cont; | |
| 104 | + if (!le32_to_cpu(bmp[i])) goto cont; | |
| 105 | + if (n + forward >= 0x3f && le32_to_cpu(bmp[i]) != 0xffffffff) goto cont; | |
| 113 | 106 | q = i<<5; |
| 114 | 107 | if (i > 0) { |
| 115 | − unsigned k = bmp[i-1]; | |
| 108 | + unsigned k = le32_to_cpu(bmp[i-1]); | |
| 116 | 109 | while (k & 0x80000000) { |
| 117 | 110 | q--; k <<= 1; |
| 118 | 111 | } |
| @@ -132,18 +125,17 @@ static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigne · 13 unmodified lines | ||
| 132 | 125 | } while (i != nr); |
| 133 | 126 | rt: |
| 134 | 127 | if (ret) { |
| 135 | − if (hpfs_sb(s)->sb_chk && ((ret >> 14) != (bs >> 14) || (bmp[(ret & 0x3fff) >> 5] | ~(((1 << n) - 1) << (ret & 0x1f))) != 0xffffffff)) { | |
| 128 | + if (hpfs_sb(s)->sb_chk && ((ret >> 14) != (bs >> 14) || (le32_to_cpu(bmp[(ret & 0x3fff) >> 5]) | ~(((1 << n) - 1) << (ret & 0x1f))) != 0xffffffff)) { | |
| 136 | 129 | hpfs_error(s, "Allocation doesn't work! Wanted %d, allocated at %08x", n, ret); |
| 137 | 130 | ret = 0; |
| 138 | 131 | goto b; |
| 139 | 132 | } |
| 140 | − bmp[(ret & 0x3fff) >> 5] &= ~(((1 << n) - 1) << (ret & 0x1f)); | |
| 133 | + bmp[(ret & 0x3fff) >> 5] &= cpu_to_le32(~(((1 << n) - 1) << (ret & 0x1f))); | |
| 141 | 134 | hpfs_mark_4buffers_dirty(&qbh); |
| 142 | 135 | } |
| 143 | 136 | b: |
| 144 | 137 | hpfs_brelse4(&qbh); |
| 145 | 138 | uls: |
| 146 | − unlock_super(s); | |
| 147 | 139 | return ret; |
| 148 | 140 | } |
| 149 | 141 | |
| @@ -155,7 +147,7 @@ static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigne · 5 unmodified lines | ||
| 155 | 147 | * sectors |
| 156 | 148 | */ |
| 157 | 149 | |
| 158 | −secno hpfs_alloc_sector(struct super_block *s, secno near, unsigned n, int forward, int lock) | |
| 150 | +secno hpfs_alloc_sector(struct super_block *s, secno near, unsigned n, int forward) | |
| 159 | 151 | { |
| 160 | 152 | secno sec; |
| 161 | 153 | int i; |
| @@ -167,7 +159,6 @@ secno hpfs_alloc_sector(struct super_block *s, secno near, unsigned n, int forwa · 5 unmodified lines | ||
| 167 | 159 | forward = -forward; |
| 168 | 160 | f_p = 1; |
| 169 | 161 | } |
| 170 | − if (lock) hpfs_lock_creation(s); | |
| 171 | 162 | n_bmps = (sbi->sb_fs_size + 0x4000 - 1) >> 14; |
| 172 | 163 | if (near && near < sbi->sb_fs_size) { |
| 173 | 164 | if ((sec = alloc_in_bmp(s, near, n, f_p ? forward : forward/4))) goto ret; |
| @@ -214,18 +205,17 @@ secno hpfs_alloc_sector(struct super_block *s, secno near, unsigned n, int forwa · 40 unmodified lines | ||
| 214 | 205 | ret: |
| 215 | 206 | if (sec && f_p) { |
| 216 | 207 | for (i = 0; i < forward; i++) { |
| 217 | − if (!hpfs_alloc_if_possible_nolock(s, sec + i + 1)) { | |
| 208 | + if (!hpfs_alloc_if_possible(s, sec + i + 1)) { | |
| 218 | 209 | hpfs_error(s, "Prealloc doesn't work! Wanted %d, allocated at %08x, can't allocate %d", forward, sec, i); |
| 219 | 210 | sec = 0; |
| 220 | 211 | break; |
| 221 | 212 | } |
| 222 | 213 | } |
| 223 | 214 | } |
| 224 | − if (lock) hpfs_unlock_creation(s); | |
| 225 | 215 | return sec; |
| 226 | 216 | } |
| 227 | 217 | |
| 228 | −static secno alloc_in_dirband(struct super_block *s, secno near, int lock) | |
| 218 | +static secno alloc_in_dirband(struct super_block *s, secno near) | |
| 229 | 219 | { |
| 230 | 220 | unsigned nr = near; |
| 231 | 221 | secno sec; |
| @@ -236,49 +226,35 @@ static secno alloc_in_dirband(struct super_block *s, secno near, int lock) · 4 unmodified lines | ||
| 236 | 226 | nr = sbi->sb_dirband_start + sbi->sb_dirband_size - 4; |
| 237 | 227 | nr -= sbi->sb_dirband_start; |
| 238 | 228 | nr >>= 2; |
| 239 | − if (lock) hpfs_lock_creation(s); | |
| 240 | 229 | sec = alloc_in_bmp(s, (~0x3fff) | nr, 1, 0); |
| 241 | − if (lock) hpfs_unlock_creation(s); | |
| 242 | 230 | if (!sec) return 0; |
| 243 | 231 | return ((sec & 0x3fff) << 2) + sbi->sb_dirband_start; |
| 244 | 232 | } |
| 245 | 233 | |
| 246 | 234 | /* Alloc sector if it's free */ |
| 247 | 235 | |
| 248 | −static int hpfs_alloc_if_possible_nolock(struct super_block *s, secno sec) | |
| 236 | +int hpfs_alloc_if_possible(struct super_block *s, secno sec) | |
| 249 | 237 | { |
| 250 | 238 | struct quad_buffer_head qbh; |
| 251 | − unsigned *bmp; | |
| 252 | − lock_super(s); | |
| 239 | + u32 *bmp; | |
| 253 | 240 | if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "aip"))) goto end; |
| 254 | − if (bmp[(sec & 0x3fff) >> 5] & (1 << (sec & 0x1f))) { | |
| 255 | − bmp[(sec & 0x3fff) >> 5] &= ~(1 << (sec & 0x1f)); | |
| 241 | + if (le32_to_cpu(bmp[(sec & 0x3fff) >> 5]) & (1 << (sec & 0x1f))) { | |
| 242 | + bmp[(sec & 0x3fff) >> 5] &= cpu_to_le32(~(1 << (sec & 0x1f))); | |
| 256 | 243 | hpfs_mark_4buffers_dirty(&qbh); |
| 257 | 244 | hpfs_brelse4(&qbh); |
| 258 | − unlock_super(s); | |
| 259 | 245 | return 1; |
| 260 | 246 | } |
| 261 | 247 | hpfs_brelse4(&qbh); |
| 262 | 248 | end: |
| 263 | − unlock_super(s); | |
| 264 | 249 | return 0; |
| 265 | 250 | } |
| 266 | 251 | |
| 267 | −int hpfs_alloc_if_possible(struct super_block *s, secno sec) | |
| 268 | −{ | |
| 269 | − int r; | |
| 270 | − hpfs_lock_creation(s); | |
| 271 | − r = hpfs_alloc_if_possible_nolock(s, sec); | |
| 272 | − hpfs_unlock_creation(s); | |
| 273 | − return r; | |
| 274 | −} | |
| 275 | − | |
| 276 | 252 | /* Free sectors in bitmaps */ |
| 277 | 253 | |
| 278 | 254 | void hpfs_free_sectors(struct super_block *s, secno sec, unsigned n) |
| 279 | 255 | { |
| 280 | 256 | struct quad_buffer_head qbh; |
| 281 | − unsigned *bmp; | |
| 257 | + u32 *bmp; | |
| 282 | 258 | struct hpfs_sb_info *sbi = hpfs_sb(s); |
| 283 | 259 | /*printk("2 - ");*/ |
| 284 | 260 | if (!n) return; |
| @@ -286,26 +262,22 @@ void hpfs_free_sectors(struct super_block *s, secno sec, unsigned n) · 1 unmodified line | ||
| 286 | 262 | hpfs_error(s, "Trying to free reserved sector %08x", sec); |
| 287 | 263 | return; |
| 288 | 264 | } |
| 289 | − lock_super(s); | |
| 290 | 265 | sbi->sb_max_fwd_alloc += n > 0xffff ? 0xffff : n; |
| 291 | 266 | if (sbi->sb_max_fwd_alloc > 0xffffff) sbi->sb_max_fwd_alloc = 0xffffff; |
| 292 | 267 | new_map: |
| 293 | 268 | if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "free"))) { |
| 294 | − unlock_super(s); | |
| 295 | 269 | return; |
| 296 | 270 | } |
| 297 | 271 | new_tst: |
| 298 | − if ((bmp[(sec & 0x3fff) >> 5] >> (sec & 0x1f) & 1)) { | |
| 272 | + if ((le32_to_cpu(bmp[(sec & 0x3fff) >> 5]) >> (sec & 0x1f) & 1)) { | |
| 299 | 273 | hpfs_error(s, "sector %08x not allocated", sec); |
| 300 | 274 | hpfs_brelse4(&qbh); |
| 301 | − unlock_super(s); | |
| 302 | 275 | return; |
| 303 | 276 | } |
| 304 | − bmp[(sec & 0x3fff) >> 5] |= 1 << (sec & 0x1f); | |
| 277 | + bmp[(sec & 0x3fff) >> 5] |= cpu_to_le32(1 << (sec & 0x1f)); | |
| 305 | 278 | if (!--n) { |
| 306 | 279 | hpfs_mark_4buffers_dirty(&qbh); |
| 307 | 280 | hpfs_brelse4(&qbh); |
| 308 | − unlock_super(s); | |
| 309 | 281 | return; |
| 310 | 282 | } |
| 311 | 283 | if (!(++sec & 0x3fff)) { |
| @@ -327,13 +299,13 @@ int hpfs_check_free_dnodes(struct super_block *s, int n) · 15 unmodified lines | ||
| 327 | 299 | int n_bmps = (hpfs_sb(s)->sb_fs_size + 0x4000 - 1) >> 14; |
| 328 | 300 | int b = hpfs_sb(s)->sb_c_bitmap & 0x0fffffff; |
| 329 | 301 | int i, j; |
| 330 | − unsigned *bmp; | |
| 302 | + u32 *bmp; | |
| 331 | 303 | struct quad_buffer_head qbh; |
| 332 | 304 | if ((bmp = hpfs_map_dnode_bitmap(s, &qbh))) { |
| 333 | 305 | for (j = 0; j < 512; j++) { |
| 334 | 306 | unsigned k; |
| 335 | − if (!bmp[j]) continue; | |
| 336 | − for (k = bmp[j]; k; k >>= 1) if (k & 1) if (!--n) { | |
| 307 | + if (!le32_to_cpu(bmp[j])) continue; | |
| 308 | + for (k = le32_to_cpu(bmp[j]); k; k >>= 1) if (k & 1) if (!--n) { | |
| 337 | 309 | hpfs_brelse4(&qbh); |
| 338 | 310 | return 0; |
| 339 | 311 | } |
| @@ -352,10 +324,10 @@ int hpfs_check_free_dnodes(struct super_block *s, int n) · 12 unmodified lines | ||
| 352 | 324 | chk_bmp: |
| 353 | 325 | if (bmp) { |
| 354 | 326 | for (j = 0; j < 512; j++) { |
| 355 | − unsigned k; | |
| 356 | − if (!bmp[j]) continue; | |
| 327 | + u32 k; | |
| 328 | + if (!le32_to_cpu(bmp[j])) continue; | |
| 357 | 329 | for (k = 0xf; k; k <<= 4) |
| 358 | − if ((bmp[j] & k) == k) { | |
| 330 | + if ((le32_to_cpu(bmp[j]) & k) == k) { | |
| 359 | 331 | if (!--n) { |
| 360 | 332 | hpfs_brelse4(&qbh); |
| 361 | 333 | return 0; |
| @@ -379,44 +351,40 @@ void hpfs_free_dnode(struct super_block *s, dnode_secno dno) · 17 unmodified lines | ||
| 379 | 351 | hpfs_free_sectors(s, dno, 4); |
| 380 | 352 | } else { |
| 381 | 353 | struct quad_buffer_head qbh; |
| 382 | − unsigned *bmp; | |
| 354 | + u32 *bmp; | |
| 383 | 355 | unsigned ssec = (dno - hpfs_sb(s)->sb_dirband_start) / 4; |
| 384 | − lock_super(s); | |
| 385 | 356 | if (!(bmp = hpfs_map_dnode_bitmap(s, &qbh))) { |
| 386 | − unlock_super(s); | |
| 387 | 357 | return; |
| 388 | 358 | } |
| 389 | − bmp[ssec >> 5] |= 1 << (ssec & 0x1f); | |
| 359 | + bmp[ssec >> 5] |= cpu_to_le32(1 << (ssec & 0x1f)); | |
| 390 | 360 | hpfs_mark_4buffers_dirty(&qbh); |
| 391 | 361 | hpfs_brelse4(&qbh); |
| 392 | − unlock_super(s); | |
| 393 | 362 | } |
| 394 | 363 | } |
| 395 | 364 | |
| 396 | 365 | struct dnode *hpfs_alloc_dnode(struct super_block *s, secno near, |
| 397 | − dnode_secno *dno, struct quad_buffer_head *qbh, | |
| 398 | − int lock) | |
| 366 | + dnode_secno *dno, struct quad_buffer_head *qbh) | |
| 399 | 367 | { |
| 400 | 368 | struct dnode *d; |
| 401 | 369 | if (hpfs_count_one_bitmap(s, hpfs_sb(s)->sb_dmap) > FREE_DNODES_ADD) { |
| 402 | − if (!(*dno = alloc_in_dirband(s, near, lock))) | |
| 403 | − if (!(*dno = hpfs_alloc_sector(s, near, 4, 0, lock))) return NULL; | |
| 370 | + if (!(*dno = alloc_in_dirband(s, near))) | |
| 371 | + if (!(*dno = hpfs_alloc_sector(s, near, 4, 0))) return NULL; | |
| 404 | 372 | } else { |
| 405 | − if (!(*dno = hpfs_alloc_sector(s, near, 4, 0, lock))) | |
| 406 | − if (!(*dno = alloc_in_dirband(s, near, lock))) return NULL; | |
| 373 | + if (!(*dno = hpfs_alloc_sector(s, near, 4, 0))) | |
| 374 | + if (!(*dno = alloc_in_dirband(s, near))) return NULL; | |
| 407 | 375 | } |
| 408 | 376 | if (!(d = hpfs_get_4sectors(s, *dno, qbh))) { |
| 409 | 377 | hpfs_free_dnode(s, *dno); |
| 410 | 378 | return NULL; |
| 411 | 379 | } |
| 412 | 380 | memset(d, 0, 2048); |
| 413 | − d->magic = DNODE_MAGIC; | |
| 414 | − d->first_free = 52; | |
| 381 | + d->magic = cpu_to_le32(DNODE_MAGIC); | |
| 382 | + d->first_free = cpu_to_le32(52); | |
| 415 | 383 | d->dirent[0] = 32; |
| 416 | 384 | d->dirent[2] = 8; |
| 417 | 385 | d->dirent[30] = 1; |
| 418 | 386 | d->dirent[31] = 255; |
| 419 | − d->self = *dno; | |
| 387 | + d->self = cpu_to_le32(*dno); | |
| 420 | 388 | return d; |
| 421 | 389 | } |
| 422 | 390 | |
| @@ -424,16 +392,16 @@ struct fnode *hpfs_alloc_fnode(struct super_block *s, secno near, fnode_secno *f · 1 unmodified line | ||
| 424 | 392 | struct buffer_head **bh) |
| 425 | 393 | { |
| 426 | 394 | struct fnode *f; |
| 427 | − if (!(*fno = hpfs_alloc_sector(s, near, 1, FNODE_ALLOC_FWD, 1))) return NULL; | |
| 395 | + if (!(*fno = hpfs_alloc_sector(s, near, 1, FNODE_ALLOC_FWD))) return NULL; | |
| 428 | 396 | if (!(f = hpfs_get_sector(s, *fno, bh))) { |
| 429 | 397 | hpfs_free_sectors(s, *fno, 1); |
| 430 | 398 | return NULL; |
| 431 | 399 | } |
| 432 | 400 | memset(f, 0, 512); |
| 433 | − f->magic = FNODE_MAGIC; | |
| 434 | − f->ea_offs = 0xc4; | |
| 401 | + f->magic = cpu_to_le32(FNODE_MAGIC); | |
| 402 | + f->ea_offs = cpu_to_le16(0xc4); | |
| 435 | 403 | f->btree.n_free_nodes = 8; |
| 436 | − f->btree.first_free = 8; | |
| 404 | + f->btree.first_free = cpu_to_le16(8); | |
| 437 | 405 | return f; |
| 438 | 406 | } |
| 439 | 407 | |
| @@ -441,16 +409,16 @@ struct anode *hpfs_alloc_anode(struct super_block *s, secno near, anode_secno *a · 1 unmodified line | ||
| 441 | 409 | struct buffer_head **bh) |
| 442 | 410 | { |
| 443 | 411 | struct anode *a; |
| 444 | − if (!(*ano = hpfs_alloc_sector(s, near, 1, ANODE_ALLOC_FWD, 1))) return NULL; | |
| 412 | + if (!(*ano = hpfs_alloc_sector(s, near, 1, ANODE_ALLOC_FWD))) return NULL; | |
| 445 | 413 | if (!(a = hpfs_get_sector(s, *ano, bh))) { |
| 446 | 414 | hpfs_free_sectors(s, *ano, 1); |
| 447 | 415 | return NULL; |
| 448 | 416 | } |
| 449 | 417 | memset(a, 0, 512); |
| 450 | − a->magic = ANODE_MAGIC; | |
| 451 | − a->self = *ano; | |
| 418 | + a->magic = cpu_to_le32(ANODE_MAGIC); | |
| 419 | + a->self = cpu_to_le32(*ano); | |
| 452 | 420 | a->btree.n_free_nodes = 40; |
| 453 | 421 | a->btree.n_used_nodes = 0; |
| 454 | − a->btree.first_free = 8; | |
| 422 | + a->btree.first_free = cpu_to_le16(8); | |
| 455 | 423 | return a; |
| 456 | 424 | } |
| @@ -22,8 +22,8 @@ secno hpfs_bplus_lookup(struct super_block *s, struct inode *inode, · 21 unmodified lines | ||
| 22 | 22 | if (hpfs_sb(s)->sb_chk) if (hpfs_stop_cycles(s, a, &c1, &c2, "hpfs_bplus_lookup")) return -1; |
| 23 | 23 | if (btree->internal) { |
| 24 | 24 | for (i = 0; i < btree->n_used_nodes; i++) |
| 25 | − if (btree->u.internal[i].file_secno > sec) { | |
| 26 | − a = btree->u.internal[i].down; | |
| 25 | + if (le32_to_cpu(btree->u.internal[i].file_secno) > sec) { | |
| 26 | + a = le32_to_cpu(btree->u.internal[i].down); | |
| 27 | 27 | brelse(bh); |
| 28 | 28 | if (!(anode = hpfs_map_anode(s, a, &bh))) return -1; |
| 29 | 29 | btree = &anode->btree; |
| @@ -34,18 +34,18 @@ secno hpfs_bplus_lookup(struct super_block *s, struct inode *inode, · 4 unmodified lines | ||
| 34 | 34 | return -1; |
| 35 | 35 | } |
| 36 | 36 | for (i = 0; i < btree->n_used_nodes; i++) |
| 37 | − if (btree->u.external[i].file_secno <= sec && | |
| 38 | − btree->u.external[i].file_secno + btree->u.external[i].length > sec) { | |
| 39 | − a = btree->u.external[i].disk_secno + sec - btree->u.external[i].file_secno; | |
| 37 | + if (le32_to_cpu(btree->u.external[i].file_secno) <= sec && | |
| 38 | + le32_to_cpu(btree->u.external[i].file_secno) + le32_to_cpu(btree->u.external[i].length) > sec) { | |
| 39 | + a = le32_to_cpu(btree->u.external[i].disk_secno) + sec - le32_to_cpu(btree->u.external[i].file_secno); | |
| 40 | 40 | if (hpfs_sb(s)->sb_chk) if (hpfs_chk_sectors(s, a, 1, "data")) { |
| 41 | 41 | brelse(bh); |
| 42 | 42 | return -1; |
| 43 | 43 | } |
| 44 | 44 | if (inode) { |
| 45 | 45 | struct hpfs_inode_info *hpfs_inode = hpfs_i(inode); |
| 46 | − hpfs_inode->i_file_sec = btree->u.external[i].file_secno; | |
| 47 | − hpfs_inode->i_disk_sec = btree->u.external[i].disk_secno; | |
| 48 | − hpfs_inode->i_n_secs = btree->u.external[i].length; | |
| 46 | + hpfs_inode->i_file_sec = le32_to_cpu(btree->u.external[i].file_secno); | |
| 47 | + hpfs_inode->i_disk_sec = le32_to_cpu(btree->u.external[i].disk_secno); | |
| 48 | + hpfs_inode->i_n_secs = le32_to_cpu(btree->u.external[i].length); | |
| 49 | 49 | } |
| 50 | 50 | brelse(bh); |
| 51 | 51 | return a; |
| @@ -83,8 +83,8 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi · 31 unmodified lines | ||
| 83 | 83 | return -1; |
| 84 | 84 | } |
| 85 | 85 | if (btree->internal) { |
| 86 | − a = btree->u.internal[n].down; | |
| 87 | − btree->u.internal[n].file_secno = -1; | |
| 86 | + a = le32_to_cpu(btree->u.internal[n].down); | |
| 87 | + btree->u.internal[n].file_secno = cpu_to_le32(-1); | |
| 88 | 88 | mark_buffer_dirty(bh); |
| 89 | 89 | brelse(bh); |
| 90 | 90 | if (hpfs_sb(s)->sb_chk) |
| @@ -94,15 +94,15 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi · 3 unmodified lines | ||
| 94 | 94 | goto go_down; |
| 95 | 95 | } |
| 96 | 96 | if (n >= 0) { |
| 97 | − if (btree->u.external[n].file_secno + btree->u.external[n].length != fsecno) { | |
| 97 | + if (le32_to_cpu(btree->u.external[n].file_secno) + le32_to_cpu(btree->u.external[n].length) != fsecno) { | |
| 98 | 98 | hpfs_error(s, "allocated size %08x, trying to add sector %08x, %cnode %08x", |
| 99 | − btree->u.external[n].file_secno + btree->u.external[n].length, fsecno, | |
| 99 | + le32_to_cpu(btree->u.external[n].file_secno) + le32_to_cpu(btree->u.external[n].length), fsecno, | |
| 100 | 100 | fnod?'f':'a', node); |
| 101 | 101 | brelse(bh); |
| 102 | 102 | return -1; |
| 103 | 103 | } |
| 104 | − if (hpfs_alloc_if_possible(s, se = btree->u.external[n].disk_secno + btree->u.external[n].length)) { | |
| 105 | − btree->u.external[n].length++; | |
| 104 | + if (hpfs_alloc_if_possible(s, se = le32_to_cpu(btree->u.external[n].disk_secno) + le32_to_cpu(btree->u.external[n].length))) { | |
| 105 | + btree->u.external[n].length = cpu_to_le32(le32_to_cpu(btree->u.external[n].length) + 1); | |
| 106 | 106 | mark_buffer_dirty(bh); |
| 107 | 107 | brelse(bh); |
| 108 | 108 | return se; |
| @@ -115,20 +115,20 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi · 6 unmodified lines | ||
| 115 | 115 | } |
| 116 | 116 | se = !fnod ? node : (node + 16384) & ~16383; |
| 117 | 117 | } |
| 118 | − if (!(se = hpfs_alloc_sector(s, se, 1, fsecno*ALLOC_M>ALLOC_FWD_MAX ? ALLOC_FWD_MAX : fsecno*ALLOC_M<ALLOC_FWD_MIN ? ALLOC_FWD_MIN : fsecno*ALLOC_M, 1))) { | |
| 118 | + if (!(se = hpfs_alloc_sector(s, se, 1, fsecno*ALLOC_M>ALLOC_FWD_MAX ? ALLOC_FWD_MAX : fsecno*ALLOC_M<ALLOC_FWD_MIN ? ALLOC_FWD_MIN : fsecno*ALLOC_M))) { | |
| 119 | 119 | brelse(bh); |
| 120 | 120 | return -1; |
| 121 | 121 | } |
| 122 | − fs = n < 0 ? 0 : btree->u.external[n].file_secno + btree->u.external[n].length; | |
| 122 | + fs = n < 0 ? 0 : le32_to_cpu(btree->u.external[n].file_secno) + le32_to_cpu(btree->u.external[n].length); | |
| 123 | 123 | if (!btree->n_free_nodes) { |
| 124 | − up = a != node ? anode->up : -1; | |
| 124 | + up = a != node ? le32_to_cpu(anode->up) : -1; | |
| 125 | 125 | if (!(anode = hpfs_alloc_anode(s, a, &na, &bh1))) { |
| 126 | 126 | brelse(bh); |
| 127 | 127 | hpfs_free_sectors(s, se, 1); |
| 128 | 128 | return -1; |
| 129 | 129 | } |
| 130 | 130 | if (a == node && fnod) { |
| 131 | − anode->up = node; | |
| 131 | + anode->up = cpu_to_le32(node); | |
| 132 | 132 | anode->btree.fnode_parent = 1; |
| 133 | 133 | anode->btree.n_used_nodes = btree->n_used_nodes; |
| 134 | 134 | anode->btree.first_free = btree->first_free; |
| @@ -137,9 +137,9 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi · 2 unmodified lines | ||
| 137 | 137 | btree->internal = 1; |
| 138 | 138 | btree->n_free_nodes = 11; |
| 139 | 139 | btree->n_used_nodes = 1; |
| 140 | − btree->first_free = (char *)&(btree->u.internal[1]) - (char *)btree; | |
| 141 | − btree->u.internal[0].file_secno = -1; | |
| 142 | − btree->u.internal[0].down = na; | |
| 140 | + btree->first_free = cpu_to_le16((char *)&(btree->u.internal[1]) - (char *)btree); | |
| 141 | + btree->u.internal[0].file_secno = cpu_to_le32(-1); | |
| 142 | + btree->u.internal[0].down = cpu_to_le32(na); | |
| 143 | 143 | mark_buffer_dirty(bh); |
| 144 | 144 | } else if (!(ranode = hpfs_alloc_anode(s, /*a*/0, &ra, &bh2))) { |
| 145 | 145 | brelse(bh); |
| @@ -153,15 +153,15 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi · 7 unmodified lines | ||
| 153 | 153 | btree = &anode->btree; |
| 154 | 154 | } |
| 155 | 155 | btree->n_free_nodes--; n = btree->n_used_nodes++; |
| 156 | − btree->first_free += 12; | |
| 157 | − btree->u.external[n].disk_secno = se; | |
| 158 | − btree->u.external[n].file_secno = fs; | |
| 159 | − btree->u.external[n].length = 1; | |
| 156 | + btree->first_free = cpu_to_le16(le16_to_cpu(btree->first_free) + 12); | |
| 157 | + btree->u.external[n].disk_secno = cpu_to_le32(se); | |
| 158 | + btree->u.external[n].file_secno = cpu_to_le32(fs); | |
| 159 | + btree->u.external[n].length = cpu_to_le32(1); | |
| 160 | 160 | mark_buffer_dirty(bh); |
| 161 | 161 | brelse(bh); |
225 more lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 540 lines aren’t shown here.
This diff is large: its 303 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 602 lines aren’t shown here.
This diff is large: its 216 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 159 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 382 lines aren’t shown here.
This diff is large: its 358 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 140 lines aren’t shown here.
This diff is large: its 254 lines aren’t shown here.
This diff is large: its 107 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 167 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 85 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 257 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 106 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 120 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 6 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 227 lines aren’t shown here.
This diff is large: its 218 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 169 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 97 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 156 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 87 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 231 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.