diff options
168 files changed, 6214 insertions, 13066 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-ufs b/Documentation/ABI/testing/sysfs-driver-ufs new file mode 100644 index 000000000000..016724ec26d5 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-ufs | |||
| @@ -0,0 +1,885 @@ | |||
| 1 | What: /sys/bus/*/drivers/ufshcd/*/auto_hibern8 | ||
| 2 | Date: March 2018 | ||
| 3 | Contact: linux-scsi@vger.kernel.org | ||
| 4 | Description: | ||
| 5 | This file contains the auto-hibernate idle timer setting of a | ||
| 6 | UFS host controller. A value of '0' means auto-hibernate is not | ||
| 7 | enabled. Otherwise the value is the number of microseconds of | ||
| 8 | idle time before the UFS host controller will autonomously put | ||
| 9 | the link into hibernate state. That will save power at the | ||
| 10 | expense of increased latency. Note that the hardware supports | ||
| 11 | 10-bit values with a power-of-ten multiplier which allows a | ||
| 12 | maximum value of 102300000. Refer to the UFS Host Controller | ||
| 13 | Interface specification for more details. | ||
| 14 | |||
| 15 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_type | ||
| 16 | Date: February 2018 | ||
| 17 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 18 | Description: This file shows the device type. This is one of the UFS | ||
| 19 | device descriptor parameters. The full information about | ||
| 20 | the descriptor could be found at UFS specifications 2.1. | ||
| 21 | The file is read only. | ||
| 22 | |||
| 23 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_class | ||
| 24 | Date: February 2018 | ||
| 25 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 26 | Description: This file shows the device class. This is one of the UFS | ||
| 27 | device descriptor parameters. The full information about | ||
| 28 | the descriptor could be found at UFS specifications 2.1. | ||
| 29 | The file is read only. | ||
| 30 | |||
| 31 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_sub_class | ||
| 32 | Date: February 2018 | ||
| 33 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 34 | Description: This file shows the UFS storage subclass. This is one of | ||
| 35 | the UFS device descriptor parameters. The full information | ||
| 36 | about the descriptor could be found at UFS specifications 2.1. | ||
| 37 | The file is read only. | ||
| 38 | |||
| 39 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/protocol | ||
| 40 | Date: February 2018 | ||
| 41 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 42 | Description: This file shows the protocol supported by an UFS device. | ||
| 43 | This is one of the UFS device descriptor parameters. | ||
| 44 | The full information about the descriptor could be found | ||
| 45 | at UFS specifications 2.1. | ||
| 46 | The file is read only. | ||
| 47 | |||
| 48 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_luns | ||
| 49 | Date: February 2018 | ||
| 50 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 51 | Description: This file shows number of logical units. This is one of | ||
| 52 | the UFS device descriptor parameters. The full information | ||
| 53 | about the descriptor could be found at UFS specifications 2.1. | ||
| 54 | The file is read only. | ||
| 55 | |||
| 56 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_wluns | ||
| 57 | Date: February 2018 | ||
| 58 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 59 | Description: This file shows number of well known logical units. | ||
| 60 | This is one of the UFS device descriptor parameters. | ||
| 61 | The full information about the descriptor could be found | ||
| 62 | at UFS specifications 2.1. | ||
| 63 | The file is read only. | ||
| 64 | |||
| 65 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/boot_enable | ||
| 66 | Date: February 2018 | ||
| 67 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 68 | Description: This file shows value that indicates whether the device is | ||
| 69 | enabled for boot. This is one of the UFS device descriptor | ||
| 70 | parameters. The full information about the descriptor could | ||
| 71 | be found at UFS specifications 2.1. | ||
| 72 | The file is read only. | ||
| 73 | |||
| 74 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/descriptor_access_enable | ||
| 75 | Date: February 2018 | ||
| 76 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 77 | Description: This file shows value that indicates whether the device | ||
| 78 | descriptor could be read after partial initialization phase | ||
| 79 | of the boot sequence. This is one of the UFS device descriptor | ||
| 80 | parameters. The full information about the descriptor could | ||
| 81 | be found at UFS specifications 2.1. | ||
| 82 | The file is read only. | ||
| 83 | |||
| 84 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/initial_power_mode | ||
| 85 | Date: February 2018 | ||
| 86 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 87 | Description: This file shows value that defines the power mode after | ||
| 88 | device initialization or hardware reset. This is one of | ||
| 89 | the UFS device descriptor parameters. The full information | ||
| 90 | about the descriptor could be found at UFS specifications 2.1. | ||
| 91 | The file is read only. | ||
| 92 | |||
| 93 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/high_priority_lun | ||
| 94 | Date: February 2018 | ||
| 95 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 96 | Description: This file shows the high priority lun. This is one of | ||
| 97 | the UFS device descriptor parameters. The full information | ||
| 98 | about the descriptor could be found at UFS specifications 2.1. | ||
| 99 | The file is read only. | ||
| 100 | |||
| 101 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/secure_removal_type | ||
| 102 | Date: February 2018 | ||
| 103 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 104 | Description: This file shows the secure removal type. This is one of | ||
| 105 | the UFS device descriptor parameters. The full information | ||
| 106 | about the descriptor could be found at UFS specifications 2.1. | ||
| 107 | The file is read only. | ||
| 108 | |||
| 109 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/support_security_lun | ||
| 110 | Date: February 2018 | ||
| 111 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 112 | Description: This file shows whether the security lun is supported. | ||
| 113 | This is one of the UFS device descriptor parameters. | ||
| 114 | The full information about the descriptor could be found | ||
| 115 | at UFS specifications 2.1. | ||
| 116 | The file is read only. | ||
| 117 | |||
| 118 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/bkops_termination_latency | ||
| 119 | Date: February 2018 | ||
| 120 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 121 | Description: This file shows the background operations termination | ||
| 122 | latency. This is one of the UFS device descriptor parameters. | ||
| 123 | The full information about the descriptor could be found | ||
| 124 | at UFS specifications 2.1. | ||
| 125 | The file is read only. | ||
| 126 | |||
| 127 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/initial_active_icc_level | ||
| 128 | Date: February 2018 | ||
| 129 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 130 | Description: This file shows the initial active ICC level. This is one | ||
| 131 | of the UFS device descriptor parameters. The full information | ||
| 132 | about the descriptor could be found at UFS specifications 2.1. | ||
| 133 | The file is read only. | ||
| 134 | |||
| 135 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/specification_version | ||
| 136 | Date: February 2018 | ||
| 137 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 138 | Description: This file shows the specification version. This is one | ||
| 139 | of the UFS device descriptor parameters. The full information | ||
| 140 | about the descriptor could be found at UFS specifications 2.1. | ||
| 141 | The file is read only. | ||
| 142 | |||
| 143 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/manufacturing_date | ||
| 144 | Date: February 2018 | ||
| 145 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 146 | Description: This file shows the manufacturing date in BCD format. | ||
| 147 | This is one of the UFS device descriptor parameters. | ||
| 148 | The full information about the descriptor could be found | ||
| 149 | at UFS specifications 2.1. | ||
| 150 | The file is read only. | ||
| 151 | |||
| 152 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/manufacturer_id | ||
| 153 | Date: February 2018 | ||
| 154 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 155 | Description: This file shows the manufacturee ID. This is one of the | ||
| 156 | UFS device descriptor parameters. The full information about | ||
| 157 | the descriptor could be found at UFS specifications 2.1. | ||
| 158 | The file is read only. | ||
| 159 | |||
| 160 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/rtt_capability | ||
| 161 | Date: February 2018 | ||
| 162 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 163 | Description: This file shows the maximum number of outstanding RTTs | ||
| 164 | supported by the device. This is one of the UFS device | ||
| 165 | descriptor parameters. The full information about | ||
| 166 | the descriptor could be found at UFS specifications 2.1. | ||
| 167 | The file is read only. | ||
| 168 | |||
| 169 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/rtc_update | ||
| 170 | Date: February 2018 | ||
| 171 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 172 | Description: This file shows the frequency and method of the realtime | ||
| 173 | clock update. This is one of the UFS device descriptor | ||
| 174 | parameters. The full information about the descriptor | ||
| 175 | could be found at UFS specifications 2.1. | ||
| 176 | The file is read only. | ||
| 177 | |||
| 178 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/ufs_features | ||
| 179 | Date: February 2018 | ||
| 180 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 181 | Description: This file shows which features are supported by the device. | ||
| 182 | This is one of the UFS device descriptor parameters. | ||
| 183 | The full information about the descriptor could be | ||
| 184 | found at UFS specifications 2.1. | ||
| 185 | The file is read only. | ||
| 186 | |||
| 187 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/ffu_timeout | ||
| 188 | Date: February 2018 | ||
| 189 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 190 | Description: This file shows the FFU timeout. This is one of the | ||
| 191 | UFS device descriptor parameters. The full information | ||
| 192 | about the descriptor could be found at UFS specifications 2.1. | ||
| 193 | The file is read only. | ||
| 194 | |||
| 195 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/queue_depth | ||
| 196 | Date: February 2018 | ||
| 197 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 198 | Description: This file shows the device queue depth. This is one of the | ||
| 199 | UFS device descriptor parameters. The full information | ||
| 200 | about the descriptor could be found at UFS specifications 2.1. | ||
| 201 | The file is read only. | ||
| 202 | |||
| 203 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/device_version | ||
| 204 | Date: February 2018 | ||
| 205 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 206 | Description: This file shows the device version. This is one of the | ||
| 207 | UFS device descriptor parameters. The full information | ||
| 208 | about the descriptor could be found at UFS specifications 2.1. | ||
| 209 | The file is read only. | ||
| 210 | |||
| 211 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/number_of_secure_wpa | ||
| 212 | Date: February 2018 | ||
| 213 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 214 | Description: This file shows number of secure write protect areas | ||
| 215 | supported by the device. This is one of the UFS device | ||
| 216 | descriptor parameters. The full information about | ||
| 217 | the descriptor could be found at UFS specifications 2.1. | ||
| 218 | The file is read only. | ||
| 219 | |||
| 220 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/psa_max_data_size | ||
| 221 | Date: February 2018 | ||
| 222 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 223 | Description: This file shows the maximum amount of data that may be | ||
| 224 | written during the pre-soldering phase of the PSA flow. | ||
| 225 | This is one of the UFS device descriptor parameters. | ||
| 226 | The full information about the descriptor could be found | ||
| 227 | at UFS specifications 2.1. | ||
| 228 | The file is read only. | ||
| 229 | |||
| 230 | What: /sys/bus/platform/drivers/ufshcd/*/device_descriptor/psa_state_timeout | ||
| 231 | Date: February 2018 | ||
| 232 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 233 | Description: This file shows the command maximum timeout for a change | ||
| 234 | in PSA state. This is one of the UFS device descriptor | ||
| 235 | parameters. The full information about the descriptor could | ||
| 236 | be found at UFS specifications 2.1. | ||
| 237 | The file is read only. | ||
| 238 | |||
| 239 | |||
| 240 | What: /sys/bus/platform/drivers/ufshcd/*/interconnect_descriptor/unipro_version | ||
| 241 | Date: February 2018 | ||
| 242 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 243 | Description: This file shows the MIPI UniPro version number in BCD format. | ||
| 244 | This is one of the UFS interconnect descriptor parameters. | ||
| 245 | The full information about the descriptor could be found at | ||
| 246 | UFS specifications 2.1. | ||
| 247 | The file is read only. | ||
| 248 | |||
| 249 | What: /sys/bus/platform/drivers/ufshcd/*/interconnect_descriptor/mphy_version | ||
| 250 | Date: February 2018 | ||
| 251 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 252 | Description: This file shows the MIPI M-PHY version number in BCD format. | ||
| 253 | This is one of the UFS interconnect descriptor parameters. | ||
| 254 | The full information about the descriptor could be found at | ||
| 255 | UFS specifications 2.1. | ||
| 256 | The file is read only. | ||
| 257 | |||
| 258 | |||
| 259 | What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/raw_device_capacity | ||
| 260 | Date: February 2018 | ||
| 261 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 262 | Description: This file shows the total memory quantity available to | ||
| 263 | the user to configure the device logical units. This is one | ||
| 264 | of the UFS geometry descriptor parameters. The full | ||
| 265 | information about the descriptor could be found at | ||
| 266 | UFS specifications 2.1. | ||
| 267 | The file is read only. | ||
| 268 | |||
| 269 | What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/max_number_of_luns | ||
| 270 | Date: February 2018 | ||
| 271 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 272 | Description: This file shows the maximum number of logical units | ||
| 273 | supported by the UFS device. This is one of the UFS | ||
| 274 | geometry descriptor parameters. The full information about | ||
| 275 | the descriptor could be found at UFS specifications 2.1. | ||
| 276 | The file is read only. | ||
| 277 | |||
| 278 | What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/segment_size | ||
| 279 | Date: February 2018 | ||
| 280 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 281 | Description: This file shows the segment size. This is one of the UFS | ||
| 282 | geometry descriptor parameters. The full information about | ||
| 283 | the descriptor could be found at UFS specifications 2.1. | ||
| 284 | The file is read only. | ||
| 285 | |||
| 286 | What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/allocation_unit_size | ||
| 287 | Date: February 2018 | ||
| 288 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 289 | Description: This file shows the allocation unit size. This is one of | ||
| 290 | the UFS geometry descriptor parameters. The full information | ||
| 291 | about the descriptor could be found at UFS specifications 2.1. | ||
| 292 | The file is read only. | ||
| 293 | |||
| 294 | What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/min_addressable_block_size | ||
| 295 | Date: February 2018 | ||
| 296 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 297 | Description: This file shows the minimum addressable block size. This | ||
| 298 | is one of the UFS geometry descriptor parameters. The full | ||
| 299 | information about the descriptor could be found at UFS | ||
| 300 | specifications 2.1. | ||
| 301 | The file is read only. | ||
| 302 | |||
| 303 | What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/optimal_read_block_size | ||
| 304 | Date: February 2018 | ||
| 305 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 306 | Description: This file shows the optimal read block size. This is one | ||
| 307 | of the UFS geometry descriptor parameters. The full | ||
| 308 | information about the descriptor could be found at UFS | ||
| 309 | specifications 2.1. | ||
| 310 | The file is read only. | ||
| 311 | |||
| 312 | What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/optimal_write_block_size | ||
| 313 | Date: February 2018 | ||
| 314 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 315 | Description: This file shows the optimal write block size. This is one | ||
| 316 | of the UFS geometry descriptor parameters. The full | ||
| 317 | information about the descriptor could be found at UFS | ||
| 318 | specifications 2.1. | ||
| 319 | The file is read only. | ||
| 320 | |||
| 321 | What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/max_in_buffer_size | ||
| 322 | Date: February 2018 | ||
| 323 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 324 | Description: This file shows the maximum data-in buffer size. This | ||
| 325 | is one of the UFS geometry descriptor parameters. The full | ||
| 326 | information about the descriptor could be found at UFS | ||
| 327 | specifications 2.1. | ||
| 328 | The file is read only. | ||
| 329 | |||
| 330 | What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/max_out_buffer_size | ||
| 331 | Date: February 2018 | ||
| 332 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 333 | Description: This file shows the maximum data-out buffer size. This | ||
| 334 | is one of the UFS geometry descriptor parameters. The full | ||
| 335 | information about the descriptor could be found at UFS | ||
| 336 | specifications 2.1. | ||
| 337 | The file is read only. | ||
| 338 | |||
| 339 | What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/rpmb_rw_size | ||
| 340 | Date: February 2018 | ||
| 341 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 342 | Description: This file shows the maximum number of RPMB frames allowed | ||
| 343 | in Security Protocol In/Out. This is one of the UFS geometry | ||
| 344 | descriptor parameters. The full information about the | ||
| 345 | descriptor could be found at UFS specifications 2.1. | ||
| 346 | The file is read only. | ||
| 347 | |||
| 348 | What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/dyn_capacity_resource_policy | ||
| 349 | Date: February 2018 | ||
| 350 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 351 | Description: This file shows the dynamic capacity resource policy. This | ||
| 352 | is one of the UFS geometry descriptor parameters. The full | ||
| 353 | information about the descriptor could be found at | ||
| 354 | UFS specifications 2.1. | ||
| 355 | The file is read only. | ||
| 356 | |||
| 357 | What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/data_ordering | ||
| 358 | Date: February 2018 | ||
| 359 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 360 | Description: This file shows support for out-of-order data transfer. | ||
| 361 | This is one of the UFS geometry descriptor parameters. | ||
| 362 | The full information about the descriptor could be found at | ||
| 363 | UFS specifications 2.1. | ||
| 364 | The file is read only. | ||
| 365 | |||
| 366 | What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/max_number_of_contexts | ||
| 367 | Date: February 2018 | ||
| 368 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 369 | Description: This file shows maximum available number of contexts which | ||
| 370 | are supported by the device. This is one of the UFS geometry | ||
| 371 | descriptor parameters. The full information about the | ||
| 372 | descriptor could be found at UFS specifications 2.1. | ||
| 373 | The file is read only. | ||
| 374 | |||
| 375 | What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/sys_data_tag_unit_size | ||
| 376 | Date: February 2018 | ||
| 377 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 378 | Description: This file shows system data tag unit size. This is one of | ||
| 379 | the UFS geometry descriptor parameters. The full information | ||
| 380 | about the descriptor could be found at UFS specifications 2.1. | ||
| 381 | The file is read only. | ||
| 382 | |||
| 383 | What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/sys_data_tag_resource_size | ||
| 384 | Date: February 2018 | ||
| 385 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 386 | Description: This file shows maximum storage area size allocated by | ||
| 387 | the device to handle system data by the tagging mechanism. | ||
| 388 | This is one of the UFS geometry descriptor parameters. | ||
| 389 | The full information about the descriptor could be found at | ||
| 390 | UFS specifications 2.1. | ||
| 391 | The file is read only. | ||
| 392 | |||
| 393 | What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/secure_removal_types | ||
| 394 | Date: February 2018 | ||
| 395 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 396 | Description: This file shows supported secure removal types. This is | ||
| 397 | one of the UFS geometry descriptor parameters. The full | ||
| 398 | information about the descriptor could be found at | ||
| 399 | UFS specifications 2.1. | ||
| 400 | The file is read only. | ||
| 401 | |||
| 402 | What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/memory_types | ||
| 403 | Date: February 2018 | ||
| 404 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 405 | Description: This file shows supported memory types. This is one of | ||
| 406 | the UFS geometry descriptor parameters. The full | ||
| 407 | information about the descriptor could be found at | ||
| 408 | UFS specifications 2.1. | ||
| 409 | The file is read only. | ||
| 410 | |||
| 411 | What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/*_memory_max_alloc_units | ||
| 412 | Date: February 2018 | ||
| 413 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 414 | Description: This file shows the maximum number of allocation units for | ||
| 415 | different memory types (system code, non persistent, | ||
| 416 | enhanced type 1-4). This is one of the UFS geometry | ||
| 417 | descriptor parameters. The full information about the | ||
| 418 | descriptor could be found at UFS specifications 2.1. | ||
| 419 | The file is read only. | ||
| 420 | |||
| 421 | What: /sys/bus/platform/drivers/ufshcd/*/geometry_descriptor/*_memory_capacity_adjustment_factor | ||
| 422 | Date: February 2018 | ||
| 423 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 424 | Description: This file shows the memory capacity adjustment factor for | ||
| 425 | different memory types (system code, non persistent, | ||
| 426 | enhanced type 1-4). This is one of the UFS geometry | ||
| 427 | descriptor parameters. The full information about the | ||
| 428 | descriptor could be found at UFS specifications 2.1. | ||
| 429 | The file is read only. | ||
| 430 | |||
| 431 | |||
| 432 | What: /sys/bus/platform/drivers/ufshcd/*/health_descriptor/eol_info | ||
| 433 | Date: February 2018 | ||
| 434 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 435 | Description: This file shows preend of life information. This is one | ||
| 436 | of the UFS health descriptor parameters. The full | ||
| 437 | information about the descriptor could be found at | ||
| 438 | UFS specifications 2.1. | ||
| 439 | The file is read only. | ||
| 440 | |||
| 441 | What: /sys/bus/platform/drivers/ufshcd/*/health_descriptor/life_time_estimation_a | ||
| 442 | Date: February 2018 | ||
| 443 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 444 | Description: This file shows indication of the device life time | ||
| 445 | (method a). This is one of the UFS health descriptor | ||
| 446 | parameters. The full information about the descriptor | ||
| 447 | could be found at UFS specifications 2.1. | ||
| 448 | The file is read only. | ||
| 449 | |||
| 450 | What: /sys/bus/platform/drivers/ufshcd/*/health_descriptor/life_time_estimation_b | ||
| 451 | Date: February 2018 | ||
| 452 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 453 | Description: This file shows indication of the device life time | ||
| 454 | (method b). This is one of the UFS health descriptor | ||
| 455 | parameters. The full information about the descriptor | ||
| 456 | could be found at UFS specifications 2.1. | ||
| 457 | The file is read only. | ||
| 458 | |||
| 459 | |||
| 460 | What: /sys/bus/platform/drivers/ufshcd/*/power_descriptor/active_icc_levels_vcc* | ||
| 461 | Date: February 2018 | ||
| 462 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 463 | Description: This file shows maximum VCC, VCCQ and VCCQ2 value for | ||
| 464 | active ICC levels from 0 to 15. This is one of the UFS | ||
| 465 | power descriptor parameters. The full information about | ||
| 466 | the descriptor could be found at UFS specifications 2.1. | ||
| 467 | The file is read only. | ||
| 468 | |||
| 469 | |||
| 470 | What: /sys/bus/platform/drivers/ufshcd/*/string_descriptors/manufacturer_name | ||
| 471 | Date: February 2018 | ||
| 472 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 473 | Description: This file contains a device manufactureer name string. | ||
| 474 | The full information about the descriptor could be found at | ||
| 475 | UFS specifications 2.1. | ||
| 476 | The file is read only. | ||
| 477 | |||
| 478 | What: /sys/bus/platform/drivers/ufshcd/*/string_descriptors/product_name | ||
| 479 | Date: February 2018 | ||
| 480 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 481 | Description: This file contains a product name string. The full information | ||
| 482 | about the descriptor could be found at UFS specifications 2.1. | ||
| 483 | The file is read only. | ||
| 484 | |||
| 485 | What: /sys/bus/platform/drivers/ufshcd/*/string_descriptors/oem_id | ||
| 486 | Date: February 2018 | ||
| 487 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 488 | Description: This file contains a OEM ID string. The full information | ||
| 489 | about the descriptor could be found at UFS specifications 2.1. | ||
| 490 | The file is read only. | ||
| 491 | |||
| 492 | What: /sys/bus/platform/drivers/ufshcd/*/string_descriptors/serial_number | ||
| 493 | Date: February 2018 | ||
| 494 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 495 | Description: This file contains a device serial number string. The full | ||
| 496 | information about the descriptor could be found at | ||
| 497 | UFS specifications 2.1. | ||
| 498 | The file is read only. | ||
| 499 | |||
| 500 | What: /sys/bus/platform/drivers/ufshcd/*/string_descriptors/product_revision | ||
| 501 | Date: February 2018 | ||
| 502 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 503 | Description: This file contains a product revision string. The full | ||
| 504 | information about the descriptor could be found at | ||
| 505 | UFS specifications 2.1. | ||
| 506 | The file is read only. | ||
| 507 | |||
| 508 | |||
| 509 | What: /sys/class/scsi_device/*/device/unit_descriptor/boot_lun_id | ||
| 510 | Date: February 2018 | ||
| 511 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 512 | Description: This file shows boot LUN information. This is one of | ||
| 513 | the UFS unit descriptor parameters. The full information | ||
| 514 | about the descriptor could be found at UFS specifications 2.1. | ||
| 515 | The file is read only. | ||
| 516 | |||
| 517 | What: /sys/class/scsi_device/*/device/unit_descriptor/lun_write_protect | ||
| 518 | Date: February 2018 | ||
| 519 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 520 | Description: This file shows LUN write protection status. This is one of | ||
| 521 | the UFS unit descriptor parameters. The full information | ||
| 522 | about the descriptor could be found at UFS specifications 2.1. | ||
| 523 | The file is read only. | ||
| 524 | |||
| 525 | What: /sys/class/scsi_device/*/device/unit_descriptor/lun_queue_depth | ||
| 526 | Date: February 2018 | ||
| 527 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 528 | Description: This file shows LUN queue depth. This is one of the UFS | ||
| 529 | unit descriptor parameters. The full information about | ||
| 530 | the descriptor could be found at UFS specifications 2.1. | ||
| 531 | The file is read only. | ||
| 532 | |||
| 533 | What: /sys/class/scsi_device/*/device/unit_descriptor/psa_sensitive | ||
| 534 | Date: February 2018 | ||
| 535 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 536 | Description: This file shows PSA sensitivity. This is one of the UFS | ||
| 537 | unit descriptor parameters. The full information about | ||
| 538 | the descriptor could be found at UFS specifications 2.1. | ||
| 539 | The file is read only. | ||
| 540 | |||
| 541 | What: /sys/class/scsi_device/*/device/unit_descriptor/lun_memory_type | ||
| 542 | Date: February 2018 | ||
| 543 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 544 | Description: This file shows LUN memory type. This is one of the UFS | ||
| 545 | unit descriptor parameters. The full information about | ||
| 546 | the descriptor could be found at UFS specifications 2.1. | ||
| 547 | The file is read only. | ||
| 548 | |||
| 549 | What: /sys/class/scsi_device/*/device/unit_descriptor/data_reliability | ||
| 550 | Date: February 2018 | ||
| 551 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 552 | Description: This file defines the device behavior when a power failure | ||
| 553 | occurs during a write operation. This is one of the UFS | ||
| 554 | unit descriptor parameters. The full information about | ||
| 555 | the descriptor could be found at UFS specifications 2.1. | ||
| 556 | The file is read only. | ||
| 557 | |||
| 558 | What: /sys/class/scsi_device/*/device/unit_descriptor/logical_block_size | ||
| 559 | Date: February 2018 | ||
| 560 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 561 | Description: This file shows the size of addressable logical blocks | ||
| 562 | (calculated as an exponent with base 2). This is one of | ||
| 563 | the UFS unit descriptor parameters. The full information about | ||
| 564 | the descriptor could be found at UFS specifications 2.1. | ||
| 565 | The file is read only. | ||
| 566 | |||
| 567 | What: /sys/class/scsi_device/*/device/unit_descriptor/logical_block_count | ||
| 568 | Date: February 2018 | ||
| 569 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 570 | Description: This file shows total number of addressable logical blocks. | ||
| 571 | This is one of the UFS unit descriptor parameters. The full | ||
| 572 | information about the descriptor could be found at | ||
| 573 | UFS specifications 2.1. | ||
| 574 | The file is read only. | ||
| 575 | |||
| 576 | What: /sys/class/scsi_device/*/device/unit_descriptor/erase_block_size | ||
| 577 | Date: February 2018 | ||
| 578 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 579 | Description: This file shows the erase block size. This is one of | ||
| 580 | the UFS unit descriptor parameters. The full information | ||
| 581 | about the descriptor could be found at UFS specifications 2.1. | ||
| 582 | The file is read only. | ||
| 583 | |||
| 584 | What: /sys/class/scsi_device/*/device/unit_descriptor/provisioning_type | ||
| 585 | Date: February 2018 | ||
| 586 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 587 | Description: This file shows the thin provisioning type. This is one of | ||
| 588 | the UFS unit descriptor parameters. The full information | ||
| 589 | about the descriptor could be found at UFS specifications 2.1. | ||
| 590 | The file is read only. | ||
| 591 | |||
| 592 | What: /sys/class/scsi_device/*/device/unit_descriptor/physical_memory_resourse_count | ||
| 593 | Date: February 2018 | ||
| 594 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 595 | Description: This file shows the total physical memory resources. This is | ||
| 596 | one of the UFS unit descriptor parameters. The full information | ||
| 597 | about the descriptor could be found at UFS specifications 2.1. | ||
| 598 | The file is read only. | ||
| 599 | |||
| 600 | What: /sys/class/scsi_device/*/device/unit_descriptor/context_capabilities | ||
| 601 | Date: February 2018 | ||
| 602 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 603 | Description: This file shows the context capabilities. This is one of | ||
| 604 | the UFS unit descriptor parameters. The full information | ||
| 605 | about the descriptor could be found at UFS specifications 2.1. | ||
| 606 | The file is read only. | ||
| 607 | |||
| 608 | What: /sys/class/scsi_device/*/device/unit_descriptor/large_unit_granularity | ||
| 609 | Date: February 2018 | ||
| 610 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 611 | Description: This file shows the granularity of the LUN. This is one of | ||
| 612 | the UFS unit descriptor parameters. The full information | ||
| 613 | about the descriptor could be found at UFS specifications 2.1. | ||
| 614 | The file is read only. | ||
| 615 | |||
| 616 | |||
| 617 | What: /sys/bus/platform/drivers/ufshcd/*/flags/device_init | ||
| 618 | Date: February 2018 | ||
| 619 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 620 | Description: This file shows the device init status. The full information | ||
| 621 | about the flag could be found at UFS specifications 2.1. | ||
| 622 | The file is read only. | ||
| 623 | |||
| 624 | What: /sys/bus/platform/drivers/ufshcd/*/flags/permanent_wpe | ||
| 625 | Date: February 2018 | ||
| 626 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 627 | Description: This file shows whether permanent write protection is enabled. | ||
| 628 | The full information about the flag could be found at | ||
| 629 | UFS specifications 2.1. | ||
| 630 | The file is read only. | ||
| 631 | |||
| 632 | What: /sys/bus/platform/drivers/ufshcd/*/flags/power_on_wpe | ||
| 633 | Date: February 2018 | ||
| 634 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 635 | Description: This file shows whether write protection is enabled on all | ||
| 636 | logical units configured as power on write protected. The | ||
| 637 | full information about the flag could be found at | ||
| 638 | UFS specifications 2.1. | ||
| 639 | The file is read only. | ||
| 640 | |||
| 641 | What: /sys/bus/platform/drivers/ufshcd/*/flags/bkops_enable | ||
| 642 | Date: February 2018 | ||
| 643 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 644 | Description: This file shows whether the device background operations are | ||
| 645 | enabled. The full information about the flag could be | ||
| 646 | found at UFS specifications 2.1. | ||
| 647 | The file is read only. | ||
| 648 | |||
| 649 | What: /sys/bus/platform/drivers/ufshcd/*/flags/life_span_mode_enable | ||
| 650 | Date: February 2018 | ||
| 651 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 652 | Description: This file shows whether the device life span mode is enabled. | ||
| 653 | The full information about the flag could be found at | ||
| 654 | UFS specifications 2.1. | ||
| 655 | The file is read only. | ||
| 656 | |||
| 657 | What: /sys/bus/platform/drivers/ufshcd/*/flags/phy_resource_removal | ||
| 658 | Date: February 2018 | ||
| 659 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 660 | Description: This file shows whether physical resource removal is enable. | ||
| 661 | The full information about the flag could be found at | ||
| 662 | UFS specifications 2.1. | ||
| 663 | The file is read only. | ||
| 664 | |||
| 665 | What: /sys/bus/platform/drivers/ufshcd/*/flags/busy_rtc | ||
| 666 | Date: February 2018 | ||
| 667 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 668 | Description: This file shows whether the device is executing internal | ||
| 669 | operation related to real time clock. The full information | ||
| 670 | about the flag could be found at UFS specifications 2.1. | ||
| 671 | The file is read only. | ||
| 672 | |||
| 673 | What: /sys/bus/platform/drivers/ufshcd/*/flags/disable_fw_update | ||
| 674 | Date: February 2018 | ||
| 675 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 676 | Description: This file shows whether the device FW update is permanently | ||
| 677 | disabled. The full information about the flag could be found | ||
| 678 | at UFS specifications 2.1. | ||
| 679 | The file is read only. | ||
| 680 | |||
| 681 | |||
| 682 | What: /sys/bus/platform/drivers/ufshcd/*/attributes/boot_lun_enabled | ||
| 683 | Date: February 2018 | ||
| 684 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 685 | Description: This file provides the boot lun enabled UFS device attribute. | ||
| 686 | The full information about the attribute could be found at | ||
| 687 | UFS specifications 2.1. | ||
| 688 | The file is read only. | ||
| 689 | |||
| 690 | What: /sys/bus/platform/drivers/ufshcd/*/attributes/current_power_mode | ||
| 691 | Date: February 2018 | ||
| 692 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 693 | Description: This file provides the current power mode UFS device attribute. | ||
| 694 | The full information about the attribute could be found at | ||
| 695 | UFS specifications 2.1. | ||
| 696 | The file is read only. | ||
| 697 | |||
| 698 | What: /sys/bus/platform/drivers/ufshcd/*/attributes/active_icc_level | ||
| 699 | Date: February 2018 | ||
| 700 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 701 | Description: This file provides the active icc level UFS device attribute. | ||
| 702 | The full information about the attribute could be found at | ||
| 703 | UFS specifications 2.1. | ||
| 704 | The file is read only. | ||
| 705 | |||
| 706 | What: /sys/bus/platform/drivers/ufshcd/*/attributes/ooo_data_enabled | ||
| 707 | Date: February 2018 | ||
| 708 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 709 | Description: This file provides the out of order data transfer enabled UFS | ||
| 710 | device attribute. The full information about the attribute | ||
| 711 | could be found at UFS specifications 2.1. | ||
| 712 | The file is read only. | ||
| 713 | |||
| 714 | What: /sys/bus/platform/drivers/ufshcd/*/attributes/bkops_status | ||
| 715 | Date: February 2018 | ||
| 716 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 717 | Description: This file provides the background operations status UFS device | ||
| 718 | attribute. The full information about the attribute could | ||
| 719 | be found at UFS specifications 2.1. | ||
| 720 | The file is read only. | ||
| 721 | |||
| 722 | What: /sys/bus/platform/drivers/ufshcd/*/attributes/purge_status | ||
| 723 | Date: February 2018 | ||
| 724 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 725 | Description: This file provides the purge operation status UFS device | ||
| 726 | attribute. The full information about the attribute could | ||
| 727 | be found at UFS specifications 2.1. | ||
| 728 | The file is read only. | ||
| 729 | |||
| 730 | What: /sys/bus/platform/drivers/ufshcd/*/attributes/max_data_in_size | ||
| 731 | Date: February 2018 | ||
| 732 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 733 | Description: This file shows the maximum data size in a DATA IN | ||
| 734 | UPIU. The full information about the attribute could | ||
| 735 | be found at UFS specifications 2.1. | ||
| 736 | The file is read only. | ||
| 737 | |||
| 738 | What: /sys/bus/platform/drivers/ufshcd/*/attributes/max_data_out_size | ||
| 739 | Date: February 2018 | ||
| 740 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 741 | Description: This file shows the maximum number of bytes that can be | ||
| 742 | requested with a READY TO TRANSFER UPIU. The full information | ||
| 743 | about the attribute could be found at UFS specifications 2.1. | ||
| 744 | The file is read only. | ||
| 745 | |||
| 746 | What: /sys/bus/platform/drivers/ufshcd/*/attributes/reference_clock_frequency | ||
| 747 | Date: February 2018 | ||
| 748 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 749 | Description: This file provides the reference clock frequency UFS device | ||
| 750 | attribute. The full information about the attribute could | ||
| 751 | be found at UFS specifications 2.1. | ||
| 752 | The file is read only. | ||
| 753 | |||
| 754 | What: /sys/bus/platform/drivers/ufshcd/*/attributes/configuration_descriptor_lock | ||
| 755 | Date: February 2018 | ||
| 756 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 757 | Description: This file shows whether the configuration descriptor is locked. | ||
| 758 | The full information about the attribute could be found at | ||
| 759 | UFS specifications 2.1. The file is read only. | ||
| 760 | |||
| 761 | What: /sys/bus/platform/drivers/ufshcd/*/attributes/max_number_of_rtt | ||
| 762 | Date: February 2018 | ||
| 763 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 764 | Description: This file provides the maximum current number of | ||
| 765 | outstanding RTTs in device that is allowed. The full | ||
| 766 | information about the attribute could be found at | ||
| 767 | UFS specifications 2.1. | ||
| 768 | The file is read only. | ||
| 769 | |||
| 770 | What: /sys/bus/platform/drivers/ufshcd/*/attributes/exception_event_control | ||
| 771 | Date: February 2018 | ||
| 772 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 773 | Description: This file provides the exception event control UFS device | ||
| 774 | attribute. The full information about the attribute could | ||
| 775 | be found at UFS specifications 2.1. | ||
| 776 | The file is read only. | ||
| 777 | |||
| 778 | What: /sys/bus/platform/drivers/ufshcd/*/attributes/exception_event_status | ||
| 779 | Date: February 2018 | ||
| 780 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 781 | Description: This file provides the exception event status UFS device | ||
| 782 | attribute. The full information about the attribute could | ||
| 783 | be found at UFS specifications 2.1. | ||
| 784 | The file is read only. | ||
| 785 | |||
| 786 | What: /sys/bus/platform/drivers/ufshcd/*/attributes/ffu_status | ||
| 787 | Date: February 2018 | ||
| 788 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 789 | Description: This file provides the ffu status UFS device attribute. | ||
| 790 | The full information about the attribute could be found at | ||
| 791 | UFS specifications 2.1. | ||
| 792 | The file is read only. | ||
| 793 | |||
| 794 | What: /sys/bus/platform/drivers/ufshcd/*/attributes/psa_state | ||
| 795 | Date: February 2018 | ||
| 796 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 797 | Description: This file show the PSA feature status. The full information | ||
| 798 | about the attribute could be found at UFS specifications 2.1. | ||
| 799 | The file is read only. | ||
| 800 | |||
| 801 | What: /sys/bus/platform/drivers/ufshcd/*/attributes/psa_data_size | ||
| 802 | Date: February 2018 | ||
| 803 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 804 | Description: This file shows the amount of data that the host plans to | ||
| 805 | load to all logical units in pre-soldering state. | ||
| 806 | The full information about the attribute could be found at | ||
| 807 | UFS specifications 2.1. | ||
| 808 | The file is read only. | ||
| 809 | |||
| 810 | |||
| 811 | What: /sys/class/scsi_device/*/device/dyn_cap_needed | ||
| 812 | Date: February 2018 | ||
| 813 | Contact: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> | ||
| 814 | Description: This file shows the The amount of physical memory needed | ||
| 815 | to be removed from the physical memory resources pool of | ||
| 816 | the particular logical unit. The full information about | ||
| 817 | the attribute could be found at UFS specifications 2.1. | ||
| 818 | The file is read only. | ||
| 819 | |||
| 820 | |||
| 821 | What: /sys/bus/platform/drivers/ufshcd/*/rpm_lvl | ||
| 822 | Date: September 2014 | ||
| 823 | Contact: Subhash Jadavani <subhashj@codeaurora.org> | ||
| 824 | Description: This entry could be used to set or show the UFS device | ||
| 825 | runtime power management level. The current driver | ||
| 826 | implementation supports 6 levels with next target states: | ||
| 827 | 0 - an UFS device will stay active, an UIC link will | ||
| 828 | stay active | ||
| 829 | 1 - an UFS device will stay active, an UIC link will | ||
| 830 | hibernate | ||
| 831 | 2 - an UFS device will moved to sleep, an UIC link will | ||
| 832 | stay active | ||
| 833 | 3 - an UFS device will moved to sleep, an UIC link will | ||
| 834 | hibernate | ||
| 835 | 4 - an UFS device will be powered off, an UIC link will | ||
| 836 | hibernate | ||
| 837 | 5 - an UFS device will be powered off, an UIC link will | ||
| 838 | be powered off | ||
| 839 | |||
| 840 | What: /sys/bus/platform/drivers/ufshcd/*/rpm_target_dev_state | ||
| 841 | Date: February 2018 | ||
| 842 | Contact: Subhash Jadavani <subhashj@codeaurora.org> | ||
| 843 | Description: This entry shows the target power mode of an UFS device | ||
| 844 | for the chosen runtime power management level. | ||
| 845 | The file is read only. | ||
| 846 | |||
| 847 | What: /sys/bus/platform/drivers/ufshcd/*/rpm_target_link_state | ||
| 848 | Date: February 2018 | ||
| 849 | Contact: Subhash Jadavani <subhashj@codeaurora.org> | ||
| 850 | Description: This entry shows the target state of an UFS UIC link | ||
| 851 | for the chosen runtime power management level. | ||
| 852 | The file is read only. | ||
| 853 | |||
| 854 | What: /sys/bus/platform/drivers/ufshcd/*/spm_lvl | ||
| 855 | Date: September 2014 | ||
| 856 | Contact: Subhash Jadavani <subhashj@codeaurora.org> | ||
| 857 | Description: This entry could be used to set or show the UFS device | ||
| 858 | system power management level. The current driver | ||
| 859 | implementation supports 6 levels with next target states: | ||
| 860 | 0 - an UFS device will stay active, an UIC link will | ||
| 861 | stay active | ||
| 862 | 1 - an UFS device will stay active, an UIC link will | ||
| 863 | hibernate | ||
| 864 | 2 - an UFS device will moved to sleep, an UIC link will | ||
| 865 | stay active | ||
| 866 | 3 - an UFS device will moved to sleep, an UIC link will | ||
| 867 | hibernate | ||
| 868 | 4 - an UFS device will be powered off, an UIC link will | ||
| 869 | hibernate | ||
| 870 | 5 - an UFS device will be powered off, an UIC link will | ||
| 871 | be powered off | ||
| 872 | |||
| 873 | What: /sys/bus/platform/drivers/ufshcd/*/spm_target_dev_state | ||
| 874 | Date: February 2018 | ||
| 875 | Contact: Subhash Jadavani <subhashj@codeaurora.org> | ||
| 876 | Description: This entry shows the target power mode of an UFS device | ||
| 877 | for the chosen system power management level. | ||
| 878 | The file is read only. | ||
| 879 | |||
| 880 | What: /sys/bus/platform/drivers/ufshcd/*/spm_target_link_state | ||
| 881 | Date: February 2018 | ||
| 882 | Contact: Subhash Jadavani <subhashj@codeaurora.org> | ||
| 883 | Description: This entry shows the target state of an UFS UIC link | ||
| 884 | for the chosen system power management level. | ||
| 885 | The file is read only. | ||
diff --git a/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt b/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt index df3bef7998fa..8c6659ed2cfc 100644 --- a/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt +++ b/Documentation/devicetree/bindings/scsi/hisilicon-sas.txt | |||
| @@ -53,6 +53,13 @@ Main node required properties: | |||
| 53 | Optional main node properties: | 53 | Optional main node properties: |
| 54 | - hip06-sas-v2-quirk-amt : when set, indicates that the v2 controller has the | 54 | - hip06-sas-v2-quirk-amt : when set, indicates that the v2 controller has the |
| 55 | "am-max-transmissions" limitation. | 55 | "am-max-transmissions" limitation. |
| 56 | - hisilicon,signal-attenuation : array of 3 32-bit values, containing de-emphasis, | ||
| 57 | preshoot, and boost attenuation readings for the board. They | ||
| 58 | are used to describe the signal attenuation of the board. These | ||
| 59 | values' range is 7600 to 12400, and used to represent -24dB to | ||
| 60 | 24dB. | ||
| 61 | The formula is "y = (x-10000)/10000". For example, 10478 | ||
| 62 | means 4.78dB. | ||
| 56 | 63 | ||
| 57 | Example: | 64 | Example: |
| 58 | sas0: sas@c1000000 { | 65 | sas0: sas@c1000000 { |
diff --git a/Documentation/driver-api/scsi.rst b/Documentation/driver-api/scsi.rst index 3ae337929721..31ad0fed6763 100644 --- a/Documentation/driver-api/scsi.rst +++ b/Documentation/driver-api/scsi.rst | |||
| @@ -154,12 +154,6 @@ lists). | |||
| 154 | .. kernel-doc:: drivers/scsi/scsi_lib_dma.c | 154 | .. kernel-doc:: drivers/scsi/scsi_lib_dma.c |
| 155 | :export: | 155 | :export: |
| 156 | 156 | ||
| 157 | drivers/scsi/scsi_module.c | ||
| 158 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 159 | |||
| 160 | The file drivers/scsi/scsi_module.c contains legacy support for | ||
| 161 | old-style host templates. It should never be used by any new driver. | ||
| 162 | |||
| 163 | drivers/scsi/scsi_proc.c | 157 | drivers/scsi/scsi_proc.c |
| 164 | ~~~~~~~~~~~~~~~~~~~~~~~~~ | 158 | ~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 165 | 159 | ||
diff --git a/Documentation/scsi/ChangeLog.1992-1997 b/Documentation/scsi/ChangeLog.1992-1997 deleted file mode 100644 index 6faad7e6417c..000000000000 --- a/Documentation/scsi/ChangeLog.1992-1997 +++ /dev/null | |||
| @@ -1,2023 +0,0 @@ | |||
| 1 | Sat Jan 18 15:51:45 1997 Richard Henderson <rth@tamu.edu> | ||
| 2 | |||
| 3 | * Don't play with usage_count directly, instead hand around | ||
| 4 | the module header and use the module macros. | ||
| 5 | |||
| 6 | Fri May 17 00:00:00 1996 Leonard N. Zubkoff <lnz@dandelion.com> | ||
| 7 | |||
| 8 | * BusLogic Driver Version 2.0.3 Released. | ||
| 9 | |||
| 10 | Tue Apr 16 21:00:00 1996 Leonard N. Zubkoff <lnz@dandelion.com> | ||
| 11 | |||
| 12 | * BusLogic Driver Version 1.3.2 Released. | ||
| 13 | |||
| 14 | Sun Dec 31 23:26:00 1995 Leonard N. Zubkoff <lnz@dandelion.com> | ||
| 15 | |||
| 16 | * BusLogic Driver Version 1.3.1 Released. | ||
| 17 | |||
| 18 | Fri Nov 10 15:29:49 1995 Leonard N. Zubkoff <lnz@dandelion.com> | ||
| 19 | |||
| 20 | * Released new BusLogic driver. | ||
| 21 | |||
| 22 | Wed Aug 9 22:37:04 1995 Andries Brouwer <aeb@cwi.nl> | ||
| 23 | |||
| 24 | As a preparation for new device code, separated the various | ||
| 25 | functions the request->dev field had into the device proper, | ||
| 26 | request->rq_dev and a status field request->rq_status. | ||
| 27 | |||
| 28 | The 2nd argument of bios_param is now a kdev_t. | ||
| 29 | |||
| 30 | Wed Jul 19 10:43:15 1995 Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de> | ||
| 31 | |||
| 32 | * scsi.c (scsi_proc_info): /proc/scsi/scsi now also lists all | ||
| 33 | attached devices. | ||
| 34 | |||
| 35 | * scsi_proc.c (proc_print_scsidevice): Added. Used by scsi.c and | ||
| 36 | eata_dma_proc.c to produce some device info for /proc/scsi. | ||
| 37 | |||
| 38 | * eata_dma.c (eata_queue)(eata_int_handler)(eata_scsi_done): | ||
| 39 | Changed handling of internal SCSI commands send to the HBA. | ||
| 40 | |||
| 41 | |||
| 42 | Wed Jul 19 10:09:17 1995 Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de> | ||
| 43 | |||
| 44 | * Linux 1.3.11 released. | ||
| 45 | |||
| 46 | * eata_dma.c (eata_queue)(eata_int_handler): Added code to do | ||
| 47 | command latency measurements if requested by root through | ||
| 48 | /proc/scsi interface. | ||
| 49 | Throughout Use HZ constant for time references. | ||
| 50 | |||
| 51 | * eata_pio.c: Use HZ constant for time references. | ||
| 52 | |||
| 53 | * aic7xxx.c, aic7xxx.h, aic7xxx_asm.c: Changed copyright from BSD | ||
| 54 | to GNU style. | ||
| 55 | |||
| 56 | * scsi.h: Added READ_12 command opcode constant | ||
| 57 | |||
| 58 | Wed Jul 19 09:25:30 1995 Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de> | ||
| 59 | |||
| 60 | * Linux 1.3.10 released. | ||
| 61 | |||
| 62 | * scsi_proc.c (dispatch_scsi_info): Removed unused variable. | ||
| 63 | |||
| 64 | Wed Jul 19 09:25:30 1995 Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de> | ||
| 65 | |||
| 66 | * Linux 1.3.9 released. | ||
| 67 | |||
| 68 | * scsi.c Blacklist concept expanded to 'support' more device | ||
| 69 | deficiencies. blacklist[] renamed to device_list[] | ||
| 70 | (scan_scsis): Code cleanup. | ||
| 71 | |||
| 72 | * scsi_debug.c (scsi_debug_proc_info): Added support to control | ||
| 73 | device lockup simulation via /proc/scsi interface. | ||
| 74 | |||
| 75 | |||
| 76 | Wed Jul 19 09:22:34 1995 Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de> | ||
| 77 | |||
| 78 | * Linux 1.3.7 released. | ||
| 79 | |||
| 80 | * scsi_proc.c: Fixed a number of bugs in directory handling | ||
| 81 | |||
| 82 | Wed Jul 19 09:18:28 1995 Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de> | ||
| 83 | |||
| 84 | * Linux 1.3.5 released. | ||
| 85 | |||
| 86 | * Native wide, multichannel and /proc/scsi support now in official | ||
| 87 | kernel distribution. | ||
| 88 | |||
| 89 | * scsi.c/h, hosts.c/h et al reindented to increase readability | ||
| 90 | (especially on 80 column wide terminals). | ||
| 91 | |||
| 92 | * scsi.c, scsi_proc.c, ../../fs/proc/inode.c: Added | ||
| 93 | /proc/scsi/scsi which allows root to scan for hotplugged devices. | ||
| 94 | |||
| 95 | * scsi.c (scsi_proc_info): Added, to support /proc/scsi/scsi. | ||
| 96 | (scan_scsis): Added some 'spaghetti' code to allow scanning for | ||
| 97 | single devices. | ||
| 98 | |||
| 99 | |||
| 100 | Thu Jun 20 15:20:27 1995 Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de> | ||
| 101 | |||
| 102 | * proc.c: Renamed to scsi_proc.c | ||
| 103 | |||
| 104 | Mon Jun 12 20:32:45 1995 Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de> | ||
| 105 | |||
| 106 | * Linux 1.3.0 released. | ||
| 107 | |||
| 108 | Mon May 15 19:33:14 1995 Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de> | ||
| 109 | |||
| 110 | * scsi.c: Added native multichannel and wide scsi support. | ||
| 111 | |||
| 112 | * proc.c (dispatch_scsi_info) (build_proc_dir_hba_entries): | ||
| 113 | Updated /proc/scsi interface. | ||
| 114 | |||
| 115 | Thu May 4 17:58:48 1995 Michael Neuffer <neuffer@goofy.zdv.uni-mainz.de> | ||
| 116 | |||
| 117 | * sd.c (requeue_sd_request): Zero out the scatterlist only if | ||
| 118 | scsi_malloc returned memory for it. | ||
| 119 | |||
| 120 | * eata_dma.c (register_HBA) (eata_queue): Add support for | ||
| 121 | large scatter/gather tables and set use_clustering accordingly | ||
| 122 | |||
| 123 | * hosts.c: Make use_clustering changeable in the Scsi_Host structure. | ||
| 124 | |||
| 125 | Wed Apr 12 15:25:52 1995 Eric Youngdale (eric@andante) | ||
| 126 | |||
| 127 | * Linux 1.2.5 released. | ||
| 128 | |||
| 129 | * buslogic.c: Update to version 1.15 (From Leonard N. Zubkoff). | ||
| 130 | Fixed interrupt routine to avoid races when handling multiple | ||
| 131 | complete commands per interrupt. Seems to come up with faster | ||
| 132 | cards. | ||
| 133 | |||
| 134 | * eata_dma.c: Update to 2.3.5r. Modularize. Improved error handling | ||
| 135 | throughout and fixed bug interrupt routine which resulted in shifted | ||
| 136 | status bytes. Added blink LED state checks for ISA and EISA HBAs. | ||
| 137 | Memory management bug seems to have disappeared ==> increasing | ||
| 138 | C_P_L_CURRENT_MAX to 16 for now. Decreasing C_P_L_DIV to 3 for | ||
| 139 | performance reasons. | ||
| 140 | |||
| 141 | * scsi.c: If we get a FMK, EOM, or ILI when attempting to scan | ||
| 142 | the bus, assume that it was just noise on the bus, and ignore | ||
| 143 | the device. | ||
| 144 | |||
| 145 | * scsi.h: Update and add a bunch of missing commands which we | ||
| 146 | were never using. | ||
| 147 | |||
| 148 | * sd.c: Use restore_flags in do_sd_request - this may result in | ||
| 149 | latency conditions, but it gets rid of races and crashes. | ||
| 150 | Do not save flags again when searching for a second command to | ||
| 151 | queue. | ||
| 152 | |||
| 153 | * st.c: Use bytes, not STP->buffer->buffer_size when reading | ||
| 154 | from tape. | ||
| 155 | |||
| 156 | |||
| 157 | Tue Apr 4 09:42:08 1995 Eric Youngdale (eric@andante) | ||
| 158 | |||
| 159 | * Linux 1.2.4 released. | ||
| 160 | |||
| 161 | * st.c: Fix typo - restoring wrong flags. | ||
| 162 | |||
| 163 | Wed Mar 29 06:55:12 1995 Eric Youngdale (eric@andante) | ||
| 164 | |||
| 165 | * Linux 1.2.3 released. | ||
| 166 | |||
| 167 | * st.c: Perform some waiting operations with interrupts off. | ||
| 168 | Is this correct??? | ||
| 169 | |||
| 170 | Wed Mar 22 10:34:26 1995 Eric Youngdale (eric@andante) | ||
| 171 | |||
| 172 | * Linux 1.2.2 released. | ||
| 173 | |||
| 174 | * aha152x.c: Modularize. Add support for PCMCIA. | ||
| 175 | |||
| 176 | * eata.c: Update to version 2.0. Fixed bug preventing media | ||
| 177 | detection. If scsi_register_host returns NULL, fail gracefully. | ||
| 178 | |||
| 179 | * scsi.c: Detect as NEC (for photo-cd purposes) for the 84 | ||
| 180 | and 25 models as "NEC_OLDCDR". | ||
| 181 | |||
| 182 | * scsi.h: Add define for NEC_OLDCDR | ||
| 183 | |||
| 184 | * sr.c: Add handling for NEC_OLDCDR. Treat as unknown. | ||
| 185 | |||
| 186 | * u14-34f.c: Update to version 2.0. Fixed same bug as in | ||
| 187 | eata.c. | ||
| 188 | |||
| 189 | |||
| 190 | Mon Mar 6 11:11:20 1995 Eric Youngdale (eric@andante) | ||
| 191 | |||
| 192 | * Linux 1.2.0 released. Yeah!!! | ||
| 193 | |||
| 194 | * Minor spelling/punctuation changes throughout. Nothing | ||
| 195 | substantive. | ||
| 196 | |||
| 197 | Mon Feb 20 21:33:03 1995 Eric Youngdale (eric@andante) | ||
| 198 | |||
| 199 | * Linux 1.1.95 released. | ||
| 200 | |||
| 201 | * qlogic.c: Update to version 0.41. | ||
| 202 | |||
| 203 | * seagate.c: Change some message to be more descriptive about what | ||
| 204 | we detected. | ||
| 205 | |||
| 206 | * sr.c: spelling/whitespace changes. | ||
| 207 | |||
| 208 | Mon Feb 20 21:33:03 1995 Eric Youngdale (eric@andante) | ||
| 209 | |||
| 210 | * Linux 1.1.94 released. | ||
| 211 | |||
| 212 | Mon Feb 20 08:57:17 1995 Eric Youngdale (eric@andante) | ||
| 213 | |||
| 214 | * Linux 1.1.93 released. | ||
| 215 | |||
| 216 | * hosts.h: Change io_port to long int from short. | ||
| 217 | |||
| 218 | * 53c7,8xx.c: crash on AEN fixed, SCSI reset is no longer a NOP, | ||
| 219 | NULL pointer panic on odd UDCs fixed, two bugs in diagnostic output | ||
| 220 | fixed, should initialize correctly if left running, now loadable, | ||
| 221 | new memory allocation, extraneous diagnostic output suppressed, | ||
| 222 | splx() replaced with save/restore flags. [ Drew ] | ||
| 223 | |||
| 224 | * hosts.c, hosts.h, scsi_ioctl.c, sd.c, sd_ioctl.c, sg.c, sr.c, | ||
| 225 | sr_ioctl.c: Add special junk at end that Emacs will use for | ||
| 226 | formatting the file. | ||
| 227 | |||
| 228 | * qlogic.c: Update to v0.40a. Improve parity handling. | ||
| 229 | |||
| 230 | * scsi.c: Add Hitachi DK312C to blacklist. Change "};" to "}" in | ||
| 231 | many places. Use scsi_init_malloc to get command block - may | ||
| 232 | need this to be dma compatible for some host adapters. | ||
| 233 | Restore interrupts after unregistering a host. | ||
| 234 | |||
| 235 | * sd.c: Use sti instead of restore flags - causes latency problems. | ||
| 236 | |||
| 237 | * seagate.c: Use controller_type to determine string used when | ||
| 238 | registering irq. | ||
| 239 | |||
| 240 | * sr.c: More photo-cd hacks to make sure we get the xa stuff right. | ||
| 241 | * sr.h, sr.c: Change is_xa to xa_flags field. | ||
| 242 | |||
| 243 | * st.c: Disable retries for write operations. | ||
| 244 | |||
| 245 | Wed Feb 15 10:52:56 1995 Eric Youngdale (eric@andante) | ||
| 246 | |||
| 247 | * Linux 1.1.92 released. | ||
| 248 | |||
| 249 | * eata.c: Update to 1.17. | ||
| 250 | |||
| 251 | * eata_dma.c: Update to 2.31a. Add more support for /proc/scsi. | ||
| 252 | Continuing modularization. Less crashes because of the bug in the | ||
| 253 | memory management ==> increase C_P_L_CURRENT_MAX to 10 | ||
| 254 | and decrease C_P_L_DIV to 4. | ||
| 255 | |||
| 256 | * hosts.c: If we remove last host registered, reuse host number. | ||
| 257 | When freeing memory from host being deregistered, free extra_bytes | ||
| 258 | too. | ||
| 259 | |||
| 260 | * scsi.c (scan_scsis): memset(SDpnt, 0) and set SCmd.device to SDpnt. | ||
| 261 | Change memory allocation to work around bugs in __get_dma_pages. | ||
| 262 | Do not free host if usage count is not zero (for modules). | ||
| 263 | |||
| 264 | * sr_ioctl.c: Increase IOCTL_TIMEOUT to 3000. | ||
| 265 | |||
| 266 | * st.c: Allow for ST_EXTRA_DEVS in st data structures. | ||
| 267 | |||
| 268 | * u14-34f.c: Update to 1.17. | ||
| 269 | |||
| 270 | Thu Feb 9 10:11:16 1995 Eric Youngdale (eric@andante) | ||
| 271 | |||
| 272 | * Linux 1.1.91 released. | ||
| 273 | |||
| 274 | * eata.c: Update to 1.16. Use wish_block instead of host->block. | ||
| 275 | |||
| 276 | * hosts.c: Initialize wish_block to 0. | ||
| 277 | |||
| 278 | * hosts.h: Add wish_block. | ||
| 279 | |||
| 280 | * scsi.c: Use wish_block as indicator that the host should be added | ||
| 281 | to block list. | ||
| 282 | |||
| 283 | * sg.c: Add SG_EXTRA_DEVS to number of slots. | ||
| 284 | |||
| 285 | * u14-34f.c: Use wish_block. | ||
| 286 | |||
| 287 | Tue Feb 7 11:46:04 1995 Eric Youngdale (eric@andante) | ||
| 288 | |||
| 289 | * Linux 1.1.90 released. | ||
| 290 | |||
| 291 | * eata.c: Change naming from eata_* to eata2x_*. Now at vers 1.15. | ||
| 292 | Update interrupt handler to take pt_regs as arg. Allow blocking | ||
| 293 | even if loaded as module. Initialize target_time_out array. | ||
| 294 | Do not put sti(); in timing loop. | ||
| 295 | |||
| 296 | * hosts.c: Do not reuse host numbers. | ||
| 297 | Use scsi_make_blocked_list to generate blocking list. | ||
| 298 | |||
| 299 | * script_asm.pl: Beats me. Don't know perl. Something to do with | ||
| 300 | phase index. | ||
| 301 | |||
| 302 | * scsi.c (scsi_make_blocked_list): New function - code copied from | ||
| 303 | hosts.c. | ||
| 304 | |||
| 305 | * scsi.c: Update code to disable photo CD for Toshiba cdroms. | ||
| 306 | Use just manufacturer name, not model number. | ||
| 307 | |||
| 308 | * sr.c: Fix setting density for Toshiba drives. | ||
| 309 | |||
| 310 | * u14-34f.c: Clear target_time_out array during reset. | ||
| 311 | |||
| 312 | Wed Feb 1 09:20:45 1995 Eric Youngdale (eric@andante) | ||
| 313 | |||
| 314 | * Linux 1.1.89 released. | ||
| 315 | |||
| 316 | * Makefile, u14-34f.c: Modularize. | ||
| 317 | |||
| 318 | * Makefile, eata.c: Modularize. Now version 1.14 | ||
| 319 | |||
| 320 | * NCR5380.c: Update interrupt handler with new arglist. Minor | ||
| 321 | cleanups. | ||
| 322 | |||
| 323 | * eata_dma.c: Begin to modularize. Add hooks for /proc/scsi. | ||
| 324 | New version 2.3.0a. Add code in interrupt handler to allow | ||
| 325 | certain CDROM drivers to be detected which return a | ||
| 326 | CHECK_CONDITION during SCSI bus scan. Add opcode check to get | ||
| 327 | all DATA IN and DATA OUT phases right. Utilize HBA_interpret flag. | ||
| 328 | Improvements in HBA identification. Various other minor stuff. | ||
| 329 | |||
| 330 | * hosts.c: Initialize ->dma_channel and ->io_port when registering | ||
| 331 | a new host. | ||
| 332 | |||
| 333 | * qlogic.c: Modularize and add PCMCIA support. | ||
| 334 | |||
| 335 | * scsi.c: Add Hitachi to blacklist. | ||
| 336 | |||
| 337 | * scsi.c: Change default to no lun scan (too many problem devices). | ||
| 338 | |||
| 339 | * scsi.h: Define QUEUE_FULL condition. | ||
| 340 | |||
| 341 | * sd.c: Do not check for non-existent partition until after | ||
| 342 | new media check. | ||
| 343 | |||
| 344 | * sg.c: Undo previous change which was wrong. | ||
| 345 | |||
| 346 | * sr_ioctl.c: Increase IOCTL_TIMEOUT to 2000. | ||
| 347 | |||
| 348 | * st.c: Patches from Kai - improve filemark handling. | ||
| 349 | |||
| 350 | Tue Jan 31 17:32:12 1995 Eric Youngdale (eric@andante) | ||
| 351 | |||
| 352 | * Linux 1.1.88 released. | ||
| 353 | |||
| 354 | * Throughout - spelling/grammar fixups. | ||
| 355 | |||
| 356 | * scsi.c: Make sure that all buffers are 16 byte aligned - some | ||
| 357 | drivers (buslogic) need this. | ||
| 358 | |||
| 359 | * scsi.c (scan_scsis): Remove message printed. | ||
| 360 | |||
| 361 | * scsi.c (scsi_init): Move message here. | ||
| 362 | |||
| 363 | Mon Jan 30 06:40:25 1995 Eric Youngdale (eric@andante) | ||
| 364 | |||
| 365 | * Linux 1.1.87 released. | ||
| 366 | |||
| 367 | * sr.c: Photo-cd related changes. (Gerd Knorr??). | ||
| 368 | |||
| 369 | * st.c: Changes from Kai related to EOM detection. | ||
| 370 | |||
| 371 | Mon Jan 23 23:53:10 1995 Eric Youngdale (eric@andante) | ||
| 372 | |||
| 373 | * Linux 1.1.86 released. | ||
| 374 | |||
| 375 | * 53c7,8xx.h: Change SG size to 127. | ||
| 376 | |||
| 377 | * eata_dma: Update to version 2.10i. Remove bug in the registration | ||
| 378 | of multiple HBAs and channels. Minor other improvements and stylistic | ||
| 379 | changes. | ||
| 380 | |||
| 381 | * scsi.c: Test for Toshiba XM-3401TA and exclude from detection | ||
| 382 | as toshiba drive - photo cd does not work with this drive. | ||
| 383 | |||
| 384 | * sr.c: Update photocd code. | ||
| 385 | |||
| 386 | Mon Jan 23 23:53:10 1995 Eric Youngdale (eric@andante) | ||
| 387 | |||
| 388 | * Linux 1.1.85 released. | ||
| 389 | |||
| 390 | * st.c, st_ioctl.c, sg.c, sd_ioctl.c, scsi_ioctl.c, hosts.c: | ||
| 391 | include linux/mm.h | ||
| 392 | |||
| 393 | * qlogic.c, buslogic.c, aha1542.c: Include linux/module.h. | ||
| 394 | |||
| 395 | Sun Jan 22 22:08:46 1995 Eric Youngdale (eric@andante) | ||
| 396 | |||
| 397 | * Linux 1.1.84 released. | ||
| 398 | |||
| 399 | * Makefile: Support for loadable QLOGIC boards. | ||
| 400 | |||
| 401 | * aha152x.c: Update to version 1.8 from Juergen. | ||
| 402 | |||
| 403 | * eata_dma.c: Update from Michael Neuffer. | ||
| 404 | Remove hard limit of 2 commands per lun and make it better | ||
| 405 | configurable. Improvements in HBA identification. | ||
| 406 | |||
| 407 | * in2000.c: Fix biosparam to support large disks. | ||
| 408 | |||
| 409 | * qlogic.c: Minor changes (change sti -> restore_flags). | ||
| 410 | |||
| 411 | Wed Jan 18 23:33:09 1995 Eric Youngdale (eric@andante) | ||
| 412 | |||
| 413 | * Linux 1.1.83 released. | ||
| 414 | |||
| 415 | * aha1542.c(aha1542_intr_handle): Use arguments handed down to find | ||
| 416 | which irq. | ||
| 417 | |||
| 418 | * buslogic.c: Likewise. | ||
| 419 | |||
| 420 | * eata_dma.c: Use min of 2 cmd_per_lun for OCS_enabled boards. | ||
| 421 | |||
| 422 | * scsi.c: Make RECOVERED_ERROR a SUGGEST_IS_OK. | ||
| 423 | |||
| 424 | * sd.c: Fail if we are opening a non-existent partition. | ||
| 425 | |||
| 426 | * sr.c: Bump SR_TIMEOUT to 15000. | ||
| 427 | Do not probe for media size at boot time(hard on changers). | ||
| 428 | Flag device as needing sector size instead. | ||
| 429 | |||
| 430 | * sr_ioctl.c: Remove CDROMMULTISESSION_SYS ioctl. | ||
| 431 | |||
| 432 | * ultrastor.c: Fix bug in call to ultrastor_interrupt (wrong #args). | ||
| 433 | |||
| 434 | Mon Jan 16 07:18:23 1995 Eric Youngdale (eric@andante) | ||
| 435 | |||
| 436 | * Linux 1.1.82 released. | ||
| 437 | |||
| 438 | Throughout. | ||
| 439 | - Change all interrupt handlers to accept new calling convention. | ||
| 440 | In particular, we now receive the irq number as one of the arguments. | ||
| 441 | |||
| 442 | * More minor spelling corrections in some of the new files. | ||
| 443 | |||
| 444 | * aha1542.c, buslogic.c: Clean up interrupt handler a little now | ||
| 445 | that we receive the irq as an arg. | ||
| 446 | |||
| 447 | * aha274x.c: s/snarf_region/request_region/ | ||
| 448 | |||
| 449 | * eata.c: Update to version 1.12. Fix some comments and display a | ||
| 450 | message if we cannot reserve the port addresses. | ||
| 451 | |||
| 452 | * u14-34f.c: Update to version 1.13. Fix some comments and display a | ||
| 453 | message if we cannot reserve the port addresses. | ||
| 454 | |||
| 455 | * eata_dma.c: Define get_board_data function (send INQUIRY command). | ||
| 456 | Use to improve detection of variants of different DPT boards. Change | ||
| 457 | version subnumber to "0g". | ||
| 458 | |||
| 459 | * fdomain.c: Update to version 5.26. Improve detection of some boards | ||
| 460 | repackaged by IBM. | ||
| 461 | |||
| 462 | * scsi.c (scsi_register_host): Change "name" to const char *. | ||
| 463 | |||
| 464 | * sr.c: Fix problem in set mode command for Toshiba drives. | ||
| 465 | |||
| 466 | * sr.c: Fix typo from patch 81. | ||
| 467 | |||
| 468 | Fri Jan 13 12:54:46 1995 Eric Youngdale (eric@andante) | ||
| 469 | |||
| 470 | * Linux 1.1.81 released. Codefreeze for 1.2 release announced. | ||
| 471 | |||
| 472 | Big changes here. | ||
| 473 | |||
| 474 | * eata_dma.*: New files from Michael Neuffer. | ||
| 475 | (neuffer@goofy.zdv.uni-mainz.de). Should support | ||
| 476 | all eata/dpt cards. | ||
| 477 | |||
| 478 | * hosts.c, Makefile: Add eata_dma. | ||
| 479 | |||
| 480 | * README.st: Document MTEOM. | ||
| 481 | |||
| 482 | Patches from me (ERY) to finish support for low-level loadable scsi. | ||
| 483 | It now works, and is actually useful. | ||
| 484 | |||
| 485 | * Throughout - add new argument to scsi_init_malloc that takes an | ||
| 486 | additional parameter. This is used as a priority to kmalloc, | ||
| 487 | and you can specify the GFP_DMA flag if you need DMA-able memory. | ||
| 488 | |||
| 489 | * Makefile: For source files that are loadable, always add name | ||
| 490 | to SCSI_SRCS. Fill in modules: target. | ||
| 491 | |||
| 492 | * hosts.c: Change next_host to next_scsi_host, and make global. | ||
| 493 | Print hosts after we have identified all of them. Use info() | ||
| 494 | function if present, otherwise use name field. | ||
| 495 | |||
| 496 | * hosts.h: Change attach function to return int, not void. | ||
| 497 | Define number of device slots to allow for loadable devices. | ||
| 498 | Define tags to tell scsi module code what type of module we | ||
| 499 | are loading. | ||
| 500 | |||
| 501 | * scsi.c: Fix scan_scsis so that it can be run by a user process. | ||
| 502 | Do not use waiting loops - use up and down mechanism as long | ||
| 503 | as current != task[0]. | ||
| 504 | |||
| 505 | * scsi.c(scan_scsis): Do not use stack variables for I/O - this | ||
| 506 | could be > 16Mb if we are loading a module at runtime (i.e. use | ||
| 507 | scsi_init_malloc to get some memory we know will be safe). | ||
| 508 | |||
| 509 | * scsi.c: Change dma freelist to be a set of pages. This allows | ||
| 510 | us to dynamically adjust the size of the list by adding more pages | ||
| 511 | to the pagelist. Fix scsi_malloc and scsi_free accordingly. | ||
| 512 | |||
| 513 | * scsi_module.c: Fix include. | ||
| 514 | |||
| 515 | * sd.c: Declare detach function. Increment/decrement module usage | ||
| 516 | count as required. Fix init functions to allow loaded devices. | ||
| 517 | Revalidate all new disks so we get the partition tables. Define | ||
| 518 | detach function. | ||
| 519 | |||
| 520 | * sr.c: Likewise. | ||
| 521 | |||
| 522 | * sg.c: Declare detach function. Allow attachment of devices on | ||
| 523 | loaded drivers. | ||
| 524 | |||
| 525 | * st.c: Declare detach function. Increment/decrement module usage | ||
| 526 | count as required. | ||
| 527 | |||
| 528 | Tue Jan 10 10:09:58 1995 Eric Youngdale (eric@andante) | ||
| 529 | |||
| 530 | * Linux 1.1.79 released. | ||
| 531 | |||
| 532 | Patch from some undetermined individual who needs to get a life :-). | ||
| 533 | |||
| 534 | * sr.c: Attacked by spelling bee... | ||
| 535 | |||
| 536 | Patches from Gerd Knorr: | ||
| 537 | |||
| 538 | * sr.c: make printk messages for photoCD a little more informative. | ||
| 539 | |||
| 540 | * sr_ioctl.c: Fix CDROMMULTISESSION_SYS ioctl. | ||
| 541 | |||
| 542 | Mon Jan 9 10:01:37 1995 Eric Youngdale (eric@andante) | ||
| 543 | |||
| 544 | * Linux 1.1.78 released. | ||
| 545 | |||
| 546 | * Makefile: Add empty modules: target. | ||
| 547 | |||
| 548 | * Wheee. Now change register_iomem to request_region. | ||
| 549 | |||
| 550 | * in2000.c: Bugfix - apparently this is the fix that we have | ||
| 551 | all been waiting for. It fixes a problem whereby the driver | ||
| 552 | is not stable under heavy load. Race condition and all that. | ||
| 553 | Patch from Peter Lu. | ||
| 554 | |||
| 555 | Wed Jan 4 21:17:40 1995 Eric Youngdale (eric@andante) | ||
| 556 | |||
| 557 | * Linux 1.1.77 released. | ||
| 558 | |||
| 559 | * 53c7,8xx.c: Fix from Linus - emulate splx. | ||
| 560 | |||
| 561 | Throughout: | ||
| 562 | |||
| 563 | Change "snarf_region" with "register_iomem". | ||
| 564 | |||
| 565 | * scsi_module.c: New file. Contains support for low-level loadable | ||
| 566 | scsi drivers. [ERY]. | ||
| 567 | |||
| 568 | * sd.c: More s/int/long/ changes. | ||
| 569 | |||
| 570 | * seagate.c: Explicitly include linux/config.h | ||
| 571 | |||
| 572 | * sg.c: Increment/decrement module usage count on open/close. | ||
| 573 | |||
| 574 | * sg.c: Be a bit more careful about the user not supplying enough | ||
| 575 | information for a valid command. Pass correct size down to | ||
| 576 | scsi_do_cmd. | ||
| 577 | |||
| 578 | * sr.c: More changes for Photo-CD. This apparently breaks NEC drives. | ||
| 579 | |||
| 580 | * sr_ioctl.c: Support CDROMMULTISESSION ioctl. | ||
| 581 | |||
| 582 | |||
| 583 | Sun Jan 1 19:55:21 1995 Eric Youngdale (eric@andante) | ||
| 584 | |||
| 585 | * Linux 1.1.76 released. | ||
| 586 | |||
| 587 | * constants.c: Add type cast in switch statement. | ||
| 588 | |||
| 589 | * scsi.c (scsi_free): Change datatype of "offset" to long. | ||
| 590 | (scsi_malloc): Change a few more variables to long. Who | ||
| 591 | did this and why was it important? 64 bit machines? | ||
| 592 | |||
| 593 | |||
| 594 | Lots of changes to use save_state/restore_state instead of cli/sti. | ||
| 595 | Files changed include: | ||
| 596 | |||
| 597 | * aha1542.c: | ||
| 598 | * aha1740.c: | ||
| 599 | * buslogic.c: | ||
| 600 | * in2000.c: | ||
| 601 | * scsi.c: | ||
| 602 | * scsi_debug.c: | ||
| 603 | * sd.c: | ||
| 604 | * sr.c: | ||
| 605 | * st.c: | ||
| 606 | |||
| 607 | Wed Dec 28 16:38:29 1994 Eric Youngdale (eric@andante) | ||
| 608 | |||
| 609 | * Linux 1.1.75 released. | ||
| 610 | |||
| 611 | * buslogic.c: Spelling fix. | ||
| 612 | |||
| 613 | * scsi.c: Add HP C1790A and C2500A scanjet to blacklist. | ||
| 614 | |||
| 615 | * scsi.c: Spelling fixup. | ||
| 616 | |||
| 617 | * sd.c: Add support for sd_hardsizes (hard sector sizes). | ||
| 618 | |||
| 619 | * ultrastor.c: Use save_flags/restore_flags instead of cli/sti. | ||
| 620 | |||
| 621 | Fri Dec 23 13:36:25 1994 Eric Youngdale (eric@andante) | ||
| 622 | |||
| 623 | * Linux 1.1.74 released. | ||
| 624 | |||
| 625 | * README.st: Update from Kai Makisara. | ||
| 626 | |||
| 627 | * eata.c: New version from Dario - version 1.11. | ||
| 628 | use scsicam bios_param routine. Add support for 2011 | ||
| 629 | and 2021 boards. | ||
| 630 | |||
| 631 | * hosts.c: Add support for blocking. Linked list automatically | ||
| 632 | generated when shpnt->block is set. | ||
| 633 | |||
| 634 | * scsi.c: Add sankyo & HP scanjet to blacklist. Add support for | ||
| 635 | kicking things loose when we deadlock. | ||
| 636 | |||
| 637 | * scsi.c: Recognize scanners and processors in scan_scsis. | ||
| 638 | |||
| 639 | * scsi_ioctl.h: Increase timeout to 9 seconds. | ||
| 640 | |||
| 641 | * st.c: New version from Kai - add better support for backspace. | ||
| 642 | |||
| 643 | * u14-34f.c: New version from Dario. Supports blocking. | ||
| 644 | |||
| 645 | Wed Dec 14 14:46:30 1994 Eric Youngdale (eric@andante) | ||
| 646 | |||
| 647 | * Linux 1.1.73 released. | ||
| 648 | |||
| 649 | * buslogic.c: Update from Dave Gentzel. Version 1.14. | ||
| 650 | Add module related stuff. More fault tolerant if out of | ||
| 651 | DMA memory. | ||
| 652 | |||
| 653 | * fdomain.c: New version from Rik Faith - version 5.22. Add support | ||
| 654 | for ISA-200S SCSI adapter. | ||
| 655 | |||
| 656 | * hosts.c: Spelling. | ||
| 657 | |||
| 658 | * qlogic.c: Update to version 0.38a. Add more support for PCMCIA. | ||
| 659 | |||
| 660 | * scsi.c: Mask device type with 0x1f during scan_scsis. | ||
| 661 | Add support for deadlocking, err, make that getting out of | ||
| 662 | deadlock situations that are created when we allow the user | ||
| 663 | to limit requests to one host adapter at a time. | ||
| 664 | |||
| 665 | * scsi.c: Bugfix - pass pid, not SCpnt as second arg to | ||
| 666 | scsi_times_out. | ||
| 667 | |||
| 668 | * scsi.c: Restore interrupt state to previous value instead of using | ||
| 669 | cli/sti pairs. | ||
| 670 | |||
| 671 | * scsi.c: Add a bunch of module stuff (all commented out for now). | ||
| 672 | |||
| 673 | * scsi.c: Clean up scsi_dump_status. | ||
| 674 | |||
| 675 | Tue Dec 6 12:34:20 1994 Eric Youngdale (eric@andante) | ||
| 676 | |||
| 677 | * Linux 1.1.72 released. | ||
| 678 | |||
| 679 | * sg.c: Bugfix - always use sg_free, since we might have big buff. | ||
| 680 | |||
| 681 | Fri Dec 2 11:24:53 1994 Eric Youngdale (eric@andante) | ||
| 682 | |||
| 683 | * Linux 1.1.71 released. | ||
| 684 | |||
| 685 | * sg.c: Clear buff field when not in use. Only call scsi_free if | ||
| 686 | non-null. | ||
| 687 | |||
| 688 | * scsi.h: Call wake_up(&wait_for_request) when done with a | ||
| 689 | command. | ||
| 690 | |||
| 691 | * scsi.c (scsi_times_out): Pass pid down so that we can protect | ||
| 692 | against race conditions. | ||
| 693 | |||
| 694 | * scsi.c (scsi_abort): Zero timeout field if we get the | ||
| 695 | NOT_RUNNING message back from low-level driver. | ||
| 696 | |||
| 697 | |||
| 698 | * scsi.c (scsi_done): Restore cmd_len, use_sg here. | ||
| 699 | |||
| 700 | * scsi.c (request_sense): Not here. | ||
| 701 | |||
| 702 | * hosts.h: Add new forbidden_addr, forbidden_size fields. Who | ||
| 703 | added these and why???? | ||
| 704 | |||
| 705 | * hosts.c (scsi_mem_init): Mark pages as reserved if they fall in | ||
| 706 | the forbidden regions. I am not sure - I think this is so that | ||
| 707 | we can deal with boards that do incomplete decoding of their | ||
| 708 | address lines for the bios chips, but I am not entirely sure. | ||
| 709 | |||
| 710 | * buslogic.c: Set forbidden_addr stuff if using a buggy board. | ||
| 711 | |||
| 712 | * aha1740.c: Test for NULL pointer in SCtmp. This should not | ||
| 713 | occur, but a nice message is better than a kernel segfault. | ||
| 714 | |||
| 715 | * 53c7,8xx.c: Add new PCI chip ID for 815. | ||
| 716 | |||
| 717 | Fri Dec 2 11:24:53 1994 Eric Youngdale (eric@andante) | ||
| 718 | |||
| 719 | * Linux 1.1.70 released. | ||
| 720 | |||
| 721 | * ChangeLog, st.c: Spelling. | ||
| 722 | |||
| 723 | Tue Nov 29 18:48:42 1994 Eric Youngdale (eric@andante) | ||
| 724 | |||
| 725 | * Linux 1.1.69 released. | ||
| 726 | |||
| 727 | * u14-34f.h: Non-functional change. [Dario]. | ||
| 728 | |||
| 729 | * u14-34f.c: Use block field in Scsi_Host to prevent commands from | ||
| 730 | being queued to more than one host at the same time (used when | ||
| 731 | motherboard does not deal with multiple bus-masters very well). | ||
| 732 | Only when SINGLE_HOST_OPERATIONS is defined. | ||
| 733 | Use new cmd_per_lun field. [Dario] | ||
| 734 | |||
| 735 | * eata.c: Likewise. | ||
| 736 | |||
| 737 | * st.c: More changes from Kai. Add ready flag to indicate drive | ||
| 738 | status. | ||
| 739 | |||
| 740 | * README.st: Document this. | ||
| 741 | |||
| 742 | * sr.c: Bugfix (do not subtract CD_BLOCK_OFFSET) for photo-cd | ||
| 743 | code. | ||
| 744 | |||
| 745 | * sg.c: Bugfix - fix problem where opcode is not correctly set up. | ||
| 746 | |||
| 747 | * seagate.[c,h]: Use #defines to set driver name. | ||
| 748 | |||
| 749 | * scsi_ioctl.c: Zero buffer before executing command. | ||
| 750 | |||
| 751 | * scsi.c: Use new cmd_per_lun field in Scsi_Hosts as appropriate. | ||
| 752 | Add Sony CDU55S to blacklist. | ||
| 753 | |||
| 754 | * hosts.h: Add new cmd_per_lun field to Scsi_Hosts. | ||
| 755 | |||
| 756 | * hosts.c: Initialize cmd_per_lun in Scsi_Hosts from template. | ||
| 757 | |||
| 758 | * buslogic.c: Use cmd_per_lun field - initialize to different | ||
| 759 | values depending upon bus type (i.e. use 1 if ISA, so we do not | ||
| 760 | hog memory). Use other patches which got lost from 1.1.68. | ||
| 761 | |||
| 762 | * aha1542.c: Spelling. | ||
| 763 | |||
| 764 | Tue Nov 29 15:43:50 1994 Eric Youngdale (eric@andante.aib.com) | ||
| 765 | |||
| 766 | * Linux 1.1.68 released. | ||
| 767 | |||
| 768 | Add support for 12 byte vendor specific commands in scsi-generics, | ||
| 769 | more (i.e. the last mandatory) low-level changes to support | ||
| 770 | loadable modules, plus a few other changes people have requested | ||
| 771 | lately. Changes by me (ERY) unless otherwise noted. Spelling | ||
| 772 | changes appear from some unknown corner of the universe. | ||
| 773 | |||
| 774 | * Throughout: Change COMMAND_SIZE() to use SCpnt->cmd_len. | ||
| 775 | |||
| 776 | * Throughout: Change info() low level function to take a Scsi_Host | ||
| 777 | pointer. This way the info function can return specific | ||
| 778 | information about the host in question, if desired. | ||
| 779 | |||
| 780 | * All low-level drivers: Add NULL in initializer for the | ||
| 781 | usage_count field added to Scsi_Host_Template. | ||
| 782 | |||
| 783 | * aha152x.[c,h]: Remove redundant info() function. | ||
| 784 | |||
| 785 | * aha1542.[c,h]: Likewise. | ||
| 786 | |||
| 787 | * aha1740.[c,h]: Likewise. | ||
| 788 | |||
| 789 | * aha274x.[c,h]: Likewise. | ||
| 790 | |||
| 791 | * eata.[c,h]: Likewise. | ||
| 792 | |||
| 793 | * pas16.[c,h]: Likewise. | ||
| 794 | |||
| 795 | * scsi_debug.[c,h]: Likewise. | ||
| 796 | |||
| 797 | * t128.[c,h]: Likewise. | ||
| 798 | |||
| 799 | * u14-34f.[c,h]: Likewise. | ||
| 800 | |||
| 801 | * ultrastor.[c,h]: Likewise. | ||
| 802 | |||
| 803 | * wd7000.[c,h]: Likewise. | ||
| 804 | |||
| 805 | * aha1542.c: Add support for command line options with lilo to set | ||
| 806 | DMA parameters, I/O port. From Matt Aarnio. | ||
| 807 | |||
| 808 | * buslogic.[c,h]: New version (1.13) from Dave Gentzel. | ||
| 809 | |||
| 810 | * hosts.h: Add new field to Scsi_Hosts "block" to allow blocking | ||
| 811 | all I/O to certain other cards. Helps prevent problems with some | ||
| 812 | ISA motherboards. | ||
| 813 | |||
| 814 | * hosts.h: Add usage_count to Scsi_Host_Template. | ||
| 815 | |||
| 816 | * hosts.h: Add n_io_port to Scsi_Host (used when releasing module). | ||
| 817 | |||
| 818 | * hosts.c: Initialize block field. | ||
| 819 | |||
| 820 | * in2000.c: Remove "static" declarations from exported functions. | ||
| 821 | |||
| 822 | * in2000.h: Likewise. | ||
| 823 | |||
| 824 | * scsi.c: Correctly set cmd_len field as required. Save and | ||
| 825 | change setting when doing a request_sense, restore when done. | ||
| 826 | Move abort timeout message. Fix panic in request_queueable to | ||
| 827 | print correct function name. | ||
| 828 | |||
| 829 | * scsi.c: When incrementing usage count, walk block linked list | ||
| 830 | for host, and or in SCSI_HOST_BLOCK bit. When decrementing usage | ||
| 831 | count to 0, clear this bit to allow usage to continue, wake up | ||
| 832 | processes waiting. | ||
| 833 | |||
| 834 | |||
| 835 | * scsi_ioctl.c: If we have an info() function, call it, otherwise | ||
| 836 | if we have a "name" field, use it, else do nothing. | ||
| 837 | |||
| 838 | * sd.c, sr.c: Clear cmd_len field prior to each command we | ||
| 839 | generate. | ||
| 840 | |||
| 841 | * sd.h: Add "has_part_table" bit to rscsi_disks. | ||
| 842 | |||
| 843 | * sg.[c,h]: Add support for vendor specific 12 byte commands (i.e. | ||
| 844 | override command length in COMMAND_SIZE). | ||
| 845 | |||
| 846 | * sr.c: Bugfix from Gerd in photocd code. | ||
| 847 | |||
| 848 | * sr.c: Bugfix in get_sectorsize - always use scsi_malloc buffer - | ||
| 849 | we cannot guarantee that the stack is < 16Mb. | ||
| 850 | |||
| 851 | Tue Nov 22 15:40:46 1994 Eric Youngdale (eric@andante.aib.com) | ||
| 852 | |||
| 853 | * Linux 1.1.67 released. | ||
| 854 | |||
| 855 | * sr.c: Change spelling of manufactor to manufacturer. | ||
| 856 | |||
| 857 | * scsi.h: Likewise. | ||
| 858 | |||
| 859 | * scsi.c: Likewise. | ||
| 860 | |||
| 861 | * qlogic.c: Spelling corrections. | ||
| 862 | |||
| 863 | * in2000.h: Spelling corrections. | ||
| 864 | |||
| 865 | * in2000.c: Update from Bill Earnest, change from | ||
| 866 | jshiffle@netcom.com. Support new bios versions. | ||
| 867 | |||
| 868 | * README.qlogic: Spelling correction. | ||
| 869 | |||
| 870 | Tue Nov 22 15:40:46 1994 Eric Youngdale (eric@andante.aib.com) | ||
| 871 | |||
| 872 | * Linux 1.1.66 released. | ||
| 873 | |||
| 874 | * u14-34f.c: Spelling corrections. | ||
| 875 | |||
| 876 | * sr.[h,c]: Add support for multi-session CDs from Gerd Knorr. | ||
| 877 | |||
| 878 | * scsi.h: Add manufactor field for keeping track of device | ||
| 879 | manufacturer. | ||
| 880 | |||
| 881 | * scsi.c: More spelling corrections. | ||
| 882 | |||
| 883 | * qlogic.h, qlogic.c, README.qlogic: New driver from Tom Zerucha. | ||
| 884 | |||
| 885 | * in2000.c, in2000.h: New driver from Brad McLean/Bill Earnest. | ||
| 886 | |||
| 887 | * fdomain.c: Spelling correction. | ||
| 888 | |||
| 889 | * eata.c: Spelling correction. | ||
| 890 | |||
| 891 | Fri Nov 18 15:22:44 1994 Eric Youngdale (eric@andante.aib.com) | ||
| 892 | |||
| 893 | * Linux 1.1.65 released. | ||
| 894 | |||
| 895 | * eata.h: Update version string to 1.08.00. | ||
| 896 | |||
| 897 | * eata.c: Set sg_tablesize correctly for DPT PM2012 boards. | ||
| 898 | |||
| 899 | * aha274x.seq: Spell checking. | ||
| 900 | |||
| 901 | * README.st: Likewise. | ||
| 902 | |||
| 903 | * README.aha274x: Likewise. | ||
| 904 | |||
| 905 | * ChangeLog: Likewise. | ||
| 906 | |||
| 907 | Tue Nov 15 15:35:08 1994 Eric Youngdale (eric@andante.aib.com) | ||
| 908 | |||
| 909 | * Linux 1.1.64 released. | ||
| 910 | |||
| 911 | * u14-34f.h: Update version number to 1.10.01. | ||
| 912 | |||
| 913 | * u14-34f.c: Use Scsi_Host can_queue variable instead of one from template. | ||
| 914 | |||
| 915 | * eata.[c,h]: New driver for DPT boards from Dario Ballabio. | ||
| 916 | |||
| 917 | * buslogic.c: Use can_queue field. | ||
| 918 | |||
| 919 | Wed Nov 30 12:09:09 1994 Eric Youngdale (eric@andante.aib.com) | ||
| 920 | |||
| 921 | * Linux 1.1.63 released. | ||
| 922 | |||
| 923 | * sd.c: Give I/O error if we attempt 512 byte I/O to a disk with | ||
| 924 | 1024 byte sectors. | ||
| 925 | |||
| 926 | * scsicam.c: Make sure we do read from whole disk (mask off | ||
| 927 | partition). | ||
| 928 | |||
| 929 | * scsi.c: Use can_queue in Scsi_Host structure. | ||
| 930 | Fix panic message about invalid host. | ||
| 931 | |||
| 932 | * hosts.c: Initialize can_queue from template. | ||
| 933 | |||
| 934 | * hosts.h: Add can_queue to Scsi_Host structure. | ||
| 935 | |||
| 936 | * aha1740.c: Print out warning about NULL ecbptr. | ||
| 937 | |||
| 938 | Fri Nov 4 12:40:30 1994 Eric Youngdale (eric@andante.aib.com) | ||
| 939 | |||
| 940 | * Linux 1.1.62 released. | ||
| 941 | |||
| 942 | * fdomain.c: Update to version 5.20. (From Rik Faith). Support | ||
| 943 | BIOS version 3.5. | ||
| 944 | |||
| 945 | * st.h: Add ST_EOD symbol. | ||
| 946 | |||
| 947 | * st.c: Patches from Kai Makisara - support additional densities, | ||
| 948 | add support for MTFSS, MTBSS, MTWSM commands. | ||
| 949 | |||
| 950 | * README.st: Update to document new commands. | ||
| 951 | |||
| 952 | * scsi.c: Add Mediavision CDR-H93MV to blacklist. | ||
| 953 | |||
| 954 | Sat Oct 29 20:57:36 1994 Eric Youngdale (eric@andante.aib.com) | ||
| 955 | |||
| 956 | * Linux 1.1.60 released. | ||
| 957 | |||
| 958 | * u14-34f.[c,h]: New driver from Dario Ballabio. | ||
| 959 | |||
| 960 | * aic7770.c, aha274x_seq.h, aha274x.seq, aha274x.h, aha274x.c, | ||
| 961 | README.aha274x: New files, new driver from John Aycock. | ||
| 962 | |||
| 963 | |||
| 964 | Tue Oct 11 08:47:39 1994 Eric Youngdale (eric@andante) | ||
| 965 | |||
| 966 | * Linux 1.1.54 released. | ||
| 967 | |||
| 968 | * Add third PCI chip id. [Drew] | ||
| 969 | |||
| 970 | * buslogic.c: Set BUSLOGIC_CMDLUN back to 1 [Eric]. | ||
| 971 | |||
| 972 | * ultrastor.c: Fix asm directives for new GCC. | ||
| 973 | |||
| 974 | * sr.c, sd.c: Use new end_scsi_request function. | ||
| 975 | |||
| 976 | * scsi.h(end_scsi_request): Return pointer to block if still | ||
| 977 | active, else return NULL if inactive. Fixes race condition. | ||
| 978 | |||
| 979 | Sun Oct 9 20:23:14 1994 Eric Youngdale (eric@andante) | ||
| 980 | |||
| 981 | * Linux 1.1.53 released. | ||
| 982 | |||
| 983 | * scsi.c: Do not allocate dma bounce buffers if we have exactly | ||
| 984 | 16Mb. | ||
| 985 | |||
| 986 | Fri Sep 9 05:35:30 1994 Eric Youngdale (eric@andante) | ||
| 987 | |||
| 988 | * Linux 1.1.51 released. | ||
| 989 | |||
| 990 | * aha152x.c: Add support for disabling the parity check. Update | ||
| 991 | to version 1.4. [Juergen]. | ||
| 992 | |||
| 993 | * seagate.c: Tweak debugging message. | ||
| 994 | |||
| 995 | Wed Aug 31 10:15:55 1994 Eric Youngdale (eric@andante) | ||
| 996 | |||
| 997 | * Linux 1.1.50 released. | ||
| 998 | |||
| 999 | * aha152x.c: Add eb800 for Vtech Platinum SMP boards. [Juergen]. | ||
| 1000 | |||
| 1001 | * scsi.c: Add Quantum PD1225S to blacklist. | ||
| 1002 | |||
| 1003 | Fri Aug 26 09:38:45 1994 Eric Youngdale (eric@andante) | ||
| 1004 | |||
| 1005 | * Linux 1.1.49 released. | ||
| 1006 | |||
| 1007 | * sd.c: Fix bug when we were deleting the wrong entry if we | ||
| 1008 | get an unsupported sector size device. | ||
| 1009 | |||
| 1010 | * sr.c: Another spelling patch. | ||
| 1011 | |||
| 1012 | Thu Aug 25 09:15:27 1994 Eric Youngdale (eric@andante) | ||
| 1013 | |||
| 1014 | * Linux 1.1.48 released. | ||
| 1015 | |||
| 1016 | * Throughout: Use new semantics for request_dma, as appropriate. | ||
| 1017 | |||
| 1018 | * sr.c: Print correct device number. | ||
| 1019 | |||
| 1020 | Sun Aug 21 17:49:23 1994 Eric Youngdale (eric@andante) | ||
| 1021 | |||
| 1022 | * Linux 1.1.47 released. | ||
| 1023 | |||
| 1024 | * NCR5380.c: Add support for LIMIT_TRANSFERSIZE. | ||
| 1025 | |||
| 1026 | * constants.h: Add prototype for print_Scsi_Cmnd. | ||
| 1027 | |||
| 1028 | * pas16.c: Some more minor tweaks. Test for Mediavision board. | ||
| 1029 | Allow for disks > 1Gb. [Drew??] | ||
| 1030 | |||
| 1031 | * sr.c: Set SCpnt->transfersize. | ||
| 1032 | |||
| 1033 | Tue Aug 16 17:29:35 1994 Eric Youngdale (eric@andante) | ||
| 1034 | |||
| 1035 | * Linux 1.1.46 released. | ||
| 1036 | |||
| 1037 | * Throughout: More spelling fixups. | ||
| 1038 | |||
| 1039 | * buslogic.c: Add a few more fixups from Dave. Disk translation | ||
| 1040 | mainly. | ||
| 1041 | |||
| 1042 | * pas16.c: Add a few patches (Drew?). | ||
| 1043 | |||
| 1044 | |||
| 1045 | Thu Aug 11 20:45:15 1994 Eric Youngdale (eric@andante) | ||
| 1046 | |||
| 1047 | * Linux 1.1.44 released. | ||
| 1048 | |||
| 1049 | * hosts.c: Add type casts for scsi_init_malloc. | ||
| 1050 | |||
| 1051 | * scsicam.c: Add type cast. | ||
| 1052 | |||
| 1053 | Wed Aug 10 19:23:01 1994 Eric Youngdale (eric@andante) | ||
| 1054 | |||
| 1055 | * Linux 1.1.43 released. | ||
| 1056 | |||
| 1057 | * Throughout: Spelling cleanups. [??] | ||
| 1058 | |||
| 1059 | * aha152x.c, NCR53*.c, fdomain.c, g_NCR5380.c, pas16.c, seagate.c, | ||
| 1060 | t128.c: Use request_irq, not irqaction. [??] | ||
| 1061 | |||
| 1062 | * aha1542.c: Move test for shost before we start to use shost. | ||
| 1063 | |||
| 1064 | * aha1542.c, aha1740.c, ultrastor.c, wd7000.c: Use new | ||
| 1065 | calling sequence for request_irq. | ||
| 1066 | |||
| 1067 | * buslogic.c: Update from Dave Gentzel. | ||
| 1068 | |||
| 1069 | Tue Aug 9 09:32:59 1994 Eric Youngdale (eric@andante) | ||
| 1070 | |||
| 1071 | * Linux 1.1.42 released. | ||
| 1072 | |||
| 1073 | * NCR5380.c: Change NCR5380_print_status to static. | ||
| 1074 | |||
| 1075 | * seagate.c: A few more bugfixes. Only Drew knows what they are | ||
| 1076 | for. | ||
| 1077 | |||
| 1078 | * ultrastor.c: Tweak some __asm__ directives so that it works | ||
| 1079 | with newer compilers. [??] | ||
| 1080 | |||
| 1081 | Sat Aug 6 21:29:36 1994 Eric Youngdale (eric@andante) | ||
| 1082 | |||
| 1083 | * Linux 1.1.40 released. | ||
| 1084 | |||
| 1085 | * NCR5380.c: Return SCSI_RESET_WAKEUP from reset function. | ||
| 1086 | |||
| 1087 | * aha1542.c: Reset mailbox status after a bus device reset. | ||
| 1088 | |||
| 1089 | * constants.c: Fix typo (;;). | ||
| 1090 | |||
| 1091 | * g_NCR5380.c: | ||
| 1092 | * pas16.c: Correct usage of NCR5380_init. | ||
| 1093 | |||
| 1094 | * scsi.c: Remove redundant (and unused variables). | ||
| 1095 | |||
| 1096 | * sd.c: Use memset to clear all of rscsi_disks before we use it. | ||
| 1097 | |||
| 1098 | * sg.c: Ditto, except for scsi_generics. | ||
| 1099 | |||
| 1100 | * sr.c: Ditto, except for scsi_CDs. | ||
| 1101 | |||
| 1102 | * st.c: Initialize STp->device. | ||
| 1103 | |||
| 1104 | * seagate.c: Fix bug. [Drew] | ||
| 1105 | |||
| 1106 | Thu Aug 4 08:47:27 1994 Eric Youngdale (eric@andante) | ||
| 1107 | |||
| 1108 | * Linux 1.1.39 released. | ||
| 1109 | |||
| 1110 | * Makefile: Fix typo in NCR53C7xx. | ||
| 1111 | |||
| 1112 | * st.c: Print correct number for device. | ||
| 1113 | |||
| 1114 | Tue Aug 2 11:29:14 1994 Eric Youngdale (eric@esp22) | ||
| 1115 | |||
| 1116 | * Linux 1.1.38 released. | ||
| 1117 | |||
| 1118 | Lots of changes in 1.1.38. All from Drew unless otherwise noted. | ||
| 1119 | |||
| 1120 | * 53c7,8xx.c: New file from Drew. PCI driver. | ||
| 1121 | |||
| 1122 | * 53c7,8xx.h: Likewise. | ||
| 1123 | |||
| 1124 | * 53c7,8xx.scr: Likewise. | ||
| 1125 | |||
| 1126 | * 53c8xx_d.h, 53c8xx_u.h, script_asm.pl: Likewise. | ||
| 1127 | |||
| 1128 | * scsicam.c: New file from Drew. Read block 0 on the disk and | ||
| 1129 | read the partition table. Attempt to deduce the geometry from | ||
| 1130 | the partition table if possible. Only used by 53c[7,8]xx right | ||
| 1131 | now, but could be used by any device for which we have no way | ||
| 1132 | of identifying the geometry. | ||
| 1133 | |||
| 1134 | * sd.c: Use device letters instead of sd%d in a lot of messages. | ||
| 1135 | |||
| 1136 | * seagate.c: Fix bug that resulted in lockups with some devices. | ||
| 1137 | |||
| 1138 | * sr.c (sr_open): Return -EROFS, not -EACCES if we attempt to open | ||
| 1139 | device for write. | ||
| 1140 | |||
| 1141 | * hosts.c, Makefile: Update for new driver. | ||
| 1142 | |||
| 1143 | * NCR5380.c, NCR5380.h, g_NCR5380.h: Update from Drew to support | ||
| 1144 | 53C400 chip. | ||
| 1145 | |||
| 1146 | * constants.c: Define CONST_CMND and CONST_MSG. Other minor | ||
| 1147 | cleanups along the way. Improve handling of CONST_MSG. | ||
| 1148 | |||
| 1149 | * fdomain.c, fdomain.h: New version from Rik Faith. Update to | ||
| 1150 | 5.18. Should now support TMC-3260 PCI card with 18C30 chip. | ||
| 1151 | |||
| 1152 | * pas16.c: Update with new irq initialization. | ||
| 1153 | |||
| 1154 | * t128.c: Update with minor cleanups. | ||
| 1155 | |||
| 1156 | * scsi.c (scsi_pid): New variable - gives each command a unique | ||
| 1157 | id. Add Quantum LPS5235S to blacklist. Change in_scan to | ||
| 1158 | in_scan_scsis and make global. | ||
| 1159 | |||
| 1160 | * scsi.h: Add some defines for extended message handling, | ||
| 1161 | INITIATE/RELEASE_RECOVERY. Add a few new fields to support sync | ||
| 1162 | transfers. | ||
| 1163 | |||
| 1164 | * scsi_ioctl.h: Add ioctl to request synchronous transfers. | ||
| 1165 | |||
| 1166 | |||
| 1167 | Tue Jul 26 21:36:58 1994 Eric Youngdale (eric@esp22) | ||
| 1168 | |||
| 1169 | * Linux 1.1.37 released. | ||
| 1170 | |||
| 1171 | * aha1542.c: Always call aha1542_mbenable, use new udelay | ||
| 1172 | mechanism so we do not wait a long time if the board does not | ||
| 1173 | implement this command. | ||
| 1174 | |||
| 1175 | * g_NCR5380.c: Remove #include <linux/config.h> and #if | ||
| 1176 | defined(CONFIG_SCSI_*). | ||
| 1177 | |||
| 1178 | * seagate.c: Likewise. | ||
| 1179 | |||
| 1180 | Next round of changes to support loadable modules. Getting closer | ||
| 1181 | now, still not possible to do anything remotely usable. | ||
| 1182 | |||
| 1183 | hosts.c: Create a linked list of detected high level devices. | ||
| 1184 | (scsi_register_device): New function to insert into this list. | ||
| 1185 | (scsi_init): Call scsi_register_device for each of the known high | ||
| 1186 | level drivers. | ||
| 1187 | |||
| 1188 | hosts.h: Add prototype for linked list header. Add structure | ||
| 1189 | definition for device template structure which defines the linked | ||
| 1190 | list. | ||
| 1191 | |||
| 1192 | scsi.c: (scan_scsis): Use linked list instead of knowledge about | ||
| 1193 | existing high level device drivers. | ||
| 1194 | (scsi_dev_init): Use init functions for drivers on linked list | ||
| 1195 | instead of explicit list to initialize and attach devices to high | ||
| 1196 | level drivers. | ||
| 1197 | |||
| 1198 | scsi.h: Add new field "attached" to scsi_device - count of number | ||
| 1199 | of high level devices attached. | ||
| 1200 | |||
| 1201 | sd.c, sr.c, sg.c, st.c: Adjust init/attach functions to use new | ||
| 1202 | scheme. | ||
| 1203 | |||
| 1204 | Sat Jul 23 13:03:17 1994 Eric Youngdale (eric@esp22) | ||
| 1205 | |||
| 1206 | * Linux 1.1.35 released. | ||
| 1207 | |||
| 1208 | * ultrastor.c: Change constraint on asm() operand so that it works | ||
| 1209 | with gcc 2.6.0. | ||
| 1210 | |||
| 1211 | Thu Jul 21 10:37:39 1994 Eric Youngdale (eric@esp22) | ||
| 1212 | |||
| 1213 | * Linux 1.1.33 released. | ||
| 1214 | |||
| 1215 | * sr.c(sr_open): Do not allow opens with write access. | ||
| 1216 | |||
| 1217 | Mon Jul 18 09:51:22 1994 Eric Youngdale (eric@esp22) | ||
| 1218 | |||
| 1219 | * Linux 1.1.31 released. | ||
| 1220 | |||
| 1221 | * sd.c: Increase SD_TIMEOUT from 300 to 600. | ||
| 1222 | |||
| 1223 | * sr.c: Remove stray task_struct* variable that was no longer | ||
| 1224 | used. | ||
| 1225 | |||
| 1226 | * sr_ioctl.c: Fix typo in up() call. | ||
| 1227 | |||
| 1228 | Sun Jul 17 16:25:29 1994 Eric Youngdale (eric@esp22) | ||
| 1229 | |||
| 1230 | * Linux 1.1.30 released. | ||
| 1231 | |||
| 1232 | * scsi.c (scan_scsis): Fix detection of some Toshiba CDROM drives | ||
| 1233 | that report themselves as disk drives. | ||
| 1234 | |||
| 1235 | * (Throughout): Use request.sem instead of request.waiting. | ||
| 1236 | Should fix swap problem with fdomain. | ||
| 1237 | |||
| 1238 | Thu Jul 14 10:51:42 1994 Eric Youngdale (eric@esp22) | ||
| 1239 | |||
| 1240 | * Linux 1.1.29 released. | ||
| 1241 | |||
| 1242 | * scsi.c (scan_scsis): Add new devices to end of linked list, not | ||
| 1243 | to the beginning. | ||
| 1244 | |||
| 1245 | * scsi.h (SCSI_SLEEP): Remove brain dead hack to try to save | ||
| 1246 | the task state before sleeping. | ||
| 1247 | |||
| 1248 | Sat Jul 9 15:01:03 1994 Eric Youngdale (eric@esp22) | ||
| 1249 | |||
| 1250 | More changes to eventually support loadable modules. Mainly | ||
| 1251 | we want to use linked lists instead of arrays because it is easier | ||
| 1252 | to dynamically add and remove things this way. | ||
| 1253 | |||
| 1254 | Quite a bit more work is needed before loadable modules are | ||
| 1255 | possible (and usable) with scsi, but this is most of the grunge | ||
| 1256 | work. | ||
| 1257 | |||
| 1258 | * Linux 1.1.28 released. | ||
| 1259 | |||
| 1260 | * scsi.c, scsi.h (allocate_device, request_queueable): Change | ||
| 1261 | argument from index into scsi_devices to a pointer to the | ||
| 1262 | Scsi_Device struct. | ||
| 1263 | |||
| 1264 | * Throughout: Change all calls to allocate_device, | ||
| 1265 | request_queueable to use new calling sequence. | ||
| 1266 | |||
| 1267 | * Throughout: Use SCpnt->device instead of | ||
| 1268 | scsi_devices[SCpnt->index]. Ugh - the pointer was there all along | ||
| 1269 | - much cleaner this way. | ||
| 1270 | |||
| 1271 | * scsi.c (scsi_init_malloc, scsi_free_malloc): New functions - | ||
| 1272 | allow us to pretend that we have a working malloc when we | ||
| 1273 | initialize. Use this instead of passing memory_start, memory_end | ||
| 1274 | around all over the place. | ||
| 1275 | |||
| 1276 | * scsi.h, st.c, sr.c, sd.c, sg.c: Change *_init1 functions to use | ||
| 1277 | scsi_init_malloc, remove all arguments, no return value. | ||
| 1278 | |||
| 1279 | * scsi.h: Remove index field from Scsi_Device and Scsi_Cmnd | ||
| 1280 | structs. | ||
| 1281 | |||
| 1282 | * scsi.c (scsi_dev_init): Set up for scsi_init_malloc. | ||
| 1283 | (scan_scsis): Get SDpnt from scsi_init_malloc, and refresh | ||
| 1284 | when we discover a device. Free pointer before returning. | ||
| 1285 | Change scsi_devices into a linked list. | ||
| 1286 | |||
| 1287 | * scsi.c (scan_scsis): Change to only scan one host. | ||
| 1288 | (scsi_dev_init): Loop over all detected hosts, and scan them. | ||
| 1289 | |||
| 1290 | * hosts.c (scsi_init_free): Change so that number of extra bytes | ||
| 1291 | is stored in struct, and we do not have to pass it each time. | ||
| 1292 | |||
| 1293 | * hosts.h: Change Scsi_Host_Template struct to include "next" and | ||
| 1294 | "release" functions. Initialize to NULL in all low level | ||
| 1295 | adapters. | ||
| 1296 | |||
| 1297 | * hosts.c: Rename scsi_hosts to builtin_scsi_hosts, create linked | ||
| 1298 | list scsi_hosts, linked together with the new "next" field. | ||
| 1299 | |||
| 1300 | Wed Jul 6 05:45:02 1994 Eric Youngdale (eric@esp22) | ||
| 1301 | |||
| 1302 | * Linux 1.1.25 released. | ||
| 1303 | |||
| 1304 | * aha152x.c: Changes from Juergen - cleanups and updates. | ||
| 1305 | |||
| 1306 | * sd.c, sr.c: Use new check_media_change and revalidate | ||
| 1307 | file_operations fields. | ||
| 1308 | |||
| 1309 | * st.c, st.h: Add changes from Kai Makisara, dated Jun 22. | ||
| 1310 | |||
| 1311 | * hosts.h: Change SG_ALL back to 0xff. Apparently soft error | ||
| 1312 | in /dev/brain resulted in having this bumped up. | ||
| 1313 | Change first parameter in bios_param function to be Disk * instead | ||
| 1314 | of index into rscsi_disks. | ||
| 1315 | |||
| 1316 | * sd_ioctl.c: Pass pointer to rscsi_disks element instead of index | ||
| 1317 | to array. | ||
| 1318 | |||
| 1319 | * sd.h: Add struct name "scsi_disk" to typedef for Scsi_Disk. | ||
| 1320 | |||
| 1321 | * scsi.c: Remove redundant Maxtor XT8760S from blacklist. | ||
| 1322 | In scsi_reset, add printk when DEBUG defined. | ||
| 1323 | |||
| 1324 | * All low level drivers: Modify definitions of bios_param in | ||
| 1325 | appropriate way. | ||
| 1326 | |||
| 1327 | Thu Jun 16 10:31:59 1994 Eric Youngdale (eric@esp22) | ||
| 1328 | |||
| 1329 | * Linux 1.1.20 released. | ||
| 1330 | |||
| 1331 | * scsi_ioctl.c: Only pass down the actual number of characters | ||
| 1332 | required to scsi_do_cmd, not the one rounded up to a even number | ||
| 1333 | of sectors. | ||
| 1334 | |||
| 1335 | * ultrastor.c: Changes from Caleb Epstein for 24f cards. Support | ||
| 1336 | larger SG lists. | ||
| 1337 | |||
| 1338 | * ultrastor.c: Changes from me - use scsi_register to register | ||
| 1339 | host. Add some consistency checking, | ||
| 1340 | |||
| 1341 | Wed Jun 1 21:12:13 1994 Eric Youngdale (eric@esp22) | ||
| 1342 | |||
| 1343 | * Linux 1.1.19 released. | ||
| 1344 | |||
| 1345 | * scsi.h: Add new return code for reset() function: | ||
| 1346 | SCSI_RESET_PUNT. | ||
| 1347 | |||
| 1348 | * scsi.c: Make SCSI_RESET_PUNT the same as SCSI_RESET_WAKEUP for | ||
| 1349 | now. | ||
| 1350 | |||
| 1351 | * aha1542.c: If the command responsible for the reset is not | ||
| 1352 | pending, return SCSI_RESET_PUNT. | ||
| 1353 | |||
| 1354 | * aha1740.c, buslogic.c, wd7000.c, ultrastor.c: Return | ||
| 1355 | SCSI_RESET_PUNT instead of SCSI_RESET_SNOOZE. | ||
| 1356 | |||
| 1357 | Tue May 31 19:36:01 1994 Eric Youngdale (eric@esp22) | ||
| 1358 | |||
| 1359 | * buslogic.c: Do not print out message about "must be Adaptec" | ||
| 1360 | if we have detected a buslogic card. Print out a warning message | ||
| 1361 | if we are configuring for >16Mb, since the 445S at board level | ||
| 1362 | D or earlier does not work right. The "D" level board can be made | ||
| 1363 | to work by flipping an undocumented switch, but this is too subtle. | ||
| 1364 | |||
| 1365 | Changes based upon patches in Yggdrasil distribution. | ||
| 1366 | |||
| 1367 | * sg.c, sg.h: Return sense data to user. | ||
| 1368 | |||
| 1369 | * aha1542.c, aha1740.c, buslogic.c: Do not panic if | ||
| 1370 | sense buffer is wrong size. | ||
| 1371 | |||
| 1372 | * hosts.c: Test for ultrastor card before any of the others. | ||
| 1373 | |||
| 1374 | * scsi.c: Allow boot-time option for max_scsi_luns=? so that | ||
| 1375 | buggy firmware has an easy work-around. | ||
| 1376 | |||
| 1377 | Sun May 15 20:24:34 1994 Eric Youngdale (eric@esp22) | ||
| 1378 | |||
| 1379 | * Linux 1.1.15 released. | ||
| 1380 | |||
| 1381 | Post-codefreeze thaw... | ||
| 1382 | |||
| 1383 | * buslogic.[c,h]: New driver from David Gentzel. | ||
| 1384 | |||
| 1385 | * hosts.h: Add use_clustering field to explicitly say whether | ||
| 1386 | clustering should be used for devices attached to this host | ||
| 1387 | adapter. The buslogic board apparently supports large SG lists, | ||
| 1388 | but it is apparently faster if sd.c condenses this into a smaller | ||
| 1389 | list. | ||
| 1390 | |||
| 1391 | * sd.c: Use this field instead of heuristic. | ||
| 1392 | |||
| 1393 | * All host adapter include files: Add appropriate initializer for | ||
| 1394 | use_clustering field. | ||
| 1395 | |||
| 1396 | * scsi.h: Add #defines for return codes for the abort and reset | ||
| 1397 | functions. There are now a specific set of return codes to fully | ||
| 1398 | specify all of the possible things that the low-level adapter | ||
| 1399 | could do. | ||
| 1400 | |||
| 1401 | * scsi.c: Act based upon return codes from abort/reset functions. | ||
| 1402 | |||
| 1403 | * All host adapter abort/reset functions: Return new return code. | ||
| 1404 | |||
| 1405 | * Add code in scsi.c to help debug timeouts. Use #define | ||
| 1406 | DEBUG_TIMEOUT to enable this. | ||
| 1407 | |||
| 1408 | * scsi.c: If the host->irq field is set, use | ||
| 1409 | disable_irq/enable_irq before calling queuecommand if we | ||
| 1410 | are not already in an interrupt. Reduce races, and we | ||
| 1411 | can be sloppier about cli/sti in the interrupt routines now | ||
| 1412 | (reduce interrupt latency). | ||
| 1413 | |||
| 1414 | * constants.c: Fix some things to eliminate warnings. Add some | ||
| 1415 | sense descriptions that were omitted before. | ||
| 1416 | |||
| 1417 | * aha1542.c: Watch for SCRD from host adapter - if we see it, set | ||
| 1418 | a flag. Currently we only print out the number of pending | ||
| 1419 | commands that might need to be restarted. | ||
| 1420 | |||
| 1421 | * aha1542.c (aha1542_abort): Look for lost interrupts, OGMB still | ||
| 1422 | full, and attempt to recover. Otherwise give up. | ||
| 1423 | |||
| 1424 | * aha1542.c (aha1542_reset): Try BUS DEVICE RESET, and then pass | ||
| 1425 | DID_RESET back up to the upper level code for all commands running | ||
| 1426 | on this target (even on different LUNs). | ||
| 1427 | |||
| 1428 | Sat May 7 14:54:01 1994 | ||
| 1429 | |||
| 1430 | * Linux 1.1.12 released. | ||
| 1431 | |||
| 1432 | * st.c, st.h: New version from Kai. Supports boot time | ||
| 1433 | specification of number of buffers. | ||
| 1434 | |||
| 1435 | * wd7000.[c,h]: Updated driver from John Boyd. Now supports | ||
| 1436 | more than one wd7000 board in machine at one time, among other things. | ||
| 1437 | |||
| 1438 | Wed Apr 20 22:20:35 1994 | ||
| 1439 | |||
| 1440 | * Linux 1.1.8 released. | ||
| 1441 | |||
| 1442 | * sd.c: Add a few type casts where scsi_malloc is called. | ||
| 1443 | |||
| 1444 | Wed Apr 13 12:53:29 1994 | ||
| 1445 | |||
| 1446 | * Linux 1.1.4 released. | ||
| 1447 | |||
| 1448 | * scsi.c: Clean up a few printks (use %p to print pointers). | ||
| 1449 | |||
| 1450 | Wed Apr 13 11:33:02 1994 | ||
| 1451 | |||
| 1452 | * Linux 1.1.3 released. | ||
| 1453 | |||
| 1454 | * fdomain.c: Update to version 5.16 (Handle different FIFO sizes | ||
| 1455 | better). | ||
| 1456 | |||
| 1457 | Fri Apr 8 08:57:19 1994 | ||
| 1458 | |||
| 1459 | * Linux 1.1.2 released. | ||
| 1460 | |||
| 1461 | * Throughout: SCSI portion of cluster diffs added. | ||
| 1462 | |||
| 1463 | Tue Apr 5 07:41:50 1994 | ||
| 1464 | |||
| 1465 | * Linux 1.1 development tree initiated. | ||
| 1466 | |||
| 1467 | * The linux 1.0 development tree is now effectively frozen except | ||
| 1468 | for obvious bugfixes. | ||
| 1469 | |||
| 1470 | ****************************************************************** | ||
| 1471 | ****************************************************************** | ||
| 1472 | ****************************************************************** | ||
| 1473 | ****************************************************************** | ||
| 1474 | |||
| 1475 | Sun Apr 17 00:17:39 1994 | ||
| 1476 | |||
| 1477 | * Linux 1.0, patchlevel 9 released. | ||
| 1478 | |||
| 1479 | * fdomain.c: Update to version 5.16 (Handle different FIFO sizes | ||
| 1480 | better). | ||
| 1481 | |||
| 1482 | Thu Apr 7 08:36:20 1994 | ||
| 1483 | |||
| 1484 | * Linux 1.0, patchlevel8 released. | ||
| 1485 | |||
| 1486 | * fdomain.c: Update to version 5.15 from 5.9. Handles 3.4 bios. | ||
| 1487 | |||
| 1488 | Sun Apr 3 14:43:03 1994 | ||
| 1489 | |||
| 1490 | * Linux 1.0, patchlevel6 released. | ||
| 1491 | |||
| 1492 | * wd7000.c: Make stab at fixing race condition. | ||
| 1493 | |||
| 1494 | Sat Mar 26 14:14:50 1994 | ||
| 1495 | |||
| 1496 | * Linux 1.0, patchlevel5 released. | ||
| 1497 | |||
| 1498 | * aha152x.c, Makefile: Fix a few bugs (too much data message). | ||
| 1499 | Add a few more bios signatures. (Patches from Juergen). | ||
| 1500 | |||
| 1501 | * aha1542.c: Fix race condition in aha1542_out. | ||
| 1502 | |||
| 1503 | Mon Mar 21 16:36:20 1994 | ||
| 1504 | |||
| 1505 | * Linux 1.0, patchlevel3 released. | ||
| 1506 | |||
| 1507 | * sd.c, st.c, sr.c, sg.c: Return -ENXIO, not -ENODEV if we attempt | ||
| 1508 | to open a non-existent device. | ||
| 1509 | |||
| 1510 | * scsi.c: Add Chinon cdrom to blacklist. | ||
| 1511 | |||
| 1512 | * sr_ioctl.c: Check return status of verify_area. | ||
| 1513 | |||
| 1514 | Sat Mar 6 16:06:19 1994 | ||
| 1515 | |||
| 1516 | * Linux 1.0 released (technically a pre-release). | ||
| 1517 | |||
| 1518 | * scsi.c: Add IMS CDD521, Maxtor XT-8760S to blacklist. | ||
| 1519 | |||
| 1520 | Tue Feb 15 10:58:20 1994 | ||
| 1521 | |||
| 1522 | * pl15e released. | ||
| 1523 | |||
| 1524 | * aha1542.c: For 1542C, allow dynamic device scan with >1Gb turned | ||
| 1525 | off. | ||
| 1526 | |||
| 1527 | * constants.c: Fix typo in definition of CONSTANTS. | ||
| 1528 | |||
| 1529 | * pl15d released. | ||
| 1530 | |||
| 1531 | Fri Feb 11 10:10:16 1994 | ||
| 1532 | |||
| 1533 | * pl15c released. | ||
| 1534 | |||
| 1535 | * scsi.c: Add Maxtor XT-3280 and Rodime RO3000S to blacklist. | ||
| 1536 | |||
| 1537 | * scsi.c: Allow tagged queueing for scsi 3 devices as well. | ||
| 1538 | Some really old devices report a version number of 0. Disallow | ||
| 1539 | LUN != 0 for these. | ||
| 1540 | |||
| 1541 | Thu Feb 10 09:48:57 1994 | ||
| 1542 | |||
| 1543 | * pl15b released. | ||
| 1544 | |||
| 1545 | Sun Feb 6 12:19:46 1994 | ||
| 1546 | |||
| 1547 | * pl15a released. | ||
| 1548 | |||
| 1549 | Fri Feb 4 09:02:17 1994 | ||
| 1550 | |||
| 1551 | * scsi.c: Add Teac cdrom to blacklist. | ||
| 1552 | |||
| 1553 | Thu Feb 3 14:16:43 1994 | ||
| 1554 | |||
| 1555 | * pl15 released. | ||
| 1556 | |||
| 1557 | Tue Feb 1 15:47:43 1994 | ||
| 1558 | |||
| 1559 | * pl14w released. | ||
| 1560 | |||
| 1561 | * wd7000.c (wd_bases): Fix typo in last change. | ||
| 1562 | |||
| 1563 | Mon Jan 24 17:37:23 1994 | ||
| 1564 | |||
| 1565 | * pl14u released. | ||
| 1566 | |||
| 1567 | * aha1542.c: Support 1542CF/extended bios. Different from 1542C | ||
| 1568 | |||
| 1569 | * wd7000.c: Allow bios at 0xd8000 as well. | ||
| 1570 | |||
| 1571 | * ultrastor.c: Do not truncate cylinders to 1024. | ||
| 1572 | |||
| 1573 | * fdomain.c: Update to version 5.9 (add new bios signature). | ||
| 1574 | |||
| 1575 | * NCR5380.c: Update from Drew - should work a lot better now. | ||
| 1576 | |||
| 1577 | Sat Jan 8 15:13:10 1994 | ||
| 1578 | |||
| 1579 | * pl14o released. | ||
| 1580 | |||
| 1581 | * sr_ioctl.c: Zero reserved field before trying to set audio volume. | ||
| 1582 | |||
| 1583 | Wed Jan 5 13:21:10 1994 | ||
| 1584 | |||
| 1585 | * pl14m released. | ||
| 1586 | |||
| 1587 | * fdomain.c: Update to version 5.8. No functional difference??? | ||
| 1588 | |||
| 1589 | Tue Jan 4 14:26:13 1994 | ||
| 1590 | |||
| 1591 | * pl14l released. | ||
| 1592 | |||
| 1593 | * ultrastor.c: Remove outl, inl functions (now provided elsewhere). | ||
| 1594 | |||
| 1595 | Mon Jan 3 12:27:25 1994 | ||
| 1596 | |||
| 1597 | * pl14k released. | ||
| 1598 | |||
| 1599 | * aha152x.c: Remove insw and outsw functions. | ||
| 1600 | |||
| 1601 | * fdomain.c: Ditto. | ||
| 1602 | |||
| 1603 | Wed Dec 29 09:47:20 1993 | ||
| 1604 | |||
| 1605 | * pl14i released. | ||
| 1606 | |||
| 1607 | * scsi.c: Support RECOVERED_ERROR for tape drives. | ||
| 1608 | |||
| 1609 | * st.c: Update of tape driver from Kai. | ||
| 1610 | |||
| 1611 | Tue Dec 21 09:18:30 1993 | ||
| 1612 | |||
| 1613 | * pl14g released. | ||
| 1614 | |||
| 1615 | * aha1542.[c,h]: Support extended BIOS stuff. | ||
| 1616 | |||
| 1617 | * scsi.c: Clean up messages about disks, so they are displayed as | ||
| 1618 | sda, sdb, etc instead of sd0, sd1, etc. | ||
| 1619 | |||
| 1620 | * sr.c: Force reread of capacity if disk was changed. | ||
| 1621 | Clear buffer before asking for capacity/sectorsize (some drives | ||
| 1622 | do not report this properly). Set needs_sector_size flag if | ||
| 1623 | drive did not return sensible sector size. | ||
| 1624 | |||
| 1625 | Mon Dec 13 12:13:47 1993 | ||
| 1626 | |||
| 1627 | * aha152x.c: Update to version .101 from Juergen. | ||
| 1628 | |||
| 1629 | Mon Nov 29 03:03:00 1993 | ||
| 1630 | |||
| 1631 | * linux 0.99.14 released. | ||
| 1632 | |||
| 1633 | * All scsi stuff moved from kernel/blk_drv/scsi to drivers/scsi. | ||
| 1634 | |||
| 1635 | * Throughout: Grammatical corrections to various comments. | ||
| 1636 | |||
| 1637 | * Makefile: fix so that we do not need to compile things we are | ||
| 1638 | not going to use. | ||
| 1639 | |||
| 1640 | * NCR5380.c, NCR5380.h, g_NCR5380.c, g_NCR5380.h, pas16.c, | ||
| 1641 | pas16.h, t128.c, t128.h: New files from Drew. | ||
| 1642 | |||
| 1643 | * aha152x.c, aha152x.h: New files from Juergen Fischer. | ||
| 1644 | |||
| 1645 | * aha1542.c: Support for more than one 1542 in the machine | ||
| 1646 | at the same time. Make functions static that do not need | ||
| 1647 | visibility. | ||
| 1648 | |||
| 1649 | * aha1740.c: Set NEEDS_JUMPSTART flag in reset function, so we | ||
| 1650 | know to restart the command. Change prototype of aha1740_reset | ||
| 1651 | to take a command pointer. | ||
| 1652 | |||
| 1653 | * constants.c: Clean up a few things. | ||
| 1654 | |||
| 1655 | * fdomain.c: Update to version 5.6. Move snarf_region. Allow | ||
| 1656 | board to be set at different SCSI ids. Remove support for | ||
| 1657 | reselection (did not work well). Set JUMPSTART flag in reset | ||
| 1658 | code. | ||
| 1659 | |||
| 1660 | * hosts.c: Support new low-level adapters. Allow for more than | ||
| 1661 | one adapter of a given type. | ||
| 1662 | |||
| 1663 | * hosts.h: Allow for more than one adapter of a given type. | ||
| 1664 | |||
| 1665 | * scsi.c: Add scsi_device_types array, if NEEDS_JUMPSTART is set | ||
| 1666 | after a low-level reset, start the command again. Sort blacklist, | ||
| 1667 | and add Maxtor MXT-1240S, XT-4170S, NEC CDROM 84, Seagate ST157N. | ||
| 1668 | |||
| 1669 | * scsi.h: Add constants for tagged queueing. | ||
| 1670 | |||
| 1671 | * Throughout: Use constants from major.h instead of hardcoded | ||
| 1672 | numbers for major numbers. | ||
| 1673 | |||
| 1674 | * scsi_ioctl.c: Fix bug in buffer length in ioctl_command. Use | ||
| 1675 | verify_area in GET_IDLUN ioctl. Add new ioctls for | ||
| 1676 | TAGGED_QUEUE_ENABLE, DISABLE. Only allow IOCTL_SEND_COMMAND by | ||
| 1677 | superuser. | ||
| 1678 | |||
| 1679 | * sd.c: Only pay attention to UNIT_ATTENTION for removable disks. | ||
| 1680 | Fix bug where sometimes portions of blocks would get lost | ||
| 1681 | resulting in processes hanging. Add messages when we spin up a | ||
| 1682 | disk, and fix a bug in the timing. Increase read-ahead for disks | ||
| 1683 | that are on a scatter-gather capable host adapter. | ||
| 1684 | |||
| 1685 | * seagate.c: Fix so that some parameters can be set from the lilo | ||
| 1686 | prompt. Supply jumpstart flag if we are resetting and need the | ||
| 1687 | command restarted. Fix so that we return 1 if we detect a card | ||
| 1688 | so that multiple card detection works correctly. Add yet another | ||
| 1689 | signature for FD cards (950). Add another signature for ST0x. | ||
| 1690 | |||
| 1691 | * sg.c, sg.h: New files from Lawrence Foard for generic scsi | ||
| 1692 | access. | ||
| 1693 | |||
| 1694 | * sr.c: Add type casts for (void*) so that we can do pointer | ||
| 1695 | arithmetic. Works with GCC without this, but it is not strictly | ||
| 1696 | correct. Same bugfix as was in sd.c. Increase read-ahead a la | ||
| 1697 | disk driver. | ||
| 1698 | |||
| 1699 | * sr_ioctl.c: Use scsi_malloc buffer instead of buffer from stack | ||
| 1700 | since we cannot guarantee that the stack is < 16Mb. | ||
| 1701 | |||
| 1702 | ultrastor.c: Update to support 24f properly (JFC's driver). | ||
| 1703 | |||
| 1704 | wd7000.c: Supply jumpstart flag for reset. Do not round up | ||
| 1705 | number of cylinders in biosparam function. | ||
| 1706 | |||
| 1707 | Sat Sep 4 20:49:56 1993 | ||
| 1708 | |||
| 1709 | * 0.99pl13 released. | ||
| 1710 | |||
| 1711 | * Throughout: Use check_region/snarf_region for all low-level | ||
| 1712 | drivers. | ||
| 1713 | |||
| 1714 | * aha1542.c: Do hard reset instead of soft (some ethercard probes | ||
| 1715 | screw us up). | ||
| 1716 | |||
| 1717 | * scsi.c: Add new flag ASKED_FOR_SENSE so that we can tell if we are | ||
| 1718 | in a loop whereby the device returns null sense data. | ||
| 1719 | |||
| 1720 | * sd.c: Add code to spin up a drive if it is not already spinning. | ||
| 1721 | Do this one at a time to make it easier on power supplies. | ||
| 1722 | |||
| 1723 | * sd_ioctl.c: Use sync_dev instead of fsync_dev in BLKFLSBUF ioctl. | ||
| 1724 | |||
| 1725 | * seagate.c: Switch around DATA/CONTROL lines. | ||
| 1726 | |||
| 1727 | * st.c: Change sense to unsigned. | ||
| 1728 | |||
| 1729 | Thu Aug 5 11:59:18 1993 | ||
| 1730 | |||
| 1731 | * 0.99pl12 released. | ||
| 1732 | |||
| 1733 | * constants.c, constants.h: New files with ascii descriptions of | ||
| 1734 | various conditions. | ||
| 1735 | |||
| 1736 | * Makefile: Do not try to count the number of low-level drivers, | ||
| 1737 | just generate the list of .o files. | ||
| 1738 | |||
| 1739 | * aha1542.c: Replace 16 with sizeof(SCpnt->sense_buffer). Add tests | ||
| 1740 | for addresses > 16Mb, panic if we find one. | ||
| 1741 | |||
| 1742 | * aha1740.c: Ditto with sizeof(). | ||
| 1743 | |||
| 1744 | * fdomain.c: Update to version 3.18. Add new signature, register IRQ | ||
| 1745 | with irqaction. Use ID 7 for new board. Be more intelligent about | ||
| 1746 | obtaining the h/s/c numbers for biosparam. | ||
| 1747 | |||
| 1748 | * hosts.c: Do not depend upon Makefile generated count of the number | ||
| 1749 | of low-level host adapters. | ||
| 1750 | |||
| 1751 | * scsi.c: Use array for scsi_command_size instead of a function. Add | ||
| 1752 | Texel cdrom and Maxtor XT-4380S to blacklist. Allow compile time | ||
| 1753 | option for no-multi lun scan. Add semaphore for possible problems | ||
| 1754 | with handshaking, assume device is faulty until we know it not to be | ||
| 1755 | the case. Add DEBUG_INIT symbol to dump info as we scan for devices. | ||
| 1756 | Zero sense buffer so we can tell if we need to request it. When | ||
| 1757 | examining sense information, request sense if buffer is all zero. | ||
| 1758 | If RESET, request sense information to see what to do next. | ||
| 1759 | |||
| 1760 | * scsi_debug.c: Change some constants to use symbols like INT_MAX. | ||
| 1761 | |||
| 1762 | * scsi_ioctl.c (kernel_scsi_ioctl): New function -for making ioctl | ||
| 1763 | calls from kernel space. | ||
| 1764 | |||
| 1765 | * sd.c: Increase timeout to 300. Use functions in constants.h to | ||
| 1766 | display info. Use scsi_malloc buffer for READ_CAPACITY, since | ||
| 1767 | we cannot guarantee that a stack based buffer is < 16Mb. | ||
| 1768 | |||
| 1769 | * sd_ioctl.c: Add BLKFLSBUF ioctl. | ||
| 1770 | |||
| 1771 | * seagate.c: Add new compile time options for ARBITRATE, | ||
| 1772 | SLOW_HANDSHAKE, and SLOW_RATE. Update assembly loops for transferring | ||
| 1773 | data. Use kernel_scsi_ioctl to request mode page with geometry. | ||
| 1774 | |||
| 1775 | * sr.c: Use functions in constants.c to display messages. | ||
| 1776 | |||
| 1777 | * st.c: Support for variable block size. | ||
| 1778 | |||
| 1779 | * ultrastor.c: Do not use cache for tape drives. Set | ||
| 1780 | unchecked_isa_dma flag, even though this may not be needed (gets set | ||
| 1781 | later). | ||
| 1782 | |||
| 1783 | Sat Jul 17 18:32:44 1993 | ||
| 1784 | |||
| 1785 | * 0.99pl11 released. C++ compilable. | ||
| 1786 | |||
| 1787 | * Throughout: Add type casts all over the place, and use "ip" instead | ||
| 1788 | of "info" in the various biosparam functions. | ||
| 1789 | |||
| 1790 | * Makefile: Compile seagate.c with C++ compiler. | ||
| 1791 | |||
| 1792 | * aha1542.c: Always set ccb pointer as this gets trashed somehow on | ||
| 1793 | some systems. Add a few type casts. Update biosparam function a little. | ||
| 1794 | |||
| 1795 | * aha1740.c: Add a few type casts. | ||
| 1796 | |||
| 1797 | * fdomain.c: Update to version 3.17 from 3.6. Now works with | ||
| 1798 | TMC-18C50. | ||
| 1799 | |||
| 1800 | * scsi.c: Minor changes here and there with datatypes. Save use_sg | ||
| 1801 | when requesting sense information so that this can properly be | ||
| 1802 | restored if we retry the command. Set aside dma buffers assuming each | ||
| 1803 | block is 1 page, not 1Kb minix block. | ||
| 1804 | |||
| 1805 | * scsi_ioctl.c: Add a few type casts. Other minor changes. | ||
| 1806 | |||
| 1807 | * sd.c: Correctly free all scsi_malloc'd memory if we run out of | ||
| 1808 | dma_pool. Store blocksize information for each partition. | ||
| 1809 | |||
| 1810 | * seagate.c: Minor cleanups here and there. | ||
| 1811 | |||
| 1812 | * sr.c: Set up blocksize array for all discs. Fix bug in freeing | ||
| 1813 | buffers if we run out of dma pool. | ||
| 1814 | |||
| 1815 | Thu Jun 2 17:58:11 1993 | ||
| 1816 | |||
| 1817 | * 0.99pl10 released. | ||
| 1818 | |||
| 1819 | * aha1542.c: Support for BT 445S (VL-bus board with no dma channel). | ||
| 1820 | |||
| 1821 | * fdomain.c: Upgrade to version 3.6. Preliminary support for TNC-18C50. | ||
| 1822 | |||
| 1823 | * scsi.c: First attempt to fix problem with old_use_sg. Change | ||
| 1824 | NOT_READY to a SUGGEST_ABORT. Fix timeout race where time might | ||
| 1825 | get decremented past zero. | ||
| 1826 | |||
| 1827 | * sd.c: Add block_fsync function to dispatch table. | ||
| 1828 | |||
| 1829 | * sr.c: Increase timeout to 500 from 250. Add entry for sync in | ||
| 1830 | dispatch table (supply NULL). If we do not have a sectorsize, | ||
| 1831 | try to get it in the sd_open function. Add new function just to | ||
| 1832 | obtain sectorsize. | ||
| 1833 | |||
| 1834 | * sr.h: Add needs_sector_size semaphore. | ||
| 1835 | |||
| 1836 | * st.c: Add NULL for fsync in dispatch table. | ||
| 1837 | |||
| 1838 | * wd7000.c: Allow another condition for power on that are normal | ||
| 1839 | and do not require a panic. | ||
| 1840 | |||
| 1841 | Thu Apr 22 23:10:11 1993 | ||
| 1842 | |||
| 1843 | * 0.99pl9 released. | ||
| 1844 | |||
| 1845 | * aha1542.c: Use (void) instead of () in setup_mailboxes. | ||
| 1846 | |||
| 1847 | * scsi.c: Initialize transfersize and underflow fields in SCmd to 0. | ||
| 1848 | Do not panic for unsupported message bytes. | ||
| 1849 | |||
| 1850 | * scsi.h: Allocate 12 bytes instead of 10 for commands. Add | ||
| 1851 | transfersize and underflow fields. | ||
| 1852 | |||
| 1853 | * scsi_ioctl.c: Further bugfix to ioctl_probe. | ||
| 1854 | |||
| 1855 | * sd.c: Use long instead of int for last parameter in sd_ioctl. | ||
| 1856 | Initialize transfersize and underflow fields. | ||
| 1857 | |||
| 1858 | * sd_ioctl.c: Ditto for sd_ioctl(,,,,); | ||
| 1859 | |||
| 1860 | * seagate.c: New version from Drew. Includes new signatures for FD | ||
| 1861 | cards. Support for 0ws jumper. Correctly initialize | ||
| 1862 | scsi_hosts[hostnum].this_id. Improved handing of | ||
| 1863 | disconnect/reconnect, and support command linking. Use | ||
| 1864 | transfersize and underflow fields. Support scatter-gather. | ||
| 1865 | |||
| 1866 | * sr.c, sr_ioctl.c: Use long instead of int for last parameter in sr_ioctl. | ||
| 1867 | Use buffer and buflength in do_ioctl. Patches from Chris Newbold for | ||
| 1868 | scsi-2 audio commands. | ||
| 1869 | |||
| 1870 | * ultrastor.c: Comment out in_byte (compiler warning). | ||
| 1871 | |||
| 1872 | * wd7000.c: Change () to (void) in wd7000_enable_dma. | ||
| 1873 | |||
| 1874 | Wed Mar 31 16:36:25 1993 | ||
| 1875 | |||
| 1876 | * 0.99pl8 released. | ||
| 1877 | |||
| 1878 | * aha1542.c: Handle mailboxes better for 1542C. | ||
| 1879 | Do not truncate number of cylinders at 1024 for biosparam call. | ||
| 1880 | |||
| 1881 | * aha1740.c: Fix a few minor bugs for multiple devices. | ||
| 1882 | Same as above for biosparam. | ||
| 1883 | |||
| 1884 | * scsi.c: Add lockable semaphore for removable devices that can have | ||
| 1885 | media removal prevented. Add another signature for flopticals. | ||
| 1886 | (allocate_device): Fix race condition. Allow more space in dma pool | ||
| 1887 | for blocksizes of up to 4Kb. | ||
| 1888 | |||
| 1889 | * scsi.h: Define COMMAND_SIZE. Define a SCSI specific version of | ||
| 1890 | INIT_REQUEST that can run with interrupts off. | ||
| 1891 | |||
| 1892 | * scsi_ioctl.c: Make ioctl_probe function more idiot-proof. If | ||
| 1893 | a removable device says ILLEGAL REQUEST to a door-locking command, | ||
| 1894 | clear lockable flag. Add SCSI_IOCTL_GET_IDLUN ioctl. Do not attempt | ||
| 1895 | to lock door for devices that do not have lockable semaphore set. | ||
| 1896 | |||
| 1897 | * sd.c: Fix race condition for multiple disks. Use INIT_SCSI_REQUEST | ||
| 1898 | instead of INIT_REQUEST. Allow sector sizes of 1024 and 256. For | ||
| 1899 | removable disks that are not ready, mark them as having a media change | ||
| 1900 | (some drives do not report this later). | ||
| 1901 | |||
| 1902 | * seagate.c: Use volatile keyword for memory-mapped register pointers. | ||
| 1903 | |||
| 1904 | * sr.c: Fix race condition, a la sd.c. Increase the number of retries | ||
| 1905 | to 1. Use INIT_SCSI_REQUEST. Allow 512 byte sector sizes. Do a | ||
| 1906 | read_capacity when we init the device so we know the size and | ||
| 1907 | sectorsize. | ||
| 1908 | |||
| 1909 | * st.c: If ioctl not found in st.c, try scsi_ioctl for others. | ||
| 1910 | |||
| 1911 | * ultrastor.c: Do not truncate number of cylinders at 1024 for | ||
| 1912 | biosparam call. | ||
| 1913 | |||
| 1914 | * wd7000.c: Ditto. | ||
| 1915 | Throughout: Use COMMAND_SIZE macro to determine length of scsi | ||
| 1916 | command. | ||
| 1917 | |||
| 1918 | |||
| 1919 | |||
| 1920 | Sat Mar 13 17:31:29 1993 | ||
| 1921 | |||
| 1922 | * 0.99pl7 released. | ||
| 1923 | |||
| 1924 | Throughout: Improve punctuation in some messages, and use new | ||
| 1925 | verify_area syntax. | ||
| 1926 | |||
| 1927 | * aha1542.c: Handle unexpected interrupts better. | ||
| 1928 | |||
| 1929 | * scsi.c: Ditto. Handle reset conditions a bit better, asking for | ||
| 1930 | sense information and retrying if required. | ||
| 1931 | |||
| 1932 | * scsi_ioctl.c: Allow for 12 byte scsi commands. | ||
| 1933 | |||
| 1934 | * ultrastor.c: Update to use scatter-gather. | ||
| 1935 | |||
| 1936 | Sat Feb 20 17:57:15 1993 | ||
| 1937 | |||
| 1938 | * 0.99pl6 released. | ||
| 1939 | |||
| 1940 | * fdomain.c: Update to version 3.5. Handle spurious interrupts | ||
| 1941 | better. | ||
| 1942 | |||
| 1943 | * sd.c: Use register_blkdev function. | ||
| 1944 | |||
| 1945 | * sr.c: Ditto. | ||
| 1946 | |||
| 1947 | * st.c: Use register_chrdev function. | ||
| 1948 | |||
| 1949 | * wd7000.c: Undo previous change. | ||
| 1950 | |||
| 1951 | Sat Feb 6 11:20:43 1993 | ||
| 1952 | |||
| 1953 | * 0.99pl5 released. | ||
| 1954 | |||
| 1955 | * scsi.c: Fix bug in testing for UNIT_ATTENTION. | ||
| 1956 | |||
| 1957 | * wd7000.c: Check at more addresses for bios. Fix bug in biosparam | ||
| 1958 | (heads & sectors turned around). | ||
| 1959 | |||
| 1960 | Wed Jan 20 18:13:59 1993 | ||
| 1961 | |||
| 1962 | * 0.99pl4 released. | ||
| 1963 | |||
| 1964 | * scsi.c: Ignore leading spaces when looking for blacklisted devices. | ||
| 1965 | |||
| 1966 | * seagate.c: Add a few new signatures for FD cards. Another patch | ||
| 1967 | with SCint to fix race condition. Use recursion_depth to keep track | ||
| 1968 | of how many times we have been recursively called, and do not start | ||
| 1969 | another command unless we are on the outer level. Fixes bug | ||
| 1970 | with Syquest cartridge drives (used to crash kernel), because | ||
| 1971 | they do not disconnect with large data transfers. | ||
| 1972 | |||
| 1973 | Tue Jan 12 14:33:36 1993 | ||
| 1974 | |||
| 1975 | * 0.99pl3 released. | ||
| 1976 | |||
| 1977 | * fdomain.c: Update to version 3.3 (a few new signatures). | ||
| 1978 | |||
| 1979 | * scsi.c: Add CDU-541, Denon DRD-25X to blacklist. | ||
| 1980 | (allocate_request, request_queueable): Init request.waiting to NULL if | ||
| 1981 | non-buffer type of request. | ||
| 1982 | |||
| 1983 | * seagate.c: Allow controller to be overridden with CONTROLLER symbol. | ||
| 1984 | Set SCint=NULL when we are done, to remove race condition. | ||
| 1985 | |||
| 1986 | * st.c: Changes from Kai. | ||
| 1987 | |||
| 1988 | Wed Dec 30 20:03:47 1992 | ||
| 1989 | |||
| 1990 | * 0.99pl2 released. | ||
| 1991 | |||
| 1992 | * scsi.c: Blacklist back in. Remove Newbury drive as other bugfix | ||
| 1993 | eliminates need for it here. | ||
| 1994 | |||
| 1995 | * sd.c: Return ENODEV instead of EACCES if no such device available. | ||
| 1996 | (sd_init) Init blkdev_fops earlier so that sd_open is available sooner. | ||
| 1997 | |||
| 1998 | * sr.c: Same as above for sd.c. | ||
| 1999 | |||
| 2000 | * st.c: Return ENODEV instead of ENXIO if no device. Init chrdev_fops | ||
| 2001 | sooner, so that it is always there even if no tapes. | ||
| 2002 | |||
| 2003 | * seagate.c (controller_type): New variable to keep track of ST0x or | ||
| 2004 | FD. Modify signatures list to indicate controller type, and init | ||
| 2005 | controller_type once we find a match. | ||
| 2006 | |||
| 2007 | * wd7000.c (wd7000_set_sync): Remove redundant function. | ||
| 2008 | |||
| 2009 | Sun Dec 20 16:26:24 1992 | ||
| 2010 | |||
| 2011 | * 0.99pl1 released. | ||
| 2012 | |||
| 2013 | * scsi_ioctl.c: Bugfix - check dev->index, not dev->id against | ||
| 2014 | NR_SCSI_DEVICES. | ||
| 2015 | |||
| 2016 | * sr_ioctl.c: Verify that device exists before allowing an ioctl. | ||
| 2017 | |||
| 2018 | * st.c: Patches from Kai - change timeout values, improve end of tape | ||
| 2019 | handling. | ||
| 2020 | |||
| 2021 | Sun Dec 13 18:15:23 1992 | ||
| 2022 | |||
| 2023 | * 0.99 kernel released. Baseline for this ChangeLog. | ||
diff --git a/Documentation/scsi/Mylex.txt b/Documentation/scsi/Mylex.txt deleted file mode 100644 index 3797f3e6c2b5..000000000000 --- a/Documentation/scsi/Mylex.txt +++ /dev/null | |||
| @@ -1,5 +0,0 @@ | |||
| 1 | Please see the file README.BusLogic for information about Linux support for | ||
| 2 | Mylex (formerly BusLogic) MultiMaster and FlashPoint SCSI Host Adapters. | ||
| 3 | |||
| 4 | The Mylex DAC960 PCI RAID Controllers are now supported. Please consult | ||
| 5 | http://sourceforge.net/projects/dandelion for further information on the DAC960 driver. | ||
diff --git a/Documentation/scsi/scsi-parameters.txt b/Documentation/scsi/scsi-parameters.txt index 453d4b79c78d..25a4b4cf04a6 100644 --- a/Documentation/scsi/scsi-parameters.txt +++ b/Documentation/scsi/scsi-parameters.txt | |||
| @@ -34,11 +34,6 @@ parameters may be changed at runtime by the command | |||
| 34 | See drivers/scsi/BusLogic.c, comment before function | 34 | See drivers/scsi/BusLogic.c, comment before function |
| 35 | BusLogic_ParseDriverOptions(). | 35 | BusLogic_ParseDriverOptions(). |
| 36 | 36 | ||
| 37 | eata= [HW,SCSI] | ||
| 38 | |||
| 39 | fdomain= [HW,SCSI] | ||
| 40 | See header of drivers/scsi/fdomain.c. | ||
| 41 | |||
| 42 | gdth= [HW,SCSI] | 37 | gdth= [HW,SCSI] |
| 43 | See header of drivers/scsi/gdth.c. | 38 | See header of drivers/scsi/gdth.c. |
| 44 | 39 | ||
| @@ -70,8 +65,6 @@ parameters may be changed at runtime by the command | |||
| 70 | ncr53c400a= [HW,SCSI] | 65 | ncr53c400a= [HW,SCSI] |
| 71 | See Documentation/scsi/g_NCR5380.txt. | 66 | See Documentation/scsi/g_NCR5380.txt. |
| 72 | 67 | ||
| 73 | ncr53c406a= [HW,SCSI] | ||
| 74 | |||
| 75 | ncr53c8xx= [HW,SCSI] | 68 | ncr53c8xx= [HW,SCSI] |
| 76 | 69 | ||
| 77 | osst= [HW,SCSI] SCSI Tape Driver | 70 | osst= [HW,SCSI] SCSI Tape Driver |
| @@ -110,12 +103,5 @@ parameters may be changed at runtime by the command | |||
| 110 | st= [HW,SCSI] SCSI tape parameters (buffers, etc.) | 103 | st= [HW,SCSI] SCSI tape parameters (buffers, etc.) |
| 111 | See Documentation/scsi/st.txt. | 104 | See Documentation/scsi/st.txt. |
| 112 | 105 | ||
| 113 | sym53c416= [HW,SCSI] | ||
| 114 | See header of drivers/scsi/sym53c416.c. | ||
| 115 | |||
| 116 | tmscsim= [HW,SCSI] | ||
| 117 | See comment before function dc390_setup() in | ||
| 118 | drivers/scsi/tmscsim.c. | ||
| 119 | |||
| 120 | wd33c93= [HW,SCSI] | 106 | wd33c93= [HW,SCSI] |
| 121 | See header of drivers/scsi/wd33c93.c. | 107 | See header of drivers/scsi/wd33c93.c. |
diff --git a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt index 2c31d9ee6776..177c031763c0 100644 --- a/Documentation/scsi/scsi_mid_low_api.txt +++ b/Documentation/scsi/scsi_mid_low_api.txt | |||
| @@ -114,9 +114,7 @@ called "xxx" could be defined as | |||
| 114 | "static int xxx_slave_alloc(struct scsi_device * sdev) { /* code */ }" | 114 | "static int xxx_slave_alloc(struct scsi_device * sdev) { /* code */ }" |
| 115 | 115 | ||
| 116 | ** the scsi_host_alloc() function is a replacement for the rather vaguely | 116 | ** the scsi_host_alloc() function is a replacement for the rather vaguely |
| 117 | named scsi_register() function in most situations. The scsi_register() | 117 | named scsi_register() function in most situations. |
| 118 | and scsi_unregister() functions remain to support legacy LLDs that use | ||
| 119 | the passive initialization model. | ||
| 120 | 118 | ||
| 121 | 119 | ||
| 122 | Hotplug initialization model | 120 | Hotplug initialization model |
| @@ -228,79 +226,6 @@ slave_configure() callbacks). Such instances are "owned" by the mid-level. | |||
| 228 | struct scsi_device instances are freed after slave_destroy(). | 226 | struct scsi_device instances are freed after slave_destroy(). |
| 229 | 227 | ||
| 230 | 228 | ||
| 231 | Passive initialization model | ||
| 232 | ============================ | ||
| 233 | These older LLDs include a file called "scsi_module.c" [yes the ".c" is a | ||
| 234 | little surprising] in their source code. For that file to work an | ||
| 235 | instance of struct scsi_host_template with the name "driver_template" | ||
| 236 | needs to be defined. Here is a typical code sequence used in this model: | ||
| 237 | static struct scsi_host_template driver_template = { | ||
| 238 | ... | ||
| 239 | }; | ||
| 240 | #include "scsi_module.c" | ||
| 241 | |||
| 242 | The scsi_module.c file contains two functions: | ||
| 243 | - init_this_scsi_driver() which is executed when the LLD is | ||
| 244 | initialized (i.e. boot time or module load time) | ||
| 245 | - exit_this_scsi_driver() which is executed when the LLD is shut | ||
| 246 | down (i.e. module unload time) | ||
| 247 | Note: since these functions are tagged with __init and __exit qualifiers | ||
| 248 | an LLD should not call them explicitly (since the kernel does that). | ||
| 249 | |||
| 250 | Here is an example of an initialization sequence when two hosts are | ||
| 251 | detected (so detect() returns 2) and the SCSI bus scan on each host | ||
| 252 | finds 1 SCSI device (and a second device does not respond). | ||
| 253 | |||
| 254 | LLD mid level LLD | ||
| 255 | ===----------------------=========-----------------===------ | ||
| 256 | init_this_scsi_driver() ----+ | ||
| 257 | | | ||
| 258 | detect() -----------------+ | ||
| 259 | | | | ||
| 260 | | scsi_register() | ||
| 261 | | scsi_register() | ||
| 262 | | | ||
| 263 | slave_alloc() | ||
| 264 | slave_configure() --> scsi_change_queue_depth() | ||
| 265 | slave_alloc() *** | ||
| 266 | slave_destroy() *** | ||
| 267 | | | ||
| 268 | slave_alloc() | ||
| 269 | slave_configure() | ||
| 270 | slave_alloc() *** | ||
| 271 | slave_destroy() *** | ||
| 272 | ------------------------------------------------------------ | ||
| 273 | |||
| 274 | The mid level invokes scsi_change_queue_depth() with "cmd_per_lun" for that | ||
| 275 | host as the queue length. These settings can be overridden by a | ||
| 276 | slave_configure() supplied by the LLD. | ||
| 277 | |||
| 278 | *** For scsi devices that the mid level tries to scan but do not | ||
| 279 | respond, a slave_alloc(), slave_destroy() pair is called. | ||
| 280 | |||
| 281 | Here is an LLD shutdown sequence: | ||
| 282 | |||
| 283 | LLD mid level LLD | ||
| 284 | ===----------------------=========-----------------===------ | ||
| 285 | exit_this_scsi_driver() ----+ | ||
| 286 | | | ||
| 287 | slave_destroy() | ||
| 288 | release() --> scsi_unregister() | ||
| 289 | | | ||
| 290 | slave_destroy() | ||
| 291 | release() --> scsi_unregister() | ||
| 292 | ------------------------------------------------------------ | ||
| 293 | |||
| 294 | An LLD need not define slave_destroy() (i.e. it is optional). | ||
| 295 | |||
| 296 | The shortcoming of the "passive initialization model" is that host | ||
| 297 | registration and de-registration are (typically) tied to LLD initialization | ||
| 298 | and shutdown. Once the LLD is initialized then a new host that appears | ||
| 299 | (e.g. via hotplugging) cannot easily be added without a redundant | ||
| 300 | driver shutdown and re-initialization. It may be possible to write an LLD | ||
| 301 | that uses both initialization models. | ||
| 302 | |||
| 303 | |||
| 304 | Reference Counting | 229 | Reference Counting |
| 305 | ================== | 230 | ================== |
| 306 | The Scsi_Host structure has had reference counting infrastructure added. | 231 | The Scsi_Host structure has had reference counting infrastructure added. |
| @@ -738,7 +663,6 @@ The interface functions are listed below in alphabetical order. | |||
| 738 | 663 | ||
| 739 | Summary: | 664 | Summary: |
| 740 | bios_param - fetch head, sector, cylinder info for a disk | 665 | bios_param - fetch head, sector, cylinder info for a disk |
| 741 | detect - detects HBAs this driver wants to control | ||
| 742 | eh_timed_out - notify the host that a command timer expired | 666 | eh_timed_out - notify the host that a command timer expired |
| 743 | eh_abort_handler - abort given command | 667 | eh_abort_handler - abort given command |
| 744 | eh_bus_reset_handler - issue SCSI bus reset | 668 | eh_bus_reset_handler - issue SCSI bus reset |
| @@ -748,7 +672,6 @@ Summary: | |||
| 748 | ioctl - driver can respond to ioctls | 672 | ioctl - driver can respond to ioctls |
| 749 | proc_info - supports /proc/scsi/{driver_name}/{host_no} | 673 | proc_info - supports /proc/scsi/{driver_name}/{host_no} |
| 750 | queuecommand - queue scsi command, invoke 'done' on completion | 674 | queuecommand - queue scsi command, invoke 'done' on completion |
| 751 | release - release all resources associated with given host | ||
| 752 | slave_alloc - prior to any commands being sent to a new device | 675 | slave_alloc - prior to any commands being sent to a new device |
| 753 | slave_configure - driver fine tuning for given device after attach | 676 | slave_configure - driver fine tuning for given device after attach |
| 754 | slave_destroy - given device is about to be shut down | 677 | slave_destroy - given device is about to be shut down |
| @@ -785,28 +708,6 @@ Details: | |||
| 785 | 708 | ||
| 786 | 709 | ||
| 787 | /** | 710 | /** |
| 788 | * detect - detects HBAs this driver wants to control | ||
| 789 | * @shtp: host template for this driver. | ||
| 790 | * | ||
| 791 | * Returns number of hosts this driver wants to control. 0 means no | ||
| 792 | * suitable hosts found. | ||
| 793 | * | ||
| 794 | * Locks: none held | ||
| 795 | * | ||
| 796 | * Calling context: process [invoked from init_this_scsi_driver()] | ||
| 797 | * | ||
| 798 | * Notes: First function called from the SCSI mid level on this | ||
| 799 | * driver. Upper level drivers (e.g. sd) may not (yet) be present. | ||
| 800 | * For each host found, this method should call scsi_register() | ||
| 801 | * [see hosts.c]. | ||
| 802 | * | ||
| 803 | * Defined in: LLD (required if "passive initialization mode" is used, | ||
| 804 | * not invoked in "hotplug initialization mode") | ||
| 805 | **/ | ||
| 806 | int detect(struct scsi_host_template * shtp) | ||
| 807 | |||
| 808 | |||
| 809 | /** | ||
| 810 | * eh_timed_out - The timer for the command has just fired | 711 | * eh_timed_out - The timer for the command has just fired |
| 811 | * @scp: identifies command timing out | 712 | * @scp: identifies command timing out |
| 812 | * | 713 | * |
| @@ -1074,27 +975,6 @@ Details: | |||
| 1074 | 975 | ||
| 1075 | 976 | ||
| 1076 | /** | 977 | /** |
| 1077 | * release - release all resources associated with given host | ||
| 1078 | * @shp: host to be released. | ||
| 1079 | * | ||
| 1080 | * Return value ignored (could soon be a function returning void). | ||
| 1081 | * | ||
| 1082 | * Locks: none held | ||
| 1083 | * | ||
| 1084 | * Calling context: process | ||
| 1085 | * | ||
| 1086 | * Notes: Invoked from scsi_module.c's exit_this_scsi_driver(). | ||
| 1087 | * LLD's implementation of this function should call | ||
| 1088 | * scsi_unregister(shp) prior to returning. | ||
| 1089 | * Only needed for old-style host templates. | ||
| 1090 | * | ||
| 1091 | * Defined in: LLD (required in "passive initialization model", | ||
| 1092 | * should not be defined in hotplug model) | ||
| 1093 | **/ | ||
| 1094 | int release(struct Scsi_Host * shp) | ||
| 1095 | |||
| 1096 | |||
| 1097 | /** | ||
| 1098 | * slave_alloc - prior to any commands being sent to a new device | 978 | * slave_alloc - prior to any commands being sent to a new device |
| 1099 | * (i.e. just prior to scan) this call is made | 979 | * (i.e. just prior to scan) this call is made |
| 1100 | * @sdp: pointer to new device (about to be scanned) | 980 | * @sdp: pointer to new device (about to be scanned) |
diff --git a/Documentation/scsi/sd-parameters.txt b/Documentation/scsi/sd-parameters.txt new file mode 100644 index 000000000000..8e5af00d88e7 --- /dev/null +++ b/Documentation/scsi/sd-parameters.txt | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | Linux SCSI Disk Driver (sd) Parameters | ||
| 2 | ====================================== | ||
| 3 | |||
| 4 | cache_type (RW) | ||
| 5 | --------------- | ||
| 6 | Enable/disable drive write & read cache. | ||
| 7 | |||
| 8 | cache_type string | WCE RCD | Write cache | Read cache | ||
| 9 | ----------------------------+---------+-------------+------------ | ||
| 10 | write through | 0 0 | off | on | ||
| 11 | none | 0 1 | off | off | ||
| 12 | write back | 1 0 | on | on | ||
| 13 | write back, no read (daft) | 1 1 | on | off | ||
| 14 | |||
| 15 | To set cache type to "write back" and save this setting to the drive: | ||
| 16 | |||
| 17 | # echo "write back" > cache_type | ||
| 18 | |||
| 19 | To modify the caching mode without making the change persistent, prepend | ||
| 20 | "temporary " to the cache type string. E.g.: | ||
| 21 | |||
| 22 | # echo "temporary write back" > cache_type | ||
diff --git a/Documentation/scsi/tmscsim.txt b/Documentation/scsi/tmscsim.txt deleted file mode 100644 index 0e0322bf0020..000000000000 --- a/Documentation/scsi/tmscsim.txt +++ /dev/null | |||
| @@ -1,443 +0,0 @@ | |||
| 1 | The tmscsim driver | ||
| 2 | ================== | ||
| 3 | |||
| 4 | 1. Purpose and history | ||
| 5 | 2. Installation | ||
| 6 | 3. Features | ||
| 7 | 4. Configuration via /proc/scsi/tmscsim/? | ||
| 8 | 5. Configuration via boot/module params | ||
| 9 | 6. Potential improvements | ||
| 10 | 7. Bug reports, debugging and updates | ||
| 11 | 8. Acknowledgements | ||
| 12 | 9. Copyright | ||
| 13 | |||
| 14 | |||
| 15 | 1. Purpose and history | ||
| 16 | ---------------------- | ||
| 17 | The tmscsim driver supports PCI SCSI Host Adapters based on the AM53C974 | ||
| 18 | chip. AM53C974 based SCSI adapters include: | ||
| 19 | Tekram DC390, DC390T | ||
| 20 | Dawicontrol 2974 | ||
| 21 | QLogic Fast! PCI Basic | ||
| 22 | some on-board adapters | ||
| 23 | (This is most probably not a complete list) | ||
| 24 | |||
| 25 | It has originally written by C.L. Huang from the Tekram corp. to support the | ||
| 26 | Tekram DC390(T) adapter. This is where the name comes from: tm = Tekram | ||
| 27 | scsi = SCSI driver, m = AMD (?) as opposed to w for the DC390W/U/F | ||
| 28 | (NCR53c8X5, X=2/7) driver. Yes, there was also a driver for the latter, | ||
| 29 | tmscsiw, which supported DC390W/U/F adapters. It's not maintained any more, | ||
| 30 | as the ncr53c8xx is perfectly supporting these adapters since some time. | ||
| 31 | |||
| 32 | The driver first appeared in April 1996, exclusively supported the DC390 | ||
| 33 | and has been enhanced since then in various steps. In May 1998 support for | ||
| 34 | general AM53C974 based adapters and some possibilities to configure it were | ||
| 35 | added. The non-DC390 support works by assuming some values for the data | ||
| 36 | normally taken from the DC390 EEPROM. See below (chapter 5) for details. | ||
| 37 | |||
| 38 | When using the DC390, the configuration is still be done using the DC390 | ||
| 39 | BIOS setup. The DC390 EEPROM is read and used by the driver, any boot or | ||
| 40 | module parameters (chapter 5) are ignored! However, you can change settings | ||
| 41 | dynamically, as described in chapter 4. | ||
| 42 | |||
| 43 | For a more detailed description of the driver's history, see the first lines | ||
| 44 | of tmscsim.c. | ||
| 45 | The numbering scheme isn't consistent. The first versions went from 1.00 to | ||
| 46 | 1.12, then 1.20a to 1.20t. Finally I decided to use the ncr53c8xx scheme. So | ||
| 47 | the next revisions will be 2.0a to 2.0X (stable), 2.1a to 2.1X (experimental), | ||
| 48 | 2.2a to 2.2X (stable, again) etc. (X = anything between a and z.) If I send | ||
| 49 | fixes to people for testing, I create intermediate versions with a digit | ||
| 50 | appended, e.g. 2.0c3. | ||
| 51 | |||
| 52 | |||
| 53 | 2. Installation | ||
| 54 | --------------- | ||
| 55 | If you got any recent kernel with this driver and document included in | ||
| 56 | linux/drivers/scsi, you basically have to do nothing special to use this | ||
| 57 | driver. Of course you have to choose to compile SCSI support and DC390(T) | ||
| 58 | support into your kernel or as module when configuring your kernel for | ||
| 59 | compiling. | ||
| 60 | NEW: You may as well compile this module outside your kernel, using the | ||
| 61 | supplied Makefile. | ||
| 62 | |||
| 63 | If you got an old kernel (pre 2.1.127, pre 2.0.37p1) with an old version of | ||
| 64 | this driver: Get dc390-21125-20b.diff.gz or dc390-2036p21-20b1.diff.gz from | ||
| 65 | my web page and apply the patch. Apply further patches to upgrade to the | ||
| 66 | latest version of the driver. | ||
| 67 | |||
| 68 | If you want to do it manually, you should copy the files (dc390.h, | ||
| 69 | tmscsim.h, tmscsim.c, scsiiom.c and README.tmscsim) from this directory to | ||
| 70 | linux/drivers/scsi. You have to recompile your kernel/module of course. | ||
| 71 | |||
| 72 | You should apply the three patches included in dc390-120-kernel.diff | ||
| 73 | (Applying them: cd /usr/src; patch -p0 <~/dc390-120-kernel.diff) | ||
| 74 | The patches are against 2.1.125, so you might have to manually resolve | ||
| 75 | rejections when applying to another kernel version. | ||
| 76 | |||
| 77 | The patches will update the kernel startup code to allow boot parameters to | ||
| 78 | be passed to the driver, update the Documentation and finally offer you the | ||
| 79 | possibility to omit the non-DC390 parts of the driver. | ||
| 80 | (By selecting "Omit support for non DC390" you basically disable the | ||
| 81 | emulation of a DC390 EEPROM for non DC390 adapters. This saves a few bytes | ||
| 82 | of memory.) | ||
| 83 | |||
| 84 | If you got a very old kernel without the tmscsim driver (pre 2.0.31) | ||
| 85 | I recommend upgrading your kernel. However, if you don't want to, please | ||
| 86 | contact me to get the appropriate patches. | ||
| 87 | |||
| 88 | |||
| 89 | Upgrading a SCSI driver is always a delicate thing to do. The 2.0 driver has | ||
| 90 | proven stable on many systems, but it's still a good idea to take some | ||
| 91 | precautions. In an ideal world you would have a full backup of your disks. | ||
| 92 | The world isn't ideal and most people don't have full backups (me neither). | ||
| 93 | So take at least the following measures: | ||
| 94 | * make your kernel remount the FS read-only on detecting an error: | ||
| 95 | tune2fs -e remount-ro /dev/sd?? | ||
| 96 | * have copies of your SCSI disk's partition tables on some safe location: | ||
| 97 | dd if=/dev/sda of=/mnt/floppy/sda bs=512 count=1 | ||
| 98 | or just print it with: | ||
| 99 | fdisk -l | lpr | ||
| 100 | * make sure you are able to boot Linux (e.g. from floppy disk using InitRD) | ||
| 101 | if your SCSI disk gets corrupted. You can use | ||
| 102 | ftp://student.physik.uni-dortmund.de/pub/linux/kernel/bootdisk.gz | ||
| 103 | |||
| 104 | One more warning: I used to overclock my PCI bus to 41.67 MHz. My Tekram | ||
| 105 | DC390F (Sym53c875) accepted this as well as my Millennium. But the Am53C974 | ||
| 106 | produced errors and started to corrupt my disks. So don't do that! A 37.50 | ||
| 107 | MHz PCI bus works for me, though, but I don't recommend using higher clocks | ||
| 108 | than the 33.33 MHz being in the PCI spec. | ||
| 109 | |||
| 110 | |||
| 111 | 3.Features | ||
| 112 | ---------- | ||
| 113 | - SCSI | ||
| 114 | * Tagged command queueing | ||
| 115 | * Sync speed up to 10 MHz | ||
| 116 | * Disconnection | ||
| 117 | * Multiple LUNs | ||
| 118 | |||
| 119 | - General / Linux interface | ||
| 120 | * Support for up to 4 AM53C974 adapters. | ||
| 121 | * DC390 EEPROM usage or boot/module params | ||
| 122 | * Information via cat /proc/scsi/tmscsim/? | ||
| 123 | * Dynamically configurable by writing to /proc/scsi/tmscsim/? | ||
| 124 | * Dynamic allocation of resources | ||
| 125 | * SMP support: Locking on io_request lock (Linux 2.1/2.2) or adapter | ||
| 126 | specific locks (Linux 2.5?) | ||
| 127 | * Uniform source code for Linux-2.x.y | ||
| 128 | * Support for dyn. addition/removal of devices via add/remove-single-device | ||
| 129 | (Try: echo "scsi add-single-device C B T U" >/proc/scsi/scsi | ||
| 130 | C = Controller, B = Bus, T = Target SCSI ID, U = Unit SCSI LUN.) | ||
| 131 | Use with care! | ||
| 132 | * Try to use the partition table for the determination of the mapping | ||
| 133 | |||
| 134 | |||
| 135 | 4. Configuration via /proc/scsi/tmscsim/? | ||
| 136 | ----------------------------------------- | ||
| 137 | First of all look at the output of /proc/scsi/tmscsim/? by typing | ||
| 138 | cat /proc/scsi/tmscsim/? | ||
| 139 | The "?" should be replaced by the SCSI host number. (The shell might do this | ||
| 140 | for you.) | ||
| 141 | You will see some info regarding the adapter and, at the end, a listing of | ||
| 142 | the attached devices and their settings. | ||
| 143 | |||
| 144 | Here's an example: | ||
| 145 | garloff@kurt:/home/garloff > cat /proc/scsi/tmscsim/0 | ||
| 146 | Tekram DC390/AM53C974 PCI SCSI Host Adapter, Driver Version 2.0e7 2000-11-28 | ||
| 147 | SCSI Host Nr 1, AM53C974 Adapter Nr 0 | ||
| 148 | IOPortBase 0xb000, IRQ 10 | ||
| 149 | MaxID 8, MaxLUN 8, AdapterID 6, SelTimeout 250 ms, DelayReset 1 s | ||
| 150 | TagMaxNum 16, Status 0x00, ACBFlag 0x00, GlitchEater 24 ns | ||
| 151 | Statistics: Cmnds 1470165, Cmnds not sent directly 0, Out of SRB conds 0 | ||
| 152 | Lost arbitrations 587, Sel. connected 0, Connected: No | ||
| 153 | Nr of attached devices: 4, Nr of DCBs: 4 | ||
| 154 | Map of attached LUNs: 01 00 00 03 01 00 00 00 | ||
| 155 | Idx ID LUN Prty Sync DsCn SndS TagQ NegoPeriod SyncSpeed SyncOffs MaxCmd | ||
| 156 | 00 00 00 Yes Yes Yes Yes Yes 100 ns 10.0 M 15 16 | ||
| 157 | 01 03 00 Yes Yes Yes Yes No 100 ns 10.0 M 15 01 | ||
| 158 | 02 03 01 Yes Yes Yes Yes No 100 ns 10.0 M 15 01 | ||
| 159 | 03 04 00 Yes Yes Yes Yes No 100 ns 10.0 M 15 01 | ||
| 160 | |||
| 161 | Note that the settings MaxID and MaxLUN are not zero- but one-based, which | ||
| 162 | means that a setting MaxLUN=4, will result in the support of LUNs 0..3. This | ||
| 163 | is somehow inconvenient, but the way the mid-level SCSI code expects it to be. | ||
| 164 | |||
| 165 | ACB and DCB are acronyms for Adapter Control Block and Device Control Block. | ||
| 166 | These are data structures of the driver containing information about the | ||
| 167 | adapter and the connected SCSI devices respectively. | ||
| 168 | |||
| 169 | Idx is the device index (just a consecutive number for the driver), ID and | ||
| 170 | LUN are the SCSI ID and LUN, Prty means Parity checking, Sync synchronous | ||
| 171 | negotiation, DsCn Disconnection, SndS Send Start command on startup (not | ||
| 172 | used by the driver) and TagQ Tagged Command Queueing. NegoPeriod and | ||
| 173 | SyncSpeed are somehow redundant, because they are reciprocal values | ||
| 174 | (1 / 112 ns = 8.9 MHz). At least in theory. The driver is able to adjust the | ||
| 175 | NegoPeriod more accurate (4ns) than the SyncSpeed (1 / 25ns). I don't know | ||
| 176 | if certain devices will have problems with this discrepancy. Max. speed is | ||
| 177 | 10 MHz corresp. to a min. NegoPeriod of 100 ns. | ||
| 178 | (The driver allows slightly higher speeds if the devices (Ultra SCSI) accept | ||
| 179 | it, but that's out of adapter spec, on your own risk and unlikely to improve | ||
| 180 | performance. You're likely to crash your disks.) | ||
| 181 | SyncOffs is the offset used for synchronous negotiations; max. is 15. | ||
| 182 | The last values are only shown, if Sync is enabled. (NegoPeriod is still | ||
| 183 | displayed in brackets to show the values which will be used after enabling | ||
| 184 | Sync.) | ||
| 185 | MaxCmd ist the number of commands (=tags) which can be processed at the same | ||
| 186 | time by the device. | ||
| 187 | |||
| 188 | If you want to change a setting, you can do that by writing to | ||
| 189 | /proc/scsi/tmscsim/?. Basically you have to imitate the output of driver. | ||
| 190 | (Don't use the brackets for NegoPeriod on Sync disabled devices.) | ||
| 191 | You don't have to care about capitalisation. The driver will accept space, | ||
| 192 | tab, comma, = and : as separators. | ||
| 193 | |||
| 194 | There are three kinds of changes: | ||
| 195 | |||
| 196 | (1) Change driver settings: | ||
| 197 | You type the names of the parameters and the params following it. | ||
| 198 | Example: | ||
| 199 | echo "MaxLUN=8 seltimeout 200" >/proc/scsi/tmscsim/0 | ||
| 200 | |||
| 201 | Note that you can only change MaxID, MaxLUN, AdapterID, SelTimeOut, | ||
| 202 | TagMaxNum, ACBFlag, GlitchEater and DelayReset. Don't change ACBFlag | ||
| 203 | unless you want to see what happens, if the driver hangs. | ||
| 204 | |||
| 205 | (2) Change device settings: You write a config line to the driver. The Nr | ||
| 206 | must match the ID and LUN given. If you give "-" as parameter, it is | ||
| 207 | ignored and the corresponding setting won't be changed. | ||
| 208 | You can use "y" or "n" instead of "Yes" and "No" if you want to. | ||
| 209 | You don't need to specify a full line. The driver automatically performs | ||
| 210 | an INQUIRY on the device if necessary to check if it is capable to operate | ||
| 211 | with the given settings (Sync, TagQ). | ||
| 212 | Examples: | ||
| 213 | echo "0 0 0 y y y - y - 10 " >/proc/scsi/tmscsim/0 | ||
| 214 | echo "3 5 0 y n y " >/proc/scsi/tmscsim/0 | ||
| 215 | |||
| 216 | To give a short explanation of the first example: | ||
| 217 | The first three numbers, "0 0 0" (Device index 0, SCSI ID 0, SCSI LUN 0), | ||
| 218 | select the device to which the following parameters apply. Note that it | ||
| 219 | would be sufficient to use the index or both SCSI ID and LUN, but I chose | ||
| 220 | to require all three to have a syntax similar to the output. | ||
| 221 | The following "y y y - y" enables Parity checking, enables Synchronous | ||
| 222 | transfers, Disconnection, leaves Send Start (not used) untouched and | ||
| 223 | enables Tagged Command Queueing for the selected device. The "-" skips | ||
| 224 | the Negotiation Period setting but the "10" sets the max sync. speed to | ||
| 225 | 10 MHz. It's useless to specify both NegoPeriod and SyncSpeed as | ||
| 226 | discussed above. The values used in this example will result in maximum | ||
| 227 | performance. | ||
| 228 | |||
| 229 | (3) Special commands: You can force a SCSI bus reset, an INQUIRY command, the | ||
| 230 | removal or the addition of a device's DCB and a SCSI register dump. | ||
| 231 | This is only used for debugging when you meet problems. The parameter of | ||
| 232 | the INQUIRY and REMOVE commands is the device index as shown by the | ||
| 233 | output of /proc/scsi/tmscsim/? in the device listing in the first column | ||
| 234 | (Idx). ADD takes the SCSI ID and LUN. | ||
| 235 | Examples: | ||
| 236 | echo "reset" >/proc/scsi/tmscsim/0 | ||
| 237 | echo "inquiry 1" >/proc/scsi/tmscsim/0 | ||
| 238 | echo "remove 2" >/proc/scsi/tmscsim/1 | ||
| 239 | echo "add 2 3" >/proc/scsi/tmscsim/? | ||
| 240 | echo "dump" >/proc/scsi/tmscsim/0 | ||
| 241 | |||
| 242 | Note that you will meet problems when you REMOVE a device's DCB with the | ||
| 243 | remove command if it contains partitions which are mounted. Only use it | ||
| 244 | after unmounting its partitions, telling the SCSI mid-level code to | ||
| 245 | remove it (scsi remove-single-device) and you really need a few bytes of | ||
| 246 | memory. | ||
| 247 | The ADD command allows you to configure a device before you tell the | ||
| 248 | mid-level code to try detection. | ||
| 249 | |||
| 250 | |||
| 251 | I'd suggest reviewing the output of /proc/scsi/tmscsim/? after changing | ||
| 252 | settings to see if everything changed as requested. | ||
| 253 | |||
| 254 | |||
| 255 | 5. Configuration via boot/module parameters | ||
| 256 | ------------------------------------------- | ||
| 257 | With the DC390, the driver reads its EEPROM settings and tries to use them. | ||
| 258 | But you may want to override the settings prior to being able to change the | ||
| 259 | driver configuration via /proc/scsi/tmscsim/?. | ||
| 260 | If you do have another AM53C974 based adapter, that's even the only | ||
| 261 | possibility to adjust settings before you are able to write to the | ||
| 262 | /proc/scsi/tmscsim/? pseudo-file, e.g. if you want to use another | ||
| 263 | adapter ID than 7. | ||
| 264 | (BTW, the log message "DC390: No EEPROM found!" is normal without a DC390.) | ||
| 265 | For this purpose, you can pass options to the driver before it is initialised | ||
| 266 | by using kernel or module parameters. See lilo(8) or modprobe(1) manual | ||
| 267 | pages on how to pass params to the kernel or a module. | ||
| 268 | [NOTE: Formerly, it was not possible to override the EEPROM supplied | ||
| 269 | settings of the DC390 with cmd line parameters. This has changed since | ||
| 270 | 2.0e7] | ||
| 271 | |||
| 272 | The syntax of the params is much shorter than the syntax of the /proc/... | ||
| 273 | interface. This makes it a little bit more difficult to use. However, long | ||
| 274 | parameter lines have the risk to be misinterpreted and the length of kernel | ||
| 275 | parameters is limited. | ||
| 276 | |||
| 277 | As the support for non-DC390 adapters works by simulating the values of the | ||
| 278 | DC390 EEPROM, the settings are given in a DC390 BIOS' way. | ||
| 279 | |||
| 280 | Here's the syntax: | ||
| 281 | tmscsim=AdaptID,SpdIdx,DevMode,AdaptMode,TaggedCmnds,DelayReset | ||
| 282 | |||
| 283 | Each of the parameters is a number, containing the described information: | ||
| 284 | |||
| 285 | * AdaptID: The SCSI ID of the host adapter. Must be in the range 0..7 | ||
| 286 | Default is 7. | ||
| 287 | |||
| 288 | * SpdIdx: The index of the maximum speed as in the DC390 BIOS. The values | ||
| 289 | 0..7 mean 10, 8.0, 6.7, 5.7, 5.0, 4.0, 3.1 and 2 MHz resp. Default is | ||
| 290 | 0 (10.0 MHz). | ||
| 291 | |||
| 292 | * DevMode is a bit mapped value describing the per-device features. It | ||
| 293 | applies to all devices. (Sync, Disc and TagQ will only apply, if the | ||
| 294 | device supports it.) The meaning of the bits (* = default): | ||
| 295 | |||
| 296 | Bit Val(hex) Val(dec) Meaning | ||
| 297 | *0 0x01 1 Parity check | ||
| 298 | *1 0x02 2 Synchronous Negotiation | ||
| 299 | *2 0x04 4 Disconnection | ||
| 300 | *3 0x08 8 Send Start command on startup. (Not used) | ||
| 301 | *4 0x10 16 Tagged Command Queueing | ||
| 302 | |||
| 303 | As usual, the desired value is obtained by adding the wanted values. If | ||
| 304 | you want to enable all values, e.g., you would use 31(0x1f). Default is 31. | ||
| 305 | |||
| 306 | * AdaptMode is a bit mapped value describing the enabled adapter features. | ||
| 307 | |||
| 308 | Bit Val(hex) Val(dec) Meaning | ||
| 309 | *0 0x01 1 Support more than two drives. (Not used) | ||
| 310 | *1 0x02 2 Use DOS compatible mapping for HDs greater than 1GB. | ||
| 311 | *2 0x04 4 Reset SCSI Bus on startup. | ||
| 312 | *3 0x08 8 Active Negation: Improves SCSI Bus noise immunity. | ||
| 313 | 4 0x10 16 Immediate return on BIOS seek command. (Not used) | ||
| 314 | (*)5 0x20 32 Check for LUNs >= 1. | ||
| 315 | |||
| 316 | * TaggedCmnds is a number indicating the maximum number of Tagged Commands. | ||
| 317 | It is the binary logarithm - 1 of the actual number. Max is 4 (32). | ||
| 318 | Value Number of Tagged Commands | ||
| 319 | 0 2 | ||
| 320 | 1 4 | ||
| 321 | 2 8 | ||
| 322 | *3 16 | ||
| 323 | 4 32 | ||
| 324 | |||
| 325 | * DelayReset is the time in seconds (minus 0.5s), the adapter waits, after a | ||
| 326 | bus reset. Default is 1 (corresp. to 1.5s). | ||
| 327 | |||
| 328 | Example: | ||
| 329 | modprobe tmscsim tmscsim=6,2,31 | ||
| 330 | would set the adapter ID to 6, max. speed to 6.7 MHz, enable all device | ||
| 331 | features and leave the adapter features, the number of Tagged Commands | ||
| 332 | and the Delay after a reset to the defaults. | ||
| 333 | |||
| 334 | As you can see, you don't need to specify all of the six params. | ||
| 335 | If you want values to be ignored (i.e. the EEprom settings or the defaults | ||
| 336 | will be used), you may pass -2 (not 0!) at the corresponding position. | ||
| 337 | |||
| 338 | The defaults (7,0,31,15,3,1) are aggressive to allow good performance. You | ||
| 339 | can use tmscsim=7,0,31,63,4,0 for maximum performance, if your SCSI chain | ||
| 340 | allows it. If you meet problems, you can use tmscsim=-1 which is a shortcut | ||
| 341 | for tmscsim=7,4,9,15,2,10. | ||
| 342 | |||
| 343 | |||
| 344 | 6. Potential improvements | ||
| 345 | ------------------------- | ||
| 346 | Most of the intended work on the driver has been done. Here are a few ideas | ||
| 347 | to further improve its usability: | ||
| 348 | |||
| 349 | * Cleanly separate per-Target and per-LUN properties (DCB) | ||
| 350 | * More intelligent abort() routine | ||
| 351 | * Use new_eh code (Linux-2.1+) | ||
| 352 | * Have the mid-level (ML) code (and not the driver) handle more of the | ||
| 353 | various conditions. | ||
| 354 | * Command queueing in the driver: Eliminate Query list and use ML instead. | ||
| 355 | * More user friendly boot/module param syntax | ||
| 356 | |||
| 357 | Further investigation on these problems: | ||
| 358 | |||
| 359 | * Driver hangs with sync readcdda (xcdroast) (most probably VIA PCI error) | ||
| 360 | |||
| 361 | Known problems: | ||
| 362 | Please see http://www.garloff.de/kurt/linux/dc390/problems.html | ||
| 363 | |||
| 364 | * Changing the parameters of multi-lun by the tmscsim/? interface will | ||
| 365 | cause problems, cause these settings are mostly per Target and not per LUN | ||
| 366 | and should be updated accordingly. To be fixed for 2.0d24. | ||
| 367 | * CDRs (eg Yam CRW4416) not recognized, because some buggy devices don't | ||
| 368 | recover from a SCSI reset in time. Use a higher delay or don't issue | ||
| 369 | a SCSI bus reset on driver initialization. See problems page. | ||
| 370 | For the CRW4416S, this seems to be solved with firmware 1.0g (reported by | ||
| 371 | Jean-Yves Barbier). | ||
| 372 | * TEAC CD-532S not being recognized. (Works with 1.11). | ||
| 373 | * Scanners (eg. Astra UMAX 1220S) don't work: Disable Sync Negotiation. | ||
| 374 | If this does not help, try echo "INQUIRY t" >/proc/scsi/tmscsim/? (t | ||
| 375 | replaced by the dev index of your scanner). You may try to reset your SCSI | ||
| 376 | bus afterwards (echo "RESET" >/proc/scsi/tmscsim/?). | ||
| 377 | The problem seems to be solved as of 2.0d18, thanks to Andreas Rick. | ||
| 378 | * If there is a valid partition table, the driver will use it for determining | ||
| 379 | the mapping. If there's none, a reasonable mapping (Symbios-like) will be | ||
| 380 | assumed. Other operating systems may not like this mapping, though | ||
| 381 | it's consistent with the BIOS' behaviour. Old DC390 drivers ignored the | ||
| 382 | partition table and used a H/S = 64/32 or 255/63 translation. So if you | ||
| 383 | want to be compatible to those, use this old mapping when creating | ||
| 384 | partition tables. Even worse, on bootup the DC390 might complain if other | ||
| 385 | mappings are found, so auto rebooting may fail. | ||
| 386 | * In some situations, the driver will get stuck in an abort loop. This is a | ||
| 387 | bad interaction between the Mid-Layer of Linux' SCSI code and the driver. | ||
| 388 | Try to disable DsCn, if you meet this problem. Please contact me for | ||
| 389 | further debugging. | ||
| 390 | |||
| 391 | |||
| 392 | 7. Bug reports, debugging and updates | ||
| 393 | ------------------------------------- | ||
| 394 | Whenever you have problems with the driver, you are invited to ask the | ||
| 395 | author for help. However, I'd suggest reading the docs and trying to solve | ||
| 396 | the problem yourself, first. | ||
| 397 | If you find something, which you believe to be a bug, please report it to me. | ||
| 398 | Please append the output of /proc/scsi/scsi, /proc/scsi/tmscsim/? and | ||
| 399 | maybe the DC390 log messages to the report. | ||
| 400 | |||
| 401 | Bug reports should be send to me (Kurt Garloff <dc390@garloff.de>) as well | ||
| 402 | as to the linux-scsi list (<linux-scsi@vger.kernel.org>), as sometimes bugs | ||
| 403 | are caused by the SCSI mid-level code. | ||
| 404 | |||
| 405 | I will ask you for some more details and probably I will also ask you to | ||
| 406 | enable some of the DEBUG options in the driver (tmscsim.c:DC390_DEBUGXXX | ||
| 407 | defines). The driver will produce some data for the syslog facility then. | ||
| 408 | Beware: If your syslog gets written to a SCSI disk connected to your | ||
| 409 | AM53C974, the logging might produce log output again, and you might end | ||
| 410 | having your box spending most of its time doing the logging. | ||
| 411 | |||
| 412 | The latest version of the driver can be found at: | ||
| 413 | http://www.garloff.de/kurt/linux/dc390/ | ||
| 414 | ftp://ftp.suse.com/pub/people/garloff/linux/dc390/ | ||
| 415 | |||
| 416 | |||
| 417 | 8. Acknowledgements | ||
| 418 | ------------------- | ||
| 419 | Thanks to Linus Torvalds, Alan Cox, the FSF people, the XFree86 team and | ||
| 420 | all the others for the wonderful OS and software. | ||
| 421 | Thanks to C.L. Huang and Philip Giang (Tekram) for the initial driver | ||
| 422 | release and support. | ||
| 423 | Thanks to Doug Ledford, Gérard Roudier for support with SCSI coding. | ||
| 424 | Thanks to a lot of people (espec. Chiaki Ishikawa, Andreas Haumer, Hubert | ||
| 425 | Tonneau) for intensively testing the driver (and even risking data loss | ||
| 426 | doing this during early revisions). | ||
| 427 | Recently, SuSE GmbH, Nuernberg, FRG, has been paying me for the driver | ||
| 428 | development and maintenance. Special thanks! | ||
| 429 | |||
| 430 | |||
| 431 | 9. Copyright | ||
| 432 | ------------ | ||
| 433 | This driver is free software; you can redistribute it and/or modify | ||
| 434 | it under the terms of the GNU General Public License as published by | ||
| 435 | the Free Software Foundation; version 2 of the License. | ||
| 436 | If you want to use any later version of the GNU GPL, you will probably | ||
| 437 | be allowed to, but you have to ask me and Tekram <erich@tekram.com.tw> | ||
| 438 | before. | ||
| 439 | |||
| 440 | ------------------------------------------------------------------------- | ||
| 441 | Written by Kurt Garloff <kurt@garloff.de> 1998/06/11 | ||
| 442 | Last updated 2000/11/28, driver revision 2.0e7 | ||
| 443 | $Id: README.tmscsim,v 2.25.2.7 2000/12/20 01:07:12 garloff Exp $ | ||
diff --git a/MAINTAINERS b/MAINTAINERS index d95925d4e1f7..8133e97980f1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -4971,12 +4971,6 @@ T: git git://linuxtv.org/anttip/media_tree.git | |||
| 4971 | S: Maintained | 4971 | S: Maintained |
| 4972 | F: drivers/media/tuners/e4000* | 4972 | F: drivers/media/tuners/e4000* |
| 4973 | 4973 | ||
| 4974 | EATA ISA/EISA/PCI SCSI DRIVER | ||
| 4975 | M: Dario Ballabio <ballabio_dario@emc.com> | ||
| 4976 | L: linux-scsi@vger.kernel.org | ||
| 4977 | S: Maintained | ||
| 4978 | F: drivers/scsi/eata.c | ||
| 4979 | |||
| 4980 | EC100 MEDIA DRIVER | 4974 | EC100 MEDIA DRIVER |
| 4981 | M: Antti Palosaari <crope@iki.fi> | 4975 | M: Antti Palosaari <crope@iki.fi> |
| 4982 | L: linux-media@vger.kernel.org | 4976 | L: linux-media@vger.kernel.org |
| @@ -5812,12 +5806,6 @@ F: tools/testing/selftests/futex/ | |||
| 5812 | F: tools/perf/bench/futex* | 5806 | F: tools/perf/bench/futex* |
| 5813 | F: Documentation/*futex* | 5807 | F: Documentation/*futex* |
| 5814 | 5808 | ||
| 5815 | FUTURE DOMAIN TMC-16x0 SCSI DRIVER (16-bit) | ||
| 5816 | M: Rik Faith <faith@cs.unc.edu> | ||
| 5817 | L: linux-scsi@vger.kernel.org | ||
| 5818 | S: Odd Fixes (e.g., new signatures) | ||
| 5819 | F: drivers/scsi/fdomain.* | ||
| 5820 | |||
| 5821 | GCC PLUGINS | 5809 | GCC PLUGINS |
| 5822 | M: Kees Cook <keescook@chromium.org> | 5810 | M: Kees Cook <keescook@chromium.org> |
| 5823 | R: Emese Revfy <re.emese@gmail.com> | 5811 | R: Emese Revfy <re.emese@gmail.com> |
diff --git a/arch/powerpc/configs/c2k_defconfig b/arch/powerpc/configs/c2k_defconfig index 4bb832a41d55..6c1196b0f81e 100644 --- a/arch/powerpc/configs/c2k_defconfig +++ b/arch/powerpc/configs/c2k_defconfig | |||
| @@ -184,7 +184,6 @@ CONFIG_MEGARAID_NEWGEN=y | |||
| 184 | CONFIG_MEGARAID_MM=m | 184 | CONFIG_MEGARAID_MM=m |
| 185 | CONFIG_MEGARAID_MAILBOX=m | 185 | CONFIG_MEGARAID_MAILBOX=m |
| 186 | CONFIG_MEGARAID_SAS=m | 186 | CONFIG_MEGARAID_SAS=m |
| 187 | CONFIG_SCSI_FUTURE_DOMAIN=m | ||
| 188 | CONFIG_SCSI_GDTH=m | 187 | CONFIG_SCSI_GDTH=m |
| 189 | CONFIG_SCSI_IPS=m | 188 | CONFIG_SCSI_IPS=m |
| 190 | CONFIG_SCSI_INITIO=m | 189 | CONFIG_SCSI_INITIO=m |
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 8a739b74cfb7..11e89e56b865 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
| @@ -640,88 +640,6 @@ config SCSI_DMX3191D | |||
| 640 | To compile this driver as a module, choose M here: the | 640 | To compile this driver as a module, choose M here: the |
| 641 | module will be called dmx3191d. | 641 | module will be called dmx3191d. |
| 642 | 642 | ||
| 643 | config SCSI_EATA | ||
| 644 | tristate "EATA ISA/EISA/PCI (DPT and generic EATA/DMA-compliant boards) support" | ||
| 645 | depends on (ISA || EISA || PCI) && SCSI && ISA_DMA_API | ||
| 646 | ---help--- | ||
| 647 | This driver supports all EATA/DMA-compliant SCSI host adapters. DPT | ||
| 648 | ISA and all EISA I/O addresses are probed looking for the "EATA" | ||
| 649 | signature. The addresses of all the PCI SCSI controllers reported | ||
| 650 | by the PCI subsystem are probed as well. | ||
| 651 | |||
| 652 | You want to read the start of <file:drivers/scsi/eata.c> and the | ||
| 653 | SCSI-HOWTO, available from | ||
| 654 | <http://www.tldp.org/docs.html#howto>. | ||
| 655 | |||
| 656 | To compile this driver as a module, choose M here: the | ||
| 657 | module will be called eata. | ||
| 658 | |||
| 659 | config SCSI_EATA_TAGGED_QUEUE | ||
| 660 | bool "enable tagged command queueing" | ||
| 661 | depends on SCSI_EATA | ||
| 662 | help | ||
| 663 | This is a feature of SCSI-2 which improves performance: the host | ||
| 664 | adapter can send several SCSI commands to a device's queue even if | ||
| 665 | previous commands haven't finished yet. | ||
| 666 | This is equivalent to the "eata=tc:y" boot option. | ||
| 667 | |||
| 668 | config SCSI_EATA_LINKED_COMMANDS | ||
| 669 | bool "enable elevator sorting" | ||
| 670 | depends on SCSI_EATA | ||
| 671 | help | ||
| 672 | This option enables elevator sorting for all probed SCSI disks and | ||
| 673 | CD-ROMs. It definitely reduces the average seek distance when doing | ||
| 674 | random seeks, but this does not necessarily result in a noticeable | ||
| 675 | performance improvement: your mileage may vary... | ||
| 676 | This is equivalent to the "eata=lc:y" boot option. | ||
| 677 | |||
| 678 | config SCSI_EATA_MAX_TAGS | ||
| 679 | int "maximum number of queued commands" | ||
| 680 | depends on SCSI_EATA | ||
| 681 | default "16" | ||
| 682 | help | ||
| 683 | This specifies how many SCSI commands can be maximally queued for | ||
| 684 | each probed SCSI device. You should reduce the default value of 16 | ||
| 685 | only if you have disks with buggy or limited tagged command support. | ||
| 686 | Minimum is 2 and maximum is 62. This value is also the window size | ||
| 687 | used by the elevator sorting option above. The effective value used | ||
| 688 | by the driver for each probed SCSI device is reported at boot time. | ||
| 689 | This is equivalent to the "eata=mq:8" boot option. | ||
| 690 | |||
| 691 | config SCSI_EATA_PIO | ||
| 692 | tristate "EATA-PIO (old DPT PM2001, PM2012A) support" | ||
| 693 | depends on (ISA || EISA || PCI) && SCSI && BROKEN | ||
| 694 | ---help--- | ||
| 695 | This driver supports all EATA-PIO protocol compliant SCSI Host | ||
| 696 | Adapters like the DPT PM2001 and the PM2012A. EATA-DMA compliant | ||
| 697 | host adapters could also use this driver but are discouraged from | ||
| 698 | doing so, since this driver only supports hard disks and lacks | ||
| 699 | numerous features. You might want to have a look at the SCSI-HOWTO, | ||
| 700 | available from <http://www.tldp.org/docs.html#howto>. | ||
| 701 | |||
| 702 | To compile this driver as a module, choose M here: the | ||
| 703 | module will be called eata_pio. | ||
| 704 | |||
| 705 | config SCSI_FUTURE_DOMAIN | ||
| 706 | tristate "Future Domain 16xx SCSI/AHA-2920A support" | ||
| 707 | depends on (ISA || PCI) && SCSI | ||
| 708 | select CHECK_SIGNATURE | ||
| 709 | ---help--- | ||
| 710 | This is support for Future Domain's 16-bit SCSI host adapters | ||
| 711 | (TMC-1660/1680, TMC-1650/1670, TMC-3260, TMC-1610M/MER/MEX) and | ||
| 712 | other adapters based on the Future Domain chipsets (Quantum | ||
| 713 | ISA-200S, ISA-250MG; Adaptec AHA-2920A; and at least one IBM board). | ||
| 714 | It is explained in section 3.7 of the SCSI-HOWTO, available from | ||
| 715 | <http://www.tldp.org/docs.html#howto>. | ||
| 716 | |||
| 717 | NOTE: Newer Adaptec AHA-2920C boards use the Adaptec AIC-7850 chip | ||
| 718 | and should use the aic7xxx driver ("Adaptec AIC7xxx chipset SCSI | ||
| 719 | controller support"). This Future Domain driver works with the older | ||
| 720 | Adaptec AHA-2920A boards with a Future Domain chip on them. | ||
| 721 | |||
| 722 | To compile this driver as a module, choose M here: the | ||
| 723 | module will be called fdomain. | ||
| 724 | |||
| 725 | config SCSI_GDTH | 643 | config SCSI_GDTH |
| 726 | tristate "Intel/ICP (former GDT SCSI Disk Array) RAID Controller support" | 644 | tristate "Intel/ICP (former GDT SCSI Disk Array) RAID Controller support" |
| 727 | depends on (ISA || EISA || PCI) && SCSI && ISA_DMA_API | 645 | depends on (ISA || EISA || PCI) && SCSI && ISA_DMA_API |
| @@ -923,18 +841,6 @@ config SCSI_IZIP_SLOW_CTR | |||
| 923 | 841 | ||
| 924 | Generally, saying N is fine. | 842 | Generally, saying N is fine. |
| 925 | 843 | ||
| 926 | config SCSI_NCR53C406A | ||
| 927 | tristate "NCR53c406a SCSI support" | ||
| 928 | depends on ISA && SCSI | ||
| 929 | help | ||
| 930 | This is support for the NCR53c406a SCSI host adapter. For user | ||
| 931 | configurable parameters, check out <file:drivers/scsi/NCR53c406a.c> | ||
| 932 | in the kernel source. Also read the SCSI-HOWTO, available from | ||
| 933 | <http://www.tldp.org/docs.html#howto>. | ||
| 934 | |||
| 935 | To compile this driver as a module, choose M here: the | ||
| 936 | module will be called NCR53c406. | ||
| 937 | |||
| 938 | config SCSI_NCR_D700 | 844 | config SCSI_NCR_D700 |
| 939 | tristate "NCR Dual 700 MCA SCSI support" | 845 | tristate "NCR Dual 700 MCA SCSI support" |
| 940 | depends on MCA && SCSI | 846 | depends on MCA && SCSI |
| @@ -1059,6 +965,7 @@ config SCSI_IPR | |||
| 1059 | depends on PCI && SCSI && ATA | 965 | depends on PCI && SCSI && ATA |
| 1060 | select FW_LOADER | 966 | select FW_LOADER |
| 1061 | select IRQ_POLL | 967 | select IRQ_POLL |
| 968 | select SGL_ALLOC | ||
| 1062 | ---help--- | 969 | ---help--- |
| 1063 | This driver supports the IBM Power Linux family RAID adapters. | 970 | This driver supports the IBM Power Linux family RAID adapters. |
| 1064 | This includes IBM pSeries 5712, 5703, 5709, and 570A, as well | 971 | This includes IBM pSeries 5712, 5703, 5709, and 570A, as well |
| @@ -1265,24 +1172,6 @@ config SCSI_SIM710 | |||
| 1265 | 1172 | ||
| 1266 | It currently supports Compaq EISA cards and NCR MCA cards | 1173 | It currently supports Compaq EISA cards and NCR MCA cards |
| 1267 | 1174 | ||
| 1268 | config SCSI_SYM53C416 | ||
| 1269 | tristate "Symbios 53c416 SCSI support" | ||
| 1270 | depends on ISA && SCSI | ||
| 1271 | ---help--- | ||
| 1272 | This is support for the sym53c416 SCSI host adapter, the SCSI | ||
| 1273 | adapter that comes with some HP scanners. This driver requires that | ||
| 1274 | the sym53c416 is configured first using some sort of PnP | ||
| 1275 | configuration program (e.g. isapnp) or by a PnP aware BIOS. If you | ||
| 1276 | are using isapnp then you need to compile this driver as a module | ||
| 1277 | and then load it using insmod after isapnp has run. The parameters | ||
| 1278 | of the configured card(s) should be passed to the driver. The format | ||
| 1279 | is: | ||
| 1280 | |||
| 1281 | insmod sym53c416 sym53c416=<base>,<irq> [sym53c416_1=<base>,<irq>] | ||
| 1282 | |||
| 1283 | To compile this driver as a module, choose M here: the | ||
| 1284 | module will be called sym53c416. | ||
| 1285 | |||
| 1286 | config SCSI_DC395x | 1175 | config SCSI_DC395x |
| 1287 | tristate "Tekram DC395(U/UW/F) and DC315(U) SCSI support" | 1176 | tristate "Tekram DC395(U/UW/F) and DC315(U) SCSI support" |
| 1288 | depends on PCI && SCSI | 1177 | depends on PCI && SCSI |
| @@ -1576,6 +1465,7 @@ config ZFCP | |||
| 1576 | config SCSI_PMCRAID | 1465 | config SCSI_PMCRAID |
| 1577 | tristate "PMC SIERRA Linux MaxRAID adapter support" | 1466 | tristate "PMC SIERRA Linux MaxRAID adapter support" |
| 1578 | depends on PCI && SCSI && NET | 1467 | depends on PCI && SCSI && NET |
| 1468 | select SGL_ALLOC | ||
| 1579 | ---help--- | 1469 | ---help--- |
| 1580 | This driver supports the PMC SIERRA MaxRAID adapters. | 1470 | This driver supports the PMC SIERRA MaxRAID adapters. |
| 1581 | 1471 | ||
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index de1b3fce936d..e29f9b8fd66d 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile | |||
| @@ -74,12 +74,9 @@ obj-$(CONFIG_SCSI_AIC94XX) += aic94xx/ | |||
| 74 | obj-$(CONFIG_SCSI_PM8001) += pm8001/ | 74 | obj-$(CONFIG_SCSI_PM8001) += pm8001/ |
| 75 | obj-$(CONFIG_SCSI_ISCI) += isci/ | 75 | obj-$(CONFIG_SCSI_ISCI) += isci/ |
| 76 | obj-$(CONFIG_SCSI_IPS) += ips.o | 76 | obj-$(CONFIG_SCSI_IPS) += ips.o |
| 77 | obj-$(CONFIG_SCSI_FUTURE_DOMAIN)+= fdomain.o | ||
| 78 | obj-$(CONFIG_SCSI_GENERIC_NCR5380) += g_NCR5380.o | 77 | obj-$(CONFIG_SCSI_GENERIC_NCR5380) += g_NCR5380.o |
| 79 | obj-$(CONFIG_SCSI_NCR53C406A) += NCR53c406a.o | ||
| 80 | obj-$(CONFIG_SCSI_NCR_D700) += 53c700.o NCR_D700.o | 78 | obj-$(CONFIG_SCSI_NCR_D700) += 53c700.o NCR_D700.o |
| 81 | obj-$(CONFIG_SCSI_NCR_Q720) += NCR_Q720_mod.o | 79 | obj-$(CONFIG_SCSI_NCR_Q720) += NCR_Q720_mod.o |
| 82 | obj-$(CONFIG_SCSI_SYM53C416) += sym53c416.o | ||
| 83 | obj-$(CONFIG_SCSI_QLOGIC_FAS) += qlogicfas408.o qlogicfas.o | 80 | obj-$(CONFIG_SCSI_QLOGIC_FAS) += qlogicfas408.o qlogicfas.o |
| 84 | obj-$(CONFIG_PCMCIA_QLOGIC) += qlogicfas408.o | 81 | obj-$(CONFIG_PCMCIA_QLOGIC) += qlogicfas408.o |
| 85 | obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o | 82 | obj-$(CONFIG_SCSI_QLOGIC_1280) += qla1280.o |
| @@ -93,8 +90,6 @@ obj-$(CONFIG_SCSI_HPSA) += hpsa.o | |||
| 93 | obj-$(CONFIG_SCSI_SMARTPQI) += smartpqi/ | 90 | obj-$(CONFIG_SCSI_SMARTPQI) += smartpqi/ |
| 94 | obj-$(CONFIG_SCSI_SYM53C8XX_2) += sym53c8xx_2/ | 91 | obj-$(CONFIG_SCSI_SYM53C8XX_2) += sym53c8xx_2/ |
| 95 | obj-$(CONFIG_SCSI_ZALON) += zalon7xx.o | 92 | obj-$(CONFIG_SCSI_ZALON) += zalon7xx.o |
| 96 | obj-$(CONFIG_SCSI_EATA_PIO) += eata_pio.o | ||
| 97 | obj-$(CONFIG_SCSI_EATA) += eata.o | ||
| 98 | obj-$(CONFIG_SCSI_DC395x) += dc395x.o | 93 | obj-$(CONFIG_SCSI_DC395x) += dc395x.o |
| 99 | obj-$(CONFIG_SCSI_AM53C974) += esp_scsi.o am53c974.o | 94 | obj-$(CONFIG_SCSI_AM53C974) += esp_scsi.o am53c974.o |
| 100 | obj-$(CONFIG_CXLFLASH) += cxlflash/ | 95 | obj-$(CONFIG_CXLFLASH) += cxlflash/ |
diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c deleted file mode 100644 index 6e110c630d2c..000000000000 --- a/drivers/scsi/NCR53c406a.c +++ /dev/null | |||
| @@ -1,1090 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * NCR53c406.c | ||
| 3 | * Low-level SCSI driver for NCR53c406a chip. | ||
| 4 | * Copyright (C) 1994, 1995, 1996 Normunds Saumanis (normunds@fi.ibm.com) | ||
| 5 | * | ||
| 6 | * LILO command line usage: ncr53c406a=<PORTBASE>[,<IRQ>[,<FASTPIO>]] | ||
| 7 | * Specify IRQ = 0 for non-interrupt driven mode. | ||
| 8 | * FASTPIO = 1 for fast pio mode, 0 for slow mode. | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify it | ||
| 11 | * under the terms of the GNU General Public License as published by the | ||
| 12 | * Free Software Foundation; either version 2, or (at your option) any | ||
| 13 | * later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, but | ||
| 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 18 | * General Public License for more details. | ||
| 19 | * | ||
| 20 | */ | ||
| 21 | |||
| 22 | #define NCR53C406A_DEBUG 0 | ||
| 23 | #define VERBOSE_NCR53C406A_DEBUG 0 | ||
| 24 | |||
| 25 | /* Set this to 1 for PIO mode (recommended) or to 0 for DMA mode */ | ||
| 26 | #define USE_PIO 1 | ||
| 27 | |||
| 28 | #define USE_BIOS 0 | ||
| 29 | /* #define BIOS_ADDR 0xD8000 *//* define this if autoprobe fails */ | ||
| 30 | /* #define PORT_BASE 0x330 *//* define this if autoprobe fails */ | ||
| 31 | /* #define IRQ_LEV 0 *//* define this if autoprobe fails */ | ||
| 32 | #define DMA_CHAN 5 /* this is ignored if DMA is disabled */ | ||
| 33 | |||
| 34 | /* Set this to 0 if you encounter kernel lockups while transferring | ||
| 35 | * data in PIO mode */ | ||
| 36 | #define USE_FAST_PIO 1 | ||
| 37 | |||
| 38 | /* ============= End of user configurable parameters ============= */ | ||
| 39 | |||
| 40 | #include <linux/module.h> | ||
| 41 | |||
| 42 | #include <linux/errno.h> | ||
| 43 | #include <linux/ioport.h> | ||
| 44 | #include <linux/interrupt.h> | ||
| 45 | #include <linux/proc_fs.h> | ||
| 46 | #include <linux/stat.h> | ||
| 47 | #include <linux/init.h> | ||
| 48 | #include <linux/bitops.h> | ||
| 49 | #include <asm/io.h> | ||
| 50 | #include <asm/dma.h> | ||
| 51 | #include <asm/irq.h> | ||
| 52 | |||
| 53 | #include <linux/blkdev.h> | ||
| 54 | #include <linux/spinlock.h> | ||
| 55 | #include "scsi.h" | ||
| 56 | #include <scsi/scsi_host.h> | ||
| 57 | |||
| 58 | /* ============================================================= */ | ||
| 59 | |||
| 60 | #define WATCHDOG 5000000 | ||
| 61 | |||
| 62 | #define SYNC_MODE 0 /* Synchronous transfer mode */ | ||
| 63 | |||
| 64 | #ifdef DEBUG | ||
| 65 | #undef NCR53C406A_DEBUG | ||
| 66 | #define NCR53C406A_DEBUG 1 | ||
| 67 | #endif | ||
| 68 | |||
| 69 | #if USE_PIO | ||
| 70 | #define USE_DMA 0 | ||
| 71 | #else | ||
| 72 | #define USE_DMA 1 | ||
| 73 | #endif | ||
| 74 | |||
| 75 | /* Default configuration */ | ||
| 76 | #define C1_IMG 0x07 /* ID=7 */ | ||
| 77 | #define C2_IMG 0x48 /* FE SCSI2 */ | ||
| 78 | #if USE_DMA | ||
| 79 | #define C3_IMG 0x21 /* CDB TE */ | ||
| 80 | #else | ||
| 81 | #define C3_IMG 0x20 /* CDB */ | ||
| 82 | #endif | ||
| 83 | #define C4_IMG 0x04 /* ANE */ | ||
| 84 | #define C5_IMG 0xb6 /* AA PI SIE POL */ | ||
| 85 | |||
| 86 | #define REG0 (outb(C4_IMG, CONFIG4)) | ||
| 87 | #define REG1 (outb(C5_IMG, CONFIG5)) | ||
| 88 | |||
| 89 | #if NCR53C406A_DEBUG | ||
| 90 | #define DEB(x) x | ||
| 91 | #else | ||
| 92 | #define DEB(x) | ||
| 93 | #endif | ||
| 94 | |||
| 95 | #if VERBOSE_NCR53C406A_DEBUG | ||
| 96 | #define VDEB(x) x | ||
| 97 | #else | ||
| 98 | #define VDEB(x) | ||
| 99 | #endif | ||
| 100 | |||
| 101 | #define LOAD_DMA_COUNT(count) \ | ||
| 102 | outb(count & 0xff, TC_LSB); \ | ||
| 103 | outb((count >> 8) & 0xff, TC_MSB); \ | ||
| 104 | outb((count >> 16) & 0xff, TC_HIGH); | ||
| 105 | |||
| 106 | /* Chip commands */ | ||
| 107 | #define DMA_OP 0x80 | ||
| 108 | |||
| 109 | #define SCSI_NOP 0x00 | ||
| 110 | #define FLUSH_FIFO 0x01 | ||
| 111 | #define CHIP_RESET 0x02 | ||
| 112 | #define SCSI_RESET 0x03 | ||
| 113 | #define RESELECT 0x40 | ||
| 114 | #define SELECT_NO_ATN 0x41 | ||
| 115 | #define SELECT_ATN 0x42 | ||
| 116 | #define SELECT_ATN_STOP 0x43 | ||
| 117 | #define ENABLE_SEL 0x44 | ||
| 118 | #define DISABLE_SEL 0x45 | ||
| 119 | #define SELECT_ATN3 0x46 | ||
| 120 | #define RESELECT3 0x47 | ||
| 121 | #define TRANSFER_INFO 0x10 | ||
| 122 | #define INIT_CMD_COMPLETE 0x11 | ||
| 123 | #define MSG_ACCEPT 0x12 | ||
| 124 | #define TRANSFER_PAD 0x18 | ||
| 125 | #define SET_ATN 0x1a | ||
| 126 | #define RESET_ATN 0x1b | ||
| 127 | #define SEND_MSG 0x20 | ||
| 128 | #define SEND_STATUS 0x21 | ||
| 129 | #define SEND_DATA 0x22 | ||
| 130 | #define DISCONN_SEQ 0x23 | ||
| 131 | #define TERMINATE_SEQ 0x24 | ||
| 132 | #define TARG_CMD_COMPLETE 0x25 | ||
| 133 | #define DISCONN 0x27 | ||
| 134 | #define RECV_MSG 0x28 | ||
| 135 | #define RECV_CMD 0x29 | ||
| 136 | #define RECV_DATA 0x2a | ||
| 137 | #define RECV_CMD_SEQ 0x2b | ||
| 138 | #define TARGET_ABORT_DMA 0x04 | ||
| 139 | |||
| 140 | /*----------------------------------------------------------------*/ | ||
| 141 | /* the following will set the monitor border color (useful to find | ||
| 142 | where something crashed or gets stuck at */ | ||
| 143 | /* 1 = blue | ||
| 144 | 2 = green | ||
| 145 | 3 = cyan | ||
| 146 | 4 = red | ||
| 147 | 5 = magenta | ||
| 148 | 6 = yellow | ||
| 149 | 7 = white | ||
| 150 | */ | ||
| 151 | |||
| 152 | #if NCR53C406A_DEBUG | ||
| 153 | #define rtrc(i) {inb(0x3da);outb(0x31,0x3c0);outb((i),0x3c0);} | ||
| 154 | #else | ||
| 155 | #define rtrc(i) {} | ||
| 156 | #endif | ||
| 157 | /*----------------------------------------------------------------*/ | ||
| 158 | |||
| 159 | enum Phase { | ||
| 160 | idle, | ||
| 161 | data_out, | ||
| 162 | data_in, | ||
| 163 | command_ph, | ||
| 164 | status_ph, | ||
| 165 | message_out, | ||
| 166 | message_in | ||
| 167 | }; | ||
| 168 | |||
| 169 | /* Static function prototypes */ | ||
| 170 | static void NCR53c406a_intr(void *); | ||
| 171 | static irqreturn_t do_NCR53c406a_intr(int, void *); | ||
| 172 | static void chip_init(void); | ||
| 173 | static void calc_port_addr(void); | ||
| 174 | #ifndef IRQ_LEV | ||
| 175 | static int irq_probe(void); | ||
| 176 | #endif | ||
| 177 | |||
| 178 | /* ================================================================= */ | ||
| 179 | |||
| 180 | #if USE_BIOS | ||
| 181 | static void *bios_base; | ||
| 182 | #endif | ||
| 183 | |||
| 184 | #ifdef PORT_BASE | ||
| 185 | static int port_base = PORT_BASE; | ||
| 186 | #else | ||
| 187 | static int port_base; | ||
| 188 | #endif | ||
| 189 | |||
| 190 | #ifdef IRQ_LEV | ||
| 191 | static int irq_level = IRQ_LEV; | ||
| 192 | #else | ||
| 193 | static int irq_level = -1; /* 0 is 'no irq', so use -1 for 'uninitialized' */ | ||
| 194 | #endif | ||
| 195 | |||
| 196 | #if USE_DMA | ||
| 197 | static int dma_chan; | ||
| 198 | #endif | ||
| 199 | |||
| 200 | #if USE_PIO | ||
| 201 | static int fast_pio = USE_FAST_PIO; | ||
| 202 | #endif | ||
| 203 | |||
| 204 | static Scsi_Cmnd *current_SC; | ||
| 205 | static char info_msg[256]; | ||
| 206 | |||
| 207 | /* ================================================================= */ | ||
| 208 | |||
| 209 | /* possible BIOS locations */ | ||
| 210 | #if USE_BIOS | ||
| 211 | static void *addresses[] = { | ||
| 212 | (void *) 0xd8000, | ||
| 213 | (void *) 0xc8000 | ||
| 214 | }; | ||
| 215 | #define ADDRESS_COUNT ARRAY_SIZE(addresses) | ||
| 216 | #endif /* USE_BIOS */ | ||
| 217 | |||
| 218 | /* possible i/o port addresses */ | ||
| 219 | static unsigned short ports[] = { 0x230, 0x330, 0x280, 0x290, 0x330, 0x340, 0x300, 0x310, 0x348, 0x350 }; | ||
| 220 | #define PORT_COUNT ARRAY_SIZE(ports) | ||
| 221 | |||
| 222 | #ifndef MODULE | ||
| 223 | /* possible interrupt channels */ | ||
| 224 | static unsigned short intrs[] = { 10, 11, 12, 15 }; | ||
| 225 | #define INTR_COUNT ARRAY_SIZE(intrs) | ||
| 226 | #endif /* !MODULE */ | ||
| 227 | |||
| 228 | /* signatures for NCR 53c406a based controllers */ | ||
| 229 | #if USE_BIOS | ||
| 230 | struct signature { | ||
| 231 | char *signature; | ||
| 232 | int sig_offset; | ||
| 233 | int sig_length; | ||
| 234 | } signatures[] __initdata = { | ||
| 235 | /* 1 2 3 4 5 6 */ | ||
| 236 | /* 123456789012345678901234567890123456789012345678901234567890 */ | ||
| 237 | { | ||
| 238 | "Copyright (C) Acculogic, Inc.\r\n2.8M Diskette Extension Bios ver 4.04.03 03/01/1993", 61, 82},}; | ||
| 239 | |||
| 240 | #define SIGNATURE_COUNT ARRAY_SIZE(signatures) | ||
| 241 | #endif /* USE_BIOS */ | ||
| 242 | |||
| 243 | /* ============================================================ */ | ||
| 244 | |||
| 245 | /* Control Register Set 0 */ | ||
| 246 | static int TC_LSB; /* transfer counter lsb */ | ||
| 247 | static int TC_MSB; /* transfer counter msb */ | ||
| 248 | static int SCSI_FIFO; /* scsi fifo register */ | ||
| 249 | static int CMD_REG; /* command register */ | ||
| 250 | static int STAT_REG; /* status register */ | ||
| 251 | static int DEST_ID; /* selection/reselection bus id */ | ||
| 252 | static int INT_REG; /* interrupt status register */ | ||
| 253 | static int SRTIMOUT; /* select/reselect timeout reg */ | ||
| 254 | static int SEQ_REG; /* sequence step register */ | ||
| 255 | static int SYNCPRD; /* synchronous transfer period */ | ||
| 256 | static int FIFO_FLAGS; /* indicates # of bytes in fifo */ | ||
| 257 | static int SYNCOFF; /* synchronous offset register */ | ||
| 258 | static int CONFIG1; /* configuration register */ | ||
| 259 | static int CLKCONV; /* clock conversion reg */ | ||
| 260 | /*static int TESTREG;*//* test mode register */ | ||
| 261 | static int CONFIG2; /* Configuration 2 Register */ | ||
| 262 | static int CONFIG3; /* Configuration 3 Register */ | ||
| 263 | static int CONFIG4; /* Configuration 4 Register */ | ||
| 264 | static int TC_HIGH; /* Transfer Counter High */ | ||
| 265 | /*static int FIFO_BOTTOM;*//* Reserve FIFO byte register */ | ||
| 266 | |||
| 267 | /* Control Register Set 1 */ | ||
| 268 | /*static int JUMPER_SENSE;*//* Jumper sense port reg (r/w) */ | ||
| 269 | /*static int SRAM_PTR;*//* SRAM address pointer reg (r/w) */ | ||
| 270 | /*static int SRAM_DATA;*//* SRAM data register (r/w) */ | ||
| 271 | static int PIO_FIFO; /* PIO FIFO registers (r/w) */ | ||
| 272 | /*static int PIO_FIFO1;*//* */ | ||
| 273 | /*static int PIO_FIFO2;*//* */ | ||
| 274 | /*static int PIO_FIFO3;*//* */ | ||
| 275 | static int PIO_STATUS; /* PIO status (r/w) */ | ||
| 276 | /*static int ATA_CMD;*//* ATA command/status reg (r/w) */ | ||
| 277 | /*static int ATA_ERR;*//* ATA features/error register (r/w) */ | ||
| 278 | static int PIO_FLAG; /* PIO flag interrupt enable (r/w) */ | ||
| 279 | static int CONFIG5; /* Configuration 5 register (r/w) */ | ||
| 280 | /*static int SIGNATURE;*//* Signature Register (r) */ | ||
| 281 | /*static int CONFIG6;*//* Configuration 6 register (r) */ | ||
| 282 | |||
| 283 | /* ============================================================== */ | ||
| 284 | |||
| 285 | #if USE_DMA | ||
| 286 | static __inline__ int NCR53c406a_dma_setup(unsigned char *ptr, unsigned int count, unsigned char mode) | ||
| 287 | { | ||
| 288 | unsigned limit; | ||
| 289 | unsigned long flags = 0; | ||
| 290 | |||
| 291 | VDEB(printk("dma: before count=%d ", count)); | ||
| 292 | if (dma_chan <= 3) { | ||
| 293 | if (count > 65536) | ||
| 294 | count = 65536; | ||
| 295 | limit = 65536 - (((unsigned) ptr) & 0xFFFF); | ||
| 296 | } else { | ||
| 297 | if (count > (65536 << 1)) | ||
| 298 | count = (65536 << 1); | ||
| 299 | limit = (65536 << 1) - (((unsigned) ptr) & 0x1FFFF); | ||
| 300 | } | ||
| 301 | |||
| 302 | if (count > limit) | ||
| 303 | count = limit; | ||
| 304 | |||
| 305 | VDEB(printk("after count=%d\n", count)); | ||
| 306 | if ((count & 1) || (((unsigned) ptr) & 1)) | ||
| 307 | panic("NCR53c406a: attempted unaligned DMA transfer\n"); | ||
| 308 | |||
| 309 | flags = claim_dma_lock(); | ||
| 310 | disable_dma(dma_chan); | ||
| 311 | clear_dma_ff(dma_chan); | ||
| 312 | set_dma_addr(dma_chan, (long) ptr); | ||
| 313 | set_dma_count(dma_chan, count); | ||
| 314 | set_dma_mode(dma_chan, mode); | ||
| 315 | enable_dma(dma_chan); | ||
| 316 | release_dma_lock(flags); | ||
| 317 | |||
| 318 | return count; | ||
| 319 | } | ||
| 320 | |||
| 321 | static __inline__ int NCR53c406a_dma_write(unsigned char *src, unsigned int count) | ||
| 322 | { | ||
| 323 | return NCR53c406a_dma_setup(src, count, DMA_MODE_WRITE); | ||
| 324 | } | ||
| 325 | |||
| 326 | static __inline__ int NCR53c406a_dma_read(unsigned char *src, unsigned int count) | ||
| 327 | { | ||
| 328 | return NCR53c406a_dma_setup(src, count, DMA_MODE_READ); | ||
| 329 | } | ||
| 330 | |||
| 331 | static __inline__ int NCR53c406a_dma_residual(void) | ||
| 332 | { | ||
| 333 | register int tmp; | ||
| 334 | unsigned long flags; | ||
| 335 | |||
| 336 | flags = claim_dma_lock(); | ||
| 337 | clear_dma_ff(dma_chan); | ||
| 338 | tmp = get_dma_residue(dma_chan); | ||
| 339 | release_dma_lock(flags); | ||
| 340 | |||
| 341 | return tmp; | ||
| 342 | } | ||
| 343 | #endif /* USE_DMA */ | ||
| 344 | |||
| 345 | #if USE_PIO | ||
| 346 | static __inline__ int NCR53c406a_pio_read(unsigned char *request, unsigned int reqlen) | ||
| 347 | { | ||
| 348 | int i; | ||
| 349 | int len; /* current scsi fifo size */ | ||
| 350 | |||
| 351 | REG1; | ||
| 352 | while (reqlen) { | ||
| 353 | i = inb(PIO_STATUS); | ||
| 354 | /* VDEB(printk("pio_status=%x\n", i)); */ | ||
| 355 | if (i & 0x80) | ||
| 356 | return 0; | ||
| 357 | |||
| 358 | switch (i & 0x1e) { | ||
| 359 | default: | ||
| 360 | case 0x10: | ||
| 361 | len = 0; | ||
| 362 | break; | ||
| 363 | case 0x0: | ||
| 364 | len = 1; | ||
| 365 | break; | ||
| 366 | case 0x8: | ||
| 367 | len = 42; | ||
| 368 | break; | ||
| 369 | case 0xc: | ||
| 370 | len = 84; | ||
| 371 | break; | ||
| 372 | case 0xe: | ||
| 373 | len = 128; | ||
| 374 | break; | ||
| 375 | } | ||
| 376 | |||
| 377 | if ((i & 0x40) && len == 0) { /* fifo empty and interrupt occurred */ | ||
| 378 | return 0; | ||
| 379 | } | ||
| 380 | |||
| 381 | if (len) { | ||
| 382 | if (len > reqlen) | ||
| 383 | len = reqlen; | ||
| 384 | |||
| 385 | if (fast_pio && len > 3) { | ||
| 386 | insl(PIO_FIFO, request, len >> 2); | ||
| 387 | request += len & 0xfc; | ||
| 388 | reqlen -= len & 0xfc; | ||
| 389 | } else { | ||
| 390 | while (len--) { | ||
| 391 | *request++ = inb(PIO_FIFO); | ||
| 392 | reqlen--; | ||
| 393 | } | ||
| 394 | } | ||
| 395 | } | ||
| 396 | } | ||
| 397 | return 0; | ||
| 398 | } | ||
| 399 | |||
| 400 | static __inline__ int NCR53c406a_pio_write(unsigned char *request, unsigned int reqlen) | ||
| 401 | { | ||
| 402 | int i = 0; | ||
| 403 | int len; /* current scsi fifo size */ | ||
| 404 | |||
| 405 | REG1; | ||
| 406 | while (reqlen && !(i & 0x40)) { | ||
| 407 | i = inb(PIO_STATUS); | ||
| 408 | /* VDEB(printk("pio_status=%x\n", i)); */ | ||
| 409 | if (i & 0x80) /* error */ | ||
| 410 | return 0; | ||
| 411 | |||
| 412 | switch (i & 0x1e) { | ||
| 413 | case 0x10: | ||
| 414 | len = 128; | ||
| 415 | break; | ||
| 416 | case 0x0: | ||
| 417 | len = 84; | ||
| 418 | break; | ||
| 419 | case 0x8: | ||
| 420 | len = 42; | ||
| 421 | break; | ||
| 422 | case 0xc: | ||
| 423 | len = 1; | ||
| 424 | break; | ||
| 425 | default: | ||
| 426 | case 0xe: | ||
| 427 | len = 0; | ||
| 428 | break; | ||
| 429 | } | ||
| 430 | |||
| 431 | if (len) { | ||
| 432 | if (len > reqlen) | ||
| 433 | len = reqlen; | ||
| 434 | |||
| 435 | if (fast_pio && len > 3) { | ||
| 436 | outsl(PIO_FIFO, request, len >> 2); | ||
| 437 | request += len & 0xfc; | ||
| 438 | reqlen -= len & 0xfc; | ||
| 439 | } else { | ||
| 440 | while (len--) { | ||
| 441 | outb(*request++, PIO_FIFO); | ||
| 442 | reqlen--; | ||
| 443 | } | ||
| 444 | } | ||
| 445 | } | ||
| 446 | } | ||
| 447 | return 0; | ||
| 448 | } | ||
| 449 | #endif /* USE_PIO */ | ||
| 450 | |||
| 451 | static int __init NCR53c406a_detect(struct scsi_host_template * tpnt) | ||
| 452 | { | ||
| 453 | int present = 0; | ||
| 454 | struct Scsi_Host *shpnt = NULL; | ||
| 455 | #ifndef PORT_BASE | ||
| 456 | int i; | ||
| 457 | #endif | ||
| 458 | |||
| 459 | #if USE_BIOS | ||
| 460 | int ii, jj; | ||
| 461 | bios_base = 0; | ||
| 462 | /* look for a valid signature */ | ||
| 463 | for (ii = 0; ii < ADDRESS_COUNT && !bios_base; ii++) | ||
| 464 | for (jj = 0; (jj < SIGNATURE_COUNT) && !bios_base; jj++) | ||
| 465 | if (!memcmp((void *) addresses[ii] + signatures[jj].sig_offset, (void *) signatures[jj].signature, (int) signatures[jj].sig_length)) | ||
| 466 | bios_base = addresses[ii]; | ||
| 467 | |||
| 468 | if (!bios_base) { | ||
| 469 | printk("NCR53c406a: BIOS signature not found\n"); | ||
| 470 | return 0; | ||
| 471 | } | ||
| 472 | |||
| 473 | DEB(printk("NCR53c406a BIOS found at 0x%x\n", (unsigned int) bios_base); | ||
| 474 | ); | ||
| 475 | #endif /* USE_BIOS */ | ||
| 476 | |||
| 477 | #ifdef PORT_BASE | ||
| 478 | if (!request_region(port_base, 0x10, "NCR53c406a")) /* ports already snatched */ | ||
| 479 | port_base = 0; | ||
| 480 | |||
| 481 | #else /* autodetect */ | ||
| 482 | if (port_base) { /* LILO override */ | ||
| 483 | if (!request_region(port_base, 0x10, "NCR53c406a")) | ||
| 484 | port_base = 0; | ||
| 485 | } else { | ||
| 486 | for (i = 0; i < PORT_COUNT && !port_base; i++) { | ||
| 487 | if (!request_region(ports[i], 0x10, "NCR53c406a")) { | ||
| 488 | DEB(printk("NCR53c406a: port 0x%x in use\n", ports[i])); | ||
| 489 | } else { | ||
| 490 | VDEB(printk("NCR53c406a: port 0x%x available\n", ports[i])); | ||
| 491 | outb(C5_IMG, ports[i] + 0x0d); /* reg set 1 */ | ||
| 492 | if ((inb(ports[i] + 0x0e) ^ inb(ports[i] + 0x0e)) == 7 && (inb(ports[i] + 0x0e) ^ inb(ports[i] + 0x0e)) == 7 && (inb(ports[i] + 0x0e) & 0xf8) == 0x58) { | ||
| 493 | port_base = ports[i]; | ||
| 494 | VDEB(printk("NCR53c406a: Sig register valid\n")); | ||
| 495 | VDEB(printk("port_base=0x%x\n", port_base)); | ||
| 496 | break; | ||
| 497 | } | ||
| 498 | release_region(ports[i], 0x10); | ||
| 499 | } | ||
| 500 | } | ||
| 501 | } | ||
| 502 | #endif /* PORT_BASE */ | ||
| 503 | |||
| 504 | if (!port_base) { /* no ports found */ | ||
| 505 | printk("NCR53c406a: no available ports found\n"); | ||
| 506 | return 0; | ||
| 507 | } | ||
| 508 | |||
| 509 | DEB(printk("NCR53c406a detected\n")); | ||
| 510 | |||
| 511 | calc_port_addr(); | ||
| 512 | chip_init(); | ||
| 513 | |||
| 514 | #ifndef IRQ_LEV | ||
| 515 | if (irq_level < 0) { /* LILO override if >= 0 */ | ||
| 516 | irq_level = irq_probe(); | ||
| 517 | if (irq_level < 0) { /* Trouble */ | ||
| 518 | printk("NCR53c406a: IRQ problem, irq_level=%d, giving up\n", irq_level); | ||
| 519 | goto err_release; | ||
| 520 | } | ||
| 521 | } | ||
| 522 | #endif | ||
| 523 | |||
| 524 | DEB(printk("NCR53c406a: using port_base 0x%x\n", port_base)); | ||
| 525 | |||
| 526 | present = 1; | ||
| 527 | tpnt->proc_name = "NCR53c406a"; | ||
| 528 | |||
| 529 | shpnt = scsi_register(tpnt, 0); | ||
| 530 | if (!shpnt) { | ||
| 531 | printk("NCR53c406a: Unable to register host, giving up.\n"); | ||
| 532 | goto err_release; | ||
| 533 | } | ||
| 534 | |||
| 535 | if (irq_level > 0) { | ||
| 536 | if (request_irq(irq_level, do_NCR53c406a_intr, 0, "NCR53c406a", shpnt)) { | ||
| 537 | printk("NCR53c406a: unable to allocate IRQ %d\n", irq_level); | ||
| 538 | goto err_free_scsi; | ||
| 539 | } | ||
| 540 | tpnt->can_queue = 1; | ||
| 541 | DEB(printk("NCR53c406a: allocated IRQ %d\n", irq_level)); | ||
| 542 | } else if (irq_level == 0) { | ||
| 543 | tpnt->can_queue = 0; | ||
| 544 | DEB(printk("NCR53c406a: No interrupts detected\n")); | ||
| 545 | printk("NCR53c406a driver no longer supports polling interface\n"); | ||
| 546 | printk("Please email linux-scsi@vger.kernel.org\n"); | ||
| 547 | |||
| 548 | #if USE_DMA | ||
| 549 | printk("NCR53c406a: No interrupts found and DMA mode defined. Giving up.\n"); | ||
| 550 | #endif /* USE_DMA */ | ||
| 551 | goto err_free_scsi; | ||
| 552 | } else { | ||
| 553 | DEB(printk("NCR53c406a: Shouldn't get here!\n")); | ||
| 554 | goto err_free_scsi; | ||
| 555 | } | ||
| 556 | |||
| 557 | #if USE_DMA | ||
| 558 | dma_chan = DMA_CHAN; | ||
| 559 | if (request_dma(dma_chan, "NCR53c406a") != 0) { | ||
| 560 | printk("NCR53c406a: unable to allocate DMA channel %d\n", dma_chan); | ||
| 561 | goto err_free_irq; | ||
| 562 | } | ||
| 563 | |||
| 564 | DEB(printk("Allocated DMA channel %d\n", dma_chan)); | ||
| 565 | #endif /* USE_DMA */ | ||
| 566 | |||
| 567 | shpnt->irq = irq_level; | ||
| 568 | shpnt->io_port = port_base; | ||
| 569 | shpnt->n_io_port = 0x10; | ||
| 570 | #if USE_DMA | ||
| 571 | shpnt->dma = dma_chan; | ||
| 572 | #endif | ||
| 573 | |||
| 574 | #if USE_DMA | ||
| 575 | sprintf(info_msg, "NCR53c406a at 0x%x, IRQ %d, DMA channel %d.", port_base, irq_level, dma_chan); | ||
| 576 | #else | ||
| 577 | sprintf(info_msg, "NCR53c406a at 0x%x, IRQ %d, %s PIO mode.", port_base, irq_level, fast_pio ? "fast" : "slow"); | ||
| 578 | #endif | ||
| 579 | |||
| 580 | return (present); | ||
| 581 | |||
| 582 | #if USE_DMA | ||
| 583 | err_free_irq: | ||
| 584 | if (irq_level) | ||
| 585 | free_irq(irq_level, shpnt); | ||
| 586 | #endif | ||
| 587 | err_free_scsi: | ||
| 588 | scsi_unregister(shpnt); | ||
| 589 | err_release: | ||
| 590 | release_region(port_base, 0x10); | ||
| 591 | return 0; | ||
| 592 | } | ||
| 593 | |||
| 594 | static int NCR53c406a_release(struct Scsi_Host *shost) | ||
| 595 | { | ||
| 596 | if (shost->irq) | ||
| 597 | free_irq(shost->irq, NULL); | ||
| 598 | #if USE_DMA | ||
| 599 | if (shost->dma_channel != 0xff) | ||
| 600 | free_dma(shost->dma_channel); | ||
| 601 | #endif | ||
| 602 | if (shost->io_port && shost->n_io_port) | ||
| 603 | release_region(shost->io_port, shost->n_io_port); | ||
| 604 | |||
| 605 | scsi_unregister(shost); | ||
| 606 | return 0; | ||
| 607 | } | ||
| 608 | |||
| 609 | #ifndef MODULE | ||
| 610 | /* called from init/main.c */ | ||
| 611 | static int __init NCR53c406a_setup(char *str) | ||
| 612 | { | ||
| 613 | static size_t setup_idx = 0; | ||
| 614 | size_t i; | ||
| 615 | int ints[4]; | ||
| 616 | |||
| 617 | DEB(printk("NCR53c406a: Setup called\n"); | ||
| 618 | ); | ||
| 619 | |||
| 620 | if (setup_idx >= PORT_COUNT - 1) { | ||
| 621 | printk("NCR53c406a: Setup called too many times. Bad LILO params?\n"); | ||
| 622 | return 0; | ||
| 623 | } | ||
| 624 | get_options(str, 4, ints); | ||
| 625 | if (ints[0] < 1 || ints[0] > 3) { | ||
| 626 | printk("NCR53c406a: Malformed command line\n"); | ||
| 627 | printk("NCR53c406a: Usage: ncr53c406a=<PORTBASE>[,<IRQ>[,<FASTPIO>]]\n"); | ||
| 628 | return 0; | ||
| 629 | } | ||
| 630 | for (i = 0; i < PORT_COUNT && !port_base; i++) | ||
| 631 | if (ports[i] == ints[1]) { | ||
| 632 | port_base = ints[1]; | ||
| 633 | DEB(printk("NCR53c406a: Specified port_base 0x%x\n", port_base); | ||
| 634 | ) | ||
| 635 | } | ||
| 636 | if (!port_base) { | ||
| 637 | printk("NCR53c406a: Invalid PORTBASE 0x%x specified\n", ints[1]); | ||
| 638 | return 0; | ||
| 639 | } | ||
| 640 | |||
| 641 | if (ints[0] > 1) { | ||
| 642 | if (ints[2] == 0) { | ||
| 643 | irq_level = 0; | ||
| 644 | DEB(printk("NCR53c406a: Specified irq %d\n", irq_level); | ||
| 645 | ) | ||
| 646 | } else | ||
| 647 | for (i = 0; i < INTR_COUNT && irq_level < 0; i++) | ||
| 648 | if (intrs[i] == ints[2]) { | ||
| 649 | irq_level = ints[2]; | ||
| 650 | DEB(printk("NCR53c406a: Specified irq %d\n", port_base); | ||
| 651 | ) | ||
| 652 | } | ||
| 653 | if (irq_level < 0) | ||
| 654 | printk("NCR53c406a: Invalid IRQ %d specified\n", ints[2]); | ||
| 655 | } | ||
| 656 | |||
| 657 | if (ints[0] > 2) | ||
| 658 | fast_pio = ints[3]; | ||
| 659 | |||
| 660 | DEB(printk("NCR53c406a: port_base=0x%x, irq=%d, fast_pio=%d\n", port_base, irq_level, fast_pio);) | ||
| 661 | return 1; | ||
| 662 | } | ||
| 663 | |||
| 664 | __setup("ncr53c406a=", NCR53c406a_setup); | ||
| 665 | |||
| 666 | #endif /* !MODULE */ | ||
| 667 | |||
| 668 | static const char *NCR53c406a_info(struct Scsi_Host *SChost) | ||
| 669 | { | ||
| 670 | DEB(printk("NCR53c406a_info called\n")); | ||
| 671 | return (info_msg); | ||
| 672 | } | ||
| 673 | |||
| 674 | #if 0 | ||
| 675 | static void wait_intr(void) | ||
| 676 | { | ||
| 677 | unsigned long i = jiffies + WATCHDOG; | ||
| 678 | |||
| 679 | while (time_after(i, jiffies) && !(inb(STAT_REG) & 0xe0)) { /* wait for a pseudo-interrupt */ | ||
| 680 | cpu_relax(); | ||
| 681 | barrier(); | ||
| 682 | } | ||
| 683 | |||
| 684 | if (time_before_eq(i, jiffies)) { /* Timed out */ | ||
| 685 | rtrc(0); | ||
| 686 | current_SC->result = DID_TIME_OUT << 16; | ||
| 687 | current_SC->SCp.phase = idle; | ||
| 688 | current_SC->scsi_done(current_SC); | ||
| 689 | return; | ||
| 690 | } | ||
| 691 | |||
| 692 | NCR53c406a_intr(NULL); | ||
| 693 | } | ||
| 694 | #endif | ||
| 695 | |||
| 696 | static int NCR53c406a_queue_lck(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *)) | ||
| 697 | { | ||
| 698 | int i; | ||
| 699 | |||
| 700 | VDEB(printk("NCR53c406a_queue called\n")); | ||
| 701 | DEB(printk("cmd=%02x, cmd_len=%02x, target=%02x, lun=%02x, bufflen=%d\n", SCpnt->cmnd[0], SCpnt->cmd_len, SCpnt->device->target, (u8)SCpnt->device->lun, scsi_bufflen(SCpnt))); | ||
| 702 | |||
| 703 | #if 0 | ||
| 704 | VDEB(for (i = 0; i < SCpnt->cmd_len; i++) | ||
| 705 | printk("cmd[%d]=%02x ", i, SCpnt->cmnd[i])); | ||
| 706 | VDEB(printk("\n")); | ||
| 707 | #endif | ||
| 708 | |||
| 709 | current_SC = SCpnt; | ||
| 710 | current_SC->scsi_done = done; | ||
| 711 | current_SC->SCp.phase = command_ph; | ||
| 712 | current_SC->SCp.Status = 0; | ||
| 713 | current_SC->SCp.Message = 0; | ||
| 714 | |||
| 715 | /* We are locked here already by the mid layer */ | ||
| 716 | REG0; | ||
| 717 | outb(scmd_id(SCpnt), DEST_ID); /* set destination */ | ||
| 718 | outb(FLUSH_FIFO, CMD_REG); /* reset the fifos */ | ||
| 719 | |||
| 720 | for (i = 0; i < SCpnt->cmd_len; i++) { | ||
| 721 | outb(SCpnt->cmnd[i], SCSI_FIFO); | ||
| 722 | } | ||
| 723 | outb(SELECT_NO_ATN, CMD_REG); | ||
| 724 | |||
| 725 | rtrc(1); | ||
| 726 | return 0; | ||
| 727 | } | ||
| 728 | |||
| 729 | static DEF_SCSI_QCMD(NCR53c406a_queue) | ||
| 730 | |||
| 731 | static int NCR53c406a_host_reset(Scsi_Cmnd * SCpnt) | ||
| 732 | { | ||
| 733 | DEB(printk("NCR53c406a_reset called\n")); | ||
| 734 | |||
| 735 | spin_lock_irq(SCpnt->device->host->host_lock); | ||
| 736 | |||
| 737 | outb(C4_IMG, CONFIG4); /* Select reg set 0 */ | ||
| 738 | outb(CHIP_RESET, CMD_REG); | ||
| 739 | outb(SCSI_NOP, CMD_REG); /* required after reset */ | ||
| 740 | outb(SCSI_RESET, CMD_REG); | ||
| 741 | chip_init(); | ||
| 742 | |||
| 743 | rtrc(2); | ||
| 744 | |||
| 745 | spin_unlock_irq(SCpnt->device->host->host_lock); | ||
| 746 | |||
| 747 | return SUCCESS; | ||
| 748 | } | ||
| 749 | |||
| 750 | static int NCR53c406a_biosparm(struct scsi_device *disk, | ||
| 751 | struct block_device *dev, | ||
| 752 | sector_t capacity, int *info_array) | ||
| 753 | { | ||
| 754 | int size; | ||
| 755 | |||
| 756 | DEB(printk("NCR53c406a_biosparm called\n")); | ||
| 757 | |||
| 758 | size = capacity; | ||
| 759 | info_array[0] = 64; /* heads */ | ||
| 760 | info_array[1] = 32; /* sectors */ | ||
| 761 | info_array[2] = size >> 11; /* cylinders */ | ||
| 762 | if (info_array[2] > 1024) { /* big disk */ | ||
| 763 | info_array[0] = 255; | ||
| 764 | info_array[1] = 63; | ||
| 765 | info_array[2] = size / (255 * 63); | ||
| 766 | } | ||
| 767 | return 0; | ||
| 768 | } | ||
| 769 | |||
| 770 | static irqreturn_t do_NCR53c406a_intr(int unused, void *dev_id) | ||
| 771 | { | ||
| 772 | unsigned long flags; | ||
| 773 | struct Scsi_Host *dev = dev_id; | ||
| 774 | |||
| 775 | spin_lock_irqsave(dev->host_lock, flags); | ||
| 776 | NCR53c406a_intr(dev_id); | ||
| 777 | spin_unlock_irqrestore(dev->host_lock, flags); | ||
| 778 | return IRQ_HANDLED; | ||
| 779 | } | ||
| 780 | |||
| 781 | static void NCR53c406a_intr(void *dev_id) | ||
| 782 | { | ||
| 783 | DEB(unsigned char fifo_size; | ||
| 784 | ) | ||
| 785 | DEB(unsigned char seq_reg; | ||
| 786 | ) | ||
| 787 | unsigned char status, int_reg; | ||
| 788 | #if USE_PIO | ||
| 789 | unsigned char pio_status; | ||
| 790 | struct scatterlist *sg; | ||
| 791 | int i; | ||
| 792 | #endif | ||
| 793 | |||
| 794 | VDEB(printk("NCR53c406a_intr called\n")); | ||
| 795 | |||
| 796 | #if USE_PIO | ||
| 797 | REG1; | ||
| 798 | pio_status = inb(PIO_STATUS); | ||
| 799 | #endif | ||
| 800 | REG0; | ||
| 801 | status = inb(STAT_REG); | ||
| 802 | DEB(seq_reg = inb(SEQ_REG)); | ||
| 803 | int_reg = inb(INT_REG); | ||
| 804 | DEB(fifo_size = inb(FIFO_FLAGS) & 0x1f); | ||
| 805 | |||
| 806 | #if NCR53C406A_DEBUG | ||
| 807 | printk("status=%02x, seq_reg=%02x, int_reg=%02x, fifo_size=%02x", status, seq_reg, int_reg, fifo_size); | ||
| 808 | #if (USE_DMA) | ||
| 809 | printk("\n"); | ||
| 810 | #else | ||
| 811 | printk(", pio=%02x\n", pio_status); | ||
| 812 | #endif /* USE_DMA */ | ||
| 813 | #endif /* NCR53C406A_DEBUG */ | ||
| 814 | |||
| 815 | if (int_reg & 0x80) { /* SCSI reset intr */ | ||
| 816 | rtrc(3); | ||
| 817 | DEB(printk("NCR53c406a: reset intr received\n")); | ||
| 818 | current_SC->SCp.phase = idle; | ||
| 819 | current_SC->result = DID_RESET << 16; | ||
| 820 | current_SC->scsi_done(current_SC); | ||
| 821 | return; | ||
| 822 | } | ||
| 823 | #if USE_PIO | ||
| 824 | if (pio_status & 0x80) { | ||
| 825 | printk("NCR53C406A: Warning: PIO error!\n"); | ||
| 826 | current_SC->SCp.phase = idle; | ||
| 827 | current_SC->result = DID_ERROR << 16; | ||
| 828 | current_SC->scsi_done(current_SC); | ||
| 829 | return; | ||
| 830 | } | ||
| 831 | #endif /* USE_PIO */ | ||
| 832 | |||
| 833 | if (status & 0x20) { /* Parity error */ | ||
| 834 | printk("NCR53c406a: Warning: parity error!\n"); | ||
| 835 | current_SC->SCp.phase = idle; | ||
| 836 | current_SC->result = DID_PARITY << 16; | ||
| 837 | current_SC->scsi_done(current_SC); | ||
| 838 | return; | ||
| 839 | } | ||
| 840 | |||
| 841 | if (status & 0x40) { /* Gross error */ | ||
| 842 | printk("NCR53c406a: Warning: gross error!\n"); | ||
| 843 | current_SC->SCp.phase = idle; | ||
| 844 | current_SC->result = DID_ERROR << 16; | ||
| 845 | current_SC->scsi_done(current_SC); | ||
| 846 | return; | ||
| 847 | } | ||
| 848 | |||
| 849 | if (int_reg & 0x20) { /* Disconnect */ | ||
| 850 | DEB(printk("NCR53c406a: disconnect intr received\n")); | ||
| 851 | if (current_SC->SCp.phase != message_in) { /* Unexpected disconnect */ | ||
| 852 | current_SC->result = DID_NO_CONNECT << 16; | ||
| 853 | } else { /* Command complete, return status and message */ | ||
| 854 | current_SC->result = (current_SC->SCp.Status & 0xff) | ||
| 855 | | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16); | ||
| 856 | } | ||
| 857 | |||
| 858 | rtrc(0); | ||
| 859 | current_SC->SCp.phase = idle; | ||
| 860 | current_SC->scsi_done(current_SC); | ||
| 861 | return; | ||
| 862 | } | ||
| 863 | |||
| 864 | switch (status & 0x07) { /* scsi phase */ | ||
| 865 | case 0x00: /* DATA-OUT */ | ||
| 866 | if (int_reg & 0x10) { /* Target requesting info transfer */ | ||
| 867 | rtrc(5); | ||
| 868 | current_SC->SCp.phase = data_out; | ||
| 869 | VDEB(printk("NCR53c406a: Data-Out phase\n")); | ||
| 870 | outb(FLUSH_FIFO, CMD_REG); | ||
| 871 | LOAD_DMA_COUNT(scsi_bufflen(current_SC)); /* Max transfer size */ | ||
| 872 | #if USE_DMA /* No s/g support for DMA */ | ||
| 873 | NCR53c406a_dma_write(scsi_sglist(current_SC), | ||
| 874 | scsdi_bufflen(current_SC)); | ||
| 875 | |||
| 876 | #endif /* USE_DMA */ | ||
| 877 | outb(TRANSFER_INFO | DMA_OP, CMD_REG); | ||
| 878 | #if USE_PIO | ||
| 879 | scsi_for_each_sg(current_SC, sg, scsi_sg_count(current_SC), i) { | ||
| 880 | NCR53c406a_pio_write(sg_virt(sg), sg->length); | ||
| 881 | } | ||
| 882 | REG0; | ||
| 883 | #endif /* USE_PIO */ | ||
| 884 | } | ||
| 885 | break; | ||
| 886 | |||
| 887 | case 0x01: /* DATA-IN */ | ||
| 888 | if (int_reg & 0x10) { /* Target requesting info transfer */ | ||
| 889 | rtrc(6); | ||
| 890 | current_SC->SCp.phase = data_in; | ||
| 891 | VDEB(printk("NCR53c406a: Data-In phase\n")); | ||
| 892 | outb(FLUSH_FIFO, CMD_REG); | ||
| 893 | LOAD_DMA_COUNT(scsi_bufflen(current_SC)); /* Max transfer size */ | ||
| 894 | #if USE_DMA /* No s/g support for DMA */ | ||
| 895 | NCR53c406a_dma_read(scsi_sglist(current_SC), | ||
| 896 | scsdi_bufflen(current_SC)); | ||
| 897 | #endif /* USE_DMA */ | ||
| 898 | outb(TRANSFER_INFO | DMA_OP, CMD_REG); | ||
| 899 | #if USE_PIO | ||
| 900 | scsi_for_each_sg(current_SC, sg, scsi_sg_count(current_SC), i) { | ||
| 901 | NCR53c406a_pio_read(sg_virt(sg), sg->length); | ||
| 902 | } | ||
| 903 | REG0; | ||
| 904 | #endif /* USE_PIO */ | ||
| 905 | } | ||
| 906 | break; | ||
| 907 | |||
| 908 | case 0x02: /* COMMAND */ | ||
| 909 | current_SC->SCp.phase = command_ph; | ||
| 910 | printk("NCR53c406a: Warning: Unknown interrupt occurred in command phase!\n"); | ||
| 911 | break; | ||
| 912 | |||
| 913 | case 0x03: /* STATUS */ | ||
| 914 | rtrc(7); | ||
| 915 | current_SC->SCp.phase = status_ph; | ||
| 916 | VDEB(printk("NCR53c406a: Status phase\n")); | ||
| 917 | outb(FLUSH_FIFO, CMD_REG); | ||
| 918 | outb(INIT_CMD_COMPLETE, CMD_REG); | ||
| 919 | break; | ||
| 920 | |||
| 921 | case 0x04: /* Reserved */ | ||
| 922 | case 0x05: /* Reserved */ | ||
| 923 | printk("NCR53c406a: WARNING: Reserved phase!!!\n"); | ||
| 924 | break; | ||
| 925 | |||
| 926 | case 0x06: /* MESSAGE-OUT */ | ||
| 927 | DEB(printk("NCR53c406a: Message-Out phase\n")); | ||
| 928 | current_SC->SCp.phase = message_out; | ||
| 929 | outb(SET_ATN, CMD_REG); /* Reject the message */ | ||
| 930 | outb(MSG_ACCEPT, CMD_REG); | ||
| 931 | break; | ||
| 932 | |||
| 933 | case 0x07: /* MESSAGE-IN */ | ||
| 934 | rtrc(4); | ||
| 935 | VDEB(printk("NCR53c406a: Message-In phase\n")); | ||
| 936 | current_SC->SCp.phase = message_in; | ||
| 937 | |||
| 938 | current_SC->SCp.Status = inb(SCSI_FIFO); | ||
| 939 | current_SC->SCp.Message = inb(SCSI_FIFO); | ||
| 940 | |||
| 941 | VDEB(printk("SCSI FIFO size=%d\n", inb(FIFO_FLAGS) & 0x1f)); | ||
| 942 | DEB(printk("Status = %02x Message = %02x\n", current_SC->SCp.Status, current_SC->SCp.Message)); | ||
| 943 | |||
| 944 | if (current_SC->SCp.Message == SAVE_POINTERS || current_SC->SCp.Message == DISCONNECT) { | ||
| 945 | outb(SET_ATN, CMD_REG); /* Reject message */ | ||
| 946 | DEB(printk("Discarding SAVE_POINTERS message\n")); | ||
| 947 | } | ||
| 948 | outb(MSG_ACCEPT, CMD_REG); | ||
| 949 | break; | ||
| 950 | } | ||
| 951 | } | ||
| 952 | |||
| 953 | #ifndef IRQ_LEV | ||
| 954 | static int irq_probe(void) | ||
| 955 | { | ||
| 956 | int irqs, irq; | ||
| 957 | unsigned long i; | ||
| 958 | |||
| 959 | inb(INT_REG); /* clear the interrupt register */ | ||
| 960 | irqs = probe_irq_on(); | ||
| 961 | |||
| 962 | /* Invalid command will cause an interrupt */ | ||
| 963 | REG0; | ||
| 964 | outb(0xff, CMD_REG); | ||
| 965 | |||
| 966 | /* Wait for the interrupt to occur */ | ||
| 967 | i = jiffies + WATCHDOG; | ||
| 968 | while (time_after(i, jiffies) && !(inb(STAT_REG) & 0x80)) | ||
| 969 | barrier(); | ||
| 970 | if (time_before_eq(i, jiffies)) { /* Timed out, must be hardware trouble */ | ||
| 971 | probe_irq_off(irqs); | ||
| 972 | return -1; | ||
| 973 | } | ||
| 974 | |||
| 975 | irq = probe_irq_off(irqs); | ||
| 976 | |||
| 977 | /* Kick the chip */ | ||
| 978 | outb(CHIP_RESET, CMD_REG); | ||
| 979 | outb(SCSI_NOP, CMD_REG); | ||
| 980 | chip_init(); | ||
| 981 | |||
| 982 | return irq; | ||
| 983 | } | ||
| 984 | #endif /* IRQ_LEV */ | ||
| 985 | |||
| 986 | static void chip_init(void) | ||
| 987 | { | ||
| 988 | REG1; | ||
| 989 | #if USE_DMA | ||
| 990 | outb(0x00, PIO_STATUS); | ||
| 991 | #else /* USE_PIO */ | ||
| 992 | outb(0x01, PIO_STATUS); | ||
| 993 | #endif | ||
| 994 | outb(0x00, PIO_FLAG); | ||
| 995 | |||
| 996 | outb(C4_IMG, CONFIG4); /* REG0; */ | ||
| 997 | outb(C3_IMG, CONFIG3); | ||
| 998 | outb(C2_IMG, CONFIG2); | ||
| 999 | outb(C1_IMG, CONFIG1); | ||
| 1000 | |||
| 1001 | outb(0x05, CLKCONV); /* clock conversion factor */ | ||
| 1002 | outb(0x9C, SRTIMOUT); /* Selection timeout */ | ||
| 1003 | outb(0x05, SYNCPRD); /* Synchronous transfer period */ | ||
| 1004 | outb(SYNC_MODE, SYNCOFF); /* synchronous mode */ | ||
| 1005 | } | ||
| 1006 | |||
| 1007 | static void __init calc_port_addr(void) | ||
| 1008 | { | ||
| 1009 | /* Control Register Set 0 */ | ||
| 1010 | TC_LSB = (port_base + 0x00); | ||
| 1011 | TC_MSB = (port_base + 0x01); | ||
| 1012 | SCSI_FIFO = (port_base + 0x02); | ||
| 1013 | CMD_REG = (port_base + 0x03); | ||
| 1014 | STAT_REG = (port_base + 0x04); | ||
| 1015 | DEST_ID = (port_base + 0x04); | ||
| 1016 | INT_REG = (port_base + 0x05); | ||
| 1017 | SRTIMOUT = (port_base + 0x05); | ||
| 1018 | SEQ_REG = (port_base + 0x06); | ||
| 1019 | SYNCPRD = (port_base + 0x06); | ||
| 1020 | FIFO_FLAGS = (port_base + 0x07); | ||
| 1021 | SYNCOFF = (port_base + 0x07); | ||
| 1022 | CONFIG1 = (port_base + 0x08); | ||
| 1023 | CLKCONV = (port_base + 0x09); | ||
| 1024 | /* TESTREG = (port_base+0x0A); */ | ||
| 1025 | CONFIG2 = (port_base + 0x0B); | ||
| 1026 | CONFIG3 = (port_base + 0x0C); | ||
| 1027 | CONFIG4 = (port_base + 0x0D); | ||
| 1028 | TC_HIGH = (port_base + 0x0E); | ||
| 1029 | /* FIFO_BOTTOM = (port_base+0x0F); */ | ||
| 1030 | |||
| 1031 | /* Control Register Set 1 */ | ||
| 1032 | /* JUMPER_SENSE = (port_base+0x00); */ | ||
| 1033 | /* SRAM_PTR = (port_base+0x01); */ | ||
| 1034 | /* SRAM_DATA = (port_base+0x02); */ | ||
| 1035 | PIO_FIFO = (port_base + 0x04); | ||
| 1036 | /* PIO_FIFO1 = (port_base+0x05); */ | ||
| 1037 | /* PIO_FIFO2 = (port_base+0x06); */ | ||
| 1038 | /* PIO_FIFO3 = (port_base+0x07); */ | ||
| 1039 | PIO_STATUS = (port_base + 0x08); | ||
| 1040 | /* ATA_CMD = (port_base+0x09); */ | ||
| 1041 | /* ATA_ERR = (port_base+0x0A); */ | ||
| 1042 | PIO_FLAG = (port_base + 0x0B); | ||
| 1043 | CONFIG5 = (port_base + 0x0D); | ||
| 1044 | /* SIGNATURE = (port_base+0x0E); */ | ||
| 1045 | /* CONFIG6 = (port_base+0x0F); */ | ||
| 1046 | } | ||
| 1047 | |||
| 1048 | MODULE_LICENSE("GPL"); | ||
| 1049 | |||
| 1050 | /* NOTE: scatter-gather support only works in PIO mode. | ||
| 1051 | * Use SG_NONE if DMA mode is enabled! | ||
| 1052 | */ | ||
| 1053 | |||
| 1054 | static struct scsi_host_template driver_template = | ||
| 1055 | { | ||
| 1056 | .proc_name = "NCR53c406a" /* proc_name */, | ||
| 1057 | .name = "NCR53c406a" /* name */, | ||
| 1058 | .detect = NCR53c406a_detect /* detect */, | ||
| 1059 | .release = NCR53c406a_release, | ||
| 1060 | .info = NCR53c406a_info /* info */, | ||
| 1061 | .queuecommand = NCR53c406a_queue /* queuecommand */, | ||
| 1062 | .eh_host_reset_handler = NCR53c406a_host_reset /* reset */, | ||
| 1063 | .bios_param = NCR53c406a_biosparm /* biosparm */, | ||
| 1064 | .can_queue = 1 /* can_queue */, | ||
| 1065 | .this_id = 7 /* SCSI ID of the chip */, | ||
| 1066 | .sg_tablesize = 32 /*SG_ALL*/ /*SG_NONE*/, | ||
| 1067 | .unchecked_isa_dma = 1 /* unchecked_isa_dma */, | ||
| 1068 | .use_clustering = ENABLE_CLUSTERING, | ||
| 1069 | }; | ||
| 1070 | |||
| 1071 | #include "scsi_module.c" | ||
| 1072 | |||
| 1073 | /* | ||
| 1074 | * Overrides for Emacs so that we get a uniform tabbing style. | ||
| 1075 | * Emacs will notice this stuff at the end of the file and automatically | ||
| 1076 | * adjust the settings for this buffer only. This must remain at the end | ||
| 1077 | * of the file. | ||
| 1078 | * --------------------------------------------------------------------------- | ||
| 1079 | * Local variables: | ||
| 1080 | * c-indent-level: 4 | ||
| 1081 | * c-brace-imaginary-offset: 0 | ||
| 1082 | * c-brace-offset: -4 | ||
| 1083 | * c-argdecl-indent: 4 | ||
| 1084 | * c-label-offset: -4 | ||
| 1085 | * c-continued-statement-offset: 4 | ||
| 1086 | * c-continued-brace-offset: 0 | ||
| 1087 | * indent-tabs-mode: nil | ||
| 1088 | * tab-width: 8 | ||
| 1089 | * End: | ||
| 1090 | */ | ||
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 0095fcbd1c88..29bf1e60f542 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h | |||
| @@ -1231,6 +1231,7 @@ struct src_registers { | |||
| 1231 | 1231 | ||
| 1232 | #define SRC_ODR_SHIFT 12 | 1232 | #define SRC_ODR_SHIFT 12 |
| 1233 | #define SRC_IDR_SHIFT 9 | 1233 | #define SRC_IDR_SHIFT 9 |
| 1234 | #define SRC_MSI_READ_MASK 0x1000 | ||
| 1234 | 1235 | ||
| 1235 | typedef void (*fib_callback)(void *ctxt, struct fib *fibctx); | 1236 | typedef void (*fib_callback)(void *ctxt, struct fib *fibctx); |
| 1236 | 1237 | ||
| @@ -1528,6 +1529,7 @@ struct aac_bus_info_response { | |||
| 1528 | #define AAC_COMM_MESSAGE_TYPE3 5 | 1529 | #define AAC_COMM_MESSAGE_TYPE3 5 |
| 1529 | 1530 | ||
| 1530 | #define AAC_EXTOPT_SA_FIRMWARE cpu_to_le32(1<<1) | 1531 | #define AAC_EXTOPT_SA_FIRMWARE cpu_to_le32(1<<1) |
| 1532 | #define AAC_EXTOPT_SOFT_RESET cpu_to_le32(1<<16) | ||
| 1531 | 1533 | ||
| 1532 | /* MSIX context */ | 1534 | /* MSIX context */ |
| 1533 | struct aac_msix_ctx { | 1535 | struct aac_msix_ctx { |
| @@ -1662,6 +1664,7 @@ struct aac_dev | |||
| 1662 | u8 raw_io_64; | 1664 | u8 raw_io_64; |
| 1663 | u8 printf_enabled; | 1665 | u8 printf_enabled; |
| 1664 | u8 in_reset; | 1666 | u8 in_reset; |
| 1667 | u8 in_soft_reset; | ||
| 1665 | u8 msi; | 1668 | u8 msi; |
| 1666 | u8 sa_firmware; | 1669 | u8 sa_firmware; |
| 1667 | int management_fib_count; | 1670 | int management_fib_count; |
| @@ -2504,6 +2507,7 @@ struct aac_hba_info { | |||
| 2504 | #define RCV_TEMP_READINGS 0x00000025 | 2507 | #define RCV_TEMP_READINGS 0x00000025 |
| 2505 | #define GET_COMM_PREFERRED_SETTINGS 0x00000026 | 2508 | #define GET_COMM_PREFERRED_SETTINGS 0x00000026 |
| 2506 | #define IOP_RESET_FW_FIB_DUMP 0x00000034 | 2509 | #define IOP_RESET_FW_FIB_DUMP 0x00000034 |
| 2510 | #define DROP_IO 0x00000035 | ||
| 2507 | #define IOP_RESET 0x00001000 | 2511 | #define IOP_RESET 0x00001000 |
| 2508 | #define IOP_RESET_ALWAYS 0x00001001 | 2512 | #define IOP_RESET_ALWAYS 0x00001001 |
| 2509 | #define RE_INIT_ADAPTER 0x000000ee | 2513 | #define RE_INIT_ADAPTER 0x000000ee |
| @@ -2539,6 +2543,7 @@ struct aac_hba_info { | |||
| 2539 | #define FLASH_UPD_PENDING 0x00002000 | 2543 | #define FLASH_UPD_PENDING 0x00002000 |
| 2540 | #define FLASH_UPD_SUCCESS 0x00004000 | 2544 | #define FLASH_UPD_SUCCESS 0x00004000 |
| 2541 | #define FLASH_UPD_FAILED 0x00008000 | 2545 | #define FLASH_UPD_FAILED 0x00008000 |
| 2546 | #define INVALID_OMR 0xffffffff | ||
| 2542 | #define FWUPD_TIMEOUT (5 * 60) | 2547 | #define FWUPD_TIMEOUT (5 * 60) |
| 2543 | 2548 | ||
| 2544 | /* | 2549 | /* |
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index a802bddf04aa..4ebb35a29caa 100644 --- a/drivers/scsi/aacraid/src.c +++ b/drivers/scsi/aacraid/src.c | |||
| @@ -255,7 +255,8 @@ static int src_sync_cmd(struct aac_dev *dev, u32 command, | |||
| 255 | */ | 255 | */ |
| 256 | src_writel(dev, MUnit.IDR, INBOUNDDOORBELL_0 << SRC_IDR_SHIFT); | 256 | src_writel(dev, MUnit.IDR, INBOUNDDOORBELL_0 << SRC_IDR_SHIFT); |
| 257 | 257 | ||
| 258 | if (!dev->sync_mode || command != SEND_SYNCHRONOUS_FIB) { | 258 | if ((!dev->sync_mode || command != SEND_SYNCHRONOUS_FIB) && |
| 259 | !dev->in_soft_reset) { | ||
| 259 | ok = 0; | 260 | ok = 0; |
| 260 | start = jiffies; | 261 | start = jiffies; |
| 261 | 262 | ||
| @@ -679,6 +680,25 @@ void aac_set_intx_mode(struct aac_dev *dev) | |||
| 679 | } | 680 | } |
| 680 | } | 681 | } |
| 681 | 682 | ||
| 683 | static void aac_clear_omr(struct aac_dev *dev) | ||
| 684 | { | ||
| 685 | u32 omr_value = 0; | ||
| 686 | |||
| 687 | omr_value = src_readl(dev, MUnit.OMR); | ||
| 688 | |||
| 689 | /* | ||
| 690 | * Check for PCI Errors or Kernel Panic | ||
| 691 | */ | ||
| 692 | if ((omr_value == INVALID_OMR) || (omr_value & KERNEL_PANIC)) | ||
| 693 | omr_value = 0; | ||
| 694 | |||
| 695 | /* | ||
| 696 | * Preserve MSIX Value if any | ||
| 697 | */ | ||
| 698 | src_writel(dev, MUnit.OMR, omr_value & AAC_INT_MODE_MSIX); | ||
| 699 | src_readl(dev, MUnit.OMR); | ||
| 700 | } | ||
| 701 | |||
| 682 | static void aac_dump_fw_fib_iop_reset(struct aac_dev *dev) | 702 | static void aac_dump_fw_fib_iop_reset(struct aac_dev *dev) |
| 683 | { | 703 | { |
| 684 | __le32 supported_options3; | 704 | __le32 supported_options3; |
| @@ -739,6 +759,8 @@ static void aac_send_iop_reset(struct aac_dev *dev) | |||
| 739 | 759 | ||
| 740 | aac_set_intx_mode(dev); | 760 | aac_set_intx_mode(dev); |
| 741 | 761 | ||
| 762 | aac_clear_omr(dev); | ||
| 763 | |||
| 742 | src_writel(dev, MUnit.IDR, IOP_SRC_RESET_MASK); | 764 | src_writel(dev, MUnit.IDR, IOP_SRC_RESET_MASK); |
| 743 | 765 | ||
| 744 | msleep(5000); | 766 | msleep(5000); |
| @@ -748,6 +770,7 @@ static void aac_send_hardware_soft_reset(struct aac_dev *dev) | |||
| 748 | { | 770 | { |
| 749 | u_int32_t val; | 771 | u_int32_t val; |
| 750 | 772 | ||
| 773 | aac_clear_omr(dev); | ||
| 751 | val = readl(((char *)(dev->base) + IBW_SWR_OFFSET)); | 774 | val = readl(((char *)(dev->base) + IBW_SWR_OFFSET)); |
| 752 | val |= 0x01; | 775 | val |= 0x01; |
| 753 | writel(val, ((char *)(dev->base) + IBW_SWR_OFFSET)); | 776 | writel(val, ((char *)(dev->base) + IBW_SWR_OFFSET)); |
| @@ -992,6 +1015,148 @@ error_iounmap: | |||
| 992 | return -1; | 1015 | return -1; |
| 993 | } | 1016 | } |
| 994 | 1017 | ||
| 1018 | static int aac_src_wait_sync(struct aac_dev *dev, int *status) | ||
| 1019 | { | ||
| 1020 | unsigned long start = jiffies; | ||
| 1021 | unsigned long usecs = 0; | ||
| 1022 | int delay = 5 * HZ; | ||
| 1023 | int rc = 1; | ||
| 1024 | |||
| 1025 | while (time_before(jiffies, start+delay)) { | ||
| 1026 | /* | ||
| 1027 | * Delay 5 microseconds to let Mon960 get info. | ||
| 1028 | */ | ||
| 1029 | udelay(5); | ||
| 1030 | |||
| 1031 | /* | ||
| 1032 | * Mon960 will set doorbell0 bit when it has completed the | ||
| 1033 | * command. | ||
| 1034 | */ | ||
| 1035 | if (aac_src_get_sync_status(dev) & OUTBOUNDDOORBELL_0) { | ||
| 1036 | /* | ||
| 1037 | * Clear: the doorbell. | ||
| 1038 | */ | ||
| 1039 | if (dev->msi_enabled) | ||
| 1040 | aac_src_access_devreg(dev, AAC_CLEAR_SYNC_BIT); | ||
| 1041 | else | ||
| 1042 | src_writel(dev, MUnit.ODR_C, | ||
| 1043 | OUTBOUNDDOORBELL_0 << SRC_ODR_SHIFT); | ||
| 1044 | rc = 0; | ||
| 1045 | |||
| 1046 | break; | ||
| 1047 | } | ||
| 1048 | |||
| 1049 | /* | ||
| 1050 | * Yield the processor in case we are slow | ||
| 1051 | */ | ||
| 1052 | usecs = 1 * USEC_PER_MSEC; | ||
| 1053 | usleep_range(usecs, usecs + 50); | ||
| 1054 | } | ||
| 1055 | /* | ||
| 1056 | * Pull the synch status from Mailbox 0. | ||
| 1057 | */ | ||
| 1058 | if (status && !rc) { | ||
| 1059 | status[0] = readl(&dev->IndexRegs->Mailbox[0]); | ||
| 1060 | status[1] = readl(&dev->IndexRegs->Mailbox[1]); | ||
| 1061 | status[2] = readl(&dev->IndexRegs->Mailbox[2]); | ||
| 1062 | status[3] = readl(&dev->IndexRegs->Mailbox[3]); | ||
| 1063 | status[4] = readl(&dev->IndexRegs->Mailbox[4]); | ||
| 1064 | } | ||
| 1065 | |||
| 1066 | return rc; | ||
| 1067 | } | ||
| 1068 | |||
| 1069 | /** | ||
| 1070 | * aac_src_soft_reset - perform soft reset to speed up | ||
| 1071 | * access | ||
| 1072 | * | ||
| 1073 | * Assumptions: That the controller is in a state where we can | ||
| 1074 | * bring it back to life with an init struct. We can only use | ||
| 1075 | * fast sync commands, as the timeout is 5 seconds. | ||
| 1076 | * | ||
| 1077 | * @dev: device to configure | ||
| 1078 | * | ||
| 1079 | */ | ||
| 1080 | |||
| 1081 | static int aac_src_soft_reset(struct aac_dev *dev) | ||
| 1082 | { | ||
| 1083 | u32 status_omr = src_readl(dev, MUnit.OMR); | ||
| 1084 | u32 status[5]; | ||
| 1085 | int rc = 1; | ||
| 1086 | int state = 0; | ||
| 1087 | char *state_str[7] = { | ||
| 1088 | "GET_ADAPTER_PROPERTIES Failed", | ||
| 1089 | "GET_ADAPTER_PROPERTIES timeout", | ||
| 1090 | "SOFT_RESET not supported", | ||
| 1091 | "DROP_IO Failed", | ||
| 1092 | "DROP_IO timeout", | ||
| 1093 | "Check Health failed" | ||
| 1094 | }; | ||
| 1095 | |||
| 1096 | if (status_omr == INVALID_OMR) | ||
| 1097 | return 1; // pcie hosed | ||
| 1098 | |||
| 1099 | if (!(status_omr & KERNEL_UP_AND_RUNNING)) | ||
| 1100 | return 1; // not up and running | ||
| 1101 | |||
| 1102 | /* | ||
| 1103 | * We go into soft reset mode to allow us to handle response | ||
| 1104 | */ | ||
| 1105 | dev->in_soft_reset = 1; | ||
| 1106 | dev->msi_enabled = status_omr & AAC_INT_MODE_MSIX; | ||
| 1107 | |||
| 1108 | /* Get adapter properties */ | ||
| 1109 | rc = aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES, 0, 0, 0, | ||
| 1110 | 0, 0, 0, status+0, status+1, status+2, status+3, status+4); | ||
| 1111 | if (rc) | ||
| 1112 | goto out; | ||
| 1113 | |||
| 1114 | state++; | ||
| 1115 | if (aac_src_wait_sync(dev, status)) { | ||
| 1116 | rc = 1; | ||
| 1117 | goto out; | ||
| 1118 | } | ||
| 1119 | |||
| 1120 | state++; | ||
| 1121 | if (!(status[1] & le32_to_cpu(AAC_OPT_EXTENDED) && | ||
| 1122 | (status[4] & le32_to_cpu(AAC_EXTOPT_SOFT_RESET)))) { | ||
| 1123 | rc = 2; | ||
| 1124 | goto out; | ||
| 1125 | } | ||
| 1126 | |||
| 1127 | if ((status[1] & le32_to_cpu(AAC_OPT_EXTENDED)) && | ||
| 1128 | (status[4] & le32_to_cpu(AAC_EXTOPT_SA_FIRMWARE))) | ||
| 1129 | dev->sa_firmware = 1; | ||
| 1130 | |||
| 1131 | state++; | ||
| 1132 | rc = aac_adapter_sync_cmd(dev, DROP_IO, 0, 0, 0, 0, 0, 0, | ||
| 1133 | status+0, status+1, status+2, status+3, status+4); | ||
| 1134 | |||
| 1135 | if (rc) | ||
| 1136 | goto out; | ||
| 1137 | |||
| 1138 | state++; | ||
| 1139 | if (aac_src_wait_sync(dev, status)) { | ||
| 1140 | rc = 3; | ||
| 1141 | goto out; | ||
| 1142 | } | ||
| 1143 | |||
| 1144 | if (status[1]) | ||
| 1145 | dev_err(&dev->pdev->dev, "%s: %d outstanding I/O pending\n", | ||
| 1146 | __func__, status[1]); | ||
| 1147 | |||
| 1148 | state++; | ||
| 1149 | rc = aac_src_check_health(dev); | ||
| 1150 | |||
| 1151 | out: | ||
| 1152 | dev->in_soft_reset = 0; | ||
| 1153 | dev->msi_enabled = 0; | ||
| 1154 | if (rc) | ||
| 1155 | dev_err(&dev->pdev->dev, "%s: %s status = %d", __func__, | ||
| 1156 | state_str[state], rc); | ||
| 1157 | |||
| 1158 | return rc; | ||
| 1159 | } | ||
| 995 | /** | 1160 | /** |
| 996 | * aac_srcv_init - initialize an SRCv card | 1161 | * aac_srcv_init - initialize an SRCv card |
| 997 | * @dev: device to configure | 1162 | * @dev: device to configure |
| @@ -1021,8 +1186,10 @@ int aac_srcv_init(struct aac_dev *dev) | |||
| 1021 | 1186 | ||
| 1022 | if (dev->init_reset) { | 1187 | if (dev->init_reset) { |
| 1023 | dev->init_reset = false; | 1188 | dev->init_reset = false; |
| 1024 | if (!aac_src_restart_adapter(dev, 0, IOP_HWSOFT_RESET)) | 1189 | if (aac_src_soft_reset(dev)) { |
| 1190 | aac_src_restart_adapter(dev, 0, IOP_HWSOFT_RESET); | ||
| 1025 | ++restart; | 1191 | ++restart; |
| 1192 | } | ||
| 1026 | } | 1193 | } |
| 1027 | 1194 | ||
| 1028 | /* | 1195 | /* |
| @@ -1072,13 +1239,16 @@ int aac_srcv_init(struct aac_dev *dev) | |||
| 1072 | printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance); | 1239 | printk(KERN_ERR "%s%d: adapter monitor panic.\n", dev->name, instance); |
| 1073 | goto error_iounmap; | 1240 | goto error_iounmap; |
| 1074 | } | 1241 | } |
| 1242 | |||
| 1075 | start = jiffies; | 1243 | start = jiffies; |
| 1076 | /* | 1244 | /* |
| 1077 | * Wait for the adapter to be up and running. Wait up to 3 minutes | 1245 | * Wait for the adapter to be up and running. Wait up to 3 minutes |
| 1078 | */ | 1246 | */ |
| 1079 | while (!((status = src_readl(dev, MUnit.OMR)) & | 1247 | do { |
| 1080 | KERNEL_UP_AND_RUNNING) || | 1248 | status = src_readl(dev, MUnit.OMR); |
| 1081 | status == 0xffffffff) { | 1249 | if (status == INVALID_OMR) |
| 1250 | status = 0; | ||
| 1251 | |||
| 1082 | if ((restart && | 1252 | if ((restart && |
| 1083 | (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) || | 1253 | (status & (KERNEL_PANIC|SELF_TEST_FAILED|MONITOR_PANIC))) || |
| 1084 | time_after(jiffies, start+HZ*startup_timeout)) { | 1254 | time_after(jiffies, start+HZ*startup_timeout)) { |
| @@ -1098,7 +1268,8 @@ int aac_srcv_init(struct aac_dev *dev) | |||
| 1098 | ++restart; | 1268 | ++restart; |
| 1099 | } | 1269 | } |
| 1100 | msleep(1); | 1270 | msleep(1); |
| 1101 | } | 1271 | } while (!(status & KERNEL_UP_AND_RUNNING)); |
| 1272 | |||
| 1102 | if (restart && aac_commit) | 1273 | if (restart && aac_commit) |
| 1103 | aac_commit = 1; | 1274 | aac_commit = 1; |
| 1104 | /* | 1275 | /* |
| @@ -1234,13 +1405,23 @@ void aac_src_access_devreg(struct aac_dev *dev, int mode) | |||
| 1234 | 1405 | ||
| 1235 | static int aac_src_get_sync_status(struct aac_dev *dev) | 1406 | static int aac_src_get_sync_status(struct aac_dev *dev) |
| 1236 | { | 1407 | { |
| 1408 | int msix_val = 0; | ||
| 1409 | int legacy_val = 0; | ||
| 1237 | 1410 | ||
| 1238 | int val; | 1411 | msix_val = src_readl(dev, MUnit.ODR_MSI) & SRC_MSI_READ_MASK ? 1 : 0; |
| 1239 | 1412 | ||
| 1240 | if (dev->msi_enabled) | 1413 | if (!dev->msi_enabled) { |
| 1241 | val = src_readl(dev, MUnit.ODR_MSI) & 0x1000 ? 1 : 0; | 1414 | /* |
| 1242 | else | 1415 | * if Legacy int status indicates cmd is not complete |
| 1243 | val = src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT; | 1416 | * sample MSIx register to see if it indiactes cmd complete, |
| 1417 | * if yes set the controller in MSIx mode and consider cmd | ||
| 1418 | * completed | ||
| 1419 | */ | ||
| 1420 | legacy_val = src_readl(dev, MUnit.ODR_R) >> SRC_ODR_SHIFT; | ||
| 1421 | if (!(legacy_val & 1) && msix_val) | ||
| 1422 | dev->msi_enabled = 1; | ||
| 1423 | return legacy_val; | ||
| 1424 | } | ||
| 1244 | 1425 | ||
| 1245 | return val; | 1426 | return msix_val; |
| 1246 | } | 1427 | } |
diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c index bad35ffc015d..b48d5436f094 100644 --- a/drivers/scsi/aha1740.c +++ b/drivers/scsi/aha1740.c | |||
| @@ -592,7 +592,7 @@ static int aha1740_probe (struct device *dev) | |||
| 592 | DMA_BIDIRECTIONAL); | 592 | DMA_BIDIRECTIONAL); |
| 593 | if (!host->ecb_dma_addr) { | 593 | if (!host->ecb_dma_addr) { |
| 594 | printk (KERN_ERR "aha1740_probe: Couldn't map ECB, giving up\n"); | 594 | printk (KERN_ERR "aha1740_probe: Couldn't map ECB, giving up\n"); |
| 595 | scsi_unregister (shpnt); | 595 | scsi_host_put (shpnt); |
| 596 | goto err_host_put; | 596 | goto err_host_put; |
| 597 | } | 597 | } |
| 598 | 598 | ||
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index b560f396ee99..034f4eebb160 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c | |||
| @@ -9338,9 +9338,9 @@ ahd_dumpseq(struct ahd_softc* ahd) | |||
| 9338 | static void | 9338 | static void |
| 9339 | ahd_loadseq(struct ahd_softc *ahd) | 9339 | ahd_loadseq(struct ahd_softc *ahd) |
| 9340 | { | 9340 | { |
| 9341 | struct cs cs_table[num_critical_sections]; | 9341 | struct cs cs_table[NUM_CRITICAL_SECTIONS]; |
| 9342 | u_int begin_set[num_critical_sections]; | 9342 | u_int begin_set[NUM_CRITICAL_SECTIONS]; |
| 9343 | u_int end_set[num_critical_sections]; | 9343 | u_int end_set[NUM_CRITICAL_SECTIONS]; |
| 9344 | const struct patch *cur_patch; | 9344 | const struct patch *cur_patch; |
| 9345 | u_int cs_count; | 9345 | u_int cs_count; |
| 9346 | u_int cur_cs; | 9346 | u_int cur_cs; |
| @@ -9456,7 +9456,7 @@ ahd_loadseq(struct ahd_softc *ahd) | |||
| 9456 | * Move through the CS table until we find a CS | 9456 | * Move through the CS table until we find a CS |
| 9457 | * that might apply to this instruction. | 9457 | * that might apply to this instruction. |
| 9458 | */ | 9458 | */ |
| 9459 | for (; cur_cs < num_critical_sections; cur_cs++) { | 9459 | for (; cur_cs < NUM_CRITICAL_SECTIONS; cur_cs++) { |
| 9460 | if (critical_sections[cur_cs].end <= i) { | 9460 | if (critical_sections[cur_cs].end <= i) { |
| 9461 | if (begin_set[cs_count] == TRUE | 9461 | if (begin_set[cs_count] == TRUE |
| 9462 | && end_set[cs_count] == FALSE) { | 9462 | && end_set[cs_count] == FALSE) { |
diff --git a/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped b/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped index 4b51e232392f..fd64a950ee44 100644 --- a/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped +++ b/drivers/scsi/aic7xxx/aic79xx_seq.h_shipped | |||
| @@ -1186,5 +1186,4 @@ static const struct cs { | |||
| 1186 | { 759, 763 } | 1186 | { 759, 763 } |
| 1187 | }; | 1187 | }; |
| 1188 | 1188 | ||
| 1189 | static const int num_critical_sections = sizeof(critical_sections) | 1189 | #define NUM_CRITICAL_SECTIONS ARRAY_SIZE(critical_sections) |
| 1190 | / sizeof(*critical_sections); | ||
diff --git a/drivers/scsi/aic7xxx/aic7xxx_core.c b/drivers/scsi/aic7xxx/aic7xxx_core.c index 6612ff3b2e83..e97eceacf522 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_core.c +++ b/drivers/scsi/aic7xxx/aic7xxx_core.c | |||
| @@ -6848,9 +6848,9 @@ ahc_dumpseq(struct ahc_softc* ahc) | |||
| 6848 | static int | 6848 | static int |
| 6849 | ahc_loadseq(struct ahc_softc *ahc) | 6849 | ahc_loadseq(struct ahc_softc *ahc) |
| 6850 | { | 6850 | { |
| 6851 | struct cs cs_table[num_critical_sections]; | 6851 | struct cs cs_table[NUM_CRITICAL_SECTIONS]; |
| 6852 | u_int begin_set[num_critical_sections]; | 6852 | u_int begin_set[NUM_CRITICAL_SECTIONS]; |
| 6853 | u_int end_set[num_critical_sections]; | 6853 | u_int end_set[NUM_CRITICAL_SECTIONS]; |
| 6854 | const struct patch *cur_patch; | 6854 | const struct patch *cur_patch; |
| 6855 | u_int cs_count; | 6855 | u_int cs_count; |
| 6856 | u_int cur_cs; | 6856 | u_int cur_cs; |
| @@ -6915,7 +6915,7 @@ ahc_loadseq(struct ahc_softc *ahc) | |||
| 6915 | * Move through the CS table until we find a CS | 6915 | * Move through the CS table until we find a CS |
| 6916 | * that might apply to this instruction. | 6916 | * that might apply to this instruction. |
| 6917 | */ | 6917 | */ |
| 6918 | for (; cur_cs < num_critical_sections; cur_cs++) { | 6918 | for (; cur_cs < NUM_CRITICAL_SECTIONS; cur_cs++) { |
| 6919 | if (critical_sections[cur_cs].end <= i) { | 6919 | if (critical_sections[cur_cs].end <= i) { |
| 6920 | if (begin_set[cs_count] == TRUE | 6920 | if (begin_set[cs_count] == TRUE |
| 6921 | && end_set[cs_count] == FALSE) { | 6921 | && end_set[cs_count] == FALSE) { |
diff --git a/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped b/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped index 07e93fbae706..f37362bc8ece 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped +++ b/drivers/scsi/aic7xxx/aic7xxx_seq.h_shipped | |||
| @@ -1304,5 +1304,4 @@ static const struct cs { | |||
| 1304 | { 875, 877 } | 1304 | { 875, 877 } |
| 1305 | }; | 1305 | }; |
| 1306 | 1306 | ||
| 1307 | static const int num_critical_sections = sizeof(critical_sections) | 1307 | #define NUM_CRITICAL_SECTIONS ARRAY_SIZE(critical_sections) |
| 1308 | / sizeof(*critical_sections); | ||
diff --git a/drivers/scsi/aic7xxx/aicasm/aicasm.c b/drivers/scsi/aic7xxx/aicasm/aicasm.c index 21ac265280bf..5f474e490f3e 100644 --- a/drivers/scsi/aic7xxx/aicasm/aicasm.c +++ b/drivers/scsi/aic7xxx/aicasm/aicasm.c | |||
| @@ -451,8 +451,7 @@ output_code() | |||
| 451 | fprintf(ofile, "\n};\n\n"); | 451 | fprintf(ofile, "\n};\n\n"); |
| 452 | 452 | ||
| 453 | fprintf(ofile, | 453 | fprintf(ofile, |
| 454 | "static const int num_critical_sections = sizeof(critical_sections)\n" | 454 | "#define NUM_CRITICAL_SECTIONS ARRAY_SIZE(critical_sections)\n"); |
| 455 | " / sizeof(*critical_sections);\n"); | ||
| 456 | 455 | ||
| 457 | fprintf(stderr, "%s: %d instructions used\n", appname, instrcount); | 456 | fprintf(stderr, "%s: %d instructions used\n", appname, instrcount); |
| 458 | } | 457 | } |
diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index f375f3557c18..2e51ccc510e8 100644 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h | |||
| @@ -49,7 +49,7 @@ struct device_attribute; | |||
| 49 | #define ARCMSR_MAX_OUTSTANDING_CMD 1024 | 49 | #define ARCMSR_MAX_OUTSTANDING_CMD 1024 |
| 50 | #define ARCMSR_DEFAULT_OUTSTANDING_CMD 128 | 50 | #define ARCMSR_DEFAULT_OUTSTANDING_CMD 128 |
| 51 | #define ARCMSR_MIN_OUTSTANDING_CMD 32 | 51 | #define ARCMSR_MIN_OUTSTANDING_CMD 32 |
| 52 | #define ARCMSR_DRIVER_VERSION "v1.40.00.04-20171130" | 52 | #define ARCMSR_DRIVER_VERSION "v1.40.00.05-20180309" |
| 53 | #define ARCMSR_SCSI_INITIATOR_ID 255 | 53 | #define ARCMSR_SCSI_INITIATOR_ID 255 |
| 54 | #define ARCMSR_MAX_XFER_SECTORS 512 | 54 | #define ARCMSR_MAX_XFER_SECTORS 512 |
| 55 | #define ARCMSR_MAX_XFER_SECTORS_B 4096 | 55 | #define ARCMSR_MAX_XFER_SECTORS_B 4096 |
| @@ -779,12 +779,12 @@ struct AdapterControlBlock | |||
| 779 | /* message clear rqbuffer */ | 779 | /* message clear rqbuffer */ |
| 780 | #define ACB_F_MESSAGE_WQBUFFER_READED 0x0040 | 780 | #define ACB_F_MESSAGE_WQBUFFER_READED 0x0040 |
| 781 | #define ACB_F_BUS_RESET 0x0080 | 781 | #define ACB_F_BUS_RESET 0x0080 |
| 782 | #define ACB_F_BUS_HANG_ON 0x0800/* need hardware reset bus */ | ||
| 783 | 782 | ||
| 784 | #define ACB_F_IOP_INITED 0x0100 | 783 | #define ACB_F_IOP_INITED 0x0100 |
| 785 | /* iop init */ | 784 | /* iop init */ |
| 786 | #define ACB_F_ABORT 0x0200 | 785 | #define ACB_F_ABORT 0x0200 |
| 787 | #define ACB_F_FIRMWARE_TRAP 0x0400 | 786 | #define ACB_F_FIRMWARE_TRAP 0x0400 |
| 787 | #define ACB_F_ADAPTER_REMOVED 0x0800 | ||
| 788 | #define ACB_F_MSG_GET_CONFIG 0x1000 | 788 | #define ACB_F_MSG_GET_CONFIG 0x1000 |
| 789 | struct CommandControlBlock * pccb_pool[ARCMSR_MAX_FREECCB_NUM]; | 789 | struct CommandControlBlock * pccb_pool[ARCMSR_MAX_FREECCB_NUM]; |
| 790 | /* used for memory free */ | 790 | /* used for memory free */ |
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 75e828bd30e3..732b5d9242f1 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c | |||
| @@ -1446,12 +1446,80 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb) | |||
| 1446 | } | 1446 | } |
| 1447 | } | 1447 | } |
| 1448 | 1448 | ||
| 1449 | static void arcmsr_remove_scsi_devices(struct AdapterControlBlock *acb) | ||
| 1450 | { | ||
| 1451 | char *acb_dev_map = (char *)acb->device_map; | ||
| 1452 | int target, lun, i; | ||
| 1453 | struct scsi_device *psdev; | ||
| 1454 | struct CommandControlBlock *ccb; | ||
| 1455 | char temp; | ||
| 1456 | |||
| 1457 | for (i = 0; i < acb->maxFreeCCB; i++) { | ||
| 1458 | ccb = acb->pccb_pool[i]; | ||
| 1459 | if (ccb->startdone == ARCMSR_CCB_START) { | ||
| 1460 | ccb->pcmd->result = DID_NO_CONNECT << 16; | ||
| 1461 | arcmsr_pci_unmap_dma(ccb); | ||
| 1462 | ccb->pcmd->scsi_done(ccb->pcmd); | ||
| 1463 | } | ||
| 1464 | } | ||
| 1465 | for (target = 0; target < ARCMSR_MAX_TARGETID; target++) { | ||
| 1466 | temp = *acb_dev_map; | ||
| 1467 | if (temp) { | ||
| 1468 | for (lun = 0; lun < ARCMSR_MAX_TARGETLUN; lun++) { | ||
| 1469 | if (temp & 1) { | ||
| 1470 | psdev = scsi_device_lookup(acb->host, | ||
| 1471 | 0, target, lun); | ||
| 1472 | if (psdev != NULL) { | ||
| 1473 | scsi_remove_device(psdev); | ||
| 1474 | scsi_device_put(psdev); | ||
| 1475 | } | ||
| 1476 | } | ||
| 1477 | temp >>= 1; | ||
| 1478 | } | ||
| 1479 | *acb_dev_map = 0; | ||
| 1480 | } | ||
| 1481 | acb_dev_map++; | ||
| 1482 | } | ||
| 1483 | } | ||
| 1484 | |||
| 1485 | static void arcmsr_free_pcidev(struct AdapterControlBlock *acb) | ||
| 1486 | { | ||
| 1487 | struct pci_dev *pdev; | ||
| 1488 | struct Scsi_Host *host; | ||
| 1489 | |||
| 1490 | host = acb->host; | ||
| 1491 | arcmsr_free_sysfs_attr(acb); | ||
| 1492 | scsi_remove_host(host); | ||
| 1493 | flush_work(&acb->arcmsr_do_message_isr_bh); | ||
| 1494 | del_timer_sync(&acb->eternal_timer); | ||
| 1495 | if (set_date_time) | ||
| 1496 | del_timer_sync(&acb->refresh_timer); | ||
| 1497 | pdev = acb->pdev; | ||
| 1498 | arcmsr_free_irq(pdev, acb); | ||
| 1499 | arcmsr_free_ccb_pool(acb); | ||
| 1500 | arcmsr_free_mu(acb); | ||
| 1501 | arcmsr_unmap_pciregion(acb); | ||
| 1502 | pci_release_regions(pdev); | ||
| 1503 | scsi_host_put(host); | ||
| 1504 | pci_disable_device(pdev); | ||
| 1505 | } | ||
| 1506 | |||
| 1449 | static void arcmsr_remove(struct pci_dev *pdev) | 1507 | static void arcmsr_remove(struct pci_dev *pdev) |
| 1450 | { | 1508 | { |
| 1451 | struct Scsi_Host *host = pci_get_drvdata(pdev); | 1509 | struct Scsi_Host *host = pci_get_drvdata(pdev); |
| 1452 | struct AdapterControlBlock *acb = | 1510 | struct AdapterControlBlock *acb = |
| 1453 | (struct AdapterControlBlock *) host->hostdata; | 1511 | (struct AdapterControlBlock *) host->hostdata; |
| 1454 | int poll_count = 0; | 1512 | int poll_count = 0; |
| 1513 | uint16_t dev_id; | ||
| 1514 | |||
| 1515 | pci_read_config_word(pdev, PCI_DEVICE_ID, &dev_id); | ||
| 1516 | if (dev_id == 0xffff) { | ||
| 1517 | acb->acb_flags &= ~ACB_F_IOP_INITED; | ||
| 1518 | acb->acb_flags |= ACB_F_ADAPTER_REMOVED; | ||
| 1519 | arcmsr_remove_scsi_devices(acb); | ||
| 1520 | arcmsr_free_pcidev(acb); | ||
| 1521 | return; | ||
| 1522 | } | ||
| 1455 | arcmsr_free_sysfs_attr(acb); | 1523 | arcmsr_free_sysfs_attr(acb); |
| 1456 | scsi_remove_host(host); | 1524 | scsi_remove_host(host); |
| 1457 | flush_work(&acb->arcmsr_do_message_isr_bh); | 1525 | flush_work(&acb->arcmsr_do_message_isr_bh); |
| @@ -1499,6 +1567,8 @@ static void arcmsr_shutdown(struct pci_dev *pdev) | |||
| 1499 | struct Scsi_Host *host = pci_get_drvdata(pdev); | 1567 | struct Scsi_Host *host = pci_get_drvdata(pdev); |
| 1500 | struct AdapterControlBlock *acb = | 1568 | struct AdapterControlBlock *acb = |
| 1501 | (struct AdapterControlBlock *)host->hostdata; | 1569 | (struct AdapterControlBlock *)host->hostdata; |
| 1570 | if (acb->acb_flags & ACB_F_ADAPTER_REMOVED) | ||
| 1571 | return; | ||
| 1502 | del_timer_sync(&acb->eternal_timer); | 1572 | del_timer_sync(&acb->eternal_timer); |
| 1503 | if (set_date_time) | 1573 | if (set_date_time) |
| 1504 | del_timer_sync(&acb->refresh_timer); | 1574 | del_timer_sync(&acb->refresh_timer); |
| @@ -2931,6 +3001,12 @@ static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd, | |||
| 2931 | struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; | 3001 | struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; |
| 2932 | struct CommandControlBlock *ccb; | 3002 | struct CommandControlBlock *ccb; |
| 2933 | int target = cmd->device->id; | 3003 | int target = cmd->device->id; |
| 3004 | |||
| 3005 | if (acb->acb_flags & ACB_F_ADAPTER_REMOVED) { | ||
| 3006 | cmd->result = (DID_NO_CONNECT << 16); | ||
| 3007 | cmd->scsi_done(cmd); | ||
| 3008 | return 0; | ||
| 3009 | } | ||
| 2934 | cmd->scsi_done = done; | 3010 | cmd->scsi_done = done; |
| 2935 | cmd->host_scribble = NULL; | 3011 | cmd->host_scribble = NULL; |
| 2936 | cmd->result = 0; | 3012 | cmd->result = 0; |
| @@ -3731,6 +3807,8 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb) | |||
| 3731 | case ACB_ADAPTER_TYPE_A: { | 3807 | case ACB_ADAPTER_TYPE_A: { |
| 3732 | struct MessageUnit_A __iomem *reg = acb->pmuA; | 3808 | struct MessageUnit_A __iomem *reg = acb->pmuA; |
| 3733 | do { | 3809 | do { |
| 3810 | if (!(acb->acb_flags & ACB_F_IOP_INITED)) | ||
| 3811 | msleep(20); | ||
| 3734 | firmware_state = readl(®->outbound_msgaddr1); | 3812 | firmware_state = readl(®->outbound_msgaddr1); |
| 3735 | } while ((firmware_state & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0); | 3813 | } while ((firmware_state & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0); |
| 3736 | } | 3814 | } |
| @@ -3739,6 +3817,8 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb) | |||
| 3739 | case ACB_ADAPTER_TYPE_B: { | 3817 | case ACB_ADAPTER_TYPE_B: { |
| 3740 | struct MessageUnit_B *reg = acb->pmuB; | 3818 | struct MessageUnit_B *reg = acb->pmuB; |
| 3741 | do { | 3819 | do { |
| 3820 | if (!(acb->acb_flags & ACB_F_IOP_INITED)) | ||
| 3821 | msleep(20); | ||
| 3742 | firmware_state = readl(reg->iop2drv_doorbell); | 3822 | firmware_state = readl(reg->iop2drv_doorbell); |
| 3743 | } while ((firmware_state & ARCMSR_MESSAGE_FIRMWARE_OK) == 0); | 3823 | } while ((firmware_state & ARCMSR_MESSAGE_FIRMWARE_OK) == 0); |
| 3744 | writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, reg->drv2iop_doorbell); | 3824 | writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, reg->drv2iop_doorbell); |
| @@ -3747,6 +3827,8 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb) | |||
| 3747 | case ACB_ADAPTER_TYPE_C: { | 3827 | case ACB_ADAPTER_TYPE_C: { |
| 3748 | struct MessageUnit_C __iomem *reg = acb->pmuC; | 3828 | struct MessageUnit_C __iomem *reg = acb->pmuC; |
| 3749 | do { | 3829 | do { |
| 3830 | if (!(acb->acb_flags & ACB_F_IOP_INITED)) | ||
| 3831 | msleep(20); | ||
| 3750 | firmware_state = readl(®->outbound_msgaddr1); | 3832 | firmware_state = readl(®->outbound_msgaddr1); |
| 3751 | } while ((firmware_state & ARCMSR_HBCMU_MESSAGE_FIRMWARE_OK) == 0); | 3833 | } while ((firmware_state & ARCMSR_HBCMU_MESSAGE_FIRMWARE_OK) == 0); |
| 3752 | } | 3834 | } |
| @@ -3754,6 +3836,8 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb) | |||
| 3754 | case ACB_ADAPTER_TYPE_D: { | 3836 | case ACB_ADAPTER_TYPE_D: { |
| 3755 | struct MessageUnit_D *reg = acb->pmuD; | 3837 | struct MessageUnit_D *reg = acb->pmuD; |
| 3756 | do { | 3838 | do { |
| 3839 | if (!(acb->acb_flags & ACB_F_IOP_INITED)) | ||
| 3840 | msleep(20); | ||
| 3757 | firmware_state = readl(reg->outbound_msgaddr1); | 3841 | firmware_state = readl(reg->outbound_msgaddr1); |
| 3758 | } while ((firmware_state & | 3842 | } while ((firmware_state & |
| 3759 | ARCMSR_ARC1214_MESSAGE_FIRMWARE_OK) == 0); | 3843 | ARCMSR_ARC1214_MESSAGE_FIRMWARE_OK) == 0); |
| @@ -3762,6 +3846,8 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb) | |||
| 3762 | case ACB_ADAPTER_TYPE_E: { | 3846 | case ACB_ADAPTER_TYPE_E: { |
| 3763 | struct MessageUnit_E __iomem *reg = acb->pmuE; | 3847 | struct MessageUnit_E __iomem *reg = acb->pmuE; |
| 3764 | do { | 3848 | do { |
| 3849 | if (!(acb->acb_flags & ACB_F_IOP_INITED)) | ||
| 3850 | msleep(20); | ||
| 3765 | firmware_state = readl(®->outbound_msgaddr1); | 3851 | firmware_state = readl(®->outbound_msgaddr1); |
| 3766 | } while ((firmware_state & ARCMSR_HBEMU_MESSAGE_FIRMWARE_OK) == 0); | 3852 | } while ((firmware_state & ARCMSR_HBEMU_MESSAGE_FIRMWARE_OK) == 0); |
| 3767 | } | 3853 | } |
| @@ -4177,6 +4263,8 @@ static int arcmsr_bus_reset(struct scsi_cmnd *cmd) | |||
| 4177 | int retry_count = 0; | 4263 | int retry_count = 0; |
| 4178 | int rtn = FAILED; | 4264 | int rtn = FAILED; |
| 4179 | acb = (struct AdapterControlBlock *) cmd->device->host->hostdata; | 4265 | acb = (struct AdapterControlBlock *) cmd->device->host->hostdata; |
| 4266 | if (acb->acb_flags & ACB_F_ADAPTER_REMOVED) | ||
| 4267 | return SUCCESS; | ||
| 4180 | pr_notice("arcmsr: executing bus reset eh.....num_resets = %d," | 4268 | pr_notice("arcmsr: executing bus reset eh.....num_resets = %d," |
| 4181 | " num_aborts = %d \n", acb->num_resets, acb->num_aborts); | 4269 | " num_aborts = %d \n", acb->num_resets, acb->num_aborts); |
| 4182 | acb->num_resets++; | 4270 | acb->num_resets++; |
| @@ -4243,6 +4331,8 @@ static int arcmsr_abort(struct scsi_cmnd *cmd) | |||
| 4243 | int rtn = FAILED; | 4331 | int rtn = FAILED; |
| 4244 | uint32_t intmask_org; | 4332 | uint32_t intmask_org; |
| 4245 | 4333 | ||
| 4334 | if (acb->acb_flags & ACB_F_ADAPTER_REMOVED) | ||
| 4335 | return SUCCESS; | ||
| 4246 | printk(KERN_NOTICE | 4336 | printk(KERN_NOTICE |
| 4247 | "arcmsr%d: abort device command of scsi id = %d lun = %d\n", | 4337 | "arcmsr%d: abort device command of scsi id = %d lun = %d\n", |
| 4248 | acb->host->host_no, cmd->device->id, (u32)cmd->device->lun); | 4338 | acb->host->host_no, cmd->device->id, (u32)cmd->device->lun); |
diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 8b52a9dbb9cf..b46997cf77e2 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c | |||
| @@ -1413,11 +1413,11 @@ static void atp885_init(struct Scsi_Host *shpnt) | |||
| 1413 | atpdev->global_map[m] = 0; | 1413 | atpdev->global_map[m] = 0; |
| 1414 | for (k = 0; k < 4; k++) { | 1414 | for (k = 0; k < 4; k++) { |
| 1415 | atp_writew_base(atpdev, 0x3c, n++); | 1415 | atp_writew_base(atpdev, 0x3c, n++); |
| 1416 | ((unsigned long *)&setupdata[m][0])[k] = atp_readl_base(atpdev, 0x38); | 1416 | ((u32 *)&setupdata[m][0])[k] = atp_readl_base(atpdev, 0x38); |
| 1417 | } | 1417 | } |
| 1418 | for (k = 0; k < 4; k++) { | 1418 | for (k = 0; k < 4; k++) { |
| 1419 | atp_writew_base(atpdev, 0x3c, n++); | 1419 | atp_writew_base(atpdev, 0x3c, n++); |
| 1420 | ((unsigned long *)&atpdev->sp[m][0])[k] = atp_readl_base(atpdev, 0x38); | 1420 | ((u32 *)&atpdev->sp[m][0])[k] = atp_readl_base(atpdev, 0x38); |
| 1421 | } | 1421 | } |
| 1422 | n += 8; | 1422 | n += 8; |
| 1423 | } | 1423 | } |
diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index 3976e787ba64..7c884f881180 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c | |||
| @@ -891,7 +891,7 @@ bfad_iocmd_fabric_get_lports(struct bfad_s *bfad, void *cmd, | |||
| 891 | 891 | ||
| 892 | if (bfad_chk_iocmd_sz(payload_len, | 892 | if (bfad_chk_iocmd_sz(payload_len, |
| 893 | sizeof(struct bfa_bsg_fabric_get_lports_s), | 893 | sizeof(struct bfa_bsg_fabric_get_lports_s), |
| 894 | sizeof(wwn_t[iocmd->nports])) != BFA_STATUS_OK) { | 894 | sizeof(wwn_t) * iocmd->nports) != BFA_STATUS_OK) { |
| 895 | iocmd->status = BFA_STATUS_VERSION_FAIL; | 895 | iocmd->status = BFA_STATUS_VERSION_FAIL; |
| 896 | goto out; | 896 | goto out; |
| 897 | } | 897 | } |
diff --git a/drivers/scsi/csiostor/csio_attr.c b/drivers/scsi/csiostor/csio_attr.c index 2d1c4ebd40f9..8a004036e3d7 100644 --- a/drivers/scsi/csiostor/csio_attr.c +++ b/drivers/scsi/csiostor/csio_attr.c | |||
| @@ -274,12 +274,24 @@ csio_get_host_speed(struct Scsi_Host *shost) | |||
| 274 | 274 | ||
| 275 | spin_lock_irq(&hw->lock); | 275 | spin_lock_irq(&hw->lock); |
| 276 | switch (hw->pport[ln->portid].link_speed) { | 276 | switch (hw->pport[ln->portid].link_speed) { |
| 277 | case FW_PORT_CAP_SPEED_1G: | 277 | case FW_PORT_CAP32_SPEED_1G: |
| 278 | fc_host_speed(shost) = FC_PORTSPEED_1GBIT; | 278 | fc_host_speed(shost) = FC_PORTSPEED_1GBIT; |
| 279 | break; | 279 | break; |
| 280 | case FW_PORT_CAP_SPEED_10G: | 280 | case FW_PORT_CAP32_SPEED_10G: |
| 281 | fc_host_speed(shost) = FC_PORTSPEED_10GBIT; | 281 | fc_host_speed(shost) = FC_PORTSPEED_10GBIT; |
| 282 | break; | 282 | break; |
| 283 | case FW_PORT_CAP32_SPEED_25G: | ||
| 284 | fc_host_speed(shost) = FC_PORTSPEED_25GBIT; | ||
| 285 | break; | ||
| 286 | case FW_PORT_CAP32_SPEED_40G: | ||
| 287 | fc_host_speed(shost) = FC_PORTSPEED_40GBIT; | ||
| 288 | break; | ||
| 289 | case FW_PORT_CAP32_SPEED_50G: | ||
| 290 | fc_host_speed(shost) = FC_PORTSPEED_50GBIT; | ||
| 291 | break; | ||
| 292 | case FW_PORT_CAP32_SPEED_100G: | ||
| 293 | fc_host_speed(shost) = FC_PORTSPEED_100GBIT; | ||
| 294 | break; | ||
| 283 | default: | 295 | default: |
| 284 | fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; | 296 | fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; |
| 285 | break; | 297 | break; |
diff --git a/drivers/scsi/csiostor/csio_hw.c b/drivers/scsi/csiostor/csio_hw.c index 0bd1131b6cc9..96bbb82c826d 100644 --- a/drivers/scsi/csiostor/csio_hw.c +++ b/drivers/scsi/csiostor/csio_hw.c | |||
| @@ -1409,6 +1409,235 @@ out: | |||
| 1409 | return rv; | 1409 | return rv; |
| 1410 | } | 1410 | } |
| 1411 | 1411 | ||
| 1412 | static inline enum cc_fec fwcap_to_cc_fec(fw_port_cap32_t fw_fec) | ||
| 1413 | { | ||
| 1414 | enum cc_fec cc_fec = 0; | ||
| 1415 | |||
| 1416 | if (fw_fec & FW_PORT_CAP32_FEC_RS) | ||
| 1417 | cc_fec |= FEC_RS; | ||
| 1418 | if (fw_fec & FW_PORT_CAP32_FEC_BASER_RS) | ||
| 1419 | cc_fec |= FEC_BASER_RS; | ||
| 1420 | |||
| 1421 | return cc_fec; | ||
| 1422 | } | ||
| 1423 | |||
| 1424 | static inline fw_port_cap32_t cc_to_fwcap_pause(enum cc_pause cc_pause) | ||
| 1425 | { | ||
| 1426 | fw_port_cap32_t fw_pause = 0; | ||
| 1427 | |||
| 1428 | if (cc_pause & PAUSE_RX) | ||
| 1429 | fw_pause |= FW_PORT_CAP32_FC_RX; | ||
| 1430 | if (cc_pause & PAUSE_TX) | ||
| 1431 | fw_pause |= FW_PORT_CAP32_FC_TX; | ||
| 1432 | |||
| 1433 | return fw_pause; | ||
| 1434 | } | ||
| 1435 | |||
| 1436 | static inline fw_port_cap32_t cc_to_fwcap_fec(enum cc_fec cc_fec) | ||
| 1437 | { | ||
| 1438 | fw_port_cap32_t fw_fec = 0; | ||
| 1439 | |||
| 1440 | if (cc_fec & FEC_RS) | ||
| 1441 | fw_fec |= FW_PORT_CAP32_FEC_RS; | ||
| 1442 | if (cc_fec & FEC_BASER_RS) | ||
| 1443 | fw_fec |= FW_PORT_CAP32_FEC_BASER_RS; | ||
| 1444 | |||
| 1445 | return fw_fec; | ||
| 1446 | } | ||
| 1447 | |||
| 1448 | /** | ||
| 1449 | * fwcap_to_fwspeed - return highest speed in Port Capabilities | ||
| 1450 | * @acaps: advertised Port Capabilities | ||
| 1451 | * | ||
| 1452 | * Get the highest speed for the port from the advertised Port | ||
| 1453 | * Capabilities. | ||
| 1454 | */ | ||
| 1455 | fw_port_cap32_t fwcap_to_fwspeed(fw_port_cap32_t acaps) | ||
| 1456 | { | ||
| 1457 | #define TEST_SPEED_RETURN(__caps_speed) \ | ||
| 1458 | do { \ | ||
| 1459 | if (acaps & FW_PORT_CAP32_SPEED_##__caps_speed) \ | ||
| 1460 | return FW_PORT_CAP32_SPEED_##__caps_speed; \ | ||
| 1461 | } while (0) | ||
| 1462 | |||
| 1463 | TEST_SPEED_RETURN(400G); | ||
| 1464 | TEST_SPEED_RETURN(200G); | ||
| 1465 | TEST_SPEED_RETURN(100G); | ||
| 1466 | TEST_SPEED_RETURN(50G); | ||
| 1467 | TEST_SPEED_RETURN(40G); | ||
| 1468 | TEST_SPEED_RETURN(25G); | ||
| 1469 | TEST_SPEED_RETURN(10G); | ||
| 1470 | TEST_SPEED_RETURN(1G); | ||
| 1471 | TEST_SPEED_RETURN(100M); | ||
| 1472 | |||
| 1473 | #undef TEST_SPEED_RETURN | ||
| 1474 | |||
| 1475 | return 0; | ||
| 1476 | } | ||
| 1477 | |||
| 1478 | /** | ||
| 1479 | * fwcaps16_to_caps32 - convert 16-bit Port Capabilities to 32-bits | ||
| 1480 | * @caps16: a 16-bit Port Capabilities value | ||
| 1481 | * | ||
| 1482 | * Returns the equivalent 32-bit Port Capabilities value. | ||
| 1483 | */ | ||
| 1484 | fw_port_cap32_t fwcaps16_to_caps32(fw_port_cap16_t caps16) | ||
| 1485 | { | ||
| 1486 | fw_port_cap32_t caps32 = 0; | ||
| 1487 | |||
| 1488 | #define CAP16_TO_CAP32(__cap) \ | ||
| 1489 | do { \ | ||
| 1490 | if (caps16 & FW_PORT_CAP_##__cap) \ | ||
| 1491 | caps32 |= FW_PORT_CAP32_##__cap; \ | ||
| 1492 | } while (0) | ||
| 1493 | |||
| 1494 | CAP16_TO_CAP32(SPEED_100M); | ||
| 1495 | CAP16_TO_CAP32(SPEED_1G); | ||
| 1496 | CAP16_TO_CAP32(SPEED_25G); | ||
| 1497 | CAP16_TO_CAP32(SPEED_10G); | ||
| 1498 | CAP16_TO_CAP32(SPEED_40G); | ||
| 1499 | CAP16_TO_CAP32(SPEED_100G); | ||
| 1500 | CAP16_TO_CAP32(FC_RX); | ||
| 1501 | CAP16_TO_CAP32(FC_TX); | ||
| 1502 | CAP16_TO_CAP32(ANEG); | ||
| 1503 | CAP16_TO_CAP32(MDIX); | ||
| 1504 | CAP16_TO_CAP32(MDIAUTO); | ||
| 1505 | CAP16_TO_CAP32(FEC_RS); | ||
| 1506 | CAP16_TO_CAP32(FEC_BASER_RS); | ||
| 1507 | CAP16_TO_CAP32(802_3_PAUSE); | ||
| 1508 | CAP16_TO_CAP32(802_3_ASM_DIR); | ||
| 1509 | |||
| 1510 | #undef CAP16_TO_CAP32 | ||
| 1511 | |||
| 1512 | return caps32; | ||
| 1513 | } | ||
| 1514 | |||
| 1515 | /** | ||
| 1516 | * lstatus_to_fwcap - translate old lstatus to 32-bit Port Capabilities | ||
| 1517 | * @lstatus: old FW_PORT_ACTION_GET_PORT_INFO lstatus value | ||
| 1518 | * | ||
| 1519 | * Translates old FW_PORT_ACTION_GET_PORT_INFO lstatus field into new | ||
| 1520 | * 32-bit Port Capabilities value. | ||
| 1521 | */ | ||
| 1522 | fw_port_cap32_t lstatus_to_fwcap(u32 lstatus) | ||
| 1523 | { | ||
| 1524 | fw_port_cap32_t linkattr = 0; | ||
| 1525 | |||
| 1526 | /* The format of the Link Status in the old | ||
| 1527 | * 16-bit Port Information message isn't the same as the | ||
| 1528 | * 16-bit Port Capabilities bitfield used everywhere else. | ||
| 1529 | */ | ||
| 1530 | if (lstatus & FW_PORT_CMD_RXPAUSE_F) | ||
| 1531 | linkattr |= FW_PORT_CAP32_FC_RX; | ||
| 1532 | if (lstatus & FW_PORT_CMD_TXPAUSE_F) | ||
| 1533 | linkattr |= FW_PORT_CAP32_FC_TX; | ||
| 1534 | if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100M)) | ||
| 1535 | linkattr |= FW_PORT_CAP32_SPEED_100M; | ||
| 1536 | if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_1G)) | ||
| 1537 | linkattr |= FW_PORT_CAP32_SPEED_1G; | ||
| 1538 | if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_10G)) | ||
| 1539 | linkattr |= FW_PORT_CAP32_SPEED_10G; | ||
| 1540 | if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_25G)) | ||
| 1541 | linkattr |= FW_PORT_CAP32_SPEED_25G; | ||
| 1542 | if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_40G)) | ||
| 1543 | linkattr |= FW_PORT_CAP32_SPEED_40G; | ||
| 1544 | if (lstatus & FW_PORT_CMD_LSPEED_V(FW_PORT_CAP_SPEED_100G)) | ||
| 1545 | linkattr |= FW_PORT_CAP32_SPEED_100G; | ||
| 1546 | |||
| 1547 | return linkattr; | ||
| 1548 | } | ||
| 1549 | |||
| 1550 | /** | ||
| 1551 | * csio_init_link_config - initialize a link's SW state | ||
| 1552 | * @lc: pointer to structure holding the link state | ||
| 1553 | * @pcaps: link Port Capabilities | ||
| 1554 | * @acaps: link current Advertised Port Capabilities | ||
| 1555 | * | ||
| 1556 | * Initializes the SW state maintained for each link, including the link's | ||
| 1557 | * capabilities and default speed/flow-control/autonegotiation settings. | ||
| 1558 | */ | ||
| 1559 | static void csio_init_link_config(struct link_config *lc, fw_port_cap32_t pcaps, | ||
| 1560 | fw_port_cap32_t acaps) | ||
| 1561 | { | ||
| 1562 | lc->pcaps = pcaps; | ||
| 1563 | lc->def_acaps = acaps; | ||
| 1564 | lc->lpacaps = 0; | ||
| 1565 | lc->speed_caps = 0; | ||
| 1566 | lc->speed = 0; | ||
| 1567 | lc->requested_fc = PAUSE_RX | PAUSE_TX; | ||
| 1568 | lc->fc = lc->requested_fc; | ||
| 1569 | |||
| 1570 | /* | ||
| 1571 | * For Forward Error Control, we default to whatever the Firmware | ||
| 1572 | * tells us the Link is currently advertising. | ||
| 1573 | */ | ||
| 1574 | lc->requested_fec = FEC_AUTO; | ||
| 1575 | lc->fec = fwcap_to_cc_fec(lc->def_acaps); | ||
| 1576 | |||
| 1577 | /* If the Port is capable of Auto-Negtotiation, initialize it as | ||
| 1578 | * "enabled" and copy over all of the Physical Port Capabilities | ||
| 1579 | * to the Advertised Port Capabilities. Otherwise mark it as | ||
| 1580 | * Auto-Negotiate disabled and select the highest supported speed | ||
| 1581 | * for the link. Note parallel structure in t4_link_l1cfg_core() | ||
| 1582 | * and t4_handle_get_port_info(). | ||
| 1583 | */ | ||
| 1584 | if (lc->pcaps & FW_PORT_CAP32_ANEG) { | ||
| 1585 | lc->acaps = lc->pcaps & ADVERT_MASK; | ||
| 1586 | lc->autoneg = AUTONEG_ENABLE; | ||
| 1587 | lc->requested_fc |= PAUSE_AUTONEG; | ||
| 1588 | } else { | ||
| 1589 | lc->acaps = 0; | ||
| 1590 | lc->autoneg = AUTONEG_DISABLE; | ||
| 1591 | } | ||
| 1592 | } | ||
| 1593 | |||
| 1594 | static void csio_link_l1cfg(struct link_config *lc, uint16_t fw_caps, | ||
| 1595 | uint32_t *rcaps) | ||
| 1596 | { | ||
| 1597 | unsigned int fw_mdi = FW_PORT_CAP32_MDI_V(FW_PORT_CAP32_MDI_AUTO); | ||
| 1598 | fw_port_cap32_t fw_fc, cc_fec, fw_fec, lrcap; | ||
| 1599 | |||
| 1600 | lc->link_ok = 0; | ||
| 1601 | |||
| 1602 | /* | ||
| 1603 | * Convert driver coding of Pause Frame Flow Control settings into the | ||
| 1604 | * Firmware's API. | ||
| 1605 | */ | ||
| 1606 | fw_fc = cc_to_fwcap_pause(lc->requested_fc); | ||
| 1607 | |||
| 1608 | /* | ||
| 1609 | * Convert Common Code Forward Error Control settings into the | ||
| 1610 | * Firmware's API. If the current Requested FEC has "Automatic" | ||
| 1611 | * (IEEE 802.3) specified, then we use whatever the Firmware | ||
| 1612 | * sent us as part of it's IEEE 802.3-based interpratation of | ||
| 1613 | * the Transceiver Module EPROM FEC parameters. Otherwise we | ||
| 1614 | * use whatever is in the current Requested FEC settings. | ||
| 1615 | */ | ||
| 1616 | if (lc->requested_fec & FEC_AUTO) | ||
| 1617 | cc_fec = fwcap_to_cc_fec(lc->def_acaps); | ||
| 1618 | else | ||
| 1619 | cc_fec = lc->requested_fec; | ||
| 1620 | fw_fec = cc_to_fwcap_fec(cc_fec); | ||
| 1621 | |||
| 1622 | /* Figure out what our Requested Port Capabilities are going to be. | ||
| 1623 | * Note parallel structure in t4_handle_get_port_info() and | ||
| 1624 | * init_link_config(). | ||
| 1625 | */ | ||
| 1626 | if (!(lc->pcaps & FW_PORT_CAP32_ANEG)) { | ||
| 1627 | lrcap = (lc->pcaps & ADVERT_MASK) | fw_fc | fw_fec; | ||
| 1628 | lc->fc = lc->requested_fc & ~PAUSE_AUTONEG; | ||
| 1629 | lc->fec = cc_fec; | ||
| 1630 | } else if (lc->autoneg == AUTONEG_DISABLE) { | ||
| 1631 | lrcap = lc->speed_caps | fw_fc | fw_fec | fw_mdi; | ||
| 1632 | lc->fc = lc->requested_fc & ~PAUSE_AUTONEG; | ||
| 1633 | lc->fec = cc_fec; | ||
| 1634 | } else { | ||
| 1635 | lrcap = lc->acaps | fw_fc | fw_fec | fw_mdi; | ||
| 1636 | } | ||
| 1637 | |||
| 1638 | *rcaps = lrcap; | ||
| 1639 | } | ||
| 1640 | |||
| 1412 | /* | 1641 | /* |
| 1413 | * csio_enable_ports - Bring up all available ports. | 1642 | * csio_enable_ports - Bring up all available ports. |
| 1414 | * @hw: HW module. | 1643 | * @hw: HW module. |
| @@ -1418,8 +1647,10 @@ static int | |||
| 1418 | csio_enable_ports(struct csio_hw *hw) | 1647 | csio_enable_ports(struct csio_hw *hw) |
| 1419 | { | 1648 | { |
| 1420 | struct csio_mb *mbp; | 1649 | struct csio_mb *mbp; |
| 1650 | u16 fw_caps = FW_CAPS_UNKNOWN; | ||
| 1421 | enum fw_retval retval; | 1651 | enum fw_retval retval; |
| 1422 | uint8_t portid; | 1652 | uint8_t portid; |
| 1653 | fw_port_cap32_t pcaps, acaps, rcaps; | ||
| 1423 | int i; | 1654 | int i; |
| 1424 | 1655 | ||
| 1425 | mbp = mempool_alloc(hw->mb_mempool, GFP_ATOMIC); | 1656 | mbp = mempool_alloc(hw->mb_mempool, GFP_ATOMIC); |
| @@ -1431,9 +1662,39 @@ csio_enable_ports(struct csio_hw *hw) | |||
| 1431 | for (i = 0; i < hw->num_pports; i++) { | 1662 | for (i = 0; i < hw->num_pports; i++) { |
| 1432 | portid = hw->pport[i].portid; | 1663 | portid = hw->pport[i].portid; |
| 1433 | 1664 | ||
| 1665 | if (fw_caps == FW_CAPS_UNKNOWN) { | ||
| 1666 | u32 param, val; | ||
| 1667 | |||
| 1668 | param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_PFVF) | | ||
| 1669 | FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_PFVF_PORT_CAPS32)); | ||
| 1670 | val = 1; | ||
| 1671 | |||
| 1672 | csio_mb_params(hw, mbp, CSIO_MB_DEFAULT_TMO, | ||
| 1673 | hw->pfn, 0, 1, ¶m, &val, false, | ||
| 1674 | NULL); | ||
| 1675 | |||
| 1676 | if (csio_mb_issue(hw, mbp)) { | ||
| 1677 | csio_err(hw, "failed to issue FW_PARAMS_CMD(r) port:%d\n", | ||
| 1678 | portid); | ||
| 1679 | mempool_free(mbp, hw->mb_mempool); | ||
| 1680 | return -EINVAL; | ||
| 1681 | } | ||
| 1682 | |||
| 1683 | csio_mb_process_read_params_rsp(hw, mbp, &retval, 1, | ||
| 1684 | &val); | ||
| 1685 | if (retval != FW_SUCCESS) { | ||
| 1686 | csio_err(hw, "FW_PARAMS_CMD(r) port:%d failed: 0x%x\n", | ||
| 1687 | portid, retval); | ||
| 1688 | mempool_free(mbp, hw->mb_mempool); | ||
| 1689 | return -EINVAL; | ||
| 1690 | } | ||
| 1691 | |||
| 1692 | fw_caps = val; | ||
| 1693 | } | ||
| 1694 | |||
| 1434 | /* Read PORT information */ | 1695 | /* Read PORT information */ |
| 1435 | csio_mb_port(hw, mbp, CSIO_MB_DEFAULT_TMO, portid, | 1696 | csio_mb_port(hw, mbp, CSIO_MB_DEFAULT_TMO, portid, |
| 1436 | false, 0, 0, NULL); | 1697 | false, 0, fw_caps, NULL); |
| 1437 | 1698 | ||
| 1438 | if (csio_mb_issue(hw, mbp)) { | 1699 | if (csio_mb_issue(hw, mbp)) { |
| 1439 | csio_err(hw, "failed to issue FW_PORT_CMD(r) port:%d\n", | 1700 | csio_err(hw, "failed to issue FW_PORT_CMD(r) port:%d\n", |
| @@ -1442,8 +1703,8 @@ csio_enable_ports(struct csio_hw *hw) | |||
| 1442 | return -EINVAL; | 1703 | return -EINVAL; |
| 1443 | } | 1704 | } |
| 1444 | 1705 | ||
| 1445 | csio_mb_process_read_port_rsp(hw, mbp, &retval, | 1706 | csio_mb_process_read_port_rsp(hw, mbp, &retval, fw_caps, |
| 1446 | &hw->pport[i].pcap); | 1707 | &pcaps, &acaps); |
| 1447 | if (retval != FW_SUCCESS) { | 1708 | if (retval != FW_SUCCESS) { |
| 1448 | csio_err(hw, "FW_PORT_CMD(r) port:%d failed: 0x%x\n", | 1709 | csio_err(hw, "FW_PORT_CMD(r) port:%d failed: 0x%x\n", |
| 1449 | portid, retval); | 1710 | portid, retval); |
| @@ -1451,9 +1712,13 @@ csio_enable_ports(struct csio_hw *hw) | |||
| 1451 | return -EINVAL; | 1712 | return -EINVAL; |
| 1452 | } | 1713 | } |
| 1453 | 1714 | ||
| 1715 | csio_init_link_config(&hw->pport[i].link_cfg, pcaps, acaps); | ||
| 1716 | |||
| 1717 | csio_link_l1cfg(&hw->pport[i].link_cfg, fw_caps, &rcaps); | ||
| 1718 | |||
| 1454 | /* Write back PORT information */ | 1719 | /* Write back PORT information */ |
| 1455 | csio_mb_port(hw, mbp, CSIO_MB_DEFAULT_TMO, portid, true, | 1720 | csio_mb_port(hw, mbp, CSIO_MB_DEFAULT_TMO, portid, |
| 1456 | (PAUSE_RX | PAUSE_TX), hw->pport[i].pcap, NULL); | 1721 | true, rcaps, fw_caps, NULL); |
| 1457 | 1722 | ||
| 1458 | if (csio_mb_issue(hw, mbp)) { | 1723 | if (csio_mb_issue(hw, mbp)) { |
| 1459 | csio_err(hw, "failed to issue FW_PORT_CMD(w) port:%d\n", | 1724 | csio_err(hw, "failed to issue FW_PORT_CMD(w) port:%d\n", |
diff --git a/drivers/scsi/csiostor/csio_hw.h b/drivers/scsi/csiostor/csio_hw.h index 30f5f523c8cc..9e73ef771eb7 100644 --- a/drivers/scsi/csiostor/csio_hw.h +++ b/drivers/scsi/csiostor/csio_hw.h | |||
| @@ -268,8 +268,62 @@ struct csio_vpd { | |||
| 268 | uint8_t id[ID_LEN + 1]; | 268 | uint8_t id[ID_LEN + 1]; |
| 269 | }; | 269 | }; |
| 270 | 270 | ||
| 271 | /* Firmware Port Capabilities types. */ | ||
| 272 | |||
| 273 | typedef u16 fw_port_cap16_t; /* 16-bit Port Capabilities integral value */ | ||
| 274 | typedef u32 fw_port_cap32_t; /* 32-bit Port Capabilities integral value */ | ||
| 275 | |||
| 276 | enum fw_caps { | ||
| 277 | FW_CAPS_UNKNOWN = 0, /* 0'ed out initial state */ | ||
| 278 | FW_CAPS16 = 1, /* old Firmware: 16-bit Port Capabilities */ | ||
| 279 | FW_CAPS32 = 2, /* new Firmware: 32-bit Port Capabilities */ | ||
| 280 | }; | ||
| 281 | |||
| 282 | enum cc_pause { | ||
| 283 | PAUSE_RX = 1 << 0, | ||
| 284 | PAUSE_TX = 1 << 1, | ||
| 285 | PAUSE_AUTONEG = 1 << 2 | ||
| 286 | }; | ||
| 287 | |||
| 288 | enum cc_fec { | ||
| 289 | FEC_AUTO = 1 << 0, /* IEEE 802.3 "automatic" */ | ||
| 290 | FEC_RS = 1 << 1, /* Reed-Solomon */ | ||
| 291 | FEC_BASER_RS = 1 << 2 /* BaseR/Reed-Solomon */ | ||
| 292 | }; | ||
| 293 | |||
| 294 | struct link_config { | ||
| 295 | fw_port_cap32_t pcaps; /* link capabilities */ | ||
| 296 | fw_port_cap32_t def_acaps; /* default advertised capabilities */ | ||
| 297 | fw_port_cap32_t acaps; /* advertised capabilities */ | ||
| 298 | fw_port_cap32_t lpacaps; /* peer advertised capabilities */ | ||
| 299 | |||
| 300 | fw_port_cap32_t speed_caps; /* speed(s) user has requested */ | ||
| 301 | unsigned int speed; /* actual link speed (Mb/s) */ | ||
| 302 | |||
| 303 | enum cc_pause requested_fc; /* flow control user has requested */ | ||
| 304 | enum cc_pause fc; /* actual link flow control */ | ||
| 305 | |||
| 306 | enum cc_fec requested_fec; /* Forward Error Correction: */ | ||
| 307 | enum cc_fec fec; /* requested and actual in use */ | ||
| 308 | |||
| 309 | unsigned char autoneg; /* autonegotiating? */ | ||
| 310 | |||
| 311 | unsigned char link_ok; /* link up? */ | ||
| 312 | unsigned char link_down_rc; /* link down reason */ | ||
| 313 | }; | ||
| 314 | |||
| 315 | #define FW_LEN16(fw_struct) FW_CMD_LEN16_V(sizeof(fw_struct) / 16) | ||
| 316 | |||
| 317 | #define ADVERT_MASK (FW_PORT_CAP32_SPEED_V(FW_PORT_CAP32_SPEED_M) | \ | ||
| 318 | FW_PORT_CAP32_ANEG) | ||
| 319 | |||
| 320 | /* Enable or disable autonegotiation. */ | ||
| 321 | #define AUTONEG_DISABLE 0x00 | ||
| 322 | #define AUTONEG_ENABLE 0x01 | ||
| 323 | |||
| 271 | struct csio_pport { | 324 | struct csio_pport { |
| 272 | uint16_t pcap; | 325 | uint16_t pcap; |
| 326 | uint16_t acap; | ||
| 273 | uint8_t portid; | 327 | uint8_t portid; |
| 274 | uint8_t link_status; | 328 | uint8_t link_status; |
| 275 | uint16_t link_speed; | 329 | uint16_t link_speed; |
| @@ -278,6 +332,7 @@ struct csio_pport { | |||
| 278 | uint8_t rsvd1; | 332 | uint8_t rsvd1; |
| 279 | uint8_t rsvd2; | 333 | uint8_t rsvd2; |
| 280 | uint8_t rsvd3; | 334 | uint8_t rsvd3; |
| 335 | struct link_config link_cfg; | ||
| 281 | }; | 336 | }; |
| 282 | 337 | ||
| 283 | /* fcoe resource information */ | 338 | /* fcoe resource information */ |
| @@ -582,6 +637,10 @@ int csio_hw_slow_intr_handler(struct csio_hw *); | |||
| 582 | int csio_handle_intr_status(struct csio_hw *, unsigned int, | 637 | int csio_handle_intr_status(struct csio_hw *, unsigned int, |
| 583 | const struct intr_info *); | 638 | const struct intr_info *); |
| 584 | 639 | ||
| 640 | fw_port_cap32_t fwcap_to_fwspeed(fw_port_cap32_t acaps); | ||
| 641 | fw_port_cap32_t fwcaps16_to_caps32(fw_port_cap16_t caps16); | ||
| 642 | fw_port_cap32_t lstatus_to_fwcap(u32 lstatus); | ||
| 643 | |||
| 585 | int csio_hw_start(struct csio_hw *); | 644 | int csio_hw_start(struct csio_hw *); |
| 586 | int csio_hw_stop(struct csio_hw *); | 645 | int csio_hw_stop(struct csio_hw *); |
| 587 | int csio_hw_reset(struct csio_hw *); | 646 | int csio_hw_reset(struct csio_hw *); |
diff --git a/drivers/scsi/csiostor/csio_lnode.c b/drivers/scsi/csiostor/csio_lnode.c index 7dbbbb81a1e7..cc5611efc7a9 100644 --- a/drivers/scsi/csiostor/csio_lnode.c +++ b/drivers/scsi/csiostor/csio_lnode.c | |||
| @@ -352,6 +352,14 @@ csio_ln_fdmi_rhba_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req) | |||
| 352 | val = htonl(FC_PORTSPEED_1GBIT); | 352 | val = htonl(FC_PORTSPEED_1GBIT); |
| 353 | else if (hw->pport[ln->portid].link_speed == FW_PORT_CAP_SPEED_10G) | 353 | else if (hw->pport[ln->portid].link_speed == FW_PORT_CAP_SPEED_10G) |
| 354 | val = htonl(FC_PORTSPEED_10GBIT); | 354 | val = htonl(FC_PORTSPEED_10GBIT); |
| 355 | else if (hw->pport[ln->portid].link_speed == FW_PORT_CAP32_SPEED_25G) | ||
| 356 | val = htonl(FC_PORTSPEED_25GBIT); | ||
| 357 | else if (hw->pport[ln->portid].link_speed == FW_PORT_CAP32_SPEED_40G) | ||
| 358 | val = htonl(FC_PORTSPEED_40GBIT); | ||
| 359 | else if (hw->pport[ln->portid].link_speed == FW_PORT_CAP32_SPEED_50G) | ||
| 360 | val = htonl(FC_PORTSPEED_50GBIT); | ||
| 361 | else if (hw->pport[ln->portid].link_speed == FW_PORT_CAP32_SPEED_100G) | ||
| 362 | val = htonl(FC_PORTSPEED_100GBIT); | ||
| 355 | else | 363 | else |
| 356 | val = htonl(CSIO_HBA_PORTSPEED_UNKNOWN); | 364 | val = htonl(CSIO_HBA_PORTSPEED_UNKNOWN); |
| 357 | csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_CURRENTPORTSPEED, | 365 | csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_CURRENTPORTSPEED, |
diff --git a/drivers/scsi/csiostor/csio_mb.c b/drivers/scsi/csiostor/csio_mb.c index 5f4e0a787bd1..c026417269c3 100644 --- a/drivers/scsi/csiostor/csio_mb.c +++ b/drivers/scsi/csiostor/csio_mb.c | |||
| @@ -326,10 +326,6 @@ csio_mb_caps_config(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, | |||
| 326 | cmdp->fcoecaps |= htons(FW_CAPS_CONFIG_FCOE_TARGET); | 326 | cmdp->fcoecaps |= htons(FW_CAPS_CONFIG_FCOE_TARGET); |
| 327 | } | 327 | } |
| 328 | 328 | ||
| 329 | #define CSIO_ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\ | ||
| 330 | FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_40G |\ | ||
| 331 | FW_PORT_CAP_ANEG) | ||
| 332 | |||
| 333 | /* | 329 | /* |
| 334 | * csio_mb_port- FW PORT command helper | 330 | * csio_mb_port- FW PORT command helper |
| 335 | * @hw: The HW structure | 331 | * @hw: The HW structure |
| @@ -344,11 +340,10 @@ csio_mb_caps_config(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, | |||
| 344 | */ | 340 | */ |
| 345 | void | 341 | void |
| 346 | csio_mb_port(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, | 342 | csio_mb_port(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, |
| 347 | uint8_t portid, bool wr, uint32_t fc, uint16_t caps, | 343 | u8 portid, bool wr, uint32_t fc, uint16_t fw_caps, |
| 348 | void (*cbfn) (struct csio_hw *, struct csio_mb *)) | 344 | void (*cbfn) (struct csio_hw *, struct csio_mb *)) |
| 349 | { | 345 | { |
| 350 | struct fw_port_cmd *cmdp = (struct fw_port_cmd *)(mbp->mb); | 346 | struct fw_port_cmd *cmdp = (struct fw_port_cmd *)(mbp->mb); |
| 351 | unsigned int lfc = 0, mdi = FW_PORT_CAP_MDI_V(FW_PORT_CAP_MDI_AUTO); | ||
| 352 | 347 | ||
| 353 | CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn, 1); | 348 | CSIO_INIT_MBP(mbp, cmdp, tmo, hw, cbfn, 1); |
| 354 | 349 | ||
| @@ -358,26 +353,24 @@ csio_mb_port(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, | |||
| 358 | FW_PORT_CMD_PORTID_V(portid)); | 353 | FW_PORT_CMD_PORTID_V(portid)); |
| 359 | if (!wr) { | 354 | if (!wr) { |
| 360 | cmdp->action_to_len16 = htonl( | 355 | cmdp->action_to_len16 = htonl( |
| 361 | FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_GET_PORT_INFO) | | 356 | FW_PORT_CMD_ACTION_V(fw_caps == FW_CAPS16 |
| 357 | ? FW_PORT_ACTION_GET_PORT_INFO | ||
| 358 | : FW_PORT_ACTION_GET_PORT_INFO32) | | ||
| 362 | FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); | 359 | FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); |
| 363 | return; | 360 | return; |
| 364 | } | 361 | } |
| 365 | 362 | ||
| 366 | /* Set port */ | 363 | /* Set port */ |
| 367 | cmdp->action_to_len16 = htonl( | 364 | cmdp->action_to_len16 = htonl( |
| 368 | FW_PORT_CMD_ACTION_V(FW_PORT_ACTION_L1_CFG) | | 365 | FW_PORT_CMD_ACTION_V(fw_caps == FW_CAPS16 |
| 366 | ? FW_PORT_ACTION_L1_CFG | ||
| 367 | : FW_PORT_ACTION_L1_CFG32) | | ||
| 369 | FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); | 368 | FW_CMD_LEN16_V(sizeof(*cmdp) / 16)); |
| 370 | 369 | ||
| 371 | if (fc & PAUSE_RX) | 370 | if (fw_caps == FW_CAPS16) |
| 372 | lfc |= FW_PORT_CAP_FC_RX; | 371 | cmdp->u.l1cfg.rcap = cpu_to_be32(fc); |
| 373 | if (fc & PAUSE_TX) | ||
| 374 | lfc |= FW_PORT_CAP_FC_TX; | ||
| 375 | |||
| 376 | if (!(caps & FW_PORT_CAP_ANEG)) | ||
| 377 | cmdp->u.l1cfg.rcap = htonl((caps & CSIO_ADVERT_MASK) | lfc); | ||
| 378 | else | 372 | else |
| 379 | cmdp->u.l1cfg.rcap = htonl((caps & CSIO_ADVERT_MASK) | | 373 | cmdp->u.l1cfg32.rcap32 = cpu_to_be32(fc); |
| 380 | lfc | mdi); | ||
| 381 | } | 374 | } |
| 382 | 375 | ||
| 383 | /* | 376 | /* |
| @@ -390,14 +383,22 @@ csio_mb_port(struct csio_hw *hw, struct csio_mb *mbp, uint32_t tmo, | |||
| 390 | */ | 383 | */ |
| 391 | void | 384 | void |
| 392 | csio_mb_process_read_port_rsp(struct csio_hw *hw, struct csio_mb *mbp, | 385 | csio_mb_process_read_port_rsp(struct csio_hw *hw, struct csio_mb *mbp, |
| 393 | enum fw_retval *retval, uint16_t *caps) | 386 | enum fw_retval *retval, uint16_t fw_caps, |
| 387 | u32 *pcaps, u32 *acaps) | ||
| 394 | { | 388 | { |
| 395 | struct fw_port_cmd *rsp = (struct fw_port_cmd *)(mbp->mb); | 389 | struct fw_port_cmd *rsp = (struct fw_port_cmd *)(mbp->mb); |
| 396 | 390 | ||
| 397 | *retval = FW_CMD_RETVAL_G(ntohl(rsp->action_to_len16)); | 391 | *retval = FW_CMD_RETVAL_G(ntohl(rsp->action_to_len16)); |
| 398 | 392 | ||
| 399 | if (*retval == FW_SUCCESS) | 393 | if (*retval == FW_SUCCESS) { |
| 400 | *caps = ntohs(rsp->u.info.pcap); | 394 | if (fw_caps == FW_CAPS16) { |
| 395 | *pcaps = fwcaps16_to_caps32(ntohs(rsp->u.info.pcap)); | ||
| 396 | *acaps = fwcaps16_to_caps32(ntohs(rsp->u.info.acap)); | ||
| 397 | } else { | ||
| 398 | *pcaps = ntohs(rsp->u.info32.pcaps32); | ||
| 399 | *acaps = ntohs(rsp->u.info32.acaps32); | ||
| 400 | } | ||
| 401 | } | ||
| 401 | } | 402 | } |
| 402 | 403 | ||
| 403 | /* | 404 | /* |
| @@ -1409,6 +1410,7 @@ csio_mb_fwevt_handler(struct csio_hw *hw, __be64 *cmd) | |||
| 1409 | uint32_t link_status; | 1410 | uint32_t link_status; |
| 1410 | uint16_t action; | 1411 | uint16_t action; |
| 1411 | uint8_t mod_type; | 1412 | uint8_t mod_type; |
| 1413 | fw_port_cap32_t linkattr; | ||
| 1412 | 1414 | ||
| 1413 | if (opcode == FW_PORT_CMD) { | 1415 | if (opcode == FW_PORT_CMD) { |
| 1414 | pcmd = (struct fw_port_cmd *)cmd; | 1416 | pcmd = (struct fw_port_cmd *)cmd; |
| @@ -1416,22 +1418,34 @@ csio_mb_fwevt_handler(struct csio_hw *hw, __be64 *cmd) | |||
| 1416 | ntohl(pcmd->op_to_portid)); | 1418 | ntohl(pcmd->op_to_portid)); |
| 1417 | action = FW_PORT_CMD_ACTION_G( | 1419 | action = FW_PORT_CMD_ACTION_G( |
| 1418 | ntohl(pcmd->action_to_len16)); | 1420 | ntohl(pcmd->action_to_len16)); |
| 1419 | if (action != FW_PORT_ACTION_GET_PORT_INFO) { | 1421 | if (action != FW_PORT_ACTION_GET_PORT_INFO && |
| 1422 | action != FW_PORT_ACTION_GET_PORT_INFO32) { | ||
| 1420 | csio_err(hw, "Unhandled FW_PORT_CMD action: %u\n", | 1423 | csio_err(hw, "Unhandled FW_PORT_CMD action: %u\n", |
| 1421 | action); | 1424 | action); |
| 1422 | return -EINVAL; | 1425 | return -EINVAL; |
| 1423 | } | 1426 | } |
| 1424 | 1427 | ||
| 1425 | link_status = ntohl(pcmd->u.info.lstatus_to_modtype); | 1428 | if (action == FW_PORT_ACTION_GET_PORT_INFO) { |
| 1426 | mod_type = FW_PORT_CMD_MODTYPE_G(link_status); | 1429 | link_status = ntohl(pcmd->u.info.lstatus_to_modtype); |
| 1430 | mod_type = FW_PORT_CMD_MODTYPE_G(link_status); | ||
| 1431 | linkattr = lstatus_to_fwcap(link_status); | ||
| 1432 | |||
| 1433 | hw->pport[port_id].link_status = | ||
| 1434 | FW_PORT_CMD_LSTATUS_G(link_status); | ||
| 1435 | } else { | ||
| 1436 | link_status = | ||
| 1437 | ntohl(pcmd->u.info32.lstatus32_to_cbllen32); | ||
| 1438 | mod_type = FW_PORT_CMD_MODTYPE32_G(link_status); | ||
| 1439 | linkattr = ntohl(pcmd->u.info32.linkattr32); | ||
| 1440 | |||
| 1441 | hw->pport[port_id].link_status = | ||
| 1442 | FW_PORT_CMD_LSTATUS32_G(link_status); | ||
| 1443 | } | ||
| 1427 | 1444 | ||
| 1428 | hw->pport[port_id].link_status = | 1445 | hw->pport[port_id].link_speed = fwcap_to_fwspeed(linkattr); |
| 1429 | FW_PORT_CMD_LSTATUS_G(link_status); | ||
| 1430 | hw->pport[port_id].link_speed = | ||
| 1431 | FW_PORT_CMD_LSPEED_G(link_status); | ||
| 1432 | 1446 | ||
| 1433 | csio_info(hw, "Port:%x - LINK %s\n", port_id, | 1447 | csio_info(hw, "Port:%x - LINK %s\n", port_id, |
| 1434 | FW_PORT_CMD_LSTATUS_G(link_status) ? "UP" : "DOWN"); | 1448 | hw->pport[port_id].link_status ? "UP" : "DOWN"); |
| 1435 | 1449 | ||
| 1436 | if (mod_type != hw->pport[port_id].mod_type) { | 1450 | if (mod_type != hw->pport[port_id].mod_type) { |
| 1437 | hw->pport[port_id].mod_type = mod_type; | 1451 | hw->pport[port_id].mod_type = mod_type; |
diff --git a/drivers/scsi/csiostor/csio_mb.h b/drivers/scsi/csiostor/csio_mb.h index a6823df73015..b07e891c5936 100644 --- a/drivers/scsi/csiostor/csio_mb.h +++ b/drivers/scsi/csiostor/csio_mb.h | |||
| @@ -88,12 +88,6 @@ enum csio_dev_state { | |||
| 88 | FW_PARAMS_PARAM_Y_V(0) | \ | 88 | FW_PARAMS_PARAM_Y_V(0) | \ |
| 89 | FW_PARAMS_PARAM_Z_V(0)) | 89 | FW_PARAMS_PARAM_Z_V(0)) |
| 90 | 90 | ||
| 91 | enum { | ||
| 92 | PAUSE_RX = 1 << 0, | ||
| 93 | PAUSE_TX = 1 << 1, | ||
| 94 | PAUSE_AUTONEG = 1 << 2 | ||
| 95 | }; | ||
| 96 | |||
| 97 | #define CSIO_INIT_MBP(__mbp, __cp, __tmo, __priv, __fn, __clear) \ | 91 | #define CSIO_INIT_MBP(__mbp, __cp, __tmo, __priv, __fn, __clear) \ |
| 98 | do { \ | 92 | do { \ |
| 99 | if (__clear) \ | 93 | if (__clear) \ |
| @@ -189,7 +183,8 @@ void csio_mb_port(struct csio_hw *, struct csio_mb *, uint32_t, | |||
| 189 | void (*) (struct csio_hw *, struct csio_mb *)); | 183 | void (*) (struct csio_hw *, struct csio_mb *)); |
| 190 | 184 | ||
| 191 | void csio_mb_process_read_port_rsp(struct csio_hw *, struct csio_mb *, | 185 | void csio_mb_process_read_port_rsp(struct csio_hw *, struct csio_mb *, |
| 192 | enum fw_retval *, uint16_t *); | 186 | enum fw_retval *, uint16_t, |
| 187 | uint32_t *, uint32_t *); | ||
| 193 | 188 | ||
| 194 | void csio_mb_initialize(struct csio_hw *, struct csio_mb *, uint32_t, | 189 | void csio_mb_initialize(struct csio_hw *, struct csio_mb *, uint32_t, |
| 195 | void (*)(struct csio_hw *, struct csio_mb *)); | 190 | void (*)(struct csio_hw *, struct csio_mb *)); |
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 4b44325d1a82..12dc7100bb4c 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c | |||
| @@ -138,12 +138,12 @@ static void release_port_group(struct kref *kref) | |||
| 138 | static int submit_rtpg(struct scsi_device *sdev, unsigned char *buff, | 138 | static int submit_rtpg(struct scsi_device *sdev, unsigned char *buff, |
| 139 | int bufflen, struct scsi_sense_hdr *sshdr, int flags) | 139 | int bufflen, struct scsi_sense_hdr *sshdr, int flags) |
| 140 | { | 140 | { |
| 141 | u8 cdb[COMMAND_SIZE(MAINTENANCE_IN)]; | 141 | u8 cdb[MAX_COMMAND_SIZE]; |
| 142 | int req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | | 142 | int req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | |
| 143 | REQ_FAILFAST_DRIVER; | 143 | REQ_FAILFAST_DRIVER; |
| 144 | 144 | ||
| 145 | /* Prepare the command. */ | 145 | /* Prepare the command. */ |
| 146 | memset(cdb, 0x0, COMMAND_SIZE(MAINTENANCE_IN)); | 146 | memset(cdb, 0x0, MAX_COMMAND_SIZE); |
| 147 | cdb[0] = MAINTENANCE_IN; | 147 | cdb[0] = MAINTENANCE_IN; |
| 148 | if (!(flags & ALUA_RTPG_EXT_HDR_UNSUPP)) | 148 | if (!(flags & ALUA_RTPG_EXT_HDR_UNSUPP)) |
| 149 | cdb[1] = MI_REPORT_TARGET_PGS | MI_EXT_HDR_PARAM_FMT; | 149 | cdb[1] = MI_REPORT_TARGET_PGS | MI_EXT_HDR_PARAM_FMT; |
| @@ -166,7 +166,7 @@ static int submit_rtpg(struct scsi_device *sdev, unsigned char *buff, | |||
| 166 | static int submit_stpg(struct scsi_device *sdev, int group_id, | 166 | static int submit_stpg(struct scsi_device *sdev, int group_id, |
| 167 | struct scsi_sense_hdr *sshdr) | 167 | struct scsi_sense_hdr *sshdr) |
| 168 | { | 168 | { |
| 169 | u8 cdb[COMMAND_SIZE(MAINTENANCE_OUT)]; | 169 | u8 cdb[MAX_COMMAND_SIZE]; |
| 170 | unsigned char stpg_data[8]; | 170 | unsigned char stpg_data[8]; |
| 171 | int stpg_len = 8; | 171 | int stpg_len = 8; |
| 172 | int req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | | 172 | int req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | |
| @@ -178,7 +178,7 @@ static int submit_stpg(struct scsi_device *sdev, int group_id, | |||
| 178 | put_unaligned_be16(group_id, &stpg_data[6]); | 178 | put_unaligned_be16(group_id, &stpg_data[6]); |
| 179 | 179 | ||
| 180 | /* Prepare the command. */ | 180 | /* Prepare the command. */ |
| 181 | memset(cdb, 0x0, COMMAND_SIZE(MAINTENANCE_OUT)); | 181 | memset(cdb, 0x0, MAX_COMMAND_SIZE); |
| 182 | cdb[0] = MAINTENANCE_OUT; | 182 | cdb[0] = MAINTENANCE_OUT; |
| 183 | cdb[1] = MO_SET_TARGET_PGS; | 183 | cdb[1] = MO_SET_TARGET_PGS; |
| 184 | put_unaligned_be32(stpg_len, &cdb[6]); | 184 | put_unaligned_be32(stpg_len, &cdb[6]); |
| @@ -214,8 +214,8 @@ static struct alua_port_group *alua_find_get_pg(char *id_str, size_t id_size, | |||
| 214 | /* | 214 | /* |
| 215 | * alua_alloc_pg - Allocate a new port_group structure | 215 | * alua_alloc_pg - Allocate a new port_group structure |
| 216 | * @sdev: scsi device | 216 | * @sdev: scsi device |
| 217 | * @h: alua device_handler data | ||
| 218 | * @group_id: port group id | 217 | * @group_id: port group id |
| 218 | * @tpgs: target port group settings | ||
| 219 | * | 219 | * |
| 220 | * Allocate a new port_group structure for a given | 220 | * Allocate a new port_group structure for a given |
| 221 | * device. | 221 | * device. |
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c index 6a2792f3a37e..95c47909a58f 100644 --- a/drivers/scsi/device_handler/scsi_dh_emc.c +++ b/drivers/scsi/device_handler/scsi_dh_emc.c | |||
| @@ -249,7 +249,7 @@ static int send_trespass_cmd(struct scsi_device *sdev, | |||
| 249 | struct clariion_dh_data *csdev) | 249 | struct clariion_dh_data *csdev) |
| 250 | { | 250 | { |
| 251 | unsigned char *page22; | 251 | unsigned char *page22; |
| 252 | unsigned char cdb[COMMAND_SIZE(MODE_SELECT)]; | 252 | unsigned char cdb[MAX_COMMAND_SIZE]; |
| 253 | int err, res = SCSI_DH_OK, len; | 253 | int err, res = SCSI_DH_OK, len; |
| 254 | struct scsi_sense_hdr sshdr; | 254 | struct scsi_sense_hdr sshdr; |
| 255 | u64 req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | | 255 | u64 req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | |
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c index 7af31a1247ee..d27fabae8ddd 100644 --- a/drivers/scsi/device_handler/scsi_dh_rdac.c +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c | |||
| @@ -533,7 +533,7 @@ static void send_mode_select(struct work_struct *work) | |||
| 533 | int err = SCSI_DH_OK, retry_cnt = RDAC_RETRY_COUNT; | 533 | int err = SCSI_DH_OK, retry_cnt = RDAC_RETRY_COUNT; |
| 534 | struct rdac_queue_data *tmp, *qdata; | 534 | struct rdac_queue_data *tmp, *qdata; |
| 535 | LIST_HEAD(list); | 535 | LIST_HEAD(list); |
| 536 | unsigned char cdb[COMMAND_SIZE(MODE_SELECT_10)]; | 536 | unsigned char cdb[MAX_COMMAND_SIZE]; |
| 537 | struct scsi_sense_hdr sshdr; | 537 | struct scsi_sense_hdr sshdr; |
| 538 | unsigned int data_size; | 538 | unsigned int data_size; |
| 539 | u64 req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | | 539 | u64 req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | |
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index a00d822e3142..6866975b25f3 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c | |||
| @@ -302,16 +302,14 @@ rebuild_sys_tab: | |||
| 302 | } | 302 | } |
| 303 | 303 | ||
| 304 | 304 | ||
| 305 | /* | 305 | static void adpt_release(adpt_hba *pHba) |
| 306 | * scsi_unregister will be called AFTER we return. | ||
| 307 | */ | ||
| 308 | static int adpt_release(struct Scsi_Host *host) | ||
| 309 | { | 306 | { |
| 310 | adpt_hba* pHba = (adpt_hba*) host->hostdata[0]; | 307 | struct Scsi_Host *shost = pHba->host; |
| 308 | |||
| 309 | scsi_remove_host(shost); | ||
| 311 | // adpt_i2o_quiesce_hba(pHba); | 310 | // adpt_i2o_quiesce_hba(pHba); |
| 312 | adpt_i2o_delete_hba(pHba); | 311 | adpt_i2o_delete_hba(pHba); |
| 313 | scsi_unregister(host); | 312 | scsi_host_put(shost); |
| 314 | return 0; | ||
| 315 | } | 313 | } |
| 316 | 314 | ||
| 317 | 315 | ||
| @@ -801,14 +799,17 @@ static int __adpt_reset(struct scsi_cmnd* cmd) | |||
| 801 | { | 799 | { |
| 802 | adpt_hba* pHba; | 800 | adpt_hba* pHba; |
| 803 | int rcode; | 801 | int rcode; |
| 802 | char name[32]; | ||
| 803 | |||
| 804 | pHba = (adpt_hba*)cmd->device->host->hostdata[0]; | 804 | pHba = (adpt_hba*)cmd->device->host->hostdata[0]; |
| 805 | printk(KERN_WARNING"%s: Hba Reset: scsi id %d: tid: %d\n",pHba->name,cmd->device->channel,pHba->channel[cmd->device->channel].tid ); | 805 | strncpy(name, pHba->name, sizeof(name)); |
| 806 | printk(KERN_WARNING"%s: Hba Reset: scsi id %d: tid: %d\n", name, cmd->device->channel, pHba->channel[cmd->device->channel].tid); | ||
| 806 | rcode = adpt_hba_reset(pHba); | 807 | rcode = adpt_hba_reset(pHba); |
| 807 | if(rcode == 0){ | 808 | if(rcode == 0){ |
| 808 | printk(KERN_WARNING"%s: HBA reset complete\n",pHba->name); | 809 | printk(KERN_WARNING"%s: HBA reset complete\n", name); |
| 809 | return SUCCESS; | 810 | return SUCCESS; |
| 810 | } else { | 811 | } else { |
| 811 | printk(KERN_WARNING"%s: HBA reset failed (%x)\n",pHba->name, rcode); | 812 | printk(KERN_WARNING"%s: HBA reset failed (%x)\n", name, rcode); |
| 812 | return FAILED; | 813 | return FAILED; |
| 813 | } | 814 | } |
| 814 | } | 815 | } |
| @@ -1087,8 +1088,6 @@ static void adpt_i2o_delete_hba(adpt_hba* pHba) | |||
| 1087 | 1088 | ||
| 1088 | 1089 | ||
| 1089 | mutex_lock(&adpt_configuration_lock); | 1090 | mutex_lock(&adpt_configuration_lock); |
| 1090 | // scsi_unregister calls our adpt_release which | ||
| 1091 | // does a quiese | ||
| 1092 | if(pHba->host){ | 1091 | if(pHba->host){ |
| 1093 | free_irq(pHba->host->irq, pHba); | 1092 | free_irq(pHba->host->irq, pHba); |
| 1094 | } | 1093 | } |
| @@ -3595,11 +3594,9 @@ static void __exit adpt_exit(void) | |||
| 3595 | { | 3594 | { |
| 3596 | adpt_hba *pHba, *next; | 3595 | adpt_hba *pHba, *next; |
| 3597 | 3596 | ||
| 3598 | for (pHba = hba_chain; pHba; pHba = pHba->next) | ||
| 3599 | scsi_remove_host(pHba->host); | ||
| 3600 | for (pHba = hba_chain; pHba; pHba = next) { | 3597 | for (pHba = hba_chain; pHba; pHba = next) { |
| 3601 | next = pHba->next; | 3598 | next = pHba->next; |
| 3602 | adpt_release(pHba->host); | 3599 | adpt_release(pHba); |
| 3603 | } | 3600 | } |
| 3604 | } | 3601 | } |
| 3605 | 3602 | ||
diff --git a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h index 1fa345ab8ecb..dfc8d2eaa09e 100644 --- a/drivers/scsi/dpti.h +++ b/drivers/scsi/dpti.h | |||
| @@ -32,7 +32,6 @@ static int adpt_detect(struct scsi_host_template * sht); | |||
| 32 | static int adpt_queue(struct Scsi_Host *h, struct scsi_cmnd * cmd); | 32 | static int adpt_queue(struct Scsi_Host *h, struct scsi_cmnd * cmd); |
| 33 | static int adpt_abort(struct scsi_cmnd * cmd); | 33 | static int adpt_abort(struct scsi_cmnd * cmd); |
| 34 | static int adpt_reset(struct scsi_cmnd* cmd); | 34 | static int adpt_reset(struct scsi_cmnd* cmd); |
| 35 | static int adpt_release(struct Scsi_Host *host); | ||
| 36 | static int adpt_slave_configure(struct scsi_device *); | 35 | static int adpt_slave_configure(struct scsi_device *); |
| 37 | 36 | ||
| 38 | static const char *adpt_info(struct Scsi_Host *pSHost); | 37 | static const char *adpt_info(struct Scsi_Host *pSHost); |
diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c deleted file mode 100644 index 6501c330d8c8..000000000000 --- a/drivers/scsi/eata.c +++ /dev/null | |||
| @@ -1,2571 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * eata.c - Low-level driver for EATA/DMA SCSI host adapters. | ||
| 3 | * | ||
| 4 | * 03 Jun 2003 Rev. 8.10 for linux-2.5.70 | ||
| 5 | * + Update for new IRQ API. | ||
| 6 | * + Use "goto" when appropriate. | ||
| 7 | * + Drop eata.h. | ||
| 8 | * + Update for new module_param API. | ||
| 9 | * + Module parameters can now be specified only in the | ||
| 10 | * same format as the kernel boot options. | ||
| 11 | * | ||
| 12 | * boot option old module param | ||
| 13 | * ----------- ------------------ | ||
| 14 | * addr,... io_port=addr,... | ||
| 15 | * lc:[y|n] linked_comm=[1|0] | ||
| 16 | * mq:xx max_queue_depth=xx | ||
| 17 | * tm:[0|1|2] tag_mode=[0|1|2] | ||
| 18 | * et:[y|n] ext_tran=[1|0] | ||
| 19 | * rs:[y|n] rev_scan=[1|0] | ||
| 20 | * ip:[y|n] isa_probe=[1|0] | ||
| 21 | * ep:[y|n] eisa_probe=[1|0] | ||
| 22 | * pp:[y|n] pci_probe=[1|0] | ||
| 23 | * | ||
| 24 | * A valid example using the new parameter format is: | ||
| 25 | * modprobe eata "eata=0x7410,0x230,lc:y,tm:0,mq:4,ep:n" | ||
| 26 | * | ||
| 27 | * which is equivalent to the old format: | ||
| 28 | * modprobe eata io_port=0x7410,0x230 linked_comm=1 tag_mode=0 \ | ||
| 29 | * max_queue_depth=4 eisa_probe=0 | ||
| 30 | * | ||
| 31 | * 12 Feb 2003 Rev. 8.04 for linux 2.5.60 | ||
| 32 | * + Release irq before calling scsi_register. | ||
| 33 | * | ||
| 34 | * 12 Nov 2002 Rev. 8.02 for linux 2.5.47 | ||
| 35 | * + Release driver_lock before calling scsi_register. | ||
| 36 | * | ||
| 37 | * 11 Nov 2002 Rev. 8.01 for linux 2.5.47 | ||
| 38 | * + Fixed bios_param and scsicam_bios_param calling parameters. | ||
| 39 | * | ||
| 40 | * 28 Oct 2002 Rev. 8.00 for linux 2.5.44-ac4 | ||
| 41 | * + Use new tcq and adjust_queue_depth api. | ||
| 42 | * + New command line option (tm:[0-2]) to choose the type of tags: | ||
| 43 | * 0 -> disable tagging ; 1 -> simple tags ; 2 -> ordered tags. | ||
| 44 | * Default is tm:0 (tagged commands disabled). | ||
| 45 | * For compatibility the "tc:" option is an alias of the "tm:" | ||
| 46 | * option; tc:n is equivalent to tm:0 and tc:y is equivalent to | ||
| 47 | * tm:1. | ||
| 48 | * + The tagged_comm module parameter has been removed, use tag_mode | ||
| 49 | * instead, equivalent to the "tm:" boot option. | ||
| 50 | * | ||
| 51 | * 10 Oct 2002 Rev. 7.70 for linux 2.5.42 | ||
| 52 | * + Foreport from revision 6.70. | ||
| 53 | * | ||
| 54 | * 25 Jun 2002 Rev. 6.70 for linux 2.4.19 | ||
| 55 | * + This release is the first one tested on a Big Endian platform: | ||
| 56 | * fixed endian-ness problem due to bitfields; | ||
| 57 | * fixed endian-ness problem in read_pio. | ||
| 58 | * + Added new options for selectively probing ISA, EISA and PCI bus: | ||
| 59 | * | ||
| 60 | * Boot option Parameter name Default according to | ||
| 61 | * | ||
| 62 | * ip:[y|n] isa_probe=[1|0] CONFIG_ISA defined | ||
| 63 | * ep:[y|n] eisa_probe=[1|0] CONFIG_EISA defined | ||
| 64 | * pp:[y|n] pci_probe=[1|0] CONFIG_PCI defined | ||
| 65 | * | ||
| 66 | * The default action is to perform probing if the corresponding | ||
| 67 | * bus is configured and to skip probing otherwise. | ||
| 68 | * | ||
| 69 | * + If pci_probe is in effect and a list of I/O ports is specified | ||
| 70 | * as parameter or boot option, pci_enable_device() is performed | ||
| 71 | * on all pci devices matching PCI_CLASS_STORAGE_SCSI. | ||
| 72 | * | ||
| 73 | * 21 Feb 2002 Rev. 6.52 for linux 2.4.18 | ||
| 74 | * + Backport from rev. 7.22 (use io_request_lock). | ||
| 75 | * | ||
| 76 | * 20 Feb 2002 Rev. 7.22 for linux 2.5.5 | ||
| 77 | * + Remove any reference to virt_to_bus(). | ||
| 78 | * + Fix pio hang while detecting multiple HBAs. | ||
| 79 | * + Fixed a board detection bug: in a system with | ||
| 80 | * multiple ISA/EISA boards, all but the first one | ||
| 81 | * were erroneously detected as PCI. | ||
| 82 | * | ||
| 83 | * 01 Jan 2002 Rev. 7.20 for linux 2.5.1 | ||
| 84 | * + Use the dynamic DMA mapping API. | ||
| 85 | * | ||
| 86 | * 19 Dec 2001 Rev. 7.02 for linux 2.5.1 | ||
| 87 | * + Use SCpnt->sc_data_direction if set. | ||
| 88 | * + Use sglist.page instead of sglist.address. | ||
| 89 | * | ||
| 90 | * 11 Dec 2001 Rev. 7.00 for linux 2.5.1 | ||
| 91 | * + Use host->host_lock instead of io_request_lock. | ||
| 92 | * | ||
| 93 | * 1 May 2001 Rev. 6.05 for linux 2.4.4 | ||
| 94 | * + Clean up all pci related routines. | ||
| 95 | * + Fix data transfer direction for opcode SEND_CUE_SHEET (0x5d) | ||
| 96 | * | ||
| 97 | * 30 Jan 2001 Rev. 6.04 for linux 2.4.1 | ||
| 98 | * + Call pci_resource_start after pci_enable_device. | ||
| 99 | * | ||
| 100 | * 25 Jan 2001 Rev. 6.03 for linux 2.4.0 | ||
| 101 | * + "check_region" call replaced by "request_region". | ||
| 102 | * | ||
| 103 | * 22 Nov 2000 Rev. 6.02 for linux 2.4.0-test11 | ||
| 104 | * + Return code checked when calling pci_enable_device. | ||
| 105 | * + Removed old scsi error handling support. | ||
| 106 | * + The obsolete boot option flag eh:n is silently ignored. | ||
| 107 | * + Removed error messages while a disk drive is powered up at | ||
| 108 | * boot time. | ||
| 109 | * + Improved boot messages: all tagged capable device are | ||
| 110 | * indicated as "tagged" or "soft-tagged" : | ||
| 111 | * - "soft-tagged" means that the driver is trying to do its | ||
| 112 | * own tagging (i.e. the tc:y option is in effect); | ||
| 113 | * - "tagged" means that the device supports tagged commands, | ||
| 114 | * but the driver lets the HBA be responsible for tagging | ||
| 115 | * support. | ||
| 116 | * | ||
| 117 | * 16 Sep 1999 Rev. 5.11 for linux 2.2.12 and 2.3.18 | ||
| 118 | * + Updated to the new __setup interface for boot command line options. | ||
| 119 | * + When loaded as a module, accepts the new parameter boot_options | ||
| 120 | * which value is a string with the same format of the kernel boot | ||
| 121 | * command line options. A valid example is: | ||
| 122 | * modprobe eata 'boot_options="0x7410,0x230,lc:y,tc:n,mq:4"' | ||
| 123 | * | ||
| 124 | * 9 Sep 1999 Rev. 5.10 for linux 2.2.12 and 2.3.17 | ||
| 125 | * + 64bit cleanup for Linux/Alpha platform support | ||
| 126 | * (contribution from H.J. Lu). | ||
| 127 | * | ||
| 128 | * 22 Jul 1999 Rev. 5.00 for linux 2.2.10 and 2.3.11 | ||
| 129 | * + Removed pre-2.2 source code compatibility. | ||
| 130 | * + Added call to pci_set_master. | ||
| 131 | * | ||
| 132 | * 26 Jul 1998 Rev. 4.33 for linux 2.0.35 and 2.1.111 | ||
| 133 | * + Added command line option (rs:[y|n]) to reverse the scan order | ||
| 134 | * of PCI boards. The default is rs:y, which reverses the BIOS order | ||
| 135 | * while registering PCI boards. The default value rs:y generates | ||
| 136 | * the same order of all previous revisions of this driver. | ||
| 137 | * Pls. note that "BIOS order" might have been reversed itself | ||
| 138 | * after the 2.1.9x PCI modifications in the linux kernel. | ||
| 139 | * The rs value is ignored when the explicit list of addresses | ||
| 140 | * is used by the "eata=port0,port1,..." command line option. | ||
| 141 | * + Added command line option (et:[y|n]) to force use of extended | ||
| 142 | * translation (255 heads, 63 sectors) as disk geometry. | ||
| 143 | * The default is et:n, which uses the disk geometry returned | ||
| 144 | * by scsicam_bios_param. The default value et:n is compatible with | ||
| 145 | * all previous revisions of this driver. | ||
| 146 | * | ||
| 147 | * 28 May 1998 Rev. 4.32 for linux 2.0.33 and 2.1.104 | ||
| 148 | * Increased busy timeout from 10 msec. to 200 msec. while | ||
| 149 | * processing interrupts. | ||
| 150 | * | ||
| 151 | * 16 May 1998 Rev. 4.31 for linux 2.0.33 and 2.1.102 | ||
| 152 | * Improved abort handling during the eh recovery process. | ||
| 153 | * | ||
| 154 | * 13 May 1998 Rev. 4.30 for linux 2.0.33 and 2.1.101 | ||
| 155 | * The driver is now fully SMP safe, including the | ||
| 156 | * abort and reset routines. | ||
| 157 | * Added command line options (eh:[y|n]) to choose between | ||
| 158 | * new_eh_code and the old scsi code. | ||
| 159 | * If linux version >= 2.1.101 the default is eh:y, while the eh | ||
| 160 | * option is ignored for previous releases and the old scsi code | ||
| 161 | * is used. | ||
| 162 | * | ||
| 163 | * 18 Apr 1998 Rev. 4.20 for linux 2.0.33 and 2.1.97 | ||
| 164 | * Reworked interrupt handler. | ||
| 165 | * | ||
| 166 | * 11 Apr 1998 rev. 4.05 for linux 2.0.33 and 2.1.95 | ||
| 167 | * Major reliability improvement: when a batch with overlapping | ||
| 168 | * requests is detected, requests are queued one at a time | ||
| 169 | * eliminating any possible board or drive reordering. | ||
| 170 | * | ||
| 171 | * 10 Apr 1998 rev. 4.04 for linux 2.0.33 and 2.1.95 | ||
| 172 | * Improved SMP support (if linux version >= 2.1.95). | ||
| 173 | * | ||
| 174 | * 9 Apr 1998 rev. 4.03 for linux 2.0.33 and 2.1.94 | ||
| 175 | * Added support for new PCI code and IO-APIC remapping of irqs. | ||
| 176 | * Performance improvement: when sequential i/o is detected, | ||
| 177 | * always use direct sort instead of reverse sort. | ||
| 178 | * | ||
| 179 | * 4 Apr 1998 rev. 4.02 for linux 2.0.33 and 2.1.92 | ||
| 180 | * io_port is now unsigned long. | ||
| 181 | * | ||
| 182 | * 17 Mar 1998 rev. 4.01 for linux 2.0.33 and 2.1.88 | ||
| 183 | * Use new scsi error handling code (if linux version >= 2.1.88). | ||
| 184 | * Use new interrupt code. | ||
| 185 | * | ||
| 186 | * 12 Sep 1997 rev. 3.11 for linux 2.0.30 and 2.1.55 | ||
| 187 | * Use of udelay inside the wait loops to avoid timeout | ||
| 188 | * problems with fast cpus. | ||
| 189 | * Removed check about useless calls to the interrupt service | ||
| 190 | * routine (reported on SMP systems only). | ||
| 191 | * At initialization time "sorted/unsorted" is displayed instead | ||
| 192 | * of "linked/unlinked" to reinforce the fact that "linking" is | ||
| 193 | * nothing but "elevator sorting" in the actual implementation. | ||
| 194 | * | ||
| 195 | * 17 May 1997 rev. 3.10 for linux 2.0.30 and 2.1.38 | ||
| 196 | * Use of serial_number_at_timeout in abort and reset processing. | ||
| 197 | * Use of the __initfunc and __initdata macro in setup code. | ||
| 198 | * Minor cleanups in the list_statistics code. | ||
| 199 | * Increased controller busy timeout in order to better support | ||
| 200 | * slow SCSI devices. | ||
| 201 | * | ||
| 202 | * 24 Feb 1997 rev. 3.00 for linux 2.0.29 and 2.1.26 | ||
| 203 | * When loading as a module, parameter passing is now supported | ||
| 204 | * both in 2.0 and in 2.1 style. | ||
| 205 | * Fixed data transfer direction for some SCSI opcodes. | ||
| 206 | * Immediate acknowledge to request sense commands. | ||
| 207 | * Linked commands to each disk device are now reordered by elevator | ||
| 208 | * sorting. Rare cases in which reordering of write requests could | ||
| 209 | * cause wrong results are managed. | ||
| 210 | * Fixed spurious timeouts caused by long simple queue tag sequences. | ||
| 211 | * New command line option (tm:[0-3]) to choose the type of tags: | ||
| 212 | * 0 -> mixed (default); 1 -> simple; 2 -> head; 3 -> ordered. | ||
| 213 | * | ||
| 214 | * 18 Jan 1997 rev. 2.60 for linux 2.1.21 and 2.0.28 | ||
| 215 | * Added command line options to enable/disable linked commands | ||
| 216 | * (lc:[y|n]), tagged commands (tc:[y|n]) and to set the max queue | ||
| 217 | * depth (mq:xx). Default is "eata=lc:n,tc:n,mq:16". | ||
| 218 | * Improved command linking. | ||
| 219 | * Documented how to setup RAID-0 with DPT SmartRAID boards. | ||
| 220 | * | ||
| 221 | * 8 Jan 1997 rev. 2.50 for linux 2.1.20 and 2.0.27 | ||
| 222 | * Added linked command support. | ||
| 223 | * Improved detection of PCI boards using ISA base addresses. | ||
| 224 | * | ||
| 225 | * 3 Dec 1996 rev. 2.40 for linux 2.1.14 and 2.0.27 | ||
| 226 | * Added support for tagged commands and queue depth adjustment. | ||
| 227 | * | ||
| 228 | * 22 Nov 1996 rev. 2.30 for linux 2.1.12 and 2.0.26 | ||
| 229 | * When CONFIG_PCI is defined, BIOS32 is used to include in the | ||
| 230 | * list of i/o ports to be probed all the PCI SCSI controllers. | ||
| 231 | * The list of i/o ports to be probed can be overwritten by the | ||
| 232 | * "eata=port0,port1,...." boot command line option. | ||
| 233 | * Scatter/gather lists are now allocated by a number of kmalloc | ||
| 234 | * calls, in order to avoid the previous size limit of 64Kb. | ||
| 235 | * | ||
| 236 | * 16 Nov 1996 rev. 2.20 for linux 2.1.10 and 2.0.25 | ||
| 237 | * Added support for EATA 2.0C, PCI, multichannel and wide SCSI. | ||
| 238 | * | ||
| 239 | * 27 Sep 1996 rev. 2.12 for linux 2.1.0 | ||
| 240 | * Portability cleanups (virtual/bus addressing, little/big endian | ||
| 241 | * support). | ||
| 242 | * | ||
| 243 | * 09 Jul 1996 rev. 2.11 for linux 2.0.4 | ||
| 244 | * Number of internal retries is now limited. | ||
| 245 | * | ||
| 246 | * 16 Apr 1996 rev. 2.10 for linux 1.3.90 | ||
| 247 | * New argument "reset_flags" to the reset routine. | ||
| 248 | * | ||
| 249 | * 6 Jul 1995 rev. 2.01 for linux 1.3.7 | ||
| 250 | * Update required by the new /proc/scsi support. | ||
| 251 | * | ||
| 252 | * 11 Mar 1995 rev. 2.00 for linux 1.2.0 | ||
| 253 | * Fixed a bug which prevented media change detection for removable | ||
| 254 | * disk drives. | ||
| 255 | * | ||
| 256 | * 23 Feb 1995 rev. 1.18 for linux 1.1.94 | ||
| 257 | * Added a check for scsi_register returning NULL. | ||
| 258 | * | ||
| 259 | * 11 Feb 1995 rev. 1.17 for linux 1.1.91 | ||
| 260 | * Now DEBUG_RESET is disabled by default. | ||
| 261 | * Register a board even if it does not assert DMA protocol support | ||
| 262 | * (DPT SK2011B does not report correctly the dmasup bit). | ||
| 263 | * | ||
| 264 | * 9 Feb 1995 rev. 1.16 for linux 1.1.90 | ||
| 265 | * Use host->wish_block instead of host->block. | ||
| 266 | * New list of Data Out SCSI commands. | ||
| 267 | * | ||
| 268 | * 8 Feb 1995 rev. 1.15 for linux 1.1.89 | ||
| 269 | * Cleared target_time_out counter while performing a reset. | ||
| 270 | * All external symbols renamed to avoid possible name conflicts. | ||
| 271 | * | ||
| 272 | * 28 Jan 1995 rev. 1.14 for linux 1.1.86 | ||
| 273 | * Added module support. | ||
| 274 | * Log and do a retry when a disk drive returns a target status | ||
| 275 | * different from zero on a recovered error. | ||
| 276 | * | ||
| 277 | * 24 Jan 1995 rev. 1.13 for linux 1.1.85 | ||
| 278 | * Use optimized board configuration, with a measured performance | ||
| 279 | * increase in the range 10%-20% on i/o throughput. | ||
| 280 | * | ||
| 281 | * 16 Jan 1995 rev. 1.12 for linux 1.1.81 | ||
| 282 | * Fix mscp structure comments (no functional change). | ||
| 283 | * Display a message if check_region detects a port address | ||
| 284 | * already in use. | ||
| 285 | * | ||
| 286 | * 17 Dec 1994 rev. 1.11 for linux 1.1.74 | ||
| 287 | * Use the scsicam_bios_param routine. This allows an easy | ||
| 288 | * migration path from disk partition tables created using | ||
| 289 | * different SCSI drivers and non optimal disk geometry. | ||
| 290 | * | ||
| 291 | * 15 Dec 1994 rev. 1.10 for linux 1.1.74 | ||
| 292 | * Added support for ISA EATA boards (DPT PM2011, DPT PM2021). | ||
| 293 | * The host->block flag is set for all the detected ISA boards. | ||
| 294 | * The detect routine no longer enforces LEVEL triggering | ||
| 295 | * for EISA boards, it just prints a warning message. | ||
| 296 | * | ||
| 297 | * 30 Nov 1994 rev. 1.09 for linux 1.1.68 | ||
| 298 | * Redo i/o on target status CHECK_CONDITION for TYPE_DISK only. | ||
| 299 | * Added optional support for using a single board at a time. | ||
| 300 | * | ||
| 301 | * 18 Nov 1994 rev. 1.08 for linux 1.1.64 | ||
| 302 | * Forces sg_tablesize = 64 and can_queue = 64 if these | ||
| 303 | * values are not correctly detected (DPT PM2012). | ||
| 304 | * | ||
| 305 | * 14 Nov 1994 rev. 1.07 for linux 1.1.63 Final BETA release. | ||
| 306 | * 04 Aug 1994 rev. 1.00 for linux 1.1.39 First BETA release. | ||
| 307 | * | ||
| 308 | * | ||
| 309 | * This driver is based on the CAM (Common Access Method Committee) | ||
| 310 | * EATA (Enhanced AT Bus Attachment) rev. 2.0A, using DMA protocol. | ||
| 311 | * | ||
| 312 | * Copyright (C) 1994-2003 Dario Ballabio (ballabio_dario@emc.com) | ||
| 313 | * | ||
| 314 | * Alternate email: dario.ballabio@inwind.it, dario.ballabio@tiscalinet.it | ||
| 315 | * | ||
| 316 | * Redistribution and use in source and binary forms, with or without | ||
| 317 | * modification, are permitted provided that redistributions of source | ||
| 318 | * code retain the above copyright notice and this comment without | ||
| 319 | * modification. | ||
| 320 | * | ||
| 321 | */ | ||
| 322 | |||
| 323 | /* | ||
| 324 | * | ||
| 325 | * Here is a brief description of the DPT SCSI host adapters. | ||
| 326 | * All these boards provide an EATA/DMA compatible programming interface | ||
| 327 | * and are fully supported by this driver in any configuration, including | ||
| 328 | * multiple SCSI channels: | ||
| 329 | * | ||
| 330 | * PM2011B/9X - Entry Level ISA | ||
| 331 | * PM2021A/9X - High Performance ISA | ||
| 332 | * PM2012A Old EISA | ||
| 333 | * PM2012B Old EISA | ||
| 334 | * PM2022A/9X - Entry Level EISA | ||
| 335 | * PM2122A/9X - High Performance EISA | ||
| 336 | * PM2322A/9X - Extra High Performance EISA | ||
| 337 | * PM3021 - SmartRAID Adapter for ISA | ||
| 338 | * PM3222 - SmartRAID Adapter for EISA (PM3222W is 16-bit wide SCSI) | ||
| 339 | * PM3224 - SmartRAID Adapter for PCI (PM3224W is 16-bit wide SCSI) | ||
| 340 | * PM33340UW - SmartRAID Adapter for PCI ultra wide multichannel | ||
| 341 | * | ||
| 342 | * The above list is just an indication: as a matter of fact all DPT | ||
| 343 | * boards using the EATA/DMA protocol are supported by this driver, | ||
| 344 | * since they use exactely the same programming interface. | ||
| 345 | * | ||
| 346 | * The DPT PM2001 provides only the EATA/PIO interface and hence is not | ||
| 347 | * supported by this driver. | ||
| 348 | * | ||
| 349 | * This code has been tested with up to 3 Distributed Processing Technology | ||
| 350 | * PM2122A/9X (DPT SCSI BIOS v002.D1, firmware v05E.0) EISA controllers, | ||
| 351 | * in any combination of private and shared IRQ. | ||
| 352 | * PCI support has been tested using up to 2 DPT PM3224W (DPT SCSI BIOS | ||
| 353 | * v003.D0, firmware v07G.0). | ||
| 354 | * | ||
| 355 | * DPT SmartRAID boards support "Hardware Array" - a group of disk drives | ||
| 356 | * which are all members of the same RAID-0, RAID-1 or RAID-5 array implemented | ||
| 357 | * in host adapter hardware. Hardware Arrays are fully compatible with this | ||
| 358 | * driver, since they look to it as a single disk drive. | ||
| 359 | * | ||
| 360 | * WARNING: to create a RAID-0 "Hardware Array" you must select "Other Unix" | ||
| 361 | * as the current OS in the DPTMGR "Initial System Installation" menu. | ||
| 362 | * Otherwise RAID-0 is generated as an "Array Group" (i.e. software RAID-0), | ||
| 363 | * which is not supported by the actual SCSI subsystem. | ||
| 364 | * To get the "Array Group" functionality, the Linux MD driver must be used | ||
| 365 | * instead of the DPT "Array Group" feature. | ||
| 366 | * | ||
| 367 | * Multiple ISA, EISA and PCI boards can be configured in the same system. | ||
| 368 | * It is suggested to put all the EISA boards on the same IRQ level, all | ||
| 369 | * the PCI boards on another IRQ level, while ISA boards cannot share | ||
| 370 | * interrupts. | ||
| 371 | * | ||
| 372 | * If you configure multiple boards on the same IRQ, the interrupt must | ||
| 373 | * be _level_ triggered (not _edge_ triggered). | ||
| 374 | * | ||
| 375 | * This driver detects EATA boards by probes at fixed port addresses, | ||
| 376 | * so no BIOS32 or PCI BIOS support is required. | ||
| 377 | * The suggested way to detect a generic EATA PCI board is to force on it | ||
| 378 | * any unused EISA address, even if there are other controllers on the EISA | ||
| 379 | * bus, or even if you system has no EISA bus at all. | ||
| 380 | * Do not force any ISA address on EATA PCI boards. | ||
| 381 | * | ||
| 382 | * If PCI bios support is configured into the kernel, BIOS32 is used to | ||
| 383 | * include in the list of i/o ports to be probed all the PCI SCSI controllers. | ||
| 384 | * | ||
| 385 | * Due to a DPT BIOS "feature", it might not be possible to force an EISA | ||
| 386 | * address on more than a single DPT PCI board, so in this case you have to | ||
| 387 | * let the PCI BIOS assign the addresses. | ||
| 388 | * | ||
| 389 | * The sequence of detection probes is: | ||
| 390 | * | ||
| 391 | * - ISA 0x1F0; | ||
| 392 | * - PCI SCSI controllers (only if BIOS32 is available); | ||
| 393 | * - EISA/PCI 0x1C88 through 0xFC88 (corresponding to EISA slots 1 to 15); | ||
| 394 | * - ISA 0x170, 0x230, 0x330. | ||
| 395 | * | ||
| 396 | * The above list of detection probes can be totally replaced by the | ||
| 397 | * boot command line option: "eata=port0,port1,port2,...", where the | ||
| 398 | * port0, port1... arguments are ISA/EISA/PCI addresses to be probed. | ||
| 399 | * For example using "eata=0x7410,0x7450,0x230", the driver probes | ||
| 400 | * only the two PCI addresses 0x7410 and 0x7450 and the ISA address 0x230, | ||
| 401 | * in this order; "eata=0" totally disables this driver. | ||
| 402 | * | ||
| 403 | * After the optional list of detection probes, other possible command line | ||
| 404 | * options are: | ||
| 405 | * | ||
| 406 | * et:y force use of extended translation (255 heads, 63 sectors); | ||
| 407 | * et:n use disk geometry detected by scsicam_bios_param; | ||
| 408 | * rs:y reverse scan order while detecting PCI boards; | ||
| 409 | * rs:n use BIOS order while detecting PCI boards; | ||
| 410 | * lc:y enables linked commands; | ||
| 411 | * lc:n disables linked commands; | ||
| 412 | * tm:0 disables tagged commands (same as tc:n); | ||
| 413 | * tm:1 use simple queue tags (same as tc:y); | ||
| 414 | * tm:2 use ordered queue tags (same as tc:2); | ||
| 415 | * mq:xx set the max queue depth to the value xx (2 <= xx <= 32). | ||
| 416 | * | ||
| 417 | * The default value is: "eata=lc:n,mq:16,tm:0,et:n,rs:n". | ||
| 418 | * An example using the list of detection probes could be: | ||
| 419 | * "eata=0x7410,0x230,lc:y,tm:2,mq:4,et:n". | ||
| 420 | * | ||
| 421 | * When loading as a module, parameters can be specified as well. | ||
| 422 | * The above example would be (use 1 in place of y and 0 in place of n): | ||
| 423 | * | ||
| 424 | * modprobe eata io_port=0x7410,0x230 linked_comm=1 \ | ||
| 425 | * max_queue_depth=4 ext_tran=0 tag_mode=2 \ | ||
| 426 | * rev_scan=1 | ||
| 427 | * | ||
| 428 | * ---------------------------------------------------------------------------- | ||
| 429 | * In this implementation, linked commands are designed to work with any DISK | ||
| 430 | * or CD-ROM, since this linking has only the intent of clustering (time-wise) | ||
| 431 | * and reordering by elevator sorting commands directed to each device, | ||
| 432 | * without any relation with the actual SCSI protocol between the controller | ||
| 433 | * and the device. | ||
| 434 | * If Q is the queue depth reported at boot time for each device (also named | ||
| 435 | * cmds/lun) and Q > 2, whenever there is already an active command to the | ||
| 436 | * device all other commands to the same device (up to Q-1) are kept waiting | ||
| 437 | * in the elevator sorting queue. When the active command completes, the | ||
| 438 | * commands in this queue are sorted by sector address. The sort is chosen | ||
| 439 | * between increasing or decreasing by minimizing the seek distance between | ||
| 440 | * the sector of the commands just completed and the sector of the first | ||
| 441 | * command in the list to be sorted. | ||
| 442 | * Trivial math assures that the unsorted average seek distance when doing | ||
| 443 | * random seeks over S sectors is S/3. | ||
| 444 | * When (Q-1) requests are uniformly distributed over S sectors, the average | ||
| 445 | * distance between two adjacent requests is S/((Q-1) + 1), so the sorted | ||
| 446 | * average seek distance for (Q-1) random requests over S sectors is S/Q. | ||
| 447 | * The elevator sorting hence divides the seek distance by a factor Q/3. | ||
| 448 | * The above pure geometric remarks are valid in all cases and the | ||
| 449 | * driver effectively reduces the seek distance by the predicted factor | ||
| 450 | * when there are Q concurrent read i/o operations on the device, but this | ||
| 451 | * does not necessarily results in a noticeable performance improvement: | ||
| 452 | * your mileage may vary.... | ||
| 453 | * | ||
| 454 | * Note: command reordering inside a batch of queued commands could cause | ||
| 455 | * wrong results only if there is at least one write request and the | ||
| 456 | * intersection (sector-wise) of all requests is not empty. | ||
| 457 | * When the driver detects a batch including overlapping requests | ||
| 458 | * (a really rare event) strict serial (pid) order is enforced. | ||
| 459 | * ---------------------------------------------------------------------------- | ||
| 460 | * The extended translation option (et:y) is useful when using large physical | ||
| 461 | * disks/arrays. It could also be useful when switching between Adaptec boards | ||
| 462 | * and DPT boards without reformatting the disk. | ||
| 463 | * When a boot disk is partitioned with extended translation, in order to | ||
| 464 | * be able to boot it with a DPT board is could be necessary to add to | ||
| 465 | * lilo.conf additional commands as in the following example: | ||
| 466 | * | ||
| 467 | * fix-table | ||
| 468 | * disk=/dev/sda bios=0x80 sectors=63 heads=128 cylindres=546 | ||
| 469 | * | ||
| 470 | * where the above geometry should be replaced with the one reported at | ||
| 471 | * power up by the DPT controller. | ||
| 472 | * ---------------------------------------------------------------------------- | ||
| 473 | * | ||
| 474 | * The boards are named EATA0, EATA1,... according to the detection order. | ||
| 475 | * | ||
| 476 | * In order to support multiple ISA boards in a reliable way, | ||
| 477 | * the driver sets host->wish_block = 1 for all ISA boards. | ||
| 478 | */ | ||
| 479 | |||
| 480 | #include <linux/string.h> | ||
| 481 | #include <linux/kernel.h> | ||
| 482 | #include <linux/ioport.h> | ||
| 483 | #include <linux/delay.h> | ||
| 484 | #include <linux/proc_fs.h> | ||
| 485 | #include <linux/blkdev.h> | ||
| 486 | #include <linux/interrupt.h> | ||
| 487 | #include <linux/stat.h> | ||
| 488 | #include <linux/pci.h> | ||
| 489 | #include <linux/init.h> | ||
| 490 | #include <linux/ctype.h> | ||
| 491 | #include <linux/spinlock.h> | ||
| 492 | #include <linux/dma-mapping.h> | ||
| 493 | #include <linux/slab.h> | ||
| 494 | #include <asm/byteorder.h> | ||
| 495 | #include <asm/dma.h> | ||
| 496 | #include <asm/io.h> | ||
| 497 | #include <asm/irq.h> | ||
| 498 | |||
| 499 | #include <scsi/scsi.h> | ||
| 500 | #include <scsi/scsi_cmnd.h> | ||
| 501 | #include <scsi/scsi_device.h> | ||
| 502 | #include <scsi/scsi_host.h> | ||
| 503 | #include <scsi/scsi_tcq.h> | ||
| 504 | #include <scsi/scsicam.h> | ||
| 505 | |||
| 506 | static int eata2x_detect(struct scsi_host_template *); | ||
| 507 | static int eata2x_release(struct Scsi_Host *); | ||
| 508 | static int eata2x_queuecommand(struct Scsi_Host *, struct scsi_cmnd *); | ||
| 509 | static int eata2x_eh_abort(struct scsi_cmnd *); | ||
| 510 | static int eata2x_eh_host_reset(struct scsi_cmnd *); | ||
| 511 | static int eata2x_bios_param(struct scsi_device *, struct block_device *, | ||
| 512 | sector_t, int *); | ||
| 513 | static int eata2x_slave_configure(struct scsi_device *); | ||
| 514 | |||
| 515 | static struct scsi_host_template driver_template = { | ||
| 516 | .name = "EATA/DMA 2.0x rev. 8.10.00 ", | ||
| 517 | .detect = eata2x_detect, | ||
| 518 | .release = eata2x_release, | ||
| 519 | .queuecommand = eata2x_queuecommand, | ||
| 520 | .eh_abort_handler = eata2x_eh_abort, | ||
| 521 | .eh_host_reset_handler = eata2x_eh_host_reset, | ||
| 522 | .bios_param = eata2x_bios_param, | ||
| 523 | .slave_configure = eata2x_slave_configure, | ||
| 524 | .this_id = 7, | ||
| 525 | .unchecked_isa_dma = 1, | ||
| 526 | .use_clustering = ENABLE_CLUSTERING, | ||
| 527 | }; | ||
| 528 | |||
| 529 | #if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD) | ||
| 530 | #error "Adjust your <asm/byteorder.h> defines" | ||
| 531 | #endif | ||
| 532 | |||
| 533 | /* Subversion values */ | ||
| 534 | #define ISA 0 | ||
| 535 | #define ESA 1 | ||
| 536 | |||
| 537 | #undef FORCE_CONFIG | ||
| 538 | |||
| 539 | #undef DEBUG_LINKED_COMMANDS | ||
| 540 | #undef DEBUG_DETECT | ||
| 541 | #undef DEBUG_PCI_DETECT | ||
| 542 | #undef DEBUG_INTERRUPT | ||
| 543 | #undef DEBUG_RESET | ||
| 544 | #undef DEBUG_GENERATE_ERRORS | ||
| 545 | #undef DEBUG_GENERATE_ABORTS | ||
| 546 | #undef DEBUG_GEOMETRY | ||
| 547 | |||
| 548 | #define MAX_ISA 4 | ||
| 549 | #define MAX_VESA 0 | ||
| 550 | #define MAX_EISA 15 | ||
| 551 | #define MAX_PCI 16 | ||
| 552 | #define MAX_BOARDS (MAX_ISA + MAX_VESA + MAX_EISA + MAX_PCI) | ||
| 553 | #define MAX_CHANNEL 4 | ||
| 554 | #define MAX_LUN 32 | ||
| 555 | #define MAX_TARGET 32 | ||
| 556 | #define MAX_MAILBOXES 64 | ||
| 557 | #define MAX_SGLIST 64 | ||
| 558 | #define MAX_LARGE_SGLIST 122 | ||
| 559 | #define MAX_INTERNAL_RETRIES 64 | ||
| 560 | #define MAX_CMD_PER_LUN 2 | ||
| 561 | #define MAX_TAGGED_CMD_PER_LUN (MAX_MAILBOXES - MAX_CMD_PER_LUN) | ||
| 562 | |||
| 563 | #define SKIP ULONG_MAX | ||
| 564 | #define FREE 0 | ||
| 565 | #define IN_USE 1 | ||
| 566 | #define LOCKED 2 | ||
| 567 | #define IN_RESET 3 | ||
| 568 | #define IGNORE 4 | ||
| 569 | #define READY 5 | ||
| 570 | #define ABORTING 6 | ||
| 571 | #define NO_DMA 0xff | ||
| 572 | #define MAXLOOP 10000 | ||
| 573 | #define TAG_DISABLED 0 | ||
| 574 | #define TAG_SIMPLE 1 | ||
| 575 | #define TAG_ORDERED 2 | ||
| 576 | |||
| 577 | #define REG_CMD 7 | ||
| 578 | #define REG_STATUS 7 | ||
| 579 | #define REG_AUX_STATUS 8 | ||
| 580 | #define REG_DATA 0 | ||
| 581 | #define REG_DATA2 1 | ||
| 582 | #define REG_SEE 6 | ||
| 583 | #define REG_LOW 2 | ||
| 584 | #define REG_LM 3 | ||
| 585 | #define REG_MID 4 | ||
| 586 | #define REG_MSB 5 | ||
| 587 | #define REGION_SIZE 9UL | ||
| 588 | #define MAX_ISA_ADDR 0x03ff | ||
| 589 | #define MIN_EISA_ADDR 0x1c88 | ||
| 590 | #define MAX_EISA_ADDR 0xfc88 | ||
| 591 | #define BSY_ASSERTED 0x80 | ||
| 592 | #define DRQ_ASSERTED 0x08 | ||
| 593 | #define ABSY_ASSERTED 0x01 | ||
| 594 | #define IRQ_ASSERTED 0x02 | ||
| 595 | #define READ_CONFIG_PIO 0xf0 | ||
| 596 | #define SET_CONFIG_PIO 0xf1 | ||
| 597 | #define SEND_CP_PIO 0xf2 | ||
| 598 | #define RECEIVE_SP_PIO 0xf3 | ||
| 599 | #define TRUNCATE_XFR_PIO 0xf4 | ||
| 600 | #define RESET_PIO 0xf9 | ||
| 601 | #define READ_CONFIG_DMA 0xfd | ||
| 602 | #define SET_CONFIG_DMA 0xfe | ||
| 603 | #define SEND_CP_DMA 0xff | ||
| 604 | #define ASOK 0x00 | ||
| 605 | #define ASST 0x01 | ||
| 606 | |||
| 607 | #define YESNO(a) ((a) ? 'y' : 'n') | ||
| 608 | #define TLDEV(type) ((type) == TYPE_DISK || (type) == TYPE_ROM) | ||
| 609 | |||
| 610 | /* "EATA", in Big Endian format */ | ||
| 611 | #define EATA_SIG_BE 0x45415441 | ||
| 612 | |||
| 613 | /* Number of valid bytes in the board config structure for EATA 2.0x */ | ||
| 614 | #define EATA_2_0A_SIZE 28 | ||
| 615 | #define EATA_2_0B_SIZE 30 | ||
| 616 | #define EATA_2_0C_SIZE 34 | ||
| 617 | |||
| 618 | /* Board info structure */ | ||
| 619 | struct eata_info { | ||
| 620 | u_int32_t data_len; /* Number of valid bytes after this field */ | ||
| 621 | u_int32_t sign; /* ASCII "EATA" signature */ | ||
| 622 | |||
| 623 | #if defined(__BIG_ENDIAN_BITFIELD) | ||
| 624 | unchar version : 4, | ||
| 625 | : 4; | ||
| 626 | unchar haaval : 1, | ||
| 627 | ata : 1, | ||
| 628 | drqvld : 1, | ||
| 629 | dmasup : 1, | ||
| 630 | morsup : 1, | ||
| 631 | trnxfr : 1, | ||
| 632 | tarsup : 1, | ||
| 633 | ocsena : 1; | ||
| 634 | #else | ||
| 635 | unchar : 4, /* unused low nibble */ | ||
| 636 | version : 4; /* EATA version, should be 0x1 */ | ||
| 637 | unchar ocsena : 1, /* Overlap Command Support Enabled */ | ||
| 638 | tarsup : 1, /* Target Mode Supported */ | ||
| 639 | trnxfr : 1, /* Truncate Transfer Cmd NOT Necessary */ | ||
| 640 | morsup : 1, /* More Supported */ | ||
| 641 | dmasup : 1, /* DMA Supported */ | ||
| 642 | drqvld : 1, /* DRQ Index (DRQX) is valid */ | ||
| 643 | ata : 1, /* This is an ATA device */ | ||
| 644 | haaval : 1; /* Host Adapter Address Valid */ | ||
| 645 | #endif | ||
| 646 | |||
| 647 | ushort cp_pad_len; /* Number of pad bytes after cp_len */ | ||
| 648 | unchar host_addr[4]; /* Host Adapter SCSI ID for channels 3, 2, 1, 0 */ | ||
| 649 | u_int32_t cp_len; /* Number of valid bytes in cp */ | ||
| 650 | u_int32_t sp_len; /* Number of valid bytes in sp */ | ||
| 651 | ushort queue_size; /* Max number of cp that can be queued */ | ||
| 652 | ushort unused; | ||
| 653 | ushort scatt_size; /* Max number of entries in scatter/gather table */ | ||
| 654 | |||
| 655 | #if defined(__BIG_ENDIAN_BITFIELD) | ||
| 656 | unchar drqx : 2, | ||
| 657 | second : 1, | ||
| 658 | irq_tr : 1, | ||
| 659 | irq : 4; | ||
| 660 | unchar sync; | ||
| 661 | unchar : 4, | ||
| 662 | res1 : 1, | ||
| 663 | large_sg : 1, | ||
| 664 | forcaddr : 1, | ||
| 665 | isaena : 1; | ||
| 666 | unchar max_chan : 3, | ||
| 667 | max_id : 5; | ||
| 668 | unchar max_lun; | ||
| 669 | unchar eisa : 1, | ||
| 670 | pci : 1, | ||
| 671 | idquest : 1, | ||
| 672 | m1 : 1, | ||
| 673 | : 4; | ||
| 674 | #else | ||
| 675 | unchar irq : 4, /* Interrupt Request assigned to this controller */ | ||
| 676 | irq_tr : 1, /* 0 for edge triggered, 1 for level triggered */ | ||
| 677 | second : 1, /* 1 if this is a secondary (not primary) controller */ | ||
| 678 | drqx : 2; /* DRQ Index (0=DMA0, 1=DMA7, 2=DMA6, 3=DMA5) */ | ||
| 679 | unchar sync; /* 1 if scsi target id 7...0 is running sync scsi */ | ||
| 680 | |||
| 681 | /* Structure extension defined in EATA 2.0B */ | ||
| 682 | unchar isaena : 1, /* ISA i/o addressing is disabled/enabled */ | ||
| 683 | forcaddr : 1, /* Port address has been forced */ | ||
| 684 | large_sg : 1, /* 1 if large SG lists are supported */ | ||
| 685 | res1 : 1, | ||
| 686 | : 4; | ||
| 687 | unchar max_id : 5, /* Max SCSI target ID number */ | ||
| 688 | max_chan : 3; /* Max SCSI channel number on this board */ | ||
| 689 | |||
| 690 | /* Structure extension defined in EATA 2.0C */ | ||
| 691 | unchar max_lun; /* Max SCSI LUN number */ | ||
| 692 | unchar | ||
| 693 | : 4, | ||
| 694 | m1 : 1, /* This is a PCI with an M1 chip installed */ | ||
| 695 | idquest : 1, /* RAIDNUM returned is questionable */ | ||
| 696 | pci : 1, /* This board is PCI */ | ||
| 697 | eisa : 1; /* This board is EISA */ | ||
| 698 | #endif | ||
| 699 | |||
| 700 | unchar raidnum; /* Uniquely identifies this HBA in a system */ | ||
| 701 | unchar notused; | ||
| 702 | |||
| 703 | ushort ipad[247]; | ||
| 704 | }; | ||
| 705 | |||
| 706 | /* Board config structure */ | ||
| 707 | struct eata_config { | ||
| 708 | ushort len; /* Number of bytes following this field */ | ||
| 709 | |||
| 710 | #if defined(__BIG_ENDIAN_BITFIELD) | ||
| 711 | unchar : 4, | ||
| 712 | tarena : 1, | ||
| 713 | mdpena : 1, | ||
| 714 | ocena : 1, | ||
| 715 | edis : 1; | ||
| 716 | #else | ||
| 717 | unchar edis : 1, /* Disable EATA interface after config command */ | ||
| 718 | ocena : 1, /* Overlapped Commands Enabled */ | ||
| 719 | mdpena : 1, /* Transfer all Modified Data Pointer Messages */ | ||
| 720 | tarena : 1, /* Target Mode Enabled for this controller */ | ||
| 721 | : 4; | ||
| 722 | #endif | ||
| 723 | unchar cpad[511]; | ||
| 724 | }; | ||
| 725 | |||
| 726 | /* Returned status packet structure */ | ||
| 727 | struct mssp { | ||
| 728 | #if defined(__BIG_ENDIAN_BITFIELD) | ||
| 729 | unchar eoc : 1, | ||
| 730 | adapter_status : 7; | ||
| 731 | #else | ||
| 732 | unchar adapter_status : 7, /* State related to current command */ | ||
| 733 | eoc : 1; /* End Of Command (1 = command completed) */ | ||
| 734 | #endif | ||
| 735 | unchar target_status; /* SCSI status received after data transfer */ | ||
| 736 | unchar unused[2]; | ||
| 737 | u_int32_t inv_res_len; /* Number of bytes not transferred */ | ||
| 738 | u_int32_t cpp_index; /* Index of address set in cp */ | ||
| 739 | char mess[12]; | ||
| 740 | }; | ||
| 741 | |||
| 742 | struct sg_list { | ||
| 743 | unsigned int address; /* Segment Address */ | ||
| 744 | unsigned int num_bytes; /* Segment Length */ | ||
| 745 | }; | ||
| 746 | |||
| 747 | /* MailBox SCSI Command Packet */ | ||
| 748 | struct mscp { | ||
| 749 | #if defined(__BIG_ENDIAN_BITFIELD) | ||
| 750 | unchar din : 1, | ||
| 751 | dout : 1, | ||
| 752 | interp : 1, | ||
| 753 | : 1, | ||
| 754 | sg : 1, | ||
| 755 | reqsen :1, | ||
| 756 | init : 1, | ||
| 757 | sreset : 1; | ||
| 758 | unchar sense_len; | ||
| 759 | unchar unused[3]; | ||
| 760 | unchar : 7, | ||
| 761 | fwnest : 1; | ||
| 762 | unchar : 5, | ||
| 763 | hbaci : 1, | ||
| 764 | iat : 1, | ||
| 765 | phsunit : 1; | ||
| 766 | unchar channel : 3, | ||
| 767 | target : 5; | ||
| 768 | unchar one : 1, | ||
| 769 | dispri : 1, | ||
| 770 | luntar : 1, | ||
| 771 | lun : 5; | ||
| 772 | #else | ||
| 773 | unchar sreset :1, /* SCSI Bus Reset Signal should be asserted */ | ||
| 774 | init :1, /* Re-initialize controller and self test */ | ||
| 775 | reqsen :1, /* Transfer Request Sense Data to addr using DMA */ | ||
| 776 | sg :1, /* Use Scatter/Gather */ | ||
| 777 | :1, | ||
| 778 | interp :1, /* The controller interprets cp, not the target */ | ||
| 779 | dout :1, /* Direction of Transfer is Out (Host to Target) */ | ||
| 780 | din :1; /* Direction of Transfer is In (Target to Host) */ | ||
| 781 | unchar sense_len; /* Request Sense Length */ | ||
| 782 | unchar unused[3]; | ||
| 783 | unchar fwnest : 1, /* Send command to a component of an Array Group */ | ||
| 784 | : 7; | ||
| 785 | unchar phsunit : 1, /* Send to Target Physical Unit (bypass RAID) */ | ||
| 786 | iat : 1, /* Inhibit Address Translation */ | ||
| 787 | hbaci : 1, /* Inhibit HBA Caching for this command */ | ||
| 788 | : 5; | ||
| 789 | unchar target : 5, /* SCSI target ID */ | ||
| 790 | channel : 3; /* SCSI channel number */ | ||
| 791 | unchar lun : 5, /* SCSI logical unit number */ | ||
| 792 | luntar : 1, /* This cp is for Target (not LUN) */ | ||
| 793 | dispri : 1, /* Disconnect Privilege granted */ | ||
| 794 | one : 1; /* 1 */ | ||
| 795 | #endif | ||
| 796 | |||
| 797 | unchar mess[3]; /* Massage to/from Target */ | ||
| 798 | unchar cdb[12]; /* Command Descriptor Block */ | ||
| 799 | u_int32_t data_len; /* If sg=0 Data Length, if sg=1 sglist length */ | ||
| 800 | u_int32_t cpp_index; /* Index of address to be returned in sp */ | ||
| 801 | u_int32_t data_address; /* If sg=0 Data Address, if sg=1 sglist address */ | ||
| 802 | u_int32_t sp_dma_addr; /* Address where sp is DMA'ed when cp completes */ | ||
| 803 | u_int32_t sense_addr; /* Address where Sense Data is DMA'ed on error */ | ||
| 804 | |||
| 805 | /* Additional fields begin here. */ | ||
| 806 | struct scsi_cmnd *SCpnt; | ||
| 807 | |||
| 808 | /* All the cp structure is zero filled by queuecommand except the | ||
| 809 | following CP_TAIL_SIZE bytes, initialized by detect */ | ||
| 810 | dma_addr_t cp_dma_addr; /* dma handle for this cp structure */ | ||
| 811 | struct sg_list *sglist; /* pointer to the allocated SG list */ | ||
| 812 | }; | ||
| 813 | |||
| 814 | #define CP_TAIL_SIZE (sizeof(struct sglist *) + sizeof(dma_addr_t)) | ||
| 815 | |||
| 816 | struct hostdata { | ||
| 817 | struct mscp cp[MAX_MAILBOXES]; /* Mailboxes for this board */ | ||
| 818 | unsigned int cp_stat[MAX_MAILBOXES]; /* FREE, IN_USE, LOCKED, IN_RESET */ | ||
| 819 | unsigned int last_cp_used; /* Index of last mailbox used */ | ||
| 820 | unsigned int iocount; /* Total i/o done for this board */ | ||
| 821 | int board_number; /* Number of this board */ | ||
| 822 | char board_name[16]; /* Name of this board */ | ||
| 823 | int in_reset; /* True if board is doing a reset */ | ||
| 824 | int target_to[MAX_TARGET][MAX_CHANNEL]; /* N. of timeout errors on target */ | ||
| 825 | int target_redo[MAX_TARGET][MAX_CHANNEL]; /* If 1 redo i/o on target */ | ||
| 826 | unsigned int retries; /* Number of internal retries */ | ||
| 827 | unsigned long last_retried_pid; /* Pid of last retried command */ | ||
| 828 | unsigned char subversion; /* Bus type, either ISA or EISA/PCI */ | ||
| 829 | unsigned char protocol_rev; /* EATA 2.0 rev., 'A' or 'B' or 'C' */ | ||
| 830 | unsigned char is_pci; /* 1 is bus type is PCI */ | ||
| 831 | struct pci_dev *pdev; /* pdev for PCI bus, NULL otherwise */ | ||
| 832 | struct mssp *sp_cpu_addr; /* cpu addr for DMA buffer sp */ | ||
| 833 | dma_addr_t sp_dma_addr; /* dma handle for DMA buffer sp */ | ||
| 834 | struct mssp sp; /* Local copy of sp buffer */ | ||
| 835 | }; | ||
| 836 | |||
| 837 | static struct Scsi_Host *sh[MAX_BOARDS]; | ||
| 838 | static const char *driver_name = "EATA"; | ||
| 839 | static char sha[MAX_BOARDS]; | ||
| 840 | |||
| 841 | /* Initialize num_boards so that ihdlr can work while detect is in progress */ | ||
| 842 | static unsigned int num_boards = MAX_BOARDS; | ||
| 843 | |||
| 844 | static unsigned long io_port[] = { | ||
| 845 | |||
| 846 | /* Space for MAX_INT_PARAM ports usable while loading as a module */ | ||
| 847 | SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, | ||
| 848 | SKIP, SKIP, | ||
| 849 | |||
| 850 | /* First ISA */ | ||
| 851 | 0x1f0, | ||
| 852 | |||
| 853 | /* Space for MAX_PCI ports possibly reported by PCI_BIOS */ | ||
| 854 | SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, | ||
| 855 | SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, | ||
| 856 | |||
| 857 | /* MAX_EISA ports */ | ||
| 858 | 0x1c88, 0x2c88, 0x3c88, 0x4c88, 0x5c88, 0x6c88, 0x7c88, 0x8c88, | ||
| 859 | 0x9c88, 0xac88, 0xbc88, 0xcc88, 0xdc88, 0xec88, 0xfc88, | ||
| 860 | |||
| 861 | /* Other (MAX_ISA - 1) ports */ | ||
| 862 | 0x170, 0x230, 0x330, | ||
| 863 | |||
| 864 | /* End of list */ | ||
| 865 | 0x0 | ||
| 866 | }; | ||
| 867 | |||
| 868 | /* Device is Big Endian */ | ||
| 869 | #define H2DEV(x) cpu_to_be32(x) | ||
| 870 | #define DEV2H(x) be32_to_cpu(x) | ||
| 871 | #define H2DEV16(x) cpu_to_be16(x) | ||
| 872 | #define DEV2H16(x) be16_to_cpu(x) | ||
| 873 | |||
| 874 | /* But transfer orientation from the 16 bit data register is Little Endian */ | ||
| 875 | #define REG2H(x) le16_to_cpu(x) | ||
| 876 | |||
| 877 | static irqreturn_t do_interrupt_handler(int, void *); | ||
| 878 | static void flush_dev(struct scsi_device *, unsigned long, struct hostdata *, | ||
| 879 | unsigned int); | ||
| 880 | static int do_trace = 0; | ||
| 881 | static int setup_done = 0; | ||
| 882 | static int link_statistics; | ||
| 883 | static int ext_tran = 0; | ||
| 884 | static int rev_scan = 1; | ||
| 885 | |||
| 886 | #if defined(CONFIG_SCSI_EATA_TAGGED_QUEUE) | ||
| 887 | static int tag_mode = TAG_SIMPLE; | ||
| 888 | #else | ||
| 889 | static int tag_mode = TAG_DISABLED; | ||
| 890 | #endif | ||
| 891 | |||
| 892 | #if defined(CONFIG_SCSI_EATA_LINKED_COMMANDS) | ||
| 893 | static int linked_comm = 1; | ||
| 894 | #else | ||
| 895 | static int linked_comm = 0; | ||
| 896 | #endif | ||
| 897 | |||
| 898 | #if defined(CONFIG_SCSI_EATA_MAX_TAGS) | ||
| 899 | static int max_queue_depth = CONFIG_SCSI_EATA_MAX_TAGS; | ||
| 900 | #else | ||
| 901 | static int max_queue_depth = MAX_CMD_PER_LUN; | ||
| 902 | #endif | ||
| 903 | |||
| 904 | #if defined(CONFIG_ISA) | ||
| 905 | static int isa_probe = 1; | ||
| 906 | #else | ||
| 907 | static int isa_probe = 0; | ||
| 908 | #endif | ||
| 909 | |||
| 910 | #if defined(CONFIG_EISA) | ||
| 911 | static int eisa_probe = 1; | ||
| 912 | #else | ||
| 913 | static int eisa_probe = 0; | ||
| 914 | #endif | ||
| 915 | |||
| 916 | #if defined(CONFIG_PCI) | ||
| 917 | static int pci_probe = 1; | ||
| 918 | #else | ||
| 919 | static int pci_probe = 0; | ||
| 920 | #endif | ||
| 921 | |||
| 922 | #define MAX_INT_PARAM 10 | ||
| 923 | #define MAX_BOOT_OPTIONS_SIZE 256 | ||
| 924 | static char boot_options[MAX_BOOT_OPTIONS_SIZE]; | ||
| 925 | |||
| 926 | #if defined(MODULE) | ||
| 927 | #include <linux/module.h> | ||
| 928 | #include <linux/moduleparam.h> | ||
| 929 | |||
| 930 | module_param_string(eata, boot_options, MAX_BOOT_OPTIONS_SIZE, 0); | ||
| 931 | MODULE_PARM_DESC(eata, " equivalent to the \"eata=...\" kernel boot option." | ||
| 932 | " Example: modprobe eata \"eata=0x7410,0x230,lc:y,tm:0,mq:4,ep:n\""); | ||
| 933 | MODULE_AUTHOR("Dario Ballabio"); | ||
| 934 | MODULE_LICENSE("GPL"); | ||
| 935 | MODULE_DESCRIPTION("EATA/DMA SCSI Driver"); | ||
| 936 | |||
| 937 | #endif | ||
| 938 | |||
| 939 | static int eata2x_slave_configure(struct scsi_device *dev) | ||
| 940 | { | ||
| 941 | int tqd, utqd; | ||
| 942 | char *tag_suffix, *link_suffix; | ||
| 943 | |||
| 944 | utqd = MAX_CMD_PER_LUN; | ||
| 945 | tqd = max_queue_depth; | ||
| 946 | |||
| 947 | if (TLDEV(dev->type) && dev->tagged_supported) { | ||
| 948 | if (tag_mode == TAG_SIMPLE) { | ||
| 949 | tag_suffix = ", simple tags"; | ||
| 950 | } else if (tag_mode == TAG_ORDERED) { | ||
| 951 | tag_suffix = ", ordered tags"; | ||
| 952 | } else { | ||
| 953 | tag_suffix = ", no tags"; | ||
| 954 | } | ||
| 955 | scsi_change_queue_depth(dev, tqd); | ||
| 956 | } else if (TLDEV(dev->type) && linked_comm) { | ||
| 957 | scsi_change_queue_depth(dev, tqd); | ||
| 958 | tag_suffix = ", untagged"; | ||
| 959 | } else { | ||
| 960 | scsi_change_queue_depth(dev, utqd); | ||
| 961 | tag_suffix = ""; | ||
| 962 | } | ||
| 963 | |||
| 964 | if (TLDEV(dev->type) && linked_comm && dev->queue_depth > 2) | ||
| 965 | link_suffix = ", sorted"; | ||
| 966 | else if (TLDEV(dev->type)) | ||
| 967 | link_suffix = ", unsorted"; | ||
| 968 | else | ||
| 969 | link_suffix = ""; | ||
| 970 | |||
| 971 | sdev_printk(KERN_INFO, dev, | ||
| 972 | "cmds/lun %d%s%s.\n", | ||
| 973 | dev->queue_depth, link_suffix, tag_suffix); | ||
| 974 | |||
| 975 | return 0; | ||
| 976 | } | ||
| 977 | |||
| 978 | static int wait_on_busy(unsigned long iobase, unsigned int loop) | ||
| 979 | { | ||
| 980 | while (inb(iobase + REG_AUX_STATUS) & ABSY_ASSERTED) { | ||
| 981 | udelay(1L); | ||
| 982 | if (--loop == 0) | ||
| 983 | return 1; | ||
| 984 | } | ||
| 985 | return 0; | ||
| 986 | } | ||
| 987 | |||
| 988 | static int do_dma(unsigned long iobase, unsigned long addr, unchar cmd) | ||
| 989 | { | ||
| 990 | unsigned char *byaddr; | ||
| 991 | unsigned long devaddr; | ||
| 992 | |||
| 993 | if (wait_on_busy(iobase, (addr ? MAXLOOP * 100 : MAXLOOP))) | ||
| 994 | return 1; | ||
| 995 | |||
| 996 | if (addr) { | ||
| 997 | devaddr = H2DEV(addr); | ||
| 998 | byaddr = (unsigned char *)&devaddr; | ||
| 999 | outb(byaddr[3], iobase + REG_LOW); | ||
| 1000 | outb(byaddr[2], iobase + REG_LM); | ||
| 1001 | outb(byaddr[1], iobase + REG_MID); | ||
| 1002 | outb(byaddr[0], iobase + REG_MSB); | ||
| 1003 | } | ||
| 1004 | |||
| 1005 | outb(cmd, iobase + REG_CMD); | ||
| 1006 | return 0; | ||
| 1007 | } | ||
| 1008 | |||
| 1009 | static int read_pio(unsigned long iobase, ushort * start, ushort * end) | ||
| 1010 | { | ||
| 1011 | unsigned int loop = MAXLOOP; | ||
| 1012 | ushort *p; | ||
| 1013 | |||
| 1014 | for (p = start; p <= end; p++) { | ||
| 1015 | while (!(inb(iobase + REG_STATUS) & DRQ_ASSERTED)) { | ||
| 1016 | udelay(1L); | ||
| 1017 | if (--loop == 0) | ||
| 1018 | return 1; | ||
| 1019 | } | ||
| 1020 | loop = MAXLOOP; | ||
| 1021 | *p = REG2H(inw(iobase)); | ||
| 1022 | } | ||
| 1023 | |||
| 1024 | return 0; | ||
| 1025 | } | ||
| 1026 | |||
| 1027 | static struct pci_dev *get_pci_dev(unsigned long port_base) | ||
| 1028 | { | ||
| 1029 | #if defined(CONFIG_PCI) | ||
| 1030 | unsigned int addr; | ||
| 1031 | struct pci_dev *dev = NULL; | ||
| 1032 | |||
| 1033 | while ((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) { | ||
| 1034 | addr = pci_resource_start(dev, 0); | ||
| 1035 | |||
| 1036 | #if defined(DEBUG_PCI_DETECT) | ||
| 1037 | printk("%s: get_pci_dev, bus %d, devfn 0x%x, addr 0x%x.\n", | ||
| 1038 | driver_name, dev->bus->number, dev->devfn, addr); | ||
| 1039 | #endif | ||
| 1040 | |||
| 1041 | /* we are in so much trouble for a pci hotplug system with this driver | ||
| 1042 | * anyway, so doing this at least lets people unload the driver and not | ||
| 1043 | * cause memory problems, but in general this is a bad thing to do (this | ||
| 1044 | * driver needs to be converted to the proper PCI api someday... */ | ||
| 1045 | pci_dev_put(dev); | ||
| 1046 | if (addr + PCI_BASE_ADDRESS_0 == port_base) | ||
| 1047 | return dev; | ||
| 1048 | } | ||
| 1049 | #endif /* end CONFIG_PCI */ | ||
| 1050 | return NULL; | ||
| 1051 | } | ||
| 1052 | |||
| 1053 | static void enable_pci_ports(void) | ||
| 1054 | { | ||
| 1055 | #if defined(CONFIG_PCI) | ||
| 1056 | struct pci_dev *dev = NULL; | ||
| 1057 | |||
| 1058 | while ((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) { | ||
| 1059 | #if defined(DEBUG_PCI_DETECT) | ||
| 1060 | printk("%s: enable_pci_ports, bus %d, devfn 0x%x.\n", | ||
| 1061 | driver_name, dev->bus->number, dev->devfn); | ||
| 1062 | #endif | ||
| 1063 | |||
| 1064 | if (pci_enable_device(dev)) | ||
| 1065 | printk | ||
| 1066 | ("%s: warning, pci_enable_device failed, bus %d devfn 0x%x.\n", | ||
| 1067 | driver_name, dev->bus->number, dev->devfn); | ||
| 1068 | } | ||
| 1069 | |||
| 1070 | #endif /* end CONFIG_PCI */ | ||
| 1071 | } | ||
| 1072 | |||
| 1073 | static int port_detect(unsigned long port_base, unsigned int j, | ||
| 1074 | struct scsi_host_template *tpnt) | ||
| 1075 | { | ||
| 1076 | unsigned char irq, dma_channel, subversion, i, is_pci = 0; | ||
| 1077 | unsigned char protocol_rev; | ||
| 1078 | struct eata_info info; | ||
| 1079 | char *bus_type, dma_name[16]; | ||
| 1080 | struct pci_dev *pdev; | ||
| 1081 | /* Allowed DMA channels for ISA (0 indicates reserved) */ | ||
| 1082 | unsigned char dma_channel_table[4] = { 5, 6, 7, 0 }; | ||
| 1083 | struct Scsi_Host *shost; | ||
| 1084 | struct hostdata *ha; | ||
| 1085 | char name[16]; | ||
| 1086 | |||
| 1087 | sprintf(name, "%s%d", driver_name, j); | ||
| 1088 | |||
| 1089 | if (!request_region(port_base, REGION_SIZE, driver_name)) { | ||
| 1090 | #if defined(DEBUG_DETECT) | ||
| 1091 | printk("%s: address 0x%03lx in use, skipping probe.\n", name, | ||
| 1092 | port_base); | ||
| 1093 | #endif | ||
| 1094 | goto fail; | ||
| 1095 | } | ||
| 1096 | |||
| 1097 | if (do_dma(port_base, 0, READ_CONFIG_PIO)) { | ||
| 1098 | #if defined(DEBUG_DETECT) | ||
| 1099 | printk("%s: detect, do_dma failed at 0x%03lx.\n", name, | ||
| 1100 | port_base); | ||
| 1101 | #endif | ||
| 1102 | goto freelock; | ||
| 1103 | } | ||
| 1104 | |||
| 1105 | /* Read the info structure */ | ||
| 1106 | if (read_pio(port_base, (ushort *) & info, (ushort *) & info.ipad[0])) { | ||
| 1107 | #if defined(DEBUG_DETECT) | ||
| 1108 | printk("%s: detect, read_pio failed at 0x%03lx.\n", name, | ||
| 1109 | port_base); | ||
| 1110 | #endif | ||
| 1111 | goto freelock; | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | info.data_len = DEV2H(info.data_len); | ||
| 1115 | info.sign = DEV2H(info.sign); | ||
| 1116 | info.cp_pad_len = DEV2H16(info.cp_pad_len); | ||
| 1117 | info.cp_len = DEV2H(info.cp_len); | ||
| 1118 | info.sp_len = DEV2H(info.sp_len); | ||
| 1119 | info.scatt_size = DEV2H16(info.scatt_size); | ||
| 1120 | info.queue_size = DEV2H16(info.queue_size); | ||
| 1121 | |||
| 1122 | /* Check the controller "EATA" signature */ | ||
| 1123 | if (info.sign != EATA_SIG_BE) { | ||
| 1124 | #if defined(DEBUG_DETECT) | ||
| 1125 | printk("%s: signature 0x%04x discarded.\n", name, info.sign); | ||
| 1126 | #endif | ||
| 1127 | goto freelock; | ||
| 1128 | } | ||
| 1129 | |||
| 1130 | if (info.data_len < EATA_2_0A_SIZE) { | ||
| 1131 | printk | ||
| 1132 | ("%s: config structure size (%d bytes) too short, detaching.\n", | ||
| 1133 | name, info.data_len); | ||
| 1134 | goto freelock; | ||
| 1135 | } else if (info.data_len == EATA_2_0A_SIZE) | ||
| 1136 | protocol_rev = 'A'; | ||
| 1137 | else if (info.data_len == EATA_2_0B_SIZE) | ||
| 1138 | protocol_rev = 'B'; | ||
| 1139 | else | ||
| 1140 | protocol_rev = 'C'; | ||
| 1141 | |||
| 1142 | if (protocol_rev != 'A' && info.forcaddr) { | ||
| 1143 | printk("%s: warning, port address has been forced.\n", name); | ||
| 1144 | bus_type = "PCI"; | ||
| 1145 | is_pci = 1; | ||
| 1146 | subversion = ESA; | ||
| 1147 | } else if (port_base > MAX_EISA_ADDR | ||
| 1148 | || (protocol_rev == 'C' && info.pci)) { | ||
| 1149 | bus_type = "PCI"; | ||
| 1150 | is_pci = 1; | ||
| 1151 | subversion = ESA; | ||
| 1152 | } else if (port_base >= MIN_EISA_ADDR | ||
| 1153 | || (protocol_rev == 'C' && info.eisa)) { | ||
| 1154 | bus_type = "EISA"; | ||
| 1155 | subversion = ESA; | ||
| 1156 | } else if (protocol_rev == 'C' && !info.eisa && !info.pci) { | ||
| 1157 | bus_type = "ISA"; | ||
| 1158 | subversion = ISA; | ||
| 1159 | } else if (port_base > MAX_ISA_ADDR) { | ||
| 1160 | bus_type = "PCI"; | ||
| 1161 | is_pci = 1; | ||
| 1162 | subversion = ESA; | ||
| 1163 | } else { | ||
| 1164 | bus_type = "ISA"; | ||
| 1165 | subversion = ISA; | ||
| 1166 | } | ||
| 1167 | |||
| 1168 | if (!info.haaval || info.ata) { | ||
| 1169 | printk | ||
| 1170 | ("%s: address 0x%03lx, unusable %s board (%d%d), detaching.\n", | ||
| 1171 | name, port_base, bus_type, info.haaval, info.ata); | ||
| 1172 | goto freelock; | ||
| 1173 | } | ||
| 1174 | |||
| 1175 | if (info.drqvld) { | ||
| 1176 | if (subversion == ESA) | ||
| 1177 | printk("%s: warning, weird %s board using DMA.\n", name, | ||
| 1178 | bus_type); | ||
| 1179 | |||
| 1180 | subversion = ISA; | ||
| 1181 | dma_channel = dma_channel_table[3 - info.drqx]; | ||
| 1182 | } else { | ||
| 1183 | if (subversion == ISA) | ||
| 1184 | printk("%s: warning, weird %s board not using DMA.\n", | ||
| 1185 | name, bus_type); | ||
| 1186 | |||
| 1187 | subversion = ESA; | ||
| 1188 | dma_channel = NO_DMA; | ||
| 1189 | } | ||
| 1190 | |||
| 1191 | if (!info.dmasup) | ||
| 1192 | printk("%s: warning, DMA protocol support not asserted.\n", | ||
| 1193 | name); | ||
| 1194 | |||
| 1195 | irq = info.irq; | ||
| 1196 | |||
| 1197 | if (subversion == ESA && !info.irq_tr) | ||
| 1198 | printk | ||
| 1199 | ("%s: warning, LEVEL triggering is suggested for IRQ %u.\n", | ||
| 1200 | name, irq); | ||
| 1201 | |||
| 1202 | if (is_pci) { | ||
| 1203 | pdev = get_pci_dev(port_base); | ||
| 1204 | if (!pdev) | ||
| 1205 | printk | ||
| 1206 | ("%s: warning, failed to get pci_dev structure.\n", | ||
| 1207 | name); | ||
| 1208 | } else | ||
| 1209 | pdev = NULL; | ||
| 1210 | |||
| 1211 | if (pdev && (irq != pdev->irq)) { | ||
| 1212 | printk("%s: IRQ %u mapped to IO-APIC IRQ %u.\n", name, irq, | ||
| 1213 | pdev->irq); | ||
| 1214 | irq = pdev->irq; | ||
| 1215 | } | ||
| 1216 | |||
| 1217 | /* Board detected, allocate its IRQ */ | ||
| 1218 | if (request_irq(irq, do_interrupt_handler, | ||
| 1219 | (subversion == ESA) ? IRQF_SHARED : 0, | ||
| 1220 | driver_name, (void *)&sha[j])) { | ||
| 1221 | printk("%s: unable to allocate IRQ %u, detaching.\n", name, | ||
| 1222 | irq); | ||
| 1223 | goto freelock; | ||
| 1224 | } | ||
| 1225 | |||
| 1226 | if (subversion == ISA && request_dma(dma_channel, driver_name)) { | ||
| 1227 | printk("%s: unable to allocate DMA channel %u, detaching.\n", | ||
| 1228 | name, dma_channel); | ||
| 1229 | goto freeirq; | ||
| 1230 | } | ||
| 1231 | #if defined(FORCE_CONFIG) | ||
| 1232 | { | ||
| 1233 | struct eata_config *cf; | ||
| 1234 | dma_addr_t cf_dma_addr; | ||
| 1235 | |||
| 1236 | cf = pci_zalloc_consistent(pdev, sizeof(struct eata_config), | ||
| 1237 | &cf_dma_addr); | ||
| 1238 | |||
| 1239 | if (!cf) { | ||
| 1240 | printk | ||
| 1241 | ("%s: config, pci_alloc_consistent failed, detaching.\n", | ||
| 1242 | name); | ||
| 1243 | goto freedma; | ||
| 1244 | } | ||
| 1245 | |||
| 1246 | /* Set board configuration */ | ||
| 1247 | cf->len = (ushort) H2DEV16((ushort) 510); | ||
| 1248 | cf->ocena = 1; | ||
| 1249 | |||
| 1250 | if (do_dma(port_base, cf_dma_addr, SET_CONFIG_DMA)) { | ||
| 1251 | printk | ||
| 1252 | ("%s: busy timeout sending configuration, detaching.\n", | ||
| 1253 | name); | ||
| 1254 | pci_free_consistent(pdev, sizeof(struct eata_config), | ||
| 1255 | cf, cf_dma_addr); | ||
| 1256 | goto freedma; | ||
| 1257 | } | ||
| 1258 | |||
| 1259 | } | ||
| 1260 | #endif | ||
| 1261 | |||
| 1262 | sh[j] = shost = scsi_register(tpnt, sizeof(struct hostdata)); | ||
| 1263 | if (shost == NULL) { | ||
| 1264 | printk("%s: unable to register host, detaching.\n", name); | ||
| 1265 | goto freedma; | ||
| 1266 | } | ||
| 1267 | |||
| 1268 | shost->io_port = port_base; | ||
| 1269 | shost->unique_id = port_base; | ||
| 1270 | shost->n_io_port = REGION_SIZE; | ||
| 1271 | shost->dma_channel = dma_channel; | ||
| 1272 | shost->irq = irq; | ||
| 1273 | shost->sg_tablesize = (ushort) info.scatt_size; | ||
| 1274 | shost->this_id = (ushort) info.host_addr[3]; | ||
| 1275 | shost->can_queue = (ushort) info.queue_size; | ||
| 1276 | shost->cmd_per_lun = MAX_CMD_PER_LUN; | ||
| 1277 | |||
| 1278 | ha = (struct hostdata *)shost->hostdata; | ||
| 1279 | |||
| 1280 | memset(ha, 0, sizeof(struct hostdata)); | ||
| 1281 | ha->subversion = subversion; | ||
| 1282 | ha->protocol_rev = protocol_rev; | ||
| 1283 | ha->is_pci = is_pci; | ||
| 1284 | ha->pdev = pdev; | ||
| 1285 | ha->board_number = j; | ||
| 1286 | |||
| 1287 | if (ha->subversion == ESA) | ||
| 1288 | shost->unchecked_isa_dma = 0; | ||
| 1289 | else { | ||
| 1290 | unsigned long flags; | ||
| 1291 | shost->unchecked_isa_dma = 1; | ||
| 1292 | |||
| 1293 | flags = claim_dma_lock(); | ||
| 1294 | disable_dma(dma_channel); | ||
| 1295 | clear_dma_ff(dma_channel); | ||
| 1296 | set_dma_mode(dma_channel, DMA_MODE_CASCADE); | ||
| 1297 | enable_dma(dma_channel); | ||
| 1298 | release_dma_lock(flags); | ||
| 1299 | |||
| 1300 | } | ||
| 1301 | |||
| 1302 | strcpy(ha->board_name, name); | ||
| 1303 | |||
| 1304 | /* DPT PM2012 does not allow to detect sg_tablesize correctly */ | ||
| 1305 | if (shost->sg_tablesize > MAX_SGLIST || shost->sg_tablesize < 2) { | ||
| 1306 | printk("%s: detect, wrong n. of SG lists %d, fixed.\n", | ||
| 1307 | ha->board_name, shost->sg_tablesize); | ||
| 1308 | shost->sg_tablesize = MAX_SGLIST; | ||
| 1309 | } | ||
| 1310 | |||
| 1311 | /* DPT PM2012 does not allow to detect can_queue correctly */ | ||
| 1312 | if (shost->can_queue > MAX_MAILBOXES || shost->can_queue < 2) { | ||
| 1313 | printk("%s: detect, wrong n. of mbox %d, fixed.\n", | ||
| 1314 | ha->board_name, shost->can_queue); | ||
| 1315 | shost->can_queue = MAX_MAILBOXES; | ||
| 1316 | } | ||
| 1317 | |||
| 1318 | if (protocol_rev != 'A') { | ||
| 1319 | if (info.max_chan > 0 && info.max_chan < MAX_CHANNEL) | ||
| 1320 | shost->max_channel = info.max_chan; | ||
| 1321 | |||
| 1322 | if (info.max_id > 7 && info.max_id < MAX_TARGET) | ||
| 1323 | shost->max_id = info.max_id + 1; | ||
| 1324 | |||
| 1325 | if (info.large_sg && shost->sg_tablesize == MAX_SGLIST) | ||
| 1326 | shost->sg_tablesize = MAX_LARGE_SGLIST; | ||
| 1327 | } | ||
| 1328 | |||
| 1329 | if (protocol_rev == 'C') { | ||
| 1330 | if (info.max_lun > 7 && info.max_lun < MAX_LUN) | ||
| 1331 | shost->max_lun = info.max_lun + 1; | ||
| 1332 | } | ||
| 1333 | |||
| 1334 | if (dma_channel == NO_DMA) | ||
| 1335 | sprintf(dma_name, "%s", "BMST"); | ||
| 1336 | else | ||
| 1337 | sprintf(dma_name, "DMA %u", dma_channel); | ||
| 1338 | |||
| 1339 | for (i = 0; i < shost->can_queue; i++) | ||
| 1340 | ha->cp[i].cp_dma_addr = pci_map_single(ha->pdev, | ||
| 1341 | &ha->cp[i], | ||
| 1342 | sizeof(struct mscp), | ||
| 1343 | PCI_DMA_BIDIRECTIONAL); | ||
| 1344 | |||
| 1345 | for (i = 0; i < shost->can_queue; i++) { | ||
| 1346 | size_t sz = shost->sg_tablesize *sizeof(struct sg_list); | ||
| 1347 | gfp_t gfp_mask = (shost->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC; | ||
| 1348 | ha->cp[i].sglist = kmalloc(sz, gfp_mask); | ||
| 1349 | if (!ha->cp[i].sglist) { | ||
| 1350 | printk | ||
| 1351 | ("%s: kmalloc SGlist failed, mbox %d, detaching.\n", | ||
| 1352 | ha->board_name, i); | ||
| 1353 | goto release; | ||
| 1354 | } | ||
| 1355 | } | ||
| 1356 | |||
| 1357 | if (!(ha->sp_cpu_addr = pci_alloc_consistent(ha->pdev, | ||
| 1358 | sizeof(struct mssp), | ||
| 1359 | &ha->sp_dma_addr))) { | ||
| 1360 | printk("%s: pci_alloc_consistent failed, detaching.\n", ha->board_name); | ||
| 1361 | goto release; | ||
| 1362 | } | ||
| 1363 | |||
| 1364 | if (max_queue_depth > MAX_TAGGED_CMD_PER_LUN) | ||
| 1365 | max_queue_depth = MAX_TAGGED_CMD_PER_LUN; | ||
| 1366 | |||
| 1367 | if (max_queue_depth < MAX_CMD_PER_LUN) | ||
| 1368 | max_queue_depth = MAX_CMD_PER_LUN; | ||
| 1369 | |||
| 1370 | if (tag_mode != TAG_DISABLED && tag_mode != TAG_SIMPLE) | ||
| 1371 | tag_mode = TAG_ORDERED; | ||
| 1372 | |||
| 1373 | if (j == 0) { | ||
| 1374 | printk | ||
| 1375 | ("EATA/DMA 2.0x: Copyright (C) 1994-2003 Dario Ballabio.\n"); | ||
| 1376 | printk | ||
| 1377 | ("%s config options -> tm:%d, lc:%c, mq:%d, rs:%c, et:%c, " | ||
| 1378 | "ip:%c, ep:%c, pp:%c.\n", driver_name, tag_mode, | ||
| 1379 | YESNO(linked_comm), max_queue_depth, YESNO(rev_scan), | ||
| 1380 | YESNO(ext_tran), YESNO(isa_probe), YESNO(eisa_probe), | ||
| 1381 | YESNO(pci_probe)); | ||
| 1382 | } | ||
| 1383 | |||
| 1384 | printk("%s: 2.0%c, %s 0x%03lx, IRQ %u, %s, SG %d, MB %d.\n", | ||
| 1385 | ha->board_name, ha->protocol_rev, bus_type, | ||
| 1386 | (unsigned long)shost->io_port, shost->irq, dma_name, | ||
| 1387 | shost->sg_tablesize, shost->can_queue); | ||
| 1388 | |||
| 1389 | if (shost->max_id > 8 || shost->max_lun > 8) | ||
| 1390 | printk | ||
| 1391 | ("%s: wide SCSI support enabled, max_id %u, max_lun %llu.\n", | ||
| 1392 | ha->board_name, shost->max_id, shost->max_lun); | ||
| 1393 | |||
| 1394 | for (i = 0; i <= shost->max_channel; i++) | ||
| 1395 | printk("%s: SCSI channel %u enabled, host target ID %d.\n", | ||
| 1396 | ha->board_name, i, info.host_addr[3 - i]); | ||
| 1397 | |||
| 1398 | #if defined(DEBUG_DETECT) | ||
| 1399 | printk("%s: Vers. 0x%x, ocs %u, tar %u, trnxfr %u, more %u, SYNC 0x%x, " | ||
| 1400 | "sec. %u, infol %d, cpl %d spl %d.\n", name, info.version, | ||
| 1401 | info.ocsena, info.tarsup, info.trnxfr, info.morsup, info.sync, | ||
| 1402 | info.second, info.data_len, info.cp_len, info.sp_len); | ||
| 1403 | |||
| 1404 | if (protocol_rev == 'B' || protocol_rev == 'C') | ||
| 1405 | printk("%s: isaena %u, forcaddr %u, max_id %u, max_chan %u, " | ||
| 1406 | "large_sg %u, res1 %u.\n", name, info.isaena, | ||
| 1407 | info.forcaddr, info.max_id, info.max_chan, info.large_sg, | ||
| 1408 | info.res1); | ||
| 1409 | |||
| 1410 | if (protocol_rev == 'C') | ||
| 1411 | printk("%s: max_lun %u, m1 %u, idquest %u, pci %u, eisa %u, " | ||
| 1412 | "raidnum %u.\n", name, info.max_lun, info.m1, | ||
| 1413 | info.idquest, info.pci, info.eisa, info.raidnum); | ||
| 1414 | #endif | ||
| 1415 | |||
| 1416 | if (ha->pdev) { | ||
| 1417 | pci_set_master(ha->pdev); | ||
| 1418 | if (pci_set_dma_mask(ha->pdev, DMA_BIT_MASK(32))) | ||
| 1419 | printk("%s: warning, pci_set_dma_mask failed.\n", | ||
| 1420 | ha->board_name); | ||
| 1421 | } | ||
| 1422 | |||
| 1423 | return 1; | ||
| 1424 | |||
| 1425 | freedma: | ||
| 1426 | if (subversion == ISA) | ||
| 1427 | free_dma(dma_channel); | ||
| 1428 | freeirq: | ||
| 1429 | free_irq(irq, &sha[j]); | ||
| 1430 | freelock: | ||
| 1431 | release_region(port_base, REGION_SIZE); | ||
| 1432 | fail: | ||
| 1433 | return 0; | ||
| 1434 | |||
| 1435 | release: | ||
| 1436 | eata2x_release(shost); | ||
| 1437 | return 0; | ||
| 1438 | } | ||
| 1439 | |||
| 1440 | static void internal_setup(char *str, int *ints) | ||
| 1441 | { | ||
| 1442 | int i, argc = ints[0]; | ||
| 1443 | char *cur = str, *pc; | ||
| 1444 | |||
| 1445 | if (argc > 0) { | ||
| 1446 | if (argc > MAX_INT_PARAM) | ||
| 1447 | argc = MAX_INT_PARAM; | ||
| 1448 | |||
| 1449 | for (i = 0; i < argc; i++) | ||
| 1450 | io_port[i] = ints[i + 1]; | ||
| 1451 | |||
| 1452 | io_port[i] = 0; | ||
| 1453 | setup_done = 1; | ||
| 1454 | } | ||
| 1455 | |||
| 1456 | while (cur && (pc = strchr(cur, ':'))) { | ||
| 1457 | int val = 0, c = *++pc; | ||
| 1458 | |||
| 1459 | if (c == 'n' || c == 'N') | ||
| 1460 | val = 0; | ||
| 1461 | else if (c == 'y' || c == 'Y') | ||
| 1462 | val = 1; | ||
| 1463 | else | ||
| 1464 | val = (int)simple_strtoul(pc, NULL, 0); | ||
| 1465 | |||
| 1466 | if (!strncmp(cur, "lc:", 3)) | ||
| 1467 | linked_comm = val; | ||
| 1468 | else if (!strncmp(cur, "tm:", 3)) | ||
| 1469 | tag_mode = val; | ||
| 1470 | else if (!strncmp(cur, "tc:", 3)) | ||
| 1471 | tag_mode = val; | ||
| 1472 | else if (!strncmp(cur, "mq:", 3)) | ||
| 1473 | max_queue_depth = val; | ||
| 1474 | else if (!strncmp(cur, "ls:", 3)) | ||
| 1475 | link_statistics = val; | ||
| 1476 | else if (!strncmp(cur, "et:", 3)) | ||
| 1477 | ext_tran = val; | ||
| 1478 | else if (!strncmp(cur, "rs:", 3)) | ||
| 1479 | rev_scan = val; | ||
| 1480 | else if (!strncmp(cur, "ip:", 3)) | ||
| 1481 | isa_probe = val; | ||
| 1482 | else if (!strncmp(cur, "ep:", 3)) | ||
| 1483 | eisa_probe = val; | ||
| 1484 | else if (!strncmp(cur, "pp:", 3)) | ||
| 1485 | pci_probe = val; | ||
| 1486 | |||
| 1487 | if ((cur = strchr(cur, ','))) | ||
| 1488 | ++cur; | ||
| 1489 | } | ||
| 1490 | |||
| 1491 | return; | ||
| 1492 | } | ||
| 1493 | |||
| 1494 | static int option_setup(char *str) | ||
| 1495 | { | ||
| 1496 | int ints[MAX_INT_PARAM]; | ||
| 1497 | char *cur = str; | ||
| 1498 | int i = 1; | ||
| 1499 | |||
| 1500 | while (cur && isdigit(*cur) && i < MAX_INT_PARAM) { | ||
| 1501 | ints[i++] = simple_strtoul(cur, NULL, 0); | ||
| 1502 | |||
| 1503 | if ((cur = strchr(cur, ',')) != NULL) | ||
| 1504 | cur++; | ||
| 1505 | } | ||
| 1506 | |||
| 1507 | ints[0] = i - 1; | ||
| 1508 | internal_setup(cur, ints); | ||
| 1509 | return 1; | ||
| 1510 | } | ||
| 1511 | |||
| 1512 | static void add_pci_ports(void) | ||
| 1513 | { | ||
| 1514 | #if defined(CONFIG_PCI) | ||
| 1515 | unsigned int addr, k; | ||
| 1516 | struct pci_dev *dev = NULL; | ||
| 1517 | |||
| 1518 | for (k = 0; k < MAX_PCI; k++) { | ||
| 1519 | |||
| 1520 | if (!(dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) | ||
| 1521 | break; | ||
| 1522 | |||
| 1523 | if (pci_enable_device(dev)) { | ||
| 1524 | #if defined(DEBUG_PCI_DETECT) | ||
| 1525 | printk | ||
| 1526 | ("%s: detect, bus %d, devfn 0x%x, pci_enable_device failed.\n", | ||
| 1527 | driver_name, dev->bus->number, dev->devfn); | ||
| 1528 | #endif | ||
| 1529 | |||
| 1530 | continue; | ||
| 1531 | } | ||
| 1532 | |||
| 1533 | addr = pci_resource_start(dev, 0); | ||
| 1534 | |||
| 1535 | #if defined(DEBUG_PCI_DETECT) | ||
| 1536 | printk("%s: detect, seq. %d, bus %d, devfn 0x%x, addr 0x%x.\n", | ||
| 1537 | driver_name, k, dev->bus->number, dev->devfn, addr); | ||
| 1538 | #endif | ||
| 1539 | |||
| 1540 | /* Order addresses according to rev_scan value */ | ||
| 1541 | io_port[MAX_INT_PARAM + (rev_scan ? (MAX_PCI - k) : (1 + k))] = | ||
| 1542 | addr + PCI_BASE_ADDRESS_0; | ||
| 1543 | } | ||
| 1544 | |||
| 1545 | pci_dev_put(dev); | ||
| 1546 | #endif /* end CONFIG_PCI */ | ||
| 1547 | } | ||
| 1548 | |||
| 1549 | static int eata2x_detect(struct scsi_host_template *tpnt) | ||
| 1550 | { | ||
| 1551 | unsigned int j = 0, k; | ||
| 1552 | |||
| 1553 | tpnt->proc_name = "eata2x"; | ||
| 1554 | |||
| 1555 | if (strlen(boot_options)) | ||
| 1556 | option_setup(boot_options); | ||
| 1557 | |||
| 1558 | #if defined(MODULE) | ||
| 1559 | /* io_port could have been modified when loading as a module */ | ||
| 1560 | if (io_port[0] != SKIP) { | ||
| 1561 | setup_done = 1; | ||
| 1562 | io_port[MAX_INT_PARAM] = 0; | ||
| 1563 | } | ||
| 1564 | #endif | ||
| 1565 | |||
| 1566 | for (k = MAX_INT_PARAM; io_port[k]; k++) | ||
| 1567 | if (io_port[k] == SKIP) | ||
| 1568 | continue; | ||
| 1569 | else if (io_port[k] <= MAX_ISA_ADDR) { | ||
| 1570 | if (!isa_probe) | ||
| 1571 | io_port[k] = SKIP; | ||
| 1572 | } else if (io_port[k] >= MIN_EISA_ADDR | ||
| 1573 | && io_port[k] <= MAX_EISA_ADDR) { | ||
| 1574 | if (!eisa_probe) | ||
| 1575 | io_port[k] = SKIP; | ||
| 1576 | } | ||
| 1577 | |||
| 1578 | if (pci_probe) { | ||
| 1579 | if (!setup_done) | ||
| 1580 | add_pci_ports(); | ||
| 1581 | else | ||
| 1582 | enable_pci_ports(); | ||
| 1583 | } | ||
| 1584 | |||
| 1585 | for (k = 0; io_port[k]; k++) { | ||
| 1586 | |||
| 1587 | if (io_port[k] == SKIP) | ||
| 1588 | continue; | ||
| 1589 | |||
| 1590 | if (j < MAX_BOARDS && port_detect(io_port[k], j, tpnt)) | ||
| 1591 | j++; | ||
| 1592 | } | ||
| 1593 | |||
| 1594 | num_boards = j; | ||
| 1595 | return j; | ||
| 1596 | } | ||
| 1597 | |||
| 1598 | static void map_dma(unsigned int i, struct hostdata *ha) | ||
| 1599 | { | ||
| 1600 | unsigned int k, pci_dir; | ||
| 1601 | int count; | ||
| 1602 | struct scatterlist *sg; | ||
| 1603 | struct mscp *cpp; | ||
| 1604 | struct scsi_cmnd *SCpnt; | ||
| 1605 | |||
| 1606 | cpp = &ha->cp[i]; | ||
| 1607 | SCpnt = cpp->SCpnt; | ||
| 1608 | pci_dir = SCpnt->sc_data_direction; | ||
| 1609 | |||
| 1610 | if (SCpnt->sense_buffer) | ||
| 1611 | cpp->sense_addr = | ||
| 1612 | H2DEV(pci_map_single(ha->pdev, SCpnt->sense_buffer, | ||
| 1613 | SCSI_SENSE_BUFFERSIZE, PCI_DMA_FROMDEVICE)); | ||
| 1614 | |||
| 1615 | cpp->sense_len = SCSI_SENSE_BUFFERSIZE; | ||
| 1616 | |||
| 1617 | if (!scsi_sg_count(SCpnt)) { | ||
| 1618 | cpp->data_len = 0; | ||
| 1619 | return; | ||
| 1620 | } | ||
| 1621 | |||
| 1622 | count = pci_map_sg(ha->pdev, scsi_sglist(SCpnt), scsi_sg_count(SCpnt), | ||
| 1623 | pci_dir); | ||
| 1624 | BUG_ON(!count); | ||
| 1625 | |||
| 1626 | scsi_for_each_sg(SCpnt, sg, count, k) { | ||
| 1627 | cpp->sglist[k].address = H2DEV(sg_dma_address(sg)); | ||
| 1628 | cpp->sglist[k].num_bytes = H2DEV(sg_dma_len(sg)); | ||
| 1629 | } | ||
| 1630 | |||
| 1631 | cpp->sg = 1; | ||
| 1632 | cpp->data_address = H2DEV(pci_map_single(ha->pdev, cpp->sglist, | ||
| 1633 | scsi_sg_count(SCpnt) * | ||
| 1634 | sizeof(struct sg_list), | ||
| 1635 | pci_dir)); | ||
| 1636 | cpp->data_len = H2DEV((scsi_sg_count(SCpnt) * sizeof(struct sg_list))); | ||
| 1637 | } | ||
| 1638 | |||
| 1639 | static void unmap_dma(unsigned int i, struct hostdata *ha) | ||
| 1640 | { | ||
| 1641 | unsigned int pci_dir; | ||
| 1642 | struct mscp *cpp; | ||
| 1643 | struct scsi_cmnd *SCpnt; | ||
| 1644 | |||
| 1645 | cpp = &ha->cp[i]; | ||
| 1646 | SCpnt = cpp->SCpnt; | ||
| 1647 | pci_dir = SCpnt->sc_data_direction; | ||
| 1648 | |||
| 1649 | if (DEV2H(cpp->sense_addr)) | ||
| 1650 | pci_unmap_single(ha->pdev, DEV2H(cpp->sense_addr), | ||
| 1651 | DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE); | ||
| 1652 | |||
| 1653 | if (scsi_sg_count(SCpnt)) | ||
| 1654 | pci_unmap_sg(ha->pdev, scsi_sglist(SCpnt), scsi_sg_count(SCpnt), | ||
| 1655 | pci_dir); | ||
| 1656 | |||
| 1657 | if (!DEV2H(cpp->data_len)) | ||
| 1658 | pci_dir = PCI_DMA_BIDIRECTIONAL; | ||
| 1659 | |||
| 1660 | if (DEV2H(cpp->data_address)) | ||
| 1661 | pci_unmap_single(ha->pdev, DEV2H(cpp->data_address), | ||
| 1662 | DEV2H(cpp->data_len), pci_dir); | ||
| 1663 | } | ||
| 1664 | |||
| 1665 | static void sync_dma(unsigned int i, struct hostdata *ha) | ||
| 1666 | { | ||
| 1667 | unsigned int pci_dir; | ||
| 1668 | struct mscp *cpp; | ||
| 1669 | struct scsi_cmnd *SCpnt; | ||
| 1670 | |||
| 1671 | cpp = &ha->cp[i]; | ||
| 1672 | SCpnt = cpp->SCpnt; | ||
| 1673 | pci_dir = SCpnt->sc_data_direction; | ||
| 1674 | |||
| 1675 | if (DEV2H(cpp->sense_addr)) | ||
| 1676 | pci_dma_sync_single_for_cpu(ha->pdev, DEV2H(cpp->sense_addr), | ||
| 1677 | DEV2H(cpp->sense_len), | ||
| 1678 | PCI_DMA_FROMDEVICE); | ||
| 1679 | |||
| 1680 | if (scsi_sg_count(SCpnt)) | ||
| 1681 | pci_dma_sync_sg_for_cpu(ha->pdev, scsi_sglist(SCpnt), | ||
| 1682 | scsi_sg_count(SCpnt), pci_dir); | ||
| 1683 | |||
| 1684 | if (!DEV2H(cpp->data_len)) | ||
| 1685 | pci_dir = PCI_DMA_BIDIRECTIONAL; | ||
| 1686 | |||
| 1687 | if (DEV2H(cpp->data_address)) | ||
| 1688 | pci_dma_sync_single_for_cpu(ha->pdev, | ||
| 1689 | DEV2H(cpp->data_address), | ||
| 1690 | DEV2H(cpp->data_len), pci_dir); | ||
| 1691 | } | ||
| 1692 | |||
| 1693 | static void scsi_to_dev_dir(unsigned int i, struct hostdata *ha) | ||
| 1694 | { | ||
| 1695 | unsigned int k; | ||
| 1696 | |||
| 1697 | static const unsigned char data_out_cmds[] = { | ||
| 1698 | 0x0a, 0x2a, 0x15, 0x55, 0x04, 0x07, 0x18, 0x1d, 0x24, 0x2e, | ||
| 1699 | 0x30, 0x31, 0x32, 0x38, 0x39, 0x3a, 0x3b, 0x3d, 0x3f, 0x40, | ||
| 1700 | 0x41, 0x4c, 0xaa, 0xae, 0xb0, 0xb1, 0xb2, 0xb6, 0xea, 0x1b, 0x5d | ||
| 1701 | }; | ||
| 1702 | |||
| 1703 | static const unsigned char data_none_cmds[] = { | ||
| 1704 | 0x01, 0x0b, 0x10, 0x11, 0x13, 0x16, 0x17, 0x19, 0x2b, 0x1e, | ||
| 1705 | 0x2c, 0xac, 0x2f, 0xaf, 0x33, 0xb3, 0x35, 0x36, 0x45, 0x47, | ||
| 1706 | 0x48, 0x49, 0xa9, 0x4b, 0xa5, 0xa6, 0xb5, 0x00 | ||
| 1707 | }; | ||
| 1708 | |||
| 1709 | struct mscp *cpp; | ||
| 1710 | struct scsi_cmnd *SCpnt; | ||
| 1711 | |||
| 1712 | cpp = &ha->cp[i]; | ||
| 1713 | SCpnt = cpp->SCpnt; | ||
| 1714 | |||
| 1715 | if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) { | ||
| 1716 | cpp->din = 1; | ||
| 1717 | cpp->dout = 0; | ||
| 1718 | return; | ||
| 1719 | } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) { | ||
| 1720 | cpp->din = 0; | ||
| 1721 | cpp->dout = 1; | ||
| 1722 | return; | ||
| 1723 | } else if (SCpnt->sc_data_direction == DMA_NONE) { | ||
| 1724 | cpp->din = 0; | ||
| 1725 | cpp->dout = 0; | ||
| 1726 | return; | ||
| 1727 | } | ||
| 1728 | |||
| 1729 | if (SCpnt->sc_data_direction != DMA_BIDIRECTIONAL) | ||
| 1730 | panic("%s: qcomm, invalid SCpnt->sc_data_direction.\n", | ||
| 1731 | ha->board_name); | ||
| 1732 | |||
| 1733 | for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++) | ||
| 1734 | if (SCpnt->cmnd[0] == data_out_cmds[k]) { | ||
| 1735 | cpp->dout = 1; | ||
| 1736 | break; | ||
| 1737 | } | ||
| 1738 | |||
| 1739 | if ((cpp->din = !cpp->dout)) | ||
| 1740 | for (k = 0; k < ARRAY_SIZE(data_none_cmds); k++) | ||
| 1741 | if (SCpnt->cmnd[0] == data_none_cmds[k]) { | ||
| 1742 | cpp->din = 0; | ||
| 1743 | break; | ||
| 1744 | } | ||
| 1745 | |||
| 1746 | } | ||
| 1747 | |||
| 1748 | static int eata2x_queuecommand_lck(struct scsi_cmnd *SCpnt, | ||
| 1749 | void (*done) (struct scsi_cmnd *)) | ||
| 1750 | { | ||
| 1751 | struct Scsi_Host *shost = SCpnt->device->host; | ||
| 1752 | struct hostdata *ha = (struct hostdata *)shost->hostdata; | ||
| 1753 | unsigned int i, k; | ||
| 1754 | struct mscp *cpp; | ||
| 1755 | |||
| 1756 | if (SCpnt->host_scribble) | ||
| 1757 | panic("%s: qcomm, SCpnt %p already active.\n", | ||
| 1758 | ha->board_name, SCpnt); | ||
| 1759 | |||
| 1760 | /* i is the mailbox number, look for the first free mailbox | ||
| 1761 | starting from last_cp_used */ | ||
| 1762 | i = ha->last_cp_used + 1; | ||
| 1763 | |||
| 1764 | for (k = 0; k < shost->can_queue; k++, i++) { | ||
| 1765 | if (i >= shost->can_queue) | ||
| 1766 | i = 0; | ||
| 1767 | if (ha->cp_stat[i] == FREE) { | ||
| 1768 | ha->last_cp_used = i; | ||
| 1769 | break; | ||
| 1770 | } | ||
| 1771 | } | ||
| 1772 | |||
| 1773 | if (k == shost->can_queue) { | ||
| 1774 | printk("%s: qcomm, no free mailbox.\n", ha->board_name); | ||
| 1775 | return 1; | ||
| 1776 | } | ||
| 1777 | |||
| 1778 | /* Set pointer to control packet structure */ | ||
| 1779 | cpp = &ha->cp[i]; | ||
| 1780 | |||
| 1781 | memset(cpp, 0, sizeof(struct mscp) - CP_TAIL_SIZE); | ||
| 1782 | |||
| 1783 | /* Set pointer to status packet structure, Big Endian format */ | ||
| 1784 | cpp->sp_dma_addr = H2DEV(ha->sp_dma_addr); | ||
| 1785 | |||
| 1786 | SCpnt->scsi_done = done; | ||
| 1787 | cpp->cpp_index = i; | ||
| 1788 | SCpnt->host_scribble = (unsigned char *)&cpp->cpp_index; | ||
| 1789 | |||
| 1790 | if (do_trace) | ||
| 1791 | scmd_printk(KERN_INFO, SCpnt, | ||
| 1792 | "qcomm, mbox %d.\n", i); | ||
| 1793 | |||
| 1794 | cpp->reqsen = 1; | ||
| 1795 | cpp->dispri = 1; | ||
| 1796 | #if 0 | ||
| 1797 | if (SCpnt->device->type == TYPE_TAPE) | ||
| 1798 | cpp->hbaci = 1; | ||
| 1799 | #endif | ||
| 1800 | cpp->one = 1; | ||
| 1801 | cpp->channel = SCpnt->device->channel; | ||
| 1802 | cpp->target = SCpnt->device->id; | ||
| 1803 | cpp->lun = SCpnt->device->lun; | ||
| 1804 | cpp->SCpnt = SCpnt; | ||
| 1805 | memcpy(cpp->cdb, SCpnt->cmnd, SCpnt->cmd_len); | ||
| 1806 | |||
| 1807 | /* Use data transfer direction SCpnt->sc_data_direction */ | ||
| 1808 | scsi_to_dev_dir(i, ha); | ||
| 1809 | |||
| 1810 | /* Map DMA buffers and SG list */ | ||
| 1811 | map_dma(i, ha); | ||
| 1812 | |||
| 1813 | if (linked_comm && SCpnt->device->queue_depth > 2 | ||
| 1814 | && TLDEV(SCpnt->device->type)) { | ||
| 1815 | ha->cp_stat[i] = READY; | ||
| 1816 | flush_dev(SCpnt->device, blk_rq_pos(SCpnt->request), ha, 0); | ||
| 1817 | return 0; | ||
| 1818 | } | ||
| 1819 | |||
| 1820 | /* Send control packet to the board */ | ||
| 1821 | if (do_dma(shost->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) { | ||
| 1822 | unmap_dma(i, ha); | ||
| 1823 | SCpnt->host_scribble = NULL; | ||
| 1824 | scmd_printk(KERN_INFO, SCpnt, "qcomm, adapter busy.\n"); | ||
| 1825 | return 1; | ||
| 1826 | } | ||
| 1827 | |||
| 1828 | ha->cp_stat[i] = IN_USE; | ||
| 1829 | return 0; | ||
| 1830 | } | ||
| 1831 | |||
| 1832 | static DEF_SCSI_QCMD(eata2x_queuecommand) | ||
| 1833 | |||
| 1834 | static int eata2x_eh_abort(struct scsi_cmnd *SCarg) | ||
| 1835 | { | ||
| 1836 | struct Scsi_Host *shost = SCarg->device->host; | ||
| 1837 | struct hostdata *ha = (struct hostdata *)shost->hostdata; | ||
| 1838 | unsigned int i; | ||
| 1839 | |||
| 1840 | if (SCarg->host_scribble == NULL) { | ||
| 1841 | scmd_printk(KERN_INFO, SCarg, "abort, cmd inactive.\n"); | ||
| 1842 | return SUCCESS; | ||
| 1843 | } | ||
| 1844 | |||
| 1845 | i = *(unsigned int *)SCarg->host_scribble; | ||
| 1846 | scmd_printk(KERN_WARNING, SCarg, "abort, mbox %d.\n", i); | ||
| 1847 | |||
| 1848 | if (i >= shost->can_queue) | ||
| 1849 | panic("%s: abort, invalid SCarg->host_scribble.\n", ha->board_name); | ||
| 1850 | |||
| 1851 | if (wait_on_busy(shost->io_port, MAXLOOP)) { | ||
| 1852 | printk("%s: abort, timeout error.\n", ha->board_name); | ||
| 1853 | return FAILED; | ||
| 1854 | } | ||
| 1855 | |||
| 1856 | if (ha->cp_stat[i] == FREE) { | ||
| 1857 | printk("%s: abort, mbox %d is free.\n", ha->board_name, i); | ||
| 1858 | return SUCCESS; | ||
| 1859 | } | ||
| 1860 | |||
| 1861 | if (ha->cp_stat[i] == IN_USE) { | ||
| 1862 | printk("%s: abort, mbox %d is in use.\n", ha->board_name, i); | ||
| 1863 | |||
| 1864 | if (SCarg != ha->cp[i].SCpnt) | ||
| 1865 | panic("%s: abort, mbox %d, SCarg %p, cp SCpnt %p.\n", | ||
| 1866 | ha->board_name, i, SCarg, ha->cp[i].SCpnt); | ||
| 1867 | |||
| 1868 | if (inb(shost->io_port + REG_AUX_STATUS) & IRQ_ASSERTED) | ||
| 1869 | printk("%s: abort, mbox %d, interrupt pending.\n", | ||
| 1870 | ha->board_name, i); | ||
| 1871 | |||
| 1872 | return FAILED; | ||
| 1873 | } | ||
| 1874 | |||
| 1875 | if (ha->cp_stat[i] == IN_RESET) { | ||
| 1876 | printk("%s: abort, mbox %d is in reset.\n", ha->board_name, i); | ||
| 1877 | return FAILED; | ||
| 1878 | } | ||
| 1879 | |||
| 1880 | if (ha->cp_stat[i] == LOCKED) { | ||
| 1881 | printk("%s: abort, mbox %d is locked.\n", ha->board_name, i); | ||
| 1882 | return SUCCESS; | ||
| 1883 | } | ||
| 1884 | |||
| 1885 | if (ha->cp_stat[i] == READY || ha->cp_stat[i] == ABORTING) { | ||
| 1886 | unmap_dma(i, ha); | ||
| 1887 | SCarg->result = DID_ABORT << 16; | ||
| 1888 | SCarg->host_scribble = NULL; | ||
| 1889 | ha->cp_stat[i] = FREE; | ||
| 1890 | printk("%s, abort, mbox %d ready, DID_ABORT, done.\n", | ||
| 1891 | ha->board_name, i); | ||
| 1892 | SCarg->scsi_done(SCarg); | ||
| 1893 | return SUCCESS; | ||
| 1894 | } | ||
| 1895 | |||
| 1896 | panic("%s: abort, mbox %d, invalid cp_stat.\n", ha->board_name, i); | ||
| 1897 | } | ||
| 1898 | |||
| 1899 | static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) | ||
| 1900 | { | ||
| 1901 | unsigned int i, time, k, c, limit = 0; | ||
| 1902 | struct scsi_cmnd *SCpnt; | ||
| 1903 | struct Scsi_Host *shost = SCarg->device->host; | ||
| 1904 | struct hostdata *ha = (struct hostdata *)shost->hostdata; | ||
| 1905 | |||
| 1906 | scmd_printk(KERN_INFO, SCarg, "reset, enter.\n"); | ||
| 1907 | |||
| 1908 | spin_lock_irq(shost->host_lock); | ||
| 1909 | |||
| 1910 | if (SCarg->host_scribble == NULL) | ||
| 1911 | printk("%s: reset, inactive.\n", ha->board_name); | ||
| 1912 | |||
| 1913 | if (ha->in_reset) { | ||
| 1914 | printk("%s: reset, exit, already in reset.\n", ha->board_name); | ||
| 1915 | spin_unlock_irq(shost->host_lock); | ||
| 1916 | return FAILED; | ||
| 1917 | } | ||
| 1918 | |||
| 1919 | if (wait_on_busy(shost->io_port, MAXLOOP)) { | ||
| 1920 | printk("%s: reset, exit, timeout error.\n", ha->board_name); | ||
| 1921 | spin_unlock_irq(shost->host_lock); | ||
| 1922 | return FAILED; | ||
| 1923 | } | ||
| 1924 | |||
| 1925 | ha->retries = 0; | ||
| 1926 | |||
| 1927 | for (c = 0; c <= shost->max_channel; c++) | ||
| 1928 | for (k = 0; k < shost->max_id; k++) { | ||
| 1929 | ha->target_redo[k][c] = 1; | ||
| 1930 | ha->target_to[k][c] = 0; | ||
| 1931 | } | ||
| 1932 | |||
| 1933 | for (i = 0; i < shost->can_queue; i++) { | ||
| 1934 | |||
| 1935 | if (ha->cp_stat[i] == FREE) | ||
| 1936 | continue; | ||
| 1937 | |||
| 1938 | if (ha->cp_stat[i] == LOCKED) { | ||
| 1939 | ha->cp_stat[i] = FREE; | ||
| 1940 | printk("%s: reset, locked mbox %d forced free.\n", | ||
| 1941 | ha->board_name, i); | ||
| 1942 | continue; | ||
| 1943 | } | ||
| 1944 | |||
| 1945 | if (!(SCpnt = ha->cp[i].SCpnt)) | ||
| 1946 | panic("%s: reset, mbox %d, SCpnt == NULL.\n", ha->board_name, i); | ||
| 1947 | |||
| 1948 | if (ha->cp_stat[i] == READY || ha->cp_stat[i] == ABORTING) { | ||
| 1949 | ha->cp_stat[i] = ABORTING; | ||
| 1950 | printk("%s: reset, mbox %d aborting.\n", | ||
| 1951 | ha->board_name, i); | ||
| 1952 | } | ||
| 1953 | |||
| 1954 | else { | ||
| 1955 | ha->cp_stat[i] = IN_RESET; | ||
| 1956 | printk("%s: reset, mbox %d in reset.\n", | ||
| 1957 | ha->board_name, i); | ||
| 1958 | } | ||
| 1959 | |||
| 1960 | if (SCpnt->host_scribble == NULL) | ||
| 1961 | panic("%s: reset, mbox %d, garbled SCpnt.\n", ha->board_name, i); | ||
| 1962 | |||
| 1963 | if (*(unsigned int *)SCpnt->host_scribble != i) | ||
| 1964 | panic("%s: reset, mbox %d, index mismatch.\n", ha->board_name, i); | ||
| 1965 | |||
| 1966 | if (SCpnt->scsi_done == NULL) | ||
| 1967 | panic("%s: reset, mbox %d, SCpnt->scsi_done == NULL.\n", | ||
| 1968 | ha->board_name, i); | ||
| 1969 | } | ||
| 1970 | |||
| 1971 | if (do_dma(shost->io_port, 0, RESET_PIO)) { | ||
| 1972 | printk("%s: reset, cannot reset, timeout error.\n", ha->board_name); | ||
| 1973 | spin_unlock_irq(shost->host_lock); | ||
| 1974 | return FAILED; | ||
| 1975 | } | ||
| 1976 | |||
| 1977 | printk("%s: reset, board reset done, enabling interrupts.\n", ha->board_name); | ||
| 1978 | |||
| 1979 | #if defined(DEBUG_RESET) | ||
| 1980 | do_trace = 1; | ||
| 1981 | #endif | ||
| 1982 | |||
| 1983 | ha->in_reset = 1; | ||
| 1984 | |||
| 1985 | spin_unlock_irq(shost->host_lock); | ||
| 1986 | |||
| 1987 | /* FIXME: use a sleep instead */ | ||
| 1988 | time = jiffies; | ||
| 1989 | while ((jiffies - time) < (10 * HZ) && limit++ < 200000) | ||
| 1990 | udelay(100L); | ||
| 1991 | |||
| 1992 | spin_lock_irq(shost->host_lock); | ||
| 1993 | |||
| 1994 | printk("%s: reset, interrupts disabled, loops %d.\n", ha->board_name, limit); | ||
| 1995 | |||
| 1996 | for (i = 0; i < shost->can_queue; i++) { | ||
| 1997 | |||
| 1998 | if (ha->cp_stat[i] == IN_RESET) { | ||
| 1999 | SCpnt = ha->cp[i].SCpnt; | ||
| 2000 | unmap_dma(i, ha); | ||
| 2001 | SCpnt->result = DID_RESET << 16; | ||
| 2002 | SCpnt->host_scribble = NULL; | ||
| 2003 | |||
| 2004 | /* This mailbox is still waiting for its interrupt */ | ||
| 2005 | ha->cp_stat[i] = LOCKED; | ||
| 2006 | |||
| 2007 | printk | ||
| 2008 | ("%s, reset, mbox %d locked, DID_RESET, done.\n", | ||
| 2009 | ha->board_name, i); | ||
| 2010 | } | ||
| 2011 | |||
| 2012 | else if (ha->cp_stat[i] == ABORTING) { | ||
| 2013 | SCpnt = ha->cp[i].SCpnt; | ||
| 2014 | unmap_dma(i, ha); | ||
| 2015 | SCpnt->result = DID_RESET << 16; | ||
| 2016 | SCpnt->host_scribble = NULL; | ||
| 2017 | |||
| 2018 | /* This mailbox was never queued to the adapter */ | ||
| 2019 | ha->cp_stat[i] = FREE; | ||
| 2020 | |||
| 2021 | printk | ||
| 2022 | ("%s, reset, mbox %d aborting, DID_RESET, done.\n", | ||
| 2023 | ha->board_name, i); | ||
| 2024 | } | ||
| 2025 | |||
| 2026 | else | ||
| 2027 | /* Any other mailbox has already been set free by interrupt */ | ||
| 2028 | continue; | ||
| 2029 | |||
| 2030 | SCpnt->scsi_done(SCpnt); | ||
| 2031 | } | ||
| 2032 | |||
| 2033 | ha->in_reset = 0; | ||
| 2034 | do_trace = 0; | ||
| 2035 | |||
| 2036 | printk("%s: reset, exit.\n", ha->board_name); | ||
| 2037 | |||
| 2038 | spin_unlock_irq(shost->host_lock); | ||
| 2039 | return SUCCESS; | ||
| 2040 | } | ||
| 2041 | |||
| 2042 | int eata2x_bios_param(struct scsi_device *sdev, struct block_device *bdev, | ||
| 2043 | sector_t capacity, int *dkinfo) | ||
| 2044 | { | ||
| 2045 | unsigned int size = capacity; | ||
| 2046 | |||
| 2047 | if (ext_tran || (scsicam_bios_param(bdev, capacity, dkinfo) < 0)) { | ||
| 2048 | dkinfo[0] = 255; | ||
| 2049 | dkinfo[1] = 63; | ||
| 2050 | dkinfo[2] = size / (dkinfo[0] * dkinfo[1]); | ||
| 2051 | } | ||
| 2052 | #if defined (DEBUG_GEOMETRY) | ||
| 2053 | printk("%s: bios_param, head=%d, sec=%d, cyl=%d.\n", driver_name, | ||
| 2054 | dkinfo[0], dkinfo[1], dkinfo[2]); | ||
| 2055 | #endif | ||
| 2056 | |||
| 2057 | return 0; | ||
| 2058 | } | ||
| 2059 | |||
| 2060 | static void sort(unsigned long sk[], unsigned int da[], unsigned int n, | ||
| 2061 | unsigned int rev) | ||
| 2062 | { | ||
| 2063 | unsigned int i, j, k, y; | ||
| 2064 | unsigned long x; | ||
| 2065 | |||
| 2066 | for (i = 0; i < n - 1; i++) { | ||
| 2067 | k = i; | ||
| 2068 | |||
| 2069 | for (j = k + 1; j < n; j++) | ||
| 2070 | if (rev) { | ||
| 2071 | if (sk[j] > sk[k]) | ||
| 2072 | k = j; | ||
| 2073 | } else { | ||
| 2074 | if (sk[j] < sk[k]) | ||
| 2075 | k = j; | ||
| 2076 | } | ||
| 2077 | |||
| 2078 | if (k != i) { | ||
| 2079 | x = sk[k]; | ||
| 2080 | sk[k] = sk[i]; | ||
| 2081 | sk[i] = x; | ||
| 2082 | y = da[k]; | ||
| 2083 | da[k] = da[i]; | ||
| 2084 | da[i] = y; | ||
| 2085 | } | ||
| 2086 | } | ||
| 2087 | |||
| 2088 | return; | ||
| 2089 | } | ||
| 2090 | |||
| 2091 | static int reorder(struct hostdata *ha, unsigned long cursec, | ||
| 2092 | unsigned int ihdlr, unsigned int il[], unsigned int n_ready) | ||
| 2093 | { | ||
| 2094 | struct scsi_cmnd *SCpnt; | ||
| 2095 | struct mscp *cpp; | ||
| 2096 | unsigned int k, n; | ||
| 2097 | unsigned int rev = 0, s = 1, r = 1; | ||
| 2098 | unsigned int input_only = 1, overlap = 0; | ||
| 2099 | unsigned long sl[n_ready], pl[n_ready], ll[n_ready]; | ||
| 2100 | unsigned long maxsec = 0, minsec = ULONG_MAX, seek = 0, iseek = 0; | ||
| 2101 | unsigned long ioseek = 0; | ||
| 2102 | |||
| 2103 | static unsigned int flushcount = 0, batchcount = 0, sortcount = 0; | ||
| 2104 | static unsigned int readycount = 0, ovlcount = 0, inputcount = 0; | ||
| 2105 | static unsigned int readysorted = 0, revcount = 0; | ||
| 2106 | static unsigned long seeksorted = 0, seeknosort = 0; | ||
| 2107 | |||
| 2108 | if (link_statistics && !(++flushcount % link_statistics)) | ||
| 2109 | printk("fc %d bc %d ic %d oc %d rc %d rs %d sc %d re %d" | ||
| 2110 | " av %ldK as %ldK.\n", flushcount, batchcount, | ||
| 2111 | inputcount, ovlcount, readycount, readysorted, sortcount, | ||
| 2112 | revcount, seeknosort / (readycount + 1), | ||
| 2113 | seeksorted / (readycount + 1)); | ||
| 2114 | |||
| 2115 | if (n_ready <= 1) | ||
| 2116 | return 0; | ||
| 2117 | |||
| 2118 | for (n = 0; n < n_ready; n++) { | ||
| 2119 | k = il[n]; | ||
| 2120 | cpp = &ha->cp[k]; | ||
| 2121 | SCpnt = cpp->SCpnt; | ||
| 2122 | |||
| 2123 | if (!cpp->din) | ||
| 2124 | input_only = 0; | ||
| 2125 | |||
| 2126 | if (blk_rq_pos(SCpnt->request) < minsec) | ||
| 2127 | minsec = blk_rq_pos(SCpnt->request); | ||
| 2128 | if (blk_rq_pos(SCpnt->request) > maxsec) | ||
| 2129 | maxsec = blk_rq_pos(SCpnt->request); | ||
| 2130 | |||
| 2131 | sl[n] = blk_rq_pos(SCpnt->request); | ||
| 2132 | ioseek += blk_rq_sectors(SCpnt->request); | ||
| 2133 | |||
| 2134 | if (!n) | ||
| 2135 | continue; | ||
| 2136 | |||
| 2137 | if (sl[n] < sl[n - 1]) | ||
| 2138 | s = 0; | ||
| 2139 | if (sl[n] > sl[n - 1]) | ||
| 2140 | r = 0; | ||
| 2141 | |||
| 2142 | if (link_statistics) { | ||
| 2143 | if (sl[n] > sl[n - 1]) | ||
| 2144 | seek += sl[n] - sl[n - 1]; | ||
| 2145 | else | ||
| 2146 | seek += sl[n - 1] - sl[n]; | ||
| 2147 | } | ||
| 2148 | |||
| 2149 | } | ||
| 2150 | |||
| 2151 | if (link_statistics) { | ||
| 2152 | if (cursec > sl[0]) | ||
| 2153 | seek += cursec - sl[0]; | ||
| 2154 | else | ||
| 2155 | seek += sl[0] - cursec; | ||
| 2156 | } | ||
| 2157 | |||
| 2158 | if (cursec > ((maxsec + minsec) / 2)) | ||
| 2159 | rev = 1; | ||
| 2160 | |||
| 2161 | if (ioseek > ((maxsec - minsec) / 2)) | ||
| 2162 | rev = 0; | ||
| 2163 | |||
| 2164 | if (!((rev && r) || (!rev && s))) | ||
| 2165 | sort(sl, il, n_ready, rev); | ||
| 2166 | |||
| 2167 | if (!input_only) | ||
| 2168 | for (n = 0; n < n_ready; n++) { | ||
| 2169 | k = il[n]; | ||
| 2170 | cpp = &ha->cp[k]; | ||
| 2171 | SCpnt = cpp->SCpnt; | ||
| 2172 | ll[n] = blk_rq_sectors(SCpnt->request); | ||
| 2173 | pl[n] = SCpnt->serial_number; | ||
| 2174 | |||
| 2175 | if (!n) | ||
| 2176 | continue; | ||
| 2177 | |||
| 2178 | if ((sl[n] == sl[n - 1]) | ||
| 2179 | || (!rev && ((sl[n - 1] + ll[n - 1]) > sl[n])) | ||
| 2180 | || (rev && ((sl[n] + ll[n]) > sl[n - 1]))) | ||
| 2181 | overlap = 1; | ||
| 2182 | } | ||
| 2183 | |||
| 2184 | if (overlap) | ||
| 2185 | sort(pl, il, n_ready, 0); | ||
| 2186 | |||
| 2187 | if (link_statistics) { | ||
| 2188 | if (cursec > sl[0]) | ||
| 2189 | iseek = cursec - sl[0]; | ||
| 2190 | else | ||
| 2191 | iseek = sl[0] - cursec; | ||
| 2192 | batchcount++; | ||
| 2193 | readycount += n_ready; | ||
| 2194 | seeknosort += seek / 1024; | ||
| 2195 | if (input_only) | ||
| 2196 | inputcount++; | ||
| 2197 | if (overlap) { | ||
| 2198 | ovlcount++; | ||
| 2199 | seeksorted += iseek / 1024; | ||
| 2200 | } else | ||
| 2201 | seeksorted += (iseek + maxsec - minsec) / 1024; | ||
| 2202 | if (rev && !r) { | ||
| 2203 | revcount++; | ||
| 2204 | readysorted += n_ready; | ||
| 2205 | } | ||
| 2206 | if (!rev && !s) { | ||
| 2207 | sortcount++; | ||
| 2208 | readysorted += n_ready; | ||
| 2209 | } | ||
| 2210 | } | ||
| 2211 | #if defined(DEBUG_LINKED_COMMANDS) | ||
| 2212 | if (link_statistics && (overlap || !(flushcount % link_statistics))) | ||
| 2213 | for (n = 0; n < n_ready; n++) { | ||
| 2214 | k = il[n]; | ||
| 2215 | cpp = &ha->cp[k]; | ||
| 2216 | SCpnt = cpp->SCpnt; | ||
| 2217 | scmd_printk(KERN_INFO, SCpnt, | ||
| 2218 | "%s mb %d fc %d nr %d sec %ld ns %u" | ||
| 2219 | " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n", | ||
| 2220 | (ihdlr ? "ihdlr" : "qcomm"), | ||
| 2221 | k, flushcount, | ||
| 2222 | n_ready, blk_rq_pos(SCpnt->request), | ||
| 2223 | blk_rq_sectors(SCpnt->request), cursec, YESNO(s), | ||
| 2224 | YESNO(r), YESNO(rev), YESNO(input_only), | ||
| 2225 | YESNO(overlap), cpp->din); | ||
| 2226 | } | ||
| 2227 | #endif | ||
| 2228 | return overlap; | ||
| 2229 | } | ||
| 2230 | |||
| 2231 | static void flush_dev(struct scsi_device *dev, unsigned long cursec, | ||
| 2232 | struct hostdata *ha, unsigned int ihdlr) | ||
| 2233 | { | ||
| 2234 | struct scsi_cmnd *SCpnt; | ||
| 2235 | struct mscp *cpp; | ||
| 2236 | unsigned int k, n, n_ready = 0, il[MAX_MAILBOXES]; | ||
| 2237 | |||
| 2238 | for (k = 0; k < dev->host->can_queue; k++) { | ||
| 2239 | |||
| 2240 | if (ha->cp_stat[k] != READY && ha->cp_stat[k] != IN_USE) | ||
| 2241 | continue; | ||
| 2242 | |||
| 2243 | cpp = &ha->cp[k]; | ||
| 2244 | SCpnt = cpp->SCpnt; | ||
| 2245 | |||
| 2246 | if (SCpnt->device != dev) | ||
| 2247 | continue; | ||
| 2248 | |||
| 2249 | if (ha->cp_stat[k] == IN_USE) | ||
| 2250 | return; | ||
| 2251 | |||
| 2252 | il[n_ready++] = k; | ||
| 2253 | } | ||
| 2254 | |||
| 2255 | if (reorder(ha, cursec, ihdlr, il, n_ready)) | ||
| 2256 | n_ready = 1; | ||
| 2257 | |||
| 2258 | for (n = 0; n < n_ready; n++) { | ||
| 2259 | k = il[n]; | ||
| 2260 | cpp = &ha->cp[k]; | ||
| 2261 | SCpnt = cpp->SCpnt; | ||
| 2262 | |||
| 2263 | if (do_dma(dev->host->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) { | ||
| 2264 | scmd_printk(KERN_INFO, SCpnt, | ||
| 2265 | "%s, mbox %d, adapter" | ||
| 2266 | " busy, will abort.\n", | ||
| 2267 | (ihdlr ? "ihdlr" : "qcomm"), | ||
| 2268 | k); | ||
| 2269 | ha->cp_stat[k] = ABORTING; | ||
| 2270 | continue; | ||
| 2271 | } | ||
| 2272 | |||
| 2273 | ha->cp_stat[k] = IN_USE; | ||
| 2274 | } | ||
| 2275 | } | ||
| 2276 | |||
| 2277 | static irqreturn_t ihdlr(struct Scsi_Host *shost) | ||
| 2278 | { | ||
| 2279 | struct scsi_cmnd *SCpnt; | ||
| 2280 | unsigned int i, k, c, status, tstatus, reg; | ||
| 2281 | struct mssp *spp; | ||
| 2282 | struct mscp *cpp; | ||
| 2283 | struct hostdata *ha = (struct hostdata *)shost->hostdata; | ||
| 2284 | int irq = shost->irq; | ||
| 2285 | |||
| 2286 | /* Check if this board need to be serviced */ | ||
| 2287 | if (!(inb(shost->io_port + REG_AUX_STATUS) & IRQ_ASSERTED)) | ||
| 2288 | goto none; | ||
| 2289 | |||
| 2290 | ha->iocount++; | ||
| 2291 | |||
| 2292 | if (do_trace) | ||
| 2293 | printk("%s: ihdlr, enter, irq %d, count %d.\n", ha->board_name, irq, | ||
| 2294 | ha->iocount); | ||
| 2295 | |||
| 2296 | /* Check if this board is still busy */ | ||
| 2297 | if (wait_on_busy(shost->io_port, 20 * MAXLOOP)) { | ||
| 2298 | reg = inb(shost->io_port + REG_STATUS); | ||
| 2299 | printk | ||
| 2300 | ("%s: ihdlr, busy timeout error, irq %d, reg 0x%x, count %d.\n", | ||
| 2301 | ha->board_name, irq, reg, ha->iocount); | ||
| 2302 | goto none; | ||
| 2303 | } | ||
| 2304 | |||
| 2305 | spp = &ha->sp; | ||
| 2306 | |||
| 2307 | /* Make a local copy just before clearing the interrupt indication */ | ||
| 2308 | memcpy(spp, ha->sp_cpu_addr, sizeof(struct mssp)); | ||
| 2309 | |||
| 2310 | /* Clear the completion flag and cp pointer on the dynamic copy of sp */ | ||
| 2311 | memset(ha->sp_cpu_addr, 0, sizeof(struct mssp)); | ||
| 2312 | |||
| 2313 | /* Read the status register to clear the interrupt indication */ | ||
| 2314 | reg = inb(shost->io_port + REG_STATUS); | ||
| 2315 | |||
| 2316 | #if defined (DEBUG_INTERRUPT) | ||
| 2317 | { | ||
| 2318 | unsigned char *bytesp; | ||
| 2319 | int cnt; | ||
| 2320 | bytesp = (unsigned char *)spp; | ||
| 2321 | if (ha->iocount < 200) { | ||
| 2322 | printk("sp[] ="); | ||
| 2323 | for (cnt = 0; cnt < 15; cnt++) | ||
| 2324 | printk(" 0x%x", bytesp[cnt]); | ||
| 2325 | printk("\n"); | ||
| 2326 | } | ||
| 2327 | } | ||
| 2328 | #endif | ||
| 2329 | |||
| 2330 | /* Reject any sp with supspect data */ | ||
| 2331 | if (spp->eoc == 0 && ha->iocount > 1) | ||
| 2332 | printk | ||
| 2333 | ("%s: ihdlr, spp->eoc == 0, irq %d, reg 0x%x, count %d.\n", | ||
| 2334 | ha->board_name, irq, reg, ha->iocount); | ||
| 2335 | if (spp->cpp_index < 0 || spp->cpp_index >= shost->can_queue) | ||
| 2336 | printk | ||
| 2337 | ("%s: ihdlr, bad spp->cpp_index %d, irq %d, reg 0x%x, count %d.\n", | ||
| 2338 | ha->board_name, spp->cpp_index, irq, reg, ha->iocount); | ||
| 2339 | if (spp->eoc == 0 || spp->cpp_index < 0 | ||
| 2340 | || spp->cpp_index >= shost->can_queue) | ||
| 2341 | goto handled; | ||
| 2342 | |||
| 2343 | /* Find the mailbox to be serviced on this board */ | ||
| 2344 | i = spp->cpp_index; | ||
| 2345 | |||
| 2346 | cpp = &(ha->cp[i]); | ||
| 2347 | |||
| 2348 | #if defined(DEBUG_GENERATE_ABORTS) | ||
| 2349 | if ((ha->iocount > 500) && ((ha->iocount % 500) < 3)) | ||
| 2350 | goto handled; | ||
| 2351 | #endif | ||
| 2352 | |||
| 2353 | if (ha->cp_stat[i] == IGNORE) { | ||
| 2354 | ha->cp_stat[i] = FREE; | ||
| 2355 | goto handled; | ||
| 2356 | } else if (ha->cp_stat[i] == LOCKED) { | ||
| 2357 | ha->cp_stat[i] = FREE; | ||
| 2358 | printk("%s: ihdlr, mbox %d unlocked, count %d.\n", ha->board_name, i, | ||
| 2359 | ha->iocount); | ||
| 2360 | goto handled; | ||
| 2361 | } else if (ha->cp_stat[i] == FREE) { | ||
| 2362 | printk("%s: ihdlr, mbox %d is free, count %d.\n", ha->board_name, i, | ||
| 2363 | ha->iocount); | ||
| 2364 | goto handled; | ||
| 2365 | } else if (ha->cp_stat[i] == IN_RESET) | ||
| 2366 | printk("%s: ihdlr, mbox %d is in reset.\n", ha->board_name, i); | ||
| 2367 | else if (ha->cp_stat[i] != IN_USE) | ||
| 2368 | panic("%s: ihdlr, mbox %d, invalid cp_stat: %d.\n", | ||
| 2369 | ha->board_name, i, ha->cp_stat[i]); | ||
| 2370 | |||
| 2371 | ha->cp_stat[i] = FREE; | ||
| 2372 | SCpnt = cpp->SCpnt; | ||
| 2373 | |||
| 2374 | if (SCpnt == NULL) | ||
| 2375 | panic("%s: ihdlr, mbox %d, SCpnt == NULL.\n", ha->board_name, i); | ||
| 2376 | |||
| 2377 | if (SCpnt->host_scribble == NULL) | ||
| 2378 | panic("%s: ihdlr, mbox %d, SCpnt %p garbled.\n", ha->board_name, | ||
| 2379 | i, SCpnt); | ||
| 2380 | |||
| 2381 | if (*(unsigned int *)SCpnt->host_scribble != i) | ||
| 2382 | panic("%s: ihdlr, mbox %d, index mismatch %d.\n", | ||
| 2383 | ha->board_name, i, | ||
| 2384 | *(unsigned int *)SCpnt->host_scribble); | ||
| 2385 | |||
| 2386 | sync_dma(i, ha); | ||
| 2387 | |||
| 2388 | if (linked_comm && SCpnt->device->queue_depth > 2 | ||
| 2389 | && TLDEV(SCpnt->device->type)) | ||
| 2390 | flush_dev(SCpnt->device, blk_rq_pos(SCpnt->request), ha, 1); | ||
| 2391 | |||
| 2392 | tstatus = status_byte(spp->target_status); | ||
| 2393 | |||
| 2394 | #if defined(DEBUG_GENERATE_ERRORS) | ||
| 2395 | if ((ha->iocount > 500) && ((ha->iocount % 200) < 2)) | ||
| 2396 | spp->adapter_status = 0x01; | ||
| 2397 | #endif | ||
| 2398 | |||
| 2399 | switch (spp->adapter_status) { | ||
| 2400 | case ASOK: /* status OK */ | ||
| 2401 | |||
| 2402 | /* Forces a reset if a disk drive keeps returning BUSY */ | ||
| 2403 | if (tstatus == BUSY && SCpnt->device->type != TYPE_TAPE) | ||
| 2404 | status = DID_ERROR << 16; | ||
| 2405 | |||
| 2406 | /* If there was a bus reset, redo operation on each target */ | ||
| 2407 | else if (tstatus != GOOD && SCpnt->device->type == TYPE_DISK | ||
| 2408 | && ha->target_redo[SCpnt->device->id][SCpnt-> | ||
| 2409 | device-> | ||
| 2410 | channel]) | ||
| 2411 | status = DID_BUS_BUSY << 16; | ||
| 2412 | |||
| 2413 | /* Works around a flaw in scsi.c */ | ||
| 2414 | else if (tstatus == CHECK_CONDITION | ||
| 2415 | && SCpnt->device->type == TYPE_DISK | ||
| 2416 | && (SCpnt->sense_buffer[2] & 0xf) == RECOVERED_ERROR) | ||
| 2417 | status = DID_BUS_BUSY << 16; | ||
| 2418 | |||
| 2419 | else | ||
| 2420 | status = DID_OK << 16; | ||
| 2421 | |||
| 2422 | if (tstatus == GOOD) | ||
| 2423 | ha->target_redo[SCpnt->device->id][SCpnt->device-> | ||
| 2424 | channel] = 0; | ||
| 2425 | |||
| 2426 | if (spp->target_status && SCpnt->device->type == TYPE_DISK && | ||
| 2427 | (!(tstatus == CHECK_CONDITION && ha->iocount <= 1000 && | ||
| 2428 | (SCpnt->sense_buffer[2] & 0xf) == NOT_READY))) | ||
| 2429 | printk("%s: ihdlr, target %d.%d:%d, " | ||
| 2430 | "target_status 0x%x, sense key 0x%x.\n", | ||
| 2431 | ha->board_name, | ||
| 2432 | SCpnt->device->channel, SCpnt->device->id, | ||
| 2433 | (u8)SCpnt->device->lun, | ||
| 2434 | spp->target_status, SCpnt->sense_buffer[2]); | ||
| 2435 | |||
| 2436 | ha->target_to[SCpnt->device->id][SCpnt->device->channel] = 0; | ||
| 2437 | |||
| 2438 | if (ha->last_retried_pid == SCpnt->serial_number) | ||
| 2439 | ha->retries = 0; | ||
| 2440 | |||
| 2441 | break; | ||
| 2442 | case ASST: /* Selection Time Out */ | ||
| 2443 | case 0x02: /* Command Time Out */ | ||
| 2444 | |||
| 2445 | if (ha->target_to[SCpnt->device->id][SCpnt->device->channel] > 1) | ||
| 2446 | status = DID_ERROR << 16; | ||
| 2447 | else { | ||
| 2448 | status = DID_TIME_OUT << 16; | ||
| 2449 | ha->target_to[SCpnt->device->id][SCpnt->device-> | ||
| 2450 | channel]++; | ||
| 2451 | } | ||
| 2452 | |||
| 2453 | break; | ||
| 2454 | |||
| 2455 | /* Perform a limited number of internal retries */ | ||
| 2456 | case 0x03: /* SCSI Bus Reset Received */ | ||
| 2457 | case 0x04: /* Initial Controller Power-up */ | ||
| 2458 | |||
| 2459 | for (c = 0; c <= shost->max_channel; c++) | ||
| 2460 | for (k = 0; k < shost->max_id; k++) | ||
| 2461 | ha->target_redo[k][c] = 1; | ||
| 2462 | |||
| 2463 | if (SCpnt->device->type != TYPE_TAPE | ||
| 2464 | && ha->retries < MAX_INTERNAL_RETRIES) { | ||
| 2465 | |||
| 2466 | #if defined(DID_SOFT_ERROR) | ||
| 2467 | status = DID_SOFT_ERROR << 16; | ||
| 2468 | #else | ||
| 2469 | status = DID_BUS_BUSY << 16; | ||
| 2470 | #endif | ||
| 2471 | |||
| 2472 | ha->retries++; | ||
| 2473 | ha->last_retried_pid = SCpnt->serial_number; | ||
| 2474 | } else | ||
| 2475 | status = DID_ERROR << 16; | ||
| 2476 | |||
| 2477 | break; | ||
| 2478 | case 0x05: /* Unexpected Bus Phase */ | ||
| 2479 | case 0x06: /* Unexpected Bus Free */ | ||
| 2480 | case 0x07: /* Bus Parity Error */ | ||
| 2481 | case 0x08: /* SCSI Hung */ | ||
| 2482 | case 0x09: /* Unexpected Message Reject */ | ||
| 2483 | case 0x0a: /* SCSI Bus Reset Stuck */ | ||
| 2484 | case 0x0b: /* Auto Request-Sense Failed */ | ||
| 2485 | case 0x0c: /* Controller Ram Parity Error */ | ||
| 2486 | default: | ||
| 2487 | status = DID_ERROR << 16; | ||
| 2488 | break; | ||
| 2489 | } | ||
| 2490 | |||
| 2491 | SCpnt->result = status | spp->target_status; | ||
| 2492 | |||
| 2493 | #if defined(DEBUG_INTERRUPT) | ||
| 2494 | if (SCpnt->result || do_trace) | ||
| 2495 | #else | ||
| 2496 | if ((spp->adapter_status != ASOK && ha->iocount > 1000) || | ||
| 2497 | (spp->adapter_status != ASOK && | ||
| 2498 | spp->adapter_status != ASST && ha->iocount <= 1000) || | ||
| 2499 | do_trace || msg_byte(spp->target_status)) | ||
| 2500 | #endif | ||
| 2501 | scmd_printk(KERN_INFO, SCpnt, "ihdlr, mbox %2d, err 0x%x:%x," | ||
| 2502 | " reg 0x%x, count %d.\n", | ||
| 2503 | i, spp->adapter_status, spp->target_status, | ||
| 2504 | reg, ha->iocount); | ||
| 2505 | |||
| 2506 | unmap_dma(i, ha); | ||
| 2507 | |||
| 2508 | /* Set the command state to inactive */ | ||
| 2509 | SCpnt->host_scribble = NULL; | ||
| 2510 | |||
| 2511 | SCpnt->scsi_done(SCpnt); | ||
| 2512 | |||
| 2513 | if (do_trace) | ||
| 2514 | printk("%s: ihdlr, exit, irq %d, count %d.\n", ha->board_name, | ||
| 2515 | irq, ha->iocount); | ||
| 2516 | |||
| 2517 | handled: | ||
| 2518 | return IRQ_HANDLED; | ||
| 2519 | none: | ||
| 2520 | return IRQ_NONE; | ||
| 2521 | } | ||
| 2522 | |||
| 2523 | static irqreturn_t do_interrupt_handler(int dummy, void *shap) | ||
| 2524 | { | ||
| 2525 | struct Scsi_Host *shost; | ||
| 2526 | unsigned int j; | ||
| 2527 | unsigned long spin_flags; | ||
| 2528 | irqreturn_t ret; | ||
| 2529 | |||
| 2530 | /* Check if the interrupt must be processed by this handler */ | ||
| 2531 | if ((j = (unsigned int)((char *)shap - sha)) >= num_boards) | ||
| 2532 | return IRQ_NONE; | ||
| 2533 | shost = sh[j]; | ||
| 2534 | |||
| 2535 | spin_lock_irqsave(shost->host_lock, spin_flags); | ||
| 2536 | ret = ihdlr(shost); | ||
| 2537 | spin_unlock_irqrestore(shost->host_lock, spin_flags); | ||
| 2538 | return ret; | ||
| 2539 | } | ||
| 2540 | |||
| 2541 | static int eata2x_release(struct Scsi_Host *shost) | ||
| 2542 | { | ||
| 2543 | struct hostdata *ha = (struct hostdata *)shost->hostdata; | ||
| 2544 | unsigned int i; | ||
| 2545 | |||
| 2546 | for (i = 0; i < shost->can_queue; i++) | ||
| 2547 | kfree((&ha->cp[i])->sglist); | ||
| 2548 | |||
| 2549 | for (i = 0; i < shost->can_queue; i++) | ||
| 2550 | pci_unmap_single(ha->pdev, ha->cp[i].cp_dma_addr, | ||
| 2551 | sizeof(struct mscp), PCI_DMA_BIDIRECTIONAL); | ||
| 2552 | |||
| 2553 | if (ha->sp_cpu_addr) | ||
| 2554 | pci_free_consistent(ha->pdev, sizeof(struct mssp), | ||
| 2555 | ha->sp_cpu_addr, ha->sp_dma_addr); | ||
| 2556 | |||
| 2557 | free_irq(shost->irq, &sha[ha->board_number]); | ||
| 2558 | |||
| 2559 | if (shost->dma_channel != NO_DMA) | ||
| 2560 | free_dma(shost->dma_channel); | ||
| 2561 | |||
| 2562 | release_region(shost->io_port, shost->n_io_port); | ||
| 2563 | scsi_unregister(shost); | ||
| 2564 | return 0; | ||
| 2565 | } | ||
| 2566 | |||
| 2567 | #include "scsi_module.c" | ||
| 2568 | |||
| 2569 | #ifndef MODULE | ||
| 2570 | __setup("eata=", option_setup); | ||
| 2571 | #endif /* end MODULE */ | ||
diff --git a/drivers/scsi/eata_generic.h b/drivers/scsi/eata_generic.h deleted file mode 100644 index 1a396c5e7f73..000000000000 --- a/drivers/scsi/eata_generic.h +++ /dev/null | |||
| @@ -1,401 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | /******************************************************** | ||
| 3 | * Header file for eata_dma.c and eata_pio.c * | ||
| 4 | * Linux EATA SCSI drivers * | ||
| 5 | * (c) 1993-96 Michael Neuffer * | ||
| 6 | * mike@i-Connect.Net * | ||
| 7 | * neuffer@mail.uni-mainz.de * | ||
| 8 | ********************************************************* | ||
| 9 | * last change: 96/08/14 * | ||
| 10 | ********************************************************/ | ||
| 11 | |||
| 12 | |||
| 13 | #ifndef _EATA_GENERIC_H | ||
| 14 | #define _EATA_GENERIC_H | ||
| 15 | |||
| 16 | |||
| 17 | |||
| 18 | /********************************************* | ||
| 19 | * Misc. definitions * | ||
| 20 | *********************************************/ | ||
| 21 | |||
| 22 | #define R_LIMIT 0x20000 | ||
| 23 | |||
| 24 | #define MAXISA 4 | ||
| 25 | #define MAXEISA 16 | ||
| 26 | #define MAXPCI 16 | ||
| 27 | #define MAXIRQ 16 | ||
| 28 | #define MAXTARGET 16 | ||
| 29 | #define MAXCHANNEL 3 | ||
| 30 | |||
| 31 | #define IS_ISA 'I' | ||
| 32 | #define IS_EISA 'E' | ||
| 33 | #define IS_PCI 'P' | ||
| 34 | |||
| 35 | #define BROKEN_INQUIRY 1 | ||
| 36 | |||
| 37 | #define BUSMASTER 0xff | ||
| 38 | #define PIO 0xfe | ||
| 39 | |||
| 40 | #define EATA_SIGNATURE 0x45415441 /* BIG ENDIAN coded "EATA" sig. */ | ||
| 41 | |||
| 42 | #define DPT_ID1 0x12 | ||
| 43 | #define DPT_ID2 0x14 | ||
| 44 | |||
| 45 | #define ATT_ID1 0x06 | ||
| 46 | #define ATT_ID2 0x94 | ||
| 47 | #define ATT_ID3 0x0 | ||
| 48 | |||
| 49 | #define NEC_ID1 0x38 | ||
| 50 | #define NEC_ID2 0xa3 | ||
| 51 | #define NEC_ID3 0x82 | ||
| 52 | |||
| 53 | |||
| 54 | #define EATA_CP_SIZE 44 | ||
| 55 | |||
| 56 | #define MAX_PCI_DEVICES 32 /* Maximum # Of Devices Per Bus */ | ||
| 57 | #define MAX_METHOD_2 16 /* Max Devices For Method 2 */ | ||
| 58 | #define MAX_PCI_BUS 16 /* Maximum # Of Busses Allowed */ | ||
| 59 | |||
| 60 | #define SG_SIZE 64 | ||
| 61 | #define SG_SIZE_BIG 252 /* max. 8096 elements, 64k */ | ||
| 62 | |||
| 63 | #define UPPER_DEVICE_QUEUE_LIMIT 64 /* The limit we have to set for the | ||
| 64 | * device queue to keep the broken | ||
| 65 | * midlevel SCSI code from producing | ||
| 66 | * bogus timeouts | ||
| 67 | */ | ||
| 68 | |||
| 69 | #define TYPE_DISK_QUEUE 16 | ||
| 70 | #define TYPE_TAPE_QUEUE 4 | ||
| 71 | #define TYPE_ROM_QUEUE 4 | ||
| 72 | #define TYPE_OTHER_QUEUE 2 | ||
| 73 | |||
| 74 | #define FREE 0 | ||
| 75 | #define OK 0 | ||
| 76 | #define NO_TIMEOUT 0 | ||
| 77 | #define USED 1 | ||
| 78 | #define TIMEOUT 2 | ||
| 79 | #define RESET 4 | ||
| 80 | #define LOCKED 8 | ||
| 81 | #define ABORTED 16 | ||
| 82 | |||
| 83 | #define READ 0 | ||
| 84 | #define WRITE 1 | ||
| 85 | #define OTHER 2 | ||
| 86 | |||
| 87 | #define HD(cmd) ((hostdata *)&(cmd->device->host->hostdata)) | ||
| 88 | #define CD(cmd) ((struct eata_ccb *)(cmd->host_scribble)) | ||
| 89 | #define SD(host) ((hostdata *)&(host->hostdata)) | ||
| 90 | |||
| 91 | /*********************************************** | ||
| 92 | * EATA Command & Register definitions * | ||
| 93 | ***********************************************/ | ||
| 94 | #define PCI_REG_DPTconfig 0x40 | ||
| 95 | #define PCI_REG_PumpModeAddress 0x44 | ||
| 96 | #define PCI_REG_PumpModeData 0x48 | ||
| 97 | #define PCI_REG_ConfigParam1 0x50 | ||
| 98 | #define PCI_REG_ConfigParam2 0x54 | ||
| 99 | |||
| 100 | |||
| 101 | #define EATA_CMD_PIO_SETUPTEST 0xc6 | ||
| 102 | #define EATA_CMD_PIO_READ_CONFIG 0xf0 | ||
| 103 | #define EATA_CMD_PIO_SET_CONFIG 0xf1 | ||
| 104 | #define EATA_CMD_PIO_SEND_CP 0xf2 | ||
| 105 | #define EATA_CMD_PIO_RECEIVE_SP 0xf3 | ||
| 106 | #define EATA_CMD_PIO_TRUNC 0xf4 | ||
| 107 | |||
| 108 | #define EATA_CMD_RESET 0xf9 | ||
| 109 | #define EATA_CMD_IMMEDIATE 0xfa | ||
| 110 | |||
| 111 | #define EATA_CMD_DMA_READ_CONFIG 0xfd | ||
| 112 | #define EATA_CMD_DMA_SET_CONFIG 0xfe | ||
| 113 | #define EATA_CMD_DMA_SEND_CP 0xff | ||
| 114 | |||
| 115 | #define ECS_EMULATE_SENSE 0xd4 | ||
| 116 | |||
| 117 | #define EATA_GENERIC_ABORT 0x00 | ||
| 118 | #define EATA_SPECIFIC_RESET 0x01 | ||
| 119 | #define EATA_BUS_RESET 0x02 | ||
| 120 | #define EATA_SPECIFIC_ABORT 0x03 | ||
| 121 | #define EATA_QUIET_INTR 0x04 | ||
| 122 | #define EATA_COLD_BOOT_HBA 0x06 /* Only as a last resort */ | ||
| 123 | #define EATA_FORCE_IO 0x07 | ||
| 124 | |||
| 125 | #define HA_CTRLREG 0x206 /* control register for HBA */ | ||
| 126 | #define HA_CTRL_DISINT 0x02 /* CTRLREG: disable interrupts */ | ||
| 127 | #define HA_CTRL_RESCPU 0x04 /* CTRLREG: reset processor */ | ||
| 128 | #define HA_CTRL_8HEADS 0x08 /* CTRLREG: set for drives with* | ||
| 129 | * >=8 heads (WD1003 rudimentary :-) */ | ||
| 130 | |||
| 131 | #define HA_WCOMMAND 0x07 /* command register offset */ | ||
| 132 | #define HA_WIFC 0x06 /* immediate command offset */ | ||
| 133 | #define HA_WCODE 0x05 | ||
| 134 | #define HA_WCODE2 0x04 | ||
| 135 | #define HA_WDMAADDR 0x02 /* DMA address LSB offset */ | ||
| 136 | #define HA_RAUXSTAT 0x08 /* aux status register offset*/ | ||
| 137 | #define HA_RSTATUS 0x07 /* status register offset */ | ||
| 138 | #define HA_RDATA 0x00 /* data register (16bit) */ | ||
| 139 | #define HA_WDATA 0x00 /* data register (16bit) */ | ||
| 140 | |||
| 141 | #define HA_ABUSY 0x01 /* aux busy bit */ | ||
| 142 | #define HA_AIRQ 0x02 /* aux IRQ pending bit */ | ||
| 143 | #define HA_SERROR 0x01 /* pr. command ended in error*/ | ||
| 144 | #define HA_SMORE 0x02 /* more data soon to come */ | ||
| 145 | #define HA_SCORR 0x04 /* data corrected */ | ||
| 146 | #define HA_SDRQ 0x08 /* data request active */ | ||
| 147 | #define HA_SSC 0x10 /* seek complete */ | ||
| 148 | #define HA_SFAULT 0x20 /* write fault */ | ||
| 149 | #define HA_SREADY 0x40 /* drive ready */ | ||
| 150 | #define HA_SBUSY 0x80 /* drive busy */ | ||
| 151 | #define HA_SDRDY HA_SSC+HA_SREADY+HA_SDRQ | ||
| 152 | |||
| 153 | /********************************************** | ||
| 154 | * Message definitions * | ||
| 155 | **********************************************/ | ||
| 156 | |||
| 157 | #define HA_NO_ERROR 0x00 /* No Error */ | ||
| 158 | #define HA_ERR_SEL_TO 0x01 /* Selection Timeout */ | ||
| 159 | #define HA_ERR_CMD_TO 0x02 /* Command Timeout */ | ||
| 160 | #define HA_BUS_RESET 0x03 /* SCSI Bus Reset Received */ | ||
| 161 | #define HA_INIT_POWERUP 0x04 /* Initial Controller Power-up */ | ||
| 162 | #define HA_UNX_BUSPHASE 0x05 /* Unexpected Bus Phase */ | ||
| 163 | #define HA_UNX_BUS_FREE 0x06 /* Unexpected Bus Free */ | ||
| 164 | #define HA_BUS_PARITY 0x07 /* Bus Parity Error */ | ||
| 165 | #define HA_SCSI_HUNG 0x08 /* SCSI Hung */ | ||
| 166 | #define HA_UNX_MSGRJCT 0x09 /* Unexpected Message Rejected */ | ||
| 167 | #define HA_RESET_STUCK 0x0a /* SCSI Bus Reset Stuck */ | ||
| 168 | #define HA_RSENSE_FAIL 0x0b /* Auto Request-Sense Failed */ | ||
| 169 | #define HA_PARITY_ERR 0x0c /* Controller Ram Parity Error */ | ||
| 170 | #define HA_CP_ABORT_NA 0x0d /* Abort Message sent to non-active cmd */ | ||
| 171 | #define HA_CP_ABORTED 0x0e /* Abort Message sent to active cmd */ | ||
| 172 | #define HA_CP_RESET_NA 0x0f /* Reset Message sent to non-active cmd */ | ||
| 173 | #define HA_CP_RESET 0x10 /* Reset Message sent to active cmd */ | ||
| 174 | #define HA_ECC_ERR 0x11 /* Controller Ram ECC Error */ | ||
| 175 | #define HA_PCI_PARITY 0x12 /* PCI Parity Error */ | ||
| 176 | #define HA_PCI_MABORT 0x13 /* PCI Master Abort */ | ||
| 177 | #define HA_PCI_TABORT 0x14 /* PCI Target Abort */ | ||
| 178 | #define HA_PCI_STABORT 0x15 /* PCI Signaled Target Abort */ | ||
| 179 | |||
| 180 | /********************************************** | ||
| 181 | * Other definitions * | ||
| 182 | **********************************************/ | ||
| 183 | |||
| 184 | struct reg_bit { /* reading this one will clear the interrupt */ | ||
| 185 | __u8 error:1; /* previous command ended in an error */ | ||
| 186 | __u8 more:1; /* more DATA coming soon, poll BSY & DRQ (PIO) */ | ||
| 187 | __u8 corr:1; /* data read was successfully corrected with ECC*/ | ||
| 188 | __u8 drq:1; /* data request active */ | ||
| 189 | __u8 sc:1; /* seek complete */ | ||
| 190 | __u8 fault:1; /* write fault */ | ||
| 191 | __u8 ready:1; /* drive ready */ | ||
| 192 | __u8 busy:1; /* controller busy */ | ||
| 193 | }; | ||
| 194 | |||
| 195 | struct reg_abit { /* reading this won't clear the interrupt */ | ||
| 196 | __u8 abusy:1; /* auxiliary busy */ | ||
| 197 | __u8 irq:1; /* set when drive interrupt is asserted */ | ||
| 198 | __u8 dummy:6; | ||
| 199 | }; | ||
| 200 | |||
| 201 | struct eata_register { /* EATA register set */ | ||
| 202 | __u8 data_reg[2]; /* R, couldn't figure this one out */ | ||
| 203 | __u8 cp_addr[4]; /* W, CP address register */ | ||
| 204 | union { | ||
| 205 | __u8 command; /* W, command code: [read|set] conf, send CP*/ | ||
| 206 | struct reg_bit status; /* R, see register_bit1 */ | ||
| 207 | __u8 statusbyte; | ||
| 208 | } ovr; | ||
| 209 | struct reg_abit aux_stat; /* R, see register_bit2 */ | ||
| 210 | }; | ||
| 211 | |||
| 212 | struct get_conf { /* Read Configuration Array */ | ||
| 213 | __u32 len; /* Should return 0x22, 0x24, etc */ | ||
| 214 | __u32 signature; /* Signature MUST be "EATA" */ | ||
| 215 | __u8 version2:4, | ||
| 216 | version:4; /* EATA Version level */ | ||
| 217 | __u8 OCS_enabled:1, /* Overlap Command Support enabled */ | ||
| 218 | TAR_support:1, /* SCSI Target Mode supported */ | ||
| 219 | TRNXFR:1, /* Truncate Transfer Cmd not necessary * | ||
| 220 | * Only used in PIO Mode */ | ||
| 221 | MORE_support:1, /* MORE supported (only PIO Mode) */ | ||
| 222 | DMA_support:1, /* DMA supported Driver uses only * | ||
| 223 | * this mode */ | ||
| 224 | DMA_valid:1, /* DRQ value in Byte 30 is valid */ | ||
| 225 | ATA:1, /* ATA device connected (not supported) */ | ||
| 226 | HAA_valid:1; /* Hostadapter Address is valid */ | ||
| 227 | |||
| 228 | __u16 cppadlen; /* Number of pad bytes send after CD data * | ||
| 229 | * set to zero for DMA commands */ | ||
| 230 | __u8 scsi_id[4]; /* SCSI ID of controller 2-0 Byte 0 res. * | ||
| 231 | * if not, zero is returned */ | ||
| 232 | __u32 cplen; /* CP length: number of valid cp bytes */ | ||
| 233 | __u32 splen; /* Number of bytes returned after * | ||
| 234 | * Receive SP command */ | ||
| 235 | __u16 queuesiz; /* max number of queueable CPs */ | ||
| 236 | __u16 dummy; | ||
| 237 | __u16 SGsiz; /* max number of SG table entries */ | ||
| 238 | __u8 IRQ:4, /* IRQ used this HA */ | ||
| 239 | IRQ_TR:1, /* IRQ Trigger: 0=edge, 1=level */ | ||
| 240 | SECOND:1, /* This is a secondary controller */ | ||
| 241 | DMA_channel:2; /* DRQ index, DRQ is 2comp of DRQX */ | ||
| 242 | __u8 sync; /* device at ID 7 tru 0 is running in * | ||
| 243 | * synchronous mode, this will disappear */ | ||
| 244 | __u8 DSBLE:1, /* ISA i/o addressing is disabled */ | ||
| 245 | FORCADR:1, /* i/o address has been forced */ | ||
| 246 | SG_64K:1, | ||
| 247 | SG_UAE:1, | ||
| 248 | :4; | ||
| 249 | __u8 MAX_ID:5, /* Max number of SCSI target IDs */ | ||
| 250 | MAX_CHAN:3; /* Number of SCSI busses on HBA */ | ||
| 251 | __u8 MAX_LUN; /* Max number of LUNs */ | ||
| 252 | __u8 :3, | ||
| 253 | AUTOTRM:1, | ||
| 254 | M1_inst:1, | ||
| 255 | ID_qest:1, /* Raidnum ID is questionable */ | ||
| 256 | is_PCI:1, /* HBA is PCI */ | ||
| 257 | is_EISA:1; /* HBA is EISA */ | ||
| 258 | __u8 RAIDNUM; /* unique HBA identifier */ | ||
| 259 | __u8 unused[474]; | ||
| 260 | }; | ||
| 261 | |||
| 262 | struct eata_sg_list | ||
| 263 | { | ||
| 264 | __u32 data; | ||
| 265 | __u32 len; | ||
| 266 | }; | ||
| 267 | |||
| 268 | struct eata_ccb { /* Send Command Packet structure */ | ||
| 269 | |||
| 270 | __u8 SCSI_Reset:1, /* Cause a SCSI Bus reset on the cmd */ | ||
| 271 | HBA_Init:1, /* Cause Controller to reinitialize */ | ||
| 272 | Auto_Req_Sen:1, /* Do Auto Request Sense on errors */ | ||
| 273 | scatter:1, /* Data Ptr points to a SG Packet */ | ||
| 274 | Resrvd:1, /* RFU */ | ||
| 275 | Interpret:1, /* Interpret the SCSI cdb of own use */ | ||
| 276 | DataOut:1, /* Data Out phase with command */ | ||
| 277 | DataIn:1; /* Data In phase with command */ | ||
| 278 | __u8 reqlen; /* Request Sense Length * | ||
| 279 | * Valid if Auto_Req_Sen=1 */ | ||
| 280 | __u8 unused[3]; | ||
| 281 | __u8 FWNEST:1, /* send cmd to phys RAID component */ | ||
| 282 | unused2:7; | ||
| 283 | __u8 Phsunit:1, /* physical unit on mirrored pair */ | ||
| 284 | I_AT:1, /* inhibit address translation */ | ||
| 285 | I_HBA_C:1, /* HBA inhibit caching */ | ||
| 286 | unused3:5; | ||
| 287 | |||
| 288 | __u8 cp_id:5, /* SCSI Device ID of target */ | ||
| 289 | cp_channel:3; /* SCSI Channel # of HBA */ | ||
| 290 | __u8 cp_lun:3, | ||
| 291 | :2, | ||
| 292 | cp_luntar:1, /* CP is for target ROUTINE */ | ||
| 293 | cp_dispri:1, /* Grant disconnect privilege */ | ||
| 294 | cp_identify:1; /* Always TRUE */ | ||
| 295 | __u8 cp_msg1; /* Message bytes 0-3 */ | ||
| 296 | __u8 cp_msg2; | ||
| 297 | __u8 cp_msg3; | ||
| 298 | __u8 cp_cdb[12]; /* Command Descriptor Block */ | ||
| 299 | __u32 cp_datalen; /* Data Transfer Length * | ||
| 300 | * If scatter=1 len of sg package */ | ||
| 301 | void *cp_viraddr; /* address of this ccb */ | ||
| 302 | __u32 cp_dataDMA; /* Data Address, if scatter=1 * | ||
| 303 | * address of scatter packet */ | ||
| 304 | __u32 cp_statDMA; /* address for Status Packet */ | ||
| 305 | __u32 cp_reqDMA; /* Request Sense Address, used if * | ||
| 306 | * CP command ends with error */ | ||
| 307 | /* Additional CP info begins here */ | ||
| 308 | __u32 timestamp; /* Needed to measure command latency */ | ||
| 309 | __u32 timeout; | ||
| 310 | __u8 sizeindex; | ||
| 311 | __u8 rw_latency; | ||
| 312 | __u8 retries; | ||
| 313 | __u8 status; /* status of this queueslot */ | ||
| 314 | struct scsi_cmnd *cmd; /* address of cmd */ | ||
| 315 | struct eata_sg_list *sg_list; | ||
| 316 | }; | ||
| 317 | |||
| 318 | |||
| 319 | struct eata_sp { | ||
| 320 | __u8 hba_stat:7, /* HBA status */ | ||
| 321 | EOC:1; /* True if command finished */ | ||
| 322 | __u8 scsi_stat; /* Target SCSI status */ | ||
| 323 | __u8 reserved[2]; | ||
| 324 | __u32 residue_len; /* Number of bytes not transferred */ | ||
| 325 | struct eata_ccb *ccb; /* Address set in COMMAND PACKET */ | ||
| 326 | __u8 msg[12]; | ||
| 327 | }; | ||
| 328 | |||
| 329 | typedef struct hstd { | ||
| 330 | __u8 vendor[9]; | ||
| 331 | __u8 name[18]; | ||
| 332 | __u8 revision[6]; | ||
| 333 | __u8 EATA_revision; | ||
| 334 | __u32 firmware_revision; | ||
| 335 | __u8 HBA_number; | ||
| 336 | __u8 bustype; /* bustype of HBA */ | ||
| 337 | __u8 channel; /* # of avail. scsi channels */ | ||
| 338 | __u8 state; /* state of HBA */ | ||
| 339 | __u8 primary; /* true if primary */ | ||
| 340 | __u8 more_support:1, /* HBA supports MORE flag */ | ||
| 341 | immediate_support:1, /* HBA supports IMMEDIATE CMDs*/ | ||
| 342 | broken_INQUIRY:1; /* This is an EISA HBA with * | ||
| 343 | * broken INQUIRY */ | ||
| 344 | __u8 do_latency; /* Latency measurement flag */ | ||
| 345 | __u32 reads[13]; | ||
| 346 | __u32 writes[13]; | ||
| 347 | __u32 reads_lat[12][4]; | ||
| 348 | __u32 writes_lat[12][4]; | ||
| 349 | __u32 all_lat[4]; | ||
| 350 | __u8 resetlevel[MAXCHANNEL]; | ||
| 351 | __u32 last_ccb; /* Last used ccb */ | ||
| 352 | __u32 cplen; /* size of CP in words */ | ||
| 353 | __u16 cppadlen; /* pad length of cp in words */ | ||
| 354 | __u16 queuesize; | ||
| 355 | __u16 sgsize; /* # of entries in the SG list*/ | ||
| 356 | __u16 devflags; /* bits set for detected devices */ | ||
| 357 | __u8 hostid; /* SCSI ID of HBA */ | ||
| 358 | __u8 moresupport; /* HBA supports MORE flag */ | ||
| 359 | struct Scsi_Host *next; | ||
| 360 | struct Scsi_Host *prev; | ||
| 361 | struct pci_dev *pdev; /* PCI device or NULL for non PCI */ | ||
| 362 | struct eata_sp sp; /* status packet */ | ||
| 363 | struct eata_ccb ccb[0]; /* ccb array begins here */ | ||
| 364 | }hostdata; | ||
| 365 | |||
| 366 | /* structure for max. 2 emulated drives */ | ||
| 367 | struct drive_geom_emul { | ||
| 368 | __u8 trans; /* translation flag 1=transl */ | ||
| 369 | __u8 channel; /* SCSI channel number */ | ||
| 370 | __u8 HBA; /* HBA number (prim/sec) */ | ||
| 371 | __u8 id; /* drive id */ | ||
| 372 | __u8 lun; /* drive lun */ | ||
| 373 | __u32 heads; /* number of heads */ | ||
| 374 | __u32 sectors; /* number of sectors */ | ||
| 375 | __u32 cylinder; /* number of cylinders */ | ||
| 376 | }; | ||
| 377 | |||
| 378 | struct geom_emul { | ||
| 379 | __u8 bios_drives; /* number of emulated drives */ | ||
| 380 | struct drive_geom_emul drv[2]; /* drive structures */ | ||
| 381 | }; | ||
| 382 | |||
| 383 | #endif /* _EATA_GENERIC_H */ | ||
| 384 | |||
| 385 | /* | ||
| 386 | * Overrides for Emacs so that we almost follow Linus's tabbing style. | ||
| 387 | * Emacs will notice this stuff at the end of the file and automatically | ||
| 388 | * adjust the settings for this buffer only. This must remain at the end | ||
| 389 | * of the file. | ||
| 390 | * --------------------------------------------------------------------------- | ||
| 391 | * Local variables: | ||
| 392 | * c-indent-level: 4 | ||
| 393 | * c-brace-imaginary-offset: 0 | ||
| 394 | * c-brace-offset: -4 | ||
| 395 | * c-argdecl-indent: 4 | ||
| 396 | * c-label-offset: -4 | ||
| 397 | * c-continued-statement-offset: 4 | ||
| 398 | * c-continued-brace-offset: 0 | ||
| 399 | * tab-width: 8 | ||
| 400 | * End: | ||
| 401 | */ | ||
diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c deleted file mode 100644 index 4299fa485622..000000000000 --- a/drivers/scsi/eata_pio.c +++ /dev/null | |||
| @@ -1,966 +0,0 @@ | |||
| 1 | /************************************************************ | ||
| 2 | * * | ||
| 3 | * Linux EATA SCSI PIO driver * | ||
| 4 | * * | ||
| 5 | * based on the CAM document CAM/89-004 rev. 2.0c, * | ||
| 6 | * DPT's driver kit, some internal documents and source, * | ||
| 7 | * and several other Linux scsi drivers and kernel docs. * | ||
| 8 | * * | ||
| 9 | * The driver currently: * | ||
| 10 | * -supports all EATA-PIO boards * | ||
| 11 | * -only supports DASD devices * | ||
| 12 | * * | ||
| 13 | * (c)1993-96 Michael Neuffer, Alfred Arnold * | ||
| 14 | * neuffer@goofy.zdv.uni-mainz.de * | ||
| 15 | * a.arnold@kfa-juelich.de * | ||
| 16 | * * | ||
| 17 | * Updated 2002 by Alan Cox <alan@lxorguk.ukuu.org.uk> for * | ||
| 18 | * Linux 2.5.x and the newer locking and error handling * | ||
| 19 | * * | ||
| 20 | * This program is free software; you can redistribute it * | ||
| 21 | * and/or modify it under the terms of the GNU General * | ||
| 22 | * Public License as published by the Free Software * | ||
| 23 | * Foundation; either version 2 of the License, or * | ||
| 24 | * (at your option) any later version. * | ||
| 25 | * * | ||
| 26 | * This program is distributed in the hope that it will be * | ||
| 27 | * useful, but WITHOUT ANY WARRANTY; without even the * | ||
| 28 | * implied warranty of MERCHANTABILITY or FITNESS FOR A * | ||
| 29 | * PARTICULAR PURPOSE. See the GNU General Public License * | ||
| 30 | * for more details. * | ||
| 31 | * * | ||
| 32 | * You should have received a copy of the GNU General * | ||
| 33 | * Public License along with this kernel; if not, write to * | ||
| 34 | * the Free Software Foundation, Inc., 675 Mass Ave, * | ||
| 35 | * Cambridge, MA 02139, USA. * | ||
| 36 | * * | ||
| 37 | * For the avoidance of doubt the "preferred form" of this * | ||
| 38 | * code is one which is in an open non patent encumbered * | ||
| 39 | * format. Where cryptographic key signing forms part of * | ||
| 40 | * the process of creating an executable the information * | ||
| 41 | * including keys needed to generate an equivalently * | ||
| 42 | * functional executable are deemed to be part of the * | ||
| 43 | * source code are deemed to be part of the source code. * | ||
| 44 | * * | ||
| 45 | ************************************************************ | ||
| 46 | * last change: 2002/11/02 OS: Linux 2.5.45 * | ||
| 47 | ************************************************************/ | ||
| 48 | |||
| 49 | #include <linux/module.h> | ||
| 50 | #include <linux/kernel.h> | ||
| 51 | #include <linux/string.h> | ||
| 52 | #include <linux/ioport.h> | ||
| 53 | #include <linux/in.h> | ||
| 54 | #include <linux/pci.h> | ||
| 55 | #include <linux/proc_fs.h> | ||
| 56 | #include <linux/interrupt.h> | ||
| 57 | #include <linux/blkdev.h> | ||
| 58 | #include <linux/spinlock.h> | ||
| 59 | #include <linux/delay.h> | ||
| 60 | |||
| 61 | #include <asm/io.h> | ||
| 62 | |||
| 63 | #include <scsi/scsi.h> | ||
| 64 | #include <scsi/scsi_cmnd.h> | ||
| 65 | #include <scsi/scsi_device.h> | ||
| 66 | #include <scsi/scsi_host.h> | ||
| 67 | |||
| 68 | #include "eata_generic.h" | ||
| 69 | #include "eata_pio.h" | ||
| 70 | |||
| 71 | |||
| 72 | static unsigned int ISAbases[MAXISA] = { | ||
| 73 | 0x1F0, 0x170, 0x330, 0x230 | ||
| 74 | }; | ||
| 75 | |||
| 76 | static unsigned int ISAirqs[MAXISA] = { | ||
| 77 | 14, 12, 15, 11 | ||
| 78 | }; | ||
| 79 | |||
| 80 | static unsigned char EISAbases[] = { | ||
| 81 | 1, 1, 1, 1, 1, 1, 1, 1, | ||
| 82 | 1, 1, 1, 1, 1, 1, 1, 1 | ||
| 83 | }; | ||
| 84 | |||
| 85 | static unsigned int registered_HBAs; | ||
| 86 | static struct Scsi_Host *last_HBA; | ||
| 87 | static struct Scsi_Host *first_HBA; | ||
| 88 | static unsigned char reg_IRQ[16]; | ||
| 89 | static unsigned char reg_IRQL[16]; | ||
| 90 | static unsigned long int_counter; | ||
| 91 | static unsigned long queue_counter; | ||
| 92 | |||
| 93 | static struct scsi_host_template driver_template; | ||
| 94 | |||
| 95 | static int eata_pio_show_info(struct seq_file *m, struct Scsi_Host *shost) | ||
| 96 | { | ||
| 97 | seq_printf(m, "EATA (Extended Attachment) PIO driver version: " | ||
| 98 | "%d.%d%s\n",VER_MAJOR, VER_MINOR, VER_SUB); | ||
| 99 | seq_printf(m, "queued commands: %10ld\n" | ||
| 100 | "processed interrupts:%10ld\n", queue_counter, int_counter); | ||
| 101 | seq_printf(m, "\nscsi%-2d: HBA %.10s\n", | ||
| 102 | shost->host_no, SD(shost)->name); | ||
| 103 | seq_printf(m, "Firmware revision: v%s\n", | ||
| 104 | SD(shost)->revision); | ||
| 105 | seq_puts(m, "IO: PIO\n"); | ||
| 106 | seq_printf(m, "Base IO : %#.4x\n", (u32) shost->base); | ||
| 107 | seq_printf(m, "Host Bus: %s\n", | ||
| 108 | (SD(shost)->bustype == 'P')?"PCI ": | ||
| 109 | (SD(shost)->bustype == 'E')?"EISA":"ISA "); | ||
| 110 | return 0; | ||
| 111 | } | ||
| 112 | |||
| 113 | static int eata_pio_release(struct Scsi_Host *sh) | ||
| 114 | { | ||
| 115 | hostdata *hd = SD(sh); | ||
| 116 | if (sh->irq && reg_IRQ[sh->irq] == 1) | ||
| 117 | free_irq(sh->irq, NULL); | ||
| 118 | else | ||
| 119 | reg_IRQ[sh->irq]--; | ||
| 120 | if (SD(sh)->channel == 0) { | ||
| 121 | if (sh->io_port && sh->n_io_port) | ||
| 122 | release_region(sh->io_port, sh->n_io_port); | ||
| 123 | } | ||
| 124 | /* At this point the PCI reference can go */ | ||
| 125 | if (hd->pdev) | ||
| 126 | pci_dev_put(hd->pdev); | ||
| 127 | return 1; | ||
| 128 | } | ||
| 129 | |||
| 130 | static void IncStat(struct scsi_pointer *SCp, unsigned int Increment) | ||
| 131 | { | ||
| 132 | SCp->ptr += Increment; | ||
| 133 | if ((SCp->this_residual -= Increment) == 0) { | ||
| 134 | if ((--SCp->buffers_residual) == 0) | ||
| 135 | SCp->Status = 0; | ||
| 136 | else { | ||
| 137 | SCp->buffer++; | ||
| 138 | SCp->ptr = sg_virt(SCp->buffer); | ||
| 139 | SCp->this_residual = SCp->buffer->length; | ||
| 140 | } | ||
| 141 | } | ||
| 142 | } | ||
| 143 | |||
| 144 | static irqreturn_t eata_pio_int_handler(int irq, void *dev_id); | ||
| 145 | |||
| 146 | static irqreturn_t do_eata_pio_int_handler(int irq, void *dev_id) | ||
| 147 | { | ||
| 148 | unsigned long flags; | ||
| 149 | struct Scsi_Host *dev = dev_id; | ||
| 150 | irqreturn_t ret; | ||
| 151 | |||
| 152 | spin_lock_irqsave(dev->host_lock, flags); | ||
| 153 | ret = eata_pio_int_handler(irq, dev_id); | ||
| 154 | spin_unlock_irqrestore(dev->host_lock, flags); | ||
| 155 | return ret; | ||
| 156 | } | ||
| 157 | |||
| 158 | static irqreturn_t eata_pio_int_handler(int irq, void *dev_id) | ||
| 159 | { | ||
| 160 | unsigned int eata_stat = 0xfffff; | ||
| 161 | struct scsi_cmnd *cmd; | ||
| 162 | hostdata *hd; | ||
| 163 | struct eata_ccb *cp; | ||
| 164 | unsigned long base; | ||
| 165 | unsigned int x, z; | ||
| 166 | struct Scsi_Host *sh; | ||
| 167 | unsigned short zwickel = 0; | ||
| 168 | unsigned char stat, odd; | ||
| 169 | irqreturn_t ret = IRQ_NONE; | ||
| 170 | |||
| 171 | for (x = 1, sh = first_HBA; x <= registered_HBAs; x++, sh = SD(sh)->prev) | ||
| 172 | { | ||
| 173 | if (sh->irq != irq) | ||
| 174 | continue; | ||
| 175 | if (inb(sh->base + HA_RSTATUS) & HA_SBUSY) | ||
| 176 | continue; | ||
| 177 | |||
| 178 | int_counter++; | ||
| 179 | ret = IRQ_HANDLED; | ||
| 180 | |||
| 181 | hd = SD(sh); | ||
| 182 | |||
| 183 | cp = &hd->ccb[0]; | ||
| 184 | cmd = cp->cmd; | ||
| 185 | base = cmd->device->host->base; | ||
| 186 | |||
| 187 | do { | ||
| 188 | stat = inb(base + HA_RSTATUS); | ||
| 189 | if (stat & HA_SDRQ) { | ||
| 190 | if (cp->DataIn) { | ||
| 191 | z = 256; | ||
| 192 | odd = 0; | ||
| 193 | while ((cmd->SCp.Status) && ((z > 0) || (odd))) { | ||
| 194 | if (odd) { | ||
| 195 | *(cmd->SCp.ptr) = zwickel >> 8; | ||
| 196 | IncStat(&cmd->SCp, 1); | ||
| 197 | odd = 0; | ||
| 198 | } | ||
| 199 | x = min_t(unsigned int, z, cmd->SCp.this_residual / 2); | ||
| 200 | insw(base + HA_RDATA, cmd->SCp.ptr, x); | ||
| 201 | z -= x; | ||
| 202 | IncStat(&cmd->SCp, 2 * x); | ||
| 203 | if ((z > 0) && (cmd->SCp.this_residual == 1)) { | ||
| 204 | zwickel = inw(base + HA_RDATA); | ||
| 205 | *(cmd->SCp.ptr) = zwickel & 0xff; | ||
| 206 | IncStat(&cmd->SCp, 1); | ||
| 207 | z--; | ||
| 208 | odd = 1; | ||
| 209 | } | ||
| 210 | } | ||
| 211 | while (z > 0) { | ||
| 212 | zwickel = inw(base + HA_RDATA); | ||
| 213 | z--; | ||
| 214 | } | ||
| 215 | } else { /* cp->DataOut */ | ||
| 216 | |||
| 217 | odd = 0; | ||
| 218 | z = 256; | ||
| 219 | while ((cmd->SCp.Status) && ((z > 0) || (odd))) { | ||
| 220 | if (odd) { | ||
| 221 | zwickel += *(cmd->SCp.ptr) << 8; | ||
| 222 | IncStat(&cmd->SCp, 1); | ||
| 223 | outw(zwickel, base + HA_RDATA); | ||
| 224 | z--; | ||
| 225 | odd = 0; | ||
| 226 | } | ||
| 227 | x = min_t(unsigned int, z, cmd->SCp.this_residual / 2); | ||
| 228 | outsw(base + HA_RDATA, cmd->SCp.ptr, x); | ||
| 229 | z -= x; | ||
| 230 | IncStat(&cmd->SCp, 2 * x); | ||
| 231 | if ((z > 0) && (cmd->SCp.this_residual == 1)) { | ||
| 232 | zwickel = *(cmd->SCp.ptr); | ||
| 233 | zwickel &= 0xff; | ||
| 234 | IncStat(&cmd->SCp, 1); | ||
| 235 | odd = 1; | ||
| 236 | } | ||
| 237 | } | ||
| 238 | while (z > 0 || odd) { | ||
| 239 | outw(zwickel, base + HA_RDATA); | ||
| 240 | z--; | ||
| 241 | odd = 0; | ||
| 242 | } | ||
| 243 | } | ||
| 244 | } | ||
| 245 | } | ||
| 246 | while ((stat & HA_SDRQ) || ((stat & HA_SMORE) && hd->moresupport)); | ||
| 247 | |||
| 248 | /* terminate handler if HBA goes busy again, i.e. transfers | ||
| 249 | * more data */ | ||
| 250 | |||
| 251 | if (stat & HA_SBUSY) | ||
| 252 | break; | ||
| 253 | |||
| 254 | /* OK, this is quite stupid, but I haven't found any correct | ||
| 255 | * way to get HBA&SCSI status so far */ | ||
| 256 | |||
| 257 | if (!(inb(base + HA_RSTATUS) & HA_SERROR)) { | ||
| 258 | cmd->result = (DID_OK << 16); | ||
| 259 | hd->devflags |= (1 << cp->cp_id); | ||
| 260 | } else if (hd->devflags & (1 << cp->cp_id)) | ||
| 261 | cmd->result = (DID_OK << 16) + 0x02; | ||
| 262 | else | ||
| 263 | cmd->result = (DID_NO_CONNECT << 16); | ||
| 264 | |||
| 265 | if (cp->status == LOCKED) { | ||
| 266 | cp->status = FREE; | ||
| 267 | eata_stat = inb(base + HA_RSTATUS); | ||
| 268 | printk(KERN_CRIT "eata_pio: int_handler, freeing locked " "queueslot\n"); | ||
| 269 | return ret; | ||
| 270 | } | ||
| 271 | #if DBG_INTR2 | ||
| 272 | if (stat != 0x50) | ||
| 273 | printk(KERN_DEBUG "stat: %#.2x, result: %#.8x\n", stat, cmd->result); | ||
| 274 | #endif | ||
| 275 | |||
| 276 | cp->status = FREE; /* now we can release the slot */ | ||
| 277 | |||
| 278 | cmd->scsi_done(cmd); | ||
| 279 | } | ||
| 280 | |||
| 281 | return ret; | ||
| 282 | } | ||
| 283 | |||
| 284 | static inline unsigned int eata_pio_send_command(unsigned long base, unsigned char command) | ||
| 285 | { | ||
| 286 | unsigned int loop = 50; | ||
| 287 | |||
| 288 | while (inb(base + HA_RSTATUS) & HA_SBUSY) | ||
| 289 | if (--loop == 0) | ||
| 290 | return 1; | ||
| 291 | |||
| 292 | /* Enable interrupts for HBA. It is not the best way to do it at this | ||
| 293 | * place, but I hope that it doesn't interfere with the IDE driver | ||
| 294 | * initialization this way */ | ||
| 295 | |||
| 296 | outb(HA_CTRL_8HEADS, base + HA_CTRLREG); | ||
| 297 | |||
| 298 | outb(command, base + HA_WCOMMAND); | ||
| 299 | return 0; | ||
| 300 | } | ||
| 301 | |||
| 302 | static int eata_pio_queue_lck(struct scsi_cmnd *cmd, | ||
| 303 | void (*done)(struct scsi_cmnd *)) | ||
| 304 | { | ||
| 305 | unsigned int x, y; | ||
| 306 | unsigned long base; | ||
| 307 | |||
| 308 | hostdata *hd; | ||
| 309 | struct Scsi_Host *sh; | ||
| 310 | struct eata_ccb *cp; | ||
| 311 | |||
| 312 | queue_counter++; | ||
| 313 | |||
| 314 | hd = HD(cmd); | ||
| 315 | sh = cmd->device->host; | ||
| 316 | base = sh->base; | ||
| 317 | |||
| 318 | /* use only slot 0, as 2001 can handle only one cmd at a time */ | ||
| 319 | |||
| 320 | y = x = 0; | ||
| 321 | |||
| 322 | if (hd->ccb[y].status != FREE) { | ||
| 323 | |||
| 324 | DBG(DBG_QUEUE, printk(KERN_EMERG "can_queue %d, x %d, y %d\n", sh->can_queue, x, y)); | ||
| 325 | #if DEBUG_EATA | ||
| 326 | panic(KERN_EMERG "eata_pio: run out of queue slots cmdno:%ld " "intrno: %ld\n", queue_counter, int_counter); | ||
| 327 | #else | ||
| 328 | panic(KERN_EMERG "eata_pio: run out of queue slots....\n"); | ||
| 329 | #endif | ||
| 330 | } | ||
| 331 | |||
| 332 | cp = &hd->ccb[y]; | ||
| 333 | |||
| 334 | memset(cp, 0, sizeof(struct eata_ccb)); | ||
| 335 | |||
| 336 | cp->status = USED; /* claim free slot */ | ||
| 337 | |||
| 338 | DBG(DBG_QUEUE, scmd_printk(KERN_DEBUG, cmd, | ||
| 339 | "eata_pio_queue 0x%p, y %d\n", cmd, y)); | ||
| 340 | |||
| 341 | cmd->scsi_done = (void *) done; | ||
| 342 | |||
| 343 | if (cmd->sc_data_direction == DMA_TO_DEVICE) | ||
| 344 | cp->DataOut = 1; /* Output mode */ | ||
| 345 | else | ||
| 346 | cp->DataIn = 0; /* Input mode */ | ||
| 347 | |||
| 348 | cp->Interpret = (cmd->device->id == hd->hostid); | ||
| 349 | cp->cp_datalen = cpu_to_be32(scsi_bufflen(cmd)); | ||
| 350 | cp->Auto_Req_Sen = 0; | ||
| 351 | cp->cp_reqDMA = 0; | ||
| 352 | cp->reqlen = 0; | ||
| 353 | |||
| 354 | cp->cp_id = cmd->device->id; | ||
| 355 | cp->cp_lun = cmd->device->lun; | ||
| 356 | cp->cp_dispri = 0; | ||
| 357 | cp->cp_identify = 1; | ||
| 358 | memcpy(cp->cp_cdb, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd)); | ||
| 359 | |||
| 360 | cp->cp_statDMA = 0; | ||
| 361 | |||
| 362 | cp->cp_viraddr = cp; | ||
| 363 | cp->cmd = cmd; | ||
| 364 | cmd->host_scribble = (char *) &hd->ccb[y]; | ||
| 365 | |||
| 366 | if (!scsi_bufflen(cmd)) { | ||
| 367 | cmd->SCp.buffers_residual = 1; | ||
| 368 | cmd->SCp.ptr = NULL; | ||
| 369 | cmd->SCp.this_residual = 0; | ||
| 370 | cmd->SCp.buffer = NULL; | ||
| 371 | } else { | ||
| 372 | cmd->SCp.buffer = scsi_sglist(cmd); | ||
| 373 | cmd->SCp.buffers_residual = scsi_sg_count(cmd); | ||
| 374 | cmd->SCp.ptr = sg_virt(cmd->SCp.buffer); | ||
| 375 | cmd->SCp.this_residual = cmd->SCp.buffer->length; | ||
| 376 | } | ||
| 377 | cmd->SCp.Status = (cmd->SCp.this_residual != 0); /* TRUE as long as bytes | ||
| 378 | * are to transfer */ | ||
| 379 | |||
| 380 | if (eata_pio_send_command(base, EATA_CMD_PIO_SEND_CP)) { | ||
| 381 | cmd->result = DID_BUS_BUSY << 16; | ||
| 382 | scmd_printk(KERN_NOTICE, cmd, | ||
| 383 | "eata_pio_queue pid 0x%p, HBA busy, " | ||
| 384 | "returning DID_BUS_BUSY, done.\n", cmd); | ||
| 385 | done(cmd); | ||
| 386 | cp->status = FREE; | ||
| 387 | return 0; | ||
| 388 | } | ||
| 389 | /* FIXME: timeout */ | ||
| 390 | while (!(inb(base + HA_RSTATUS) & HA_SDRQ)) | ||
| 391 | cpu_relax(); | ||
| 392 | outsw(base + HA_RDATA, cp, hd->cplen); | ||
| 393 | outb(EATA_CMD_PIO_TRUNC, base + HA_WCOMMAND); | ||
| 394 | for (x = 0; x < hd->cppadlen; x++) | ||
| 395 | outw(0, base + HA_RDATA); | ||
| 396 | |||
| 397 | DBG(DBG_QUEUE, scmd_printk(KERN_DEBUG, cmd, | ||
| 398 | "Queued base %#.4lx cmd: 0x%p " | ||
| 399 | "slot %d irq %d\n", sh->base, cmd, y, sh->irq)); | ||
| 400 | |||
| 401 | return 0; | ||
| 402 | } | ||
| 403 | |||
| 404 | static DEF_SCSI_QCMD(eata_pio_queue) | ||
| 405 | |||
| 406 | static int eata_pio_abort(struct scsi_cmnd *cmd) | ||
| 407 | { | ||
| 408 | unsigned int loop = 100; | ||
| 409 | |||
| 410 | DBG(DBG_ABNORM, scmd_printk(KERN_WARNING, cmd, | ||
| 411 | "eata_pio_abort called pid: 0x%p\n", cmd)); | ||
| 412 | |||
| 413 | while (inb(cmd->device->host->base + HA_RAUXSTAT) & HA_ABUSY) | ||
| 414 | if (--loop == 0) { | ||
| 415 | printk(KERN_WARNING "eata_pio: abort, timeout error.\n"); | ||
| 416 | return FAILED; | ||
| 417 | } | ||
| 418 | if (CD(cmd)->status == FREE) { | ||
| 419 | DBG(DBG_ABNORM, printk(KERN_WARNING "Returning: SCSI_ABORT_NOT_RUNNING\n")); | ||
| 420 | return FAILED; | ||
| 421 | } | ||
| 422 | if (CD(cmd)->status == USED) { | ||
| 423 | DBG(DBG_ABNORM, printk(KERN_WARNING "Returning: SCSI_ABORT_BUSY\n")); | ||
| 424 | /* We want to sleep a bit more here */ | ||
| 425 | return FAILED; /* SNOOZE */ | ||
| 426 | } | ||
| 427 | if (CD(cmd)->status == RESET) { | ||
| 428 | printk(KERN_WARNING "eata_pio: abort, command reset error.\n"); | ||
| 429 | return FAILED; | ||
| 430 | } | ||
| 431 | if (CD(cmd)->status == LOCKED) { | ||
| 432 | DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio: abort, queue slot " "locked.\n")); | ||
| 433 | return FAILED; | ||
| 434 | } | ||
| 435 | panic("eata_pio: abort: invalid slot status\n"); | ||
| 436 | } | ||
| 437 | |||
| 438 | static int eata_pio_host_reset(struct scsi_cmnd *cmd) | ||
| 439 | { | ||
| 440 | unsigned int x, limit = 0; | ||
| 441 | unsigned char success = 0; | ||
| 442 | struct scsi_cmnd *sp; | ||
| 443 | struct Scsi_Host *host = cmd->device->host; | ||
| 444 | |||
| 445 | DBG(DBG_ABNORM, scmd_printk(KERN_WARNING, cmd, | ||
| 446 | "eata_pio_reset called\n")); | ||
| 447 | |||
| 448 | spin_lock_irq(host->host_lock); | ||
| 449 | |||
| 450 | if (HD(cmd)->state == RESET) { | ||
| 451 | printk(KERN_WARNING "eata_pio_reset: exit, already in reset.\n"); | ||
| 452 | spin_unlock_irq(host->host_lock); | ||
| 453 | return FAILED; | ||
| 454 | } | ||
| 455 | |||
| 456 | /* force all slots to be free */ | ||
| 457 | |||
| 458 | for (x = 0; x < cmd->device->host->can_queue; x++) { | ||
| 459 | |||
| 460 | if (HD(cmd)->ccb[x].status == FREE) | ||
| 461 | continue; | ||
| 462 | |||
| 463 | sp = HD(cmd)->ccb[x].cmd; | ||
| 464 | HD(cmd)->ccb[x].status = RESET; | ||
| 465 | printk(KERN_WARNING "eata_pio_reset: slot %d in reset.\n", x); | ||
| 466 | |||
| 467 | if (sp == NULL) | ||
| 468 | panic("eata_pio_reset: slot %d, sp==NULL.\n", x); | ||
| 469 | } | ||
| 470 | |||
| 471 | /* hard reset the HBA */ | ||
| 472 | outb(EATA_CMD_RESET, cmd->device->host->base + HA_WCOMMAND); | ||
| 473 | |||
| 474 | DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: board reset done.\n")); | ||
| 475 | HD(cmd)->state = RESET; | ||
| 476 | |||
| 477 | spin_unlock_irq(host->host_lock); | ||
| 478 | msleep(3000); | ||
| 479 | spin_lock_irq(host->host_lock); | ||
| 480 | |||
| 481 | DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: interrupts disabled, " "loops %d.\n", limit)); | ||
| 482 | |||
| 483 | for (x = 0; x < cmd->device->host->can_queue; x++) { | ||
| 484 | |||
| 485 | /* Skip slots already set free by interrupt */ | ||
| 486 | if (HD(cmd)->ccb[x].status != RESET) | ||
| 487 | continue; | ||
| 488 | |||
| 489 | sp = HD(cmd)->ccb[x].cmd; | ||
| 490 | sp->result = DID_RESET << 16; | ||
| 491 | |||
| 492 | /* This mailbox is terminated */ | ||
| 493 | printk(KERN_WARNING "eata_pio_reset: reset ccb %d.\n", x); | ||
| 494 | HD(cmd)->ccb[x].status = FREE; | ||
| 495 | |||
| 496 | sp->scsi_done(sp); | ||
| 497 | } | ||
| 498 | |||
| 499 | HD(cmd)->state = 0; | ||
| 500 | |||
| 501 | spin_unlock_irq(host->host_lock); | ||
| 502 | |||
| 503 | if (success) { /* hmmm... */ | ||
| 504 | DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: exit, success.\n")); | ||
| 505 | return SUCCESS; | ||
| 506 | } else { | ||
| 507 | DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: exit, wakeup.\n")); | ||
| 508 | return FAILED; | ||
| 509 | } | ||
| 510 | } | ||
| 511 | |||
| 512 | static char *get_pio_board_data(unsigned long base, unsigned int irq, unsigned int id, unsigned long cplen, unsigned short cppadlen) | ||
| 513 | { | ||
| 514 | struct eata_ccb cp; | ||
| 515 | static char buff[256]; | ||
| 516 | int z; | ||
| 517 | |||
| 518 | memset(&cp, 0, sizeof(struct eata_ccb)); | ||
| 519 | memset(buff, 0, sizeof(buff)); | ||
| 520 | |||
| 521 | cp.DataIn = 1; | ||
| 522 | cp.Interpret = 1; /* Interpret command */ | ||
| 523 | |||
| 524 | cp.cp_datalen = cpu_to_be32(254); | ||
| 525 | cp.cp_dataDMA = cpu_to_be32(0); | ||
| 526 | |||
| 527 | cp.cp_id = id; | ||
| 528 | cp.cp_lun = 0; | ||
| 529 | |||
| 530 | cp.cp_cdb[0] = INQUIRY; | ||
| 531 | cp.cp_cdb[1] = 0; | ||
| 532 | cp.cp_cdb[2] = 0; | ||
| 533 | cp.cp_cdb[3] = 0; | ||
| 534 | cp.cp_cdb[4] = 254; | ||
| 535 | cp.cp_cdb[5] = 0; | ||
| 536 | |||
| 537 | if (eata_pio_send_command(base, EATA_CMD_PIO_SEND_CP)) | ||
| 538 | return NULL; | ||
| 539 | |||
| 540 | while (!(inb(base + HA_RSTATUS) & HA_SDRQ)) | ||
| 541 | cpu_relax(); | ||
| 542 | |||
| 543 | outsw(base + HA_RDATA, &cp, cplen); | ||
| 544 | outb(EATA_CMD_PIO_TRUNC, base + HA_WCOMMAND); | ||
| 545 | for (z = 0; z < cppadlen; z++) | ||
| 546 | outw(0, base + HA_RDATA); | ||
| 547 | |||
| 548 | while (inb(base + HA_RSTATUS) & HA_SBUSY) | ||
| 549 | cpu_relax(); | ||
| 550 | |||
| 551 | if (inb(base + HA_RSTATUS) & HA_SERROR) | ||
| 552 | return NULL; | ||
| 553 | else if (!(inb(base + HA_RSTATUS) & HA_SDRQ)) | ||
| 554 | return NULL; | ||
| 555 | else { | ||
| 556 | insw(base + HA_RDATA, &buff, 127); | ||
| 557 | while (inb(base + HA_RSTATUS) & HA_SDRQ) | ||
| 558 | inw(base + HA_RDATA); | ||
| 559 | return buff; | ||
| 560 | } | ||
| 561 | } | ||
| 562 | |||
| 563 | static int get_pio_conf_PIO(unsigned long base, struct get_conf *buf) | ||
| 564 | { | ||
| 565 | unsigned long loop = HZ / 2; | ||
| 566 | int z; | ||
| 567 | unsigned short *p; | ||
| 568 | |||
| 569 | if (!request_region(base, 9, "eata_pio")) | ||
| 570 | return 0; | ||
| 571 | |||
| 572 | memset(buf, 0, sizeof(struct get_conf)); | ||
| 573 | |||
| 574 | while (inb(base + HA_RSTATUS) & HA_SBUSY) | ||
| 575 | if (--loop == 0) | ||
| 576 | goto fail; | ||
| 577 | |||
| 578 | DBG(DBG_PIO && DBG_PROBE, printk(KERN_DEBUG "Issuing PIO READ CONFIG to HBA at %#lx\n", base)); | ||
| 579 | eata_pio_send_command(base, EATA_CMD_PIO_READ_CONFIG); | ||
| 580 | |||
| 581 | loop = 50; | ||
| 582 | for (p = (unsigned short *) buf; (long) p <= ((long) buf + (sizeof(struct get_conf) / 2)); p++) { | ||
| 583 | while (!(inb(base + HA_RSTATUS) & HA_SDRQ)) | ||
| 584 | if (--loop == 0) | ||
| 585 | goto fail; | ||
| 586 | |||
| 587 | loop = 50; | ||
| 588 | *p = inw(base + HA_RDATA); | ||
| 589 | } | ||
| 590 | if (inb(base + HA_RSTATUS) & HA_SERROR) { | ||
| 591 | DBG(DBG_PROBE, printk("eata_dma: get_conf_PIO, error during " | ||
| 592 | "transfer for HBA at %lx\n", base)); | ||
| 593 | goto fail; | ||
| 594 | } | ||
| 595 | |||
| 596 | if (cpu_to_be32(EATA_SIGNATURE) != buf->signature) | ||
| 597 | goto fail; | ||
| 598 | |||
| 599 | DBG(DBG_PIO && DBG_PROBE, printk(KERN_NOTICE "EATA Controller found " | ||
| 600 | "at %#4lx EATA Level: %x\n", | ||
| 601 | base, (unsigned int) (buf->version))); | ||
| 602 | |||
| 603 | while (inb(base + HA_RSTATUS) & HA_SDRQ) | ||
| 604 | inw(base + HA_RDATA); | ||
| 605 | |||
| 606 | if (!ALLOW_DMA_BOARDS) { | ||
| 607 | for (z = 0; z < MAXISA; z++) | ||
| 608 | if (base == ISAbases[z]) { | ||
| 609 | buf->IRQ = ISAirqs[z]; | ||
| 610 | break; | ||
| 611 | } | ||
| 612 | } | ||
| 613 | |||
| 614 | return 1; | ||
| 615 | |||
| 616 | fail: | ||
| 617 | release_region(base, 9); | ||
| 618 | return 0; | ||
| 619 | } | ||
| 620 | |||
| 621 | static void print_pio_config(struct get_conf *gc) | ||
| 622 | { | ||
| 623 | printk("Please check values: (read config data)\n"); | ||
| 624 | printk("LEN: %d ver:%d OCS:%d TAR:%d TRNXFR:%d MORES:%d\n", be32_to_cpu(gc->len), gc->version, gc->OCS_enabled, gc->TAR_support, gc->TRNXFR, gc->MORE_support); | ||
| 625 | printk("HAAV:%d SCSIID0:%d ID1:%d ID2:%d QUEUE:%d SG:%d SEC:%d\n", gc->HAA_valid, gc->scsi_id[3], gc->scsi_id[2], gc->scsi_id[1], be16_to_cpu(gc->queuesiz), be16_to_cpu(gc->SGsiz), gc->SECOND); | ||
| 626 | printk("IRQ:%d IRQT:%d FORCADR:%d MCH:%d RIDQ:%d\n", gc->IRQ, gc->IRQ_TR, gc->FORCADR, gc->MAX_CHAN, gc->ID_qest); | ||
| 627 | } | ||
| 628 | |||
| 629 | static unsigned int print_selftest(unsigned int base) | ||
| 630 | { | ||
| 631 | unsigned char buffer[512]; | ||
| 632 | #ifdef VERBOSE_SETUP | ||
| 633 | int z; | ||
| 634 | #endif | ||
| 635 | |||
| 636 | printk("eata_pio: executing controller self test & setup...\n"); | ||
| 637 | while (inb(base + HA_RSTATUS) & HA_SBUSY); | ||
| 638 | outb(EATA_CMD_PIO_SETUPTEST, base + HA_WCOMMAND); | ||
| 639 | do { | ||
| 640 | while (inb(base + HA_RSTATUS) & HA_SBUSY) | ||
| 641 | /* nothing */ ; | ||
| 642 | if (inb(base + HA_RSTATUS) & HA_SDRQ) { | ||
| 643 | insw(base + HA_RDATA, &buffer, 256); | ||
| 644 | #ifdef VERBOSE_SETUP | ||
| 645 | /* no beeps please... */ | ||
| 646 | for (z = 0; z < 511 && buffer[z]; z++) | ||
| 647 | if (buffer[z] != 7) | ||
| 648 | printk("%c", buffer[z]); | ||
| 649 | #endif | ||
| 650 | } | ||
| 651 | } while (inb(base + HA_RSTATUS) & (HA_SBUSY | HA_SDRQ)); | ||
| 652 | |||
| 653 | return (!(inb(base + HA_RSTATUS) & HA_SERROR)); | ||
| 654 | } | ||
| 655 | |||
| 656 | static int register_pio_HBA(long base, struct get_conf *gc, struct pci_dev *pdev) | ||
| 657 | { | ||
| 658 | unsigned long size = 0; | ||
| 659 | char *buff; | ||
| 660 | unsigned long cplen; | ||
| 661 | unsigned short cppadlen; | ||
| 662 | struct Scsi_Host *sh; | ||
| 663 | hostdata *hd; | ||
| 664 | |||
| 665 | DBG(DBG_REGISTER, print_pio_config(gc)); | ||
| 666 | |||
| 667 | if (gc->DMA_support) { | ||
| 668 | printk("HBA at %#.4lx supports DMA. Please use EATA-DMA driver.\n", base); | ||
| 669 | if (!ALLOW_DMA_BOARDS) | ||
| 670 | return 0; | ||
| 671 | } | ||
| 672 | |||
| 673 | if ((buff = get_pio_board_data(base, gc->IRQ, gc->scsi_id[3], cplen = (cpu_to_be32(gc->cplen) + 1) / 2, cppadlen = (cpu_to_be16(gc->cppadlen) + 1) / 2)) == NULL) { | ||
| 674 | printk("HBA at %#lx didn't react on INQUIRY. Sorry.\n", base); | ||
| 675 | return 0; | ||
| 676 | } | ||
| 677 | |||
| 678 | if (!print_selftest(base) && !ALLOW_DMA_BOARDS) { | ||
| 679 | printk("HBA at %#lx failed while performing self test & setup.\n", base); | ||
| 680 | return 0; | ||
| 681 | } | ||
| 682 | |||
| 683 | size = sizeof(hostdata) + (sizeof(struct eata_ccb) * be16_to_cpu(gc->queuesiz)); | ||
| 684 | |||
| 685 | sh = scsi_register(&driver_template, size); | ||
| 686 | if (sh == NULL) | ||
| 687 | return 0; | ||
| 688 | |||
| 689 | if (!reg_IRQ[gc->IRQ]) { /* Interrupt already registered ? */ | ||
| 690 | if (!request_irq(gc->IRQ, do_eata_pio_int_handler, 0, "EATA-PIO", sh)) { | ||
| 691 | reg_IRQ[gc->IRQ]++; | ||
| 692 | if (!gc->IRQ_TR) | ||
| 693 | reg_IRQL[gc->IRQ] = 1; /* IRQ is edge triggered */ | ||
| 694 | } else { | ||
| 695 | printk("Couldn't allocate IRQ %d, Sorry.\n", gc->IRQ); | ||
| 696 | return 0; | ||
| 697 | } | ||
| 698 | } else { /* More than one HBA on this IRQ */ | ||
| 699 | if (reg_IRQL[gc->IRQ]) { | ||
| 700 | printk("Can't support more than one HBA on this IRQ,\n" " if the IRQ is edge triggered. Sorry.\n"); | ||
| 701 | return 0; | ||
| 702 | } else | ||
| 703 | reg_IRQ[gc->IRQ]++; | ||
| 704 | } | ||
| 705 | |||
| 706 | hd = SD(sh); | ||
| 707 | |||
| 708 | memset(hd->ccb, 0, (sizeof(struct eata_ccb) * be16_to_cpu(gc->queuesiz))); | ||
| 709 | memset(hd->reads, 0, sizeof(hd->reads)); | ||
| 710 | |||
| 711 | strlcpy(SD(sh)->vendor, &buff[8], sizeof(SD(sh)->vendor)); | ||
| 712 | strlcpy(SD(sh)->name, &buff[16], sizeof(SD(sh)->name)); | ||
| 713 | SD(sh)->revision[0] = buff[32]; | ||
| 714 | SD(sh)->revision[1] = buff[33]; | ||
| 715 | SD(sh)->revision[2] = buff[34]; | ||
| 716 | SD(sh)->revision[3] = '.'; | ||
| 717 | SD(sh)->revision[4] = buff[35]; | ||
| 718 | SD(sh)->revision[5] = 0; | ||
| 719 | |||
| 720 | switch (be32_to_cpu(gc->len)) { | ||
| 721 | case 0x1c: | ||
| 722 | SD(sh)->EATA_revision = 'a'; | ||
| 723 | break; | ||
| 724 | case 0x1e: | ||
| 725 | SD(sh)->EATA_revision = 'b'; | ||
| 726 | break; | ||
| 727 | case 0x22: | ||
| 728 | SD(sh)->EATA_revision = 'c'; | ||
| 729 | break; | ||
| 730 | case 0x24: | ||
| 731 | SD(sh)->EATA_revision = 'z'; | ||
| 732 | break; | ||
| 733 | default: | ||
| 734 | SD(sh)->EATA_revision = '?'; | ||
| 735 | } | ||
| 736 | |||
| 737 | if (be32_to_cpu(gc->len) >= 0x22) { | ||
| 738 | if (gc->is_PCI) | ||
| 739 | hd->bustype = IS_PCI; | ||
| 740 | else if (gc->is_EISA) | ||
| 741 | hd->bustype = IS_EISA; | ||
| 742 | else | ||
| 743 | hd->bustype = IS_ISA; | ||
| 744 | } else { | ||
| 745 | if (buff[21] == '4') | ||
| 746 | hd->bustype = IS_PCI; | ||
| 747 | else if (buff[21] == '2') | ||
| 748 | hd->bustype = IS_EISA; | ||
| 749 | else | ||
| 750 | hd->bustype = IS_ISA; | ||
| 751 | } | ||
| 752 | |||
| 753 | SD(sh)->cplen = cplen; | ||
| 754 | SD(sh)->cppadlen = cppadlen; | ||
| 755 | SD(sh)->hostid = gc->scsi_id[3]; | ||
| 756 | SD(sh)->devflags = 1 << gc->scsi_id[3]; | ||
| 757 | SD(sh)->moresupport = gc->MORE_support; | ||
| 758 | sh->unique_id = base; | ||
| 759 | sh->base = base; | ||
| 760 | sh->io_port = base; | ||
| 761 | sh->n_io_port = 9; | ||
| 762 | sh->irq = gc->IRQ; | ||
| 763 | sh->dma_channel = PIO; | ||
| 764 | sh->this_id = gc->scsi_id[3]; | ||
| 765 | sh->can_queue = 1; | ||
| 766 | sh->cmd_per_lun = 1; | ||
| 767 | sh->sg_tablesize = SG_ALL; | ||
| 768 | |||
| 769 | hd->channel = 0; | ||
| 770 | |||
| 771 | hd->pdev = pci_dev_get(pdev); /* Keep a PCI reference */ | ||
| 772 | |||
| 773 | sh->max_id = 8; | ||
| 774 | sh->max_lun = 8; | ||
| 775 | |||
| 776 | if (gc->SECOND) | ||
| 777 | hd->primary = 0; | ||
| 778 | else | ||
| 779 | hd->primary = 1; | ||
| 780 | |||
| 781 | hd->next = NULL; /* build a linked list of all HBAs */ | ||
| 782 | hd->prev = last_HBA; | ||
| 783 | if (hd->prev != NULL) | ||
| 784 | SD(hd->prev)->next = sh; | ||
| 785 | last_HBA = sh; | ||
| 786 | if (first_HBA == NULL) | ||
| 787 | first_HBA = sh; | ||
| 788 | registered_HBAs++; | ||
| 789 | return (1); | ||
| 790 | } | ||
| 791 | |||
| 792 | static void find_pio_ISA(struct get_conf *buf) | ||
| 793 | { | ||
| 794 | int i; | ||
| 795 | |||
| 796 | for (i = 0; i < MAXISA; i++) { | ||
| 797 | if (!ISAbases[i]) | ||
| 798 | continue; | ||
| 799 | if (!get_pio_conf_PIO(ISAbases[i], buf)) | ||
| 800 | continue; | ||
| 801 | if (!register_pio_HBA(ISAbases[i], buf, NULL)) | ||
| 802 | release_region(ISAbases[i], 9); | ||
| 803 | else | ||
| 804 | ISAbases[i] = 0; | ||
| 805 | } | ||
| 806 | return; | ||
| 807 | } | ||
| 808 | |||
| 809 | static void find_pio_EISA(struct get_conf *buf) | ||
| 810 | { | ||
| 811 | u32 base; | ||
| 812 | int i; | ||
| 813 | |||
| 814 | #ifdef CHECKPAL | ||
| 815 | u8 pal1, pal2, pal3; | ||
| 816 | #endif | ||
| 817 | |||
| 818 | for (i = 0; i < MAXEISA; i++) { | ||
| 819 | if (EISAbases[i]) { /* Still a possibility ? */ | ||
| 820 | |||
| 821 | base = 0x1c88 + (i * 0x1000); | ||
| 822 | #ifdef CHECKPAL | ||
| 823 | pal1 = inb((u16) base - 8); | ||
| 824 | pal2 = inb((u16) base - 7); | ||
| 825 | pal3 = inb((u16) base - 6); | ||
| 826 | |||
| 827 | if (((pal1 == 0x12) && (pal2 == 0x14)) || ((pal1 == 0x38) && (pal2 == 0xa3) && (pal3 == 0x82)) || ((pal1 == 0x06) && (pal2 == 0x94) && (pal3 == 0x24))) { | ||
| 828 | DBG(DBG_PROBE, printk(KERN_NOTICE "EISA EATA id tags found: " "%x %x %x \n", (int) pal1, (int) pal2, (int) pal3)); | ||
| 829 | #endif | ||
| 830 | if (get_pio_conf_PIO(base, buf)) { | ||
| 831 | DBG(DBG_PROBE && DBG_EISA, print_pio_config(buf)); | ||
| 832 | if (buf->IRQ) { | ||
| 833 | if (!register_pio_HBA(base, buf, NULL)) | ||
| 834 | release_region(base, 9); | ||
| 835 | } else { | ||
| 836 | printk(KERN_NOTICE "eata_dma: No valid IRQ. HBA " "removed from list\n"); | ||
| 837 | release_region(base, 9); | ||
| 838 | } | ||
| 839 | } | ||
| 840 | /* Nothing found here so we take it from the list */ | ||
| 841 | EISAbases[i] = 0; | ||
| 842 | #ifdef CHECKPAL | ||
| 843 | } | ||
| 844 | #endif | ||
| 845 | } | ||
| 846 | } | ||
| 847 | return; | ||
| 848 | } | ||
| 849 | |||
| 850 | static void find_pio_PCI(struct get_conf *buf) | ||
| 851 | { | ||
| 852 | #ifndef CONFIG_PCI | ||
| 853 | printk("eata_dma: kernel PCI support not enabled. Skipping scan for PCI HBAs.\n"); | ||
| 854 | #else | ||
| 855 | struct pci_dev *dev = NULL; | ||
| 856 | unsigned long base, x; | ||
| 857 | |||
| 858 | while ((dev = pci_get_device(PCI_VENDOR_ID_DPT, PCI_DEVICE_ID_DPT, dev)) != NULL) { | ||
| 859 | DBG(DBG_PROBE && DBG_PCI, printk("eata_pio: find_PCI, HBA at %s\n", pci_name(dev))); | ||
| 860 | if (pci_enable_device(dev)) | ||
| 861 | continue; | ||
| 862 | pci_set_master(dev); | ||
| 863 | base = pci_resource_flags(dev, 0); | ||
| 864 | if (base & IORESOURCE_MEM) { | ||
| 865 | printk("eata_pio: invalid base address of device %s\n", pci_name(dev)); | ||
| 866 | continue; | ||
| 867 | } | ||
| 868 | base = pci_resource_start(dev, 0); | ||
| 869 | /* EISA tag there ? */ | ||
| 870 | if ((inb(base) == 0x12) && (inb(base + 1) == 0x14)) | ||
| 871 | continue; /* Jep, it's forced, so move on */ | ||
| 872 | base += 0x10; /* Now, THIS is the real address */ | ||
| 873 | if (base != 0x1f8) { | ||
| 874 | /* We didn't find it in the primary search */ | ||
| 875 | if (get_pio_conf_PIO(base, buf)) { | ||
| 876 | if (buf->FORCADR) { /* If the address is forced */ | ||
| 877 | release_region(base, 9); | ||
| 878 | continue; /* we'll find it later */ | ||
| 879 | } | ||
| 880 | |||
| 881 | /* OK. We made it till here, so we can go now | ||
| 882 | * and register it. We only have to check and | ||
| 883 | * eventually remove it from the EISA and ISA list | ||
| 884 | */ | ||
| 885 | |||
| 886 | if (!register_pio_HBA(base, buf, dev)) { | ||
| 887 | release_region(base, 9); | ||
| 888 | continue; | ||
| 889 | } | ||
| 890 | |||
| 891 | if (base < 0x1000) { | ||
| 892 | for (x = 0; x < MAXISA; ++x) { | ||
| 893 | if (ISAbases[x] == base) { | ||
| 894 | ISAbases[x] = 0; | ||
| 895 | break; | ||
| 896 | } | ||
| 897 | } | ||
| 898 | } else if ((base & 0x0fff) == 0x0c88) { | ||
| 899 | x = (base >> 12) & 0x0f; | ||
| 900 | EISAbases[x] = 0; | ||
| 901 | } | ||
| 902 | } | ||
| 903 | #ifdef CHECK_BLINK | ||
| 904 | else if (check_blink_state(base)) { | ||
| 905 | printk("eata_pio: HBA is in BLINK state.\n" "Consult your HBAs manual to correct this.\n"); | ||
| 906 | } | ||
| 907 | #endif | ||
| 908 | } | ||
| 909 | } | ||
| 910 | #endif /* #ifndef CONFIG_PCI */ | ||
| 911 | } | ||
| 912 | |||
| 913 | static int eata_pio_detect(struct scsi_host_template *tpnt) | ||
| 914 | { | ||
| 915 | struct Scsi_Host *HBA_ptr; | ||
| 916 | struct get_conf gc; | ||
| 917 | int i; | ||
| 918 | |||
| 919 | find_pio_PCI(&gc); | ||
| 920 | find_pio_EISA(&gc); | ||
| 921 | find_pio_ISA(&gc); | ||
| 922 | |||
| 923 | for (i = 0; i < MAXIRQ; i++) | ||
| 924 | if (reg_IRQ[i]) | ||
| 925 | request_irq(i, do_eata_pio_int_handler, 0, "EATA-PIO", NULL); | ||
| 926 | |||
| 927 | HBA_ptr = first_HBA; | ||
| 928 | |||
| 929 | if (registered_HBAs != 0) { | ||
| 930 | printk("EATA (Extended Attachment) PIO driver version: %d.%d%s\n" | ||
| 931 | "(c) 1993-95 Michael Neuffer, neuffer@goofy.zdv.uni-mainz.de\n" " Alfred Arnold, a.arnold@kfa-juelich.de\n" "This release only supports DASD devices (harddisks)\n", VER_MAJOR, VER_MINOR, VER_SUB); | ||
| 932 | |||
| 933 | printk("Registered HBAs:\n"); | ||
| 934 | printk("HBA no. Boardtype: Revis: EATA: Bus: BaseIO: IRQ: Ch: ID: Pr:" " QS: SG: CPL:\n"); | ||
| 935 | for (i = 1; i <= registered_HBAs; i++) { | ||
| 936 | printk("scsi%-2d: %.10s v%s 2.0%c %s %#.4lx %2d %d %d %c" | ||
| 937 | " %2d %2d %2d\n", | ||
| 938 | HBA_ptr->host_no, SD(HBA_ptr)->name, SD(HBA_ptr)->revision, | ||
| 939 | SD(HBA_ptr)->EATA_revision, (SD(HBA_ptr)->bustype == 'P') ? | ||
| 940 | "PCI " : (SD(HBA_ptr)->bustype == 'E') ? "EISA" : "ISA ", | ||
| 941 | HBA_ptr->base, HBA_ptr->irq, SD(HBA_ptr)->channel, HBA_ptr->this_id, | ||
| 942 | SD(HBA_ptr)->primary ? 'Y' : 'N', HBA_ptr->can_queue, | ||
| 943 | HBA_ptr->sg_tablesize, HBA_ptr->cmd_per_lun); | ||
| 944 | HBA_ptr = SD(HBA_ptr)->next; | ||
| 945 | } | ||
| 946 | } | ||
| 947 | return (registered_HBAs); | ||
| 948 | } | ||
| 949 | |||
| 950 | static struct scsi_host_template driver_template = { | ||
| 951 | .proc_name = "eata_pio", | ||
| 952 | .name = "EATA (Extended Attachment) PIO driver", | ||
| 953 | .show_info = eata_pio_show_info, | ||
| 954 | .detect = eata_pio_detect, | ||
| 955 | .release = eata_pio_release, | ||
| 956 | .queuecommand = eata_pio_queue, | ||
| 957 | .eh_abort_handler = eata_pio_abort, | ||
| 958 | .eh_host_reset_handler = eata_pio_host_reset, | ||
| 959 | .use_clustering = ENABLE_CLUSTERING, | ||
| 960 | }; | ||
| 961 | |||
| 962 | MODULE_AUTHOR("Michael Neuffer, Alfred Arnold"); | ||
| 963 | MODULE_DESCRIPTION("EATA SCSI PIO driver"); | ||
| 964 | MODULE_LICENSE("GPL"); | ||
| 965 | |||
| 966 | #include "scsi_module.c" | ||
diff --git a/drivers/scsi/eata_pio.h b/drivers/scsi/eata_pio.h deleted file mode 100644 index 5b5e3d13670b..000000000000 --- a/drivers/scsi/eata_pio.h +++ /dev/null | |||
| @@ -1,54 +0,0 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | /******************************************************** | ||
| 3 | * Header file for eata_pio.c Linux EATA-PIO SCSI driver * | ||
| 4 | * (c) 1993-96 Michael Neuffer * | ||
| 5 | ********************************************************* | ||
| 6 | * last change: 2002/11/02 * | ||
| 7 | ********************************************************/ | ||
| 8 | |||
| 9 | |||
| 10 | #ifndef _EATA_PIO_H | ||
| 11 | #define _EATA_PIO_H | ||
| 12 | |||
| 13 | #define VER_MAJOR 0 | ||
| 14 | #define VER_MINOR 0 | ||
| 15 | #define VER_SUB "1b" | ||
| 16 | |||
| 17 | /************************************************************************ | ||
| 18 | * Here you can switch parts of the code on and of * | ||
| 19 | ************************************************************************/ | ||
| 20 | |||
| 21 | #define VERBOSE_SETUP /* show startup screen of 2001 */ | ||
| 22 | #define ALLOW_DMA_BOARDS 1 | ||
| 23 | |||
| 24 | /************************************************************************ | ||
| 25 | * Debug options. * | ||
| 26 | * Enable DEBUG and whichever options you require. * | ||
| 27 | ************************************************************************/ | ||
| 28 | #define DEBUG_EATA 1 /* Enable debug code. */ | ||
| 29 | #define DPT_DEBUG 0 /* Bobs special */ | ||
| 30 | #define DBG_DELAY 0 /* Build in delays so debug messages can be | ||
| 31 | * be read before they vanish of the top of | ||
| 32 | * the screen! | ||
| 33 | */ | ||
| 34 | #define DBG_PROBE 0 /* Debug probe routines. */ | ||
| 35 | #define DBG_ISA 0 /* Trace ISA routines */ | ||
| 36 | #define DBG_EISA 0 /* Trace EISA routines */ | ||
| 37 | #define DBG_PCI 0 /* Trace PCI routines */ | ||
| 38 | #define DBG_PIO 0 /* Trace get_config_PIO */ | ||
| 39 | #define DBG_COM 0 /* Trace command call */ | ||
| 40 | #define DBG_QUEUE 0 /* Trace command queueing. */ | ||
| 41 | #define DBG_INTR 0 /* Trace interrupt service routine. */ | ||
| 42 | #define DBG_INTR2 0 /* Trace interrupt service routine. */ | ||
| 43 | #define DBG_PROC 0 /* Debug proc-fs related statistics */ | ||
| 44 | #define DBG_PROC_WRITE 0 | ||
| 45 | #define DBG_REGISTER 0 /* */ | ||
| 46 | #define DBG_ABNORM 1 /* Debug abnormal actions (reset, abort) */ | ||
| 47 | |||
| 48 | #if DEBUG_EATA | ||
| 49 | #define DBG(x, y) if ((x)) {y;} | ||
| 50 | #else | ||
| 51 | #define DBG(x, y) | ||
| 52 | #endif | ||
| 53 | |||
| 54 | #endif /* _EATA_PIO_H */ | ||
diff --git a/drivers/scsi/esas2r/esas2r.h b/drivers/scsi/esas2r/esas2r.h index 1da6407ee142..858c3b33db78 100644 --- a/drivers/scsi/esas2r/esas2r.h +++ b/drivers/scsi/esas2r/esas2r.h | |||
| @@ -962,7 +962,6 @@ struct esas2r_adapter { | |||
| 962 | * Function Declarations | 962 | * Function Declarations |
| 963 | * SCSI functions | 963 | * SCSI functions |
| 964 | */ | 964 | */ |
| 965 | int esas2r_release(struct Scsi_Host *); | ||
| 966 | const char *esas2r_info(struct Scsi_Host *); | 965 | const char *esas2r_info(struct Scsi_Host *); |
| 967 | int esas2r_write_params(struct esas2r_adapter *a, struct esas2r_request *rq, | 966 | int esas2r_write_params(struct esas2r_adapter *a, struct esas2r_request *rq, |
| 968 | struct esas2r_sas_nvram *data); | 967 | struct esas2r_sas_nvram *data); |
| @@ -984,7 +983,6 @@ int esas2r_target_reset(struct scsi_cmnd *cmd); | |||
| 984 | /* Internal functions */ | 983 | /* Internal functions */ |
| 985 | int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid, | 984 | int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid, |
| 986 | int index); | 985 | int index); |
| 987 | int esas2r_cleanup(struct Scsi_Host *host); | ||
| 988 | int esas2r_read_fw(struct esas2r_adapter *a, char *buf, long off, int count); | 986 | int esas2r_read_fw(struct esas2r_adapter *a, char *buf, long off, int count); |
| 989 | int esas2r_write_fw(struct esas2r_adapter *a, const char *buf, long off, | 987 | int esas2r_write_fw(struct esas2r_adapter *a, const char *buf, long off, |
| 990 | int count); | 988 | int count); |
diff --git a/drivers/scsi/esas2r/esas2r_init.c b/drivers/scsi/esas2r/esas2r_init.c index 5b14dd29b764..9dffcb28c9b7 100644 --- a/drivers/scsi/esas2r/esas2r_init.c +++ b/drivers/scsi/esas2r/esas2r_init.c | |||
| @@ -661,27 +661,6 @@ void esas2r_kill_adapter(int i) | |||
| 661 | } | 661 | } |
| 662 | } | 662 | } |
| 663 | 663 | ||
| 664 | int esas2r_cleanup(struct Scsi_Host *host) | ||
| 665 | { | ||
| 666 | struct esas2r_adapter *a; | ||
| 667 | int index; | ||
| 668 | |||
| 669 | if (host == NULL) { | ||
| 670 | int i; | ||
| 671 | |||
| 672 | esas2r_debug("esas2r_cleanup everything"); | ||
| 673 | for (i = 0; i < MAX_ADAPTERS; i++) | ||
| 674 | esas2r_kill_adapter(i); | ||
| 675 | return -1; | ||
| 676 | } | ||
| 677 | |||
| 678 | esas2r_debug("esas2r_cleanup called for host %p", host); | ||
| 679 | a = (struct esas2r_adapter *)host->hostdata; | ||
| 680 | index = a->index; | ||
| 681 | esas2r_kill_adapter(index); | ||
| 682 | return index; | ||
| 683 | } | ||
| 684 | |||
| 685 | int esas2r_suspend(struct pci_dev *pdev, pm_message_t state) | 664 | int esas2r_suspend(struct pci_dev *pdev, pm_message_t state) |
| 686 | { | 665 | { |
| 687 | struct Scsi_Host *host = pci_get_drvdata(pdev); | 666 | struct Scsi_Host *host = pci_get_drvdata(pdev); |
diff --git a/drivers/scsi/esas2r/esas2r_main.c b/drivers/scsi/esas2r/esas2r_main.c index 4eb14301a497..e07eac5be087 100644 --- a/drivers/scsi/esas2r/esas2r_main.c +++ b/drivers/scsi/esas2r/esas2r_main.c | |||
| @@ -235,7 +235,6 @@ static struct scsi_host_template driver_template = { | |||
| 235 | .module = THIS_MODULE, | 235 | .module = THIS_MODULE, |
| 236 | .show_info = esas2r_show_info, | 236 | .show_info = esas2r_show_info, |
| 237 | .name = ESAS2R_LONGNAME, | 237 | .name = ESAS2R_LONGNAME, |
| 238 | .release = esas2r_release, | ||
| 239 | .info = esas2r_info, | 238 | .info = esas2r_info, |
| 240 | .ioctl = esas2r_ioctl, | 239 | .ioctl = esas2r_ioctl, |
| 241 | .queuecommand = esas2r_queuecommand, | 240 | .queuecommand = esas2r_queuecommand, |
| @@ -520,44 +519,16 @@ static int esas2r_probe(struct pci_dev *pcid, | |||
| 520 | 519 | ||
| 521 | static void esas2r_remove(struct pci_dev *pdev) | 520 | static void esas2r_remove(struct pci_dev *pdev) |
| 522 | { | 521 | { |
| 523 | struct Scsi_Host *host; | 522 | struct Scsi_Host *host = pci_get_drvdata(pdev); |
| 524 | int index; | 523 | struct esas2r_adapter *a = (struct esas2r_adapter *)host->hostdata; |
| 525 | |||
| 526 | if (pdev == NULL) { | ||
| 527 | esas2r_log(ESAS2R_LOG_WARN, "esas2r_remove pdev==NULL"); | ||
| 528 | return; | ||
| 529 | } | ||
| 530 | |||
| 531 | host = pci_get_drvdata(pdev); | ||
| 532 | |||
| 533 | if (host == NULL) { | ||
| 534 | /* | ||
| 535 | * this can happen if pci_set_drvdata was already called | ||
| 536 | * to clear the host pointer. if this is the case, we | ||
| 537 | * are okay; this channel has already been cleaned up. | ||
| 538 | */ | ||
| 539 | |||
| 540 | return; | ||
| 541 | } | ||
| 542 | 524 | ||
| 543 | esas2r_log_dev(ESAS2R_LOG_INFO, &(pdev->dev), | 525 | esas2r_log_dev(ESAS2R_LOG_INFO, &(pdev->dev), |
| 544 | "esas2r_remove(%p) called; " | 526 | "esas2r_remove(%p) called; " |
| 545 | "host:%p", pdev, | 527 | "host:%p", pdev, |
| 546 | host); | 528 | host); |
| 547 | 529 | ||
| 548 | index = esas2r_cleanup(host); | 530 | esas2r_kill_adapter(a->index); |
| 549 | |||
| 550 | if (index < 0) | ||
| 551 | esas2r_log_dev(ESAS2R_LOG_WARN, &(pdev->dev), | ||
| 552 | "unknown host in %s", | ||
| 553 | __func__); | ||
| 554 | |||
| 555 | found_adapters--; | 531 | found_adapters--; |
| 556 | |||
| 557 | /* if this was the last adapter, clean up the rest of the driver */ | ||
| 558 | |||
| 559 | if (found_adapters == 0) | ||
| 560 | esas2r_cleanup(NULL); | ||
| 561 | } | 532 | } |
| 562 | 533 | ||
| 563 | static int __init esas2r_init(void) | 534 | static int __init esas2r_init(void) |
| @@ -638,30 +609,7 @@ static int __init esas2r_init(void) | |||
| 638 | for (i = 0; i < MAX_ADAPTERS; i++) | 609 | for (i = 0; i < MAX_ADAPTERS; i++) |
| 639 | esas2r_adapters[i] = NULL; | 610 | esas2r_adapters[i] = NULL; |
| 640 | 611 | ||
| 641 | /* initialize */ | 612 | return pci_register_driver(&esas2r_pci_driver); |
| 642 | |||
| 643 | driver_template.module = THIS_MODULE; | ||
| 644 | |||
| 645 | if (pci_register_driver(&esas2r_pci_driver) != 0) | ||
| 646 | esas2r_log(ESAS2R_LOG_CRIT, "pci_register_driver FAILED"); | ||
| 647 | else | ||
| 648 | esas2r_log(ESAS2R_LOG_INFO, "pci_register_driver() OK"); | ||
| 649 | |||
| 650 | if (!found_adapters) { | ||
| 651 | pci_unregister_driver(&esas2r_pci_driver); | ||
| 652 | esas2r_cleanup(NULL); | ||
| 653 | |||
| 654 | esas2r_log(ESAS2R_LOG_CRIT, | ||
| 655 | "driver will not be loaded because no ATTO " | ||
| 656 | "%s devices were found", | ||
| 657 | ESAS2R_DRVR_NAME); | ||
| 658 | return -1; | ||
| 659 | } else { | ||
| 660 | esas2r_log(ESAS2R_LOG_INFO, "found %d adapters", | ||
| 661 | found_adapters); | ||
| 662 | } | ||
| 663 | |||
| 664 | return 0; | ||
| 665 | } | 613 | } |
| 666 | 614 | ||
| 667 | /* Handle ioctl calls to "/proc/scsi/esas2r/ATTOnode" */ | 615 | /* Handle ioctl calls to "/proc/scsi/esas2r/ATTOnode" */ |
| @@ -753,18 +701,6 @@ int esas2r_show_info(struct seq_file *m, struct Scsi_Host *sh) | |||
| 753 | 701 | ||
| 754 | } | 702 | } |
| 755 | 703 | ||
| 756 | int esas2r_release(struct Scsi_Host *sh) | ||
| 757 | { | ||
| 758 | esas2r_log_dev(ESAS2R_LOG_INFO, &(sh->shost_gendev), | ||
| 759 | "esas2r_release() called"); | ||
| 760 | |||
| 761 | esas2r_cleanup(sh); | ||
| 762 | if (sh->irq) | ||
| 763 | free_irq(sh->irq, NULL); | ||
| 764 | scsi_unregister(sh); | ||
| 765 | return 0; | ||
| 766 | } | ||
| 767 | |||
| 768 | const char *esas2r_info(struct Scsi_Host *sh) | 704 | const char *esas2r_info(struct Scsi_Host *sh) |
| 769 | { | 705 | { |
| 770 | struct esas2r_adapter *a = (struct esas2r_adapter *)sh->hostdata; | 706 | struct esas2r_adapter *a = (struct esas2r_adapter *)sh->hostdata; |
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c deleted file mode 100644 index ebbe5a3e665d..000000000000 --- a/drivers/scsi/fdomain.c +++ /dev/null | |||
| @@ -1,1783 +0,0 @@ | |||
| 1 | /* fdomain.c -- Future Domain TMC-16x0 SCSI driver | ||
| 2 | * Created: Sun May 3 18:53:19 1992 by faith@cs.unc.edu | ||
| 3 | * Revised: Mon Dec 28 21:59:02 1998 by faith@acm.org | ||
| 4 | * Author: Rickard E. Faith, faith@cs.unc.edu | ||
| 5 | * Copyright 1992-1996, 1998 Rickard E. Faith (faith@acm.org) | ||
| 6 | * Shared IRQ supported added 7/7/2001 Alan Cox <alan@lxorguk.ukuu.org.uk> | ||
| 7 | |||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the | ||
| 10 | * Free Software Foundation; either version 2, or (at your option) any | ||
| 11 | * later version. | ||
| 12 | |||
| 13 | * This program is distributed in the hope that it will be useful, but | ||
| 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 16 | * General Public License for more details. | ||
| 17 | |||
| 18 | * You should have received a copy of the GNU General Public License along | ||
| 19 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 20 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 21 | |||
| 22 | ************************************************************************** | ||
| 23 | |||
| 24 | SUMMARY: | ||
| 25 | |||
| 26 | Future Domain BIOS versions supported for autodetect: | ||
| 27 | 2.0, 3.0, 3.2, 3.4 (1.0), 3.5 (2.0), 3.6, 3.61 | ||
| 28 | Chips are supported: | ||
| 29 | TMC-1800, TMC-18C50, TMC-18C30, TMC-36C70 | ||
| 30 | Boards supported: | ||
| 31 | Future Domain TMC-1650, TMC-1660, TMC-1670, TMC-1680, TMC-1610M/MER/MEX | ||
| 32 | Future Domain TMC-3260 (PCI) | ||
| 33 | Quantum ISA-200S, ISA-250MG | ||
| 34 | Adaptec AHA-2920A (PCI) [BUT *NOT* AHA-2920C -- use aic7xxx instead] | ||
| 35 | IBM ? | ||
| 36 | LILO/INSMOD command-line options: | ||
| 37 | fdomain=<PORT_BASE>,<IRQ>[,<ADAPTER_ID>] | ||
| 38 | |||
| 39 | |||
| 40 | |||
| 41 | NOTE: | ||
| 42 | |||
| 43 | The Adaptec AHA-2920C has an Adaptec AIC-7850 chip on it. | ||
| 44 | Use the aic7xxx driver for this board. | ||
| 45 | |||
| 46 | The Adaptec AHA-2920A has a Future Domain chip on it, so this is the right | ||
| 47 | driver for that card. Unfortunately, the boxes will probably just say | ||
| 48 | "2920", so you'll have to look on the card for a Future Domain logo, or a | ||
| 49 | letter after the 2920. | ||
| 50 | |||
| 51 | |||
| 52 | |||
| 53 | THANKS: | ||
| 54 | |||
| 55 | Thanks to Adaptec for providing PCI boards for testing. This finally | ||
| 56 | enabled me to test the PCI detection and correct it for PCI boards that do | ||
| 57 | not have a BIOS at a standard ISA location. For PCI boards, LILO/INSMOD | ||
| 58 | command-line options should no longer be needed. --RF 18Nov98 | ||
| 59 | |||
| 60 | |||
| 61 | |||
| 62 | DESCRIPTION: | ||
| 63 | |||
| 64 | This is the Linux low-level SCSI driver for Future Domain TMC-1660/1680 | ||
| 65 | TMC-1650/1670, and TMC-3260 SCSI host adapters. The 1650 and 1670 have a | ||
| 66 | 25-pin external connector, whereas the 1660 and 1680 have a SCSI-2 50-pin | ||
| 67 | high-density external connector. The 1670 and 1680 have floppy disk | ||
| 68 | controllers built in. The TMC-3260 is a PCI bus card. | ||
| 69 | |||
| 70 | Future Domain's older boards are based on the TMC-1800 chip, and this | ||
| 71 | driver was originally written for a TMC-1680 board with the TMC-1800 chip. | ||
| 72 | More recently, boards are being produced with the TMC-18C50 and TMC-18C30 | ||
| 73 | chips. The latest and greatest board may not work with this driver. If | ||
| 74 | you have to patch this driver so that it will recognize your board's BIOS | ||
| 75 | signature, then the driver may fail to function after the board is | ||
| 76 | detected. | ||
| 77 | |||
| 78 | Please note that the drive ordering that Future Domain implemented in BIOS | ||
| 79 | versions 3.4 and 3.5 is the opposite of the order (currently) used by the | ||
| 80 | rest of the SCSI industry. If you have BIOS version 3.4 or 3.5, and have | ||
| 81 | more than one drive, then the drive ordering will be the reverse of that | ||
| 82 | which you see under DOS. For example, under DOS SCSI ID 0 will be D: and | ||
| 83 | SCSI ID 1 will be C: (the boot device). Under Linux, SCSI ID 0 will be | ||
| 84 | /dev/sda and SCSI ID 1 will be /dev/sdb. The Linux ordering is consistent | ||
| 85 | with that provided by all the other SCSI drivers for Linux. If you want | ||
| 86 | this changed, you will probably have to patch the higher level SCSI code. | ||
| 87 | If you do so, please send me patches that are protected by #ifdefs. | ||
| 88 | |||
| 89 | If you have a TMC-8xx or TMC-9xx board, then this is not the driver for | ||
| 90 | your board. Please refer to the Seagate driver for more information and | ||
| 91 | possible support. | ||
| 92 | |||
| 93 | |||
| 94 | |||
| 95 | HISTORY: | ||
| 96 | |||
| 97 | Linux Driver Driver | ||
| 98 | Version Version Date Support/Notes | ||
| 99 | |||
| 100 | 0.0 3 May 1992 V2.0 BIOS; 1800 chip | ||
| 101 | 0.97 1.9 28 Jul 1992 | ||
| 102 | 0.98.6 3.1 27 Nov 1992 | ||
| 103 | 0.99 3.2 9 Dec 1992 | ||
| 104 | |||
| 105 | 0.99.3 3.3 10 Jan 1993 V3.0 BIOS | ||
| 106 | 0.99.5 3.5 18 Feb 1993 | ||
| 107 | 0.99.10 3.6 15 May 1993 V3.2 BIOS; 18C50 chip | ||
| 108 | 0.99.11 3.17 3 Jul 1993 (now under RCS) | ||
| 109 | 0.99.12 3.18 13 Aug 1993 | ||
| 110 | 0.99.14 5.6 31 Oct 1993 (reselection code removed) | ||
| 111 | |||
| 112 | 0.99.15 5.9 23 Jan 1994 V3.4 BIOS (preliminary) | ||
| 113 | 1.0.8/1.1.1 5.15 1 Apr 1994 V3.4 BIOS; 18C30 chip (preliminary) | ||
| 114 | 1.0.9/1.1.3 5.16 7 Apr 1994 V3.4 BIOS; 18C30 chip | ||
| 115 | 1.1.38 5.18 30 Jul 1994 36C70 chip (PCI version of 18C30) | ||
| 116 | 1.1.62 5.20 2 Nov 1994 V3.5 BIOS | ||
| 117 | 1.1.73 5.22 7 Dec 1994 Quantum ISA-200S board; V2.0 BIOS | ||
| 118 | |||
| 119 | 1.1.82 5.26 14 Jan 1995 V3.5 BIOS; TMC-1610M/MER/MEX board | ||
| 120 | 1.2.10 5.28 5 Jun 1995 Quantum ISA-250MG board; V2.0, V2.01 BIOS | ||
| 121 | 1.3.4 5.31 23 Jun 1995 PCI BIOS-32 detection (preliminary) | ||
| 122 | 1.3.7 5.33 4 Jul 1995 PCI BIOS-32 detection | ||
| 123 | 1.3.28 5.36 17 Sep 1995 V3.61 BIOS; LILO command-line support | ||
| 124 | 1.3.34 5.39 12 Oct 1995 V3.60 BIOS; /proc | ||
| 125 | 1.3.72 5.39 8 Feb 1996 Adaptec AHA-2920 board | ||
| 126 | 1.3.85 5.41 4 Apr 1996 | ||
| 127 | 2.0.12 5.44 8 Aug 1996 Use ID 7 for all PCI cards | ||
| 128 | 2.1.1 5.45 2 Oct 1996 Update ROM accesses for 2.1.x | ||
| 129 | 2.1.97 5.46 23 Apr 1998 Rewritten PCI detection routines [mj] | ||
| 130 | 2.1.11x 5.47 9 Aug 1998 Touched for 8 SCSI disk majors support | ||
| 131 | 5.48 18 Nov 1998 BIOS no longer needed for PCI detection | ||
| 132 | 2.2.0 5.50 28 Dec 1998 Support insmod parameters | ||
| 133 | |||
| 134 | |||
| 135 | REFERENCES USED: | ||
| 136 | |||
| 137 | "TMC-1800 SCSI Chip Specification (FDC-1800T)", Future Domain Corporation, | ||
| 138 | 1990. | ||
| 139 | |||
| 140 | "Technical Reference Manual: 18C50 SCSI Host Adapter Chip", Future Domain | ||
| 141 | Corporation, January 1992. | ||
| 142 | |||
| 143 | "LXT SCSI Products: Specifications and OEM Technical Manual (Revision | ||
| 144 | B/September 1991)", Maxtor Corporation, 1991. | ||
| 145 | |||
| 146 | "7213S product Manual (Revision P3)", Maxtor Corporation, 1992. | ||
| 147 | |||
| 148 | "Draft Proposed American National Standard: Small Computer System | ||
| 149 | Interface - 2 (SCSI-2)", Global Engineering Documents. (X3T9.2/86-109, | ||
| 150 | revision 10h, October 17, 1991) | ||
| 151 | |||
| 152 | Private communications, Drew Eckhardt (drew@cs.colorado.edu) and Eric | ||
| 153 | Youngdale (ericy@cais.com), 1992. | ||
| 154 | |||
| 155 | Private communication, Tuong Le (Future Domain Engineering department), | ||
| 156 | 1994. (Disk geometry computations for Future Domain BIOS version 3.4, and | ||
| 157 | TMC-18C30 detection.) | ||
| 158 | |||
| 159 | Hogan, Thom. The Programmer's PC Sourcebook. Microsoft Press, 1988. Page | ||
| 160 | 60 (2.39: Disk Partition Table Layout). | ||
| 161 | |||
| 162 | "18C30 Technical Reference Manual", Future Domain Corporation, 1993, page | ||
| 163 | 6-1. | ||
| 164 | |||
| 165 | |||
| 166 | |||
| 167 | NOTES ON REFERENCES: | ||
| 168 | |||
| 169 | The Maxtor manuals were free. Maxtor telephone technical support is | ||
| 170 | great! | ||
| 171 | |||
| 172 | The Future Domain manuals were $25 and $35. They document the chip, not | ||
| 173 | the TMC-16x0 boards, so some information I had to guess at. In 1992, | ||
| 174 | Future Domain sold DOS BIOS source for $250 and the UN*X driver source was | ||
| 175 | $750, but these required a non-disclosure agreement, so even if I could | ||
| 176 | have afforded them, they would *not* have been useful for writing this | ||
| 177 | publicly distributable driver. Future Domain technical support has | ||
| 178 | provided some information on the phone and have sent a few useful FAXs. | ||
| 179 | They have been much more helpful since they started to recognize that the | ||
| 180 | word "Linux" refers to an operating system :-). | ||
| 181 | |||
| 182 | |||
| 183 | |||
| 184 | ALPHA TESTERS: | ||
| 185 | |||
| 186 | There are many other alpha testers that come and go as the driver | ||
| 187 | develops. The people listed here were most helpful in times of greatest | ||
| 188 | need (mostly early on -- I've probably left out a few worthy people in | ||
| 189 | more recent times): | ||
| 190 | |||
| 191 | Todd Carrico (todd@wutc.wustl.edu), Dan Poirier (poirier@cs.unc.edu ), Ken | ||
| 192 | Corey (kenc@sol.acs.unt.edu), C. de Bruin (bruin@bruin@sterbbs.nl), Sakari | ||
| 193 | Aaltonen (sakaria@vipunen.hit.fi), John Rice (rice@xanth.cs.odu.edu), Brad | ||
| 194 | Yearwood (brad@optilink.com), and Ray Toy (toy@soho.crd.ge.com). | ||
| 195 | |||
| 196 | Special thanks to Tien-Wan Yang (twyang@cs.uh.edu), who graciously lent me | ||
| 197 | his 18C50-based card for debugging. He is the sole reason that this | ||
| 198 | driver works with the 18C50 chip. | ||
| 199 | |||
| 200 | Thanks to Dave Newman (dnewman@crl.com) for providing initial patches for | ||
| 201 | the version 3.4 BIOS. | ||
| 202 | |||
| 203 | Thanks to James T. McKinley (mckinley@msupa.pa.msu.edu) for providing | ||
| 204 | patches that support the TMC-3260, a PCI bus card with the 36C70 chip. | ||
| 205 | The 36C70 chip appears to be "completely compatible" with the 18C30 chip. | ||
| 206 | |||
| 207 | Thanks to Eric Kasten (tigger@petroglyph.cl.msu.edu) for providing the | ||
| 208 | patch for the version 3.5 BIOS. | ||
| 209 | |||
| 210 | Thanks for Stephen Henson (shenson@nyx10.cs.du.edu) for providing the | ||
| 211 | patch for the Quantum ISA-200S SCSI adapter. | ||
| 212 | |||
| 213 | Thanks to Adam Bowen for the signature to the 1610M/MER/MEX scsi cards, to | ||
| 214 | Martin Andrews (andrewm@ccfadm.eeg.ccf.org) for the signature to some | ||
| 215 | random TMC-1680 repackaged by IBM; and to Mintak Ng (mintak@panix.com) for | ||
| 216 | the version 3.61 BIOS signature. | ||
| 217 | |||
| 218 | Thanks for Mark Singer (elf@netcom.com) and Richard Simpson | ||
| 219 | (rsimpson@ewrcsdra.demon.co.uk) for more Quantum signatures and detective | ||
| 220 | work on the Quantum RAM layout. | ||
| 221 | |||
| 222 | Special thanks to James T. McKinley (mckinley@msupa.pa.msu.edu) for | ||
| 223 | providing patches for proper PCI BIOS32-mediated detection of the TMC-3260 | ||
| 224 | card (a PCI bus card with the 36C70 chip). Please send James PCI-related | ||
| 225 | bug reports. | ||
| 226 | |||
| 227 | Thanks to Tom Cavin (tec@usa1.com) for preliminary command-line option | ||
| 228 | patches. | ||
| 229 | |||
| 230 | New PCI detection code written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> | ||
| 231 | |||
| 232 | Insmod parameter code based on patches from Daniel Graham | ||
| 233 | <graham@balance.uoregon.edu>. | ||
| 234 | |||
| 235 | All of the alpha testers deserve much thanks. | ||
| 236 | |||
| 237 | |||
| 238 | |||
| 239 | NOTES ON USER DEFINABLE OPTIONS: | ||
| 240 | |||
| 241 | DEBUG: This turns on the printing of various debug information. | ||
| 242 | |||
| 243 | ENABLE_PARITY: This turns on SCSI parity checking. With the current | ||
| 244 | driver, all attached devices must support SCSI parity. If none of your | ||
| 245 | devices support parity, then you can probably get the driver to work by | ||
| 246 | turning this option off. I have no way of testing this, however, and it | ||
| 247 | would appear that no one ever uses this option. | ||
| 248 | |||
| 249 | FIFO_COUNT: The host adapter has an 8K cache (host adapters based on the | ||
| 250 | 18C30 chip have a 2k cache). When this many 512 byte blocks are filled by | ||
| 251 | the SCSI device, an interrupt will be raised. Therefore, this could be as | ||
| 252 | low as 0, or as high as 16. Note, however, that values which are too high | ||
| 253 | or too low seem to prevent any interrupts from occurring, and thereby lock | ||
| 254 | up the machine. I have found that 2 is a good number, but throughput may | ||
| 255 | be increased by changing this value to values which are close to 2. | ||
| 256 | Please let me know if you try any different values. | ||
| 257 | |||
| 258 | RESELECTION: This is no longer an option, since I gave up trying to | ||
| 259 | implement it in version 4.x of this driver. It did not improve | ||
| 260 | performance at all and made the driver unstable (because I never found one | ||
| 261 | of the two race conditions which were introduced by the multiple | ||
| 262 | outstanding command code). The instability seems a very high price to pay | ||
| 263 | just so that you don't have to wait for the tape to rewind. If you want | ||
| 264 | this feature implemented, send me patches. I'll be happy to send a copy | ||
| 265 | of my (broken) driver to anyone who would like to see a copy. | ||
| 266 | |||
| 267 | **************************************************************************/ | ||
| 268 | |||
| 269 | #include <linux/module.h> | ||
| 270 | #include <linux/init.h> | ||
| 271 | #include <linux/interrupt.h> | ||
| 272 | #include <linux/blkdev.h> | ||
| 273 | #include <linux/spinlock.h> | ||
| 274 | #include <linux/errno.h> | ||
| 275 | #include <linux/string.h> | ||
| 276 | #include <linux/ioport.h> | ||
| 277 | #include <linux/proc_fs.h> | ||
| 278 | #include <linux/pci.h> | ||
| 279 | #include <linux/stat.h> | ||
| 280 | #include <linux/delay.h> | ||
| 281 | #include <linux/io.h> | ||
| 282 | #include <linux/slab.h> | ||
| 283 | #include <scsi/scsicam.h> | ||
| 284 | |||
| 285 | |||
| 286 | #include <scsi/scsi.h> | ||
| 287 | #include <scsi/scsi_cmnd.h> | ||
| 288 | #include <scsi/scsi_device.h> | ||
| 289 | #include <scsi/scsi_host.h> | ||
| 290 | #include <scsi/scsi_ioctl.h> | ||
| 291 | #include "fdomain.h" | ||
| 292 | |||
| 293 | #ifndef PCMCIA | ||
| 294 | MODULE_AUTHOR("Rickard E. Faith"); | ||
| 295 | MODULE_DESCRIPTION("Future domain SCSI driver"); | ||
| 296 | MODULE_LICENSE("GPL"); | ||
| 297 | #endif | ||
| 298 | |||
| 299 | |||
| 300 | #define VERSION "$Revision: 5.51 $" | ||
| 301 | |||
| 302 | /* START OF USER DEFINABLE OPTIONS */ | ||
| 303 | |||
| 304 | #define DEBUG 0 /* Enable debugging output */ | ||
| 305 | #define ENABLE_PARITY 1 /* Enable SCSI Parity */ | ||
| 306 | #define FIFO_COUNT 2 /* Number of 512 byte blocks before INTR */ | ||
| 307 | |||
| 308 | /* END OF USER DEFINABLE OPTIONS */ | ||
| 309 | |||
| 310 | #if DEBUG | ||
| 311 | #define EVERY_ACCESS 0 /* Write a line on every scsi access */ | ||
| 312 | #define ERRORS_ONLY 1 /* Only write a line if there is an error */ | ||
| 313 | #define DEBUG_DETECT 0 /* Debug fdomain_16x0_detect() */ | ||
| 314 | #define DEBUG_MESSAGES 1 /* Debug MESSAGE IN phase */ | ||
| 315 | #define DEBUG_ABORT 1 /* Debug abort() routine */ | ||
| 316 | #define DEBUG_RESET 1 /* Debug reset() routine */ | ||
| 317 | #define DEBUG_RACE 1 /* Debug interrupt-driven race condition */ | ||
| 318 | #else | ||
| 319 | #define EVERY_ACCESS 0 /* LEAVE THESE ALONE--CHANGE THE ONES ABOVE */ | ||
| 320 | #define ERRORS_ONLY 0 | ||
| 321 | #define DEBUG_DETECT 0 | ||
| 322 | #define DEBUG_MESSAGES 0 | ||
| 323 | #define DEBUG_ABORT 0 | ||
| 324 | #define DEBUG_RESET 0 | ||
| 325 | #define DEBUG_RACE 0 | ||
| 326 | #endif | ||
| 327 | |||
| 328 | /* Errors are reported on the line, so we don't need to report them again */ | ||
| 329 | #if EVERY_ACCESS | ||
| 330 | #undef ERRORS_ONLY | ||
| 331 | #define ERRORS_ONLY 0 | ||
| 332 | #endif | ||
| 333 | |||
| 334 | #if ENABLE_PARITY | ||
| 335 | #define PARITY_MASK 0x08 | ||
| 336 | #else | ||
| 337 | #define PARITY_MASK 0x00 | ||
| 338 | #endif | ||
| 339 | |||
| 340 | enum chip_type { | ||
| 341 | unknown = 0x00, | ||
| 342 | tmc1800 = 0x01, | ||
| 343 | tmc18c50 = 0x02, | ||
| 344 | tmc18c30 = 0x03, | ||
| 345 | }; | ||
| 346 | |||
| 347 | enum { | ||
| 348 | in_arbitration = 0x02, | ||
| 349 | in_selection = 0x04, | ||
| 350 | in_other = 0x08, | ||
| 351 | disconnect = 0x10, | ||
| 352 | aborted = 0x20, | ||
| 353 | sent_ident = 0x40, | ||
| 354 | }; | ||
| 355 | |||
| 356 | enum in_port_type { | ||
| 357 | Read_SCSI_Data = 0, | ||
| 358 | SCSI_Status = 1, | ||
| 359 | TMC_Status = 2, | ||
| 360 | FIFO_Status = 3, /* tmc18c50/tmc18c30 only */ | ||
| 361 | Interrupt_Cond = 4, /* tmc18c50/tmc18c30 only */ | ||
| 362 | LSB_ID_Code = 5, | ||
| 363 | MSB_ID_Code = 6, | ||
| 364 | Read_Loopback = 7, | ||
| 365 | SCSI_Data_NoACK = 8, | ||
| 366 | Interrupt_Status = 9, | ||
| 367 | Configuration1 = 10, | ||
| 368 | Configuration2 = 11, /* tmc18c50/tmc18c30 only */ | ||
| 369 | Read_FIFO = 12, | ||
| 370 | FIFO_Data_Count = 14 | ||
| 371 | }; | ||
| 372 | |||
| 373 | enum out_port_type { | ||
| 374 | Write_SCSI_Data = 0, | ||
| 375 | SCSI_Cntl = 1, | ||
| 376 | Interrupt_Cntl = 2, | ||
| 377 | SCSI_Mode_Cntl = 3, | ||
| 378 | TMC_Cntl = 4, | ||
| 379 | Memory_Cntl = 5, /* tmc18c50/tmc18c30 only */ | ||
| 380 | Write_Loopback = 7, | ||
| 381 | IO_Control = 11, /* tmc18c30 only */ | ||
| 382 | Write_FIFO = 12 | ||
| 383 | }; | ||
| 384 | |||
| 385 | /* .bss will zero all the static variables below */ | ||
| 386 | static int port_base; | ||
| 387 | static unsigned long bios_base; | ||
| 388 | static void __iomem * bios_mem; | ||
| 389 | static int bios_major; | ||
| 390 | static int bios_minor; | ||
| 391 | static int PCI_bus; | ||
| 392 | #ifdef CONFIG_PCI | ||
| 393 | static struct pci_dev *PCI_dev; | ||
| 394 | #endif | ||
| 395 | static int Quantum; /* Quantum board variant */ | ||
| 396 | static int interrupt_level; | ||
| 397 | static volatile int in_command; | ||
| 398 | static struct scsi_cmnd *current_SC; | ||
| 399 | static enum chip_type chip = unknown; | ||
| 400 | static int adapter_mask; | ||
| 401 | static int this_id; | ||
| 402 | static int setup_called; | ||
| 403 | |||
| 404 | #if DEBUG_RACE | ||
| 405 | static volatile int in_interrupt_flag; | ||
| 406 | #endif | ||
| 407 | |||
| 408 | static int FIFO_Size = 0x2000; /* 8k FIFO for | ||
| 409 | pre-tmc18c30 chips */ | ||
| 410 | |||
| 411 | static irqreturn_t do_fdomain_16x0_intr( int irq, void *dev_id ); | ||
| 412 | /* Allow insmod parameters to be like LILO parameters. For example: | ||
| 413 | insmod fdomain fdomain=0x140,11 */ | ||
| 414 | static char * fdomain = NULL; | ||
| 415 | module_param(fdomain, charp, 0); | ||
| 416 | |||
| 417 | #ifndef PCMCIA | ||
| 418 | |||
| 419 | static unsigned long addresses[] = { | ||
| 420 | 0xc8000, | ||
| 421 | 0xca000, | ||
| 422 | 0xce000, | ||
| 423 | 0xde000, | ||
| 424 | 0xcc000, /* Extra addresses for PCI boards */ | ||
| 425 | 0xd0000, | ||
| 426 | 0xe0000, | ||
| 427 | }; | ||
| 428 | #define ADDRESS_COUNT ARRAY_SIZE(addresses) | ||
| 429 | |||
| 430 | static unsigned short ports[] = { 0x140, 0x150, 0x160, 0x170 }; | ||
| 431 | #define PORT_COUNT ARRAY_SIZE(ports) | ||
| 432 | |||
| 433 | static unsigned short ints[] = { 3, 5, 10, 11, 12, 14, 15, 0 }; | ||
| 434 | |||
| 435 | #endif /* !PCMCIA */ | ||
| 436 | |||
| 437 | /* | ||
| 438 | |||
| 439 | READ THIS BEFORE YOU ADD A SIGNATURE! | ||
| 440 | |||
| 441 | READING THIS SHORT NOTE CAN SAVE YOU LOTS OF TIME! | ||
| 442 | |||
| 443 | READ EVERY WORD, ESPECIALLY THE WORD *NOT* | ||
| 444 | |||
| 445 | This driver works *ONLY* for Future Domain cards using the TMC-1800, | ||
| 446 | TMC-18C50, or TMC-18C30 chip. This includes models TMC-1650, 1660, 1670, | ||
| 447 | and 1680. These are all 16-bit cards. | ||
| 448 | |||
| 449 | The following BIOS signature signatures are for boards which do *NOT* | ||
| 450 | work with this driver (these TMC-8xx and TMC-9xx boards may work with the | ||
| 451 | Seagate driver): | ||
| 452 | |||
| 453 | FUTURE DOMAIN CORP. (C) 1986-1988 V4.0I 03/16/88 | ||
| 454 | FUTURE DOMAIN CORP. (C) 1986-1989 V5.0C2/14/89 | ||
| 455 | FUTURE DOMAIN CORP. (C) 1986-1989 V6.0A7/28/89 | ||
| 456 | FUTURE DOMAIN CORP. (C) 1986-1990 V6.0105/31/90 | ||
| 457 | FUTURE DOMAIN CORP. (C) 1986-1990 V6.0209/18/90 | ||
| 458 | FUTURE DOMAIN CORP. (C) 1986-1990 V7.009/18/90 | ||
| 459 | FUTURE DOMAIN CORP. (C) 1992 V8.00.004/02/92 | ||
| 460 | |||
| 461 | (The cards which do *NOT* work are all 8-bit cards -- although some of | ||
| 462 | them have a 16-bit form-factor, the upper 8-bits are used only for IRQs | ||
| 463 | and are *NOT* used for data. You can tell the difference by following | ||
| 464 | the tracings on the circuit board -- if only the IRQ lines are involved, | ||
| 465 | you have a "8-bit" card, and should *NOT* use this driver.) | ||
| 466 | |||
| 467 | */ | ||
| 468 | |||
| 469 | #ifndef PCMCIA | ||
| 470 | |||
| 471 | static struct signature { | ||
| 472 | const char *signature; | ||
| 473 | int sig_offset; | ||
| 474 | int sig_length; | ||
| 475 | int major_bios_version; | ||
| 476 | int minor_bios_version; | ||
| 477 | int flag; /* 1 == PCI_bus, 2 == ISA_200S, 3 == ISA_250MG, 4 == ISA_200S */ | ||
| 478 | } signatures[] = { | ||
| 479 | /* 1 2 3 4 5 6 */ | ||
| 480 | /* 123456789012345678901234567890123456789012345678901234567890 */ | ||
| 481 | { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 5, 50, 2, 0, 0 }, | ||
| 482 | { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V1.07/28/89", 5, 50, 2, 0, 0 }, | ||
| 483 | { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.07/28/89", 72, 50, 2, 0, 2 }, | ||
| 484 | { "FUTURE DOMAIN CORP. (C) 1986-1990 1800-V2.0", 73, 43, 2, 0, 3 }, | ||
| 485 | { "FUTURE DOMAIN CORP. (C) 1991 1800-V2.0.", 72, 39, 2, 0, 4 }, | ||
| 486 | { "FUTURE DOMAIN CORP. (C) 1992 V3.00.004/02/92", 5, 44, 3, 0, 0 }, | ||
| 487 | { "FUTURE DOMAIN TMC-18XX (C) 1993 V3.203/12/93", 5, 44, 3, 2, 0 }, | ||
| 488 | { "IBM F1 P2 BIOS v1.0104/29/93", 5, 28, 3, -1, 0 }, | ||
| 489 | { "Future Domain Corp. V1.0008/18/93", 5, 33, 3, 4, 0 }, | ||
| 490 | { "Future Domain Corp. V1.0008/18/93", 26, 33, 3, 4, 1 }, | ||
| 491 | { "Adaptec AHA-2920 PCI-SCSI Card", 42, 31, 3, -1, 1 }, | ||
| 492 | { "IBM F1 P264/32", 5, 14, 3, -1, 1 }, | ||
| 493 | /* This next signature may not be a 3.5 bios */ | ||
| 494 | { "Future Domain Corp. V2.0108/18/93", 5, 33, 3, 5, 0 }, | ||
| 495 | { "FUTURE DOMAIN CORP. V3.5008/18/93", 5, 34, 3, 5, 0 }, | ||
| 496 | { "FUTURE DOMAIN 18c30/18c50/1800 (C) 1994 V3.5", 5, 44, 3, 5, 0 }, | ||
| 497 | { "FUTURE DOMAIN CORP. V3.6008/18/93", 5, 34, 3, 6, 0 }, | ||
| 498 | { "FUTURE DOMAIN CORP. V3.6108/18/93", 5, 34, 3, 6, 0 }, | ||
| 499 | { "FUTURE DOMAIN TMC-18XX", 5, 22, -1, -1, 0 }, | ||
| 500 | |||
| 501 | /* READ NOTICE ABOVE *BEFORE* YOU WASTE YOUR TIME ADDING A SIGNATURE | ||
| 502 | Also, fix the disk geometry code for your signature and send your | ||
| 503 | changes for faith@cs.unc.edu. Above all, do *NOT* change any old | ||
| 504 | signatures! | ||
| 505 | |||
| 506 | Note that the last line will match a "generic" 18XX bios. Because | ||
| 507 | Future Domain has changed the host SCSI ID and/or the location of the | ||
| 508 | geometry information in the on-board RAM area for each of the first | ||
| 509 | three BIOS's, it is still important to enter a fully qualified | ||
| 510 | signature in the table for any new BIOS's (after the host SCSI ID and | ||
| 511 | geometry location are verified). */ | ||
| 512 | }; | ||
| 513 | |||
| 514 | #define SIGNATURE_COUNT ARRAY_SIZE(signatures) | ||
| 515 | |||
| 516 | #endif /* !PCMCIA */ | ||
| 517 | |||
| 518 | static void print_banner( struct Scsi_Host *shpnt ) | ||
| 519 | { | ||
| 520 | if (!shpnt) return; /* This won't ever happen */ | ||
| 521 | |||
| 522 | if (bios_major < 0 && bios_minor < 0) { | ||
| 523 | printk(KERN_INFO "scsi%d: <fdomain> No BIOS; using scsi id %d\n", | ||
| 524 | shpnt->host_no, shpnt->this_id); | ||
| 525 | } else { | ||
| 526 | printk(KERN_INFO "scsi%d: <fdomain> BIOS version ", shpnt->host_no); | ||
| 527 | |||
| 528 | if (bios_major >= 0) printk("%d.", bios_major); | ||
| 529 | else printk("?."); | ||
| 530 | |||
| 531 | if (bios_minor >= 0) printk("%d", bios_minor); | ||
| 532 | else printk("?."); | ||
| 533 | |||
| 534 | printk( " at 0x%lx using scsi id %d\n", | ||
| 535 | bios_base, shpnt->this_id ); | ||
| 536 | } | ||
| 537 | |||
| 538 | /* If this driver works for later FD PCI | ||
| 539 | boards, we will have to modify banner | ||
| 540 | for additional PCI cards, but for now if | ||
| 541 | it's PCI it's a TMC-3260 - JTM */ | ||
| 542 | printk(KERN_INFO "scsi%d: <fdomain> %s chip at 0x%x irq ", | ||
| 543 | shpnt->host_no, | ||
| 544 | chip == tmc1800 ? "TMC-1800" : (chip == tmc18c50 ? "TMC-18C50" : (chip == tmc18c30 ? (PCI_bus ? "TMC-36C70 (PCI bus)" : "TMC-18C30") : "Unknown")), | ||
| 545 | port_base); | ||
| 546 | |||
| 547 | if (interrupt_level) | ||
| 548 | printk("%d", interrupt_level); | ||
| 549 | else | ||
| 550 | printk("<none>"); | ||
| 551 | |||
| 552 | printk( "\n" ); | ||
| 553 | } | ||
| 554 | |||
| 555 | int fdomain_setup(char *str) | ||
| 556 | { | ||
| 557 | int ints[4]; | ||
| 558 | |||
| 559 | (void)get_options(str, ARRAY_SIZE(ints), ints); | ||
| 560 | |||
| 561 | if (setup_called++ || ints[0] < 2 || ints[0] > 3) { | ||
| 562 | printk(KERN_INFO "scsi: <fdomain> Usage: fdomain=<PORT_BASE>,<IRQ>[,<ADAPTER_ID>]\n"); | ||
| 563 | printk(KERN_ERR "scsi: <fdomain> Bad LILO/INSMOD parameters?\n"); | ||
| 564 | return 0; | ||
| 565 | } | ||
| 566 | |||
| 567 | port_base = ints[0] >= 1 ? ints[1] : 0; | ||
| 568 | interrupt_level = ints[0] >= 2 ? ints[2] : 0; | ||
| 569 | this_id = ints[0] >= 3 ? ints[3] : 0; | ||
| 570 | |||
| 571 | bios_major = bios_minor = -1; /* Use geometry for BIOS version >= 3.4 */ | ||
| 572 | ++setup_called; | ||
| 573 | return 1; | ||
| 574 | } | ||
| 575 | |||
| 576 | __setup("fdomain=", fdomain_setup); | ||
| 577 | |||
| 578 | |||
| 579 | static void do_pause(unsigned amount) /* Pause for amount*10 milliseconds */ | ||
| 580 | { | ||
| 581 | mdelay(10*amount); | ||
| 582 | } | ||
| 583 | |||
| 584 | static inline void fdomain_make_bus_idle( void ) | ||
| 585 | { | ||
| 586 | outb(0, port_base + SCSI_Cntl); | ||
| 587 | outb(0, port_base + SCSI_Mode_Cntl); | ||
| 588 | if (chip == tmc18c50 || chip == tmc18c30) | ||
| 589 | outb(0x21 | PARITY_MASK, port_base + TMC_Cntl); /* Clear forced intr. */ | ||
| 590 | else | ||
| 591 | outb(0x01 | PARITY_MASK, port_base + TMC_Cntl); | ||
| 592 | } | ||
| 593 | |||
| 594 | static int fdomain_is_valid_port( int port ) | ||
| 595 | { | ||
| 596 | #if DEBUG_DETECT | ||
| 597 | printk( " (%x%x),", | ||
| 598 | inb( port + MSB_ID_Code ), inb( port + LSB_ID_Code ) ); | ||
| 599 | #endif | ||
| 600 | |||
| 601 | /* The MCA ID is a unique id for each MCA compatible board. We | ||
| 602 | are using ISA boards, but Future Domain provides the MCA ID | ||
| 603 | anyway. We can use this ID to ensure that this is a Future | ||
| 604 | Domain TMC-1660/TMC-1680. | ||
| 605 | */ | ||
| 606 | |||
| 607 | if (inb( port + LSB_ID_Code ) != 0xe9) { /* test for 0x6127 id */ | ||
| 608 | if (inb( port + LSB_ID_Code ) != 0x27) return 0; | ||
| 609 | if (inb( port + MSB_ID_Code ) != 0x61) return 0; | ||
| 610 | chip = tmc1800; | ||
| 611 | } else { /* test for 0xe960 id */ | ||
| 612 | if (inb( port + MSB_ID_Code ) != 0x60) return 0; | ||
| 613 | chip = tmc18c50; | ||
| 614 | |||
| 615 | /* Try to toggle 32-bit mode. This only | ||
| 616 | works on an 18c30 chip. (User reports | ||
| 617 | say this works, so we should switch to | ||
| 618 | it in the near future.) */ | ||
| 619 | |||
| 620 | outb( 0x80, port + IO_Control ); | ||
| 621 | if ((inb( port + Configuration2 ) & 0x80) == 0x80) { | ||
| 622 | outb( 0x00, port + IO_Control ); | ||
| 623 | if ((inb( port + Configuration2 ) & 0x80) == 0x00) { | ||
| 624 | chip = tmc18c30; | ||
| 625 | FIFO_Size = 0x800; /* 2k FIFO */ | ||
| 626 | } | ||
| 627 | } | ||
| 628 | /* If that failed, we are an 18c50. */ | ||
| 629 | } | ||
| 630 | |||
| 631 | return 1; | ||
| 632 | } | ||
| 633 | |||
| 634 | static int fdomain_test_loopback( void ) | ||
| 635 | { | ||
| 636 | int i; | ||
| 637 | int result; | ||
| 638 | |||
| 639 | for (i = 0; i < 255; i++) { | ||
| 640 | outb( i, port_base + Write_Loopback ); | ||
| 641 | result = inb( port_base + Read_Loopback ); | ||
| 642 | if (i != result) | ||
| 643 | return 1; | ||
| 644 | } | ||
| 645 | return 0; | ||
| 646 | } | ||
| 647 | |||
| 648 | #ifndef PCMCIA | ||
| 649 | |||
| 650 | /* fdomain_get_irq assumes that we have a valid MCA ID for a | ||
| 651 | TMC-1660/TMC-1680 Future Domain board. Now, check to be sure the | ||
| 652 | bios_base matches these ports. If someone was unlucky enough to have | ||
| 653 | purchased more than one Future Domain board, then they will have to | ||
| 654 | modify this code, as we only detect one board here. [The one with the | ||
| 655 | lowest bios_base.] | ||
| 656 | |||
| 657 | Note that this routine is only used for systems without a PCI BIOS32 | ||
| 658 | (e.g., ISA bus). For PCI bus systems, this routine will likely fail | ||
| 659 | unless one of the IRQs listed in the ints array is used by the board. | ||
| 660 | Sometimes it is possible to use the computer's BIOS setup screen to | ||
| 661 | configure a PCI system so that one of these IRQs will be used by the | ||
| 662 | Future Domain card. */ | ||
| 663 | |||
| 664 | static int fdomain_get_irq( int base ) | ||
| 665 | { | ||
| 666 | int options = inb(base + Configuration1); | ||
| 667 | |||
| 668 | #if DEBUG_DETECT | ||
| 669 | printk("scsi: <fdomain> Options = %x\n", options); | ||
| 670 | #endif | ||
| 671 | |||
| 672 | /* Check for board with lowest bios_base -- | ||
| 673 | this isn't valid for the 18c30 or for | ||
| 674 | boards on the PCI bus, so just assume we | ||
| 675 | have the right board. */ | ||
| 676 | |||
| 677 | if (chip != tmc18c30 && !PCI_bus && addresses[(options & 0xc0) >> 6 ] != bios_base) | ||
| 678 | return 0; | ||
| 679 | return ints[(options & 0x0e) >> 1]; | ||
| 680 | } | ||
| 681 | |||
| 682 | static int fdomain_isa_detect( int *irq, int *iobase ) | ||
| 683 | { | ||
| 684 | int i, j; | ||
| 685 | int base = 0xdeadbeef; | ||
| 686 | int flag = 0; | ||
| 687 | |||
| 688 | #if DEBUG_DETECT | ||
| 689 | printk( "scsi: <fdomain> fdomain_isa_detect:" ); | ||
| 690 | #endif | ||
| 691 | |||
| 692 | for (i = 0; i < ADDRESS_COUNT; i++) { | ||
| 693 | void __iomem *p = ioremap(addresses[i], 0x2000); | ||
| 694 | if (!p) | ||
| 695 | continue; | ||
| 696 | #if DEBUG_DETECT | ||
| 697 | printk( " %lx(%lx),", addresses[i], bios_base ); | ||
| 698 | #endif | ||
| 699 | for (j = 0; j < SIGNATURE_COUNT; j++) { | ||
| 700 | if (check_signature(p + signatures[j].sig_offset, | ||
| 701 | signatures[j].signature, | ||
| 702 | signatures[j].sig_length )) { | ||
| 703 | bios_major = signatures[j].major_bios_version; | ||
| 704 | bios_minor = signatures[j].minor_bios_version; | ||
| 705 | PCI_bus = (signatures[j].flag == 1); | ||
| 706 | Quantum = (signatures[j].flag > 1) ? signatures[j].flag : 0; | ||
| 707 | bios_base = addresses[i]; | ||
| 708 | bios_mem = p; | ||
| 709 | goto found; | ||
| 710 | } | ||
| 711 | } | ||
| 712 | iounmap(p); | ||
| 713 | } | ||
| 714 | |||
| 715 | found: | ||
| 716 | if (bios_major == 2) { | ||
| 717 | /* The TMC-1660/TMC-1680 has a RAM area just after the BIOS ROM. | ||
| 718 | Assuming the ROM is enabled (otherwise we wouldn't have been | ||
| 719 | able to read the ROM signature :-), then the ROM sets up the | ||
| 720 | RAM area with some magic numbers, such as a list of port | ||
| 721 | base addresses and a list of the disk "geometry" reported to | ||
| 722 | DOS (this geometry has nothing to do with physical geometry). | ||
| 723 | */ | ||
| 724 | |||
| 725 | switch (Quantum) { | ||
| 726 | case 2: /* ISA_200S */ | ||
| 727 | case 3: /* ISA_250MG */ | ||
| 728 | base = readb(bios_mem + 0x1fa2) + (readb(bios_mem + 0x1fa3) << 8); | ||
| 729 | break; | ||
| 730 | case 4: /* ISA_200S (another one) */ | ||
| 731 | base = readb(bios_mem + 0x1fa3) + (readb(bios_mem + 0x1fa4) << 8); | ||
| 732 | break; | ||
| 733 | default: | ||
| 734 | base = readb(bios_mem + 0x1fcc) + (readb(bios_mem + 0x1fcd) << 8); | ||
| 735 | break; | ||
| 736 | } | ||
| 737 | |||
| 738 | #if DEBUG_DETECT | ||
| 739 | printk( " %x,", base ); | ||
| 740 | #endif | ||
| 741 | |||
| 742 | for (i = 0; i < PORT_COUNT; i++) { | ||
| 743 | if (base == ports[i]) { | ||
| 744 | if (!request_region(base, 0x10, "fdomain")) | ||
| 745 | break; | ||
| 746 | if (!fdomain_is_valid_port(base)) { | ||
| 747 | release_region(base, 0x10); | ||
| 748 | break; | ||
| 749 | } | ||
| 750 | *irq = fdomain_get_irq( base ); | ||
| 751 | *iobase = base; | ||
| 752 | return 1; | ||
| 753 | } | ||
| 754 | } | ||
| 755 | |||
| 756 | /* This is a bad sign. It usually means that someone patched the | ||
| 757 | BIOS signature list (the signatures variable) to contain a BIOS | ||
| 758 | signature for a board *OTHER THAN* the TMC-1660/TMC-1680. */ | ||
| 759 | |||
| 760 | #if DEBUG_DETECT | ||
| 761 | printk( " RAM FAILED, " ); | ||
| 762 | #endif | ||
| 763 | } | ||
| 764 | |||
| 765 | /* Anyway, the alternative to finding the address in the RAM is to just | ||
| 766 | search through every possible port address for one that is attached | ||
| 767 | to the Future Domain card. Don't panic, though, about reading all | ||
| 768 | these random port addresses -- there are rumors that the Future | ||
| 769 | Domain BIOS does something very similar. | ||
| 770 | |||
| 771 | Do not, however, check ports which the kernel knows are being used by | ||
| 772 | another driver. */ | ||
| 773 | |||
| 774 | for (i = 0; i < PORT_COUNT; i++) { | ||
| 775 | base = ports[i]; | ||
| 776 | if (!request_region(base, 0x10, "fdomain")) { | ||
| 777 | #if DEBUG_DETECT | ||
| 778 | printk( " (%x inuse),", base ); | ||
| 779 | #endif | ||
| 780 | continue; | ||
| 781 | } | ||
| 782 | #if DEBUG_DETECT | ||
| 783 | printk( " %x,", base ); | ||
| 784 | #endif | ||
| 785 | flag = fdomain_is_valid_port(base); | ||
| 786 | if (flag) | ||
| 787 | break; | ||
| 788 | release_region(base, 0x10); | ||
| 789 | } | ||
| 790 | |||
| 791 | #if DEBUG_DETECT | ||
| 792 | if (flag) printk( " SUCCESS\n" ); | ||
| 793 | else printk( " FAILURE\n" ); | ||
| 794 | #endif | ||
| 795 | |||
| 796 | if (!flag) return 0; /* iobase not found */ | ||
| 797 | |||
| 798 | *irq = fdomain_get_irq( base ); | ||
| 799 | *iobase = base; | ||
| 800 | |||
| 801 | return 1; /* success */ | ||
| 802 | } | ||
| 803 | |||
| 804 | #else /* PCMCIA */ | ||
| 805 | |||
| 806 | static int fdomain_isa_detect( int *irq, int *iobase ) | ||
| 807 | { | ||
| 808 | if (irq) | ||
| 809 | *irq = 0; | ||
| 810 | if (iobase) | ||
| 811 | *iobase = 0; | ||
| 812 | return 0; | ||
| 813 | } | ||
| 814 | |||
| 815 | #endif /* !PCMCIA */ | ||
| 816 | |||
| 817 | |||
| 818 | /* PCI detection function: int fdomain_pci_bios_detect(int* irq, int* | ||
| 819 | iobase) This function gets the Interrupt Level and I/O base address from | ||
| 820 | the PCI configuration registers. */ | ||
| 821 | |||
| 822 | #ifdef CONFIG_PCI | ||
| 823 | static int fdomain_pci_bios_detect( int *irq, int *iobase, struct pci_dev **ret_pdev ) | ||
| 824 | { | ||
| 825 | unsigned int pci_irq; /* PCI interrupt line */ | ||
| 826 | unsigned long pci_base; /* PCI I/O base address */ | ||
| 827 | struct pci_dev *pdev = NULL; | ||
| 828 | |||
| 829 | #if DEBUG_DETECT | ||
| 830 | /* Tell how to print a list of the known PCI devices from bios32 and | ||
| 831 | list vendor and device IDs being used if in debug mode. */ | ||
| 832 | |||
| 833 | printk( "scsi: <fdomain> INFO: use lspci -v to see list of PCI devices\n" ); | ||
| 834 | printk( "scsi: <fdomain> TMC-3260 detect:" | ||
| 835 | " Using Vendor ID: 0x%x and Device ID: 0x%x\n", | ||
| 836 | PCI_VENDOR_ID_FD, | ||
| 837 | PCI_DEVICE_ID_FD_36C70 ); | ||
| 838 | #endif | ||
| 839 | |||
| 840 | if ((pdev = pci_get_device(PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, pdev)) == NULL) | ||
| 841 | return 0; | ||
| 842 | if (pci_enable_device(pdev)) | ||
| 843 | goto fail; | ||
| 844 | |||
| 845 | #if DEBUG_DETECT | ||
| 846 | printk( "scsi: <fdomain> TMC-3260 detect:" | ||
| 847 | " PCI bus %u, device %u, function %u\n", | ||
| 848 | pdev->bus->number, | ||
| 849 | PCI_SLOT(pdev->devfn), | ||
| 850 | PCI_FUNC(pdev->devfn)); | ||
| 851 | #endif | ||
| 852 | |||
| 853 | /* We now have the appropriate device function for the FD board so we | ||
| 854 | just read the PCI config info from the registers. */ | ||
| 855 | |||
| 856 | pci_base = pci_resource_start(pdev, 0); | ||
| 857 | pci_irq = pdev->irq; | ||
| 858 | |||
| 859 | if (!request_region( pci_base, 0x10, "fdomain" )) | ||
| 860 | goto fail; | ||
| 861 | |||
| 862 | /* Now we have the I/O base address and interrupt from the PCI | ||
| 863 | configuration registers. */ | ||
| 864 | |||
| 865 | *irq = pci_irq; | ||
| 866 | *iobase = pci_base; | ||
| 867 | *ret_pdev = pdev; | ||
| 868 | |||
| 869 | #if DEBUG_DETECT | ||
| 870 | printk( "scsi: <fdomain> TMC-3260 detect:" | ||
| 871 | " IRQ = %d, I/O base = 0x%x [0x%lx]\n", *irq, *iobase, pci_base ); | ||
| 872 | #endif | ||
| 873 | |||
| 874 | if (!fdomain_is_valid_port(pci_base)) { | ||
| 875 | printk(KERN_ERR "scsi: <fdomain> PCI card detected, but driver not loaded (invalid port)\n" ); | ||
| 876 | release_region(pci_base, 0x10); | ||
| 877 | goto fail; | ||
| 878 | } | ||
| 879 | |||
| 880 | /* Fill in a few global variables. Ugh. */ | ||
| 881 | bios_major = bios_minor = -1; | ||
| 882 | PCI_bus = 1; | ||
| 883 | PCI_dev = pdev; | ||
| 884 | Quantum = 0; | ||
| 885 | bios_base = 0; | ||
| 886 | |||
| 887 | return 1; | ||
| 888 | fail: | ||
| 889 | pci_dev_put(pdev); | ||
| 890 | return 0; | ||
| 891 | } | ||
| 892 | |||
| 893 | #endif | ||
| 894 | |||
| 895 | struct Scsi_Host *__fdomain_16x0_detect(struct scsi_host_template *tpnt ) | ||
| 896 | { | ||
| 897 | int retcode; | ||
| 898 | struct Scsi_Host *shpnt; | ||
| 899 | struct pci_dev *pdev = NULL; | ||
| 900 | |||
| 901 | if (setup_called) { | ||
| 902 | #if DEBUG_DETECT | ||
| 903 | printk( "scsi: <fdomain> No BIOS, using port_base = 0x%x, irq = %d\n", | ||
| 904 | port_base, interrupt_level ); | ||
| 905 | #endif | ||
| 906 | if (!request_region(port_base, 0x10, "fdomain")) { | ||
| 907 | printk( "scsi: <fdomain> port 0x%x is busy\n", port_base ); | ||
| 908 | printk( "scsi: <fdomain> Bad LILO/INSMOD parameters?\n" ); | ||
| 909 | return NULL; | ||
| 910 | } | ||
| 911 | if (!fdomain_is_valid_port( port_base )) { | ||
| 912 | printk( "scsi: <fdomain> Cannot locate chip at port base 0x%x\n", | ||
| 913 | port_base ); | ||
| 914 | printk( "scsi: <fdomain> Bad LILO/INSMOD parameters?\n" ); | ||
| 915 | release_region(port_base, 0x10); | ||
| 916 | return NULL; | ||
| 917 | } | ||
| 918 | } else { | ||
| 919 | int flag = 0; | ||
| 920 | |||
| 921 | #ifdef CONFIG_PCI | ||
| 922 | /* Try PCI detection first */ | ||
| 923 | flag = fdomain_pci_bios_detect( &interrupt_level, &port_base, &pdev ); | ||
| 924 | #endif | ||
| 925 | if (!flag) { | ||
| 926 | /* Then try ISA bus detection */ | ||
| 927 | flag = fdomain_isa_detect( &interrupt_level, &port_base ); | ||
| 928 | |||
| 929 | if (!flag) { | ||
| 930 | printk( "scsi: <fdomain> Detection failed (no card)\n" ); | ||
| 931 | return NULL; | ||
| 932 | } | ||
| 933 | } | ||
| 934 | } | ||
| 935 | |||
| 936 | fdomain_16x0_host_reset(NULL); | ||
| 937 | |||
| 938 | if (fdomain_test_loopback()) { | ||
| 939 | printk(KERN_ERR "scsi: <fdomain> Detection failed (loopback test failed at port base 0x%x)\n", port_base); | ||
| 940 | if (setup_called) { | ||
| 941 | printk(KERN_ERR "scsi: <fdomain> Bad LILO/INSMOD parameters?\n"); | ||
| 942 | } | ||
| 943 | goto fail; | ||
| 944 | } | ||
| 945 | |||
| 946 | if (this_id) { | ||
| 947 | tpnt->this_id = (this_id & 0x07); | ||
| 948 | adapter_mask = (1 << tpnt->this_id); | ||
| 949 | } else { | ||
| 950 | if (PCI_bus || (bios_major == 3 && bios_minor >= 2) || bios_major < 0) { | ||
| 951 | tpnt->this_id = 7; | ||
| 952 | adapter_mask = 0x80; | ||
| 953 | } else { | ||
| 954 | tpnt->this_id = 6; | ||
| 955 | adapter_mask = 0x40; | ||
| 956 | } | ||
| 957 | } | ||
| 958 | |||
| 959 | /* Print out a banner here in case we can't | ||
| 960 | get resources. */ | ||
| 961 | |||
| 962 | shpnt = scsi_register( tpnt, 0 ); | ||
| 963 | if(shpnt == NULL) { | ||
| 964 | release_region(port_base, 0x10); | ||
| 965 | return NULL; | ||
| 966 | } | ||
| 967 | shpnt->irq = interrupt_level; | ||
| 968 | shpnt->io_port = port_base; | ||
| 969 | shpnt->n_io_port = 0x10; | ||
| 970 | print_banner( shpnt ); | ||
| 971 | |||
| 972 | /* Log IRQ with kernel */ | ||
| 973 | if (!interrupt_level) { | ||
| 974 | printk(KERN_ERR "scsi: <fdomain> Card Detected, but driver not loaded (no IRQ)\n" ); | ||
| 975 | goto fail; | ||
| 976 | } else { | ||
| 977 | /* Register the IRQ with the kernel */ | ||
| 978 | |||
| 979 | retcode = request_irq( interrupt_level, | ||
| 980 | do_fdomain_16x0_intr, pdev?IRQF_SHARED:0, "fdomain", shpnt); | ||
| 981 | |||
| 982 | if (retcode < 0) { | ||
| 983 | if (retcode == -EINVAL) { | ||
| 984 | printk(KERN_ERR "scsi: <fdomain> IRQ %d is bad!\n", interrupt_level ); | ||
| 985 | printk(KERN_ERR " This shouldn't happen!\n" ); | ||
| 986 | printk(KERN_ERR " Send mail to faith@acm.org\n" ); | ||
| 987 | } else if (retcode == -EBUSY) { | ||
| 988 | printk(KERN_ERR "scsi: <fdomain> IRQ %d is already in use!\n", interrupt_level ); | ||
| 989 | printk(KERN_ERR " Please use another IRQ!\n" ); | ||
| 990 | } else { | ||
| 991 | printk(KERN_ERR "scsi: <fdomain> Error getting IRQ %d\n", interrupt_level ); | ||
| 992 | printk(KERN_ERR " This shouldn't happen!\n" ); | ||
| 993 | printk(KERN_ERR " Send mail to faith@acm.org\n" ); | ||
| 994 | } | ||
| 995 | printk(KERN_ERR "scsi: <fdomain> Detected, but driver not loaded (IRQ)\n" ); | ||
| 996 | goto fail; | ||
| 997 | } | ||
| 998 | } | ||
| 999 | return shpnt; | ||
| 1000 | fail: | ||
| 1001 | pci_dev_put(pdev); | ||
| 1002 | release_region(port_base, 0x10); | ||
| 1003 | return NULL; | ||
| 1004 | } | ||
| 1005 | |||
| 1006 | static int fdomain_16x0_detect(struct scsi_host_template *tpnt) | ||
| 1007 | { | ||
| 1008 | if (fdomain) | ||
| 1009 | fdomain_setup(fdomain); | ||
| 1010 | return (__fdomain_16x0_detect(tpnt) != NULL); | ||
| 1011 | } | ||
| 1012 | |||
| 1013 | static const char *fdomain_16x0_info( struct Scsi_Host *ignore ) | ||
| 1014 | { | ||
| 1015 | static char buffer[128]; | ||
| 1016 | char *pt; | ||
| 1017 | |||
| 1018 | strcpy( buffer, "Future Domain 16-bit SCSI Driver Version" ); | ||
| 1019 | if (strchr( VERSION, ':')) { /* Assume VERSION is an RCS Revision string */ | ||
| 1020 | strcat( buffer, strchr( VERSION, ':' ) + 1 ); | ||
| 1021 | pt = strrchr( buffer, '$') - 1; | ||
| 1022 | if (!pt) /* Stripped RCS Revision string? */ | ||
| 1023 | pt = buffer + strlen( buffer ) - 1; | ||
| 1024 | if (*pt != ' ') | ||
| 1025 | ++pt; | ||
| 1026 | *pt = '\0'; | ||
| 1027 | } else { /* Assume VERSION is a number */ | ||
| 1028 | strcat( buffer, " " VERSION ); | ||
| 1029 | } | ||
| 1030 | |||
| 1031 | return buffer; | ||
| 1032 | } | ||
| 1033 | |||
| 1034 | #if 0 | ||
| 1035 | static int fdomain_arbitrate( void ) | ||
| 1036 | { | ||
| 1037 | int status = 0; | ||
| 1038 | unsigned long timeout; | ||
| 1039 | |||
| 1040 | #if EVERY_ACCESS | ||
| 1041 | printk( "fdomain_arbitrate()\n" ); | ||
| 1042 | #endif | ||
| 1043 | |||
| 1044 | outb(0x00, port_base + SCSI_Cntl); /* Disable data drivers */ | ||
| 1045 | outb(adapter_mask, port_base + SCSI_Data_NoACK); /* Set our id bit */ | ||
| 1046 | outb(0x04 | PARITY_MASK, port_base + TMC_Cntl); /* Start arbitration */ | ||
| 1047 | |||
| 1048 | timeout = 500; | ||
| 1049 | do { | ||
| 1050 | status = inb(port_base + TMC_Status); /* Read adapter status */ | ||
| 1051 | if (status & 0x02) /* Arbitration complete */ | ||
| 1052 | return 0; | ||
| 1053 | mdelay(1); /* Wait one millisecond */ | ||
| 1054 | } while (--timeout); | ||
| 1055 | |||
| 1056 | /* Make bus idle */ | ||
| 1057 | fdomain_make_bus_idle(); | ||
| 1058 | |||
| 1059 | #if EVERY_ACCESS | ||
| 1060 | printk( "Arbitration failed, status = %x\n", status ); | ||
| 1061 | #endif | ||
| 1062 | #if ERRORS_ONLY | ||
| 1063 | printk( "scsi: <fdomain> Arbitration failed, status = %x\n", status ); | ||
| 1064 | #endif | ||
| 1065 | return 1; | ||
| 1066 | } | ||
| 1067 | #endif | ||
| 1068 | |||
| 1069 | static int fdomain_select( int target ) | ||
| 1070 | { | ||
| 1071 | int status; | ||
| 1072 | unsigned long timeout; | ||
| 1073 | #if ERRORS_ONLY | ||
| 1074 | static int flag = 0; | ||
| 1075 | #endif | ||
| 1076 | |||
| 1077 | outb(0x82, port_base + SCSI_Cntl); /* Bus Enable + Select */ | ||
| 1078 | outb(adapter_mask | (1 << target), port_base + SCSI_Data_NoACK); | ||
| 1079 | |||
| 1080 | /* Stop arbitration and enable parity */ | ||
| 1081 | outb(PARITY_MASK, port_base + TMC_Cntl); | ||
| 1082 | |||
| 1083 | timeout = 350; /* 350 msec */ | ||
| 1084 | |||
| 1085 | do { | ||
| 1086 | status = inb(port_base + SCSI_Status); /* Read adapter status */ | ||
| 1087 | if (status & 1) { /* Busy asserted */ | ||
| 1088 | /* Enable SCSI Bus (on error, should make bus idle with 0) */ | ||
| 1089 | outb(0x80, port_base + SCSI_Cntl); | ||
| 1090 | return 0; | ||
| 1091 | } | ||
| 1092 | mdelay(1); /* wait one msec */ | ||
| 1093 | } while (--timeout); | ||
| 1094 | /* Make bus idle */ | ||
| 1095 | fdomain_make_bus_idle(); | ||
| 1096 | #if EVERY_ACCESS | ||
| 1097 | if (!target) printk( "Selection failed\n" ); | ||
| 1098 | #endif | ||
| 1099 | #if ERRORS_ONLY | ||
| 1100 | if (!target) { | ||
| 1101 | if (!flag) /* Skip first failure for all chips. */ | ||
| 1102 | ++flag; | ||
| 1103 | else | ||
| 1104 | printk( "scsi: <fdomain> Selection failed\n" ); | ||
| 1105 | } | ||
| 1106 | #endif | ||
| 1107 | return 1; | ||
| 1108 | } | ||
| 1109 | |||
| 1110 | static void my_done(int error) | ||
| 1111 | { | ||
| 1112 | if (in_command) { | ||
| 1113 | in_command = 0; | ||
| 1114 | outb(0x00, port_base + Interrupt_Cntl); | ||
| 1115 | fdomain_make_bus_idle(); | ||
| 1116 | current_SC->result = error; | ||
| 1117 | if (current_SC->scsi_done) | ||
| 1118 | current_SC->scsi_done( current_SC ); | ||
| 1119 | else panic( "scsi: <fdomain> current_SC->scsi_done() == NULL" ); | ||
| 1120 | } else { | ||
| 1121 | panic( "scsi: <fdomain> my_done() called outside of command\n" ); | ||
| 1122 | } | ||
| 1123 | #if DEBUG_RACE | ||
| 1124 | in_interrupt_flag = 0; | ||
| 1125 | #endif | ||
| 1126 | } | ||
| 1127 | |||
| 1128 | static irqreturn_t do_fdomain_16x0_intr(int irq, void *dev_id) | ||
| 1129 | { | ||
| 1130 | unsigned long flags; | ||
| 1131 | int status; | ||
| 1132 | int done = 0; | ||
| 1133 | unsigned data_count; | ||
| 1134 | |||
| 1135 | /* The fdomain_16x0_intr is only called via | ||
| 1136 | the interrupt handler. The goal of the | ||
| 1137 | sti() here is to allow other | ||
| 1138 | interruptions while this routine is | ||
| 1139 | running. */ | ||
| 1140 | |||
| 1141 | /* Check for other IRQ sources */ | ||
| 1142 | if ((inb(port_base + TMC_Status) & 0x01) == 0) | ||
| 1143 | return IRQ_NONE; | ||
| 1144 | |||
| 1145 | /* It is our IRQ */ | ||
| 1146 | outb(0x00, port_base + Interrupt_Cntl); | ||
| 1147 | |||
| 1148 | /* We usually have one spurious interrupt after each command. Ignore it. */ | ||
| 1149 | if (!in_command || !current_SC) { /* Spurious interrupt */ | ||
| 1150 | #if EVERY_ACCESS | ||
| 1151 | printk( "Spurious interrupt, in_command = %d, current_SC = %x\n", | ||
| 1152 | in_command, current_SC ); | ||
| 1153 | #endif | ||
| 1154 | return IRQ_NONE; | ||
| 1155 | } | ||
| 1156 | |||
| 1157 | /* Abort calls my_done, so we do nothing here. */ | ||
| 1158 | if (current_SC->SCp.phase & aborted) { | ||
| 1159 | #if DEBUG_ABORT | ||
| 1160 | printk( "scsi: <fdomain> Interrupt after abort, ignoring\n" ); | ||
| 1161 | #endif | ||
| 1162 | /* | ||
| 1163 | return IRQ_HANDLED; */ | ||
| 1164 | } | ||
| 1165 | |||
| 1166 | #if DEBUG_RACE | ||
| 1167 | ++in_interrupt_flag; | ||
| 1168 | #endif | ||
| 1169 | |||
| 1170 | if (current_SC->SCp.phase & in_arbitration) { | ||
| 1171 | status = inb(port_base + TMC_Status); /* Read adapter status */ | ||
| 1172 | if (!(status & 0x02)) { | ||
| 1173 | #if EVERY_ACCESS | ||
| 1174 | printk( " AFAIL " ); | ||
| 1175 | #endif | ||
| 1176 | spin_lock_irqsave(current_SC->device->host->host_lock, flags); | ||
| 1177 | my_done( DID_BUS_BUSY << 16 ); | ||
| 1178 | spin_unlock_irqrestore(current_SC->device->host->host_lock, flags); | ||
| 1179 | return IRQ_HANDLED; | ||
| 1180 | } | ||
| 1181 | current_SC->SCp.phase = in_selection; | ||
| 1182 | |||
| 1183 | outb(0x40 | FIFO_COUNT, port_base + Interrupt_Cntl); | ||
| 1184 | |||
| 1185 | outb(0x82, port_base + SCSI_Cntl); /* Bus Enable + Select */ | ||
| 1186 | outb(adapter_mask | (1 << scmd_id(current_SC)), port_base + SCSI_Data_NoACK); | ||
| 1187 | |||
| 1188 | /* Stop arbitration and enable parity */ | ||
| 1189 | outb(0x10 | PARITY_MASK, port_base + TMC_Cntl); | ||
| 1190 | #if DEBUG_RACE | ||
| 1191 | in_interrupt_flag = 0; | ||
| 1192 | #endif | ||
| 1193 | return IRQ_HANDLED; | ||
| 1194 | } else if (current_SC->SCp.phase & in_selection) { | ||
| 1195 | status = inb(port_base + SCSI_Status); | ||
| 1196 | if (!(status & 0x01)) { | ||
| 1197 | /* Try again, for slow devices */ | ||
| 1198 | if (fdomain_select( scmd_id(current_SC) )) { | ||
| 1199 | #if EVERY_ACCESS | ||
| 1200 | printk( " SFAIL " ); | ||
| 1201 | #endif | ||
| 1202 | spin_lock_irqsave(current_SC->device->host->host_lock, flags); | ||
| 1203 | my_done( DID_NO_CONNECT << 16 ); | ||
| 1204 | spin_unlock_irqrestore(current_SC->device->host->host_lock, flags); | ||
| 1205 | return IRQ_HANDLED; | ||
| 1206 | } else { | ||
| 1207 | #if EVERY_ACCESS | ||
| 1208 | printk( " AltSel " ); | ||
| 1209 | #endif | ||
| 1210 | /* Stop arbitration and enable parity */ | ||
| 1211 | outb(0x10 | PARITY_MASK, port_base + TMC_Cntl); | ||
| 1212 | } | ||
| 1213 | } | ||
| 1214 | current_SC->SCp.phase = in_other; | ||
| 1215 | outb(0x90 | FIFO_COUNT, port_base + Interrupt_Cntl); | ||
| 1216 | outb(0x80, port_base + SCSI_Cntl); | ||
| 1217 | #if DEBUG_RACE | ||
| 1218 | in_interrupt_flag = 0; | ||
| 1219 | #endif | ||
| 1220 | return IRQ_HANDLED; | ||
| 1221 | } | ||
| 1222 | |||
| 1223 | /* current_SC->SCp.phase == in_other: this is the body of the routine */ | ||
| 1224 | |||
| 1225 | status = inb(port_base + SCSI_Status); | ||
| 1226 | |||
| 1227 | if (status & 0x10) { /* REQ */ | ||
| 1228 | |||
| 1229 | switch (status & 0x0e) { | ||
| 1230 | |||
| 1231 | case 0x08: /* COMMAND OUT */ | ||
| 1232 | outb(current_SC->cmnd[current_SC->SCp.sent_command++], | ||
| 1233 | port_base + Write_SCSI_Data); | ||
| 1234 | #if EVERY_ACCESS | ||
| 1235 | printk( "CMD = %x,", | ||
| 1236 | current_SC->cmnd[ current_SC->SCp.sent_command - 1] ); | ||
| 1237 | #endif | ||
| 1238 | break; | ||
| 1239 | case 0x00: /* DATA OUT -- tmc18c50/tmc18c30 only */ | ||
| 1240 | if (chip != tmc1800 && !current_SC->SCp.have_data_in) { | ||
| 1241 | current_SC->SCp.have_data_in = -1; | ||
| 1242 | outb(0xd0 | PARITY_MASK, port_base + TMC_Cntl); | ||
| 1243 | } | ||
| 1244 | break; | ||
| 1245 | case 0x04: /* DATA IN -- tmc18c50/tmc18c30 only */ | ||
| 1246 | if (chip != tmc1800 && !current_SC->SCp.have_data_in) { | ||
| 1247 | current_SC->SCp.have_data_in = 1; | ||
| 1248 | outb(0x90 | PARITY_MASK, port_base + TMC_Cntl); | ||
| 1249 | } | ||
| 1250 | break; | ||
| 1251 | case 0x0c: /* STATUS IN */ | ||
| 1252 | current_SC->SCp.Status = inb(port_base + Read_SCSI_Data); | ||
| 1253 | #if EVERY_ACCESS | ||
| 1254 | printk( "Status = %x, ", current_SC->SCp.Status ); | ||
| 1255 | #endif | ||
| 1256 | #if ERRORS_ONLY | ||
| 1257 | if (current_SC->SCp.Status | ||
| 1258 | && current_SC->SCp.Status != 2 | ||
| 1259 | && current_SC->SCp.Status != 8) { | ||
| 1260 | printk( "scsi: <fdomain> target = %d, command = %x, status = %x\n", | ||
| 1261 | current_SC->device->id, | ||
| 1262 | current_SC->cmnd[0], | ||
| 1263 | current_SC->SCp.Status ); | ||
| 1264 | } | ||
| 1265 | #endif | ||
| 1266 | break; | ||
| 1267 | case 0x0a: /* MESSAGE OUT */ | ||
| 1268 | outb(MESSAGE_REJECT, port_base + Write_SCSI_Data); /* Reject */ | ||
| 1269 | break; | ||
| 1270 | case 0x0e: /* MESSAGE IN */ | ||
| 1271 | current_SC->SCp.Message = inb(port_base + Read_SCSI_Data); | ||
| 1272 | #if EVERY_ACCESS | ||
| 1273 | printk( "Message = %x, ", current_SC->SCp.Message ); | ||
| 1274 | #endif | ||
| 1275 | if (!current_SC->SCp.Message) ++done; | ||
| 1276 | #if DEBUG_MESSAGES || EVERY_ACCESS | ||
| 1277 | if (current_SC->SCp.Message) { | ||
| 1278 | printk( "scsi: <fdomain> message = %x\n", | ||
| 1279 | current_SC->SCp.Message ); | ||
| 1280 | } | ||
| 1281 | #endif | ||
| 1282 | break; | ||
| 1283 | } | ||
| 1284 | } | ||
| 1285 | |||
| 1286 | if (chip == tmc1800 && !current_SC->SCp.have_data_in | ||
| 1287 | && (current_SC->SCp.sent_command >= current_SC->cmd_len)) { | ||
| 1288 | |||
| 1289 | if(current_SC->sc_data_direction == DMA_TO_DEVICE) | ||
| 1290 | { | ||
| 1291 | current_SC->SCp.have_data_in = -1; | ||
| 1292 | outb(0xd0 | PARITY_MASK, port_base + TMC_Cntl); | ||
| 1293 | } | ||
| 1294 | else | ||
| 1295 | { | ||
| 1296 | current_SC->SCp.have_data_in = 1; | ||
| 1297 | outb(0x90 | PARITY_MASK, port_base + TMC_Cntl); | ||
| 1298 | } | ||
| 1299 | } | ||
| 1300 | |||
| 1301 | if (current_SC->SCp.have_data_in == -1) { /* DATA OUT */ | ||
| 1302 | while ((data_count = FIFO_Size - inw(port_base + FIFO_Data_Count)) > 512) { | ||
| 1303 | #if EVERY_ACCESS | ||
| 1304 | printk( "DC=%d, ", data_count ) ; | ||
| 1305 | #endif | ||
| 1306 | if (data_count > current_SC->SCp.this_residual) | ||
| 1307 | data_count = current_SC->SCp.this_residual; | ||
| 1308 | if (data_count > 0) { | ||
| 1309 | #if EVERY_ACCESS | ||
| 1310 | printk( "%d OUT, ", data_count ); | ||
| 1311 | #endif | ||
| 1312 | if (data_count == 1) { | ||
| 1313 | outb(*current_SC->SCp.ptr++, port_base + Write_FIFO); | ||
| 1314 | --current_SC->SCp.this_residual; | ||
| 1315 | } else { | ||
| 1316 | data_count >>= 1; | ||
| 1317 | outsw(port_base + Write_FIFO, current_SC->SCp.ptr, data_count); | ||
| 1318 | current_SC->SCp.ptr += 2 * data_count; | ||
| 1319 | current_SC->SCp.this_residual -= 2 * data_count; | ||
| 1320 | } | ||
| 1321 | } | ||
| 1322 | if (!current_SC->SCp.this_residual) { | ||
| 1323 | if (current_SC->SCp.buffers_residual) { | ||
| 1324 | --current_SC->SCp.buffers_residual; | ||
| 1325 | ++current_SC->SCp.buffer; | ||
| 1326 | current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer); | ||
| 1327 | current_SC->SCp.this_residual = current_SC->SCp.buffer->length; | ||
| 1328 | } else | ||
| 1329 | break; | ||
| 1330 | } | ||
| 1331 | } | ||
| 1332 | } | ||
| 1333 | |||
| 1334 | if (current_SC->SCp.have_data_in == 1) { /* DATA IN */ | ||
| 1335 | while ((data_count = inw(port_base + FIFO_Data_Count)) > 0) { | ||
| 1336 | #if EVERY_ACCESS | ||
| 1337 | printk( "DC=%d, ", data_count ); | ||
| 1338 | #endif | ||
| 1339 | if (data_count > current_SC->SCp.this_residual) | ||
| 1340 | data_count = current_SC->SCp.this_residual; | ||
| 1341 | if (data_count) { | ||
| 1342 | #if EVERY_ACCESS | ||
| 1343 | printk( "%d IN, ", data_count ); | ||
| 1344 | #endif | ||
| 1345 | if (data_count == 1) { | ||
| 1346 | *current_SC->SCp.ptr++ = inb(port_base + Read_FIFO); | ||
| 1347 | --current_SC->SCp.this_residual; | ||
| 1348 | } else { | ||
| 1349 | data_count >>= 1; /* Number of words */ | ||
| 1350 | insw(port_base + Read_FIFO, current_SC->SCp.ptr, data_count); | ||
| 1351 | current_SC->SCp.ptr += 2 * data_count; | ||
| 1352 | current_SC->SCp.this_residual -= 2 * data_count; | ||
| 1353 | } | ||
| 1354 | } | ||
| 1355 | if (!current_SC->SCp.this_residual | ||
| 1356 | && current_SC->SCp.buffers_residual) { | ||
| 1357 | --current_SC->SCp.buffers_residual; | ||
| 1358 | ++current_SC->SCp.buffer; | ||
| 1359 | current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer); | ||
| 1360 | current_SC->SCp.this_residual = current_SC->SCp.buffer->length; | ||
| 1361 | } | ||
| 1362 | } | ||
| 1363 | } | ||
| 1364 | |||
| 1365 | if (done) { | ||
| 1366 | #if EVERY_ACCESS | ||
| 1367 | printk( " ** IN DONE %d ** ", current_SC->SCp.have_data_in ); | ||
| 1368 | #endif | ||
| 1369 | |||
| 1370 | #if ERRORS_ONLY | ||
| 1371 | if (current_SC->cmnd[0] == REQUEST_SENSE && !current_SC->SCp.Status) { | ||
| 1372 | char *buf = scsi_sglist(current_SC); | ||
| 1373 | if ((unsigned char)(*(buf + 2)) & 0x0f) { | ||
| 1374 | unsigned char key; | ||
| 1375 | unsigned char code; | ||
| 1376 | unsigned char qualifier; | ||
| 1377 | |||
| 1378 | key = (unsigned char)(*(buf + 2)) & 0x0f; | ||
| 1379 | code = (unsigned char)(*(buf + 12)); | ||
| 1380 | qualifier = (unsigned char)(*(buf + 13)); | ||
| 1381 | |||
| 1382 | if (key != UNIT_ATTENTION | ||
| 1383 | && !(key == NOT_READY | ||
| 1384 | && code == 0x04 | ||
| 1385 | && (!qualifier || qualifier == 0x02 || qualifier == 0x01)) | ||
| 1386 | && !(key == ILLEGAL_REQUEST && (code == 0x25 | ||
| 1387 | || code == 0x24 | ||
| 1388 | || !code))) | ||
| 1389 | |||
| 1390 | printk( "scsi: <fdomain> REQUEST SENSE" | ||
| 1391 | " Key = %x, Code = %x, Qualifier = %x\n", | ||
| 1392 | key, code, qualifier ); | ||
| 1393 | } | ||
| 1394 | } | ||
| 1395 | #endif | ||
| 1396 | #if EVERY_ACCESS | ||
| 1397 | printk( "BEFORE MY_DONE. . ." ); | ||
| 1398 | #endif | ||
| 1399 | spin_lock_irqsave(current_SC->device->host->host_lock, flags); | ||
| 1400 | my_done( (current_SC->SCp.Status & 0xff) | ||
| 1401 | | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16) ); | ||
| 1402 | spin_unlock_irqrestore(current_SC->device->host->host_lock, flags); | ||
| 1403 | #if EVERY_ACCESS | ||
| 1404 | printk( "RETURNING.\n" ); | ||
| 1405 | #endif | ||
| 1406 | |||
| 1407 | } else { | ||
| 1408 | if (current_SC->SCp.phase & disconnect) { | ||
| 1409 | outb(0xd0 | FIFO_COUNT, port_base + Interrupt_Cntl); | ||
| 1410 | outb(0x00, port_base + SCSI_Cntl); | ||
| 1411 | } else { | ||
| 1412 | outb(0x90 | FIFO_COUNT, port_base + Interrupt_Cntl); | ||
| 1413 | } | ||
| 1414 | } | ||
| 1415 | #if DEBUG_RACE | ||
| 1416 | in_interrupt_flag = 0; | ||
| 1417 | #endif | ||
| 1418 | return IRQ_HANDLED; | ||
| 1419 | } | ||
| 1420 | |||
| 1421 | static int fdomain_16x0_queue_lck(struct scsi_cmnd *SCpnt, | ||
| 1422 | void (*done)(struct scsi_cmnd *)) | ||
| 1423 | { | ||
| 1424 | if (in_command) { | ||
| 1425 | panic( "scsi: <fdomain> fdomain_16x0_queue() NOT REENTRANT!\n" ); | ||
| 1426 | } | ||
| 1427 | #if EVERY_ACCESS | ||
| 1428 | printk( "queue: target = %d cmnd = 0x%02x pieces = %d size = %u\n", | ||
| 1429 | SCpnt->target, | ||
| 1430 | *(unsigned char *)SCpnt->cmnd, | ||
| 1431 | scsi_sg_count(SCpnt), | ||
| 1432 | scsi_bufflen(SCpnt)); | ||
| 1433 | #endif | ||
| 1434 | |||
| 1435 | fdomain_make_bus_idle(); | ||
| 1436 | |||
| 1437 | current_SC = SCpnt; /* Save this for the done function */ | ||
| 1438 | current_SC->scsi_done = done; | ||
| 1439 | |||
| 1440 | /* Initialize static data */ | ||
| 1441 | |||
| 1442 | if (scsi_sg_count(current_SC)) { | ||
| 1443 | current_SC->SCp.buffer = scsi_sglist(current_SC); | ||
| 1444 | current_SC->SCp.ptr = sg_virt(current_SC->SCp.buffer); | ||
| 1445 | current_SC->SCp.this_residual = current_SC->SCp.buffer->length; | ||
| 1446 | current_SC->SCp.buffers_residual = scsi_sg_count(current_SC) - 1; | ||
| 1447 | } else { | ||
| 1448 | current_SC->SCp.ptr = NULL; | ||
| 1449 | current_SC->SCp.this_residual = 0; | ||
| 1450 | current_SC->SCp.buffer = NULL; | ||
| 1451 | current_SC->SCp.buffers_residual = 0; | ||
| 1452 | } | ||
| 1453 | |||
| 1454 | current_SC->SCp.Status = 0; | ||
| 1455 | current_SC->SCp.Message = 0; | ||
| 1456 | current_SC->SCp.have_data_in = 0; | ||
| 1457 | current_SC->SCp.sent_command = 0; | ||
| 1458 | current_SC->SCp.phase = in_arbitration; | ||
| 1459 | |||
| 1460 | /* Start arbitration */ | ||
| 1461 | outb(0x00, port_base + Interrupt_Cntl); | ||
| 1462 | outb(0x00, port_base + SCSI_Cntl); /* Disable data drivers */ | ||
| 1463 | outb(adapter_mask, port_base + SCSI_Data_NoACK); /* Set our id bit */ | ||
| 1464 | ++in_command; | ||
| 1465 | outb(0x20, port_base + Interrupt_Cntl); | ||
| 1466 | outb(0x14 | PARITY_MASK, port_base + TMC_Cntl); /* Start arbitration */ | ||
| 1467 | |||
| 1468 | return 0; | ||
| 1469 | } | ||
| 1470 | |||
| 1471 | static DEF_SCSI_QCMD(fdomain_16x0_queue) | ||
| 1472 | |||
| 1473 | #if DEBUG_ABORT | ||
| 1474 | static void print_info(struct scsi_cmnd *SCpnt) | ||
| 1475 | { | ||
| 1476 | unsigned int imr; | ||
| 1477 | unsigned int irr; | ||
| 1478 | unsigned int isr; | ||
| 1479 | |||
| 1480 | if (!SCpnt || !SCpnt->device || !SCpnt->device->host) { | ||
| 1481 | printk(KERN_WARNING "scsi: <fdomain> Cannot provide detailed information\n"); | ||
| 1482 | return; | ||
| 1483 | } | ||
| 1484 | |||
| 1485 | printk(KERN_INFO "%s\n", fdomain_16x0_info( SCpnt->device->host ) ); | ||
| 1486 | print_banner(SCpnt->device->host); | ||
| 1487 | switch (SCpnt->SCp.phase) { | ||
| 1488 | case in_arbitration: printk("arbitration"); break; | ||
| 1489 | case in_selection: printk("selection"); break; | ||
| 1490 | case in_other: printk("other"); break; | ||
| 1491 | default: printk("unknown"); break; | ||
| 1492 | } | ||
| 1493 | |||
| 1494 | printk( " (%d), target = %d cmnd = 0x%02x pieces = %d size = %u\n", | ||
| 1495 | SCpnt->SCp.phase, | ||
| 1496 | SCpnt->device->id, | ||
| 1497 | *(unsigned char *)SCpnt->cmnd, | ||
| 1498 | scsi_sg_count(SCpnt), | ||
| 1499 | scsi_bufflen(SCpnt)); | ||
| 1500 | printk( "sent_command = %d, have_data_in = %d, timeout = %d\n", | ||
| 1501 | SCpnt->SCp.sent_command, | ||
| 1502 | SCpnt->SCp.have_data_in, | ||
| 1503 | SCpnt->timeout ); | ||
| 1504 | #if DEBUG_RACE | ||
| 1505 | printk( "in_interrupt_flag = %d\n", in_interrupt_flag ); | ||
| 1506 | #endif | ||
| 1507 | |||
| 1508 | imr = (inb( 0x0a1 ) << 8) + inb( 0x21 ); | ||
| 1509 | outb( 0x0a, 0xa0 ); | ||
| 1510 | irr = inb( 0xa0 ) << 8; | ||
| 1511 | outb( 0x0a, 0x20 ); | ||
| 1512 | irr += inb( 0x20 ); | ||
| 1513 | outb( 0x0b, 0xa0 ); | ||
| 1514 | isr = inb( 0xa0 ) << 8; | ||
| 1515 | outb( 0x0b, 0x20 ); | ||
| 1516 | isr += inb( 0x20 ); | ||
| 1517 | |||
| 1518 | /* Print out interesting information */ | ||
| 1519 | printk( "IMR = 0x%04x", imr ); | ||
| 1520 | if (imr & (1 << interrupt_level)) | ||
| 1521 | printk( " (masked)" ); | ||
| 1522 | printk( ", IRR = 0x%04x, ISR = 0x%04x\n", irr, isr ); | ||
| 1523 | |||
| 1524 | printk( "SCSI Status = 0x%02x\n", inb(port_base + SCSI_Status)); | ||
| 1525 | printk( "TMC Status = 0x%02x", inb(port_base + TMC_Status)); | ||
| 1526 | if (inb((port_base + TMC_Status) & 1)) | ||
| 1527 | printk( " (interrupt)" ); | ||
| 1528 | printk( "\n" ); | ||
| 1529 | printk("Interrupt Status = 0x%02x", inb(port_base + Interrupt_Status)); | ||
| 1530 | if (inb(port_base + Interrupt_Status) & 0x08) | ||
| 1531 | printk( " (enabled)" ); | ||
| 1532 | printk( "\n" ); | ||
| 1533 | if (chip == tmc18c50 || chip == tmc18c30) { | ||
| 1534 | printk("FIFO Status = 0x%02x\n", inb(port_base + FIFO_Status)); | ||
| 1535 | printk( "Int. Condition = 0x%02x\n", | ||
| 1536 | inb( port_base + Interrupt_Cond ) ); | ||
| 1537 | } | ||
| 1538 | printk( "Configuration 1 = 0x%02x\n", inb( port_base + Configuration1 ) ); | ||
| 1539 | if (chip == tmc18c50 || chip == tmc18c30) | ||
| 1540 | printk( "Configuration 2 = 0x%02x\n", | ||
| 1541 | inb( port_base + Configuration2 ) ); | ||
| 1542 | } | ||
| 1543 | #endif | ||
| 1544 | |||
| 1545 | static int fdomain_16x0_abort(struct scsi_cmnd *SCpnt) | ||
| 1546 | { | ||
| 1547 | #if EVERY_ACCESS || ERRORS_ONLY || DEBUG_ABORT | ||
| 1548 | printk( "scsi: <fdomain> abort " ); | ||
| 1549 | #endif | ||
| 1550 | |||
| 1551 | if (!in_command) { | ||
| 1552 | #if EVERY_ACCESS || ERRORS_ONLY | ||
| 1553 | printk( " (not in command)\n" ); | ||
| 1554 | #endif | ||
| 1555 | return FAILED; | ||
| 1556 | } else printk( "\n" ); | ||
| 1557 | |||
| 1558 | #if DEBUG_ABORT | ||
| 1559 | print_info( SCpnt ); | ||
| 1560 | #endif | ||
| 1561 | |||
| 1562 | fdomain_make_bus_idle(); | ||
| 1563 | current_SC->SCp.phase |= aborted; | ||
| 1564 | current_SC->result = DID_ABORT << 16; | ||
| 1565 | |||
| 1566 | /* Aborts are not done well. . . */ | ||
| 1567 | my_done(DID_ABORT << 16); | ||
| 1568 | return SUCCESS; | ||
| 1569 | } | ||
| 1570 | |||
| 1571 | int fdomain_16x0_host_reset(struct scsi_cmnd *SCpnt) | ||
| 1572 | { | ||
| 1573 | unsigned long flags; | ||
| 1574 | |||
| 1575 | local_irq_save(flags); | ||
| 1576 | |||
| 1577 | outb(1, port_base + SCSI_Cntl); | ||
| 1578 | do_pause( 2 ); | ||
| 1579 | outb(0, port_base + SCSI_Cntl); | ||
| 1580 | do_pause( 115 ); | ||
| 1581 | outb(0, port_base + SCSI_Mode_Cntl); | ||
| 1582 | outb(PARITY_MASK, port_base + TMC_Cntl); | ||
| 1583 | |||
| 1584 | local_irq_restore(flags); | ||
| 1585 | return SUCCESS; | ||
| 1586 | } | ||
| 1587 | |||
| 1588 | static int fdomain_16x0_biosparam(struct scsi_device *sdev, | ||
| 1589 | struct block_device *bdev, | ||
| 1590 | sector_t capacity, int *info_array) | ||
| 1591 | { | ||
| 1592 | int drive; | ||
| 1593 | int size = capacity; | ||
| 1594 | unsigned long offset; | ||
| 1595 | struct drive_info { | ||
| 1596 | unsigned short cylinders; | ||
| 1597 | unsigned char heads; | ||
| 1598 | unsigned char sectors; | ||
| 1599 | } i; | ||
| 1600 | |||
| 1601 | /* NOTES: | ||
| 1602 | The RAM area starts at 0x1f00 from the bios_base address. | ||
| 1603 | |||
| 1604 | For BIOS Version 2.0: | ||
| 1605 | |||
| 1606 | The drive parameter table seems to start at 0x1f30. | ||
| 1607 | The first byte's purpose is not known. | ||
| 1608 | Next is the cylinder, head, and sector information. | ||
| 1609 | The last 4 bytes appear to be the drive's size in sectors. | ||
| 1610 | The other bytes in the drive parameter table are unknown. | ||
| 1611 | If anyone figures them out, please send me mail, and I will | ||
| 1612 | update these notes. | ||
| 1613 | |||
| 1614 | Tape drives do not get placed in this table. | ||
| 1615 | |||
| 1616 | There is another table at 0x1fea: | ||
| 1617 | If the byte is 0x01, then the SCSI ID is not in use. | ||
| 1618 | If the byte is 0x18 or 0x48, then the SCSI ID is in use, | ||
| 1619 | although tapes don't seem to be in this table. I haven't | ||
| 1620 | seen any other numbers (in a limited sample). | ||
| 1621 | |||
| 1622 | 0x1f2d is a drive count (i.e., not including tapes) | ||
| 1623 | |||
| 1624 | The table at 0x1fcc are I/O ports addresses for the various | ||
| 1625 | operations. I calculate these by hand in this driver code. | ||
| 1626 | |||
| 1627 | |||
| 1628 | |||
| 1629 | For the ISA-200S version of BIOS Version 2.0: | ||
| 1630 | |||
| 1631 | The drive parameter table starts at 0x1f33. | ||
| 1632 | |||
| 1633 | WARNING: Assume that the table entry is 25 bytes long. Someone needs | ||
| 1634 | to check this for the Quantum ISA-200S card. | ||
| 1635 | |||
| 1636 | |||
| 1637 | |||
| 1638 | For BIOS Version 3.2: | ||
| 1639 | |||
| 1640 | The drive parameter table starts at 0x1f70. Each entry is | ||
| 1641 | 0x0a bytes long. Heads are one less than we need to report. | ||
| 1642 | */ | ||
| 1643 | |||
| 1644 | if (MAJOR(bdev->bd_dev) != SCSI_DISK0_MAJOR) { | ||
| 1645 | printk("scsi: <fdomain> fdomain_16x0_biosparam: too many disks"); | ||
| 1646 | return 0; | ||
| 1647 | } | ||
| 1648 | drive = MINOR(bdev->bd_dev) >> 4; | ||
| 1649 | |||
| 1650 | if (bios_major == 2) { | ||
| 1651 | switch (Quantum) { | ||
| 1652 | case 2: /* ISA_200S */ | ||
| 1653 | /* The value of 25 has never been verified. | ||
| 1654 | It should probably be 15. */ | ||
| 1655 | offset = 0x1f33 + drive * 25; | ||
| 1656 | break; | ||
| 1657 | case 3: /* ISA_250MG */ | ||
| 1658 | offset = 0x1f36 + drive * 15; | ||
| 1659 | break; | ||
| 1660 | case 4: /* ISA_200S (another one) */ | ||
| 1661 | offset = 0x1f34 + drive * 15; | ||
| 1662 | break; | ||
| 1663 | default: | ||
| 1664 | offset = 0x1f31 + drive * 25; | ||
| 1665 | break; | ||
| 1666 | } | ||
| 1667 | memcpy_fromio( &i, bios_mem + offset, sizeof( struct drive_info ) ); | ||
| 1668 | info_array[0] = i.heads; | ||
| 1669 | info_array[1] = i.sectors; | ||
| 1670 | info_array[2] = i.cylinders; | ||
| 1671 | } else if (bios_major == 3 | ||
| 1672 | && bios_minor >= 0 | ||
| 1673 | && bios_minor < 4) { /* 3.0 and 3.2 BIOS */ | ||
| 1674 | memcpy_fromio( &i, bios_mem + 0x1f71 + drive * 10, | ||
| 1675 | sizeof( struct drive_info ) ); | ||
| 1676 | info_array[0] = i.heads + 1; | ||
| 1677 | info_array[1] = i.sectors; | ||
| 1678 | info_array[2] = i.cylinders; | ||
| 1679 | } else { /* 3.4 BIOS (and up?) */ | ||
| 1680 | /* This algorithm was provided by Future Domain (much thanks!). */ | ||
| 1681 | unsigned char *p = scsi_bios_ptable(bdev); | ||
| 1682 | |||
| 1683 | if (p && p[65] == 0xaa && p[64] == 0x55 /* Partition table valid */ | ||
| 1684 | && p[4]) { /* Partition type */ | ||
| 1685 | |||
| 1686 | /* The partition table layout is as follows: | ||
| 1687 | |||
| 1688 | Start: 0x1b3h | ||
| 1689 | Offset: 0 = partition status | ||
| 1690 | 1 = starting head | ||
| 1691 | 2 = starting sector and cylinder (word, encoded) | ||
| 1692 | 4 = partition type | ||
| 1693 | 5 = ending head | ||
| 1694 | 6 = ending sector and cylinder (word, encoded) | ||
| 1695 | 8 = starting absolute sector (double word) | ||
| 1696 | c = number of sectors (double word) | ||
| 1697 | Signature: 0x1fe = 0x55aa | ||
| 1698 | |||
| 1699 | So, this algorithm assumes: | ||
| 1700 | 1) the first partition table is in use, | ||
| 1701 | 2) the data in the first entry is correct, and | ||
| 1702 | 3) partitions never divide cylinders | ||
| 1703 | |||
| 1704 | Note that (1) may be FALSE for NetBSD (and other BSD flavors), | ||
| 1705 | as well as for Linux. Note also, that Linux doesn't pay any | ||
| 1706 | attention to the fields that are used by this algorithm -- it | ||
| 1707 | only uses the absolute sector data. Recent versions of Linux's | ||
| 1708 | fdisk(1) will fill this data in correctly, and forthcoming | ||
| 1709 | versions will check for consistency. | ||
| 1710 | |||
| 1711 | Checking for a non-zero partition type is not part of the | ||
| 1712 | Future Domain algorithm, but it seemed to be a reasonable thing | ||
| 1713 | to do, especially in the Linux and BSD worlds. */ | ||
| 1714 | |||
| 1715 | info_array[0] = p[5] + 1; /* heads */ | ||
| 1716 | info_array[1] = p[6] & 0x3f; /* sectors */ | ||
| 1717 | } else { | ||
| 1718 | |||
| 1719 | /* Note that this new method guarantees that there will always be | ||
| 1720 | less than 1024 cylinders on a platter. This is good for drives | ||
| 1721 | up to approximately 7.85GB (where 1GB = 1024 * 1024 kB). */ | ||
| 1722 | |||
| 1723 | if ((unsigned int)size >= 0x7e0000U) { | ||
| 1724 | info_array[0] = 0xff; /* heads = 255 */ | ||
| 1725 | info_array[1] = 0x3f; /* sectors = 63 */ | ||
| 1726 | } else if ((unsigned int)size >= 0x200000U) { | ||
| 1727 | info_array[0] = 0x80; /* heads = 128 */ | ||
| 1728 | info_array[1] = 0x3f; /* sectors = 63 */ | ||
| 1729 | } else { | ||
| 1730 | info_array[0] = 0x40; /* heads = 64 */ | ||
| 1731 | info_array[1] = 0x20; /* sectors = 32 */ | ||
| 1732 | } | ||
| 1733 | } | ||
| 1734 | /* For both methods, compute the cylinders */ | ||
| 1735 | info_array[2] = (unsigned int)size / (info_array[0] * info_array[1] ); | ||
| 1736 | kfree(p); | ||
| 1737 | } | ||
| 1738 | |||
| 1739 | return 0; | ||
| 1740 | } | ||
| 1741 | |||
| 1742 | static int fdomain_16x0_release(struct Scsi_Host *shpnt) | ||
| 1743 | { | ||
| 1744 | if (shpnt->irq) | ||
| 1745 | free_irq(shpnt->irq, shpnt); | ||
| 1746 | if (shpnt->io_port && shpnt->n_io_port) | ||
| 1747 | release_region(shpnt->io_port, shpnt->n_io_port); | ||
| 1748 | if (PCI_bus) | ||
| 1749 | pci_dev_put(PCI_dev); | ||
| 1750 | return 0; | ||
| 1751 | } | ||
| 1752 | |||
| 1753 | struct scsi_host_template fdomain_driver_template = { | ||
| 1754 | .module = THIS_MODULE, | ||
| 1755 | .name = "fdomain", | ||
| 1756 | .proc_name = "fdomain", | ||
| 1757 | .detect = fdomain_16x0_detect, | ||
| 1758 | .info = fdomain_16x0_info, | ||
| 1759 | .queuecommand = fdomain_16x0_queue, | ||
| 1760 | .eh_abort_handler = fdomain_16x0_abort, | ||
| 1761 | .eh_host_reset_handler = fdomain_16x0_host_reset, | ||
| 1762 | .bios_param = fdomain_16x0_biosparam, | ||
| 1763 | .release = fdomain_16x0_release, | ||
| 1764 | .can_queue = 1, | ||
| 1765 | .this_id = 6, | ||
| 1766 | .sg_tablesize = 64, | ||
| 1767 | .use_clustering = DISABLE_CLUSTERING, | ||
| 1768 | }; | ||
| 1769 | |||
| 1770 | #ifndef PCMCIA | ||
| 1771 | #if defined(CONFIG_PCI) && defined(MODULE) | ||
| 1772 | |||
| 1773 | static struct pci_device_id fdomain_pci_tbl[] = { | ||
| 1774 | { PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, | ||
| 1775 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, | ||
| 1776 | { } | ||
| 1777 | }; | ||
| 1778 | MODULE_DEVICE_TABLE(pci, fdomain_pci_tbl); | ||
| 1779 | #endif | ||
| 1780 | #define driver_template fdomain_driver_template | ||
| 1781 | #include "scsi_module.c" | ||
| 1782 | |||
| 1783 | #endif | ||
diff --git a/drivers/scsi/fdomain.h b/drivers/scsi/fdomain.h deleted file mode 100644 index 5cbe86b573ae..000000000000 --- a/drivers/scsi/fdomain.h +++ /dev/null | |||
| @@ -1,24 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * fdomain.c -- Future Domain TMC-16x0 SCSI driver | ||
| 3 | * Author: Rickard E. Faith, faith@cs.unc.edu | ||
| 4 | * Copyright 1992-1996, 1998 Rickard E. Faith (faith@acm.org) | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms of the GNU General Public License as published by the | ||
| 8 | * Free Software Foundation; either version 2, or (at your option) any | ||
| 9 | * later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, but | ||
| 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 14 | * General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License along | ||
| 17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 18 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | extern struct scsi_host_template fdomain_driver_template; | ||
| 22 | extern int fdomain_setup(char *str); | ||
| 23 | extern struct Scsi_Host *__fdomain_16x0_detect(struct scsi_host_template *tpnt ); | ||
| 24 | extern int fdomain_16x0_host_reset(struct scsi_cmnd *SCpnt); | ||
diff --git a/drivers/scsi/hisi_sas/Kconfig b/drivers/scsi/hisi_sas/Kconfig index d42f29a5eb65..57183fce70fb 100644 --- a/drivers/scsi/hisi_sas/Kconfig +++ b/drivers/scsi/hisi_sas/Kconfig | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | config SCSI_HISI_SAS | 1 | config SCSI_HISI_SAS |
| 2 | tristate "HiSilicon SAS" | 2 | tristate "HiSilicon SAS" |
| 3 | depends on HAS_DMA && HAS_IOMEM | 3 | depends on HAS_IOMEM |
| 4 | depends on ARM64 || COMPILE_TEST | 4 | depends on ARM64 || COMPILE_TEST |
| 5 | select SCSI_SAS_LIBSAS | 5 | select SCSI_SAS_LIBSAS |
| 6 | select BLK_DEV_INTEGRITY | 6 | select BLK_DEV_INTEGRITY |
diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index e7fd2877c19c..d1153e8e846b 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h | |||
| @@ -175,7 +175,6 @@ struct hisi_sas_device { | |||
| 175 | struct hisi_sas_dq *dq; | 175 | struct hisi_sas_dq *dq; |
| 176 | struct list_head list; | 176 | struct list_head list; |
| 177 | u64 attached_phy; | 177 | u64 attached_phy; |
| 178 | atomic64_t running_req; | ||
| 179 | enum sas_device_type dev_type; | 178 | enum sas_device_type dev_type; |
| 180 | int device_id; | 179 | int device_id; |
| 181 | int sata_idx; | 180 | int sata_idx; |
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 2d4dbed03ee3..49c1fa643803 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c | |||
| @@ -33,7 +33,7 @@ u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis, int direction) | |||
| 33 | case ATA_CMD_FPDMA_RECV: | 33 | case ATA_CMD_FPDMA_RECV: |
| 34 | case ATA_CMD_FPDMA_SEND: | 34 | case ATA_CMD_FPDMA_SEND: |
| 35 | case ATA_CMD_NCQ_NON_DATA: | 35 | case ATA_CMD_NCQ_NON_DATA: |
| 36 | return HISI_SAS_SATA_PROTOCOL_FPDMA; | 36 | return HISI_SAS_SATA_PROTOCOL_FPDMA; |
| 37 | 37 | ||
| 38 | case ATA_CMD_DOWNLOAD_MICRO: | 38 | case ATA_CMD_DOWNLOAD_MICRO: |
| 39 | case ATA_CMD_ID_ATA: | 39 | case ATA_CMD_ID_ATA: |
| @@ -45,7 +45,7 @@ u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis, int direction) | |||
| 45 | case ATA_CMD_WRITE_LOG_EXT: | 45 | case ATA_CMD_WRITE_LOG_EXT: |
| 46 | case ATA_CMD_PIO_WRITE: | 46 | case ATA_CMD_PIO_WRITE: |
| 47 | case ATA_CMD_PIO_WRITE_EXT: | 47 | case ATA_CMD_PIO_WRITE_EXT: |
| 48 | return HISI_SAS_SATA_PROTOCOL_PIO; | 48 | return HISI_SAS_SATA_PROTOCOL_PIO; |
| 49 | 49 | ||
| 50 | case ATA_CMD_DSM: | 50 | case ATA_CMD_DSM: |
| 51 | case ATA_CMD_DOWNLOAD_MICRO_DMA: | 51 | case ATA_CMD_DOWNLOAD_MICRO_DMA: |
| @@ -64,7 +64,7 @@ u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis, int direction) | |||
| 64 | case ATA_CMD_WRITE_LOG_DMA_EXT: | 64 | case ATA_CMD_WRITE_LOG_DMA_EXT: |
| 65 | case ATA_CMD_WRITE_STREAM_DMA_EXT: | 65 | case ATA_CMD_WRITE_STREAM_DMA_EXT: |
| 66 | case ATA_CMD_ZAC_MGMT_IN: | 66 | case ATA_CMD_ZAC_MGMT_IN: |
| 67 | return HISI_SAS_SATA_PROTOCOL_DMA; | 67 | return HISI_SAS_SATA_PROTOCOL_DMA; |
| 68 | 68 | ||
| 69 | case ATA_CMD_CHK_POWER: | 69 | case ATA_CMD_CHK_POWER: |
| 70 | case ATA_CMD_DEV_RESET: | 70 | case ATA_CMD_DEV_RESET: |
| @@ -77,21 +77,21 @@ u8 hisi_sas_get_ata_protocol(struct host_to_dev_fis *fis, int direction) | |||
| 77 | case ATA_CMD_STANDBY: | 77 | case ATA_CMD_STANDBY: |
| 78 | case ATA_CMD_STANDBYNOW1: | 78 | case ATA_CMD_STANDBYNOW1: |
| 79 | case ATA_CMD_ZAC_MGMT_OUT: | 79 | case ATA_CMD_ZAC_MGMT_OUT: |
| 80 | return HISI_SAS_SATA_PROTOCOL_NONDATA; | 80 | return HISI_SAS_SATA_PROTOCOL_NONDATA; |
| 81 | default: | 81 | default: |
| 82 | { | 82 | { |
| 83 | if (fis->command == ATA_CMD_SET_MAX) { | 83 | if (fis->command == ATA_CMD_SET_MAX) { |
| 84 | switch (fis->features) { | 84 | switch (fis->features) { |
| 85 | case ATA_SET_MAX_PASSWD: | 85 | case ATA_SET_MAX_PASSWD: |
| 86 | case ATA_SET_MAX_LOCK: | 86 | case ATA_SET_MAX_LOCK: |
| 87 | return HISI_SAS_SATA_PROTOCOL_PIO; | 87 | return HISI_SAS_SATA_PROTOCOL_PIO; |
| 88 | 88 | ||
| 89 | case ATA_SET_MAX_PASSWD_DMA: | 89 | case ATA_SET_MAX_PASSWD_DMA: |
| 90 | case ATA_SET_MAX_UNLOCK_DMA: | 90 | case ATA_SET_MAX_UNLOCK_DMA: |
| 91 | return HISI_SAS_SATA_PROTOCOL_DMA; | 91 | return HISI_SAS_SATA_PROTOCOL_DMA; |
| 92 | 92 | ||
| 93 | default: | 93 | default: |
| 94 | return HISI_SAS_SATA_PROTOCOL_NONDATA; | 94 | return HISI_SAS_SATA_PROTOCOL_NONDATA; |
| 95 | } | 95 | } |
| 96 | } | 96 | } |
| 97 | if (direction == DMA_NONE) | 97 | if (direction == DMA_NONE) |
| @@ -200,8 +200,6 @@ void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task, | |||
| 200 | 200 | ||
| 201 | if (task) { | 201 | if (task) { |
| 202 | struct device *dev = hisi_hba->dev; | 202 | struct device *dev = hisi_hba->dev; |
| 203 | struct domain_device *device = task->dev; | ||
| 204 | struct hisi_sas_device *sas_dev = device->lldd_dev; | ||
| 205 | 203 | ||
| 206 | if (!task->lldd_task) | 204 | if (!task->lldd_task) |
| 207 | return; | 205 | return; |
| @@ -213,9 +211,6 @@ void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task, | |||
| 213 | dma_unmap_sg(dev, task->scatter, | 211 | dma_unmap_sg(dev, task->scatter, |
| 214 | task->num_scatter, | 212 | task->num_scatter, |
| 215 | task->data_dir); | 213 | task->data_dir); |
| 216 | |||
| 217 | if (sas_dev) | ||
| 218 | atomic64_dec(&sas_dev->running_req); | ||
| 219 | } | 214 | } |
| 220 | 215 | ||
| 221 | if (slot->buf) | 216 | if (slot->buf) |
| @@ -321,7 +316,7 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq | |||
| 321 | */ | 316 | */ |
| 322 | if (device->dev_type != SAS_SATA_DEV) | 317 | if (device->dev_type != SAS_SATA_DEV) |
| 323 | task->task_done(task); | 318 | task->task_done(task); |
| 324 | return SAS_PHY_DOWN; | 319 | return -ECOMM; |
| 325 | } | 320 | } |
| 326 | 321 | ||
| 327 | if (DEV_IS_GONE(sas_dev)) { | 322 | if (DEV_IS_GONE(sas_dev)) { |
| @@ -332,7 +327,7 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq | |||
| 332 | dev_info(dev, "task prep: device %016llx not ready\n", | 327 | dev_info(dev, "task prep: device %016llx not ready\n", |
| 333 | SAS_ADDR(device->sas_addr)); | 328 | SAS_ADDR(device->sas_addr)); |
| 334 | 329 | ||
| 335 | return SAS_PHY_DOWN; | 330 | return -ECOMM; |
| 336 | } | 331 | } |
| 337 | 332 | ||
| 338 | port = to_hisi_sas_port(sas_port); | 333 | port = to_hisi_sas_port(sas_port); |
| @@ -342,7 +337,7 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq | |||
| 342 | "SATA/STP" : "SAS", | 337 | "SATA/STP" : "SAS", |
| 343 | device->port->id); | 338 | device->port->id); |
| 344 | 339 | ||
| 345 | return SAS_PHY_DOWN; | 340 | return -ECOMM; |
| 346 | } | 341 | } |
| 347 | 342 | ||
| 348 | if (!sas_protocol_ata(task->task_proto)) { | 343 | if (!sas_protocol_ata(task->task_proto)) { |
| @@ -431,8 +426,6 @@ static int hisi_sas_task_prep(struct sas_task *task, struct hisi_sas_dq | |||
| 431 | spin_unlock_irqrestore(&task->task_state_lock, flags); | 426 | spin_unlock_irqrestore(&task->task_state_lock, flags); |
| 432 | 427 | ||
| 433 | dq->slot_prep = slot; | 428 | dq->slot_prep = slot; |
| 434 | |||
| 435 | atomic64_inc(&sas_dev->running_req); | ||
| 436 | ++(*pass); | 429 | ++(*pass); |
| 437 | 430 | ||
| 438 | return 0; | 431 | return 0; |
| @@ -683,6 +676,8 @@ static void hisi_sas_phy_init(struct hisi_hba *hisi_hba, int phy_no) | |||
| 683 | 676 | ||
| 684 | phy->hisi_hba = hisi_hba; | 677 | phy->hisi_hba = hisi_hba; |
| 685 | phy->port = NULL; | 678 | phy->port = NULL; |
| 679 | phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS; | ||
| 680 | phy->maximum_linkrate = hisi_hba->hw->phy_get_max_linkrate(); | ||
| 686 | sas_phy->enabled = (phy_no < hisi_hba->n_phy) ? 1 : 0; | 681 | sas_phy->enabled = (phy_no < hisi_hba->n_phy) ? 1 : 0; |
| 687 | sas_phy->class = SAS; | 682 | sas_phy->class = SAS; |
| 688 | sas_phy->iproto = SAS_PROTOCOL_ALL; | 683 | sas_phy->iproto = SAS_PROTOCOL_ALL; |
| @@ -869,6 +864,7 @@ static void hisi_sas_tmf_timedout(struct timer_list *t) | |||
| 869 | 864 | ||
| 870 | #define TASK_TIMEOUT 20 | 865 | #define TASK_TIMEOUT 20 |
| 871 | #define TASK_RETRY 3 | 866 | #define TASK_RETRY 3 |
| 867 | #define INTERNAL_ABORT_TIMEOUT 6 | ||
| 872 | static int hisi_sas_exec_internal_tmf_task(struct domain_device *device, | 868 | static int hisi_sas_exec_internal_tmf_task(struct domain_device *device, |
| 873 | void *parameter, u32 para_len, | 869 | void *parameter, u32 para_len, |
| 874 | struct hisi_sas_tmf_task *tmf) | 870 | struct hisi_sas_tmf_task *tmf) |
| @@ -1514,8 +1510,6 @@ hisi_sas_internal_abort_task_exec(struct hisi_hba *hisi_hba, int device_id, | |||
| 1514 | 1510 | ||
| 1515 | dq->slot_prep = slot; | 1511 | dq->slot_prep = slot; |
| 1516 | 1512 | ||
| 1517 | atomic64_inc(&sas_dev->running_req); | ||
| 1518 | |||
| 1519 | /* send abort command to the chip */ | 1513 | /* send abort command to the chip */ |
| 1520 | hisi_hba->hw->start_delivery(dq); | 1514 | hisi_hba->hw->start_delivery(dq); |
| 1521 | spin_unlock_irqrestore(&dq->lock, flags_dq); | 1515 | spin_unlock_irqrestore(&dq->lock, flags_dq); |
| @@ -1572,7 +1566,7 @@ hisi_sas_internal_task_abort(struct hisi_hba *hisi_hba, | |||
| 1572 | task->task_proto = device->tproto; | 1566 | task->task_proto = device->tproto; |
| 1573 | task->task_done = hisi_sas_task_done; | 1567 | task->task_done = hisi_sas_task_done; |
| 1574 | task->slow_task->timer.function = hisi_sas_tmf_timedout; | 1568 | task->slow_task->timer.function = hisi_sas_tmf_timedout; |
| 1575 | task->slow_task->timer.expires = jiffies + msecs_to_jiffies(110); | 1569 | task->slow_task->timer.expires = jiffies + INTERNAL_ABORT_TIMEOUT*HZ; |
| 1576 | add_timer(&task->slow_task->timer); | 1570 | add_timer(&task->slow_task->timer); |
| 1577 | 1571 | ||
| 1578 | res = hisi_sas_internal_abort_task_exec(hisi_hba, sas_dev->device_id, | 1572 | res = hisi_sas_internal_abort_task_exec(hisi_hba, sas_dev->device_id, |
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 679e76f58a0a..84a0ccc4daf5 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | |||
| @@ -651,8 +651,10 @@ static int reset_hw_v1_hw(struct hisi_hba *hisi_hba) | |||
| 651 | dev_err(dev, "De-reset failed\n"); | 651 | dev_err(dev, "De-reset failed\n"); |
| 652 | return -EIO; | 652 | return -EIO; |
| 653 | } | 653 | } |
| 654 | } else | 654 | } else { |
| 655 | dev_warn(dev, "no reset method\n"); | 655 | dev_warn(dev, "no reset method\n"); |
| 656 | return -EINVAL; | ||
| 657 | } | ||
| 656 | 658 | ||
| 657 | return 0; | 659 | return 0; |
| 658 | } | 660 | } |
| @@ -873,7 +875,6 @@ static void phy_set_linkrate_v1_hw(struct hisi_hba *hisi_hba, int phy_no, | |||
| 873 | sas_phy->phy->maximum_linkrate = max; | 875 | sas_phy->phy->maximum_linkrate = max; |
| 874 | sas_phy->phy->minimum_linkrate = min; | 876 | sas_phy->phy->minimum_linkrate = min; |
| 875 | 877 | ||
| 876 | min -= SAS_LINK_RATE_1_5_GBPS; | ||
| 877 | max -= SAS_LINK_RATE_1_5_GBPS; | 878 | max -= SAS_LINK_RATE_1_5_GBPS; |
| 878 | 879 | ||
| 879 | for (i = 0; i <= max; i++) | 880 | for (i = 0; i <= max; i++) |
| @@ -882,10 +883,11 @@ static void phy_set_linkrate_v1_hw(struct hisi_hba *hisi_hba, int phy_no, | |||
| 882 | prog_phy_link_rate &= ~0xff; | 883 | prog_phy_link_rate &= ~0xff; |
| 883 | prog_phy_link_rate |= rate_mask; | 884 | prog_phy_link_rate |= rate_mask; |
| 884 | 885 | ||
| 886 | disable_phy_v1_hw(hisi_hba, phy_no); | ||
| 887 | msleep(100); | ||
| 885 | hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE, | 888 | hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE, |
| 886 | prog_phy_link_rate); | 889 | prog_phy_link_rate); |
| 887 | 890 | start_phy_v1_hw(hisi_hba, phy_no); | |
| 888 | phy_hard_reset_v1_hw(hisi_hba, phy_no); | ||
| 889 | } | 891 | } |
| 890 | 892 | ||
| 891 | static int get_wideport_bitmap_v1_hw(struct hisi_hba *hisi_hba, int port_id) | 893 | static int get_wideport_bitmap_v1_hw(struct hisi_hba *hisi_hba, int port_id) |
| @@ -1407,9 +1409,6 @@ static int slot_complete_v1_hw(struct hisi_hba *hisi_hba, | |||
| 1407 | } | 1409 | } |
| 1408 | 1410 | ||
| 1409 | out: | 1411 | out: |
| 1410 | if (sas_dev) | ||
| 1411 | atomic64_dec(&sas_dev->running_req); | ||
| 1412 | |||
| 1413 | hisi_sas_slot_task_free(hisi_hba, task, slot); | 1412 | hisi_sas_slot_task_free(hisi_hba, task, slot); |
| 1414 | sts = ts->stat; | 1413 | sts = ts->stat; |
| 1415 | 1414 | ||
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index 4ccb61e2ae5c..f89fb9a49ea9 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | |||
| @@ -406,6 +406,17 @@ struct hisi_sas_err_record_v2 { | |||
| 406 | __le32 dma_rx_err_type; | 406 | __le32 dma_rx_err_type; |
| 407 | }; | 407 | }; |
| 408 | 408 | ||
| 409 | struct signal_attenuation_s { | ||
| 410 | u32 de_emphasis; | ||
| 411 | u32 preshoot; | ||
| 412 | u32 boost; | ||
| 413 | }; | ||
| 414 | |||
| 415 | struct sig_atten_lu_s { | ||
| 416 | const struct signal_attenuation_s *att; | ||
| 417 | u32 sas_phy_ctrl; | ||
| 418 | }; | ||
| 419 | |||
| 409 | static const struct hisi_sas_hw_error one_bit_ecc_errors[] = { | 420 | static const struct hisi_sas_hw_error one_bit_ecc_errors[] = { |
| 410 | { | 421 | { |
| 411 | .irq_msk = BIT(SAS_ECC_INTR_DQE_ECC_1B_OFF), | 422 | .irq_msk = BIT(SAS_ECC_INTR_DQE_ECC_1B_OFF), |
| @@ -1084,8 +1095,10 @@ static int reset_hw_v2_hw(struct hisi_hba *hisi_hba) | |||
| 1084 | dev_err(dev, "SAS de-reset fail.\n"); | 1095 | dev_err(dev, "SAS de-reset fail.\n"); |
| 1085 | return -EIO; | 1096 | return -EIO; |
| 1086 | } | 1097 | } |
| 1087 | } else | 1098 | } else { |
| 1088 | dev_warn(dev, "no reset method\n"); | 1099 | dev_err(dev, "no reset method\n"); |
| 1100 | return -EINVAL; | ||
| 1101 | } | ||
| 1089 | 1102 | ||
| 1090 | return 0; | 1103 | return 0; |
| 1091 | } | 1104 | } |
| @@ -1130,9 +1143,16 @@ static void phys_try_accept_stp_links_v2_hw(struct hisi_hba *hisi_hba) | |||
| 1130 | } | 1143 | } |
| 1131 | } | 1144 | } |
| 1132 | 1145 | ||
| 1146 | static const struct signal_attenuation_s x6000 = {9200, 0, 10476}; | ||
| 1147 | static const struct sig_atten_lu_s sig_atten_lu[] = { | ||
| 1148 | { &x6000, 0x3016a68 }, | ||
| 1149 | }; | ||
| 1150 | |||
| 1133 | static void init_reg_v2_hw(struct hisi_hba *hisi_hba) | 1151 | static void init_reg_v2_hw(struct hisi_hba *hisi_hba) |
| 1134 | { | 1152 | { |
| 1135 | struct device *dev = hisi_hba->dev; | 1153 | struct device *dev = hisi_hba->dev; |
| 1154 | u32 sas_phy_ctrl = 0x30b9908; | ||
| 1155 | u32 signal[3]; | ||
| 1136 | int i; | 1156 | int i; |
| 1137 | 1157 | ||
| 1138 | /* Global registers init */ | 1158 | /* Global registers init */ |
| @@ -1176,9 +1196,28 @@ static void init_reg_v2_hw(struct hisi_hba *hisi_hba) | |||
| 1176 | hisi_sas_write32(hisi_hba, AXI_AHB_CLK_CFG, 1); | 1196 | hisi_sas_write32(hisi_hba, AXI_AHB_CLK_CFG, 1); |
| 1177 | hisi_sas_write32(hisi_hba, HYPER_STREAM_ID_EN_CFG, 1); | 1197 | hisi_sas_write32(hisi_hba, HYPER_STREAM_ID_EN_CFG, 1); |
| 1178 | 1198 | ||
| 1199 | /* Get sas_phy_ctrl value to deal with TX FFE issue. */ | ||
| 1200 | if (!device_property_read_u32_array(dev, "hisilicon,signal-attenuation", | ||
| 1201 | signal, ARRAY_SIZE(signal))) { | ||
| 1202 | for (i = 0; i < ARRAY_SIZE(sig_atten_lu); i++) { | ||
| 1203 | const struct sig_atten_lu_s *lookup = &sig_atten_lu[i]; | ||
| 1204 | const struct signal_attenuation_s *att = lookup->att; | ||
| 1205 | |||
| 1206 | if ((signal[0] == att->de_emphasis) && | ||
| 1207 | (signal[1] == att->preshoot) && | ||
| 1208 | (signal[2] == att->boost)) { | ||
| 1209 | sas_phy_ctrl = lookup->sas_phy_ctrl; | ||
| 1210 | break; | ||
| 1211 | } | ||
| 1212 | } | ||
| 1213 | |||
| 1214 | if (i == ARRAY_SIZE(sig_atten_lu)) | ||
| 1215 | dev_warn(dev, "unknown signal attenuation values, using default PHY ctrl config\n"); | ||
| 1216 | } | ||
| 1217 | |||
| 1179 | for (i = 0; i < hisi_hba->n_phy; i++) { | 1218 | for (i = 0; i < hisi_hba->n_phy; i++) { |
| 1180 | hisi_sas_phy_write32(hisi_hba, i, PROG_PHY_LINK_RATE, 0x855); | 1219 | hisi_sas_phy_write32(hisi_hba, i, PROG_PHY_LINK_RATE, 0x855); |
| 1181 | hisi_sas_phy_write32(hisi_hba, i, SAS_PHY_CTRL, 0x30b9908); | 1220 | hisi_sas_phy_write32(hisi_hba, i, SAS_PHY_CTRL, sas_phy_ctrl); |
| 1182 | hisi_sas_phy_write32(hisi_hba, i, SL_TOUT_CFG, 0x7d7d7d7d); | 1221 | hisi_sas_phy_write32(hisi_hba, i, SL_TOUT_CFG, 0x7d7d7d7d); |
| 1183 | hisi_sas_phy_write32(hisi_hba, i, SL_CONTROL, 0x0); | 1222 | hisi_sas_phy_write32(hisi_hba, i, SL_CONTROL, 0x0); |
| 1184 | hisi_sas_phy_write32(hisi_hba, i, TXID_AUTO, 0x2); | 1223 | hisi_sas_phy_write32(hisi_hba, i, TXID_AUTO, 0x2); |
| @@ -1566,7 +1605,6 @@ static void phy_set_linkrate_v2_hw(struct hisi_hba *hisi_hba, int phy_no, | |||
| 1566 | sas_phy->phy->maximum_linkrate = max; | 1605 | sas_phy->phy->maximum_linkrate = max; |
| 1567 | sas_phy->phy->minimum_linkrate = min; | 1606 | sas_phy->phy->minimum_linkrate = min; |
| 1568 | 1607 | ||
| 1569 | min -= SAS_LINK_RATE_1_5_GBPS; | ||
| 1570 | max -= SAS_LINK_RATE_1_5_GBPS; | 1608 | max -= SAS_LINK_RATE_1_5_GBPS; |
| 1571 | 1609 | ||
| 1572 | for (i = 0; i <= max; i++) | 1610 | for (i = 0; i <= max; i++) |
| @@ -1575,10 +1613,11 @@ static void phy_set_linkrate_v2_hw(struct hisi_hba *hisi_hba, int phy_no, | |||
| 1575 | prog_phy_link_rate &= ~0xff; | 1613 | prog_phy_link_rate &= ~0xff; |
| 1576 | prog_phy_link_rate |= rate_mask; | 1614 | prog_phy_link_rate |= rate_mask; |
| 1577 | 1615 | ||
| 1616 | disable_phy_v2_hw(hisi_hba, phy_no); | ||
| 1617 | msleep(100); | ||
| 1578 | hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE, | 1618 | hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE, |
| 1579 | prog_phy_link_rate); | 1619 | prog_phy_link_rate); |
| 1580 | 1620 | start_phy_v2_hw(hisi_hba, phy_no); | |
| 1581 | phy_hard_reset_v2_hw(hisi_hba, phy_no); | ||
| 1582 | } | 1621 | } |
| 1583 | 1622 | ||
| 1584 | static int get_wideport_bitmap_v2_hw(struct hisi_hba *hisi_hba, int port_id) | 1623 | static int get_wideport_bitmap_v2_hw(struct hisi_hba *hisi_hba, int port_id) |
| @@ -2371,7 +2410,7 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) | |||
| 2371 | spin_lock_irqsave(&hisi_hba->lock, flags); | 2410 | spin_lock_irqsave(&hisi_hba->lock, flags); |
| 2372 | hisi_sas_slot_task_free(hisi_hba, task, slot); | 2411 | hisi_sas_slot_task_free(hisi_hba, task, slot); |
| 2373 | spin_unlock_irqrestore(&hisi_hba->lock, flags); | 2412 | spin_unlock_irqrestore(&hisi_hba->lock, flags); |
| 2374 | return -1; | 2413 | return ts->stat; |
| 2375 | } | 2414 | } |
| 2376 | 2415 | ||
| 2377 | if (unlikely(!sas_dev)) { | 2416 | if (unlikely(!sas_dev)) { |
| @@ -2630,7 +2669,7 @@ static int prep_abort_v2_hw(struct hisi_hba *hisi_hba, | |||
| 2630 | /* dw0 */ | 2669 | /* dw0 */ |
| 2631 | hdr->dw0 = cpu_to_le32((5 << CMD_HDR_CMD_OFF) | /*abort*/ | 2670 | hdr->dw0 = cpu_to_le32((5 << CMD_HDR_CMD_OFF) | /*abort*/ |
| 2632 | (port->id << CMD_HDR_PORT_OFF) | | 2671 | (port->id << CMD_HDR_PORT_OFF) | |
| 2633 | ((dev_is_sata(dev) ? 1:0) << | 2672 | (dev_is_sata(dev) << |
| 2634 | CMD_HDR_ABORT_DEVICE_TYPE_OFF) | | 2673 | CMD_HDR_ABORT_DEVICE_TYPE_OFF) | |
| 2635 | (abort_flag << CMD_HDR_ABORT_FLAG_OFF)); | 2674 | (abort_flag << CMD_HDR_ABORT_FLAG_OFF)); |
| 2636 | 2675 | ||
| @@ -2647,7 +2686,7 @@ static int prep_abort_v2_hw(struct hisi_hba *hisi_hba, | |||
| 2647 | static int phy_up_v2_hw(int phy_no, struct hisi_hba *hisi_hba) | 2686 | static int phy_up_v2_hw(int phy_no, struct hisi_hba *hisi_hba) |
| 2648 | { | 2687 | { |
| 2649 | int i, res = IRQ_HANDLED; | 2688 | int i, res = IRQ_HANDLED; |
| 2650 | u32 port_id, link_rate, hard_phy_linkrate; | 2689 | u32 port_id, link_rate; |
| 2651 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; | 2690 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; |
| 2652 | struct asd_sas_phy *sas_phy = &phy->sas_phy; | 2691 | struct asd_sas_phy *sas_phy = &phy->sas_phy; |
| 2653 | struct device *dev = hisi_hba->dev; | 2692 | struct device *dev = hisi_hba->dev; |
| @@ -2686,11 +2725,6 @@ static int phy_up_v2_hw(int phy_no, struct hisi_hba *hisi_hba) | |||
| 2686 | } | 2725 | } |
| 2687 | 2726 | ||
| 2688 | sas_phy->linkrate = link_rate; | 2727 | sas_phy->linkrate = link_rate; |
| 2689 | hard_phy_linkrate = hisi_sas_phy_read32(hisi_hba, phy_no, | ||
| 2690 | HARD_PHY_LINKRATE); | ||
| 2691 | phy->maximum_linkrate = hard_phy_linkrate & 0xf; | ||
| 2692 | phy->minimum_linkrate = (hard_phy_linkrate >> 4) & 0xf; | ||
| 2693 | |||
| 2694 | sas_phy->oob_mode = SAS_OOB_MODE; | 2728 | sas_phy->oob_mode = SAS_OOB_MODE; |
| 2695 | memcpy(sas_phy->attached_sas_addr, &id->sas_addr, SAS_ADDR_SIZE); | 2729 | memcpy(sas_phy->attached_sas_addr, &id->sas_addr, SAS_ADDR_SIZE); |
| 2696 | dev_info(dev, "phyup: phy%d link_rate=%d\n", phy_no, link_rate); | 2730 | dev_info(dev, "phyup: phy%d link_rate=%d\n", phy_no, link_rate); |
diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index a1f18689729a..6f3e5ba6b472 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | |||
| @@ -172,6 +172,7 @@ | |||
| 172 | #define CHL_INT1_MSK (PORT_BASE + 0x1c4) | 172 | #define CHL_INT1_MSK (PORT_BASE + 0x1c4) |
| 173 | #define CHL_INT2_MSK (PORT_BASE + 0x1c8) | 173 | #define CHL_INT2_MSK (PORT_BASE + 0x1c8) |
| 174 | #define CHL_INT_COAL_EN (PORT_BASE + 0x1d0) | 174 | #define CHL_INT_COAL_EN (PORT_BASE + 0x1d0) |
| 175 | #define SAS_RX_TRAIN_TIMER (PORT_BASE + 0x2a4) | ||
| 175 | #define PHY_CTRL_RDY_MSK (PORT_BASE + 0x2b0) | 176 | #define PHY_CTRL_RDY_MSK (PORT_BASE + 0x2b0) |
| 176 | #define PHYCTRL_NOT_RDY_MSK (PORT_BASE + 0x2b4) | 177 | #define PHYCTRL_NOT_RDY_MSK (PORT_BASE + 0x2b4) |
| 177 | #define PHYCTRL_DWS_RESET_MSK (PORT_BASE + 0x2b8) | 178 | #define PHYCTRL_DWS_RESET_MSK (PORT_BASE + 0x2b8) |
| @@ -184,6 +185,8 @@ | |||
| 184 | #define DMA_RX_STATUS (PORT_BASE + 0x2e8) | 185 | #define DMA_RX_STATUS (PORT_BASE + 0x2e8) |
| 185 | #define DMA_RX_STATUS_BUSY_OFF 0 | 186 | #define DMA_RX_STATUS_BUSY_OFF 0 |
| 186 | #define DMA_RX_STATUS_BUSY_MSK (0x1 << DMA_RX_STATUS_BUSY_OFF) | 187 | #define DMA_RX_STATUS_BUSY_MSK (0x1 << DMA_RX_STATUS_BUSY_OFF) |
| 188 | |||
| 189 | #define COARSETUNE_TIME (PORT_BASE + 0x304) | ||
| 187 | #define ERR_CNT_DWS_LOST (PORT_BASE + 0x380) | 190 | #define ERR_CNT_DWS_LOST (PORT_BASE + 0x380) |
| 188 | #define ERR_CNT_RESET_PROB (PORT_BASE + 0x384) | 191 | #define ERR_CNT_RESET_PROB (PORT_BASE + 0x384) |
| 189 | #define ERR_CNT_INVLD_DW (PORT_BASE + 0x390) | 192 | #define ERR_CNT_INVLD_DW (PORT_BASE + 0x390) |
| @@ -340,12 +343,6 @@ struct hisi_sas_err_record_v3 { | |||
| 340 | #define HISI_SAS_COMMAND_ENTRIES_V3_HW 4096 | 343 | #define HISI_SAS_COMMAND_ENTRIES_V3_HW 4096 |
| 341 | #define HISI_SAS_MSI_COUNT_V3_HW 32 | 344 | #define HISI_SAS_MSI_COUNT_V3_HW 32 |
| 342 | 345 | ||
| 343 | enum { | ||
| 344 | HISI_SAS_PHY_PHY_UPDOWN, | ||
| 345 | HISI_SAS_PHY_CHNL_INT, | ||
| 346 | HISI_SAS_PHY_INT_NR | ||
| 347 | }; | ||
| 348 | |||
| 349 | #define DIR_NO_DATA 0 | 346 | #define DIR_NO_DATA 0 |
| 350 | #define DIR_TO_INI 1 | 347 | #define DIR_TO_INI 1 |
| 351 | #define DIR_TO_DEVICE 2 | 348 | #define DIR_TO_DEVICE 2 |
| @@ -423,10 +420,10 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba) | |||
| 423 | hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK+0x4*i, 0); | 420 | hisi_sas_write32(hisi_hba, OQ0_INT_SRC_MSK+0x4*i, 0); |
| 424 | 421 | ||
| 425 | hisi_sas_write32(hisi_hba, HYPER_STREAM_ID_EN_CFG, 1); | 422 | hisi_sas_write32(hisi_hba, HYPER_STREAM_ID_EN_CFG, 1); |
| 426 | hisi_sas_write32(hisi_hba, AXI_MASTER_CFG_BASE, 0x30000); | ||
| 427 | 423 | ||
| 428 | for (i = 0; i < hisi_hba->n_phy; i++) { | 424 | for (i = 0; i < hisi_hba->n_phy; i++) { |
| 429 | hisi_sas_phy_write32(hisi_hba, i, PROG_PHY_LINK_RATE, 0x801); | 425 | hisi_sas_phy_write32(hisi_hba, i, PROG_PHY_LINK_RATE, 0x855); |
| 426 | hisi_sas_phy_write32(hisi_hba, i, SAS_RX_TRAIN_TIMER, 0x13e80); | ||
| 430 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT0, 0xffffffff); | 427 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT0, 0xffffffff); |
| 431 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT1, 0xffffffff); | 428 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT1, 0xffffffff); |
| 432 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, 0xffffffff); | 429 | hisi_sas_phy_write32(hisi_hba, i, CHL_INT2, 0xffffffff); |
| @@ -438,17 +435,13 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba) | |||
| 438 | hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_DWS_RESET_MSK, 0x0); | 435 | hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_DWS_RESET_MSK, 0x0); |
| 439 | hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_PHY_ENA_MSK, 0x0); | 436 | hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_PHY_ENA_MSK, 0x0); |
| 440 | hisi_sas_phy_write32(hisi_hba, i, SL_RX_BCAST_CHK_MSK, 0x0); | 437 | hisi_sas_phy_write32(hisi_hba, i, SL_RX_BCAST_CHK_MSK, 0x0); |
| 441 | hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_OOB_RESTART_MSK, 0x0); | 438 | hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_OOB_RESTART_MSK, 0x1); |
| 442 | hisi_sas_phy_write32(hisi_hba, i, PHY_CTRL, 0x199b4fa); | 439 | hisi_sas_phy_write32(hisi_hba, i, STP_LINK_TIMER, 0x7f7a120); |
| 443 | hisi_sas_phy_write32(hisi_hba, i, SAS_SSP_CON_TIMER_CFG, | 440 | |
| 444 | 0xa03e8); | 441 | /* used for 12G negotiate */ |
| 445 | hisi_sas_phy_write32(hisi_hba, i, SAS_STP_CON_TIMER_CFG, | 442 | hisi_sas_phy_write32(hisi_hba, i, COARSETUNE_TIME, 0x1e); |
| 446 | 0xa03e8); | ||
| 447 | hisi_sas_phy_write32(hisi_hba, i, STP_LINK_TIMER, | ||
| 448 | 0x7f7a120); | ||
| 449 | hisi_sas_phy_write32(hisi_hba, i, CON_CFG_DRIVER, | ||
| 450 | 0x2a0a80); | ||
| 451 | } | 443 | } |
| 444 | |||
| 452 | for (i = 0; i < hisi_hba->queue_count; i++) { | 445 | for (i = 0; i < hisi_hba->queue_count; i++) { |
| 453 | /* Delivery queue */ | 446 | /* Delivery queue */ |
| 454 | hisi_sas_write32(hisi_hba, | 447 | hisi_sas_write32(hisi_hba, |
| @@ -676,8 +669,10 @@ static int reset_hw_v3_hw(struct hisi_hba *hisi_hba) | |||
| 676 | dev_err(dev, "Reset failed\n"); | 669 | dev_err(dev, "Reset failed\n"); |
| 677 | return -EIO; | 670 | return -EIO; |
| 678 | } | 671 | } |
| 679 | } else | 672 | } else { |
| 680 | dev_err(dev, "no reset method!\n"); | 673 | dev_err(dev, "no reset method!\n"); |
| 674 | return -EINVAL; | ||
| 675 | } | ||
| 681 | 676 | ||
| 682 | return 0; | 677 | return 0; |
| 683 | } | 678 | } |
| @@ -737,7 +732,7 @@ static void phy_hard_reset_v3_hw(struct hisi_hba *hisi_hba, int phy_no) | |||
| 737 | start_phy_v3_hw(hisi_hba, phy_no); | 732 | start_phy_v3_hw(hisi_hba, phy_no); |
| 738 | } | 733 | } |
| 739 | 734 | ||
| 740 | enum sas_linkrate phy_get_max_linkrate_v3_hw(void) | 735 | static enum sas_linkrate phy_get_max_linkrate_v3_hw(void) |
| 741 | { | 736 | { |
| 742 | return SAS_LINK_RATE_12_0_GBPS; | 737 | return SAS_LINK_RATE_12_0_GBPS; |
| 743 | } | 738 | } |
| @@ -1102,7 +1097,7 @@ static int prep_abort_v3_hw(struct hisi_hba *hisi_hba, | |||
| 1102 | /* dw0 */ | 1097 | /* dw0 */ |
| 1103 | hdr->dw0 = cpu_to_le32((5 << CMD_HDR_CMD_OFF) | /*abort*/ | 1098 | hdr->dw0 = cpu_to_le32((5 << CMD_HDR_CMD_OFF) | /*abort*/ |
| 1104 | (port->id << CMD_HDR_PORT_OFF) | | 1099 | (port->id << CMD_HDR_PORT_OFF) | |
| 1105 | ((dev_is_sata(dev) ? 1:0) | 1100 | (dev_is_sata(dev) |
| 1106 | << CMD_HDR_ABORT_DEVICE_TYPE_OFF) | | 1101 | << CMD_HDR_ABORT_DEVICE_TYPE_OFF) | |
| 1107 | (abort_flag | 1102 | (abort_flag |
| 1108 | << CMD_HDR_ABORT_FLAG_OFF)); | 1103 | << CMD_HDR_ABORT_FLAG_OFF)); |
| @@ -1118,10 +1113,10 @@ static int prep_abort_v3_hw(struct hisi_hba *hisi_hba, | |||
| 1118 | return 0; | 1113 | return 0; |
| 1119 | } | 1114 | } |
| 1120 | 1115 | ||
| 1121 | static int phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) | 1116 | static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) |
| 1122 | { | 1117 | { |
| 1123 | int i, res = 0; | 1118 | int i, res; |
| 1124 | u32 context, port_id, link_rate, hard_phy_linkrate; | 1119 | u32 context, port_id, link_rate; |
| 1125 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; | 1120 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; |
| 1126 | struct asd_sas_phy *sas_phy = &phy->sas_phy; | 1121 | struct asd_sas_phy *sas_phy = &phy->sas_phy; |
| 1127 | struct device *dev = hisi_hba->dev; | 1122 | struct device *dev = hisi_hba->dev; |
| @@ -1139,10 +1134,6 @@ static int phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) | |||
| 1139 | goto end; | 1134 | goto end; |
| 1140 | } | 1135 | } |
| 1141 | sas_phy->linkrate = link_rate; | 1136 | sas_phy->linkrate = link_rate; |
| 1142 | hard_phy_linkrate = hisi_sas_phy_read32(hisi_hba, phy_no, | ||
| 1143 | HARD_PHY_LINKRATE); | ||
| 1144 | phy->maximum_linkrate = hard_phy_linkrate & 0xf; | ||
| 1145 | phy->minimum_linkrate = (hard_phy_linkrate >> 4) & 0xf; | ||
| 1146 | phy->phy_type &= ~(PORT_TYPE_SAS | PORT_TYPE_SATA); | 1137 | phy->phy_type &= ~(PORT_TYPE_SAS | PORT_TYPE_SATA); |
| 1147 | 1138 | ||
| 1148 | /* Check for SATA dev */ | 1139 | /* Check for SATA dev */ |
| @@ -1196,7 +1187,7 @@ static int phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) | |||
| 1196 | phy->port_id = port_id; | 1187 | phy->port_id = port_id; |
| 1197 | phy->phy_attached = 1; | 1188 | phy->phy_attached = 1; |
| 1198 | hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP); | 1189 | hisi_sas_notify_phy_event(phy, HISI_PHYE_PHY_UP); |
| 1199 | 1190 | res = IRQ_HANDLED; | |
| 1200 | end: | 1191 | end: |
| 1201 | hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, | 1192 | hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, |
| 1202 | CHL_INT0_SL_PHY_ENABLE_MSK); | 1193 | CHL_INT0_SL_PHY_ENABLE_MSK); |
| @@ -1205,7 +1196,7 @@ end: | |||
| 1205 | return res; | 1196 | return res; |
| 1206 | } | 1197 | } |
| 1207 | 1198 | ||
| 1208 | static int phy_down_v3_hw(int phy_no, struct hisi_hba *hisi_hba) | 1199 | static irqreturn_t phy_down_v3_hw(int phy_no, struct hisi_hba *hisi_hba) |
| 1209 | { | 1200 | { |
| 1210 | u32 phy_state, sl_ctrl, txid_auto; | 1201 | u32 phy_state, sl_ctrl, txid_auto; |
| 1211 | struct device *dev = hisi_hba->dev; | 1202 | struct device *dev = hisi_hba->dev; |
| @@ -1227,10 +1218,10 @@ static int phy_down_v3_hw(int phy_no, struct hisi_hba *hisi_hba) | |||
| 1227 | hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, CHL_INT0_NOT_RDY_MSK); | 1218 | hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, CHL_INT0_NOT_RDY_MSK); |
| 1228 | hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_NOT_RDY_MSK, 0); | 1219 | hisi_sas_phy_write32(hisi_hba, phy_no, PHYCTRL_NOT_RDY_MSK, 0); |
| 1229 | 1220 | ||
| 1230 | return 0; | 1221 | return IRQ_HANDLED; |
| 1231 | } | 1222 | } |
| 1232 | 1223 | ||
| 1233 | static void phy_bcast_v3_hw(int phy_no, struct hisi_hba *hisi_hba) | 1224 | static irqreturn_t phy_bcast_v3_hw(int phy_no, struct hisi_hba *hisi_hba) |
| 1234 | { | 1225 | { |
| 1235 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; | 1226 | struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; |
| 1236 | struct asd_sas_phy *sas_phy = &phy->sas_phy; | 1227 | struct asd_sas_phy *sas_phy = &phy->sas_phy; |
| @@ -1241,6 +1232,8 @@ static void phy_bcast_v3_hw(int phy_no, struct hisi_hba *hisi_hba) | |||
| 1241 | hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, | 1232 | hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT0, |
| 1242 | CHL_INT0_SL_RX_BCST_ACK_MSK); | 1233 | CHL_INT0_SL_RX_BCST_ACK_MSK); |
| 1243 | hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0); | 1234 | hisi_sas_phy_write32(hisi_hba, phy_no, SL_RX_BCAST_CHK_MSK, 0); |
| 1235 | |||
| 1236 | return IRQ_HANDLED; | ||
| 1244 | } | 1237 | } |
| 1245 | 1238 | ||
| 1246 | static irqreturn_t int_phy_up_down_bcast_v3_hw(int irq_no, void *p) | 1239 | static irqreturn_t int_phy_up_down_bcast_v3_hw(int irq_no, void *p) |
| @@ -1267,7 +1260,9 @@ static irqreturn_t int_phy_up_down_bcast_v3_hw(int irq_no, void *p) | |||
| 1267 | res = IRQ_HANDLED; | 1260 | res = IRQ_HANDLED; |
| 1268 | if (irq_value & CHL_INT0_SL_RX_BCST_ACK_MSK) | 1261 | if (irq_value & CHL_INT0_SL_RX_BCST_ACK_MSK) |
| 1269 | /* phy bcast */ | 1262 | /* phy bcast */ |
| 1270 | phy_bcast_v3_hw(phy_no, hisi_hba); | 1263 | if (phy_bcast_v3_hw(phy_no, hisi_hba) |
| 1264 | == IRQ_HANDLED) | ||
| 1265 | res = IRQ_HANDLED; | ||
| 1271 | } else { | 1266 | } else { |
| 1272 | if (irq_value & CHL_INT0_NOT_RDY_MSK) | 1267 | if (irq_value & CHL_INT0_NOT_RDY_MSK) |
| 1273 | /* phy down */ | 1268 | /* phy down */ |
| @@ -1583,7 +1578,7 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot) | |||
| 1583 | spin_lock_irqsave(&hisi_hba->lock, flags); | 1578 | spin_lock_irqsave(&hisi_hba->lock, flags); |
| 1584 | hisi_sas_slot_task_free(hisi_hba, task, slot); | 1579 | hisi_sas_slot_task_free(hisi_hba, task, slot); |
| 1585 | spin_unlock_irqrestore(&hisi_hba->lock, flags); | 1580 | spin_unlock_irqrestore(&hisi_hba->lock, flags); |
| 1586 | return -1; | 1581 | return ts->stat; |
| 1587 | } | 1582 | } |
| 1588 | 1583 | ||
| 1589 | if (unlikely(!sas_dev)) { | 1584 | if (unlikely(!sas_dev)) { |
| @@ -1864,7 +1859,6 @@ static void phy_set_linkrate_v3_hw(struct hisi_hba *hisi_hba, int phy_no, | |||
| 1864 | sas_phy->phy->maximum_linkrate = max; | 1859 | sas_phy->phy->maximum_linkrate = max; |
| 1865 | sas_phy->phy->minimum_linkrate = min; | 1860 | sas_phy->phy->minimum_linkrate = min; |
| 1866 | 1861 | ||
| 1867 | min -= SAS_LINK_RATE_1_5_GBPS; | ||
| 1868 | max -= SAS_LINK_RATE_1_5_GBPS; | 1862 | max -= SAS_LINK_RATE_1_5_GBPS; |
| 1869 | 1863 | ||
| 1870 | for (i = 0; i <= max; i++) | 1864 | for (i = 0; i <= max; i++) |
| @@ -1873,10 +1867,11 @@ static void phy_set_linkrate_v3_hw(struct hisi_hba *hisi_hba, int phy_no, | |||
| 1873 | prog_phy_link_rate &= ~0xff; | 1867 | prog_phy_link_rate &= ~0xff; |
| 1874 | prog_phy_link_rate |= rate_mask; | 1868 | prog_phy_link_rate |= rate_mask; |
| 1875 | 1869 | ||
| 1870 | disable_phy_v3_hw(hisi_hba, phy_no); | ||
| 1871 | msleep(100); | ||
| 1876 | hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE, | 1872 | hisi_sas_phy_write32(hisi_hba, phy_no, PROG_PHY_LINK_RATE, |
| 1877 | prog_phy_link_rate); | 1873 | prog_phy_link_rate); |
| 1878 | 1874 | start_phy_v3_hw(hisi_hba, phy_no); | |
| 1879 | phy_hard_reset_v3_hw(hisi_hba, phy_no); | ||
| 1880 | } | 1875 | } |
| 1881 | 1876 | ||
| 1882 | static void interrupt_disable_v3_hw(struct hisi_hba *hisi_hba) | 1877 | static void interrupt_disable_v3_hw(struct hisi_hba *hisi_hba) |
| @@ -2399,6 +2394,7 @@ static const struct pci_device_id sas_v3_pci_table[] = { | |||
| 2399 | { PCI_VDEVICE(HUAWEI, 0xa230), hip08 }, | 2394 | { PCI_VDEVICE(HUAWEI, 0xa230), hip08 }, |
| 2400 | {} | 2395 | {} |
| 2401 | }; | 2396 | }; |
| 2397 | MODULE_DEVICE_TABLE(pci, sas_v3_pci_table); | ||
| 2402 | 2398 | ||
| 2403 | static const struct pci_error_handlers hisi_sas_err_handler = { | 2399 | static const struct pci_error_handlers hisi_sas_err_handler = { |
| 2404 | .error_detected = hisi_sas_error_detected_v3_hw, | 2400 | .error_detected = hisi_sas_error_detected_v3_hw, |
| @@ -2421,4 +2417,4 @@ module_pci_driver(sas_v3_pci_driver); | |||
| 2421 | MODULE_LICENSE("GPL"); | 2417 | MODULE_LICENSE("GPL"); |
| 2422 | MODULE_AUTHOR("John Garry <john.garry@huawei.com>"); | 2418 | MODULE_AUTHOR("John Garry <john.garry@huawei.com>"); |
| 2423 | MODULE_DESCRIPTION("HISILICON SAS controller v3 hw driver based on pci device"); | 2419 | MODULE_DESCRIPTION("HISILICON SAS controller v3 hw driver based on pci device"); |
| 2424 | MODULE_ALIAS("platform:" DRV_NAME); | 2420 | MODULE_ALIAS("pci:" DRV_NAME); |
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index ef22b275d050..7649d63a1b8d 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c | |||
| @@ -42,6 +42,12 @@ | |||
| 42 | #include "scsi_logging.h" | 42 | #include "scsi_logging.h" |
| 43 | 43 | ||
| 44 | 44 | ||
| 45 | static int shost_eh_deadline = -1; | ||
| 46 | |||
| 47 | module_param_named(eh_deadline, shost_eh_deadline, int, S_IRUGO|S_IWUSR); | ||
| 48 | MODULE_PARM_DESC(eh_deadline, | ||
| 49 | "SCSI EH timeout in seconds (should be between 0 and 2^31-1)"); | ||
| 50 | |||
| 45 | static DEFINE_IDA(host_index_ida); | 51 | static DEFINE_IDA(host_index_ida); |
| 46 | 52 | ||
| 47 | 53 | ||
| @@ -148,7 +154,6 @@ int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state) | |||
| 148 | scsi_host_state_name(state))); | 154 | scsi_host_state_name(state))); |
| 149 | return -EINVAL; | 155 | return -EINVAL; |
| 150 | } | 156 | } |
| 151 | EXPORT_SYMBOL(scsi_host_set_state); | ||
| 152 | 157 | ||
| 153 | /** | 158 | /** |
| 154 | * scsi_remove_host - remove a scsi host | 159 | * scsi_remove_host - remove a scsi host |
| @@ -356,12 +361,6 @@ static void scsi_host_dev_release(struct device *dev) | |||
| 356 | kfree(shost); | 361 | kfree(shost); |
| 357 | } | 362 | } |
| 358 | 363 | ||
| 359 | static int shost_eh_deadline = -1; | ||
| 360 | |||
| 361 | module_param_named(eh_deadline, shost_eh_deadline, int, S_IRUGO|S_IWUSR); | ||
| 362 | MODULE_PARM_DESC(eh_deadline, | ||
| 363 | "SCSI EH timeout in seconds (should be between 0 and 2^31-1)"); | ||
| 364 | |||
| 365 | static struct device_type scsi_host_type = { | 364 | static struct device_type scsi_host_type = { |
| 366 | .name = "scsi_host", | 365 | .name = "scsi_host", |
| 367 | .release = scsi_host_dev_release, | 366 | .release = scsi_host_dev_release, |
| @@ -517,29 +516,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) | |||
| 517 | } | 516 | } |
| 518 | EXPORT_SYMBOL(scsi_host_alloc); | 517 | EXPORT_SYMBOL(scsi_host_alloc); |
| 519 | 518 | ||
| 520 | struct Scsi_Host *scsi_register(struct scsi_host_template *sht, int privsize) | ||
| 521 | { | ||
| 522 | struct Scsi_Host *shost = scsi_host_alloc(sht, privsize); | ||
| 523 | |||
| 524 | if (!sht->detect) { | ||
| 525 | printk(KERN_WARNING "scsi_register() called on new-style " | ||
| 526 | "template for driver %s\n", sht->name); | ||
| 527 | dump_stack(); | ||
| 528 | } | ||
| 529 | |||
| 530 | if (shost) | ||
| 531 | list_add_tail(&shost->sht_legacy_list, &sht->legacy_hosts); | ||
| 532 | return shost; | ||
| 533 | } | ||
| 534 | EXPORT_SYMBOL(scsi_register); | ||
| 535 | |||
| 536 | void scsi_unregister(struct Scsi_Host *shost) | ||
| 537 | { | ||
| 538 | list_del(&shost->sht_legacy_list); | ||
| 539 | scsi_host_put(shost); | ||
| 540 | } | ||
| 541 | EXPORT_SYMBOL(scsi_unregister); | ||
| 542 | |||
| 543 | static int __scsi_host_match(struct device *dev, const void *data) | 519 | static int __scsi_host_match(struct device *dev, const void *data) |
| 544 | { | 520 | { |
| 545 | struct Scsi_Host *p; | 521 | struct Scsi_Host *p; |
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index e07dd990e585..dda1a64ab89c 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c | |||
| @@ -3816,10 +3816,8 @@ static struct device_attribute ipr_iopoll_weight_attr = { | |||
| 3816 | **/ | 3816 | **/ |
| 3817 | static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len) | 3817 | static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len) |
| 3818 | { | 3818 | { |
| 3819 | int sg_size, order, bsize_elem, num_elem, i, j; | 3819 | int sg_size, order; |
| 3820 | struct ipr_sglist *sglist; | 3820 | struct ipr_sglist *sglist; |
| 3821 | struct scatterlist *scatterlist; | ||
| 3822 | struct page *page; | ||
| 3823 | 3821 | ||
| 3824 | /* Get the minimum size per scatter/gather element */ | 3822 | /* Get the minimum size per scatter/gather element */ |
| 3825 | sg_size = buf_len / (IPR_MAX_SGLIST - 1); | 3823 | sg_size = buf_len / (IPR_MAX_SGLIST - 1); |
| @@ -3827,45 +3825,18 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len) | |||
| 3827 | /* Get the actual size per element */ | 3825 | /* Get the actual size per element */ |
| 3828 | order = get_order(sg_size); | 3826 | order = get_order(sg_size); |
| 3829 | 3827 | ||
| 3830 | /* Determine the actual number of bytes per element */ | ||
| 3831 | bsize_elem = PAGE_SIZE * (1 << order); | ||
| 3832 | |||
| 3833 | /* Determine the actual number of sg entries needed */ | ||
| 3834 | if (buf_len % bsize_elem) | ||
| 3835 | num_elem = (buf_len / bsize_elem) + 1; | ||
| 3836 | else | ||
| 3837 | num_elem = buf_len / bsize_elem; | ||
| 3838 | |||
| 3839 | /* Allocate a scatter/gather list for the DMA */ | 3828 | /* Allocate a scatter/gather list for the DMA */ |
| 3840 | sglist = kzalloc(sizeof(struct ipr_sglist) + | 3829 | sglist = kzalloc(sizeof(struct ipr_sglist), GFP_KERNEL); |
| 3841 | (sizeof(struct scatterlist) * (num_elem - 1)), | ||
| 3842 | GFP_KERNEL); | ||
| 3843 | |||
| 3844 | if (sglist == NULL) { | 3830 | if (sglist == NULL) { |
| 3845 | ipr_trace; | 3831 | ipr_trace; |
| 3846 | return NULL; | 3832 | return NULL; |
| 3847 | } | 3833 | } |
| 3848 | |||
| 3849 | scatterlist = sglist->scatterlist; | ||
| 3850 | sg_init_table(scatterlist, num_elem); | ||
| 3851 | |||
| 3852 | sglist->order = order; | 3834 | sglist->order = order; |
| 3853 | sglist->num_sg = num_elem; | 3835 | sglist->scatterlist = sgl_alloc_order(buf_len, order, false, GFP_KERNEL, |
| 3854 | 3836 | &sglist->num_sg); | |
| 3855 | /* Allocate a bunch of sg elements */ | 3837 | if (!sglist->scatterlist) { |
| 3856 | for (i = 0; i < num_elem; i++) { | 3838 | kfree(sglist); |
| 3857 | page = alloc_pages(GFP_KERNEL, order); | 3839 | return NULL; |
| 3858 | if (!page) { | ||
| 3859 | ipr_trace; | ||
| 3860 | |||
| 3861 | /* Free up what we already allocated */ | ||
| 3862 | for (j = i - 1; j >= 0; j--) | ||
| 3863 | __free_pages(sg_page(&scatterlist[j]), order); | ||
| 3864 | kfree(sglist); | ||
| 3865 | return NULL; | ||
| 3866 | } | ||
| 3867 | |||
| 3868 | sg_set_page(&scatterlist[i], page, 0, 0); | ||
| 3869 | } | 3840 | } |
| 3870 | 3841 | ||
| 3871 | return sglist; | 3842 | return sglist; |
| @@ -3883,11 +3854,7 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len) | |||
| 3883 | **/ | 3854 | **/ |
| 3884 | static void ipr_free_ucode_buffer(struct ipr_sglist *sglist) | 3855 | static void ipr_free_ucode_buffer(struct ipr_sglist *sglist) |
| 3885 | { | 3856 | { |
| 3886 | int i; | 3857 | sgl_free_order(sglist->scatterlist, sglist->order); |
| 3887 | |||
| 3888 | for (i = 0; i < sglist->num_sg; i++) | ||
| 3889 | __free_pages(sg_page(&sglist->scatterlist[i]), sglist->order); | ||
| 3890 | |||
| 3891 | kfree(sglist); | 3858 | kfree(sglist); |
| 3892 | } | 3859 | } |
| 3893 | 3860 | ||
| @@ -9684,14 +9651,14 @@ static int ipr_alloc_cmd_blks(struct ipr_ioa_cfg *ioa_cfg) | |||
| 9684 | } | 9651 | } |
| 9685 | 9652 | ||
| 9686 | for (i = 0; i < IPR_NUM_CMD_BLKS; i++) { | 9653 | for (i = 0; i < IPR_NUM_CMD_BLKS; i++) { |
| 9687 | ipr_cmd = dma_pool_alloc(ioa_cfg->ipr_cmd_pool, GFP_KERNEL, &dma_addr); | 9654 | ipr_cmd = dma_pool_zalloc(ioa_cfg->ipr_cmd_pool, |
| 9655 | GFP_KERNEL, &dma_addr); | ||
| 9688 | 9656 | ||
| 9689 | if (!ipr_cmd) { | 9657 | if (!ipr_cmd) { |
| 9690 | ipr_free_cmd_blks(ioa_cfg); | 9658 | ipr_free_cmd_blks(ioa_cfg); |
| 9691 | return -ENOMEM; | 9659 | return -ENOMEM; |
| 9692 | } | 9660 | } |
| 9693 | 9661 | ||
| 9694 | memset(ipr_cmd, 0, sizeof(*ipr_cmd)); | ||
| 9695 | ioa_cfg->ipr_cmnd_list[i] = ipr_cmd; | 9662 | ioa_cfg->ipr_cmnd_list[i] = ipr_cmd; |
| 9696 | ioa_cfg->ipr_cmnd_list_dma[i] = dma_addr; | 9663 | ioa_cfg->ipr_cmnd_list_dma[i] = dma_addr; |
| 9697 | 9664 | ||
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h index c7f0e9e3cd7d..93570734cbfb 100644 --- a/drivers/scsi/ipr.h +++ b/drivers/scsi/ipr.h | |||
| @@ -1454,7 +1454,7 @@ struct ipr_sglist { | |||
| 1454 | u32 num_sg; | 1454 | u32 num_sg; |
| 1455 | u32 num_dma_sg; | 1455 | u32 num_dma_sg; |
| 1456 | u32 buffer_len; | 1456 | u32 buffer_len; |
| 1457 | struct scatterlist scatterlist[1]; | 1457 | struct scatterlist *scatterlist; |
| 1458 | }; | 1458 | }; |
| 1459 | 1459 | ||
| 1460 | enum ipr_sdt_state { | 1460 | enum ipr_sdt_state { |
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index 67621308eb9c..e3c8857741a1 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c | |||
| @@ -224,8 +224,6 @@ module_param(ips, charp, 0); | |||
| 224 | /* | 224 | /* |
| 225 | * Function prototypes | 225 | * Function prototypes |
| 226 | */ | 226 | */ |
| 227 | static int ips_detect(struct scsi_host_template *); | ||
| 228 | static int ips_release(struct Scsi_Host *); | ||
| 229 | static int ips_eh_abort(struct scsi_cmnd *); | 227 | static int ips_eh_abort(struct scsi_cmnd *); |
| 230 | static int ips_eh_reset(struct scsi_cmnd *); | 228 | static int ips_eh_reset(struct scsi_cmnd *); |
| 231 | static int ips_queue(struct Scsi_Host *, struct scsi_cmnd *); | 229 | static int ips_queue(struct Scsi_Host *, struct scsi_cmnd *); |
| @@ -355,8 +353,6 @@ static dma_addr_t ips_flashbusaddr; | |||
| 355 | static long ips_FlashDataInUse; /* CD Boot - Flash Data In Use Flag */ | 353 | static long ips_FlashDataInUse; /* CD Boot - Flash Data In Use Flag */ |
| 356 | static uint32_t MaxLiteCmds = 32; /* Max Active Cmds for a Lite Adapter */ | 354 | static uint32_t MaxLiteCmds = 32; /* Max Active Cmds for a Lite Adapter */ |
| 357 | static struct scsi_host_template ips_driver_template = { | 355 | static struct scsi_host_template ips_driver_template = { |
| 358 | .detect = ips_detect, | ||
| 359 | .release = ips_release, | ||
| 360 | .info = ips_info, | 356 | .info = ips_info, |
| 361 | .queuecommand = ips_queue, | 357 | .queuecommand = ips_queue, |
| 362 | .eh_abort_handler = ips_eh_abort, | 358 | .eh_abort_handler = ips_eh_abort, |
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c index 13b37cdffa8e..1ee3868ade07 100644 --- a/drivers/scsi/isci/host.c +++ b/drivers/scsi/isci/host.c | |||
| @@ -2766,7 +2766,7 @@ static int sci_write_gpio_tx_gp(struct isci_host *ihost, u8 reg_index, u8 reg_co | |||
| 2766 | int i; | 2766 | int i; |
| 2767 | 2767 | ||
| 2768 | for (i = 0; i < 3; i++) { | 2768 | for (i = 0; i < 3; i++) { |
| 2769 | int bit = (i << 2) + 2; | 2769 | int bit; |
| 2770 | 2770 | ||
| 2771 | bit = try_test_sas_gpio_gp_bit(to_sas_gpio_od(d, i), | 2771 | bit = try_test_sas_gpio_gp_bit(to_sas_gpio_od(d, i), |
| 2772 | write_data, reg_index, | 2772 | write_data, reg_index, |
diff --git a/drivers/scsi/jazz_esp.c b/drivers/scsi/jazz_esp.c index 9aaa74e349cc..6eb5ff3e2e61 100644 --- a/drivers/scsi/jazz_esp.c +++ b/drivers/scsi/jazz_esp.c | |||
| @@ -147,7 +147,7 @@ static int esp_jazz_probe(struct platform_device *dev) | |||
| 147 | esp = shost_priv(host); | 147 | esp = shost_priv(host); |
| 148 | 148 | ||
| 149 | esp->host = host; | 149 | esp->host = host; |
| 150 | esp->dev = dev; | 150 | esp->dev = &dev->dev; |
| 151 | esp->ops = &jazz_esp_ops; | 151 | esp->ops = &jazz_esp_ops; |
| 152 | 152 | ||
| 153 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | 153 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); |
diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c index 8660f923ace0..3f3569ec5ce3 100644 --- a/drivers/scsi/libfc/fc_disc.c +++ b/drivers/scsi/libfc/fc_disc.c | |||
| @@ -731,7 +731,7 @@ static void fc_disc_stop_final(struct fc_lport *lport) | |||
| 731 | */ | 731 | */ |
| 732 | void fc_disc_config(struct fc_lport *lport, void *priv) | 732 | void fc_disc_config(struct fc_lport *lport, void *priv) |
| 733 | { | 733 | { |
| 734 | struct fc_disc *disc = &lport->disc; | 734 | struct fc_disc *disc; |
| 735 | 735 | ||
| 736 | if (!lport->tt.disc_start) | 736 | if (!lport->tt.disc_start) |
| 737 | lport->tt.disc_start = fc_disc_start; | 737 | lport->tt.disc_start = fc_disc_start; |
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 2b3637b40dde..0cc1567eacc1 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c | |||
| @@ -709,7 +709,7 @@ void sas_resume_sata(struct asd_sas_port *port) | |||
| 709 | } | 709 | } |
| 710 | 710 | ||
| 711 | /** | 711 | /** |
| 712 | * sas_discover_sata -- discover an STP/SATA domain device | 712 | * sas_discover_sata - discover an STP/SATA domain device |
| 713 | * @dev: pointer to struct domain_device of interest | 713 | * @dev: pointer to struct domain_device of interest |
| 714 | * | 714 | * |
| 715 | * Devices directly attached to a HA port, have no parents. All other | 715 | * Devices directly attached to a HA port, have no parents. All other |
diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c index e4fd078e4175..a0fa7ef3a071 100644 --- a/drivers/scsi/libsas/sas_discover.c +++ b/drivers/scsi/libsas/sas_discover.c | |||
| @@ -55,7 +55,7 @@ void sas_init_dev(struct domain_device *dev) | |||
| 55 | /* ---------- Domain device discovery ---------- */ | 55 | /* ---------- Domain device discovery ---------- */ |
| 56 | 56 | ||
| 57 | /** | 57 | /** |
| 58 | * sas_get_port_device -- Discover devices which caused port creation | 58 | * sas_get_port_device - Discover devices which caused port creation |
| 59 | * @port: pointer to struct sas_port of interest | 59 | * @port: pointer to struct sas_port of interest |
| 60 | * | 60 | * |
| 61 | * Devices directly attached to a HA port, have no parent. This is | 61 | * Devices directly attached to a HA port, have no parent. This is |
| @@ -278,8 +278,8 @@ static void sas_resume_devices(struct work_struct *work) | |||
| 278 | } | 278 | } |
| 279 | 279 | ||
| 280 | /** | 280 | /** |
| 281 | * sas_discover_end_dev -- discover an end device (SSP, etc) | 281 | * sas_discover_end_dev - discover an end device (SSP, etc) |
| 282 | * @end: pointer to domain device of interest | 282 | * @dev: pointer to domain device of interest |
| 283 | * | 283 | * |
| 284 | * See comment in sas_discover_sata(). | 284 | * See comment in sas_discover_sata(). |
| 285 | */ | 285 | */ |
| @@ -428,8 +428,8 @@ void sas_device_set_phy(struct domain_device *dev, struct sas_port *port) | |||
| 428 | /* ---------- Discovery and Revalidation ---------- */ | 428 | /* ---------- Discovery and Revalidation ---------- */ |
| 429 | 429 | ||
| 430 | /** | 430 | /** |
| 431 | * sas_discover_domain -- discover the domain | 431 | * sas_discover_domain - discover the domain |
| 432 | * @port: port to the domain of interest | 432 | * @work: work structure embedded in port domain device. |
| 433 | * | 433 | * |
| 434 | * NOTE: this process _must_ quit (return) as soon as any connection | 434 | * NOTE: this process _must_ quit (return) as soon as any connection |
| 435 | * errors are encountered. Connection recovery is done elsewhere. | 435 | * errors are encountered. Connection recovery is done elsewhere. |
| @@ -572,7 +572,8 @@ int sas_discover_event(struct asd_sas_port *port, enum discover_event ev) | |||
| 572 | } | 572 | } |
| 573 | 573 | ||
| 574 | /** | 574 | /** |
| 575 | * sas_init_disc -- initialize the discovery struct in the port | 575 | * sas_init_disc - initialize the discovery struct in the port |
| 576 | * @disc: port discovery structure | ||
| 576 | * @port: pointer to struct port | 577 | * @port: pointer to struct port |
| 577 | * | 578 | * |
| 578 | * Called when the ports are being initialized. | 579 | * Called when the ports are being initialized. |
diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 6a4f8198b78e..8b7114348def 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c | |||
| @@ -1170,9 +1170,9 @@ static int sas_check_level_subtractive_boundary(struct domain_device *dev) | |||
| 1170 | return 0; | 1170 | return 0; |
| 1171 | } | 1171 | } |
| 1172 | /** | 1172 | /** |
| 1173 | * sas_ex_discover_devices -- discover devices attached to this expander | 1173 | * sas_ex_discover_devices - discover devices attached to this expander |
| 1174 | * dev: pointer to the expander domain device | 1174 | * @dev: pointer to the expander domain device |
| 1175 | * single: if you want to do a single phy, else set to -1; | 1175 | * @single: if you want to do a single phy, else set to -1; |
| 1176 | * | 1176 | * |
| 1177 | * Configure this expander for use with its devices and register the | 1177 | * Configure this expander for use with its devices and register the |
| 1178 | * devices of this expander. | 1178 | * devices of this expander. |
| @@ -1528,10 +1528,11 @@ static int sas_configure_phy(struct domain_device *dev, int phy_id, | |||
| 1528 | } | 1528 | } |
| 1529 | 1529 | ||
| 1530 | /** | 1530 | /** |
| 1531 | * sas_configure_parent -- configure routing table of parent | 1531 | * sas_configure_parent - configure routing table of parent |
| 1532 | * parent: parent expander | 1532 | * @parent: parent expander |
| 1533 | * child: child expander | 1533 | * @child: child expander |
| 1534 | * sas_addr: SAS port identifier of device directly attached to child | 1534 | * @sas_addr: SAS port identifier of device directly attached to child |
| 1535 | * @include: whether or not to include @child in the expander routing table | ||
| 1535 | */ | 1536 | */ |
| 1536 | static int sas_configure_parent(struct domain_device *parent, | 1537 | static int sas_configure_parent(struct domain_device *parent, |
| 1537 | struct domain_device *child, | 1538 | struct domain_device *child, |
| @@ -1570,9 +1571,9 @@ static int sas_configure_parent(struct domain_device *parent, | |||
| 1570 | } | 1571 | } |
| 1571 | 1572 | ||
| 1572 | /** | 1573 | /** |
| 1573 | * sas_configure_routing -- configure routing | 1574 | * sas_configure_routing - configure routing |
| 1574 | * dev: expander device | 1575 | * @dev: expander device |
| 1575 | * sas_addr: port identifier of device directly attached to the expander device | 1576 | * @sas_addr: port identifier of device directly attached to the expander device |
| 1576 | */ | 1577 | */ |
| 1577 | static int sas_configure_routing(struct domain_device *dev, u8 *sas_addr) | 1578 | static int sas_configure_routing(struct domain_device *dev, u8 *sas_addr) |
| 1578 | { | 1579 | { |
| @@ -1589,8 +1590,8 @@ static int sas_disable_routing(struct domain_device *dev, u8 *sas_addr) | |||
| 1589 | } | 1590 | } |
| 1590 | 1591 | ||
| 1591 | /** | 1592 | /** |
| 1592 | * sas_discover_expander -- expander discovery | 1593 | * sas_discover_expander - expander discovery |
| 1593 | * @ex: pointer to expander domain device | 1594 | * @dev: pointer to expander domain device |
| 1594 | * | 1595 | * |
| 1595 | * See comment in sas_discover_sata(). | 1596 | * See comment in sas_discover_sata(). |
| 1596 | */ | 1597 | */ |
| @@ -2111,8 +2112,8 @@ static int sas_rediscover(struct domain_device *dev, const int phy_id) | |||
| 2111 | } | 2112 | } |
| 2112 | 2113 | ||
| 2113 | /** | 2114 | /** |
| 2114 | * sas_revalidate_domain -- revalidate the domain | 2115 | * sas_ex_revalidate_domain - revalidate the domain |
| 2115 | * @port: port to the domain of interest | 2116 | * @port_dev: port domain device. |
| 2116 | * | 2117 | * |
| 2117 | * NOTE: this process _must_ quit (return) as soon as any connection | 2118 | * NOTE: this process _must_ quit (return) as soon as any connection |
| 2118 | * errors are encountered. Connection recovery is done elsewhere. | 2119 | * errors are encountered. Connection recovery is done elsewhere. |
diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c index c81a63b5dc71..ede0af78144f 100644 --- a/drivers/scsi/libsas/sas_init.c +++ b/drivers/scsi/libsas/sas_init.c | |||
| @@ -234,7 +234,7 @@ int sas_try_ata_reset(struct asd_sas_phy *asd_phy) | |||
| 234 | return -ENODEV; | 234 | return -ENODEV; |
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | /** | 237 | /* |
| 238 | * transport_sas_phy_reset - reset a phy and permit libata to manage the link | 238 | * transport_sas_phy_reset - reset a phy and permit libata to manage the link |
| 239 | * | 239 | * |
| 240 | * phy reset request via sysfs in host workqueue context so we know we | 240 | * phy reset request via sysfs in host workqueue context so we know we |
diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c index f07e55d3aa73..fad23dd39114 100644 --- a/drivers/scsi/libsas/sas_port.c +++ b/drivers/scsi/libsas/sas_port.c | |||
| @@ -84,7 +84,7 @@ static void sas_resume_port(struct asd_sas_phy *phy) | |||
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | /** | 86 | /** |
| 87 | * sas_form_port -- add this phy to a port | 87 | * sas_form_port - add this phy to a port |
| 88 | * @phy: the phy of interest | 88 | * @phy: the phy of interest |
| 89 | * | 89 | * |
| 90 | * This function adds this phy to an existing port, thus creating a wide | 90 | * This function adds this phy to an existing port, thus creating a wide |
| @@ -197,8 +197,9 @@ static void sas_form_port(struct asd_sas_phy *phy) | |||
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | /** | 199 | /** |
| 200 | * sas_deform_port -- remove this phy from the port it belongs to | 200 | * sas_deform_port - remove this phy from the port it belongs to |
| 201 | * @phy: the phy of interest | 201 | * @phy: the phy of interest |
| 202 | * @gone: whether or not the PHY is gone | ||
| 202 | * | 203 | * |
| 203 | * This is called when the physical link to the other phy has been | 204 | * This is called when the physical link to the other phy has been |
| 204 | * lost (on this phy), in Event thread context. We cannot delay here. | 205 | * lost (on this phy), in Event thread context. We cannot delay here. |
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 61fb46da05d4..6c0d351c0d0d 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * | 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -544,16 +544,10 @@ struct unsol_rcv_ct_ctx { | |||
| 544 | #define LPFC_USER_LINK_SPEED_10G 10 /* 10 Gigabaud */ | 544 | #define LPFC_USER_LINK_SPEED_10G 10 /* 10 Gigabaud */ |
| 545 | #define LPFC_USER_LINK_SPEED_16G 16 /* 16 Gigabaud */ | 545 | #define LPFC_USER_LINK_SPEED_16G 16 /* 16 Gigabaud */ |
| 546 | #define LPFC_USER_LINK_SPEED_32G 32 /* 32 Gigabaud */ | 546 | #define LPFC_USER_LINK_SPEED_32G 32 /* 32 Gigabaud */ |
| 547 | #define LPFC_USER_LINK_SPEED_MAX LPFC_USER_LINK_SPEED_32G | 547 | #define LPFC_USER_LINK_SPEED_64G 64 /* 64 Gigabaud */ |
| 548 | #define LPFC_USER_LINK_SPEED_BITMAP ((1ULL << LPFC_USER_LINK_SPEED_32G) | \ | 548 | #define LPFC_USER_LINK_SPEED_MAX LPFC_USER_LINK_SPEED_64G |
| 549 | (1 << LPFC_USER_LINK_SPEED_16G) | \ | 549 | |
| 550 | (1 << LPFC_USER_LINK_SPEED_10G) | \ | 550 | #define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8, 10, 16, 32, 64" |
| 551 | (1 << LPFC_USER_LINK_SPEED_8G) | \ | ||
| 552 | (1 << LPFC_USER_LINK_SPEED_4G) | \ | ||
| 553 | (1 << LPFC_USER_LINK_SPEED_2G) | \ | ||
| 554 | (1 << LPFC_USER_LINK_SPEED_1G) | \ | ||
| 555 | (1 << LPFC_USER_LINK_SPEED_AUTO)) | ||
| 556 | #define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8, 10, 16, 32" | ||
| 557 | 551 | ||
| 558 | enum nemb_type { | 552 | enum nemb_type { |
| 559 | nemb_mse = 1, | 553 | nemb_mse = 1, |
| @@ -760,6 +754,7 @@ struct lpfc_hba { | |||
| 760 | uint8_t mds_diags_support; | 754 | uint8_t mds_diags_support; |
| 761 | uint32_t initial_imax; | 755 | uint32_t initial_imax; |
| 762 | uint8_t bbcredit_support; | 756 | uint8_t bbcredit_support; |
| 757 | uint8_t enab_exp_wqcq_pages; | ||
| 763 | 758 | ||
| 764 | /* HBA Config Parameters */ | 759 | /* HBA Config Parameters */ |
| 765 | uint32_t cfg_ack0; | 760 | uint32_t cfg_ack0; |
| @@ -787,6 +782,7 @@ struct lpfc_hba { | |||
| 787 | uint32_t cfg_fcp_io_channel; | 782 | uint32_t cfg_fcp_io_channel; |
| 788 | uint32_t cfg_suppress_rsp; | 783 | uint32_t cfg_suppress_rsp; |
| 789 | uint32_t cfg_nvme_oas; | 784 | uint32_t cfg_nvme_oas; |
| 785 | uint32_t cfg_nvme_embed_cmd; | ||
| 790 | uint32_t cfg_nvme_io_channel; | 786 | uint32_t cfg_nvme_io_channel; |
| 791 | uint32_t cfg_nvmet_mrq; | 787 | uint32_t cfg_nvmet_mrq; |
| 792 | uint32_t cfg_enable_nvmet; | 788 | uint32_t cfg_enable_nvmet; |
| @@ -839,11 +835,14 @@ struct lpfc_hba { | |||
| 839 | uint32_t cfg_enable_SmartSAN; | 835 | uint32_t cfg_enable_SmartSAN; |
| 840 | uint32_t cfg_enable_mds_diags; | 836 | uint32_t cfg_enable_mds_diags; |
| 841 | uint32_t cfg_enable_fc4_type; | 837 | uint32_t cfg_enable_fc4_type; |
| 842 | uint32_t cfg_enable_bbcr; /*Enable BB Credit Recovery*/ | 838 | uint32_t cfg_enable_bbcr; /* Enable BB Credit Recovery */ |
| 839 | uint32_t cfg_enable_dpp; /* Enable Direct Packet Push */ | ||
| 843 | uint32_t cfg_xri_split; | 840 | uint32_t cfg_xri_split; |
| 844 | #define LPFC_ENABLE_FCP 1 | 841 | #define LPFC_ENABLE_FCP 1 |
| 845 | #define LPFC_ENABLE_NVME 2 | 842 | #define LPFC_ENABLE_NVME 2 |
| 846 | #define LPFC_ENABLE_BOTH 3 | 843 | #define LPFC_ENABLE_BOTH 3 |
| 844 | uint32_t nvme_embed_pbde; | ||
| 845 | uint32_t fcp_embed_pbde; | ||
| 847 | uint32_t io_channel_irqs; /* number of irqs for io channels */ | 846 | uint32_t io_channel_irqs; /* number of irqs for io channels */ |
| 848 | struct nvmet_fc_target_port *targetport; | 847 | struct nvmet_fc_target_port *targetport; |
| 849 | lpfc_vpd_t vpd; /* vital product data */ | 848 | lpfc_vpd_t vpd; /* vital product data */ |
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index ac77081e6e9e..2ac1d21c553f 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * | 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -259,6 +259,12 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr, | |||
| 259 | atomic_read(&tgtp->xmt_abort_rsp), | 259 | atomic_read(&tgtp->xmt_abort_rsp), |
| 260 | atomic_read(&tgtp->xmt_abort_rsp_error)); | 260 | atomic_read(&tgtp->xmt_abort_rsp_error)); |
| 261 | 261 | ||
| 262 | len += snprintf(buf + len, PAGE_SIZE - len, | ||
| 263 | "DELAY: ctx %08x fod %08x wqfull %08x\n", | ||
| 264 | atomic_read(&tgtp->defer_ctx), | ||
| 265 | atomic_read(&tgtp->defer_fod), | ||
| 266 | atomic_read(&tgtp->defer_wqfull)); | ||
| 267 | |||
| 262 | /* Calculate outstanding IOs */ | 268 | /* Calculate outstanding IOs */ |
| 263 | tot = atomic_read(&tgtp->rcv_fcp_cmd_drop); | 269 | tot = atomic_read(&tgtp->rcv_fcp_cmd_drop); |
| 264 | tot += atomic_read(&tgtp->xmt_fcp_release); | 270 | tot += atomic_read(&tgtp->xmt_fcp_release); |
| @@ -905,7 +911,12 @@ lpfc_issue_lip(struct Scsi_Host *shost) | |||
| 905 | LPFC_MBOXQ_t *pmboxq; | 911 | LPFC_MBOXQ_t *pmboxq; |
| 906 | int mbxstatus = MBXERR_ERROR; | 912 | int mbxstatus = MBXERR_ERROR; |
| 907 | 913 | ||
| 914 | /* | ||
| 915 | * If the link is offline, disabled or BLOCK_MGMT_IO | ||
| 916 | * it doesn't make any sense to allow issue_lip | ||
| 917 | */ | ||
| 908 | if ((vport->fc_flag & FC_OFFLINE_MODE) || | 918 | if ((vport->fc_flag & FC_OFFLINE_MODE) || |
| 919 | (phba->hba_flag & LINK_DISABLED) || | ||
| 909 | (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)) | 920 | (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO)) |
| 910 | return -EPERM; | 921 | return -EPERM; |
| 911 | 922 | ||
| @@ -3458,8 +3469,8 @@ LPFC_VPORT_ATTR_R(lun_queue_depth, 30, 1, 512, | |||
| 3458 | # tgt_queue_depth: This parameter is used to limit the number of outstanding | 3469 | # tgt_queue_depth: This parameter is used to limit the number of outstanding |
| 3459 | # commands per target port. Value range is [10,65535]. Default value is 65535. | 3470 | # commands per target port. Value range is [10,65535]. Default value is 65535. |
| 3460 | */ | 3471 | */ |
| 3461 | LPFC_VPORT_ATTR_R(tgt_queue_depth, 65535, 10, 65535, | 3472 | LPFC_VPORT_ATTR_RW(tgt_queue_depth, 65535, 10, 65535, |
| 3462 | "Max number of FCP commands we can queue to a specific target port"); | 3473 | "Max number of FCP commands we can queue to a specific target port"); |
| 3463 | 3474 | ||
| 3464 | /* | 3475 | /* |
| 3465 | # hba_queue_depth: This parameter is used to limit the number of outstanding | 3476 | # hba_queue_depth: This parameter is used to limit the number of outstanding |
| @@ -4104,23 +4115,32 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr, | |||
| 4104 | ((val == LPFC_USER_LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) || | 4115 | ((val == LPFC_USER_LINK_SPEED_8G) && !(phba->lmt & LMT_8Gb)) || |
| 4105 | ((val == LPFC_USER_LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb)) || | 4116 | ((val == LPFC_USER_LINK_SPEED_10G) && !(phba->lmt & LMT_10Gb)) || |
| 4106 | ((val == LPFC_USER_LINK_SPEED_16G) && !(phba->lmt & LMT_16Gb)) || | 4117 | ((val == LPFC_USER_LINK_SPEED_16G) && !(phba->lmt & LMT_16Gb)) || |
| 4107 | ((val == LPFC_USER_LINK_SPEED_32G) && !(phba->lmt & LMT_32Gb))) { | 4118 | ((val == LPFC_USER_LINK_SPEED_32G) && !(phba->lmt & LMT_32Gb)) || |
| 4119 | ((val == LPFC_USER_LINK_SPEED_64G) && !(phba->lmt & LMT_64Gb))) { | ||
| 4108 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 4120 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
| 4109 | "2879 lpfc_link_speed attribute cannot be set " | 4121 | "2879 lpfc_link_speed attribute cannot be set " |
| 4110 | "to %d. Speed is not supported by this port.\n", | 4122 | "to %d. Speed is not supported by this port.\n", |
| 4111 | val); | 4123 | val); |
| 4112 | return -EINVAL; | 4124 | return -EINVAL; |
| 4113 | } | 4125 | } |
| 4114 | if (val == LPFC_USER_LINK_SPEED_16G && | 4126 | if (val >= LPFC_USER_LINK_SPEED_16G && |
| 4115 | phba->fc_topology == LPFC_TOPOLOGY_LOOP) { | 4127 | phba->fc_topology == LPFC_TOPOLOGY_LOOP) { |
| 4116 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 4128 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
| 4117 | "3112 lpfc_link_speed attribute cannot be set " | 4129 | "3112 lpfc_link_speed attribute cannot be set " |
| 4118 | "to %d. Speed is not supported in loop mode.\n", | 4130 | "to %d. Speed is not supported in loop mode.\n", |
| 4119 | val); | 4131 | val); |
| 4120 | return -EINVAL; | 4132 | return -EINVAL; |
| 4121 | } | 4133 | } |
| 4122 | if ((val >= 0) && (val <= LPFC_USER_LINK_SPEED_MAX) && | 4134 | |
| 4123 | (LPFC_USER_LINK_SPEED_BITMAP & (1 << val))) { | 4135 | switch (val) { |
| 4136 | case LPFC_USER_LINK_SPEED_AUTO: | ||
| 4137 | case LPFC_USER_LINK_SPEED_1G: | ||
| 4138 | case LPFC_USER_LINK_SPEED_2G: | ||
| 4139 | case LPFC_USER_LINK_SPEED_4G: | ||
| 4140 | case LPFC_USER_LINK_SPEED_8G: | ||
| 4141 | case LPFC_USER_LINK_SPEED_16G: | ||
| 4142 | case LPFC_USER_LINK_SPEED_32G: | ||
| 4143 | case LPFC_USER_LINK_SPEED_64G: | ||
| 4124 | prev_val = phba->cfg_link_speed; | 4144 | prev_val = phba->cfg_link_speed; |
| 4125 | phba->cfg_link_speed = val; | 4145 | phba->cfg_link_speed = val; |
| 4126 | if (nolip) | 4146 | if (nolip) |
| @@ -4130,13 +4150,18 @@ lpfc_link_speed_store(struct device *dev, struct device_attribute *attr, | |||
| 4130 | if (err) { | 4150 | if (err) { |
| 4131 | phba->cfg_link_speed = prev_val; | 4151 | phba->cfg_link_speed = prev_val; |
| 4132 | return -EINVAL; | 4152 | return -EINVAL; |
| 4133 | } else | 4153 | } |
| 4134 | return strlen(buf); | 4154 | return strlen(buf); |
| 4155 | default: | ||
| 4156 | break; | ||
| 4135 | } | 4157 | } |
| 4158 | |||
| 4136 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 4159 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
| 4137 | "0469 lpfc_link_speed attribute cannot be set to %d, " | 4160 | "0469 lpfc_link_speed attribute cannot be set to %d, " |
| 4138 | "allowed values are ["LPFC_LINK_SPEED_STRING"]\n", val); | 4161 | "allowed values are [%s]\n", |
| 4162 | val, LPFC_LINK_SPEED_STRING); | ||
| 4139 | return -EINVAL; | 4163 | return -EINVAL; |
| 4164 | |||
| 4140 | } | 4165 | } |
| 4141 | 4166 | ||
| 4142 | static int lpfc_link_speed = 0; | 4167 | static int lpfc_link_speed = 0; |
| @@ -4163,24 +4188,33 @@ lpfc_param_show(link_speed) | |||
| 4163 | static int | 4188 | static int |
| 4164 | lpfc_link_speed_init(struct lpfc_hba *phba, int val) | 4189 | lpfc_link_speed_init(struct lpfc_hba *phba, int val) |
| 4165 | { | 4190 | { |
| 4166 | if (val == LPFC_USER_LINK_SPEED_16G && phba->cfg_topology == 4) { | 4191 | if (val >= LPFC_USER_LINK_SPEED_16G && phba->cfg_topology == 4) { |
| 4167 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 4192 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
| 4168 | "3111 lpfc_link_speed of %d cannot " | 4193 | "3111 lpfc_link_speed of %d cannot " |
| 4169 | "support loop mode, setting topology to default.\n", | 4194 | "support loop mode, setting topology to default.\n", |
| 4170 | val); | 4195 | val); |
| 4171 | phba->cfg_topology = 0; | 4196 | phba->cfg_topology = 0; |
| 4172 | } | 4197 | } |
| 4173 | if ((val >= 0) && (val <= LPFC_USER_LINK_SPEED_MAX) && | 4198 | |
| 4174 | (LPFC_USER_LINK_SPEED_BITMAP & (1 << val))) { | 4199 | switch (val) { |
| 4200 | case LPFC_USER_LINK_SPEED_AUTO: | ||
| 4201 | case LPFC_USER_LINK_SPEED_1G: | ||
| 4202 | case LPFC_USER_LINK_SPEED_2G: | ||
| 4203 | case LPFC_USER_LINK_SPEED_4G: | ||
| 4204 | case LPFC_USER_LINK_SPEED_8G: | ||
| 4205 | case LPFC_USER_LINK_SPEED_16G: | ||
| 4206 | case LPFC_USER_LINK_SPEED_32G: | ||
| 4207 | case LPFC_USER_LINK_SPEED_64G: | ||
| 4175 | phba->cfg_link_speed = val; | 4208 | phba->cfg_link_speed = val; |
| 4176 | return 0; | 4209 | return 0; |
| 4210 | default: | ||
| 4211 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
| 4212 | "0405 lpfc_link_speed attribute cannot " | ||
| 4213 | "be set to %d, allowed values are " | ||
| 4214 | "["LPFC_LINK_SPEED_STRING"]\n", val); | ||
| 4215 | phba->cfg_link_speed = LPFC_USER_LINK_SPEED_AUTO; | ||
| 4216 | return -EINVAL; | ||
| 4177 | } | 4217 | } |
| 4178 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
| 4179 | "0405 lpfc_link_speed attribute cannot " | ||
| 4180 | "be set to %d, allowed values are " | ||
| 4181 | "["LPFC_LINK_SPEED_STRING"]\n", val); | ||
| 4182 | phba->cfg_link_speed = LPFC_USER_LINK_SPEED_AUTO; | ||
| 4183 | return -EINVAL; | ||
| 4184 | } | 4218 | } |
| 4185 | 4219 | ||
| 4186 | static DEVICE_ATTR_RW(lpfc_link_speed); | 4220 | static DEVICE_ATTR_RW(lpfc_link_speed); |
| @@ -5008,6 +5042,18 @@ LPFC_ATTR_RW(nvme_oas, 0, 0, 1, | |||
| 5008 | "Use OAS bit on NVME IOs"); | 5042 | "Use OAS bit on NVME IOs"); |
| 5009 | 5043 | ||
| 5010 | /* | 5044 | /* |
| 5045 | * lpfc_nvme_embed_cmd: Use the oas bit when sending NVME/NVMET IOs | ||
| 5046 | * | ||
| 5047 | * 0 = Put NVME Command in SGL | ||
| 5048 | * 1 = Embed NVME Command in WQE (unless G7) | ||
| 5049 | * 2 = Embed NVME Command in WQE (force) | ||
| 5050 | * | ||
| 5051 | * Value range is [0,2]. Default value is 1. | ||
| 5052 | */ | ||
| 5053 | LPFC_ATTR_RW(nvme_embed_cmd, 1, 0, 2, | ||
| 5054 | "Embed NVME Command in WQE"); | ||
| 5055 | |||
| 5056 | /* | ||
| 5011 | * lpfc_fcp_io_channel: Set the number of FCP IO channels the driver | 5057 | * lpfc_fcp_io_channel: Set the number of FCP IO channels the driver |
| 5012 | * will advertise it supports to the SCSI layer. This also will map to | 5058 | * will advertise it supports to the SCSI layer. This also will map to |
| 5013 | * the number of WQs the driver will create. | 5059 | * the number of WQs the driver will create. |
| @@ -5175,6 +5221,14 @@ LPFC_ATTR_R(enable_mds_diags, 0, 0, 1, "Enable MDS Diagnostics"); | |||
| 5175 | */ | 5221 | */ |
| 5176 | LPFC_BBCR_ATTR_RW(enable_bbcr, 1, 0, 1, "Enable BBC Recovery"); | 5222 | LPFC_BBCR_ATTR_RW(enable_bbcr, 1, 0, 1, "Enable BBC Recovery"); |
| 5177 | 5223 | ||
| 5224 | /* | ||
| 5225 | * lpfc_enable_dpp: Enable DPP on G7 | ||
| 5226 | * 0 = DPP on G7 disabled | ||
| 5227 | * 1 = DPP on G7 enabled (default) | ||
| 5228 | * Value range is [0,1]. Default value is 1. | ||
| 5229 | */ | ||
| 5230 | LPFC_ATTR_RW(enable_dpp, 1, 0, 1, "Enable Direct Packet Push"); | ||
| 5231 | |||
| 5178 | struct device_attribute *lpfc_hba_attrs[] = { | 5232 | struct device_attribute *lpfc_hba_attrs[] = { |
| 5179 | &dev_attr_nvme_info, | 5233 | &dev_attr_nvme_info, |
| 5180 | &dev_attr_bg_info, | 5234 | &dev_attr_bg_info, |
| @@ -5240,6 +5294,7 @@ struct device_attribute *lpfc_hba_attrs[] = { | |||
| 5240 | &dev_attr_lpfc_task_mgmt_tmo, | 5294 | &dev_attr_lpfc_task_mgmt_tmo, |
| 5241 | &dev_attr_lpfc_use_msi, | 5295 | &dev_attr_lpfc_use_msi, |
| 5242 | &dev_attr_lpfc_nvme_oas, | 5296 | &dev_attr_lpfc_nvme_oas, |
| 5297 | &dev_attr_lpfc_nvme_embed_cmd, | ||
| 5243 | &dev_attr_lpfc_auto_imax, | 5298 | &dev_attr_lpfc_auto_imax, |
| 5244 | &dev_attr_lpfc_fcp_imax, | 5299 | &dev_attr_lpfc_fcp_imax, |
| 5245 | &dev_attr_lpfc_fcp_cpu_map, | 5300 | &dev_attr_lpfc_fcp_cpu_map, |
| @@ -5283,6 +5338,7 @@ struct device_attribute *lpfc_hba_attrs[] = { | |||
| 5283 | &dev_attr_lpfc_xlane_supported, | 5338 | &dev_attr_lpfc_xlane_supported, |
| 5284 | &dev_attr_lpfc_enable_mds_diags, | 5339 | &dev_attr_lpfc_enable_mds_diags, |
| 5285 | &dev_attr_lpfc_enable_bbcr, | 5340 | &dev_attr_lpfc_enable_bbcr, |
| 5341 | &dev_attr_lpfc_enable_dpp, | ||
| 5286 | NULL, | 5342 | NULL, |
| 5287 | }; | 5343 | }; |
| 5288 | 5344 | ||
| @@ -5696,6 +5752,9 @@ lpfc_get_host_speed(struct Scsi_Host *shost) | |||
| 5696 | case LPFC_LINK_SPEED_32GHZ: | 5752 | case LPFC_LINK_SPEED_32GHZ: |
| 5697 | fc_host_speed(shost) = FC_PORTSPEED_32GBIT; | 5753 | fc_host_speed(shost) = FC_PORTSPEED_32GBIT; |
| 5698 | break; | 5754 | break; |
| 5755 | case LPFC_LINK_SPEED_64GHZ: | ||
| 5756 | fc_host_speed(shost) = FC_PORTSPEED_64GBIT; | ||
| 5757 | break; | ||
| 5699 | default: | 5758 | default: |
| 5700 | fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; | 5759 | fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; |
| 5701 | break; | 5760 | break; |
| @@ -6260,6 +6319,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) | |||
| 6260 | lpfc_enable_SmartSAN_init(phba, lpfc_enable_SmartSAN); | 6319 | lpfc_enable_SmartSAN_init(phba, lpfc_enable_SmartSAN); |
| 6261 | lpfc_use_msi_init(phba, lpfc_use_msi); | 6320 | lpfc_use_msi_init(phba, lpfc_use_msi); |
| 6262 | lpfc_nvme_oas_init(phba, lpfc_nvme_oas); | 6321 | lpfc_nvme_oas_init(phba, lpfc_nvme_oas); |
| 6322 | lpfc_nvme_embed_cmd_init(phba, lpfc_nvme_embed_cmd); | ||
| 6263 | lpfc_auto_imax_init(phba, lpfc_auto_imax); | 6323 | lpfc_auto_imax_init(phba, lpfc_auto_imax); |
| 6264 | lpfc_fcp_imax_init(phba, lpfc_fcp_imax); | 6324 | lpfc_fcp_imax_init(phba, lpfc_fcp_imax); |
| 6265 | lpfc_fcp_cpu_map_init(phba, lpfc_fcp_cpu_map); | 6325 | lpfc_fcp_cpu_map_init(phba, lpfc_fcp_cpu_map); |
| @@ -6284,6 +6344,10 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) | |||
| 6284 | phba->cfg_poll = 0; | 6344 | phba->cfg_poll = 0; |
| 6285 | else | 6345 | else |
| 6286 | phba->cfg_poll = lpfc_poll; | 6346 | phba->cfg_poll = lpfc_poll; |
| 6347 | |||
| 6348 | if (phba->cfg_enable_bg) | ||
| 6349 | phba->sli3_options |= LPFC_SLI3_BG_ENABLED; | ||
| 6350 | |||
| 6287 | lpfc_suppress_rsp_init(phba, lpfc_suppress_rsp); | 6351 | lpfc_suppress_rsp_init(phba, lpfc_suppress_rsp); |
| 6288 | 6352 | ||
| 6289 | lpfc_enable_fc4_type_init(phba, lpfc_enable_fc4_type); | 6353 | lpfc_enable_fc4_type_init(phba, lpfc_enable_fc4_type); |
| @@ -6295,6 +6359,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba) | |||
| 6295 | lpfc_fcp_io_channel_init(phba, lpfc_fcp_io_channel); | 6359 | lpfc_fcp_io_channel_init(phba, lpfc_fcp_io_channel); |
| 6296 | lpfc_nvme_io_channel_init(phba, lpfc_nvme_io_channel); | 6360 | lpfc_nvme_io_channel_init(phba, lpfc_nvme_io_channel); |
| 6297 | lpfc_enable_bbcr_init(phba, lpfc_enable_bbcr); | 6361 | lpfc_enable_bbcr_init(phba, lpfc_enable_bbcr); |
| 6362 | lpfc_enable_dpp_init(phba, lpfc_enable_dpp); | ||
| 6298 | 6363 | ||
| 6299 | if (phba->sli_rev != LPFC_SLI_REV4) { | 6364 | if (phba->sli_rev != LPFC_SLI_REV4) { |
| 6300 | /* NVME only supported on SLI4 */ | 6365 | /* NVME only supported on SLI4 */ |
diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index d89816222b23..0f174ca80f67 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2009-2015 Emulex. All rights reserved. * | 6 | * Copyright (C) 2009-2015 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -3867,7 +3867,7 @@ lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, struct bsg_job *job, | |||
| 3867 | "ext_buf_cnt:%d\n", ext_buf_cnt); | 3867 | "ext_buf_cnt:%d\n", ext_buf_cnt); |
| 3868 | } else { | 3868 | } else { |
| 3869 | /* sanity check on interface type for support */ | 3869 | /* sanity check on interface type for support */ |
| 3870 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != | 3870 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) < |
| 3871 | LPFC_SLI_INTF_IF_TYPE_2) { | 3871 | LPFC_SLI_INTF_IF_TYPE_2) { |
| 3872 | rc = -ENODEV; | 3872 | rc = -ENODEV; |
| 3873 | goto job_error; | 3873 | goto job_error; |
| @@ -4053,7 +4053,7 @@ lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct bsg_job *job, | |||
| 4053 | "ext_buf_cnt:%d\n", ext_buf_cnt); | 4053 | "ext_buf_cnt:%d\n", ext_buf_cnt); |
| 4054 | } else { | 4054 | } else { |
| 4055 | /* sanity check on interface type for support */ | 4055 | /* sanity check on interface type for support */ |
| 4056 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != | 4056 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) < |
| 4057 | LPFC_SLI_INTF_IF_TYPE_2) | 4057 | LPFC_SLI_INTF_IF_TYPE_2) |
| 4058 | return -ENODEV; | 4058 | return -ENODEV; |
| 4059 | /* nemb_tp == nemb_hbd */ | 4059 | /* nemb_tp == nemb_hbd */ |
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 559f9aa0ed08..4ae9ba425e78 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * | 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -254,6 +254,7 @@ void lpfc_nvmet_ctxbuf_post(struct lpfc_hba *phba, | |||
| 254 | struct lpfc_nvmet_ctxbuf *ctxp); | 254 | struct lpfc_nvmet_ctxbuf *ctxp); |
| 255 | int lpfc_nvmet_rcv_unsol_abort(struct lpfc_vport *vport, | 255 | int lpfc_nvmet_rcv_unsol_abort(struct lpfc_vport *vport, |
| 256 | struct fc_frame_header *fc_hdr); | 256 | struct fc_frame_header *fc_hdr); |
| 257 | void lpfc_nvmet_wqfull_process(struct lpfc_hba *phba, struct lpfc_queue *wq); | ||
| 257 | void lpfc_sli_flush_nvme_rings(struct lpfc_hba *phba); | 258 | void lpfc_sli_flush_nvme_rings(struct lpfc_hba *phba); |
| 258 | void lpfc_nvme_wait_for_io_drain(struct lpfc_hba *phba); | 259 | void lpfc_nvme_wait_for_io_drain(struct lpfc_hba *phba); |
| 259 | void lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *, struct fcf_record *, | 260 | void lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *, struct fcf_record *, |
| @@ -564,6 +565,8 @@ void lpfc_nvme_mod_param_dep(struct lpfc_hba *phba); | |||
| 564 | void lpfc_nvme_abort_fcreq_cmpl(struct lpfc_hba *phba, | 565 | void lpfc_nvme_abort_fcreq_cmpl(struct lpfc_hba *phba, |
| 565 | struct lpfc_iocbq *cmdiocb, | 566 | struct lpfc_iocbq *cmdiocb, |
| 566 | struct lpfc_wcqe_complete *abts_cmpl); | 567 | struct lpfc_wcqe_complete *abts_cmpl); |
| 568 | void lpfc_nvme_cmd_template(void); | ||
| 569 | void lpfc_nvmet_cmd_template(void); | ||
| 567 | extern int lpfc_enable_nvmet_cnt; | 570 | extern int lpfc_enable_nvmet_cnt; |
| 568 | extern unsigned long long lpfc_enable_nvmet[]; | 571 | extern unsigned long long lpfc_enable_nvmet[]; |
| 569 | extern int lpfc_no_hba_reset_cnt; | 572 | extern int lpfc_no_hba_reset_cnt; |
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 9d20d2c208c7..0617c8ea88c6 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * | 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -471,7 +471,6 @@ lpfc_prep_node_fc4type(struct lpfc_vport *vport, uint32_t Did, uint8_t fc4_type) | |||
| 471 | "Parse GID_FTrsp: did:x%x flg:x%x x%x", | 471 | "Parse GID_FTrsp: did:x%x flg:x%x x%x", |
| 472 | Did, ndlp->nlp_flag, vport->fc_flag); | 472 | Did, ndlp->nlp_flag, vport->fc_flag); |
| 473 | 473 | ||
| 474 | ndlp->nlp_fc4_type &= ~(NLP_FC4_FCP | NLP_FC4_NVME); | ||
| 475 | /* By default, the driver expects to support FCP FC4 */ | 474 | /* By default, the driver expects to support FCP FC4 */ |
| 476 | if (fc4_type == FC_TYPE_FCP) | 475 | if (fc4_type == FC_TYPE_FCP) |
| 477 | ndlp->nlp_fc4_type |= NLP_FC4_FCP; | 476 | ndlp->nlp_fc4_type |= NLP_FC4_FCP; |
| @@ -2130,6 +2129,8 @@ lpfc_fdmi_port_attr_support_speed(struct lpfc_vport *vport, | |||
| 2130 | 2129 | ||
| 2131 | ae->un.AttrInt = 0; | 2130 | ae->un.AttrInt = 0; |
| 2132 | if (!(phba->hba_flag & HBA_FCOE_MODE)) { | 2131 | if (!(phba->hba_flag & HBA_FCOE_MODE)) { |
| 2132 | if (phba->lmt & LMT_64Gb) | ||
| 2133 | ae->un.AttrInt |= HBA_PORTSPEED_64GFC; | ||
| 2133 | if (phba->lmt & LMT_32Gb) | 2134 | if (phba->lmt & LMT_32Gb) |
| 2134 | ae->un.AttrInt |= HBA_PORTSPEED_32GFC; | 2135 | ae->un.AttrInt |= HBA_PORTSPEED_32GFC; |
| 2135 | if (phba->lmt & LMT_16Gb) | 2136 | if (phba->lmt & LMT_16Gb) |
| @@ -2201,6 +2202,9 @@ lpfc_fdmi_port_attr_speed(struct lpfc_vport *vport, | |||
| 2201 | case LPFC_LINK_SPEED_32GHZ: | 2202 | case LPFC_LINK_SPEED_32GHZ: |
| 2202 | ae->un.AttrInt = HBA_PORTSPEED_32GFC; | 2203 | ae->un.AttrInt = HBA_PORTSPEED_32GFC; |
| 2203 | break; | 2204 | break; |
| 2205 | case LPFC_LINK_SPEED_64GHZ: | ||
| 2206 | ae->un.AttrInt = HBA_PORTSPEED_64GFC; | ||
| 2207 | break; | ||
| 2204 | default: | 2208 | default: |
| 2205 | ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN; | 2209 | ae->un.AttrInt = HBA_PORTSPEED_UNKNOWN; |
| 2206 | break; | 2210 | break; |
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 17ea3bb04266..fb0dc2aeed91 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2007-2015 Emulex. All rights reserved. * | 6 | * Copyright (C) 2007-2015 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -3944,10 +3944,15 @@ lpfc_idiag_drbacc_read_reg(struct lpfc_hba *phba, char *pbuffer, | |||
| 3944 | return 0; | 3944 | return 0; |
| 3945 | 3945 | ||
| 3946 | switch (drbregid) { | 3946 | switch (drbregid) { |
| 3947 | case LPFC_DRB_EQCQ: | 3947 | case LPFC_DRB_EQ: |
| 3948 | len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len, | 3948 | len += snprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE-len, |
| 3949 | "EQCQ-DRB-REG: 0x%08x\n", | 3949 | "EQ-DRB-REG: 0x%08x\n", |
| 3950 | readl(phba->sli4_hba.EQCQDBregaddr)); | 3950 | readl(phba->sli4_hba.EQDBregaddr)); |
| 3951 | break; | ||
| 3952 | case LPFC_DRB_CQ: | ||
| 3953 | len += snprintf(pbuffer + len, LPFC_DRB_ACC_BUF_SIZE - len, | ||
| 3954 | "CQ-DRB-REG: 0x%08x\n", | ||
| 3955 | readl(phba->sli4_hba.CQDBregaddr)); | ||
| 3951 | break; | 3956 | break; |
| 3952 | case LPFC_DRB_MQ: | 3957 | case LPFC_DRB_MQ: |
| 3953 | len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len, | 3958 | len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len, |
| @@ -4086,8 +4091,11 @@ lpfc_idiag_drbacc_write(struct file *file, const char __user *buf, | |||
| 4086 | idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST || | 4091 | idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST || |
| 4087 | idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) { | 4092 | idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) { |
| 4088 | switch (drb_reg_id) { | 4093 | switch (drb_reg_id) { |
| 4089 | case LPFC_DRB_EQCQ: | 4094 | case LPFC_DRB_EQ: |
| 4090 | drb_reg = phba->sli4_hba.EQCQDBregaddr; | 4095 | drb_reg = phba->sli4_hba.EQDBregaddr; |
| 4096 | break; | ||
| 4097 | case LPFC_DRB_CQ: | ||
| 4098 | drb_reg = phba->sli4_hba.CQDBregaddr; | ||
| 4091 | break; | 4099 | break; |
| 4092 | case LPFC_DRB_MQ: | 4100 | case LPFC_DRB_MQ: |
| 4093 | drb_reg = phba->sli4_hba.MQDBregaddr; | 4101 | drb_reg = phba->sli4_hba.MQDBregaddr; |
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.h b/drivers/scsi/lpfc/lpfc_debugfs.h index c4edd87bfc65..f32eaeb2225a 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.h +++ b/drivers/scsi/lpfc/lpfc_debugfs.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2007-2011 Emulex. All rights reserved. * | 6 | * Copyright (C) 2007-2011 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -126,12 +126,13 @@ | |||
| 126 | #define LPFC_DRB_ACC_WR_CMD_ARG 2 | 126 | #define LPFC_DRB_ACC_WR_CMD_ARG 2 |
| 127 | #define LPFC_DRB_ACC_BUF_SIZE 256 | 127 | #define LPFC_DRB_ACC_BUF_SIZE 256 |
| 128 | 128 | ||
| 129 | #define LPFC_DRB_EQCQ 1 | 129 | #define LPFC_DRB_EQ 1 |
| 130 | #define LPFC_DRB_MQ 2 | 130 | #define LPFC_DRB_CQ 2 |
| 131 | #define LPFC_DRB_WQ 3 | 131 | #define LPFC_DRB_MQ 3 |
| 132 | #define LPFC_DRB_RQ 4 | 132 | #define LPFC_DRB_WQ 4 |
| 133 | #define LPFC_DRB_RQ 5 | ||
| 133 | 134 | ||
| 134 | #define LPFC_DRB_MAX 4 | 135 | #define LPFC_DRB_MAX 5 |
| 135 | 136 | ||
| 136 | #define IDIAG_DRBACC_REGID_INDX 0 | 137 | #define IDIAG_DRBACC_REGID_INDX 0 |
| 137 | #define IDIAG_DRBACC_VALUE_INDX 1 | 138 | #define IDIAG_DRBACC_VALUE_INDX 1 |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 234c7c015982..74895e62aaea 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * | 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -1661,6 +1661,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp, | |||
| 1661 | if (ndlp->nrport) { | 1661 | if (ndlp->nrport) { |
| 1662 | ndlp->nrport = NULL; | 1662 | ndlp->nrport = NULL; |
| 1663 | lpfc_nlp_put(ndlp); | 1663 | lpfc_nlp_put(ndlp); |
| 1664 | new_ndlp->nlp_fc4_type = ndlp->nlp_fc4_type; | ||
| 1664 | } | 1665 | } |
| 1665 | 1666 | ||
| 1666 | /* We shall actually free the ndlp with both nlp_DID and | 1667 | /* We shall actually free the ndlp with both nlp_DID and |
| @@ -2293,10 +2294,11 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
| 2293 | if (phba->nvmet_support) { | 2294 | if (phba->nvmet_support) { |
| 2294 | bf_set(prli_tgt, npr_nvme, 1); | 2295 | bf_set(prli_tgt, npr_nvme, 1); |
| 2295 | bf_set(prli_disc, npr_nvme, 1); | 2296 | bf_set(prli_disc, npr_nvme, 1); |
| 2296 | |||
| 2297 | } else { | 2297 | } else { |
| 2298 | bf_set(prli_init, npr_nvme, 1); | 2298 | bf_set(prli_init, npr_nvme, 1); |
| 2299 | bf_set(prli_conf, npr_nvme, 1); | ||
| 2299 | } | 2300 | } |
| 2301 | |||
| 2300 | npr_nvme->word1 = cpu_to_be32(npr_nvme->word1); | 2302 | npr_nvme->word1 = cpu_to_be32(npr_nvme->word1); |
| 2301 | npr_nvme->word4 = cpu_to_be32(npr_nvme->word4); | 2303 | npr_nvme->word4 = cpu_to_be32(npr_nvme->word4); |
| 2302 | elsiocb->iocb_flag |= LPFC_PRLI_NVME_REQ; | 2304 | elsiocb->iocb_flag |= LPFC_PRLI_NVME_REQ; |
| @@ -5269,6 +5271,9 @@ lpfc_rdp_res_speed(struct fc_rdp_port_speed_desc *desc, struct lpfc_hba *phba) | |||
| 5269 | case LPFC_LINK_SPEED_32GHZ: | 5271 | case LPFC_LINK_SPEED_32GHZ: |
| 5270 | rdp_speed = RDP_PS_32GB; | 5272 | rdp_speed = RDP_PS_32GB; |
| 5271 | break; | 5273 | break; |
| 5274 | case LPFC_LINK_SPEED_64GHZ: | ||
| 5275 | rdp_speed = RDP_PS_64GB; | ||
| 5276 | break; | ||
| 5272 | default: | 5277 | default: |
| 5273 | rdp_speed = RDP_PS_UNKNOWN; | 5278 | rdp_speed = RDP_PS_UNKNOWN; |
| 5274 | break; | 5279 | break; |
| @@ -5276,6 +5281,8 @@ lpfc_rdp_res_speed(struct fc_rdp_port_speed_desc *desc, struct lpfc_hba *phba) | |||
| 5276 | 5281 | ||
| 5277 | desc->info.port_speed.speed = cpu_to_be16(rdp_speed); | 5282 | desc->info.port_speed.speed = cpu_to_be16(rdp_speed); |
| 5278 | 5283 | ||
| 5284 | if (phba->lmt & LMT_64Gb) | ||
| 5285 | rdp_cap |= RDP_PS_64GB; | ||
| 5279 | if (phba->lmt & LMT_32Gb) | 5286 | if (phba->lmt & LMT_32Gb) |
| 5280 | rdp_cap |= RDP_PS_32GB; | 5287 | rdp_cap |= RDP_PS_32GB; |
| 5281 | if (phba->lmt & LMT_16Gb) | 5288 | if (phba->lmt & LMT_16Gb) |
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index b159a5c4e388..3e7712cd6c9a 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * | 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -696,8 +696,9 @@ lpfc_work_done(struct lpfc_hba *phba) | |||
| 696 | phba->hba_flag & HBA_SP_QUEUE_EVT)) { | 696 | phba->hba_flag & HBA_SP_QUEUE_EVT)) { |
| 697 | if (pring->flag & LPFC_STOP_IOCB_EVENT) { | 697 | if (pring->flag & LPFC_STOP_IOCB_EVENT) { |
| 698 | pring->flag |= LPFC_DEFERRED_RING_EVENT; | 698 | pring->flag |= LPFC_DEFERRED_RING_EVENT; |
| 699 | /* Set the lpfc data pending flag */ | 699 | /* Preserve legacy behavior. */ |
| 700 | set_bit(LPFC_DATA_READY, &phba->data_flags); | 700 | if (!(phba->hba_flag & HBA_SP_QUEUE_EVT)) |
| 701 | set_bit(LPFC_DATA_READY, &phba->data_flags); | ||
| 701 | } else { | 702 | } else { |
| 702 | if (phba->link_state >= LPFC_LINK_UP || | 703 | if (phba->link_state >= LPFC_LINK_UP || |
| 703 | phba->link_flag & LS_MDS_LOOPBACK) { | 704 | phba->link_flag & LS_MDS_LOOPBACK) { |
| @@ -958,6 +959,7 @@ lpfc_linkup_cleanup_nodes(struct lpfc_vport *vport) | |||
| 958 | struct lpfc_nodelist *ndlp; | 959 | struct lpfc_nodelist *ndlp; |
| 959 | 960 | ||
| 960 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { | 961 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { |
| 962 | ndlp->nlp_fc4_type &= ~(NLP_FC4_FCP | NLP_FC4_NVME); | ||
| 961 | if (!NLP_CHK_NODE_ACT(ndlp)) | 963 | if (!NLP_CHK_NODE_ACT(ndlp)) |
| 962 | continue; | 964 | continue; |
| 963 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) | 965 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) |
| @@ -3083,6 +3085,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, struct lpfc_mbx_read_top *la) | |||
| 3083 | case LPFC_LINK_SPEED_10GHZ: | 3085 | case LPFC_LINK_SPEED_10GHZ: |
| 3084 | case LPFC_LINK_SPEED_16GHZ: | 3086 | case LPFC_LINK_SPEED_16GHZ: |
| 3085 | case LPFC_LINK_SPEED_32GHZ: | 3087 | case LPFC_LINK_SPEED_32GHZ: |
| 3088 | case LPFC_LINK_SPEED_64GHZ: | ||
| 3086 | break; | 3089 | break; |
| 3087 | default: | 3090 | default: |
| 3088 | phba->fc_linkspeed = LPFC_LINK_SPEED_UNKNOWN; | 3091 | phba->fc_linkspeed = LPFC_LINK_SPEED_UNKNOWN; |
| @@ -3873,6 +3876,10 @@ int | |||
| 3873 | lpfc_issue_gidft(struct lpfc_vport *vport) | 3876 | lpfc_issue_gidft(struct lpfc_vport *vport) |
| 3874 | { | 3877 | { |
| 3875 | struct lpfc_hba *phba = vport->phba; | 3878 | struct lpfc_hba *phba = vport->phba; |
| 3879 | struct lpfc_nodelist *ndlp; | ||
| 3880 | |||
| 3881 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) | ||
| 3882 | ndlp->nlp_fc4_type &= ~(NLP_FC4_FCP | NLP_FC4_NVME); | ||
| 3876 | 3883 | ||
| 3877 | /* Good status, issue CT Request to NameServer */ | 3884 | /* Good status, issue CT Request to NameServer */ |
| 3878 | if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) || | 3885 | if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) || |
diff --git a/drivers/scsi/lpfc/lpfc_hw.h b/drivers/scsi/lpfc/lpfc_hw.h index bdc1f184f67a..08a3f1520159 100644 --- a/drivers/scsi/lpfc/lpfc_hw.h +++ b/drivers/scsi/lpfc/lpfc_hw.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * | 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -1177,6 +1177,9 @@ struct fc_rdp_link_error_status_desc { | |||
| 1177 | #define RDP_PS_8GB 0x0800 | 1177 | #define RDP_PS_8GB 0x0800 |
| 1178 | #define RDP_PS_16GB 0x0400 | 1178 | #define RDP_PS_16GB 0x0400 |
| 1179 | #define RDP_PS_32GB 0x0200 | 1179 | #define RDP_PS_32GB 0x0200 |
| 1180 | #define RDP_PS_64GB 0x0100 | ||
| 1181 | #define RDP_PS_128GB 0x0080 | ||
| 1182 | #define RDP_PS_256GB 0x0040 | ||
| 1180 | 1183 | ||
| 1181 | #define RDP_CAP_USER_CONFIGURED 0x0002 | 1184 | #define RDP_CAP_USER_CONFIGURED 0x0002 |
| 1182 | #define RDP_CAP_UNKNOWN 0x0001 | 1185 | #define RDP_CAP_UNKNOWN 0x0001 |
| @@ -1580,6 +1583,7 @@ struct lpfc_fdmi_reg_portattr { | |||
| 1580 | #define PCI_DEVICE_ID_LANCER_FCOE 0xe260 | 1583 | #define PCI_DEVICE_ID_LANCER_FCOE 0xe260 |
| 1581 | #define PCI_DEVICE_ID_LANCER_FCOE_VF 0xe268 | 1584 | #define PCI_DEVICE_ID_LANCER_FCOE_VF 0xe268 |
| 1582 | #define PCI_DEVICE_ID_LANCER_G6_FC 0xe300 | 1585 | #define PCI_DEVICE_ID_LANCER_G6_FC 0xe300 |
| 1586 | #define PCI_DEVICE_ID_LANCER_G7_FC 0xf400 | ||
| 1583 | #define PCI_DEVICE_ID_SAT_SMB 0xf011 | 1587 | #define PCI_DEVICE_ID_SAT_SMB 0xf011 |
| 1584 | #define PCI_DEVICE_ID_SAT_MID 0xf015 | 1588 | #define PCI_DEVICE_ID_SAT_MID 0xf015 |
| 1585 | #define PCI_DEVICE_ID_RFLY 0xf095 | 1589 | #define PCI_DEVICE_ID_RFLY 0xf095 |
| @@ -2257,6 +2261,9 @@ typedef struct { | |||
| 2257 | #define LINK_SPEED_10G 0x10 /* 10 Gigabaud */ | 2261 | #define LINK_SPEED_10G 0x10 /* 10 Gigabaud */ |
| 2258 | #define LINK_SPEED_16G 0x11 /* 16 Gigabaud */ | 2262 | #define LINK_SPEED_16G 0x11 /* 16 Gigabaud */ |
| 2259 | #define LINK_SPEED_32G 0x14 /* 32 Gigabaud */ | 2263 | #define LINK_SPEED_32G 0x14 /* 32 Gigabaud */ |
| 2264 | #define LINK_SPEED_64G 0x17 /* 64 Gigabaud */ | ||
| 2265 | #define LINK_SPEED_128G 0x1A /* 128 Gigabaud */ | ||
| 2266 | #define LINK_SPEED_256G 0x1D /* 256 Gigabaud */ | ||
| 2260 | 2267 | ||
| 2261 | } INIT_LINK_VAR; | 2268 | } INIT_LINK_VAR; |
| 2262 | 2269 | ||
| @@ -2441,6 +2448,9 @@ typedef struct { | |||
| 2441 | #define LMT_10Gb 0x100 | 2448 | #define LMT_10Gb 0x100 |
| 2442 | #define LMT_16Gb 0x200 | 2449 | #define LMT_16Gb 0x200 |
| 2443 | #define LMT_32Gb 0x400 | 2450 | #define LMT_32Gb 0x400 |
| 2451 | #define LMT_64Gb 0x800 | ||
| 2452 | #define LMT_128Gb 0x1000 | ||
| 2453 | #define LMT_256Gb 0x2000 | ||
| 2444 | uint32_t rsvd2; | 2454 | uint32_t rsvd2; |
| 2445 | uint32_t rsvd3; | 2455 | uint32_t rsvd3; |
| 2446 | uint32_t max_xri; | 2456 | uint32_t max_xri; |
| @@ -2965,6 +2975,9 @@ struct lpfc_mbx_read_top { | |||
| 2965 | #define LPFC_LINK_SPEED_10GHZ 0x40 | 2975 | #define LPFC_LINK_SPEED_10GHZ 0x40 |
| 2966 | #define LPFC_LINK_SPEED_16GHZ 0x80 | 2976 | #define LPFC_LINK_SPEED_16GHZ 0x80 |
| 2967 | #define LPFC_LINK_SPEED_32GHZ 0x90 | 2977 | #define LPFC_LINK_SPEED_32GHZ 0x90 |
| 2978 | #define LPFC_LINK_SPEED_64GHZ 0xA0 | ||
| 2979 | #define LPFC_LINK_SPEED_128GHZ 0xB0 | ||
| 2980 | #define LPFC_LINK_SPEED_256GHZ 0xC0 | ||
| 2968 | }; | 2981 | }; |
| 2969 | 2982 | ||
| 2970 | /* Structure for MB Command CLEAR_LA (22) */ | 2983 | /* Structure for MB Command CLEAR_LA (22) */ |
diff --git a/drivers/scsi/lpfc/lpfc_hw4.h b/drivers/scsi/lpfc/lpfc_hw4.h index 73c2f6971d2b..98b80559c215 100644 --- a/drivers/scsi/lpfc/lpfc_hw4.h +++ b/drivers/scsi/lpfc/lpfc_hw4.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2009-2016 Emulex. All rights reserved. * | 6 | * Copyright (C) 2009-2016 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -84,6 +84,7 @@ struct lpfc_sli_intf { | |||
| 84 | #define LPFC_SLI_INTF_IF_TYPE_0 0 | 84 | #define LPFC_SLI_INTF_IF_TYPE_0 0 |
| 85 | #define LPFC_SLI_INTF_IF_TYPE_1 1 | 85 | #define LPFC_SLI_INTF_IF_TYPE_1 1 |
| 86 | #define LPFC_SLI_INTF_IF_TYPE_2 2 | 86 | #define LPFC_SLI_INTF_IF_TYPE_2 2 |
| 87 | #define LPFC_SLI_INTF_IF_TYPE_6 6 | ||
| 87 | #define lpfc_sli_intf_sli_family_SHIFT 8 | 88 | #define lpfc_sli_intf_sli_family_SHIFT 8 |
| 88 | #define lpfc_sli_intf_sli_family_MASK 0x0000000F | 89 | #define lpfc_sli_intf_sli_family_MASK 0x0000000F |
| 89 | #define lpfc_sli_intf_sli_family_WORD word0 | 90 | #define lpfc_sli_intf_sli_family_WORD word0 |
| @@ -731,11 +732,13 @@ struct lpfc_register { | |||
| 731 | * register sets depending on the UCNA Port's reported if_type | 732 | * register sets depending on the UCNA Port's reported if_type |
| 732 | * value. For UCNA ports running SLI4 and if_type 0, they reside in | 733 | * value. For UCNA ports running SLI4 and if_type 0, they reside in |
| 733 | * BAR4. For UCNA ports running SLI4 and if_type 2, they reside in | 734 | * BAR4. For UCNA ports running SLI4 and if_type 2, they reside in |
| 734 | * BAR0. The offsets are the same so the driver must account for | 735 | * BAR0. For FC ports running SLI4 and if_type 6, they reside in |
| 735 | * any base address difference. | 736 | * BAR2. The offsets and base address are different, so the driver |
| 737 | * has to compute the register addresses accordingly | ||
| 736 | */ | 738 | */ |
| 737 | #define LPFC_ULP0_RQ_DOORBELL 0x00A0 | 739 | #define LPFC_ULP0_RQ_DOORBELL 0x00A0 |
| 738 | #define LPFC_ULP1_RQ_DOORBELL 0x00C0 | 740 | #define LPFC_ULP1_RQ_DOORBELL 0x00C0 |
| 741 | #define LPFC_IF6_RQ_DOORBELL 0x0080 | ||
| 739 | #define lpfc_rq_db_list_fm_num_posted_SHIFT 24 | 742 | #define lpfc_rq_db_list_fm_num_posted_SHIFT 24 |
| 740 | #define lpfc_rq_db_list_fm_num_posted_MASK 0x00FF | 743 | #define lpfc_rq_db_list_fm_num_posted_MASK 0x00FF |
| 741 | #define lpfc_rq_db_list_fm_num_posted_WORD word0 | 744 | #define lpfc_rq_db_list_fm_num_posted_WORD word0 |
| @@ -770,6 +773,20 @@ struct lpfc_register { | |||
| 770 | #define lpfc_wq_db_ring_fm_id_MASK 0xFFFF | 773 | #define lpfc_wq_db_ring_fm_id_MASK 0xFFFF |
| 771 | #define lpfc_wq_db_ring_fm_id_WORD word0 | 774 | #define lpfc_wq_db_ring_fm_id_WORD word0 |
| 772 | 775 | ||
| 776 | #define LPFC_IF6_WQ_DOORBELL 0x0040 | ||
| 777 | #define lpfc_if6_wq_db_list_fm_num_posted_SHIFT 24 | ||
| 778 | #define lpfc_if6_wq_db_list_fm_num_posted_MASK 0x00FF | ||
| 779 | #define lpfc_if6_wq_db_list_fm_num_posted_WORD word0 | ||
| 780 | #define lpfc_if6_wq_db_list_fm_dpp_SHIFT 23 | ||
| 781 | #define lpfc_if6_wq_db_list_fm_dpp_MASK 0x0001 | ||
| 782 | #define lpfc_if6_wq_db_list_fm_dpp_WORD word0 | ||
| 783 | #define lpfc_if6_wq_db_list_fm_dpp_id_SHIFT 16 | ||
| 784 | #define lpfc_if6_wq_db_list_fm_dpp_id_MASK 0x001F | ||
| 785 | #define lpfc_if6_wq_db_list_fm_dpp_id_WORD word0 | ||
| 786 | #define lpfc_if6_wq_db_list_fm_id_SHIFT 0 | ||
| 787 | #define lpfc_if6_wq_db_list_fm_id_MASK 0xFFFF | ||
| 788 | #define lpfc_if6_wq_db_list_fm_id_WORD word0 | ||
| 789 | |||
| 773 | #define LPFC_EQCQ_DOORBELL 0x0120 | 790 | #define LPFC_EQCQ_DOORBELL 0x0120 |
| 774 | #define lpfc_eqcq_doorbell_se_SHIFT 31 | 791 | #define lpfc_eqcq_doorbell_se_SHIFT 31 |
| 775 | #define lpfc_eqcq_doorbell_se_MASK 0x0001 | 792 | #define lpfc_eqcq_doorbell_se_MASK 0x0001 |
| @@ -805,6 +822,38 @@ struct lpfc_register { | |||
| 805 | #define LPFC_CQID_HI_FIELD_SHIFT 10 | 822 | #define LPFC_CQID_HI_FIELD_SHIFT 10 |
| 806 | #define LPFC_EQID_HI_FIELD_SHIFT 9 | 823 | #define LPFC_EQID_HI_FIELD_SHIFT 9 |
| 807 | 824 | ||
| 825 | #define LPFC_IF6_CQ_DOORBELL 0x00C0 | ||
| 826 | #define lpfc_if6_cq_doorbell_se_SHIFT 31 | ||
| 827 | #define lpfc_if6_cq_doorbell_se_MASK 0x0001 | ||
| 828 | #define lpfc_if6_cq_doorbell_se_WORD word0 | ||
| 829 | #define LPFC_IF6_CQ_SOLICIT_ENABLE_OFF 0 | ||
| 830 | #define LPFC_IF6_CQ_SOLICIT_ENABLE_ON 1 | ||
| 831 | #define lpfc_if6_cq_doorbell_arm_SHIFT 29 | ||
| 832 | #define lpfc_if6_cq_doorbell_arm_MASK 0x0001 | ||
| 833 | #define lpfc_if6_cq_doorbell_arm_WORD word0 | ||
| 834 | #define lpfc_if6_cq_doorbell_num_released_SHIFT 16 | ||
| 835 | #define lpfc_if6_cq_doorbell_num_released_MASK 0x1FFF | ||
| 836 | #define lpfc_if6_cq_doorbell_num_released_WORD word0 | ||
| 837 | #define lpfc_if6_cq_doorbell_cqid_SHIFT 0 | ||
| 838 | #define lpfc_if6_cq_doorbell_cqid_MASK 0xFFFF | ||
| 839 | #define lpfc_if6_cq_doorbell_cqid_WORD word0 | ||
| 840 | |||
| 841 | #define LPFC_IF6_EQ_DOORBELL 0x0120 | ||
| 842 | #define lpfc_if6_eq_doorbell_io_SHIFT 31 | ||
| 843 | #define lpfc_if6_eq_doorbell_io_MASK 0x0001 | ||
| 844 | #define lpfc_if6_eq_doorbell_io_WORD word0 | ||
| 845 | #define LPFC_IF6_EQ_INTR_OVERRIDE_OFF 0 | ||
| 846 | #define LPFC_IF6_EQ_INTR_OVERRIDE_ON 1 | ||
| 847 | #define lpfc_if6_eq_doorbell_arm_SHIFT 29 | ||
| 848 | #define lpfc_if6_eq_doorbell_arm_MASK 0x0001 | ||
| 849 | #define lpfc_if6_eq_doorbell_arm_WORD word0 | ||
| 850 | #define lpfc_if6_eq_doorbell_num_released_SHIFT 16 | ||
| 851 | #define lpfc_if6_eq_doorbell_num_released_MASK 0x1FFF | ||
| 852 | #define lpfc_if6_eq_doorbell_num_released_WORD word0 | ||
| 853 | #define lpfc_if6_eq_doorbell_eqid_SHIFT 0 | ||
| 854 | #define lpfc_if6_eq_doorbell_eqid_MASK 0x0FFF | ||
| 855 | #define lpfc_if6_eq_doorbell_eqid_WORD word0 | ||
| 856 | |||
| 808 | #define LPFC_BMBX 0x0160 | 857 | #define LPFC_BMBX 0x0160 |
| 809 | #define lpfc_bmbx_addr_SHIFT 2 | 858 | #define lpfc_bmbx_addr_SHIFT 2 |
| 810 | #define lpfc_bmbx_addr_MASK 0x3FFFFFFF | 859 | #define lpfc_bmbx_addr_MASK 0x3FFFFFFF |
| @@ -817,6 +866,7 @@ struct lpfc_register { | |||
| 817 | #define lpfc_bmbx_rdy_WORD word0 | 866 | #define lpfc_bmbx_rdy_WORD word0 |
| 818 | 867 | ||
| 819 | #define LPFC_MQ_DOORBELL 0x0140 | 868 | #define LPFC_MQ_DOORBELL 0x0140 |
| 869 | #define LPFC_IF6_MQ_DOORBELL 0x0160 | ||
| 820 | #define lpfc_mq_doorbell_num_posted_SHIFT 16 | 870 | #define lpfc_mq_doorbell_num_posted_SHIFT 16 |
| 821 | #define lpfc_mq_doorbell_num_posted_MASK 0x3FFF | 871 | #define lpfc_mq_doorbell_num_posted_MASK 0x3FFF |
| 822 | #define lpfc_mq_doorbell_num_posted_WORD word0 | 872 | #define lpfc_mq_doorbell_num_posted_WORD word0 |
| @@ -990,6 +1040,9 @@ struct eq_context { | |||
| 990 | #define lpfc_eq_context_valid_SHIFT 29 | 1040 | #define lpfc_eq_context_valid_SHIFT 29 |
| 991 | #define lpfc_eq_context_valid_MASK 0x00000001 | 1041 | #define lpfc_eq_context_valid_MASK 0x00000001 |
| 992 | #define lpfc_eq_context_valid_WORD word0 | 1042 | #define lpfc_eq_context_valid_WORD word0 |
| 1043 | #define lpfc_eq_context_autovalid_SHIFT 28 | ||
| 1044 | #define lpfc_eq_context_autovalid_MASK 0x00000001 | ||
| 1045 | #define lpfc_eq_context_autovalid_WORD word0 | ||
| 993 | uint32_t word1; | 1046 | uint32_t word1; |
| 994 | #define lpfc_eq_context_count_SHIFT 26 | 1047 | #define lpfc_eq_context_count_SHIFT 26 |
| 995 | #define lpfc_eq_context_count_MASK 0x00000003 | 1048 | #define lpfc_eq_context_count_MASK 0x00000003 |
| @@ -1123,6 +1176,9 @@ struct cq_context { | |||
| 1123 | #define LPFC_CQ_CNT_512 0x1 | 1176 | #define LPFC_CQ_CNT_512 0x1 |
| 1124 | #define LPFC_CQ_CNT_1024 0x2 | 1177 | #define LPFC_CQ_CNT_1024 0x2 |
| 1125 | #define LPFC_CQ_CNT_WORD7 0x3 | 1178 | #define LPFC_CQ_CNT_WORD7 0x3 |
| 1179 | #define lpfc_cq_context_autovalid_SHIFT 15 | ||
| 1180 | #define lpfc_cq_context_autovalid_MASK 0x00000001 | ||
| 1181 | #define lpfc_cq_context_autovalid_WORD word0 | ||
| 1126 | uint32_t word1; | 1182 | uint32_t word1; |
| 1127 | #define lpfc_cq_eq_id_SHIFT 22 /* Version 0 Only */ | 1183 | #define lpfc_cq_eq_id_SHIFT 22 /* Version 0 Only */ |
| 1128 | #define lpfc_cq_eq_id_MASK 0x000000FF | 1184 | #define lpfc_cq_eq_id_MASK 0x000000FF |
| @@ -1181,9 +1237,9 @@ struct lpfc_mbx_cq_create_set { | |||
| 1181 | #define lpfc_mbx_cq_create_set_cqe_size_SHIFT 25 | 1237 | #define lpfc_mbx_cq_create_set_cqe_size_SHIFT 25 |
| 1182 | #define lpfc_mbx_cq_create_set_cqe_size_MASK 0x00000003 | 1238 | #define lpfc_mbx_cq_create_set_cqe_size_MASK 0x00000003 |
| 1183 | #define lpfc_mbx_cq_create_set_cqe_size_WORD word1 | 1239 | #define lpfc_mbx_cq_create_set_cqe_size_WORD word1 |
| 1184 | #define lpfc_mbx_cq_create_set_auto_SHIFT 15 | 1240 | #define lpfc_mbx_cq_create_set_autovalid_SHIFT 15 |
| 1185 | #define lpfc_mbx_cq_create_set_auto_MASK 0x0000001 | 1241 | #define lpfc_mbx_cq_create_set_autovalid_MASK 0x0000001 |
| 1186 | #define lpfc_mbx_cq_create_set_auto_WORD word1 | 1242 | #define lpfc_mbx_cq_create_set_autovalid_WORD word1 |
| 1187 | #define lpfc_mbx_cq_create_set_nodelay_SHIFT 14 | 1243 | #define lpfc_mbx_cq_create_set_nodelay_SHIFT 14 |
| 1188 | #define lpfc_mbx_cq_create_set_nodelay_MASK 0x00000001 | 1244 | #define lpfc_mbx_cq_create_set_nodelay_MASK 0x00000001 |
| 1189 | #define lpfc_mbx_cq_create_set_nodelay_WORD word1 | 1245 | #define lpfc_mbx_cq_create_set_nodelay_WORD word1 |
| @@ -1322,6 +1378,15 @@ struct lpfc_mbx_wq_create { | |||
| 1322 | #define lpfc_mbx_wq_create_page_size_MASK 0x000000FF | 1378 | #define lpfc_mbx_wq_create_page_size_MASK 0x000000FF |
| 1323 | #define lpfc_mbx_wq_create_page_size_WORD word1 | 1379 | #define lpfc_mbx_wq_create_page_size_WORD word1 |
| 1324 | #define LPFC_WQ_PAGE_SIZE_4096 0x1 | 1380 | #define LPFC_WQ_PAGE_SIZE_4096 0x1 |
| 1381 | #define lpfc_mbx_wq_create_dpp_req_SHIFT 15 | ||
| 1382 | #define lpfc_mbx_wq_create_dpp_req_MASK 0x00000001 | ||
| 1383 | #define lpfc_mbx_wq_create_dpp_req_WORD word1 | ||
| 1384 | #define lpfc_mbx_wq_create_doe_SHIFT 14 | ||
| 1385 | #define lpfc_mbx_wq_create_doe_MASK 0x00000001 | ||
| 1386 | #define lpfc_mbx_wq_create_doe_WORD word1 | ||
| 1387 | #define lpfc_mbx_wq_create_toe_SHIFT 13 | ||
| 1388 | #define lpfc_mbx_wq_create_toe_MASK 0x00000001 | ||
| 1389 | #define lpfc_mbx_wq_create_toe_WORD word1 | ||
| 1325 | #define lpfc_mbx_wq_create_wqe_size_SHIFT 8 | 1390 | #define lpfc_mbx_wq_create_wqe_size_SHIFT 8 |
| 1326 | #define lpfc_mbx_wq_create_wqe_size_MASK 0x0000000F | 1391 | #define lpfc_mbx_wq_create_wqe_size_MASK 0x0000000F |
| 1327 | #define lpfc_mbx_wq_create_wqe_size_WORD word1 | 1392 | #define lpfc_mbx_wq_create_wqe_size_WORD word1 |
| @@ -1350,6 +1415,28 @@ struct lpfc_mbx_wq_create { | |||
| 1350 | #define lpfc_mbx_wq_create_db_format_MASK 0x0000FFFF | 1415 | #define lpfc_mbx_wq_create_db_format_MASK 0x0000FFFF |
| 1351 | #define lpfc_mbx_wq_create_db_format_WORD word2 | 1416 | #define lpfc_mbx_wq_create_db_format_WORD word2 |
| 1352 | } response; | 1417 | } response; |
| 1418 | struct { | ||
| 1419 | uint32_t word0; | ||
| 1420 | #define lpfc_mbx_wq_create_dpp_rsp_SHIFT 31 | ||
| 1421 | #define lpfc_mbx_wq_create_dpp_rsp_MASK 0x00000001 | ||
| 1422 | #define lpfc_mbx_wq_create_dpp_rsp_WORD word0 | ||
| 1423 | #define lpfc_mbx_wq_create_v1_q_id_SHIFT 0 | ||
| 1424 | #define lpfc_mbx_wq_create_v1_q_id_MASK 0x0000FFFF | ||
| 1425 | #define lpfc_mbx_wq_create_v1_q_id_WORD word0 | ||
| 1426 | uint32_t word1; | ||
| 1427 | #define lpfc_mbx_wq_create_v1_bar_set_SHIFT 0 | ||
| 1428 | #define lpfc_mbx_wq_create_v1_bar_set_MASK 0x0000000F | ||
| 1429 | #define lpfc_mbx_wq_create_v1_bar_set_WORD word1 | ||
| 1430 | uint32_t doorbell_offset; | ||
| 1431 | uint32_t word3; | ||
| 1432 | #define lpfc_mbx_wq_create_dpp_id_SHIFT 16 | ||
| 1433 | #define lpfc_mbx_wq_create_dpp_id_MASK 0x0000001F | ||
| 1434 | #define lpfc_mbx_wq_create_dpp_id_WORD word3 | ||
| 1435 | #define lpfc_mbx_wq_create_dpp_bar_SHIFT 0 | ||
| 1436 | #define lpfc_mbx_wq_create_dpp_bar_MASK 0x0000000F | ||
| 1437 | #define lpfc_mbx_wq_create_dpp_bar_WORD word3 | ||
| 1438 | uint32_t dpp_offset; | ||
| 1439 | } response_1; | ||
| 1353 | } u; | 1440 | } u; |
| 1354 | }; | 1441 | }; |
| 1355 | 1442 | ||
| @@ -2154,6 +2241,7 @@ struct lpfc_mbx_redisc_fcf_tbl { | |||
| 2154 | * command. | 2241 | * command. |
| 2155 | */ | 2242 | */ |
| 2156 | #define ADD_STATUS_OPERATION_ALREADY_ACTIVE 0x67 | 2243 | #define ADD_STATUS_OPERATION_ALREADY_ACTIVE 0x67 |
| 2244 | #define ADD_STATUS_FW_NOT_SUPPORTED 0xEB | ||
| 2157 | 2245 | ||
| 2158 | struct lpfc_mbx_sli4_config { | 2246 | struct lpfc_mbx_sli4_config { |
| 2159 | struct mbox_header header; | 2247 | struct mbox_header header; |
| @@ -2590,6 +2678,7 @@ struct lpfc_mbx_read_rev { | |||
| 2590 | #define lpfc_mbx_rd_rev_vpd_MASK 0x00000001 | 2678 | #define lpfc_mbx_rd_rev_vpd_MASK 0x00000001 |
| 2591 | #define lpfc_mbx_rd_rev_vpd_WORD word1 | 2679 | #define lpfc_mbx_rd_rev_vpd_WORD word1 |
| 2592 | uint32_t first_hw_rev; | 2680 | uint32_t first_hw_rev; |
| 2681 | #define LPFC_G7_ASIC_1 0xd | ||
| 2593 | uint32_t second_hw_rev; | 2682 | uint32_t second_hw_rev; |
| 2594 | uint32_t word4_rsvd; | 2683 | uint32_t word4_rsvd; |
| 2595 | uint32_t third_hw_rev; | 2684 | uint32_t third_hw_rev; |
| @@ -3207,11 +3296,20 @@ struct lpfc_sli4_parameters { | |||
| 3207 | #define cfg_sli_hint_2_MASK 0x0000001f | 3296 | #define cfg_sli_hint_2_MASK 0x0000001f |
| 3208 | #define cfg_sli_hint_2_WORD word1 | 3297 | #define cfg_sli_hint_2_WORD word1 |
| 3209 | uint32_t word2; | 3298 | uint32_t word2; |
| 3299 | #define cfg_eqav_SHIFT 31 | ||
| 3300 | #define cfg_eqav_MASK 0x00000001 | ||
| 3301 | #define cfg_eqav_WORD word2 | ||
| 3210 | uint32_t word3; | 3302 | uint32_t word3; |
| 3211 | uint32_t word4; | 3303 | uint32_t word4; |
| 3212 | #define cfg_cqv_SHIFT 14 | 3304 | #define cfg_cqv_SHIFT 14 |
| 3213 | #define cfg_cqv_MASK 0x00000003 | 3305 | #define cfg_cqv_MASK 0x00000003 |
| 3214 | #define cfg_cqv_WORD word4 | 3306 | #define cfg_cqv_WORD word4 |
| 3307 | #define cfg_cqpsize_SHIFT 16 | ||
| 3308 | #define cfg_cqpsize_MASK 0x000000ff | ||
| 3309 | #define cfg_cqpsize_WORD word4 | ||
| 3310 | #define cfg_cqav_SHIFT 31 | ||
| 3311 | #define cfg_cqav_MASK 0x00000001 | ||
| 3312 | #define cfg_cqav_WORD word4 | ||
| 3215 | uint32_t word5; | 3313 | uint32_t word5; |
| 3216 | uint32_t word6; | 3314 | uint32_t word6; |
| 3217 | #define cfg_mqv_SHIFT 14 | 3315 | #define cfg_mqv_SHIFT 14 |
| @@ -3290,6 +3388,9 @@ struct lpfc_sli4_parameters { | |||
| 3290 | #define cfg_eqdr_SHIFT 8 | 3388 | #define cfg_eqdr_SHIFT 8 |
| 3291 | #define cfg_eqdr_MASK 0x00000001 | 3389 | #define cfg_eqdr_MASK 0x00000001 |
| 3292 | #define cfg_eqdr_WORD word19 | 3390 | #define cfg_eqdr_WORD word19 |
| 3391 | #define cfg_nosr_SHIFT 9 | ||
| 3392 | #define cfg_nosr_MASK 0x00000001 | ||
| 3393 | #define cfg_nosr_WORD word19 | ||
| 3293 | #define LPFC_NODELAY_MAX_IO 32 | 3394 | #define LPFC_NODELAY_MAX_IO 32 |
| 3294 | }; | 3395 | }; |
| 3295 | 3396 | ||
| @@ -3874,6 +3975,9 @@ struct lpfc_acqe_fc_la { | |||
| 3874 | #define LPFC_FC_LA_SPEED_10G 0xA | 3975 | #define LPFC_FC_LA_SPEED_10G 0xA |
| 3875 | #define LPFC_FC_LA_SPEED_16G 0x10 | 3976 | #define LPFC_FC_LA_SPEED_16G 0x10 |
| 3876 | #define LPFC_FC_LA_SPEED_32G 0x20 | 3977 | #define LPFC_FC_LA_SPEED_32G 0x20 |
| 3978 | #define LPFC_FC_LA_SPEED_64G 0x21 | ||
| 3979 | #define LPFC_FC_LA_SPEED_128G 0x22 | ||
| 3980 | #define LPFC_FC_LA_SPEED_256G 0x23 | ||
| 3877 | #define lpfc_acqe_fc_la_topology_SHIFT 16 | 3981 | #define lpfc_acqe_fc_la_topology_SHIFT 16 |
| 3878 | #define lpfc_acqe_fc_la_topology_MASK 0x000000FF | 3982 | #define lpfc_acqe_fc_la_topology_MASK 0x000000FF |
| 3879 | #define lpfc_acqe_fc_la_topology_WORD word0 | 3983 | #define lpfc_acqe_fc_la_topology_WORD word0 |
| @@ -4079,6 +4183,7 @@ struct wqe_common { | |||
| 4079 | #define wqe_iod_SHIFT 13 | 4183 | #define wqe_iod_SHIFT 13 |
| 4080 | #define wqe_iod_MASK 0x00000001 | 4184 | #define wqe_iod_MASK 0x00000001 |
| 4081 | #define wqe_iod_WORD word10 | 4185 | #define wqe_iod_WORD word10 |
| 4186 | #define LPFC_WQE_IOD_NONE 0 | ||
| 4082 | #define LPFC_WQE_IOD_WRITE 0 | 4187 | #define LPFC_WQE_IOD_WRITE 0 |
| 4083 | #define LPFC_WQE_IOD_READ 1 | 4188 | #define LPFC_WQE_IOD_READ 1 |
| 4084 | #define wqe_dbde_SHIFT 14 | 4189 | #define wqe_dbde_SHIFT 14 |
| @@ -4123,6 +4228,9 @@ struct wqe_common { | |||
| 4123 | #define wqe_irsp_SHIFT 4 | 4228 | #define wqe_irsp_SHIFT 4 |
| 4124 | #define wqe_irsp_MASK 0x00000001 | 4229 | #define wqe_irsp_MASK 0x00000001 |
| 4125 | #define wqe_irsp_WORD word11 | 4230 | #define wqe_irsp_WORD word11 |
| 4231 | #define wqe_pbde_SHIFT 5 | ||
| 4232 | #define wqe_pbde_MASK 0x00000001 | ||
| 4233 | #define wqe_pbde_WORD word11 | ||
| 4126 | #define wqe_sup_SHIFT 6 | 4234 | #define wqe_sup_SHIFT 6 |
| 4127 | #define wqe_sup_MASK 0x00000001 | 4235 | #define wqe_sup_MASK 0x00000001 |
| 4128 | #define wqe_sup_WORD word11 | 4236 | #define wqe_sup_WORD word11 |
| @@ -4343,9 +4451,9 @@ struct lpfc_nvme_prli { | |||
| 4343 | #define prli_init_SHIFT 5 | 4451 | #define prli_init_SHIFT 5 |
| 4344 | #define prli_init_MASK 0x00000001 | 4452 | #define prli_init_MASK 0x00000001 |
| 4345 | #define prli_init_WORD word4 | 4453 | #define prli_init_WORD word4 |
| 4346 | #define prli_recov_SHIFT 8 | 4454 | #define prli_conf_SHIFT 7 |
| 4347 | #define prli_recov_MASK 0x00000001 | 4455 | #define prli_conf_MASK 0x00000001 |
| 4348 | #define prli_recov_WORD word4 | 4456 | #define prli_conf_WORD word4 |
| 4349 | uint32_t word5; | 4457 | uint32_t word5; |
| 4350 | #define prli_fb_sz_SHIFT 0 | 4458 | #define prli_fb_sz_SHIFT 0 |
| 4351 | #define prli_fb_sz_MASK 0x0000ffff | 4459 | #define prli_fb_sz_MASK 0x0000ffff |
| @@ -4494,17 +4602,20 @@ union lpfc_wqe128 { | |||
| 4494 | struct fcp_icmnd64_wqe fcp_icmd; | 4602 | struct fcp_icmnd64_wqe fcp_icmd; |
| 4495 | struct fcp_iread64_wqe fcp_iread; | 4603 | struct fcp_iread64_wqe fcp_iread; |
| 4496 | struct fcp_iwrite64_wqe fcp_iwrite; | 4604 | struct fcp_iwrite64_wqe fcp_iwrite; |
| 4605 | struct abort_cmd_wqe abort_cmd; | ||
| 4606 | struct create_xri_wqe create_xri; | ||
| 4607 | struct xmit_bcast64_wqe xmit_bcast64; | ||
| 4608 | struct xmit_seq64_wqe xmit_sequence; | ||
| 4609 | struct xmit_bls_rsp64_wqe xmit_bls_rsp; | ||
| 4610 | struct xmit_els_rsp64_wqe xmit_els_rsp; | ||
| 4611 | struct els_request64_wqe els_req; | ||
| 4612 | struct gen_req64_wqe gen_req; | ||
| 4497 | struct fcp_trsp64_wqe fcp_trsp; | 4613 | struct fcp_trsp64_wqe fcp_trsp; |
| 4498 | struct fcp_tsend64_wqe fcp_tsend; | 4614 | struct fcp_tsend64_wqe fcp_tsend; |
| 4499 | struct fcp_treceive64_wqe fcp_treceive; | 4615 | struct fcp_treceive64_wqe fcp_treceive; |
| 4500 | struct xmit_seq64_wqe xmit_sequence; | 4616 | struct send_frame_wqe send_frame; |
| 4501 | struct gen_req64_wqe gen_req; | ||
| 4502 | }; | 4617 | }; |
| 4503 | 4618 | ||
| 4504 | #define LPFC_GROUP_OJECT_MAGIC_G5 0xfeaa0001 | ||
| 4505 | #define LPFC_GROUP_OJECT_MAGIC_G6 0xfeaa0003 | ||
| 4506 | #define LPFC_FILE_TYPE_GROUP 0xf7 | ||
| 4507 | #define LPFC_FILE_ID_GROUP 0xa2 | ||
| 4508 | struct lpfc_grp_hdr { | 4619 | struct lpfc_grp_hdr { |
| 4509 | uint32_t size; | 4620 | uint32_t size; |
| 4510 | uint32_t magic_number; | 4621 | uint32_t magic_number; |
diff --git a/drivers/scsi/lpfc/lpfc_ids.h b/drivers/scsi/lpfc/lpfc_ids.h index 0ba3733eb36d..07ee34017d88 100644 --- a/drivers/scsi/lpfc/lpfc_ids.h +++ b/drivers/scsi/lpfc/lpfc_ids.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * | 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -116,6 +116,8 @@ const struct pci_device_id lpfc_id_table[] = { | |||
| 116 | PCI_ANY_ID, PCI_ANY_ID, }, | 116 | PCI_ANY_ID, PCI_ANY_ID, }, |
| 117 | {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_G6_FC, | 117 | {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_G6_FC, |
| 118 | PCI_ANY_ID, PCI_ANY_ID, }, | 118 | PCI_ANY_ID, PCI_ANY_ID, }, |
| 119 | {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_G7_FC, | ||
| 120 | PCI_ANY_ID, PCI_ANY_ID, }, | ||
| 119 | {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK, | 121 | {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK, |
| 120 | PCI_ANY_ID, PCI_ANY_ID, }, | 122 | PCI_ANY_ID, PCI_ANY_ID, }, |
| 121 | {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK_VF, | 123 | {PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_SKYHAWK_VF, |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index f539c554588c..7887468c71b4 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * | 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -731,7 +731,9 @@ lpfc_hba_init_link_fc_topology(struct lpfc_hba *phba, uint32_t fc_topology, | |||
| 731 | ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_16G) && | 731 | ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_16G) && |
| 732 | !(phba->lmt & LMT_16Gb)) || | 732 | !(phba->lmt & LMT_16Gb)) || |
| 733 | ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_32G) && | 733 | ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_32G) && |
| 734 | !(phba->lmt & LMT_32Gb))) { | 734 | !(phba->lmt & LMT_32Gb)) || |
| 735 | ((phba->cfg_link_speed == LPFC_USER_LINK_SPEED_64G) && | ||
| 736 | !(phba->lmt & LMT_64Gb))) { | ||
| 735 | /* Reset link speed to auto */ | 737 | /* Reset link speed to auto */ |
| 736 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, | 738 | lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT, |
| 737 | "1302 Invalid speed for this board:%d " | 739 | "1302 Invalid speed for this board:%d " |
| @@ -958,6 +960,7 @@ lpfc_hba_clean_txcmplq(struct lpfc_hba *phba) | |||
| 958 | struct lpfc_sli_ring *pring; | 960 | struct lpfc_sli_ring *pring; |
| 959 | LIST_HEAD(completions); | 961 | LIST_HEAD(completions); |
| 960 | int i; | 962 | int i; |
| 963 | struct lpfc_iocbq *piocb, *next_iocb; | ||
| 961 | 964 | ||
| 962 | if (phba->sli_rev != LPFC_SLI_REV4) { | 965 | if (phba->sli_rev != LPFC_SLI_REV4) { |
| 963 | for (i = 0; i < psli->num_rings; i++) { | 966 | for (i = 0; i < psli->num_rings; i++) { |
| @@ -983,6 +986,9 @@ lpfc_hba_clean_txcmplq(struct lpfc_hba *phba) | |||
| 983 | if (!pring) | 986 | if (!pring) |
| 984 | continue; | 987 | continue; |
| 985 | spin_lock_irq(&pring->ring_lock); | 988 | spin_lock_irq(&pring->ring_lock); |
| 989 | list_for_each_entry_safe(piocb, next_iocb, | ||
| 990 | &pring->txcmplq, list) | ||
| 991 | piocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ; | ||
| 986 | list_splice_init(&pring->txcmplq, &completions); | 992 | list_splice_init(&pring->txcmplq, &completions); |
| 987 | pring->txcmplq_cnt = 0; | 993 | pring->txcmplq_cnt = 0; |
| 988 | spin_unlock_irq(&pring->ring_lock); | 994 | spin_unlock_irq(&pring->ring_lock); |
| @@ -1757,7 +1763,7 @@ lpfc_sli4_port_sta_fn_reset(struct lpfc_hba *phba, int mbx_action, | |||
| 1757 | int rc; | 1763 | int rc; |
| 1758 | uint32_t intr_mode; | 1764 | uint32_t intr_mode; |
| 1759 | 1765 | ||
| 1760 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) == | 1766 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) >= |
| 1761 | LPFC_SLI_INTF_IF_TYPE_2) { | 1767 | LPFC_SLI_INTF_IF_TYPE_2) { |
| 1762 | /* | 1768 | /* |
| 1763 | * On error status condition, driver need to wait for port | 1769 | * On error status condition, driver need to wait for port |
| @@ -1888,6 +1894,7 @@ lpfc_handle_eratt_s4(struct lpfc_hba *phba) | |||
| 1888 | break; | 1894 | break; |
| 1889 | 1895 | ||
| 1890 | case LPFC_SLI_INTF_IF_TYPE_2: | 1896 | case LPFC_SLI_INTF_IF_TYPE_2: |
| 1897 | case LPFC_SLI_INTF_IF_TYPE_6: | ||
| 1891 | pci_rd_rc1 = lpfc_readl( | 1898 | pci_rd_rc1 = lpfc_readl( |
| 1892 | phba->sli4_hba.u.if_type2.STATUSregaddr, | 1899 | phba->sli4_hba.u.if_type2.STATUSregaddr, |
| 1893 | &portstat_reg.word0); | 1900 | &portstat_reg.word0); |
| @@ -2269,7 +2276,9 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) | |||
| 2269 | && descp && descp[0] != '\0') | 2276 | && descp && descp[0] != '\0') |
| 2270 | return; | 2277 | return; |
| 2271 | 2278 | ||
| 2272 | if (phba->lmt & LMT_32Gb) | 2279 | if (phba->lmt & LMT_64Gb) |
| 2280 | max_speed = 64; | ||
| 2281 | else if (phba->lmt & LMT_32Gb) | ||
| 2273 | max_speed = 32; | 2282 | max_speed = 32; |
| 2274 | else if (phba->lmt & LMT_16Gb) | 2283 | else if (phba->lmt & LMT_16Gb) |
| 2275 | max_speed = 16; | 2284 | max_speed = 16; |
| @@ -2468,6 +2477,9 @@ lpfc_get_hba_model_desc(struct lpfc_hba *phba, uint8_t *mdp, uint8_t *descp) | |||
| 2468 | case PCI_DEVICE_ID_LANCER_G6_FC: | 2477 | case PCI_DEVICE_ID_LANCER_G6_FC: |
| 2469 | m = (typeof(m)){"LPe32000", "PCIe", "Fibre Channel Adapter"}; | 2478 | m = (typeof(m)){"LPe32000", "PCIe", "Fibre Channel Adapter"}; |
| 2470 | break; | 2479 | break; |
| 2480 | case PCI_DEVICE_ID_LANCER_G7_FC: | ||
| 2481 | m = (typeof(m)){"LPe36000", "PCIe", "Fibre Channel Adapter"}; | ||
| 2482 | break; | ||
| 2471 | case PCI_DEVICE_ID_SKYHAWK: | 2483 | case PCI_DEVICE_ID_SKYHAWK: |
| 2472 | case PCI_DEVICE_ID_SKYHAWK_VF: | 2484 | case PCI_DEVICE_ID_SKYHAWK_VF: |
| 2473 | oneConnect = 1; | 2485 | oneConnect = 1; |
| @@ -4104,6 +4116,8 @@ void lpfc_host_attrib_init(struct Scsi_Host *shost) | |||
| 4104 | sizeof fc_host_symbolic_name(shost)); | 4116 | sizeof fc_host_symbolic_name(shost)); |
| 4105 | 4117 | ||
| 4106 | fc_host_supported_speeds(shost) = 0; | 4118 | fc_host_supported_speeds(shost) = 0; |
| 4119 | if (phba->lmt & LMT_64Gb) | ||
| 4120 | fc_host_supported_speeds(shost) |= FC_PORTSPEED_64GBIT; | ||
| 4107 | if (phba->lmt & LMT_32Gb) | 4121 | if (phba->lmt & LMT_32Gb) |
| 4108 | fc_host_supported_speeds(shost) |= FC_PORTSPEED_32GBIT; | 4122 | fc_host_supported_speeds(shost) |= FC_PORTSPEED_32GBIT; |
| 4109 | if (phba->lmt & LMT_16Gb) | 4123 | if (phba->lmt & LMT_16Gb) |
| @@ -4440,6 +4454,9 @@ lpfc_sli4_port_speed_parse(struct lpfc_hba *phba, uint32_t evt_code, | |||
| 4440 | case LPFC_FC_LA_SPEED_32G: | 4454 | case LPFC_FC_LA_SPEED_32G: |
| 4441 | port_speed = 32000; | 4455 | port_speed = 32000; |
| 4442 | break; | 4456 | break; |
| 4457 | case LPFC_FC_LA_SPEED_64G: | ||
| 4458 | port_speed = 64000; | ||
| 4459 | break; | ||
| 4443 | default: | 4460 | default: |
| 4444 | port_speed = 0; | 4461 | port_speed = 0; |
| 4445 | } | 4462 | } |
| @@ -5895,7 +5912,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
| 5895 | * Since lpfc_sg_seg_cnt is module param, the sg_dma_buf_size | 5912 | * Since lpfc_sg_seg_cnt is module param, the sg_dma_buf_size |
| 5896 | * used to create the sg_dma_buf_pool must be calculated. | 5913 | * used to create the sg_dma_buf_pool must be calculated. |
| 5897 | */ | 5914 | */ |
| 5898 | if (phba->cfg_enable_bg) { | 5915 | if (phba->sli3_options & LPFC_SLI3_BG_ENABLED) { |
| 5899 | /* | 5916 | /* |
| 5900 | * The scsi_buf for a T10-DIF I/O holds the FCP cmnd, | 5917 | * The scsi_buf for a T10-DIF I/O holds the FCP cmnd, |
| 5901 | * the FCP rsp, and a SGE. Sice we have no control | 5918 | * the FCP rsp, and a SGE. Sice we have no control |
| @@ -6014,7 +6031,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) | |||
| 6014 | return -ENOMEM; | 6031 | return -ENOMEM; |
| 6015 | 6032 | ||
| 6016 | /* IF Type 2 ports get initialized now. */ | 6033 | /* IF Type 2 ports get initialized now. */ |
| 6017 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) == | 6034 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) >= |
| 6018 | LPFC_SLI_INTF_IF_TYPE_2) { | 6035 | LPFC_SLI_INTF_IF_TYPE_2) { |
| 6019 | rc = lpfc_pci_function_reset(phba); | 6036 | rc = lpfc_pci_function_reset(phba); |
| 6020 | if (unlikely(rc)) { | 6037 | if (unlikely(rc)) { |
| @@ -7344,6 +7361,7 @@ lpfc_sli4_post_status_check(struct lpfc_hba *phba) | |||
| 7344 | } | 7361 | } |
| 7345 | break; | 7362 | break; |
| 7346 | case LPFC_SLI_INTF_IF_TYPE_2: | 7363 | case LPFC_SLI_INTF_IF_TYPE_2: |
| 7364 | case LPFC_SLI_INTF_IF_TYPE_6: | ||
| 7347 | /* Final checks. The port status should be clean. */ | 7365 | /* Final checks. The port status should be clean. */ |
| 7348 | if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr, | 7366 | if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr, |
| 7349 | ®_data.word0) || | 7367 | ®_data.word0) || |
| @@ -7426,13 +7444,36 @@ lpfc_sli4_bar0_register_memmap(struct lpfc_hba *phba, uint32_t if_type) | |||
| 7426 | phba->sli4_hba.WQDBregaddr = | 7444 | phba->sli4_hba.WQDBregaddr = |
| 7427 | phba->sli4_hba.conf_regs_memmap_p + | 7445 | phba->sli4_hba.conf_regs_memmap_p + |
| 7428 | LPFC_ULP0_WQ_DOORBELL; | 7446 | LPFC_ULP0_WQ_DOORBELL; |
| 7429 | phba->sli4_hba.EQCQDBregaddr = | 7447 | phba->sli4_hba.CQDBregaddr = |
| 7430 | phba->sli4_hba.conf_regs_memmap_p + LPFC_EQCQ_DOORBELL; | 7448 | phba->sli4_hba.conf_regs_memmap_p + LPFC_EQCQ_DOORBELL; |
| 7449 | phba->sli4_hba.EQDBregaddr = phba->sli4_hba.CQDBregaddr; | ||
| 7431 | phba->sli4_hba.MQDBregaddr = | 7450 | phba->sli4_hba.MQDBregaddr = |
| 7432 | phba->sli4_hba.conf_regs_memmap_p + LPFC_MQ_DOORBELL; | 7451 | phba->sli4_hba.conf_regs_memmap_p + LPFC_MQ_DOORBELL; |
| 7433 | phba->sli4_hba.BMBXregaddr = | 7452 | phba->sli4_hba.BMBXregaddr = |
| 7434 | phba->sli4_hba.conf_regs_memmap_p + LPFC_BMBX; | 7453 | phba->sli4_hba.conf_regs_memmap_p + LPFC_BMBX; |
| 7435 | break; | 7454 | break; |
| 7455 | case LPFC_SLI_INTF_IF_TYPE_6: | ||
| 7456 | phba->sli4_hba.u.if_type2.EQDregaddr = | ||
| 7457 | phba->sli4_hba.conf_regs_memmap_p + | ||
| 7458 | LPFC_CTL_PORT_EQ_DELAY_OFFSET; | ||
| 7459 | phba->sli4_hba.u.if_type2.ERR1regaddr = | ||
| 7460 | phba->sli4_hba.conf_regs_memmap_p + | ||
| 7461 | LPFC_CTL_PORT_ER1_OFFSET; | ||
| 7462 | phba->sli4_hba.u.if_type2.ERR2regaddr = | ||
| 7463 | phba->sli4_hba.conf_regs_memmap_p + | ||
| 7464 | LPFC_CTL_PORT_ER2_OFFSET; | ||
| 7465 | phba->sli4_hba.u.if_type2.CTRLregaddr = | ||
| 7466 | phba->sli4_hba.conf_regs_memmap_p + | ||
| 7467 | LPFC_CTL_PORT_CTL_OFFSET; | ||
| 7468 | phba->sli4_hba.u.if_type2.STATUSregaddr = | ||
| 7469 | phba->sli4_hba.conf_regs_memmap_p + | ||
| 7470 | LPFC_CTL_PORT_STA_OFFSET; | ||
| 7471 | phba->sli4_hba.PSMPHRregaddr = | ||
| 7472 | phba->sli4_hba.conf_regs_memmap_p + | ||
| 7473 | LPFC_CTL_PORT_SEM_OFFSET; | ||
| 7474 | phba->sli4_hba.BMBXregaddr = | ||
| 7475 | phba->sli4_hba.conf_regs_memmap_p + LPFC_BMBX; | ||
| 7476 | break; | ||
| 7436 | case LPFC_SLI_INTF_IF_TYPE_1: | 7477 | case LPFC_SLI_INTF_IF_TYPE_1: |
| 7437 | default: | 7478 | default: |
| 7438 | dev_printk(KERN_ERR, &phba->pcidev->dev, | 7479 | dev_printk(KERN_ERR, &phba->pcidev->dev, |
| @@ -7446,20 +7487,43 @@ lpfc_sli4_bar0_register_memmap(struct lpfc_hba *phba, uint32_t if_type) | |||
| 7446 | * lpfc_sli4_bar1_register_memmap - Set up SLI4 BAR1 register memory map. | 7487 | * lpfc_sli4_bar1_register_memmap - Set up SLI4 BAR1 register memory map. |
| 7447 | * @phba: pointer to lpfc hba data structure. | 7488 | * @phba: pointer to lpfc hba data structure. |
| 7448 | * | 7489 | * |
| 7449 | * This routine is invoked to set up SLI4 BAR1 control status register (CSR) | 7490 | * This routine is invoked to set up SLI4 BAR1 register memory map. |
| 7450 | * memory map. | ||
| 7451 | **/ | 7491 | **/ |
| 7452 | static void | 7492 | static void |
| 7453 | lpfc_sli4_bar1_register_memmap(struct lpfc_hba *phba) | 7493 | lpfc_sli4_bar1_register_memmap(struct lpfc_hba *phba, uint32_t if_type) |
| 7454 | { | 7494 | { |
| 7455 | phba->sli4_hba.PSMPHRregaddr = phba->sli4_hba.ctrl_regs_memmap_p + | 7495 | switch (if_type) { |
| 7456 | LPFC_SLIPORT_IF0_SMPHR; | 7496 | case LPFC_SLI_INTF_IF_TYPE_0: |
| 7457 | phba->sli4_hba.ISRregaddr = phba->sli4_hba.ctrl_regs_memmap_p + | 7497 | phba->sli4_hba.PSMPHRregaddr = |
| 7458 | LPFC_HST_ISR0; | 7498 | phba->sli4_hba.ctrl_regs_memmap_p + |
| 7459 | phba->sli4_hba.IMRregaddr = phba->sli4_hba.ctrl_regs_memmap_p + | 7499 | LPFC_SLIPORT_IF0_SMPHR; |
| 7460 | LPFC_HST_IMR0; | 7500 | phba->sli4_hba.ISRregaddr = phba->sli4_hba.ctrl_regs_memmap_p + |
| 7461 | phba->sli4_hba.ISCRregaddr = phba->sli4_hba.ctrl_regs_memmap_p + | 7501 | LPFC_HST_ISR0; |
| 7462 | LPFC_HST_ISCR0; | 7502 | phba->sli4_hba.IMRregaddr = phba->sli4_hba.ctrl_regs_memmap_p + |
| 7503 | LPFC_HST_IMR0; | ||
| 7504 | phba->sli4_hba.ISCRregaddr = phba->sli4_hba.ctrl_regs_memmap_p + | ||
| 7505 | LPFC_HST_ISCR0; | ||
| 7506 | break; | ||
| 7507 | case LPFC_SLI_INTF_IF_TYPE_6: | ||
| 7508 | phba->sli4_hba.RQDBregaddr = phba->sli4_hba.drbl_regs_memmap_p + | ||
| 7509 | LPFC_IF6_RQ_DOORBELL; | ||
| 7510 | phba->sli4_hba.WQDBregaddr = phba->sli4_hba.drbl_regs_memmap_p + | ||
| 7511 | LPFC_IF6_WQ_DOORBELL; | ||
| 7512 | phba->sli4_hba.CQDBregaddr = phba->sli4_hba.drbl_regs_memmap_p + | ||
| 7513 | LPFC_IF6_CQ_DOORBELL; | ||
| 7514 | phba->sli4_hba.EQDBregaddr = phba->sli4_hba.drbl_regs_memmap_p + | ||
| 7515 | LPFC_IF6_EQ_DOORBELL; | ||
| 7516 | phba->sli4_hba.MQDBregaddr = phba->sli4_hba.drbl_regs_memmap_p + | ||
| 7517 | LPFC_IF6_MQ_DOORBELL; | ||
| 7518 | break; | ||
| 7519 | case LPFC_SLI_INTF_IF_TYPE_2: | ||
| 7520 | case LPFC_SLI_INTF_IF_TYPE_1: | ||
| 7521 | default: | ||
| 7522 | dev_err(&phba->pcidev->dev, | ||
| 7523 | "FATAL - unsupported SLI4 interface type - %d\n", | ||
| 7524 | if_type); | ||
| 7525 | break; | ||
| 7526 | } | ||
| 7463 | } | 7527 | } |
| 7464 | 7528 | ||
| 7465 | /** | 7529 | /** |
| @@ -7484,8 +7548,10 @@ lpfc_sli4_bar2_register_memmap(struct lpfc_hba *phba, uint32_t vf) | |||
| 7484 | phba->sli4_hba.WQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p + | 7548 | phba->sli4_hba.WQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p + |
| 7485 | vf * LPFC_VFR_PAGE_SIZE + | 7549 | vf * LPFC_VFR_PAGE_SIZE + |
| 7486 | LPFC_ULP0_WQ_DOORBELL); | 7550 | LPFC_ULP0_WQ_DOORBELL); |
| 7487 | phba->sli4_hba.EQCQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p + | 7551 | phba->sli4_hba.CQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p + |
| 7488 | vf * LPFC_VFR_PAGE_SIZE + LPFC_EQCQ_DOORBELL); | 7552 | vf * LPFC_VFR_PAGE_SIZE + |
| 7553 | LPFC_EQCQ_DOORBELL); | ||
| 7554 | phba->sli4_hba.EQDBregaddr = phba->sli4_hba.CQDBregaddr; | ||
| 7489 | phba->sli4_hba.MQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p + | 7555 | phba->sli4_hba.MQDBregaddr = (phba->sli4_hba.drbl_regs_memmap_p + |
| 7490 | vf * LPFC_VFR_PAGE_SIZE + LPFC_MQ_DOORBELL); | 7556 | vf * LPFC_VFR_PAGE_SIZE + LPFC_MQ_DOORBELL); |
| 7491 | phba->sli4_hba.BMBXregaddr = (phba->sli4_hba.drbl_regs_memmap_p + | 7557 | phba->sli4_hba.BMBXregaddr = (phba->sli4_hba.drbl_regs_memmap_p + |
| @@ -7722,7 +7788,7 @@ lpfc_sli4_read_config(struct lpfc_hba *phba) | |||
| 7722 | 7788 | ||
| 7723 | /* Update link speed if forced link speed is supported */ | 7789 | /* Update link speed if forced link speed is supported */ |
| 7724 | if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf); | 7790 | if_type = bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf); |
| 7725 | if (if_type == LPFC_SLI_INTF_IF_TYPE_2) { | 7791 | if (if_type >= LPFC_SLI_INTF_IF_TYPE_2) { |
| 7726 | forced_link_speed = | 7792 | forced_link_speed = |
| 7727 | bf_get(lpfc_mbx_rd_conf_link_speed, rd_config); | 7793 | bf_get(lpfc_mbx_rd_conf_link_speed, rd_config); |
| 7728 | if (forced_link_speed) { | 7794 | if (forced_link_speed) { |
| @@ -7757,6 +7823,10 @@ lpfc_sli4_read_config(struct lpfc_hba *phba) | |||
| 7757 | phba->cfg_link_speed = | 7823 | phba->cfg_link_speed = |
| 7758 | LPFC_USER_LINK_SPEED_32G; | 7824 | LPFC_USER_LINK_SPEED_32G; |
| 7759 | break; | 7825 | break; |
| 7826 | case LINK_SPEED_64G: | ||
| 7827 | phba->cfg_link_speed = | ||
| 7828 | LPFC_USER_LINK_SPEED_64G; | ||
| 7829 | break; | ||
| 7760 | case 0xffff: | 7830 | case 0xffff: |
| 7761 | phba->cfg_link_speed = | 7831 | phba->cfg_link_speed = |
| 7762 | LPFC_USER_LINK_SPEED_AUTO; | 7832 | LPFC_USER_LINK_SPEED_AUTO; |
| @@ -7782,7 +7852,7 @@ lpfc_sli4_read_config(struct lpfc_hba *phba) | |||
| 7782 | phba->cfg_hba_queue_depth = length; | 7852 | phba->cfg_hba_queue_depth = length; |
| 7783 | } | 7853 | } |
| 7784 | 7854 | ||
| 7785 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != | 7855 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) < |
| 7786 | LPFC_SLI_INTF_IF_TYPE_2) | 7856 | LPFC_SLI_INTF_IF_TYPE_2) |
| 7787 | goto read_cfg_out; | 7857 | goto read_cfg_out; |
| 7788 | 7858 | ||
| @@ -7896,6 +7966,7 @@ lpfc_setup_endian_order(struct lpfc_hba *phba) | |||
| 7896 | } | 7966 | } |
| 7897 | mempool_free(mboxq, phba->mbox_mem_pool); | 7967 | mempool_free(mboxq, phba->mbox_mem_pool); |
| 7898 | break; | 7968 | break; |
| 7969 | case LPFC_SLI_INTF_IF_TYPE_6: | ||
| 7899 | case LPFC_SLI_INTF_IF_TYPE_2: | 7970 | case LPFC_SLI_INTF_IF_TYPE_2: |
| 7900 | case LPFC_SLI_INTF_IF_TYPE_1: | 7971 | case LPFC_SLI_INTF_IF_TYPE_1: |
| 7901 | default: | 7972 | default: |
| @@ -7992,6 +8063,7 @@ lpfc_alloc_nvme_wq_cq(struct lpfc_hba *phba, int wqidx) | |||
| 7992 | wqidx); | 8063 | wqidx); |
| 7993 | return 1; | 8064 | return 1; |
| 7994 | } | 8065 | } |
| 8066 | qdesc->qe_valid = 1; | ||
| 7995 | phba->sli4_hba.nvme_cq[wqidx] = qdesc; | 8067 | phba->sli4_hba.nvme_cq[wqidx] = qdesc; |
| 7996 | 8068 | ||
| 7997 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE, | 8069 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE, |
| @@ -8011,9 +8083,10 @@ static int | |||
| 8011 | lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx) | 8083 | lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx) |
| 8012 | { | 8084 | { |
| 8013 | struct lpfc_queue *qdesc; | 8085 | struct lpfc_queue *qdesc; |
| 8086 | uint32_t wqesize; | ||
| 8014 | 8087 | ||
| 8015 | /* Create Fast Path FCP CQs */ | 8088 | /* Create Fast Path FCP CQs */ |
| 8016 | if (phba->fcp_embed_io) | 8089 | if (phba->enab_exp_wqcq_pages) |
| 8017 | /* Increase the CQ size when WQEs contain an embedded cdb */ | 8090 | /* Increase the CQ size when WQEs contain an embedded cdb */ |
| 8018 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE, | 8091 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE, |
| 8019 | phba->sli4_hba.cq_esize, | 8092 | phba->sli4_hba.cq_esize, |
| @@ -8028,18 +8101,22 @@ lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx) | |||
| 8028 | "0499 Failed allocate fast-path FCP CQ (%d)\n", wqidx); | 8101 | "0499 Failed allocate fast-path FCP CQ (%d)\n", wqidx); |
| 8029 | return 1; | 8102 | return 1; |
| 8030 | } | 8103 | } |
| 8104 | qdesc->qe_valid = 1; | ||
| 8031 | phba->sli4_hba.fcp_cq[wqidx] = qdesc; | 8105 | phba->sli4_hba.fcp_cq[wqidx] = qdesc; |
| 8032 | 8106 | ||
| 8033 | /* Create Fast Path FCP WQs */ | 8107 | /* Create Fast Path FCP WQs */ |
| 8034 | if (phba->fcp_embed_io) | 8108 | if (phba->enab_exp_wqcq_pages) { |
| 8035 | /* Increase the WQ size when WQEs contain an embedded cdb */ | 8109 | /* Increase the WQ size when WQEs contain an embedded cdb */ |
| 8110 | wqesize = (phba->fcp_embed_io) ? | ||
| 8111 | LPFC_WQE128_SIZE : phba->sli4_hba.wq_esize; | ||
| 8036 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE, | 8112 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_EXPANDED_PAGE_SIZE, |
| 8037 | LPFC_WQE128_SIZE, | 8113 | wqesize, |
| 8038 | LPFC_WQE_EXP_COUNT); | 8114 | LPFC_WQE_EXP_COUNT); |
| 8039 | else | 8115 | } else |
| 8040 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, | 8116 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, |
| 8041 | phba->sli4_hba.wq_esize, | 8117 | phba->sli4_hba.wq_esize, |
| 8042 | phba->sli4_hba.wq_ecount); | 8118 | phba->sli4_hba.wq_ecount); |
| 8119 | |||
| 8043 | if (!qdesc) { | 8120 | if (!qdesc) { |
| 8044 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 8121 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
| 8045 | "0503 Failed allocate fast-path FCP WQ (%d)\n", | 8122 | "0503 Failed allocate fast-path FCP WQ (%d)\n", |
| @@ -8218,6 +8295,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) | |||
| 8218 | "0497 Failed allocate EQ (%d)\n", idx); | 8295 | "0497 Failed allocate EQ (%d)\n", idx); |
| 8219 | goto out_error; | 8296 | goto out_error; |
| 8220 | } | 8297 | } |
| 8298 | qdesc->qe_valid = 1; | ||
| 8221 | phba->sli4_hba.hba_eq[idx] = qdesc; | 8299 | phba->sli4_hba.hba_eq[idx] = qdesc; |
| 8222 | } | 8300 | } |
| 8223 | 8301 | ||
| @@ -8243,6 +8321,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) | |||
| 8243 | "CQ Set (%d)\n", idx); | 8321 | "CQ Set (%d)\n", idx); |
| 8244 | goto out_error; | 8322 | goto out_error; |
| 8245 | } | 8323 | } |
| 8324 | qdesc->qe_valid = 1; | ||
| 8246 | phba->sli4_hba.nvmet_cqset[idx] = qdesc; | 8325 | phba->sli4_hba.nvmet_cqset[idx] = qdesc; |
| 8247 | } | 8326 | } |
| 8248 | } | 8327 | } |
| @@ -8260,6 +8339,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) | |||
| 8260 | "0500 Failed allocate slow-path mailbox CQ\n"); | 8339 | "0500 Failed allocate slow-path mailbox CQ\n"); |
| 8261 | goto out_error; | 8340 | goto out_error; |
| 8262 | } | 8341 | } |
| 8342 | qdesc->qe_valid = 1; | ||
| 8263 | phba->sli4_hba.mbx_cq = qdesc; | 8343 | phba->sli4_hba.mbx_cq = qdesc; |
| 8264 | 8344 | ||
| 8265 | /* Create slow-path ELS Complete Queue */ | 8345 | /* Create slow-path ELS Complete Queue */ |
| @@ -8271,6 +8351,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) | |||
| 8271 | "0501 Failed allocate slow-path ELS CQ\n"); | 8351 | "0501 Failed allocate slow-path ELS CQ\n"); |
| 8272 | goto out_error; | 8352 | goto out_error; |
| 8273 | } | 8353 | } |
| 8354 | qdesc->qe_valid = 1; | ||
| 8274 | phba->sli4_hba.els_cq = qdesc; | 8355 | phba->sli4_hba.els_cq = qdesc; |
| 8275 | 8356 | ||
| 8276 | 8357 | ||
| @@ -8316,6 +8397,7 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) | |||
| 8316 | "6079 Failed allocate NVME LS CQ\n"); | 8397 | "6079 Failed allocate NVME LS CQ\n"); |
| 8317 | goto out_error; | 8398 | goto out_error; |
| 8318 | } | 8399 | } |
| 8400 | qdesc->qe_valid = 1; | ||
| 8319 | phba->sli4_hba.nvmels_cq = qdesc; | 8401 | phba->sli4_hba.nvmels_cq = qdesc; |
| 8320 | 8402 | ||
| 8321 | /* Create NVME LS Work Queue */ | 8403 | /* Create NVME LS Work Queue */ |
| @@ -9303,6 +9385,7 @@ lpfc_pci_function_reset(struct lpfc_hba *phba) | |||
| 9303 | } | 9385 | } |
| 9304 | break; | 9386 | break; |
| 9305 | case LPFC_SLI_INTF_IF_TYPE_2: | 9387 | case LPFC_SLI_INTF_IF_TYPE_2: |
| 9388 | case LPFC_SLI_INTF_IF_TYPE_6: | ||
| 9306 | wait: | 9389 | wait: |
| 9307 | /* | 9390 | /* |
| 9308 | * Poll the Port Status Register and wait for RDY for | 9391 | * Poll the Port Status Register and wait for RDY for |
| @@ -9458,7 +9541,7 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba) | |||
| 9458 | } else { | 9541 | } else { |
| 9459 | phba->pci_bar0_map = pci_resource_start(pdev, 1); | 9542 | phba->pci_bar0_map = pci_resource_start(pdev, 1); |
| 9460 | bar0map_len = pci_resource_len(pdev, 1); | 9543 | bar0map_len = pci_resource_len(pdev, 1); |
| 9461 | if (if_type == LPFC_SLI_INTF_IF_TYPE_2) { | 9544 | if (if_type >= LPFC_SLI_INTF_IF_TYPE_2) { |
| 9462 | dev_printk(KERN_ERR, &pdev->dev, | 9545 | dev_printk(KERN_ERR, &pdev->dev, |
| 9463 | "FATAL - No BAR0 mapping for SLI4, if_type 2\n"); | 9546 | "FATAL - No BAR0 mapping for SLI4, if_type 2\n"); |
| 9464 | goto out; | 9547 | goto out; |
| @@ -9495,13 +9578,32 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba) | |||
| 9495 | } | 9578 | } |
| 9496 | phba->pci_bar2_memmap_p = | 9579 | phba->pci_bar2_memmap_p = |
| 9497 | phba->sli4_hba.ctrl_regs_memmap_p; | 9580 | phba->sli4_hba.ctrl_regs_memmap_p; |
| 9498 | lpfc_sli4_bar1_register_memmap(phba); | 9581 | lpfc_sli4_bar1_register_memmap(phba, if_type); |
| 9499 | } else { | 9582 | } else { |
| 9500 | error = -ENOMEM; | 9583 | error = -ENOMEM; |
| 9501 | goto out_iounmap_conf; | 9584 | goto out_iounmap_conf; |
| 9502 | } | 9585 | } |
| 9503 | } | 9586 | } |
| 9504 | 9587 | ||
| 9588 | if ((if_type == LPFC_SLI_INTF_IF_TYPE_6) && | ||
| 9589 | (pci_resource_start(pdev, PCI_64BIT_BAR2))) { | ||
| 9590 | /* | ||
| 9591 | * Map SLI4 if type 6 HBA Doorbell Register base to a kernel | ||
| 9592 | * virtual address and setup the registers. | ||
| 9593 | */ | ||
| 9594 | phba->pci_bar1_map = pci_resource_start(pdev, PCI_64BIT_BAR2); | ||
| 9595 | bar1map_len = pci_resource_len(pdev, PCI_64BIT_BAR2); | ||
| 9596 | phba->sli4_hba.drbl_regs_memmap_p = | ||
| 9597 | ioremap(phba->pci_bar1_map, bar1map_len); | ||
| 9598 | if (!phba->sli4_hba.drbl_regs_memmap_p) { | ||
| 9599 | dev_err(&pdev->dev, | ||
| 9600 | "ioremap failed for SLI4 HBA doorbell registers.\n"); | ||
| 9601 | goto out_iounmap_conf; | ||
| 9602 | } | ||
| 9603 | phba->pci_bar2_memmap_p = phba->sli4_hba.drbl_regs_memmap_p; | ||
| 9604 | lpfc_sli4_bar1_register_memmap(phba, if_type); | ||
| 9605 | } | ||
| 9606 | |||
| 9505 | if (if_type == LPFC_SLI_INTF_IF_TYPE_0) { | 9607 | if (if_type == LPFC_SLI_INTF_IF_TYPE_0) { |
| 9506 | if (pci_resource_start(pdev, PCI_64BIT_BAR4)) { | 9608 | if (pci_resource_start(pdev, PCI_64BIT_BAR4)) { |
| 9507 | /* | 9609 | /* |
| @@ -9532,6 +9634,41 @@ lpfc_sli4_pci_mem_setup(struct lpfc_hba *phba) | |||
| 9532 | } | 9634 | } |
| 9533 | } | 9635 | } |
| 9534 | 9636 | ||
| 9637 | if (if_type == LPFC_SLI_INTF_IF_TYPE_6 && | ||
| 9638 | pci_resource_start(pdev, PCI_64BIT_BAR4)) { | ||
| 9639 | /* | ||
| 9640 | * Map SLI4 if type 6 HBA DPP Register base to a kernel | ||
| 9641 | * virtual address and setup the registers. | ||
| 9642 | */ | ||
| 9643 | phba->pci_bar2_map = pci_resource_start(pdev, PCI_64BIT_BAR4); | ||
| 9644 | bar2map_len = pci_resource_len(pdev, PCI_64BIT_BAR4); | ||
| 9645 | phba->sli4_hba.dpp_regs_memmap_p = | ||
| 9646 | ioremap(phba->pci_bar2_map, bar2map_len); | ||
| 9647 | if (!phba->sli4_hba.dpp_regs_memmap_p) { | ||
| 9648 | dev_err(&pdev->dev, | ||
| 9649 | "ioremap failed for SLI4 HBA dpp registers.\n"); | ||
| 9650 | goto out_iounmap_ctrl; | ||
| 9651 | } | ||
| 9652 | phba->pci_bar4_memmap_p = phba->sli4_hba.dpp_regs_memmap_p; | ||
| 9653 | } | ||
| 9654 | |||
| 9655 | /* Set up the EQ/CQ register handeling functions now */ | ||
| 9656 | switch (if_type) { | ||
| 9657 | case LPFC_SLI_INTF_IF_TYPE_0: | ||
| 9658 | case LPFC_SLI_INTF_IF_TYPE_2: | ||
| 9659 | phba->sli4_hba.sli4_eq_clr_intr = lpfc_sli4_eq_clr_intr; | ||
| 9660 | phba->sli4_hba.sli4_eq_release = lpfc_sli4_eq_release; | ||
| 9661 | phba->sli4_hba.sli4_cq_release = lpfc_sli4_cq_release; | ||
| 9662 | break; | ||
| 9663 | case LPFC_SLI_INTF_IF_TYPE_6: | ||
| 9664 | phba->sli4_hba.sli4_eq_clr_intr = lpfc_sli4_if6_eq_clr_intr; | ||
| 9665 | phba->sli4_hba.sli4_eq_release = lpfc_sli4_if6_eq_release; | ||
| 9666 | phba->sli4_hba.sli4_cq_release = lpfc_sli4_if6_cq_release; | ||
| 9667 | break; | ||
| 9668 | default: | ||
| 9669 | break; | ||
| 9670 | } | ||
| 9671 | |||
| 9535 | return 0; | 9672 | return 0; |
| 9536 | 9673 | ||
| 9537 | out_iounmap_all: | 9674 | out_iounmap_all: |
| @@ -9566,6 +9703,10 @@ lpfc_sli4_pci_mem_unset(struct lpfc_hba *phba) | |||
| 9566 | case LPFC_SLI_INTF_IF_TYPE_2: | 9703 | case LPFC_SLI_INTF_IF_TYPE_2: |
| 9567 | iounmap(phba->sli4_hba.conf_regs_memmap_p); | 9704 | iounmap(phba->sli4_hba.conf_regs_memmap_p); |
| 9568 | break; | 9705 | break; |
| 9706 | case LPFC_SLI_INTF_IF_TYPE_6: | ||
| 9707 | iounmap(phba->sli4_hba.drbl_regs_memmap_p); | ||
| 9708 | iounmap(phba->sli4_hba.conf_regs_memmap_p); | ||
| 9709 | break; | ||
| 9569 | case LPFC_SLI_INTF_IF_TYPE_1: | 9710 | case LPFC_SLI_INTF_IF_TYPE_1: |
| 9570 | default: | 9711 | default: |
| 9571 | dev_printk(KERN_ERR, &phba->pcidev->dev, | 9712 | dev_printk(KERN_ERR, &phba->pcidev->dev, |
| @@ -10435,6 +10576,8 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
| 10435 | sli4_params->mqv = bf_get(cfg_mqv, mbx_sli4_parameters); | 10576 | sli4_params->mqv = bf_get(cfg_mqv, mbx_sli4_parameters); |
| 10436 | sli4_params->wqv = bf_get(cfg_wqv, mbx_sli4_parameters); | 10577 | sli4_params->wqv = bf_get(cfg_wqv, mbx_sli4_parameters); |
| 10437 | sli4_params->rqv = bf_get(cfg_rqv, mbx_sli4_parameters); | 10578 | sli4_params->rqv = bf_get(cfg_rqv, mbx_sli4_parameters); |
| 10579 | sli4_params->eqav = bf_get(cfg_eqav, mbx_sli4_parameters); | ||
| 10580 | sli4_params->cqav = bf_get(cfg_cqav, mbx_sli4_parameters); | ||
| 10438 | sli4_params->wqsize = bf_get(cfg_wqsize, mbx_sli4_parameters); | 10581 | sli4_params->wqsize = bf_get(cfg_wqsize, mbx_sli4_parameters); |
| 10439 | sli4_params->sgl_pages_max = bf_get(cfg_sgl_page_cnt, | 10582 | sli4_params->sgl_pages_max = bf_get(cfg_sgl_page_cnt, |
| 10440 | mbx_sli4_parameters); | 10583 | mbx_sli4_parameters); |
| @@ -10465,8 +10608,32 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
| 10465 | phba->cfg_enable_fc4_type = LPFC_ENABLE_FCP; | 10608 | phba->cfg_enable_fc4_type = LPFC_ENABLE_FCP; |
| 10466 | } | 10609 | } |
| 10467 | 10610 | ||
| 10468 | if (bf_get(cfg_xib, mbx_sli4_parameters) && phba->cfg_suppress_rsp) | 10611 | /* Only embed PBDE for if_type 6 */ |
| 10612 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) == | ||
| 10613 | LPFC_SLI_INTF_IF_TYPE_6) { | ||
| 10614 | phba->fcp_embed_pbde = 1; | ||
| 10615 | phba->nvme_embed_pbde = 1; | ||
| 10616 | } | ||
| 10617 | |||
| 10618 | /* PBDE support requires xib be set */ | ||
| 10619 | if (!bf_get(cfg_xib, mbx_sli4_parameters)) { | ||
| 10620 | phba->fcp_embed_pbde = 0; | ||
| 10621 | phba->nvme_embed_pbde = 0; | ||
| 10622 | } | ||
| 10623 | |||
| 10624 | /* | ||
| 10625 | * To support Suppress Response feature we must satisfy 3 conditions. | ||
| 10626 | * lpfc_suppress_rsp module parameter must be set (default). | ||
| 10627 | * In SLI4-Parameters Descriptor: | ||
| 10628 | * Extended Inline Buffers (XIB) must be supported. | ||
| 10629 | * Suppress Response IU Not Supported (SRIUNS) must NOT be supported | ||
| 10630 | * (double negative). | ||
| 10631 | */ | ||
| 10632 | if (phba->cfg_suppress_rsp && bf_get(cfg_xib, mbx_sli4_parameters) && | ||
| 10633 | !(bf_get(cfg_nosr, mbx_sli4_parameters))) | ||
| 10469 | phba->sli.sli_flag |= LPFC_SLI_SUPPRESS_RSP; | 10634 | phba->sli.sli_flag |= LPFC_SLI_SUPPRESS_RSP; |
| 10635 | else | ||
| 10636 | phba->cfg_suppress_rsp = 0; | ||
| 10470 | 10637 | ||
| 10471 | if (bf_get(cfg_eqdr, mbx_sli4_parameters)) | 10638 | if (bf_get(cfg_eqdr, mbx_sli4_parameters)) |
| 10472 | phba->sli.sli_flag |= LPFC_SLI_USE_EQDR; | 10639 | phba->sli.sli_flag |= LPFC_SLI_USE_EQDR; |
| @@ -10476,15 +10643,28 @@ lpfc_get_sli4_parameters(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) | |||
| 10476 | sli4_params->sge_supp_len = LPFC_MAX_SGE_SIZE; | 10643 | sli4_params->sge_supp_len = LPFC_MAX_SGE_SIZE; |
| 10477 | 10644 | ||
| 10478 | /* | 10645 | /* |
| 10479 | * Issue IOs with CDB embedded in WQE to minimized the number | 10646 | * Check whether the adapter supports an embedded copy of the |
| 10480 | * of DMAs the firmware has to do. Setting this to 1 also forces | 10647 | * FCP CMD IU within the WQE for FCP_Ixxx commands. In order |
| 10481 | * the driver to use 128 bytes WQEs for FCP IOs. | 10648 | * to use this option, 128-byte WQEs must be used. |
| 10482 | */ | 10649 | */ |
| 10483 | if (bf_get(cfg_ext_embed_cb, mbx_sli4_parameters)) | 10650 | if (bf_get(cfg_ext_embed_cb, mbx_sli4_parameters)) |
| 10484 | phba->fcp_embed_io = 1; | 10651 | phba->fcp_embed_io = 1; |
| 10485 | else | 10652 | else |
| 10486 | phba->fcp_embed_io = 0; | 10653 | phba->fcp_embed_io = 0; |
| 10487 | 10654 | ||
| 10655 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT | LOG_NVME, | ||
| 10656 | "6422 XIB %d: FCP %d %d NVME %d %d %d %d\n", | ||
| 10657 | bf_get(cfg_xib, mbx_sli4_parameters), | ||
| 10658 | phba->fcp_embed_pbde, phba->fcp_embed_io, | ||
| 10659 | phba->nvme_support, phba->nvme_embed_pbde, | ||
| 10660 | phba->cfg_nvme_embed_cmd, phba->cfg_suppress_rsp); | ||
| 10661 | |||
| 10662 | if ((bf_get(cfg_cqpsize, mbx_sli4_parameters) & LPFC_CQ_16K_PAGE_SZ) && | ||
| 10663 | (bf_get(cfg_wqpsize, mbx_sli4_parameters) & LPFC_WQ_16K_PAGE_SZ) && | ||
| 10664 | (sli4_params->wqsize & LPFC_WQ_SZ128_SUPPORT)) | ||
| 10665 | phba->enab_exp_wqcq_pages = 1; | ||
| 10666 | else | ||
| 10667 | phba->enab_exp_wqcq_pages = 0; | ||
| 10488 | /* | 10668 | /* |
| 10489 | * Check if the SLI port supports MDS Diagnostics | 10669 | * Check if the SLI port supports MDS Diagnostics |
| 10490 | */ | 10670 | */ |
| @@ -11137,6 +11317,27 @@ lpfc_sli4_get_iocb_cnt(struct lpfc_hba *phba) | |||
| 11137 | } | 11317 | } |
| 11138 | 11318 | ||
| 11139 | 11319 | ||
| 11320 | static void | ||
| 11321 | lpfc_log_write_firmware_error(struct lpfc_hba *phba, uint32_t offset, | ||
| 11322 | uint32_t magic_number, uint32_t ftype, uint32_t fid, uint32_t fsize, | ||
| 11323 | const struct firmware *fw) | ||
| 11324 | { | ||
| 11325 | if (offset == ADD_STATUS_FW_NOT_SUPPORTED) | ||
| 11326 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
| 11327 | "3030 This firmware version is not supported on " | ||
| 11328 | "this HBA model. Device:%x Magic:%x Type:%x " | ||
| 11329 | "ID:%x Size %d %zd\n", | ||
| 11330 | phba->pcidev->device, magic_number, ftype, fid, | ||
| 11331 | fsize, fw->size); | ||
| 11332 | else | ||
| 11333 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
| 11334 | "3022 FW Download failed. Device:%x Magic:%x Type:%x " | ||
| 11335 | "ID:%x Size %d %zd\n", | ||
| 11336 | phba->pcidev->device, magic_number, ftype, fid, | ||
| 11337 | fsize, fw->size); | ||
| 11338 | } | ||
| 11339 | |||
| 11340 | |||
| 11140 | /** | 11341 | /** |
| 11141 | * lpfc_write_firmware - attempt to write a firmware image to the port | 11342 | * lpfc_write_firmware - attempt to write a firmware image to the port |
| 11142 | * @fw: pointer to firmware image returned from request_firmware. | 11343 | * @fw: pointer to firmware image returned from request_firmware. |
| @@ -11164,20 +11365,10 @@ lpfc_write_firmware(const struct firmware *fw, void *context) | |||
| 11164 | 11365 | ||
| 11165 | magic_number = be32_to_cpu(image->magic_number); | 11366 | magic_number = be32_to_cpu(image->magic_number); |
| 11166 | ftype = bf_get_be32(lpfc_grp_hdr_file_type, image); | 11367 | ftype = bf_get_be32(lpfc_grp_hdr_file_type, image); |
| 11167 | fid = bf_get_be32(lpfc_grp_hdr_id, image), | 11368 | fid = bf_get_be32(lpfc_grp_hdr_id, image); |
| 11168 | fsize = be32_to_cpu(image->size); | 11369 | fsize = be32_to_cpu(image->size); |
| 11169 | 11370 | ||
| 11170 | INIT_LIST_HEAD(&dma_buffer_list); | 11371 | INIT_LIST_HEAD(&dma_buffer_list); |
| 11171 | if ((magic_number != LPFC_GROUP_OJECT_MAGIC_G5 && | ||
| 11172 | magic_number != LPFC_GROUP_OJECT_MAGIC_G6) || | ||
| 11173 | ftype != LPFC_FILE_TYPE_GROUP || fsize != fw->size) { | ||
| 11174 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
| 11175 | "3022 Invalid FW image found. " | ||
| 11176 | "Magic:%x Type:%x ID:%x Size %d %zd\n", | ||
| 11177 | magic_number, ftype, fid, fsize, fw->size); | ||
| 11178 | rc = -EINVAL; | ||
| 11179 | goto release_out; | ||
| 11180 | } | ||
| 11181 | lpfc_decode_firmware_rev(phba, fwrev, 1); | 11372 | lpfc_decode_firmware_rev(phba, fwrev, 1); |
| 11182 | if (strncmp(fwrev, image->revision, strnlen(image->revision, 16))) { | 11373 | if (strncmp(fwrev, image->revision, strnlen(image->revision, 16))) { |
| 11183 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 11374 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
| @@ -11218,11 +11409,18 @@ lpfc_write_firmware(const struct firmware *fw, void *context) | |||
| 11218 | } | 11409 | } |
| 11219 | rc = lpfc_wr_object(phba, &dma_buffer_list, | 11410 | rc = lpfc_wr_object(phba, &dma_buffer_list, |
| 11220 | (fw->size - offset), &offset); | 11411 | (fw->size - offset), &offset); |
| 11221 | if (rc) | 11412 | if (rc) { |
| 11413 | lpfc_log_write_firmware_error(phba, offset, | ||
| 11414 | magic_number, ftype, fid, fsize, fw); | ||
| 11222 | goto release_out; | 11415 | goto release_out; |
| 11416 | } | ||
| 11223 | } | 11417 | } |
| 11224 | rc = offset; | 11418 | rc = offset; |
| 11225 | } | 11419 | } else |
| 11420 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
| 11421 | "3029 Skipped Firmware update, Current " | ||
| 11422 | "Version:%s New Version:%s\n", | ||
| 11423 | fwrev, image->revision); | ||
| 11226 | 11424 | ||
| 11227 | release_out: | 11425 | release_out: |
| 11228 | list_for_each_entry_safe(dmabuf, next, &dma_buffer_list, list) { | 11426 | list_for_each_entry_safe(dmabuf, next, &dma_buffer_list, list) { |
| @@ -11253,7 +11451,7 @@ lpfc_sli4_request_firmware_update(struct lpfc_hba *phba, uint8_t fw_upgrade) | |||
| 11253 | const struct firmware *fw; | 11451 | const struct firmware *fw; |
| 11254 | 11452 | ||
| 11255 | /* Only supported on SLI4 interface type 2 for now */ | 11453 | /* Only supported on SLI4 interface type 2 for now */ |
| 11256 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) != | 11454 | if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) < |
| 11257 | LPFC_SLI_INTF_IF_TYPE_2) | 11455 | LPFC_SLI_INTF_IF_TYPE_2) |
| 11258 | return -EPERM; | 11456 | return -EPERM; |
| 11259 | 11457 | ||
| @@ -11493,13 +11691,6 @@ lpfc_pci_remove_one_s4(struct pci_dev *pdev) | |||
| 11493 | /* Remove FC host and then SCSI host with the physical port */ | 11691 | /* Remove FC host and then SCSI host with the physical port */ |
| 11494 | fc_remove_host(shost); | 11692 | fc_remove_host(shost); |
| 11495 | scsi_remove_host(shost); | 11693 | scsi_remove_host(shost); |
| 11496 | /* | ||
| 11497 | * Bring down the SLI Layer. This step disables all interrupts, | ||
| 11498 | * clears the rings, discards all mailbox commands, and resets | ||
| 11499 | * the HBA FCoE function. | ||
| 11500 | */ | ||
| 11501 | lpfc_debugfs_terminate(vport); | ||
| 11502 | lpfc_sli4_hba_unset(phba); | ||
| 11503 | 11694 | ||
| 11504 | /* Perform ndlp cleanup on the physical port. The nvme and nvmet | 11695 | /* Perform ndlp cleanup on the physical port. The nvme and nvmet |
| 11505 | * localports are destroyed after to cleanup all transport memory. | 11696 | * localports are destroyed after to cleanup all transport memory. |
| @@ -11508,6 +11699,13 @@ lpfc_pci_remove_one_s4(struct pci_dev *pdev) | |||
| 11508 | lpfc_nvmet_destroy_targetport(phba); | 11699 | lpfc_nvmet_destroy_targetport(phba); |
| 11509 | lpfc_nvme_destroy_localport(vport); | 11700 | lpfc_nvme_destroy_localport(vport); |
| 11510 | 11701 | ||
| 11702 | /* | ||
| 11703 | * Bring down the SLI Layer. This step disables all interrupts, | ||
| 11704 | * clears the rings, discards all mailbox commands, and resets | ||
| 11705 | * the HBA FCoE function. | ||
| 11706 | */ | ||
| 11707 | lpfc_debugfs_terminate(vport); | ||
| 11708 | lpfc_sli4_hba_unset(phba); | ||
| 11511 | 11709 | ||
| 11512 | lpfc_stop_hba_timers(phba); | 11710 | lpfc_stop_hba_timers(phba); |
| 11513 | spin_lock_irq(&phba->hbalock); | 11711 | spin_lock_irq(&phba->hbalock); |
| @@ -12227,6 +12425,7 @@ int | |||
| 12227 | lpfc_fof_queue_create(struct lpfc_hba *phba) | 12425 | lpfc_fof_queue_create(struct lpfc_hba *phba) |
| 12228 | { | 12426 | { |
| 12229 | struct lpfc_queue *qdesc; | 12427 | struct lpfc_queue *qdesc; |
| 12428 | uint32_t wqesize; | ||
| 12230 | 12429 | ||
| 12231 | /* Create FOF EQ */ | 12430 | /* Create FOF EQ */ |
| 12232 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, | 12431 | qdesc = lpfc_sli4_queue_alloc(phba, LPFC_DEFAULT_PAGE_SIZE, |
| @@ -12235,12 +12434,13 @@ lpfc_fof_queue_create(struct lpfc_hba *phba) | |||
| 12235 | if (!qdesc) | 12434 | if (!qdesc) |
| 12236 | goto out_error; | 12435 | goto out_error; |
| 12237 | 12436 | ||
| 12437 | qdesc->qe_valid = 1; | ||
| 12238 | phba->sli4_hba.fof_eq = qdesc; | 12438 | phba->sli4_hba.fof_eq = qdesc; |
| 12239 | 12439 | ||
| 12240 | if (phba->cfg_fof) { | 12440 | if (phba->cfg_fof) { |
| 12241 | 12441 | ||
| 12242 | /* Create OAS CQ */ | 12442 | /* Create OAS CQ */ |
| 12243 | if (phba->fcp_embed_io) | 12443 | if (phba->enab_exp_wqcq_pages) |
| 12244 | qdesc = lpfc_sli4_queue_alloc(phba, | 12444 | qdesc = lpfc_sli4_queue_alloc(phba, |
| 12245 | LPFC_EXPANDED_PAGE_SIZE, | 12445 | LPFC_EXPANDED_PAGE_SIZE, |
| 12246 | phba->sli4_hba.cq_esize, | 12446 | phba->sli4_hba.cq_esize, |
| @@ -12253,19 +12453,23 @@ lpfc_fof_queue_create(struct lpfc_hba *phba) | |||
| 12253 | if (!qdesc) | 12453 | if (!qdesc) |
| 12254 | goto out_error; | 12454 | goto out_error; |
| 12255 | 12455 | ||
| 12456 | qdesc->qe_valid = 1; | ||
| 12256 | phba->sli4_hba.oas_cq = qdesc; | 12457 | phba->sli4_hba.oas_cq = qdesc; |
| 12257 | 12458 | ||
| 12258 | /* Create OAS WQ */ | 12459 | /* Create OAS WQ */ |
| 12259 | if (phba->fcp_embed_io) | 12460 | if (phba->enab_exp_wqcq_pages) { |
| 12461 | wqesize = (phba->fcp_embed_io) ? | ||
| 12462 | LPFC_WQE128_SIZE : phba->sli4_hba.wq_esize; | ||
| 12260 | qdesc = lpfc_sli4_queue_alloc(phba, | 12463 | qdesc = lpfc_sli4_queue_alloc(phba, |
| 12261 | LPFC_EXPANDED_PAGE_SIZE, | 12464 | LPFC_EXPANDED_PAGE_SIZE, |
| 12262 | LPFC_WQE128_SIZE, | 12465 | wqesize, |
| 12263 | LPFC_WQE_EXP_COUNT); | 12466 | LPFC_WQE_EXP_COUNT); |
| 12264 | else | 12467 | } else |
| 12265 | qdesc = lpfc_sli4_queue_alloc(phba, | 12468 | qdesc = lpfc_sli4_queue_alloc(phba, |
| 12266 | LPFC_DEFAULT_PAGE_SIZE, | 12469 | LPFC_DEFAULT_PAGE_SIZE, |
| 12267 | phba->sli4_hba.wq_esize, | 12470 | phba->sli4_hba.wq_esize, |
| 12268 | phba->sli4_hba.wq_ecount); | 12471 | phba->sli4_hba.wq_ecount); |
| 12472 | |||
| 12269 | if (!qdesc) | 12473 | if (!qdesc) |
| 12270 | goto out_error; | 12474 | goto out_error; |
| 12271 | 12475 | ||
| @@ -12379,6 +12583,8 @@ lpfc_init(void) | |||
| 12379 | fc_release_transport(lpfc_transport_template); | 12583 | fc_release_transport(lpfc_transport_template); |
| 12380 | return -ENOMEM; | 12584 | return -ENOMEM; |
| 12381 | } | 12585 | } |
| 12586 | lpfc_nvme_cmd_template(); | ||
| 12587 | lpfc_nvmet_cmd_template(); | ||
| 12382 | 12588 | ||
| 12383 | /* Initialize in case vector mapping is needed */ | 12589 | /* Initialize in case vector mapping is needed */ |
| 12384 | lpfc_used_cpu = NULL; | 12590 | lpfc_used_cpu = NULL; |
diff --git a/drivers/scsi/lpfc/lpfc_mbox.c b/drivers/scsi/lpfc/lpfc_mbox.c index 81fb92967b11..47c02da11f01 100644 --- a/drivers/scsi/lpfc/lpfc_mbox.c +++ b/drivers/scsi/lpfc/lpfc_mbox.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * | 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -557,6 +557,10 @@ lpfc_init_link(struct lpfc_hba * phba, | |||
| 557 | mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED; | 557 | mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED; |
| 558 | mb->un.varInitLnk.link_speed = LINK_SPEED_32G; | 558 | mb->un.varInitLnk.link_speed = LINK_SPEED_32G; |
| 559 | break; | 559 | break; |
| 560 | case LPFC_USER_LINK_SPEED_64G: | ||
| 561 | mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED; | ||
| 562 | mb->un.varInitLnk.link_speed = LINK_SPEED_64G; | ||
| 563 | break; | ||
| 560 | case LPFC_USER_LINK_SPEED_AUTO: | 564 | case LPFC_USER_LINK_SPEED_AUTO: |
| 561 | default: | 565 | default: |
| 562 | mb->un.varInitLnk.link_speed = LINK_SPEED_AUTO; | 566 | mb->un.varInitLnk.link_speed = LINK_SPEED_AUTO; |
| @@ -2170,10 +2174,8 @@ lpfc_reg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport, dma_addr_t phys) | |||
| 2170 | /* Only FC supports upd bit */ | 2174 | /* Only FC supports upd bit */ |
| 2171 | if ((phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC) && | 2175 | if ((phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC) && |
| 2172 | (vport->fc_flag & FC_VFI_REGISTERED) && | 2176 | (vport->fc_flag & FC_VFI_REGISTERED) && |
| 2173 | (!phba->fc_topology_changed)) { | 2177 | (!phba->fc_topology_changed)) |
| 2174 | bf_set(lpfc_reg_vfi_vp, reg_vfi, 0); | ||
| 2175 | bf_set(lpfc_reg_vfi_upd, reg_vfi, 1); | 2178 | bf_set(lpfc_reg_vfi_upd, reg_vfi, 1); |
| 2176 | } | ||
| 2177 | 2179 | ||
| 2178 | bf_set(lpfc_reg_vfi_bbcr, reg_vfi, 0); | 2180 | bf_set(lpfc_reg_vfi_bbcr, reg_vfi, 0); |
| 2179 | bf_set(lpfc_reg_vfi_bbscn, reg_vfi, 0); | 2181 | bf_set(lpfc_reg_vfi_bbscn, reg_vfi, 0); |
diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c index 87c08ff37ddd..41361662ff08 100644 --- a/drivers/scsi/lpfc/lpfc_mem.c +++ b/drivers/scsi/lpfc/lpfc_mem.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2004-2014 Emulex. All rights reserved. * | 6 | * Copyright (C) 2004-2014 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -753,12 +753,16 @@ lpfc_rq_buf_free(struct lpfc_hba *phba, struct lpfc_dmabuf *mp) | |||
| 753 | drqe.address_hi = putPaddrHigh(rqb_entry->dbuf.phys); | 753 | drqe.address_hi = putPaddrHigh(rqb_entry->dbuf.phys); |
| 754 | rc = lpfc_sli4_rq_put(rqb_entry->hrq, rqb_entry->drq, &hrqe, &drqe); | 754 | rc = lpfc_sli4_rq_put(rqb_entry->hrq, rqb_entry->drq, &hrqe, &drqe); |
| 755 | if (rc < 0) { | 755 | if (rc < 0) { |
| 756 | (rqbp->rqb_free_buffer)(phba, rqb_entry); | ||
| 756 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 757 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
| 757 | "6409 Cannot post to RQ %d: %x %x\n", | 758 | "6409 Cannot post to HRQ %d: %x %x %x " |
| 759 | "DRQ %x %x\n", | ||
| 758 | rqb_entry->hrq->queue_id, | 760 | rqb_entry->hrq->queue_id, |
| 759 | rqb_entry->hrq->host_index, | 761 | rqb_entry->hrq->host_index, |
| 760 | rqb_entry->hrq->hba_index); | 762 | rqb_entry->hrq->hba_index, |
| 761 | (rqbp->rqb_free_buffer)(phba, rqb_entry); | 763 | rqb_entry->hrq->entry_count, |
| 764 | rqb_entry->drq->host_index, | ||
| 765 | rqb_entry->drq->hba_index); | ||
| 762 | } else { | 766 | } else { |
| 763 | list_add_tail(&rqb_entry->hbuf.list, &rqbp->rqb_buffer_list); | 767 | list_add_tail(&rqb_entry->hbuf.list, &rqbp->rqb_buffer_list); |
| 764 | rqbp->buffer_count++; | 768 | rqbp->buffer_count++; |
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index d841aa42f607..022060636ae1 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * | 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -1998,8 +1998,14 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
| 1998 | ndlp->nlp_type |= NLP_NVME_TARGET; | 1998 | ndlp->nlp_type |= NLP_NVME_TARGET; |
| 1999 | if (bf_get_be32(prli_disc, nvpr)) | 1999 | if (bf_get_be32(prli_disc, nvpr)) |
| 2000 | ndlp->nlp_type |= NLP_NVME_DISCOVERY; | 2000 | ndlp->nlp_type |= NLP_NVME_DISCOVERY; |
| 2001 | |||
| 2002 | /* | ||
| 2003 | * If prli_fba is set, the Target supports FirstBurst. | ||
| 2004 | * If prli_fb_sz is 0, the FirstBurst size is unlimited, | ||
| 2005 | * otherwise it defines the actual size supported by | ||
| 2006 | * the NVME Target. | ||
| 2007 | */ | ||
| 2001 | if ((bf_get_be32(prli_fba, nvpr) == 1) && | 2008 | if ((bf_get_be32(prli_fba, nvpr) == 1) && |
| 2002 | (bf_get_be32(prli_fb_sz, nvpr) > 0) && | ||
| 2003 | (phba->cfg_nvme_enable_fb) && | 2009 | (phba->cfg_nvme_enable_fb) && |
| 2004 | (!phba->nvmet_support)) { | 2010 | (!phba->nvmet_support)) { |
| 2005 | /* Both sides support FB. The target's first | 2011 | /* Both sides support FB. The target's first |
| @@ -2008,12 +2014,16 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
| 2008 | ndlp->nlp_flag |= NLP_FIRSTBURST; | 2014 | ndlp->nlp_flag |= NLP_FIRSTBURST; |
| 2009 | ndlp->nvme_fb_size = bf_get_be32(prli_fb_sz, | 2015 | ndlp->nvme_fb_size = bf_get_be32(prli_fb_sz, |
| 2010 | nvpr); | 2016 | nvpr); |
| 2017 | |||
| 2018 | /* Expressed in units of 512 bytes */ | ||
| 2019 | if (ndlp->nvme_fb_size) | ||
| 2020 | ndlp->nvme_fb_size <<= | ||
| 2021 | LPFC_NVME_FB_SHIFT; | ||
| 2022 | else | ||
| 2023 | ndlp->nvme_fb_size = LPFC_NVME_MAX_FB; | ||
| 2011 | } | 2024 | } |
| 2012 | } | 2025 | } |
| 2013 | 2026 | ||
| 2014 | if (bf_get_be32(prli_recov, nvpr)) | ||
| 2015 | ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE; | ||
| 2016 | |||
| 2017 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, | 2027 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, |
| 2018 | "6029 NVME PRLI Cmpl w1 x%08x " | 2028 | "6029 NVME PRLI Cmpl w1 x%08x " |
| 2019 | "w4 x%08x w5 x%08x flag x%x, " | 2029 | "w4 x%08x w5 x%08x flag x%x, " |
diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 81e3a4f10c3c..378dca40ca20 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * | 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -65,6 +65,136 @@ lpfc_release_nvme_buf(struct lpfc_hba *, struct lpfc_nvme_buf *); | |||
| 65 | 65 | ||
| 66 | static struct nvme_fc_port_template lpfc_nvme_template; | 66 | static struct nvme_fc_port_template lpfc_nvme_template; |
| 67 | 67 | ||
| 68 | static union lpfc_wqe128 lpfc_iread_cmd_template; | ||
| 69 | static union lpfc_wqe128 lpfc_iwrite_cmd_template; | ||
| 70 | static union lpfc_wqe128 lpfc_icmnd_cmd_template; | ||
| 71 | |||
| 72 | /* Setup WQE templates for NVME IOs */ | ||
| 73 | void | ||
| 74 | lpfc_nvme_cmd_template(void) | ||
| 75 | { | ||
| 76 | union lpfc_wqe128 *wqe; | ||
| 77 | |||
| 78 | /* IREAD template */ | ||
| 79 | wqe = &lpfc_iread_cmd_template; | ||
| 80 | memset(wqe, 0, sizeof(union lpfc_wqe128)); | ||
| 81 | |||
| 82 | /* Word 0, 1, 2 - BDE is variable */ | ||
| 83 | |||
| 84 | /* Word 3 - cmd_buff_len, payload_offset_len is zero */ | ||
| 85 | |||
| 86 | /* Word 4 - total_xfer_len is variable */ | ||
| 87 | |||
| 88 | /* Word 5 - is zero */ | ||
| 89 | |||
| 90 | /* Word 6 - ctxt_tag, xri_tag is variable */ | ||
| 91 | |||
| 92 | /* Word 7 */ | ||
| 93 | bf_set(wqe_cmnd, &wqe->fcp_iread.wqe_com, CMD_FCP_IREAD64_WQE); | ||
| 94 | bf_set(wqe_pu, &wqe->fcp_iread.wqe_com, PARM_READ_CHECK); | ||
| 95 | bf_set(wqe_class, &wqe->fcp_iread.wqe_com, CLASS3); | ||
| 96 | bf_set(wqe_ct, &wqe->fcp_iread.wqe_com, SLI4_CT_RPI); | ||
| 97 | |||
| 98 | /* Word 8 - abort_tag is variable */ | ||
| 99 | |||
| 100 | /* Word 9 - reqtag is variable */ | ||
| 101 | |||
| 102 | /* Word 10 - dbde, wqes is variable */ | ||
| 103 | bf_set(wqe_qosd, &wqe->fcp_iread.wqe_com, 0); | ||
| 104 | bf_set(wqe_nvme, &wqe->fcp_iread.wqe_com, 1); | ||
| 105 | bf_set(wqe_iod, &wqe->fcp_iread.wqe_com, LPFC_WQE_IOD_READ); | ||
| 106 | bf_set(wqe_lenloc, &wqe->fcp_iread.wqe_com, LPFC_WQE_LENLOC_WORD4); | ||
| 107 | bf_set(wqe_dbde, &wqe->fcp_iread.wqe_com, 0); | ||
| 108 | bf_set(wqe_wqes, &wqe->fcp_iread.wqe_com, 1); | ||
| 109 | |||
| 110 | /* Word 11 - pbde is variable */ | ||
| 111 | bf_set(wqe_cmd_type, &wqe->fcp_iread.wqe_com, NVME_READ_CMD); | ||
| 112 | bf_set(wqe_cqid, &wqe->fcp_iread.wqe_com, LPFC_WQE_CQ_ID_DEFAULT); | ||
| 113 | bf_set(wqe_pbde, &wqe->fcp_iread.wqe_com, 1); | ||
| 114 | |||
| 115 | /* Word 12 - is zero */ | ||
| 116 | |||
| 117 | /* Word 13, 14, 15 - PBDE is variable */ | ||
| 118 | |||
| 119 | /* IWRITE template */ | ||
| 120 | wqe = &lpfc_iwrite_cmd_template; | ||
| 121 | memset(wqe, 0, sizeof(union lpfc_wqe128)); | ||
| 122 | |||
| 123 | /* Word 0, 1, 2 - BDE is variable */ | ||
| 124 | |||
| 125 | /* Word 3 - cmd_buff_len, payload_offset_len is zero */ | ||
| 126 | |||
| 127 | /* Word 4 - total_xfer_len is variable */ | ||
| 128 | |||
| 129 | /* Word 5 - initial_xfer_len is variable */ | ||
| 130 | |||
| 131 | /* Word 6 - ctxt_tag, xri_tag is variable */ | ||
| 132 | |||
| 133 | /* Word 7 */ | ||
| 134 | bf_set(wqe_cmnd, &wqe->fcp_iwrite.wqe_com, CMD_FCP_IWRITE64_WQE); | ||
| 135 | bf_set(wqe_pu, &wqe->fcp_iwrite.wqe_com, PARM_READ_CHECK); | ||
| 136 | bf_set(wqe_class, &wqe->fcp_iwrite.wqe_com, CLASS3); | ||
| 137 | bf_set(wqe_ct, &wqe->fcp_iwrite.wqe_com, SLI4_CT_RPI); | ||
| 138 | |||
| 139 | /* Word 8 - abort_tag is variable */ | ||
| 140 | |||
| 141 | /* Word 9 - reqtag is variable */ | ||
| 142 | |||
| 143 | /* Word 10 - dbde, wqes is variable */ | ||
| 144 | bf_set(wqe_qosd, &wqe->fcp_iwrite.wqe_com, 0); | ||
| 145 | bf_set(wqe_nvme, &wqe->fcp_iwrite.wqe_com, 1); | ||
| 146 | bf_set(wqe_iod, &wqe->fcp_iwrite.wqe_com, LPFC_WQE_IOD_WRITE); | ||
| 147 | bf_set(wqe_lenloc, &wqe->fcp_iwrite.wqe_com, LPFC_WQE_LENLOC_WORD4); | ||
| 148 | bf_set(wqe_dbde, &wqe->fcp_iwrite.wqe_com, 0); | ||
| 149 | bf_set(wqe_wqes, &wqe->fcp_iwrite.wqe_com, 1); | ||
| 150 | |||
| 151 | /* Word 11 - pbde is variable */ | ||
| 152 | bf_set(wqe_cmd_type, &wqe->fcp_iwrite.wqe_com, NVME_WRITE_CMD); | ||
| 153 | bf_set(wqe_cqid, &wqe->fcp_iwrite.wqe_com, LPFC_WQE_CQ_ID_DEFAULT); | ||
| 154 | bf_set(wqe_pbde, &wqe->fcp_iwrite.wqe_com, 1); | ||
| 155 | |||
| 156 | /* Word 12 - is zero */ | ||
| 157 | |||
| 158 | /* Word 13, 14, 15 - PBDE is variable */ | ||
| 159 | |||
| 160 | /* ICMND template */ | ||
| 161 | wqe = &lpfc_icmnd_cmd_template; | ||
| 162 | memset(wqe, 0, sizeof(union lpfc_wqe128)); | ||
| 163 | |||
| 164 | /* Word 0, 1, 2 - BDE is variable */ | ||
| 165 | |||
| 166 | /* Word 3 - payload_offset_len is variable */ | ||
| 167 | |||
| 168 | /* Word 4, 5 - is zero */ | ||
| 169 | |||
| 170 | /* Word 6 - ctxt_tag, xri_tag is variable */ | ||
| 171 | |||
| 172 | /* Word 7 */ | ||
| 173 | bf_set(wqe_cmnd, &wqe->fcp_icmd.wqe_com, CMD_FCP_ICMND64_WQE); | ||
| 174 | bf_set(wqe_pu, &wqe->fcp_icmd.wqe_com, 0); | ||
| 175 | bf_set(wqe_class, &wqe->fcp_icmd.wqe_com, CLASS3); | ||
| 176 | bf_set(wqe_ct, &wqe->fcp_icmd.wqe_com, SLI4_CT_RPI); | ||
| 177 | |||
| 178 | /* Word 8 - abort_tag is variable */ | ||
| 179 | |||
| 180 | /* Word 9 - reqtag is variable */ | ||
| 181 | |||
| 182 | /* Word 10 - dbde, wqes is variable */ | ||
| 183 | bf_set(wqe_qosd, &wqe->fcp_icmd.wqe_com, 1); | ||
| 184 | bf_set(wqe_nvme, &wqe->fcp_icmd.wqe_com, 1); | ||
| 185 | bf_set(wqe_iod, &wqe->fcp_icmd.wqe_com, LPFC_WQE_IOD_NONE); | ||
| 186 | bf_set(wqe_lenloc, &wqe->fcp_icmd.wqe_com, LPFC_WQE_LENLOC_NONE); | ||
| 187 | bf_set(wqe_dbde, &wqe->fcp_icmd.wqe_com, 0); | ||
| 188 | bf_set(wqe_wqes, &wqe->fcp_icmd.wqe_com, 1); | ||
| 189 | |||
| 190 | /* Word 11 */ | ||
| 191 | bf_set(wqe_cmd_type, &wqe->fcp_icmd.wqe_com, FCP_COMMAND); | ||
| 192 | bf_set(wqe_cqid, &wqe->fcp_icmd.wqe_com, LPFC_WQE_CQ_ID_DEFAULT); | ||
| 193 | bf_set(wqe_pbde, &wqe->fcp_icmd.wqe_com, 0); | ||
| 194 | |||
| 195 | /* Word 12, 13, 14, 15 - is zero */ | ||
| 196 | } | ||
| 197 | |||
| 68 | /** | 198 | /** |
| 69 | * lpfc_nvme_create_queue - | 199 | * lpfc_nvme_create_queue - |
| 70 | * @lpfc_pnvme: Pointer to the driver's nvme instance data | 200 | * @lpfc_pnvme: Pointer to the driver's nvme instance data |
| @@ -241,10 +371,11 @@ lpfc_nvme_cmpl_gen_req(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe, | |||
| 241 | ndlp = (struct lpfc_nodelist *)cmdwqe->context1; | 371 | ndlp = (struct lpfc_nodelist *)cmdwqe->context1; |
| 242 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, | 372 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, |
| 243 | "6047 nvme cmpl Enter " | 373 | "6047 nvme cmpl Enter " |
| 244 | "Data %p DID %x Xri: %x status %x cmd:%p lsreg:%p " | 374 | "Data %p DID %x Xri: %x status %x reason x%x cmd:%p " |
| 245 | "bmp:%p ndlp:%p\n", | 375 | "lsreg:%p bmp:%p ndlp:%p\n", |
| 246 | pnvme_lsreq, ndlp ? ndlp->nlp_DID : 0, | 376 | pnvme_lsreq, ndlp ? ndlp->nlp_DID : 0, |
| 247 | cmdwqe->sli4_xritag, status, | 377 | cmdwqe->sli4_xritag, status, |
| 378 | (wcqe->parameter & 0xffff), | ||
| 248 | cmdwqe, pnvme_lsreq, cmdwqe->context3, ndlp); | 379 | cmdwqe, pnvme_lsreq, cmdwqe->context3, ndlp); |
| 249 | 380 | ||
| 250 | lpfc_nvmeio_data(phba, "NVME LS CMPL: xri x%x stat x%x parm x%x\n", | 381 | lpfc_nvmeio_data(phba, "NVME LS CMPL: xri x%x stat x%x parm x%x\n", |
| @@ -274,14 +405,14 @@ lpfc_nvme_cmpl_gen_req(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe, | |||
| 274 | static int | 405 | static int |
| 275 | lpfc_nvme_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp, | 406 | lpfc_nvme_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp, |
| 276 | struct lpfc_dmabuf *inp, | 407 | struct lpfc_dmabuf *inp, |
| 277 | struct nvmefc_ls_req *pnvme_lsreq, | 408 | struct nvmefc_ls_req *pnvme_lsreq, |
| 278 | void (*cmpl)(struct lpfc_hba *, struct lpfc_iocbq *, | 409 | void (*cmpl)(struct lpfc_hba *, struct lpfc_iocbq *, |
| 279 | struct lpfc_wcqe_complete *), | 410 | struct lpfc_wcqe_complete *), |
| 280 | struct lpfc_nodelist *ndlp, uint32_t num_entry, | 411 | struct lpfc_nodelist *ndlp, uint32_t num_entry, |
| 281 | uint32_t tmo, uint8_t retry) | 412 | uint32_t tmo, uint8_t retry) |
| 282 | { | 413 | { |
| 283 | struct lpfc_hba *phba = vport->phba; | 414 | struct lpfc_hba *phba = vport->phba; |
| 284 | union lpfc_wqe *wqe; | 415 | union lpfc_wqe128 *wqe; |
| 285 | struct lpfc_iocbq *genwqe; | 416 | struct lpfc_iocbq *genwqe; |
| 286 | struct ulp_bde64 *bpl; | 417 | struct ulp_bde64 *bpl; |
| 287 | struct ulp_bde64 bde; | 418 | struct ulp_bde64 bde; |
| @@ -419,6 +550,7 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport, | |||
| 419 | { | 550 | { |
| 420 | int ret = 0; | 551 | int ret = 0; |
| 421 | struct lpfc_nvme_lport *lport; | 552 | struct lpfc_nvme_lport *lport; |
| 553 | struct lpfc_nvme_rport *rport; | ||
| 422 | struct lpfc_vport *vport; | 554 | struct lpfc_vport *vport; |
| 423 | struct lpfc_nodelist *ndlp; | 555 | struct lpfc_nodelist *ndlp; |
| 424 | struct ulp_bde64 *bpl; | 556 | struct ulp_bde64 *bpl; |
| @@ -437,19 +569,18 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport, | |||
| 437 | */ | 569 | */ |
| 438 | 570 | ||
| 439 | lport = (struct lpfc_nvme_lport *)pnvme_lport->private; | 571 | lport = (struct lpfc_nvme_lport *)pnvme_lport->private; |
| 572 | rport = (struct lpfc_nvme_rport *)pnvme_rport->private; | ||
| 440 | vport = lport->vport; | 573 | vport = lport->vport; |
| 441 | 574 | ||
| 442 | if (vport->load_flag & FC_UNLOADING) | 575 | if (vport->load_flag & FC_UNLOADING) |
| 443 | return -ENODEV; | 576 | return -ENODEV; |
| 444 | 577 | ||
| 445 | if (vport->load_flag & FC_UNLOADING) | 578 | /* Need the ndlp. It is stored in the driver's rport. */ |
| 446 | return -ENODEV; | 579 | ndlp = rport->ndlp; |
| 447 | |||
| 448 | ndlp = lpfc_findnode_did(vport, pnvme_rport->port_id); | ||
| 449 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { | 580 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { |
| 450 | lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE | LOG_NVME_IOERR, | 581 | lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE | LOG_NVME_IOERR, |
| 451 | "6051 DID x%06x not an active rport.\n", | 582 | "6051 Remoteport %p, rport has invalid ndlp. " |
| 452 | pnvme_rport->port_id); | 583 | "Failing LS Req\n", pnvme_rport); |
| 453 | return -ENODEV; | 584 | return -ENODEV; |
| 454 | } | 585 | } |
| 455 | 586 | ||
| @@ -500,8 +631,9 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport, | |||
| 500 | 631 | ||
| 501 | /* Expand print to include key fields. */ | 632 | /* Expand print to include key fields. */ |
| 502 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, | 633 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, |
| 503 | "6149 ENTER. lport %p, rport %p lsreq%p rqstlen:%d " | 634 | "6149 Issue LS Req to DID 0x%06x lport %p, rport %p " |
| 504 | "rsplen:%d %pad %pad\n", | 635 | "lsreq%p rqstlen:%d rsplen:%d %pad %pad\n", |
| 636 | ndlp->nlp_DID, | ||
| 505 | pnvme_lport, pnvme_rport, | 637 | pnvme_lport, pnvme_rport, |
| 506 | pnvme_lsreq, pnvme_lsreq->rqstlen, | 638 | pnvme_lsreq, pnvme_lsreq->rqstlen, |
| 507 | pnvme_lsreq->rsplen, &pnvme_lsreq->rqstdma, | 639 | pnvme_lsreq->rsplen, &pnvme_lsreq->rqstdma, |
| @@ -517,7 +649,7 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport, | |||
| 517 | ndlp, 2, 30, 0); | 649 | ndlp, 2, 30, 0); |
| 518 | if (ret != WQE_SUCCESS) { | 650 | if (ret != WQE_SUCCESS) { |
| 519 | atomic_inc(&lport->xmt_ls_err); | 651 | atomic_inc(&lport->xmt_ls_err); |
| 520 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, | 652 | lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_DISC, |
| 521 | "6052 EXIT. issue ls wqe failed lport %p, " | 653 | "6052 EXIT. issue ls wqe failed lport %p, " |
| 522 | "rport %p lsreq%p Status %x DID %x\n", | 654 | "rport %p lsreq%p Status %x DID %x\n", |
| 523 | pnvme_lport, pnvme_rport, pnvme_lsreq, | 655 | pnvme_lport, pnvme_rport, pnvme_lsreq, |
| @@ -610,16 +742,25 @@ lpfc_nvme_ls_abort(struct nvme_fc_local_port *pnvme_lport, | |||
| 610 | } | 742 | } |
| 611 | 743 | ||
| 612 | /* Fix up the existing sgls for NVME IO. */ | 744 | /* Fix up the existing sgls for NVME IO. */ |
| 613 | static void | 745 | static inline void |
| 614 | lpfc_nvme_adj_fcp_sgls(struct lpfc_vport *vport, | 746 | lpfc_nvme_adj_fcp_sgls(struct lpfc_vport *vport, |
| 615 | struct lpfc_nvme_buf *lpfc_ncmd, | 747 | struct lpfc_nvme_buf *lpfc_ncmd, |
| 616 | struct nvmefc_fcp_req *nCmd) | 748 | struct nvmefc_fcp_req *nCmd) |
| 617 | { | 749 | { |
| 750 | struct lpfc_hba *phba = vport->phba; | ||
| 618 | struct sli4_sge *sgl; | 751 | struct sli4_sge *sgl; |
| 619 | union lpfc_wqe128 *wqe; | 752 | union lpfc_wqe128 *wqe; |
| 620 | uint32_t *wptr, *dptr; | 753 | uint32_t *wptr, *dptr; |
| 621 | 754 | ||
| 622 | /* | 755 | /* |
| 756 | * Get a local pointer to the built-in wqe and correct | ||
| 757 | * the cmd size to match NVME's 96 bytes and fix | ||
| 758 | * the dma address. | ||
| 759 | */ | ||
| 760 | |||
| 761 | wqe = &lpfc_ncmd->cur_iocbq.wqe; | ||
| 762 | |||
| 763 | /* | ||
| 623 | * Adjust the FCP_CMD and FCP_RSP DMA data and sge_len to | 764 | * Adjust the FCP_CMD and FCP_RSP DMA data and sge_len to |
| 624 | * match NVME. NVME sends 96 bytes. Also, use the | 765 | * match NVME. NVME sends 96 bytes. Also, use the |
| 625 | * nvme commands command and response dma addresses | 766 | * nvme commands command and response dma addresses |
| @@ -628,6 +769,60 @@ lpfc_nvme_adj_fcp_sgls(struct lpfc_vport *vport, | |||
| 628 | */ | 769 | */ |
| 629 | sgl = lpfc_ncmd->nvme_sgl; | 770 | sgl = lpfc_ncmd->nvme_sgl; |
| 630 | sgl->sge_len = cpu_to_le32(nCmd->cmdlen); | 771 | sgl->sge_len = cpu_to_le32(nCmd->cmdlen); |
| 772 | if (phba->cfg_nvme_embed_cmd) { | ||
| 773 | sgl->addr_hi = 0; | ||
| 774 | sgl->addr_lo = 0; | ||
| 775 | |||
| 776 | /* Word 0-2 - NVME CMND IU (embedded payload) */ | ||
| 777 | wqe->generic.bde.tus.f.bdeFlags = BUFF_TYPE_BDE_IMMED; | ||
| 778 | wqe->generic.bde.tus.f.bdeSize = 56; | ||
| 779 | wqe->generic.bde.addrHigh = 0; | ||
| 780 | wqe->generic.bde.addrLow = 64; /* Word 16 */ | ||
| 781 | |||
| 782 | /* Word 10 - dbde is 0, wqes is 1 in template */ | ||
| 783 | |||
| 784 | /* | ||
| 785 | * Embed the payload in the last half of the WQE | ||
| 786 | * WQE words 16-30 get the NVME CMD IU payload | ||
| 787 | * | ||
| 788 | * WQE words 16-19 get payload Words 1-4 | ||
| 789 | * WQE words 20-21 get payload Words 6-7 | ||
| 790 | * WQE words 22-29 get payload Words 16-23 | ||
| 791 | */ | ||
| 792 | wptr = &wqe->words[16]; /* WQE ptr */ | ||
| 793 | dptr = (uint32_t *)nCmd->cmdaddr; /* payload ptr */ | ||
| 794 | dptr++; /* Skip Word 0 in payload */ | ||
| 795 | |||
| 796 | *wptr++ = *dptr++; /* Word 1 */ | ||
| 797 | *wptr++ = *dptr++; /* Word 2 */ | ||
| 798 | *wptr++ = *dptr++; /* Word 3 */ | ||
| 799 | *wptr++ = *dptr++; /* Word 4 */ | ||
| 800 | dptr++; /* Skip Word 5 in payload */ | ||
| 801 | *wptr++ = *dptr++; /* Word 6 */ | ||
| 802 | *wptr++ = *dptr++; /* Word 7 */ | ||
| 803 | dptr += 8; /* Skip Words 8-15 in payload */ | ||
| 804 | *wptr++ = *dptr++; /* Word 16 */ | ||
| 805 | *wptr++ = *dptr++; /* Word 17 */ | ||
| 806 | *wptr++ = *dptr++; /* Word 18 */ | ||
| 807 | *wptr++ = *dptr++; /* Word 19 */ | ||
| 808 | *wptr++ = *dptr++; /* Word 20 */ | ||
| 809 | *wptr++ = *dptr++; /* Word 21 */ | ||
| 810 | *wptr++ = *dptr++; /* Word 22 */ | ||
| 811 | *wptr = *dptr; /* Word 23 */ | ||
| 812 | } else { | ||
| 813 | sgl->addr_hi = cpu_to_le32(putPaddrHigh(nCmd->cmddma)); | ||
| 814 | sgl->addr_lo = cpu_to_le32(putPaddrLow(nCmd->cmddma)); | ||
| 815 | |||
| 816 | /* Word 0-2 - NVME CMND IU Inline BDE */ | ||
| 817 | wqe->generic.bde.tus.f.bdeFlags = BUFF_TYPE_BDE_64; | ||
| 818 | wqe->generic.bde.tus.f.bdeSize = nCmd->cmdlen; | ||
| 819 | wqe->generic.bde.addrHigh = sgl->addr_hi; | ||
| 820 | wqe->generic.bde.addrLow = sgl->addr_lo; | ||
| 821 | |||
| 822 | /* Word 10 */ | ||
| 823 | bf_set(wqe_dbde, &wqe->generic.wqe_com, 1); | ||
| 824 | bf_set(wqe_wqes, &wqe->generic.wqe_com, 0); | ||
| 825 | } | ||
| 631 | 826 | ||
| 632 | sgl++; | 827 | sgl++; |
| 633 | 828 | ||
| @@ -641,58 +836,6 @@ lpfc_nvme_adj_fcp_sgls(struct lpfc_vport *vport, | |||
| 641 | bf_set(lpfc_sli4_sge_last, sgl, 1); | 836 | bf_set(lpfc_sli4_sge_last, sgl, 1); |
| 642 | sgl->word2 = cpu_to_le32(sgl->word2); | 837 | sgl->word2 = cpu_to_le32(sgl->word2); |
| 643 | sgl->sge_len = cpu_to_le32(nCmd->rsplen); | 838 | sgl->sge_len = cpu_to_le32(nCmd->rsplen); |
| 644 | |||
| 645 | /* | ||
| 646 | * Get a local pointer to the built-in wqe and correct | ||
| 647 | * the cmd size to match NVME's 96 bytes and fix | ||
| 648 | * the dma address. | ||
| 649 | */ | ||
| 650 | |||
| 651 | /* 128 byte wqe support here */ | ||
| 652 | wqe = (union lpfc_wqe128 *)&lpfc_ncmd->cur_iocbq.wqe; | ||
| 653 | |||
| 654 | /* Word 0-2 - NVME CMND IU (embedded payload) */ | ||
| 655 | wqe->generic.bde.tus.f.bdeFlags = BUFF_TYPE_BDE_IMMED; | ||
| 656 | wqe->generic.bde.tus.f.bdeSize = 60; | ||
| 657 | wqe->generic.bde.addrHigh = 0; | ||
| 658 | wqe->generic.bde.addrLow = 64; /* Word 16 */ | ||
| 659 | |||
| 660 | /* Word 3 */ | ||
| 661 | bf_set(payload_offset_len, &wqe->fcp_icmd, | ||
| 662 | (nCmd->rsplen + nCmd->cmdlen)); | ||
| 663 | |||
| 664 | /* Word 10 */ | ||
| 665 | bf_set(wqe_nvme, &wqe->fcp_icmd.wqe_com, 1); | ||
| 666 | bf_set(wqe_wqes, &wqe->fcp_icmd.wqe_com, 1); | ||
| 667 | |||
| 668 | /* | ||
| 669 | * Embed the payload in the last half of the WQE | ||
| 670 | * WQE words 16-30 get the NVME CMD IU payload | ||
| 671 | * | ||
| 672 | * WQE words 16-19 get payload Words 1-4 | ||
| 673 | * WQE words 20-21 get payload Words 6-7 | ||
| 674 | * WQE words 22-29 get payload Words 16-23 | ||
| 675 | */ | ||
| 676 | wptr = &wqe->words[16]; /* WQE ptr */ | ||
| 677 | dptr = (uint32_t *)nCmd->cmdaddr; /* payload ptr */ | ||
| 678 | dptr++; /* Skip Word 0 in payload */ | ||
| 679 | |||
| 680 | *wptr++ = *dptr++; /* Word 1 */ | ||
| 681 | *wptr++ = *dptr++; /* Word 2 */ | ||
| 682 | *wptr++ = *dptr++; /* Word 3 */ | ||
| 683 | *wptr++ = *dptr++; /* Word 4 */ | ||
| 684 | dptr++; /* Skip Word 5 in payload */ | ||
| 685 | *wptr++ = *dptr++; /* Word 6 */ | ||
| 686 | *wptr++ = *dptr++; /* Word 7 */ | ||
| 687 | dptr += 8; /* Skip Words 8-15 in payload */ | ||
| 688 | *wptr++ = *dptr++; /* Word 16 */ | ||
| 689 | *wptr++ = *dptr++; /* Word 17 */ | ||
| 690 | *wptr++ = *dptr++; /* Word 18 */ | ||
| 691 | *wptr++ = *dptr++; /* Word 19 */ | ||
| 692 | *wptr++ = *dptr++; /* Word 20 */ | ||
| 693 | *wptr++ = *dptr++; /* Word 21 */ | ||
| 694 | *wptr++ = *dptr++; /* Word 22 */ | ||
| 695 | *wptr = *dptr; /* Word 23 */ | ||
| 696 | } | 839 | } |
| 697 | 840 | ||
| 698 | #ifdef CONFIG_SCSI_LPFC_DEBUG_FS | 841 | #ifdef CONFIG_SCSI_LPFC_DEBUG_FS |
| @@ -980,14 +1123,14 @@ out_err: | |||
| 980 | phba->cpucheck_cmpl_io[lpfc_ncmd->cpu]++; | 1123 | phba->cpucheck_cmpl_io[lpfc_ncmd->cpu]++; |
| 981 | } | 1124 | } |
| 982 | #endif | 1125 | #endif |
| 983 | freqpriv = nCmd->private; | ||
| 984 | freqpriv->nvme_buf = NULL; | ||
| 985 | 1126 | ||
| 986 | /* NVME targets need completion held off until the abort exchange | 1127 | /* NVME targets need completion held off until the abort exchange |
| 987 | * completes unless the NVME Rport is getting unregistered. | 1128 | * completes unless the NVME Rport is getting unregistered. |
| 988 | */ | 1129 | */ |
| 989 | 1130 | ||
| 990 | if (!(lpfc_ncmd->flags & LPFC_SBUF_XBUSY)) { | 1131 | if (!(lpfc_ncmd->flags & LPFC_SBUF_XBUSY)) { |
| 1132 | freqpriv = nCmd->private; | ||
| 1133 | freqpriv->nvme_buf = NULL; | ||
| 991 | nCmd->done(nCmd); | 1134 | nCmd->done(nCmd); |
| 992 | lpfc_ncmd->nvmeCmd = NULL; | 1135 | lpfc_ncmd->nvmeCmd = NULL; |
| 993 | } | 1136 | } |
| @@ -1025,7 +1168,7 @@ lpfc_nvme_prep_io_cmd(struct lpfc_vport *vport, | |||
| 1025 | struct lpfc_hba *phba = vport->phba; | 1168 | struct lpfc_hba *phba = vport->phba; |
| 1026 | struct nvmefc_fcp_req *nCmd = lpfc_ncmd->nvmeCmd; | 1169 | struct nvmefc_fcp_req *nCmd = lpfc_ncmd->nvmeCmd; |
| 1027 | struct lpfc_iocbq *pwqeq = &(lpfc_ncmd->cur_iocbq); | 1170 | struct lpfc_iocbq *pwqeq = &(lpfc_ncmd->cur_iocbq); |
| 1028 | union lpfc_wqe128 *wqe = (union lpfc_wqe128 *)&pwqeq->wqe; | 1171 | union lpfc_wqe128 *wqe = &pwqeq->wqe; |
| 1029 | uint32_t req_len; | 1172 | uint32_t req_len; |
| 1030 | 1173 | ||
| 1031 | if (!pnode || !NLP_CHK_NODE_ACT(pnode)) | 1174 | if (!pnode || !NLP_CHK_NODE_ACT(pnode)) |
| @@ -1035,9 +1178,16 @@ lpfc_nvme_prep_io_cmd(struct lpfc_vport *vport, | |||
| 1035 | * There are three possibilities here - use scatter-gather segment, use | 1178 | * There are three possibilities here - use scatter-gather segment, use |
| 1036 | * the single mapping, or neither. | 1179 | * the single mapping, or neither. |
| 1037 | */ | 1180 | */ |
| 1038 | wqe->fcp_iwrite.initial_xfer_len = 0; | ||
| 1039 | if (nCmd->sg_cnt) { | 1181 | if (nCmd->sg_cnt) { |
| 1040 | if (nCmd->io_dir == NVMEFC_FCP_WRITE) { | 1182 | if (nCmd->io_dir == NVMEFC_FCP_WRITE) { |
| 1183 | /* From the iwrite template, initialize words 7 - 11 */ | ||
| 1184 | memcpy(&wqe->words[7], | ||
| 1185 | &lpfc_iwrite_cmd_template.words[7], | ||
| 1186 | sizeof(uint32_t) * 5); | ||
| 1187 | |||
| 1188 | /* Word 4 */ | ||
| 1189 | wqe->fcp_iwrite.total_xfer_len = nCmd->payload_length; | ||
| 1190 | |||
| 1041 | /* Word 5 */ | 1191 | /* Word 5 */ |
| 1042 | if ((phba->cfg_nvme_enable_fb) && | 1192 | if ((phba->cfg_nvme_enable_fb) && |
| 1043 | (pnode->nlp_flag & NLP_FIRSTBURST)) { | 1193 | (pnode->nlp_flag & NLP_FIRSTBURST)) { |
| @@ -1048,69 +1198,28 @@ lpfc_nvme_prep_io_cmd(struct lpfc_vport *vport, | |||
| 1048 | else | 1198 | else |
| 1049 | wqe->fcp_iwrite.initial_xfer_len = | 1199 | wqe->fcp_iwrite.initial_xfer_len = |
| 1050 | pnode->nvme_fb_size; | 1200 | pnode->nvme_fb_size; |
| 1201 | } else { | ||
| 1202 | wqe->fcp_iwrite.initial_xfer_len = 0; | ||
| 1051 | } | 1203 | } |
| 1052 | |||
| 1053 | /* Word 7 */ | ||
| 1054 | bf_set(wqe_cmnd, &wqe->generic.wqe_com, | ||
| 1055 | CMD_FCP_IWRITE64_WQE); | ||
| 1056 | bf_set(wqe_pu, &wqe->generic.wqe_com, | ||
| 1057 | PARM_READ_CHECK); | ||
| 1058 | |||
| 1059 | /* Word 10 */ | ||
| 1060 | bf_set(wqe_qosd, &wqe->fcp_iwrite.wqe_com, 0); | ||
| 1061 | bf_set(wqe_iod, &wqe->fcp_iwrite.wqe_com, | ||
| 1062 | LPFC_WQE_IOD_WRITE); | ||
| 1063 | bf_set(wqe_lenloc, &wqe->fcp_iwrite.wqe_com, | ||
| 1064 | LPFC_WQE_LENLOC_WORD4); | ||
| 1065 | if (phba->cfg_nvme_oas) | ||
| 1066 | bf_set(wqe_oas, &wqe->fcp_iwrite.wqe_com, 1); | ||
| 1067 | |||
| 1068 | /* Word 11 */ | ||
| 1069 | bf_set(wqe_cmd_type, &wqe->generic.wqe_com, | ||
| 1070 | NVME_WRITE_CMD); | ||
| 1071 | |||
| 1072 | atomic_inc(&phba->fc4NvmeOutputRequests); | 1204 | atomic_inc(&phba->fc4NvmeOutputRequests); |
| 1073 | } else { | 1205 | } else { |
| 1074 | /* Word 7 */ | 1206 | /* From the iread template, initialize words 7 - 11 */ |
| 1075 | bf_set(wqe_cmnd, &wqe->generic.wqe_com, | 1207 | memcpy(&wqe->words[7], |
| 1076 | CMD_FCP_IREAD64_WQE); | 1208 | &lpfc_iread_cmd_template.words[7], |
| 1077 | bf_set(wqe_pu, &wqe->generic.wqe_com, | 1209 | sizeof(uint32_t) * 5); |
| 1078 | PARM_READ_CHECK); | 1210 | |
| 1079 | 1211 | /* Word 4 */ | |
| 1080 | /* Word 10 */ | 1212 | wqe->fcp_iread.total_xfer_len = nCmd->payload_length; |
| 1081 | bf_set(wqe_qosd, &wqe->fcp_iread.wqe_com, 0); | 1213 | |
| 1082 | bf_set(wqe_iod, &wqe->fcp_iread.wqe_com, | 1214 | /* Word 5 */ |
| 1083 | LPFC_WQE_IOD_READ); | 1215 | wqe->fcp_iread.rsrvd5 = 0; |
| 1084 | bf_set(wqe_lenloc, &wqe->fcp_iread.wqe_com, | ||
| 1085 | LPFC_WQE_LENLOC_WORD4); | ||
| 1086 | if (phba->cfg_nvme_oas) | ||
| 1087 | bf_set(wqe_oas, &wqe->fcp_iread.wqe_com, 1); | ||
| 1088 | |||
| 1089 | /* Word 11 */ | ||
| 1090 | bf_set(wqe_cmd_type, &wqe->generic.wqe_com, | ||
| 1091 | NVME_READ_CMD); | ||
| 1092 | 1216 | ||
| 1093 | atomic_inc(&phba->fc4NvmeInputRequests); | 1217 | atomic_inc(&phba->fc4NvmeInputRequests); |
| 1094 | } | 1218 | } |
| 1095 | } else { | 1219 | } else { |
| 1096 | /* Word 4 */ | 1220 | /* From the icmnd template, initialize words 4 - 11 */ |
| 1097 | wqe->fcp_icmd.rsrvd4 = 0; | 1221 | memcpy(&wqe->words[4], &lpfc_icmnd_cmd_template.words[4], |
| 1098 | 1222 | sizeof(uint32_t) * 8); | |
| 1099 | /* Word 7 */ | ||
| 1100 | bf_set(wqe_cmnd, &wqe->generic.wqe_com, CMD_FCP_ICMND64_WQE); | ||
| 1101 | bf_set(wqe_pu, &wqe->generic.wqe_com, 0); | ||
| 1102 | |||
| 1103 | /* Word 10 */ | ||
| 1104 | bf_set(wqe_qosd, &wqe->fcp_icmd.wqe_com, 1); | ||
| 1105 | bf_set(wqe_iod, &wqe->fcp_icmd.wqe_com, LPFC_WQE_IOD_WRITE); | ||
| 1106 | bf_set(wqe_lenloc, &wqe->fcp_icmd.wqe_com, | ||
| 1107 | LPFC_WQE_LENLOC_NONE); | ||
| 1108 | if (phba->cfg_nvme_oas) | ||
| 1109 | bf_set(wqe_oas, &wqe->fcp_icmd.wqe_com, 1); | ||
| 1110 | |||
| 1111 | /* Word 11 */ | ||
| 1112 | bf_set(wqe_cmd_type, &wqe->generic.wqe_com, NVME_READ_CMD); | ||
| 1113 | |||
| 1114 | atomic_inc(&phba->fc4NvmeControlRequests); | 1223 | atomic_inc(&phba->fc4NvmeControlRequests); |
| 1115 | } | 1224 | } |
| 1116 | /* | 1225 | /* |
| @@ -1118,25 +1227,21 @@ lpfc_nvme_prep_io_cmd(struct lpfc_vport *vport, | |||
| 1118 | * of the nvme_cmnd request_buffer | 1227 | * of the nvme_cmnd request_buffer |
| 1119 | */ | 1228 | */ |
| 1120 | 1229 | ||
| 1230 | /* Word 3 */ | ||
| 1231 | bf_set(payload_offset_len, &wqe->fcp_icmd, | ||
| 1232 | (nCmd->rsplen + nCmd->cmdlen)); | ||
| 1233 | |||
| 1121 | /* Word 6 */ | 1234 | /* Word 6 */ |
| 1122 | bf_set(wqe_ctxt_tag, &wqe->generic.wqe_com, | 1235 | bf_set(wqe_ctxt_tag, &wqe->generic.wqe_com, |
| 1123 | phba->sli4_hba.rpi_ids[pnode->nlp_rpi]); | 1236 | phba->sli4_hba.rpi_ids[pnode->nlp_rpi]); |
| 1124 | bf_set(wqe_xri_tag, &wqe->generic.wqe_com, pwqeq->sli4_xritag); | 1237 | bf_set(wqe_xri_tag, &wqe->generic.wqe_com, pwqeq->sli4_xritag); |
| 1125 | 1238 | ||
| 1126 | /* Word 7 */ | ||
| 1127 | /* Preserve Class data in the ndlp. */ | ||
| 1128 | bf_set(wqe_class, &wqe->generic.wqe_com, | ||
| 1129 | (pnode->nlp_fcp_info & 0x0f)); | ||
| 1130 | |||
| 1131 | /* Word 8 */ | 1239 | /* Word 8 */ |
| 1132 | wqe->generic.wqe_com.abort_tag = pwqeq->iotag; | 1240 | wqe->generic.wqe_com.abort_tag = pwqeq->iotag; |
| 1133 | 1241 | ||
| 1134 | /* Word 9 */ | 1242 | /* Word 9 */ |
| 1135 | bf_set(wqe_reqtag, &wqe->generic.wqe_com, pwqeq->iotag); | 1243 | bf_set(wqe_reqtag, &wqe->generic.wqe_com, pwqeq->iotag); |
| 1136 | 1244 | ||
| 1137 | /* Word 11 */ | ||
| 1138 | bf_set(wqe_cqid, &wqe->generic.wqe_com, LPFC_WQE_CQ_ID_DEFAULT); | ||
| 1139 | |||
| 1140 | pwqeq->vport = vport; | 1245 | pwqeq->vport = vport; |
| 1141 | return 0; | 1246 | return 0; |
| 1142 | } | 1247 | } |
| @@ -1164,10 +1269,11 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport, | |||
| 1164 | { | 1269 | { |
| 1165 | struct lpfc_hba *phba = vport->phba; | 1270 | struct lpfc_hba *phba = vport->phba; |
| 1166 | struct nvmefc_fcp_req *nCmd = lpfc_ncmd->nvmeCmd; | 1271 | struct nvmefc_fcp_req *nCmd = lpfc_ncmd->nvmeCmd; |
| 1167 | union lpfc_wqe128 *wqe = (union lpfc_wqe128 *)&lpfc_ncmd->cur_iocbq.wqe; | 1272 | union lpfc_wqe128 *wqe = &lpfc_ncmd->cur_iocbq.wqe; |
| 1168 | struct sli4_sge *sgl = lpfc_ncmd->nvme_sgl; | 1273 | struct sli4_sge *sgl = lpfc_ncmd->nvme_sgl; |
| 1169 | struct scatterlist *data_sg; | 1274 | struct scatterlist *data_sg; |
| 1170 | struct sli4_sge *first_data_sgl; | 1275 | struct sli4_sge *first_data_sgl; |
| 1276 | struct ulp_bde64 *bde; | ||
| 1171 | dma_addr_t physaddr; | 1277 | dma_addr_t physaddr; |
| 1172 | uint32_t num_bde = 0; | 1278 | uint32_t num_bde = 0; |
| 1173 | uint32_t dma_len; | 1279 | uint32_t dma_len; |
| @@ -1235,7 +1341,26 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport, | |||
| 1235 | data_sg = sg_next(data_sg); | 1341 | data_sg = sg_next(data_sg); |
| 1236 | sgl++; | 1342 | sgl++; |
| 1237 | } | 1343 | } |
| 1344 | if (phba->nvme_embed_pbde) { | ||
| 1345 | /* Use PBDE support for first SGL only, offset == 0 */ | ||
| 1346 | /* Words 13-15 */ | ||
| 1347 | bde = (struct ulp_bde64 *) | ||
| 1348 | &wqe->words[13]; | ||
| 1349 | bde->addrLow = first_data_sgl->addr_lo; | ||
| 1350 | bde->addrHigh = first_data_sgl->addr_hi; | ||
| 1351 | bde->tus.f.bdeSize = | ||
| 1352 | le32_to_cpu(first_data_sgl->sge_len); | ||
| 1353 | bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64; | ||
| 1354 | bde->tus.w = cpu_to_le32(bde->tus.w); | ||
| 1355 | /* wqe_pbde is 1 in template */ | ||
| 1356 | } else { | ||
| 1357 | memset(&wqe->words[13], 0, (sizeof(uint32_t) * 3)); | ||
| 1358 | bf_set(wqe_pbde, &wqe->generic.wqe_com, 0); | ||
| 1359 | } | ||
| 1238 | } else { | 1360 | } else { |
| 1361 | bf_set(wqe_pbde, &wqe->generic.wqe_com, 0); | ||
| 1362 | memset(&wqe->words[13], 0, (sizeof(uint32_t) * 3)); | ||
| 1363 | |||
| 1239 | /* For this clause to be valid, the payload_length | 1364 | /* For this clause to be valid, the payload_length |
| 1240 | * and sg_cnt must zero. | 1365 | * and sg_cnt must zero. |
| 1241 | */ | 1366 | */ |
| @@ -1247,12 +1372,6 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport, | |||
| 1247 | return 1; | 1372 | return 1; |
| 1248 | } | 1373 | } |
| 1249 | } | 1374 | } |
| 1250 | |||
| 1251 | /* | ||
| 1252 | * Due to difference in data length between DIF/non-DIF paths, | ||
| 1253 | * we need to set word 4 of WQE here | ||
| 1254 | */ | ||
| 1255 | wqe->fcp_iread.total_xfer_len = nCmd->payload_length; | ||
| 1256 | return 0; | 1375 | return 0; |
| 1257 | } | 1376 | } |
| 1258 | 1377 | ||
| @@ -1554,7 +1673,7 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, | |||
| 1554 | struct lpfc_iocbq *abts_buf; | 1673 | struct lpfc_iocbq *abts_buf; |
| 1555 | struct lpfc_iocbq *nvmereq_wqe; | 1674 | struct lpfc_iocbq *nvmereq_wqe; |
| 1556 | struct lpfc_nvme_fcpreq_priv *freqpriv; | 1675 | struct lpfc_nvme_fcpreq_priv *freqpriv; |
| 1557 | union lpfc_wqe *abts_wqe; | 1676 | union lpfc_wqe128 *abts_wqe; |
| 1558 | unsigned long flags; | 1677 | unsigned long flags; |
| 1559 | int ret_val; | 1678 | int ret_val; |
| 1560 | 1679 | ||
| @@ -2098,7 +2217,7 @@ lpfc_new_nvme_buf(struct lpfc_vport *vport, int num_to_alloc) | |||
| 2098 | break; | 2217 | break; |
| 2099 | } | 2218 | } |
| 2100 | pwqeq = &(lpfc_ncmd->cur_iocbq); | 2219 | pwqeq = &(lpfc_ncmd->cur_iocbq); |
| 2101 | wqe = (union lpfc_wqe128 *)&pwqeq->wqe; | 2220 | wqe = &pwqeq->wqe; |
| 2102 | 2221 | ||
| 2103 | /* Allocate iotag for lpfc_ncmd->cur_iocbq. */ | 2222 | /* Allocate iotag for lpfc_ncmd->cur_iocbq. */ |
| 2104 | iotag = lpfc_sli_next_iotag(phba, pwqeq); | 2223 | iotag = lpfc_sli_next_iotag(phba, pwqeq); |
| @@ -2135,14 +2254,8 @@ lpfc_new_nvme_buf(struct lpfc_vport *vport, int num_to_alloc) | |||
| 2135 | 2254 | ||
| 2136 | lpfc_ncmd->cur_iocbq.context1 = lpfc_ncmd; | 2255 | lpfc_ncmd->cur_iocbq.context1 = lpfc_ncmd; |
| 2137 | 2256 | ||
| 2138 | /* Word 7 */ | 2257 | /* Initialize WQE */ |
| 2139 | bf_set(wqe_erp, &wqe->generic.wqe_com, 0); | 2258 | memset(wqe, 0, sizeof(union lpfc_wqe)); |
| 2140 | /* NVME upper layers will time things out, if needed */ | ||
| 2141 | bf_set(wqe_tmo, &wqe->generic.wqe_com, 0); | ||
| 2142 | |||
| 2143 | /* Word 10 */ | ||
| 2144 | bf_set(wqe_ebde_cnt, &wqe->generic.wqe_com, 0); | ||
| 2145 | bf_set(wqe_dbde, &wqe->generic.wqe_com, 1); | ||
| 2146 | 2259 | ||
| 2147 | /* add the nvme buffer to a post list */ | 2260 | /* add the nvme buffer to a post list */ |
| 2148 | list_add_tail(&lpfc_ncmd->list, &post_nblist); | 2261 | list_add_tail(&lpfc_ncmd->list, &post_nblist); |
diff --git a/drivers/scsi/lpfc/lpfc_nvme.h b/drivers/scsi/lpfc/lpfc_nvme.h index e79f8f75758c..9216653e0441 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.h +++ b/drivers/scsi/lpfc/lpfc_nvme.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * | 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -27,6 +27,8 @@ | |||
| 27 | 27 | ||
| 28 | #define LPFC_NVME_WAIT_TMO 10 | 28 | #define LPFC_NVME_WAIT_TMO 10 |
| 29 | #define LPFC_NVME_EXPEDITE_XRICNT 8 | 29 | #define LPFC_NVME_EXPEDITE_XRICNT 8 |
| 30 | #define LPFC_NVME_FB_SHIFT 9 | ||
| 31 | #define LPFC_NVME_MAX_FB (1 << 20) /* 1M */ | ||
| 30 | 32 | ||
| 31 | struct lpfc_nvme_qhandle { | 33 | struct lpfc_nvme_qhandle { |
| 32 | uint32_t index; /* WQ index to use */ | 34 | uint32_t index; /* WQ index to use */ |
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c index 8dbf5c9d51aa..7271c9d885dd 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.c +++ b/drivers/scsi/lpfc/lpfc_nvmet.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channsel Host Bus Adapters. * | 3 | * Fibre Channsel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * | 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -36,7 +36,7 @@ | |||
| 36 | #include <scsi/scsi_transport_fc.h> | 36 | #include <scsi/scsi_transport_fc.h> |
| 37 | #include <scsi/fc/fc_fs.h> | 37 | #include <scsi/fc/fc_fs.h> |
| 38 | 38 | ||
| 39 | #include <../drivers/nvme/host/nvme.h> | 39 | #include <linux/nvme.h> |
| 40 | #include <linux/nvme-fc-driver.h> | 40 | #include <linux/nvme-fc-driver.h> |
| 41 | #include <linux/nvme-fc.h> | 41 | #include <linux/nvme-fc.h> |
| 42 | 42 | ||
| @@ -71,6 +71,151 @@ static int lpfc_nvmet_unsol_fcp_issue_abort(struct lpfc_hba *, | |||
| 71 | static int lpfc_nvmet_unsol_ls_issue_abort(struct lpfc_hba *, | 71 | static int lpfc_nvmet_unsol_ls_issue_abort(struct lpfc_hba *, |
| 72 | struct lpfc_nvmet_rcv_ctx *, | 72 | struct lpfc_nvmet_rcv_ctx *, |
| 73 | uint32_t, uint16_t); | 73 | uint32_t, uint16_t); |
| 74 | static void lpfc_nvmet_wqfull_flush(struct lpfc_hba *, struct lpfc_queue *, | ||
| 75 | struct lpfc_nvmet_rcv_ctx *); | ||
| 76 | |||
| 77 | static union lpfc_wqe128 lpfc_tsend_cmd_template; | ||
| 78 | static union lpfc_wqe128 lpfc_treceive_cmd_template; | ||
| 79 | static union lpfc_wqe128 lpfc_trsp_cmd_template; | ||
| 80 | |||
| 81 | /* Setup WQE templates for NVME IOs */ | ||
| 82 | void | ||
| 83 | lpfc_nvmet_cmd_template(void) | ||
| 84 | { | ||
| 85 | union lpfc_wqe128 *wqe; | ||
| 86 | |||
| 87 | /* TSEND template */ | ||
| 88 | wqe = &lpfc_tsend_cmd_template; | ||
| 89 | memset(wqe, 0, sizeof(union lpfc_wqe128)); | ||
| 90 | |||
| 91 | /* Word 0, 1, 2 - BDE is variable */ | ||
| 92 | |||
| 93 | /* Word 3 - payload_offset_len is zero */ | ||
| 94 | |||
| 95 | /* Word 4 - relative_offset is variable */ | ||
| 96 | |||
| 97 | /* Word 5 - is zero */ | ||
| 98 | |||
| 99 | /* Word 6 - ctxt_tag, xri_tag is variable */ | ||
| 100 | |||
| 101 | /* Word 7 - wqe_ar is variable */ | ||
| 102 | bf_set(wqe_cmnd, &wqe->fcp_tsend.wqe_com, CMD_FCP_TSEND64_WQE); | ||
| 103 | bf_set(wqe_pu, &wqe->fcp_tsend.wqe_com, PARM_REL_OFF); | ||
| 104 | bf_set(wqe_class, &wqe->fcp_tsend.wqe_com, CLASS3); | ||
| 105 | bf_set(wqe_ct, &wqe->fcp_tsend.wqe_com, SLI4_CT_RPI); | ||
| 106 | bf_set(wqe_ar, &wqe->fcp_tsend.wqe_com, 1); | ||
| 107 | |||
| 108 | /* Word 8 - abort_tag is variable */ | ||
| 109 | |||
| 110 | /* Word 9 - reqtag, rcvoxid is variable */ | ||
| 111 | |||
| 112 | /* Word 10 - wqes, xc is variable */ | ||
| 113 | bf_set(wqe_nvme, &wqe->fcp_tsend.wqe_com, 1); | ||
| 114 | bf_set(wqe_dbde, &wqe->fcp_tsend.wqe_com, 1); | ||
| 115 | bf_set(wqe_wqes, &wqe->fcp_tsend.wqe_com, 0); | ||
| 116 | bf_set(wqe_xc, &wqe->fcp_tsend.wqe_com, 1); | ||
| 117 | bf_set(wqe_iod, &wqe->fcp_tsend.wqe_com, LPFC_WQE_IOD_WRITE); | ||
| 118 | bf_set(wqe_lenloc, &wqe->fcp_tsend.wqe_com, LPFC_WQE_LENLOC_WORD12); | ||
| 119 | |||
| 120 | /* Word 11 - sup, irsp, irsplen is variable */ | ||
| 121 | bf_set(wqe_cmd_type, &wqe->fcp_tsend.wqe_com, FCP_COMMAND_TSEND); | ||
| 122 | bf_set(wqe_cqid, &wqe->fcp_tsend.wqe_com, LPFC_WQE_CQ_ID_DEFAULT); | ||
| 123 | bf_set(wqe_sup, &wqe->fcp_tsend.wqe_com, 0); | ||
| 124 | bf_set(wqe_irsp, &wqe->fcp_tsend.wqe_com, 0); | ||
| 125 | bf_set(wqe_irsplen, &wqe->fcp_tsend.wqe_com, 0); | ||
| 126 | bf_set(wqe_pbde, &wqe->fcp_tsend.wqe_com, 0); | ||
| 127 | |||
| 128 | /* Word 12 - fcp_data_len is variable */ | ||
| 129 | |||
| 130 | /* Word 13, 14, 15 - PBDE is zero */ | ||
| 131 | |||
| 132 | /* TRECEIVE template */ | ||
| 133 | wqe = &lpfc_treceive_cmd_template; | ||
| 134 | memset(wqe, 0, sizeof(union lpfc_wqe128)); | ||
| 135 | |||
| 136 | /* Word 0, 1, 2 - BDE is variable */ | ||
| 137 | |||
| 138 | /* Word 3 */ | ||
| 139 | wqe->fcp_treceive.payload_offset_len = TXRDY_PAYLOAD_LEN; | ||
| 140 | |||
| 141 | /* Word 4 - relative_offset is variable */ | ||
| 142 | |||
| 143 | /* Word 5 - is zero */ | ||
| 144 | |||
| 145 | /* Word 6 - ctxt_tag, xri_tag is variable */ | ||
| 146 | |||
| 147 | /* Word 7 */ | ||
| 148 | bf_set(wqe_cmnd, &wqe->fcp_treceive.wqe_com, CMD_FCP_TRECEIVE64_WQE); | ||
| 149 | bf_set(wqe_pu, &wqe->fcp_treceive.wqe_com, PARM_REL_OFF); | ||
| 150 | bf_set(wqe_class, &wqe->fcp_treceive.wqe_com, CLASS3); | ||
| 151 | bf_set(wqe_ct, &wqe->fcp_treceive.wqe_com, SLI4_CT_RPI); | ||
| 152 | bf_set(wqe_ar, &wqe->fcp_treceive.wqe_com, 0); | ||
| 153 | |||
| 154 | /* Word 8 - abort_tag is variable */ | ||
| 155 | |||
| 156 | /* Word 9 - reqtag, rcvoxid is variable */ | ||
| 157 | |||
| 158 | /* Word 10 - xc is variable */ | ||
| 159 | bf_set(wqe_dbde, &wqe->fcp_treceive.wqe_com, 1); | ||
| 160 | bf_set(wqe_wqes, &wqe->fcp_treceive.wqe_com, 0); | ||
| 161 | bf_set(wqe_nvme, &wqe->fcp_treceive.wqe_com, 1); | ||
| 162 | bf_set(wqe_iod, &wqe->fcp_treceive.wqe_com, LPFC_WQE_IOD_READ); | ||
| 163 | bf_set(wqe_lenloc, &wqe->fcp_treceive.wqe_com, LPFC_WQE_LENLOC_WORD12); | ||
| 164 | bf_set(wqe_xc, &wqe->fcp_tsend.wqe_com, 1); | ||
| 165 | |||
| 166 | /* Word 11 - pbde is variable */ | ||
| 167 | bf_set(wqe_cmd_type, &wqe->fcp_treceive.wqe_com, FCP_COMMAND_TRECEIVE); | ||
| 168 | bf_set(wqe_cqid, &wqe->fcp_treceive.wqe_com, LPFC_WQE_CQ_ID_DEFAULT); | ||
| 169 | bf_set(wqe_sup, &wqe->fcp_treceive.wqe_com, 0); | ||
| 170 | bf_set(wqe_irsp, &wqe->fcp_treceive.wqe_com, 0); | ||
| 171 | bf_set(wqe_irsplen, &wqe->fcp_treceive.wqe_com, 0); | ||
| 172 | bf_set(wqe_pbde, &wqe->fcp_treceive.wqe_com, 1); | ||
| 173 | |||
| 174 | /* Word 12 - fcp_data_len is variable */ | ||
| 175 | |||
| 176 | /* Word 13, 14, 15 - PBDE is variable */ | ||
| 177 | |||
| 178 | /* TRSP template */ | ||
| 179 | wqe = &lpfc_trsp_cmd_template; | ||
| 180 | memset(wqe, 0, sizeof(union lpfc_wqe128)); | ||
| 181 | |||
| 182 | /* Word 0, 1, 2 - BDE is variable */ | ||
| 183 | |||
| 184 | /* Word 3 - response_len is variable */ | ||
| 185 | |||
| 186 | /* Word 4, 5 - is zero */ | ||
| 187 | |||
| 188 | /* Word 6 - ctxt_tag, xri_tag is variable */ | ||
| 189 | |||
| 190 | /* Word 7 */ | ||
| 191 | bf_set(wqe_cmnd, &wqe->fcp_trsp.wqe_com, CMD_FCP_TRSP64_WQE); | ||
| 192 | bf_set(wqe_pu, &wqe->fcp_trsp.wqe_com, PARM_UNUSED); | ||
| 193 | bf_set(wqe_class, &wqe->fcp_trsp.wqe_com, CLASS3); | ||
| 194 | bf_set(wqe_ct, &wqe->fcp_trsp.wqe_com, SLI4_CT_RPI); | ||
| 195 | bf_set(wqe_ag, &wqe->fcp_trsp.wqe_com, 1); /* wqe_ar */ | ||
| 196 | |||
| 197 | /* Word 8 - abort_tag is variable */ | ||
| 198 | |||
| 199 | /* Word 9 - reqtag is variable */ | ||
| 200 | |||
| 201 | /* Word 10 wqes, xc is variable */ | ||
| 202 | bf_set(wqe_dbde, &wqe->fcp_trsp.wqe_com, 1); | ||
| 203 | bf_set(wqe_nvme, &wqe->fcp_trsp.wqe_com, 1); | ||
| 204 | bf_set(wqe_wqes, &wqe->fcp_trsp.wqe_com, 0); | ||
| 205 | bf_set(wqe_xc, &wqe->fcp_trsp.wqe_com, 0); | ||
| 206 | bf_set(wqe_iod, &wqe->fcp_trsp.wqe_com, LPFC_WQE_IOD_NONE); | ||
| 207 | bf_set(wqe_lenloc, &wqe->fcp_trsp.wqe_com, LPFC_WQE_LENLOC_WORD3); | ||
| 208 | |||
| 209 | /* Word 11 irsp, irsplen is variable */ | ||
| 210 | bf_set(wqe_cmd_type, &wqe->fcp_trsp.wqe_com, FCP_COMMAND_TRSP); | ||
| 211 | bf_set(wqe_cqid, &wqe->fcp_trsp.wqe_com, LPFC_WQE_CQ_ID_DEFAULT); | ||
| 212 | bf_set(wqe_sup, &wqe->fcp_trsp.wqe_com, 0); | ||
| 213 | bf_set(wqe_irsp, &wqe->fcp_trsp.wqe_com, 0); | ||
| 214 | bf_set(wqe_irsplen, &wqe->fcp_trsp.wqe_com, 0); | ||
| 215 | bf_set(wqe_pbde, &wqe->fcp_trsp.wqe_com, 0); | ||
| 216 | |||
| 217 | /* Word 12, 13, 14, 15 - is zero */ | ||
| 218 | } | ||
| 74 | 219 | ||
| 75 | void | 220 | void |
| 76 | lpfc_nvmet_defer_release(struct lpfc_hba *phba, struct lpfc_nvmet_rcv_ctx *ctxp) | 221 | lpfc_nvmet_defer_release(struct lpfc_hba *phba, struct lpfc_nvmet_rcv_ctx *ctxp) |
| @@ -130,7 +275,7 @@ lpfc_nvmet_xmt_ls_rsp_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe, | |||
| 130 | if (tgtp) { | 275 | if (tgtp) { |
| 131 | if (status) { | 276 | if (status) { |
| 132 | atomic_inc(&tgtp->xmt_ls_rsp_error); | 277 | atomic_inc(&tgtp->xmt_ls_rsp_error); |
| 133 | if (status == IOERR_ABORT_REQUESTED) | 278 | if (result == IOERR_ABORT_REQUESTED) |
| 134 | atomic_inc(&tgtp->xmt_ls_rsp_aborted); | 279 | atomic_inc(&tgtp->xmt_ls_rsp_aborted); |
| 135 | if (bf_get(lpfc_wcqe_c_xb, wcqe)) | 280 | if (bf_get(lpfc_wcqe_c_xb, wcqe)) |
| 136 | atomic_inc(&tgtp->xmt_ls_rsp_xb_set); | 281 | atomic_inc(&tgtp->xmt_ls_rsp_xb_set); |
| @@ -268,8 +413,6 @@ lpfc_nvmet_ctxbuf_post(struct lpfc_hba *phba, struct lpfc_nvmet_ctxbuf *ctx_buf) | |||
| 268 | "NVMET RCV BUSY: xri x%x sz %d " | 413 | "NVMET RCV BUSY: xri x%x sz %d " |
| 269 | "from %06x\n", | 414 | "from %06x\n", |
| 270 | oxid, size, sid); | 415 | oxid, size, sid); |
| 271 | /* defer repost rcv buffer till .defer_rcv callback */ | ||
| 272 | ctxp->flag &= ~LPFC_NVMET_DEFER_RCV_REPOST; | ||
| 273 | atomic_inc(&tgtp->rcv_fcp_cmd_out); | 416 | atomic_inc(&tgtp->rcv_fcp_cmd_out); |
| 274 | return; | 417 | return; |
| 275 | } | 418 | } |
| @@ -541,7 +684,7 @@ lpfc_nvmet_xmt_fcp_op_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe, | |||
| 541 | rsp->transferred_length = 0; | 684 | rsp->transferred_length = 0; |
| 542 | if (tgtp) { | 685 | if (tgtp) { |
| 543 | atomic_inc(&tgtp->xmt_fcp_rsp_error); | 686 | atomic_inc(&tgtp->xmt_fcp_rsp_error); |
| 544 | if (status == IOERR_ABORT_REQUESTED) | 687 | if (result == IOERR_ABORT_REQUESTED) |
| 545 | atomic_inc(&tgtp->xmt_fcp_rsp_aborted); | 688 | atomic_inc(&tgtp->xmt_fcp_rsp_aborted); |
| 546 | } | 689 | } |
| 547 | 690 | ||
| @@ -741,7 +884,10 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport, | |||
| 741 | struct lpfc_nvmet_rcv_ctx *ctxp = | 884 | struct lpfc_nvmet_rcv_ctx *ctxp = |
| 742 | container_of(rsp, struct lpfc_nvmet_rcv_ctx, ctx.fcp_req); | 885 | container_of(rsp, struct lpfc_nvmet_rcv_ctx, ctx.fcp_req); |
| 743 | struct lpfc_hba *phba = ctxp->phba; | 886 | struct lpfc_hba *phba = ctxp->phba; |
| 887 | struct lpfc_queue *wq; | ||
| 744 | struct lpfc_iocbq *nvmewqeq; | 888 | struct lpfc_iocbq *nvmewqeq; |
| 889 | struct lpfc_sli_ring *pring; | ||
| 890 | unsigned long iflags; | ||
| 745 | int rc; | 891 | int rc; |
| 746 | 892 | ||
| 747 | if (phba->pport->load_flag & FC_UNLOADING) { | 893 | if (phba->pport->load_flag & FC_UNLOADING) { |
| @@ -820,6 +966,22 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport, | |||
| 820 | return 0; | 966 | return 0; |
| 821 | } | 967 | } |
| 822 | 968 | ||
| 969 | if (rc == -EBUSY) { | ||
| 970 | /* | ||
| 971 | * WQ was full, so queue nvmewqeq to be sent after | ||
| 972 | * WQE release CQE | ||
| 973 | */ | ||
| 974 | ctxp->flag |= LPFC_NVMET_DEFER_WQFULL; | ||
| 975 | wq = phba->sli4_hba.nvme_wq[rsp->hwqid]; | ||
| 976 | pring = wq->pring; | ||
| 977 | spin_lock_irqsave(&pring->ring_lock, iflags); | ||
| 978 | list_add_tail(&nvmewqeq->list, &wq->wqfull_list); | ||
| 979 | wq->q_flag |= HBA_NVMET_WQFULL; | ||
| 980 | spin_unlock_irqrestore(&pring->ring_lock, iflags); | ||
| 981 | atomic_inc(&lpfc_nvmep->defer_wqfull); | ||
| 982 | return 0; | ||
| 983 | } | ||
| 984 | |||
| 823 | /* Give back resources */ | 985 | /* Give back resources */ |
| 824 | atomic_inc(&lpfc_nvmep->xmt_fcp_drop); | 986 | atomic_inc(&lpfc_nvmep->xmt_fcp_drop); |
| 825 | lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR, | 987 | lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR, |
| @@ -851,6 +1013,7 @@ lpfc_nvmet_xmt_fcp_abort(struct nvmet_fc_target_port *tgtport, | |||
| 851 | struct lpfc_nvmet_rcv_ctx *ctxp = | 1013 | struct lpfc_nvmet_rcv_ctx *ctxp = |
| 852 | container_of(req, struct lpfc_nvmet_rcv_ctx, ctx.fcp_req); | 1014 | container_of(req, struct lpfc_nvmet_rcv_ctx, ctx.fcp_req); |
| 853 | struct lpfc_hba *phba = ctxp->phba; | 1015 | struct lpfc_hba *phba = ctxp->phba; |
| 1016 | struct lpfc_queue *wq; | ||
| 854 | unsigned long flags; | 1017 | unsigned long flags; |
| 855 | 1018 | ||
| 856 | if (phba->pport->load_flag & FC_UNLOADING) | 1019 | if (phba->pport->load_flag & FC_UNLOADING) |
| @@ -880,6 +1043,15 @@ lpfc_nvmet_xmt_fcp_abort(struct nvmet_fc_target_port *tgtport, | |||
| 880 | } | 1043 | } |
| 881 | ctxp->flag |= LPFC_NVMET_ABORT_OP; | 1044 | ctxp->flag |= LPFC_NVMET_ABORT_OP; |
| 882 | 1045 | ||
| 1046 | if (ctxp->flag & LPFC_NVMET_DEFER_WQFULL) { | ||
| 1047 | lpfc_nvmet_unsol_fcp_issue_abort(phba, ctxp, ctxp->sid, | ||
| 1048 | ctxp->oxid); | ||
| 1049 | wq = phba->sli4_hba.nvme_wq[ctxp->wqeq->hba_wqidx]; | ||
| 1050 | spin_unlock_irqrestore(&ctxp->ctxlock, flags); | ||
| 1051 | lpfc_nvmet_wqfull_flush(phba, wq, ctxp); | ||
| 1052 | return; | ||
| 1053 | } | ||
| 1054 | |||
| 883 | /* An state of LPFC_NVMET_STE_RCV means we have just received | 1055 | /* An state of LPFC_NVMET_STE_RCV means we have just received |
| 884 | * the NVME command and have not started processing it. | 1056 | * the NVME command and have not started processing it. |
| 885 | * (by issuing any IO WQEs on this exchange yet) | 1057 | * (by issuing any IO WQEs on this exchange yet) |
| @@ -946,11 +1118,9 @@ lpfc_nvmet_defer_rcv(struct nvmet_fc_target_port *tgtport, | |||
| 946 | 1118 | ||
| 947 | tgtp = phba->targetport->private; | 1119 | tgtp = phba->targetport->private; |
| 948 | atomic_inc(&tgtp->rcv_fcp_cmd_defer); | 1120 | atomic_inc(&tgtp->rcv_fcp_cmd_defer); |
| 949 | if (ctxp->flag & LPFC_NVMET_DEFER_RCV_REPOST) | 1121 | |
| 950 | lpfc_rq_buf_free(phba, &nvmebuf->hbuf); /* repost */ | 1122 | /* Free the nvmebuf since a new buffer already replaced it */ |
| 951 | else | 1123 | nvmebuf->hrq->rqbp->rqb_free_buffer(phba, nvmebuf); |
| 952 | nvmebuf->hrq->rqbp->rqb_free_buffer(phba, nvmebuf); | ||
| 953 | ctxp->flag &= ~LPFC_NVMET_DEFER_RCV_REPOST; | ||
| 954 | } | 1124 | } |
| 955 | 1125 | ||
| 956 | static struct nvmet_fc_target_template lpfc_tgttemplate = { | 1126 | static struct nvmet_fc_target_template lpfc_tgttemplate = { |
| @@ -1124,16 +1294,10 @@ lpfc_nvmet_setup_io_context(struct lpfc_hba *phba) | |||
| 1124 | } | 1294 | } |
| 1125 | ctx_buf->iocbq->iocb_flag = LPFC_IO_NVMET; | 1295 | ctx_buf->iocbq->iocb_flag = LPFC_IO_NVMET; |
| 1126 | nvmewqe = ctx_buf->iocbq; | 1296 | nvmewqe = ctx_buf->iocbq; |
| 1127 | wqe = (union lpfc_wqe128 *)&nvmewqe->wqe; | 1297 | wqe = &nvmewqe->wqe; |
| 1298 | |||
| 1128 | /* Initialize WQE */ | 1299 | /* Initialize WQE */ |
| 1129 | memset(wqe, 0, sizeof(union lpfc_wqe)); | 1300 | memset(wqe, 0, sizeof(union lpfc_wqe)); |
| 1130 | /* Word 7 */ | ||
| 1131 | bf_set(wqe_ct, &wqe->generic.wqe_com, SLI4_CT_RPI); | ||
| 1132 | bf_set(wqe_class, &wqe->generic.wqe_com, CLASS3); | ||
| 1133 | /* Word 10 */ | ||
| 1134 | bf_set(wqe_nvme, &wqe->fcp_tsend.wqe_com, 1); | ||
| 1135 | bf_set(wqe_ebde_cnt, &wqe->generic.wqe_com, 0); | ||
| 1136 | bf_set(wqe_qosd, &wqe->generic.wqe_com, 0); | ||
| 1137 | 1301 | ||
| 1138 | ctx_buf->iocbq->context1 = NULL; | 1302 | ctx_buf->iocbq->context1 = NULL; |
| 1139 | spin_lock(&phba->sli4_hba.sgl_list_lock); | 1303 | spin_lock(&phba->sli4_hba.sgl_list_lock); |
| @@ -1280,6 +1444,9 @@ lpfc_nvmet_create_targetport(struct lpfc_hba *phba) | |||
| 1280 | atomic_set(&tgtp->xmt_abort_sol, 0); | 1444 | atomic_set(&tgtp->xmt_abort_sol, 0); |
| 1281 | atomic_set(&tgtp->xmt_abort_rsp, 0); | 1445 | atomic_set(&tgtp->xmt_abort_rsp, 0); |
| 1282 | atomic_set(&tgtp->xmt_abort_rsp_error, 0); | 1446 | atomic_set(&tgtp->xmt_abort_rsp_error, 0); |
| 1447 | atomic_set(&tgtp->defer_ctx, 0); | ||
| 1448 | atomic_set(&tgtp->defer_fod, 0); | ||
| 1449 | atomic_set(&tgtp->defer_wqfull, 0); | ||
| 1283 | } | 1450 | } |
| 1284 | return error; | 1451 | return error; |
| 1285 | } | 1452 | } |
| @@ -1435,16 +1602,103 @@ lpfc_nvmet_rcv_unsol_abort(struct lpfc_vport *vport, | |||
| 1435 | return 0; | 1602 | return 0; |
| 1436 | } | 1603 | } |
| 1437 | 1604 | ||
| 1605 | static void | ||
| 1606 | lpfc_nvmet_wqfull_flush(struct lpfc_hba *phba, struct lpfc_queue *wq, | ||
| 1607 | struct lpfc_nvmet_rcv_ctx *ctxp) | ||
| 1608 | { | ||
| 1609 | struct lpfc_sli_ring *pring; | ||
| 1610 | struct lpfc_iocbq *nvmewqeq; | ||
| 1611 | struct lpfc_iocbq *next_nvmewqeq; | ||
| 1612 | unsigned long iflags; | ||
| 1613 | struct lpfc_wcqe_complete wcqe; | ||
| 1614 | struct lpfc_wcqe_complete *wcqep; | ||
| 1615 | |||
| 1616 | pring = wq->pring; | ||
| 1617 | wcqep = &wcqe; | ||
| 1618 | |||
| 1619 | /* Fake an ABORT error code back to cmpl routine */ | ||
| 1620 | memset(wcqep, 0, sizeof(struct lpfc_wcqe_complete)); | ||
| 1621 | bf_set(lpfc_wcqe_c_status, wcqep, IOSTAT_LOCAL_REJECT); | ||
| 1622 | wcqep->parameter = IOERR_ABORT_REQUESTED; | ||
| 1623 | |||
| 1624 | spin_lock_irqsave(&pring->ring_lock, iflags); | ||
| 1625 | list_for_each_entry_safe(nvmewqeq, next_nvmewqeq, | ||
| 1626 | &wq->wqfull_list, list) { | ||
| 1627 | if (ctxp) { | ||
| 1628 | /* Checking for a specific IO to flush */ | ||
| 1629 | if (nvmewqeq->context2 == ctxp) { | ||
| 1630 | list_del(&nvmewqeq->list); | ||
| 1631 | spin_unlock_irqrestore(&pring->ring_lock, | ||
| 1632 | iflags); | ||
| 1633 | lpfc_nvmet_xmt_fcp_op_cmp(phba, nvmewqeq, | ||
| 1634 | wcqep); | ||
| 1635 | return; | ||
| 1636 | } | ||
| 1637 | continue; | ||
| 1638 | } else { | ||
| 1639 | /* Flush all IOs */ | ||
| 1640 | list_del(&nvmewqeq->list); | ||
| 1641 | spin_unlock_irqrestore(&pring->ring_lock, iflags); | ||
| 1642 | lpfc_nvmet_xmt_fcp_op_cmp(phba, nvmewqeq, wcqep); | ||
| 1643 | spin_lock_irqsave(&pring->ring_lock, iflags); | ||
| 1644 | } | ||
| 1645 | } | ||
| 1646 | if (!ctxp) | ||
| 1647 | wq->q_flag &= ~HBA_NVMET_WQFULL; | ||
| 1648 | spin_unlock_irqrestore(&pring->ring_lock, iflags); | ||
| 1649 | } | ||
| 1650 | |||
| 1651 | void | ||
| 1652 | lpfc_nvmet_wqfull_process(struct lpfc_hba *phba, | ||
| 1653 | struct lpfc_queue *wq) | ||
| 1654 | { | ||
| 1655 | #if (IS_ENABLED(CONFIG_NVME_TARGET_FC)) | ||
| 1656 | struct lpfc_sli_ring *pring; | ||
| 1657 | struct lpfc_iocbq *nvmewqeq; | ||
| 1658 | unsigned long iflags; | ||
| 1659 | int rc; | ||
| 1660 | |||
| 1661 | /* | ||
| 1662 | * Some WQE slots are available, so try to re-issue anything | ||
| 1663 | * on the WQ wqfull_list. | ||
| 1664 | */ | ||
| 1665 | pring = wq->pring; | ||
| 1666 | spin_lock_irqsave(&pring->ring_lock, iflags); | ||
| 1667 | while (!list_empty(&wq->wqfull_list)) { | ||
| 1668 | list_remove_head(&wq->wqfull_list, nvmewqeq, struct lpfc_iocbq, | ||
| 1669 | list); | ||
| 1670 | spin_unlock_irqrestore(&pring->ring_lock, iflags); | ||
| 1671 | rc = lpfc_sli4_issue_wqe(phba, LPFC_FCP_RING, nvmewqeq); | ||
| 1672 | spin_lock_irqsave(&pring->ring_lock, iflags); | ||
| 1673 | if (rc == -EBUSY) { | ||
| 1674 | /* WQ was full again, so put it back on the list */ | ||
| 1675 | list_add(&nvmewqeq->list, &wq->wqfull_list); | ||
| 1676 | spin_unlock_irqrestore(&pring->ring_lock, iflags); | ||
| 1677 | return; | ||
| 1678 | } | ||
| 1679 | } | ||
| 1680 | wq->q_flag &= ~HBA_NVMET_WQFULL; | ||
| 1681 | spin_unlock_irqrestore(&pring->ring_lock, iflags); | ||
| 1682 | |||
| 1683 | #endif | ||
| 1684 | } | ||
| 1685 | |||
| 1438 | void | 1686 | void |
| 1439 | lpfc_nvmet_destroy_targetport(struct lpfc_hba *phba) | 1687 | lpfc_nvmet_destroy_targetport(struct lpfc_hba *phba) |
| 1440 | { | 1688 | { |
| 1441 | #if (IS_ENABLED(CONFIG_NVME_TARGET_FC)) | 1689 | #if (IS_ENABLED(CONFIG_NVME_TARGET_FC)) |
| 1442 | struct lpfc_nvmet_tgtport *tgtp; | 1690 | struct lpfc_nvmet_tgtport *tgtp; |
| 1691 | struct lpfc_queue *wq; | ||
| 1692 | uint32_t qidx; | ||
| 1443 | 1693 | ||
| 1444 | if (phba->nvmet_support == 0) | 1694 | if (phba->nvmet_support == 0) |
| 1445 | return; | 1695 | return; |
| 1446 | if (phba->targetport) { | 1696 | if (phba->targetport) { |
| 1447 | tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private; | 1697 | tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private; |
| 1698 | for (qidx = 0; qidx < phba->cfg_nvme_io_channel; qidx++) { | ||
| 1699 | wq = phba->sli4_hba.nvme_wq[qidx]; | ||
| 1700 | lpfc_nvmet_wqfull_flush(phba, wq, NULL); | ||
| 1701 | } | ||
| 1448 | init_completion(&tgtp->tport_unreg_done); | 1702 | init_completion(&tgtp->tport_unreg_done); |
| 1449 | nvmet_fc_unregister_targetport(phba->targetport); | 1703 | nvmet_fc_unregister_targetport(phba->targetport); |
| 1450 | wait_for_completion_timeout(&tgtp->tport_unreg_done, 5); | 1704 | wait_for_completion_timeout(&tgtp->tport_unreg_done, 5); |
| @@ -1694,6 +1948,8 @@ lpfc_nvmet_unsol_fcp_buffer(struct lpfc_hba *phba, | |||
| 1694 | lpfc_nvmeio_data(phba, "NVMET FCP RCV: xri x%x sz %d CPU %02x\n", | 1948 | lpfc_nvmeio_data(phba, "NVMET FCP RCV: xri x%x sz %d CPU %02x\n", |
| 1695 | oxid, size, smp_processor_id()); | 1949 | oxid, size, smp_processor_id()); |
| 1696 | 1950 | ||
| 1951 | tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private; | ||
| 1952 | |||
| 1697 | if (!ctx_buf) { | 1953 | if (!ctx_buf) { |
| 1698 | /* Queue this NVME IO to process later */ | 1954 | /* Queue this NVME IO to process later */ |
| 1699 | spin_lock_irqsave(&phba->sli4_hba.nvmet_io_wait_lock, iflag); | 1955 | spin_lock_irqsave(&phba->sli4_hba.nvmet_io_wait_lock, iflag); |
| @@ -1709,10 +1965,11 @@ lpfc_nvmet_unsol_fcp_buffer(struct lpfc_hba *phba, | |||
| 1709 | lpfc_post_rq_buffer( | 1965 | lpfc_post_rq_buffer( |
| 1710 | phba, phba->sli4_hba.nvmet_mrq_hdr[qno], | 1966 | phba, phba->sli4_hba.nvmet_mrq_hdr[qno], |
| 1711 | phba->sli4_hba.nvmet_mrq_data[qno], 1, qno); | 1967 | phba->sli4_hba.nvmet_mrq_data[qno], 1, qno); |
| 1968 | |||
| 1969 | atomic_inc(&tgtp->defer_ctx); | ||
| 1712 | return; | 1970 | return; |
| 1713 | } | 1971 | } |
| 1714 | 1972 | ||
| 1715 | tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private; | ||
| 1716 | payload = (uint32_t *)(nvmebuf->dbuf.virt); | 1973 | payload = (uint32_t *)(nvmebuf->dbuf.virt); |
| 1717 | sid = sli4_sid_from_fc_hdr(fc_hdr); | 1974 | sid = sli4_sid_from_fc_hdr(fc_hdr); |
| 1718 | 1975 | ||
| @@ -1776,12 +2033,20 @@ lpfc_nvmet_unsol_fcp_buffer(struct lpfc_hba *phba, | |||
| 1776 | 2033 | ||
| 1777 | /* Processing of FCP command is deferred */ | 2034 | /* Processing of FCP command is deferred */ |
| 1778 | if (rc == -EOVERFLOW) { | 2035 | if (rc == -EOVERFLOW) { |
| 2036 | /* | ||
| 2037 | * Post a brand new DMA buffer to RQ and defer | ||
| 2038 | * freeing rcv buffer till .defer_rcv callback | ||
| 2039 | */ | ||
| 2040 | qno = nvmebuf->idx; | ||
| 2041 | lpfc_post_rq_buffer( | ||
| 2042 | phba, phba->sli4_hba.nvmet_mrq_hdr[qno], | ||
| 2043 | phba->sli4_hba.nvmet_mrq_data[qno], 1, qno); | ||
| 2044 | |||
| 1779 | lpfc_nvmeio_data(phba, | 2045 | lpfc_nvmeio_data(phba, |
| 1780 | "NVMET RCV BUSY: xri x%x sz %d from %06x\n", | 2046 | "NVMET RCV BUSY: xri x%x sz %d from %06x\n", |
| 1781 | oxid, size, sid); | 2047 | oxid, size, sid); |
| 1782 | /* defer reposting rcv buffer till .defer_rcv callback */ | ||
| 1783 | ctxp->flag |= LPFC_NVMET_DEFER_RCV_REPOST; | ||
| 1784 | atomic_inc(&tgtp->rcv_fcp_cmd_out); | 2048 | atomic_inc(&tgtp->rcv_fcp_cmd_out); |
| 2049 | atomic_inc(&tgtp->defer_fod); | ||
| 1785 | return; | 2050 | return; |
| 1786 | } | 2051 | } |
| 1787 | ctxp->rqb_buffer = nvmebuf; | 2052 | ctxp->rqb_buffer = nvmebuf; |
| @@ -1897,7 +2162,7 @@ lpfc_nvmet_prep_ls_wqe(struct lpfc_hba *phba, | |||
| 1897 | { | 2162 | { |
| 1898 | struct lpfc_nodelist *ndlp; | 2163 | struct lpfc_nodelist *ndlp; |
| 1899 | struct lpfc_iocbq *nvmewqe; | 2164 | struct lpfc_iocbq *nvmewqe; |
| 1900 | union lpfc_wqe *wqe; | 2165 | union lpfc_wqe128 *wqe; |
| 1901 | 2166 | ||
| 1902 | if (!lpfc_is_link_up(phba)) { | 2167 | if (!lpfc_is_link_up(phba)) { |
| 1903 | lpfc_printf_log(phba, KERN_ERR, LOG_NVME_DISC, | 2168 | lpfc_printf_log(phba, KERN_ERR, LOG_NVME_DISC, |
| @@ -2023,9 +2288,11 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, | |||
| 2023 | struct lpfc_iocbq *nvmewqe; | 2288 | struct lpfc_iocbq *nvmewqe; |
| 2024 | struct scatterlist *sgel; | 2289 | struct scatterlist *sgel; |
| 2025 | union lpfc_wqe128 *wqe; | 2290 | union lpfc_wqe128 *wqe; |
| 2291 | struct ulp_bde64 *bde; | ||
| 2026 | uint32_t *txrdy; | 2292 | uint32_t *txrdy; |
| 2027 | dma_addr_t physaddr; | 2293 | dma_addr_t physaddr; |
| 2028 | int i, cnt; | 2294 | int i, cnt; |
| 2295 | int do_pbde; | ||
| 2029 | int xc = 1; | 2296 | int xc = 1; |
| 2030 | 2297 | ||
| 2031 | if (!lpfc_is_link_up(phba)) { | 2298 | if (!lpfc_is_link_up(phba)) { |
| @@ -2078,7 +2345,7 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, | |||
| 2078 | if (((ctxp->state == LPFC_NVMET_STE_RCV) && | 2345 | if (((ctxp->state == LPFC_NVMET_STE_RCV) && |
| 2079 | (ctxp->entry_cnt == 1)) || | 2346 | (ctxp->entry_cnt == 1)) || |
| 2080 | (ctxp->state == LPFC_NVMET_STE_DATA)) { | 2347 | (ctxp->state == LPFC_NVMET_STE_DATA)) { |
| 2081 | wqe = (union lpfc_wqe128 *)&nvmewqe->wqe; | 2348 | wqe = &nvmewqe->wqe; |
| 2082 | } else { | 2349 | } else { |
| 2083 | lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR, | 2350 | lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR, |
| 2084 | "6111 Wrong state NVMET FCP: %d cnt %d\n", | 2351 | "6111 Wrong state NVMET FCP: %d cnt %d\n", |
| @@ -2090,6 +2357,11 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, | |||
| 2090 | switch (rsp->op) { | 2357 | switch (rsp->op) { |
| 2091 | case NVMET_FCOP_READDATA: | 2358 | case NVMET_FCOP_READDATA: |
| 2092 | case NVMET_FCOP_READDATA_RSP: | 2359 | case NVMET_FCOP_READDATA_RSP: |
| 2360 | /* From the tsend template, initialize words 7 - 11 */ | ||
| 2361 | memcpy(&wqe->words[7], | ||
| 2362 | &lpfc_tsend_cmd_template.words[7], | ||
| 2363 | sizeof(uint32_t) * 5); | ||
| 2364 | |||
| 2093 | /* Words 0 - 2 : The first sg segment */ | 2365 | /* Words 0 - 2 : The first sg segment */ |
| 2094 | sgel = &rsp->sg[0]; | 2366 | sgel = &rsp->sg[0]; |
| 2095 | physaddr = sg_dma_address(sgel); | 2367 | physaddr = sg_dma_address(sgel); |
| @@ -2106,6 +2378,7 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, | |||
| 2106 | wqe->fcp_tsend.relative_offset = ctxp->offset; | 2378 | wqe->fcp_tsend.relative_offset = ctxp->offset; |
| 2107 | 2379 | ||
| 2108 | /* Word 5 */ | 2380 | /* Word 5 */ |
| 2381 | wqe->fcp_tsend.reserved = 0; | ||
| 2109 | 2382 | ||
| 2110 | /* Word 6 */ | 2383 | /* Word 6 */ |
| 2111 | bf_set(wqe_ctxt_tag, &wqe->fcp_tsend.wqe_com, | 2384 | bf_set(wqe_ctxt_tag, &wqe->fcp_tsend.wqe_com, |
| @@ -2113,9 +2386,7 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, | |||
| 2113 | bf_set(wqe_xri_tag, &wqe->fcp_tsend.wqe_com, | 2386 | bf_set(wqe_xri_tag, &wqe->fcp_tsend.wqe_com, |
| 2114 | nvmewqe->sli4_xritag); | 2387 | nvmewqe->sli4_xritag); |
| 2115 | 2388 | ||
| 2116 | /* Word 7 */ | 2389 | /* Word 7 - set ar later */ |
| 2117 | bf_set(wqe_pu, &wqe->fcp_tsend.wqe_com, 1); | ||
| 2118 | bf_set(wqe_cmnd, &wqe->fcp_tsend.wqe_com, CMD_FCP_TSEND64_WQE); | ||
| 2119 | 2390 | ||
| 2120 | /* Word 8 */ | 2391 | /* Word 8 */ |
| 2121 | wqe->fcp_tsend.wqe_com.abort_tag = nvmewqe->iotag; | 2392 | wqe->fcp_tsend.wqe_com.abort_tag = nvmewqe->iotag; |
| @@ -2124,23 +2395,12 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, | |||
| 2124 | bf_set(wqe_reqtag, &wqe->fcp_tsend.wqe_com, nvmewqe->iotag); | 2395 | bf_set(wqe_reqtag, &wqe->fcp_tsend.wqe_com, nvmewqe->iotag); |
| 2125 | bf_set(wqe_rcvoxid, &wqe->fcp_tsend.wqe_com, ctxp->oxid); | 2396 | bf_set(wqe_rcvoxid, &wqe->fcp_tsend.wqe_com, ctxp->oxid); |
| 2126 | 2397 | ||
| 2127 | /* Word 10 */ | 2398 | /* Word 10 - set wqes later, in template xc=1 */ |
| 2128 | bf_set(wqe_nvme, &wqe->fcp_tsend.wqe_com, 1); | 2399 | if (!xc) |
| 2129 | bf_set(wqe_dbde, &wqe->fcp_tsend.wqe_com, 1); | 2400 | bf_set(wqe_xc, &wqe->fcp_tsend.wqe_com, 0); |
| 2130 | bf_set(wqe_iod, &wqe->fcp_tsend.wqe_com, LPFC_WQE_IOD_WRITE); | ||
| 2131 | bf_set(wqe_lenloc, &wqe->fcp_tsend.wqe_com, | ||
| 2132 | LPFC_WQE_LENLOC_WORD12); | ||
| 2133 | bf_set(wqe_ebde_cnt, &wqe->fcp_tsend.wqe_com, 0); | ||
| 2134 | bf_set(wqe_xc, &wqe->fcp_tsend.wqe_com, xc); | ||
| 2135 | bf_set(wqe_nvme, &wqe->fcp_tsend.wqe_com, 1); | ||
| 2136 | if (phba->cfg_nvme_oas) | ||
| 2137 | bf_set(wqe_oas, &wqe->fcp_tsend.wqe_com, 1); | ||
| 2138 | 2401 | ||
| 2139 | /* Word 11 */ | 2402 | /* Word 11 - set sup, irsp, irsplen later */ |
| 2140 | bf_set(wqe_cqid, &wqe->fcp_tsend.wqe_com, | 2403 | do_pbde = 0; |
| 2141 | LPFC_WQE_CQ_ID_DEFAULT); | ||
| 2142 | bf_set(wqe_cmd_type, &wqe->fcp_tsend.wqe_com, | ||
| 2143 | FCP_COMMAND_TSEND); | ||
| 2144 | 2404 | ||
| 2145 | /* Word 12 */ | 2405 | /* Word 12 */ |
| 2146 | wqe->fcp_tsend.fcp_data_len = rsp->transfer_length; | 2406 | wqe->fcp_tsend.fcp_data_len = rsp->transfer_length; |
| @@ -2162,15 +2422,14 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, | |||
| 2162 | sgl++; | 2422 | sgl++; |
| 2163 | if (rsp->op == NVMET_FCOP_READDATA_RSP) { | 2423 | if (rsp->op == NVMET_FCOP_READDATA_RSP) { |
| 2164 | atomic_inc(&tgtp->xmt_fcp_read_rsp); | 2424 | atomic_inc(&tgtp->xmt_fcp_read_rsp); |
| 2165 | bf_set(wqe_ar, &wqe->fcp_tsend.wqe_com, 1); | 2425 | |
| 2166 | if ((ndlp->nlp_flag & NLP_SUPPRESS_RSP) && | 2426 | /* In template ar=1 wqes=0 sup=0 irsp=0 irsplen=0 */ |
| 2167 | (rsp->rsplen == 12)) { | 2427 | |
| 2168 | bf_set(wqe_sup, &wqe->fcp_tsend.wqe_com, 1); | 2428 | if (rsp->rsplen == LPFC_NVMET_SUCCESS_LEN) { |
| 2169 | bf_set(wqe_wqes, &wqe->fcp_tsend.wqe_com, 0); | 2429 | if (ndlp->nlp_flag & NLP_SUPPRESS_RSP) |
| 2170 | bf_set(wqe_irsp, &wqe->fcp_tsend.wqe_com, 0); | 2430 | bf_set(wqe_sup, |
| 2171 | bf_set(wqe_irsplen, &wqe->fcp_tsend.wqe_com, 0); | 2431 | &wqe->fcp_tsend.wqe_com, 1); |
| 2172 | } else { | 2432 | } else { |
| 2173 | bf_set(wqe_sup, &wqe->fcp_tsend.wqe_com, 0); | ||
| 2174 | bf_set(wqe_wqes, &wqe->fcp_tsend.wqe_com, 1); | 2433 | bf_set(wqe_wqes, &wqe->fcp_tsend.wqe_com, 1); |
| 2175 | bf_set(wqe_irsp, &wqe->fcp_tsend.wqe_com, 1); | 2434 | bf_set(wqe_irsp, &wqe->fcp_tsend.wqe_com, 1); |
| 2176 | bf_set(wqe_irsplen, &wqe->fcp_tsend.wqe_com, | 2435 | bf_set(wqe_irsplen, &wqe->fcp_tsend.wqe_com, |
| @@ -2181,15 +2440,17 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, | |||
| 2181 | } else { | 2440 | } else { |
| 2182 | atomic_inc(&tgtp->xmt_fcp_read); | 2441 | atomic_inc(&tgtp->xmt_fcp_read); |
| 2183 | 2442 | ||
| 2184 | bf_set(wqe_sup, &wqe->fcp_tsend.wqe_com, 0); | 2443 | /* In template ar=1 wqes=0 sup=0 irsp=0 irsplen=0 */ |
| 2185 | bf_set(wqe_wqes, &wqe->fcp_tsend.wqe_com, 0); | ||
| 2186 | bf_set(wqe_irsp, &wqe->fcp_tsend.wqe_com, 0); | ||
| 2187 | bf_set(wqe_ar, &wqe->fcp_tsend.wqe_com, 0); | 2444 | bf_set(wqe_ar, &wqe->fcp_tsend.wqe_com, 0); |
| 2188 | bf_set(wqe_irsplen, &wqe->fcp_tsend.wqe_com, 0); | ||
| 2189 | } | 2445 | } |
| 2190 | break; | 2446 | break; |
| 2191 | 2447 | ||
| 2192 | case NVMET_FCOP_WRITEDATA: | 2448 | case NVMET_FCOP_WRITEDATA: |
| 2449 | /* From the treceive template, initialize words 3 - 11 */ | ||
| 2450 | memcpy(&wqe->words[3], | ||
| 2451 | &lpfc_treceive_cmd_template.words[3], | ||
| 2452 | sizeof(uint32_t) * 9); | ||
| 2453 | |||
| 2193 | /* Words 0 - 2 : The first sg segment */ | 2454 | /* Words 0 - 2 : The first sg segment */ |
| 2194 | txrdy = dma_pool_alloc(phba->txrdy_payload_pool, | 2455 | txrdy = dma_pool_alloc(phba->txrdy_payload_pool, |
| 2195 | GFP_KERNEL, &physaddr); | 2456 | GFP_KERNEL, &physaddr); |
| @@ -2208,14 +2469,9 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, | |||
| 2208 | wqe->fcp_treceive.bde.addrHigh = | 2469 | wqe->fcp_treceive.bde.addrHigh = |
| 2209 | cpu_to_le32(putPaddrHigh(physaddr)); | 2470 | cpu_to_le32(putPaddrHigh(physaddr)); |
| 2210 | 2471 | ||
| 2211 | /* Word 3 */ | ||
| 2212 | wqe->fcp_treceive.payload_offset_len = TXRDY_PAYLOAD_LEN; | ||
| 2213 | |||
| 2214 | /* Word 4 */ | 2472 | /* Word 4 */ |
| 2215 | wqe->fcp_treceive.relative_offset = ctxp->offset; | 2473 | wqe->fcp_treceive.relative_offset = ctxp->offset; |
| 2216 | 2474 | ||
| 2217 | /* Word 5 */ | ||
| 2218 | |||
| 2219 | /* Word 6 */ | 2475 | /* Word 6 */ |
| 2220 | bf_set(wqe_ctxt_tag, &wqe->fcp_treceive.wqe_com, | 2476 | bf_set(wqe_ctxt_tag, &wqe->fcp_treceive.wqe_com, |
| 2221 | phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]); | 2477 | phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]); |
| @@ -2223,10 +2479,6 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, | |||
| 2223 | nvmewqe->sli4_xritag); | 2479 | nvmewqe->sli4_xritag); |
| 2224 | 2480 | ||
| 2225 | /* Word 7 */ | 2481 | /* Word 7 */ |
| 2226 | bf_set(wqe_pu, &wqe->fcp_treceive.wqe_com, 1); | ||
| 2227 | bf_set(wqe_ar, &wqe->fcp_treceive.wqe_com, 0); | ||
| 2228 | bf_set(wqe_cmnd, &wqe->fcp_treceive.wqe_com, | ||
| 2229 | CMD_FCP_TRECEIVE64_WQE); | ||
| 2230 | 2482 | ||
| 2231 | /* Word 8 */ | 2483 | /* Word 8 */ |
| 2232 | wqe->fcp_treceive.wqe_com.abort_tag = nvmewqe->iotag; | 2484 | wqe->fcp_treceive.wqe_com.abort_tag = nvmewqe->iotag; |
| @@ -2235,26 +2487,17 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, | |||
| 2235 | bf_set(wqe_reqtag, &wqe->fcp_treceive.wqe_com, nvmewqe->iotag); | 2487 | bf_set(wqe_reqtag, &wqe->fcp_treceive.wqe_com, nvmewqe->iotag); |
| 2236 | bf_set(wqe_rcvoxid, &wqe->fcp_treceive.wqe_com, ctxp->oxid); | 2488 | bf_set(wqe_rcvoxid, &wqe->fcp_treceive.wqe_com, ctxp->oxid); |
| 2237 | 2489 | ||
| 2238 | /* Word 10 */ | 2490 | /* Word 10 - in template xc=1 */ |
| 2239 | bf_set(wqe_nvme, &wqe->fcp_treceive.wqe_com, 1); | 2491 | if (!xc) |
| 2240 | bf_set(wqe_dbde, &wqe->fcp_treceive.wqe_com, 1); | 2492 | bf_set(wqe_xc, &wqe->fcp_treceive.wqe_com, 0); |
| 2241 | bf_set(wqe_iod, &wqe->fcp_treceive.wqe_com, LPFC_WQE_IOD_READ); | ||
| 2242 | bf_set(wqe_lenloc, &wqe->fcp_treceive.wqe_com, | ||
| 2243 | LPFC_WQE_LENLOC_WORD12); | ||
| 2244 | bf_set(wqe_xc, &wqe->fcp_treceive.wqe_com, xc); | ||
| 2245 | bf_set(wqe_wqes, &wqe->fcp_treceive.wqe_com, 0); | ||
| 2246 | bf_set(wqe_irsp, &wqe->fcp_treceive.wqe_com, 0); | ||
| 2247 | bf_set(wqe_irsplen, &wqe->fcp_treceive.wqe_com, 0); | ||
| 2248 | bf_set(wqe_nvme, &wqe->fcp_treceive.wqe_com, 1); | ||
| 2249 | if (phba->cfg_nvme_oas) | ||
| 2250 | bf_set(wqe_oas, &wqe->fcp_treceive.wqe_com, 1); | ||
| 2251 | 2493 | ||
| 2252 | /* Word 11 */ | 2494 | /* Word 11 - set pbde later */ |
| 2253 | bf_set(wqe_cqid, &wqe->fcp_treceive.wqe_com, | 2495 | if (phba->nvme_embed_pbde) { |
| 2254 | LPFC_WQE_CQ_ID_DEFAULT); | 2496 | do_pbde = 1; |
| 2255 | bf_set(wqe_cmd_type, &wqe->fcp_treceive.wqe_com, | 2497 | } else { |
| 2256 | FCP_COMMAND_TRECEIVE); | 2498 | bf_set(wqe_pbde, &wqe->fcp_treceive.wqe_com, 0); |
| 2257 | bf_set(wqe_sup, &wqe->fcp_tsend.wqe_com, 0); | 2499 | do_pbde = 0; |
| 2500 | } | ||
| 2258 | 2501 | ||
| 2259 | /* Word 12 */ | 2502 | /* Word 12 */ |
| 2260 | wqe->fcp_tsend.fcp_data_len = rsp->transfer_length; | 2503 | wqe->fcp_tsend.fcp_data_len = rsp->transfer_length; |
| @@ -2282,6 +2525,11 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, | |||
| 2282 | break; | 2525 | break; |
| 2283 | 2526 | ||
| 2284 | case NVMET_FCOP_RSP: | 2527 | case NVMET_FCOP_RSP: |
| 2528 | /* From the treceive template, initialize words 4 - 11 */ | ||
| 2529 | memcpy(&wqe->words[4], | ||
| 2530 | &lpfc_trsp_cmd_template.words[4], | ||
| 2531 | sizeof(uint32_t) * 8); | ||
| 2532 | |||
| 2285 | /* Words 0 - 2 */ | 2533 | /* Words 0 - 2 */ |
| 2286 | physaddr = rsp->rspdma; | 2534 | physaddr = rsp->rspdma; |
| 2287 | wqe->fcp_trsp.bde.tus.f.bdeFlags = BUFF_TYPE_BDE_64; | 2535 | wqe->fcp_trsp.bde.tus.f.bdeFlags = BUFF_TYPE_BDE_64; |
| @@ -2294,12 +2542,6 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, | |||
| 2294 | /* Word 3 */ | 2542 | /* Word 3 */ |
| 2295 | wqe->fcp_trsp.response_len = rsp->rsplen; | 2543 | wqe->fcp_trsp.response_len = rsp->rsplen; |
| 2296 | 2544 | ||
| 2297 | /* Word 4 */ | ||
| 2298 | wqe->fcp_trsp.rsvd_4_5[0] = 0; | ||
| 2299 | |||
| 2300 | |||
| 2301 | /* Word 5 */ | ||
| 2302 | |||
| 2303 | /* Word 6 */ | 2545 | /* Word 6 */ |
| 2304 | bf_set(wqe_ctxt_tag, &wqe->fcp_trsp.wqe_com, | 2546 | bf_set(wqe_ctxt_tag, &wqe->fcp_trsp.wqe_com, |
| 2305 | phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]); | 2547 | phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]); |
| @@ -2307,9 +2549,6 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, | |||
| 2307 | nvmewqe->sli4_xritag); | 2549 | nvmewqe->sli4_xritag); |
| 2308 | 2550 | ||
| 2309 | /* Word 7 */ | 2551 | /* Word 7 */ |
| 2310 | bf_set(wqe_pu, &wqe->fcp_trsp.wqe_com, 0); | ||
| 2311 | bf_set(wqe_ag, &wqe->fcp_trsp.wqe_com, 1); | ||
| 2312 | bf_set(wqe_cmnd, &wqe->fcp_trsp.wqe_com, CMD_FCP_TRSP64_WQE); | ||
| 2313 | 2552 | ||
| 2314 | /* Word 8 */ | 2553 | /* Word 8 */ |
| 2315 | wqe->fcp_trsp.wqe_com.abort_tag = nvmewqe->iotag; | 2554 | wqe->fcp_trsp.wqe_com.abort_tag = nvmewqe->iotag; |
| @@ -2319,35 +2558,23 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, | |||
| 2319 | bf_set(wqe_rcvoxid, &wqe->fcp_trsp.wqe_com, ctxp->oxid); | 2558 | bf_set(wqe_rcvoxid, &wqe->fcp_trsp.wqe_com, ctxp->oxid); |
| 2320 | 2559 | ||
| 2321 | /* Word 10 */ | 2560 | /* Word 10 */ |
| 2322 | bf_set(wqe_nvme, &wqe->fcp_trsp.wqe_com, 1); | 2561 | if (xc) |
| 2323 | bf_set(wqe_dbde, &wqe->fcp_trsp.wqe_com, 0); | 2562 | bf_set(wqe_xc, &wqe->fcp_trsp.wqe_com, 1); |
| 2324 | bf_set(wqe_iod, &wqe->fcp_trsp.wqe_com, LPFC_WQE_IOD_WRITE); | ||
| 2325 | bf_set(wqe_lenloc, &wqe->fcp_trsp.wqe_com, | ||
| 2326 | LPFC_WQE_LENLOC_WORD3); | ||
| 2327 | bf_set(wqe_xc, &wqe->fcp_trsp.wqe_com, xc); | ||
| 2328 | bf_set(wqe_nvme, &wqe->fcp_trsp.wqe_com, 1); | ||
| 2329 | if (phba->cfg_nvme_oas) | ||
| 2330 | bf_set(wqe_oas, &wqe->fcp_trsp.wqe_com, 1); | ||
| 2331 | 2563 | ||
| 2332 | /* Word 11 */ | 2564 | /* Word 11 */ |
| 2333 | bf_set(wqe_cqid, &wqe->fcp_trsp.wqe_com, | 2565 | /* In template wqes=0 irsp=0 irsplen=0 - good response */ |
| 2334 | LPFC_WQE_CQ_ID_DEFAULT); | 2566 | if (rsp->rsplen != LPFC_NVMET_SUCCESS_LEN) { |
| 2335 | bf_set(wqe_cmd_type, &wqe->fcp_trsp.wqe_com, | 2567 | /* Bad response - embed it */ |
| 2336 | FCP_COMMAND_TRSP); | ||
| 2337 | bf_set(wqe_sup, &wqe->fcp_tsend.wqe_com, 0); | ||
| 2338 | |||
| 2339 | if (rsp->rsplen == LPFC_NVMET_SUCCESS_LEN) { | ||
| 2340 | /* Good response - all zero's on wire */ | ||
| 2341 | bf_set(wqe_wqes, &wqe->fcp_trsp.wqe_com, 0); | ||
| 2342 | bf_set(wqe_irsp, &wqe->fcp_trsp.wqe_com, 0); | ||
| 2343 | bf_set(wqe_irsplen, &wqe->fcp_trsp.wqe_com, 0); | ||
| 2344 | } else { | ||
| 2345 | bf_set(wqe_wqes, &wqe->fcp_trsp.wqe_com, 1); | 2568 | bf_set(wqe_wqes, &wqe->fcp_trsp.wqe_com, 1); |
| 2346 | bf_set(wqe_irsp, &wqe->fcp_trsp.wqe_com, 1); | 2569 | bf_set(wqe_irsp, &wqe->fcp_trsp.wqe_com, 1); |
| 2347 | bf_set(wqe_irsplen, &wqe->fcp_trsp.wqe_com, | 2570 | bf_set(wqe_irsplen, &wqe->fcp_trsp.wqe_com, |
| 2348 | ((rsp->rsplen >> 2) - 1)); | 2571 | ((rsp->rsplen >> 2) - 1)); |
| 2349 | memcpy(&wqe->words[16], rsp->rspaddr, rsp->rsplen); | 2572 | memcpy(&wqe->words[16], rsp->rspaddr, rsp->rsplen); |
| 2350 | } | 2573 | } |
| 2574 | do_pbde = 0; | ||
| 2575 | |||
| 2576 | /* Word 12 */ | ||
| 2577 | wqe->fcp_trsp.rsvd_12_15[0] = 0; | ||
| 2351 | 2578 | ||
| 2352 | /* Use rspbuf, NOT sg list */ | 2579 | /* Use rspbuf, NOT sg list */ |
| 2353 | rsp->sg_cnt = 0; | 2580 | rsp->sg_cnt = 0; |
| @@ -2380,6 +2607,17 @@ lpfc_nvmet_prep_fcp_wqe(struct lpfc_hba *phba, | |||
| 2380 | bf_set(lpfc_sli4_sge_last, sgl, 1); | 2607 | bf_set(lpfc_sli4_sge_last, sgl, 1); |
| 2381 | sgl->word2 = cpu_to_le32(sgl->word2); | 2608 | sgl->word2 = cpu_to_le32(sgl->word2); |
| 2382 | sgl->sge_len = cpu_to_le32(cnt); | 2609 | sgl->sge_len = cpu_to_le32(cnt); |
| 2610 | if (do_pbde && i == 0) { | ||
| 2611 | bde = (struct ulp_bde64 *)&wqe->words[13]; | ||
| 2612 | memset(bde, 0, sizeof(struct ulp_bde64)); | ||
| 2613 | /* Words 13-15 (PBDE)*/ | ||
| 2614 | bde->addrLow = sgl->addr_lo; | ||
| 2615 | bde->addrHigh = sgl->addr_hi; | ||
| 2616 | bde->tus.f.bdeSize = | ||
| 2617 | le32_to_cpu(sgl->sge_len); | ||
| 2618 | bde->tus.f.bdeFlags = BUFF_TYPE_BDE_64; | ||
| 2619 | bde->tus.w = cpu_to_le32(bde->tus.w); | ||
| 2620 | } | ||
| 2383 | sgl++; | 2621 | sgl++; |
| 2384 | ctxp->offset += cnt; | 2622 | ctxp->offset += cnt; |
| 2385 | } | 2623 | } |
| @@ -2597,7 +2835,7 @@ lpfc_nvmet_unsol_issue_abort(struct lpfc_hba *phba, | |||
| 2597 | { | 2835 | { |
| 2598 | struct lpfc_nvmet_tgtport *tgtp; | 2836 | struct lpfc_nvmet_tgtport *tgtp; |
| 2599 | struct lpfc_iocbq *abts_wqeq; | 2837 | struct lpfc_iocbq *abts_wqeq; |
| 2600 | union lpfc_wqe *wqe_abts; | 2838 | union lpfc_wqe128 *wqe_abts; |
| 2601 | struct lpfc_nodelist *ndlp; | 2839 | struct lpfc_nodelist *ndlp; |
| 2602 | 2840 | ||
| 2603 | lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS, | 2841 | lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS, |
| @@ -2692,7 +2930,7 @@ lpfc_nvmet_sol_fcp_issue_abort(struct lpfc_hba *phba, | |||
| 2692 | { | 2930 | { |
| 2693 | struct lpfc_nvmet_tgtport *tgtp; | 2931 | struct lpfc_nvmet_tgtport *tgtp; |
| 2694 | struct lpfc_iocbq *abts_wqeq; | 2932 | struct lpfc_iocbq *abts_wqeq; |
| 2695 | union lpfc_wqe *abts_wqe; | 2933 | union lpfc_wqe128 *abts_wqe; |
| 2696 | struct lpfc_nodelist *ndlp; | 2934 | struct lpfc_nodelist *ndlp; |
| 2697 | unsigned long flags; | 2935 | unsigned long flags; |
| 2698 | int rc; | 2936 | int rc; |
| @@ -2882,7 +3120,7 @@ lpfc_nvmet_unsol_ls_issue_abort(struct lpfc_hba *phba, | |||
| 2882 | { | 3120 | { |
| 2883 | struct lpfc_nvmet_tgtport *tgtp; | 3121 | struct lpfc_nvmet_tgtport *tgtp; |
| 2884 | struct lpfc_iocbq *abts_wqeq; | 3122 | struct lpfc_iocbq *abts_wqeq; |
| 2885 | union lpfc_wqe *wqe_abts; | 3123 | union lpfc_wqe128 *wqe_abts; |
| 2886 | unsigned long flags; | 3124 | unsigned long flags; |
| 2887 | int rc; | 3125 | int rc; |
| 2888 | 3126 | ||
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.h b/drivers/scsi/lpfc/lpfc_nvmet.h index 5b32c9e4d4ef..c1bcef3f103c 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.h +++ b/drivers/scsi/lpfc/lpfc_nvmet.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * | 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -72,7 +72,6 @@ struct lpfc_nvmet_tgtport { | |||
| 72 | atomic_t xmt_fcp_rsp_aborted; | 72 | atomic_t xmt_fcp_rsp_aborted; |
| 73 | atomic_t xmt_fcp_rsp_drop; | 73 | atomic_t xmt_fcp_rsp_drop; |
| 74 | 74 | ||
| 75 | |||
| 76 | /* Stats counters - lpfc_nvmet_xmt_fcp_abort */ | 75 | /* Stats counters - lpfc_nvmet_xmt_fcp_abort */ |
| 77 | atomic_t xmt_fcp_xri_abort_cqe; | 76 | atomic_t xmt_fcp_xri_abort_cqe; |
| 78 | atomic_t xmt_fcp_abort; | 77 | atomic_t xmt_fcp_abort; |
| @@ -81,6 +80,11 @@ struct lpfc_nvmet_tgtport { | |||
| 81 | atomic_t xmt_abort_unsol; | 80 | atomic_t xmt_abort_unsol; |
| 82 | atomic_t xmt_abort_rsp; | 81 | atomic_t xmt_abort_rsp; |
| 83 | atomic_t xmt_abort_rsp_error; | 82 | atomic_t xmt_abort_rsp_error; |
| 83 | |||
| 84 | /* Stats counters - defer IO */ | ||
| 85 | atomic_t defer_ctx; | ||
| 86 | atomic_t defer_fod; | ||
| 87 | atomic_t defer_wqfull; | ||
| 84 | }; | 88 | }; |
| 85 | 89 | ||
| 86 | struct lpfc_nvmet_ctx_info { | 90 | struct lpfc_nvmet_ctx_info { |
| @@ -131,7 +135,7 @@ struct lpfc_nvmet_rcv_ctx { | |||
| 131 | #define LPFC_NVMET_XBUSY 0x4 /* XB bit set on IO cmpl */ | 135 | #define LPFC_NVMET_XBUSY 0x4 /* XB bit set on IO cmpl */ |
| 132 | #define LPFC_NVMET_CTX_RLS 0x8 /* ctx free requested */ | 136 | #define LPFC_NVMET_CTX_RLS 0x8 /* ctx free requested */ |
| 133 | #define LPFC_NVMET_ABTS_RCV 0x10 /* ABTS received on exchange */ | 137 | #define LPFC_NVMET_ABTS_RCV 0x10 /* ABTS received on exchange */ |
| 134 | #define LPFC_NVMET_DEFER_RCV_REPOST 0x20 /* repost to RQ on defer rcv */ | 138 | #define LPFC_NVMET_DEFER_WQFULL 0x40 /* Waiting on a free WQE */ |
| 135 | struct rqb_dmabuf *rqb_buffer; | 139 | struct rqb_dmabuf *rqb_buffer; |
| 136 | struct lpfc_nvmet_ctxbuf *ctxbuf; | 140 | struct lpfc_nvmet_ctxbuf *ctxbuf; |
| 137 | 141 | ||
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index c0cdaef4db24..050f04418f5f 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * | 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -837,8 +837,13 @@ lpfc_new_scsi_buf_s4(struct lpfc_vport *vport, int num_to_alloc) | |||
| 837 | * 4K Page alignment is CRITICAL to BlockGuard, double check | 837 | * 4K Page alignment is CRITICAL to BlockGuard, double check |
| 838 | * to be sure. | 838 | * to be sure. |
| 839 | */ | 839 | */ |
| 840 | if (phba->cfg_enable_bg && (((unsigned long)(psb->data) & | 840 | if ((phba->sli3_options & LPFC_SLI3_BG_ENABLED) && |
| 841 | (((unsigned long)(psb->data) & | ||
| 841 | (unsigned long)(SLI4_PAGE_SIZE - 1)) != 0)) { | 842 | (unsigned long)(SLI4_PAGE_SIZE - 1)) != 0)) { |
| 843 | lpfc_printf_log(phba, KERN_ERR, LOG_FCP, | ||
| 844 | "3369 Memory alignment error " | ||
| 845 | "addr=%lx\n", | ||
| 846 | (unsigned long)psb->data); | ||
| 842 | dma_pool_free(phba->lpfc_sg_dma_buf_pool, | 847 | dma_pool_free(phba->lpfc_sg_dma_buf_pool, |
| 843 | psb->data, psb->dma_handle); | 848 | psb->data, psb->dma_handle); |
| 844 | kfree(psb); | 849 | kfree(psb); |
| @@ -3304,8 +3309,12 @@ lpfc_scsi_prep_dma_buf_s4(struct lpfc_hba *phba, struct lpfc_scsi_buf *lpfc_cmd) | |||
| 3304 | dma_offset += dma_len; | 3309 | dma_offset += dma_len; |
| 3305 | sgl++; | 3310 | sgl++; |
| 3306 | } | 3311 | } |
| 3307 | /* setup the performance hint (first data BDE) if enabled */ | 3312 | /* |
| 3308 | if (phba->sli3_options & LPFC_SLI4_PERFH_ENABLED) { | 3313 | * Setup the first Payload BDE. For FCoE we just key off |
| 3314 | * Performance Hints, for FC we utilize fcp_embed_pbde. | ||
| 3315 | */ | ||
| 3316 | if ((phba->sli3_options & LPFC_SLI4_PERFH_ENABLED) || | ||
| 3317 | phba->fcp_embed_pbde) { | ||
| 3309 | bde = (struct ulp_bde64 *) | 3318 | bde = (struct ulp_bde64 *) |
| 3310 | &(iocb_cmd->unsli3.sli3Words[5]); | 3319 | &(iocb_cmd->unsli3.sli3Words[5]); |
| 3311 | bde->addrLow = first_data_sgl->addr_lo; | 3320 | bde->addrLow = first_data_sgl->addr_lo; |
| @@ -3772,20 +3781,18 @@ lpfc_handle_fcp_err(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd, | |||
| 3772 | scsi_set_resid(cmnd, be32_to_cpu(fcprsp->rspResId)); | 3781 | scsi_set_resid(cmnd, be32_to_cpu(fcprsp->rspResId)); |
| 3773 | 3782 | ||
| 3774 | lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP_UNDER, | 3783 | lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP_UNDER, |
| 3775 | "9025 FCP Read Underrun, expected %d, " | 3784 | "9025 FCP Underrun, expected %d, " |
| 3776 | "residual %d Data: x%x x%x x%x\n", | 3785 | "residual %d Data: x%x x%x x%x\n", |
| 3777 | fcpDl, | 3786 | fcpDl, |
| 3778 | scsi_get_resid(cmnd), fcpi_parm, cmnd->cmnd[0], | 3787 | scsi_get_resid(cmnd), fcpi_parm, cmnd->cmnd[0], |
| 3779 | cmnd->underflow); | 3788 | cmnd->underflow); |
| 3780 | 3789 | ||
| 3781 | /* | 3790 | /* |
| 3782 | * If there is an under run check if under run reported by | 3791 | * If there is an under run, check if under run reported by |
| 3783 | * storage array is same as the under run reported by HBA. | 3792 | * storage array is same as the under run reported by HBA. |
| 3784 | * If this is not same, there is a dropped frame. | 3793 | * If this is not same, there is a dropped frame. |
| 3785 | */ | 3794 | */ |
| 3786 | if ((cmnd->sc_data_direction == DMA_FROM_DEVICE) && | 3795 | if (fcpi_parm && (scsi_get_resid(cmnd) != fcpi_parm)) { |
| 3787 | fcpi_parm && | ||
| 3788 | (scsi_get_resid(cmnd) != fcpi_parm)) { | ||
| 3789 | lpfc_printf_vlog(vport, KERN_WARNING, | 3796 | lpfc_printf_vlog(vport, KERN_WARNING, |
| 3790 | LOG_FCP | LOG_FCP_ERROR, | 3797 | LOG_FCP | LOG_FCP_ERROR, |
| 3791 | "9026 FCP Read Check Error " | 3798 | "9026 FCP Read Check Error " |
| @@ -3926,7 +3933,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
| 3926 | struct lpfc_rport_data *rdata = lpfc_cmd->rdata; | 3933 | struct lpfc_rport_data *rdata = lpfc_cmd->rdata; |
| 3927 | struct lpfc_nodelist *pnode = rdata->pnode; | 3934 | struct lpfc_nodelist *pnode = rdata->pnode; |
| 3928 | struct scsi_cmnd *cmd; | 3935 | struct scsi_cmnd *cmd; |
| 3929 | int depth; | ||
| 3930 | unsigned long flags; | 3936 | unsigned long flags; |
| 3931 | struct lpfc_fast_path_event *fast_path_evt; | 3937 | struct lpfc_fast_path_event *fast_path_evt; |
| 3932 | struct Scsi_Host *shost; | 3938 | struct Scsi_Host *shost; |
| @@ -4132,16 +4138,11 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, | |||
| 4132 | } | 4138 | } |
| 4133 | spin_unlock_irqrestore(shost->host_lock, flags); | 4139 | spin_unlock_irqrestore(shost->host_lock, flags); |
| 4134 | } else if (pnode && NLP_CHK_NODE_ACT(pnode)) { | 4140 | } else if (pnode && NLP_CHK_NODE_ACT(pnode)) { |
| 4135 | if ((pnode->cmd_qdepth < vport->cfg_tgt_queue_depth) && | 4141 | if ((pnode->cmd_qdepth != vport->cfg_tgt_queue_depth) && |
| 4136 | time_after(jiffies, pnode->last_change_time + | 4142 | time_after(jiffies, pnode->last_change_time + |
| 4137 | msecs_to_jiffies(LPFC_TGTQ_INTERVAL))) { | 4143 | msecs_to_jiffies(LPFC_TGTQ_INTERVAL))) { |
| 4138 | spin_lock_irqsave(shost->host_lock, flags); | 4144 | spin_lock_irqsave(shost->host_lock, flags); |
| 4139 | depth = pnode->cmd_qdepth * LPFC_TGTQ_RAMPUP_PCENT | 4145 | pnode->cmd_qdepth = vport->cfg_tgt_queue_depth; |
| 4140 | / 100; | ||
| 4141 | depth = depth ? depth : 1; | ||
| 4142 | pnode->cmd_qdepth += depth; | ||
| 4143 | if (pnode->cmd_qdepth > vport->cfg_tgt_queue_depth) | ||
| 4144 | pnode->cmd_qdepth = vport->cfg_tgt_queue_depth; | ||
| 4145 | pnode->last_change_time = jiffies; | 4146 | pnode->last_change_time = jiffies; |
| 4146 | spin_unlock_irqrestore(shost->host_lock, flags); | 4147 | spin_unlock_irqrestore(shost->host_lock, flags); |
| 4147 | } | 4148 | } |
| @@ -4564,9 +4565,32 @@ lpfc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmnd) | |||
| 4564 | */ | 4565 | */ |
| 4565 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) | 4566 | if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) |
| 4566 | goto out_tgt_busy; | 4567 | goto out_tgt_busy; |
| 4567 | if (atomic_read(&ndlp->cmd_pending) >= ndlp->cmd_qdepth) | 4568 | if (atomic_read(&ndlp->cmd_pending) >= ndlp->cmd_qdepth) { |
| 4569 | lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP_ERROR, | ||
| 4570 | "3377 Target Queue Full, scsi Id:%d Qdepth:%d" | ||
| 4571 | " Pending command:%d" | ||
| 4572 | " WWNN:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, " | ||
| 4573 | " WWPN:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", | ||
| 4574 | ndlp->nlp_sid, ndlp->cmd_qdepth, | ||
| 4575 | atomic_read(&ndlp->cmd_pending), | ||
| 4576 | ndlp->nlp_nodename.u.wwn[0], | ||
| 4577 | ndlp->nlp_nodename.u.wwn[1], | ||
| 4578 | ndlp->nlp_nodename.u.wwn[2], | ||
| 4579 | ndlp->nlp_nodename.u.wwn[3], | ||
| 4580 | ndlp->nlp_nodename.u.wwn[4], | ||
| 4581 | ndlp->nlp_nodename.u.wwn[5], | ||
| 4582 | ndlp->nlp_nodename.u.wwn[6], | ||
| 4583 | ndlp->nlp_nodename.u.wwn[7], | ||
| 4584 | ndlp->nlp_portname.u.wwn[0], | ||
| 4585 | ndlp->nlp_portname.u.wwn[1], | ||
| 4586 | ndlp->nlp_portname.u.wwn[2], | ||
| 4587 | ndlp->nlp_portname.u.wwn[3], | ||
| 4588 | ndlp->nlp_portname.u.wwn[4], | ||
| 4589 | ndlp->nlp_portname.u.wwn[5], | ||
| 4590 | ndlp->nlp_portname.u.wwn[6], | ||
| 4591 | ndlp->nlp_portname.u.wwn[7]); | ||
| 4568 | goto out_tgt_busy; | 4592 | goto out_tgt_busy; |
| 4569 | 4593 | } | |
| 4570 | lpfc_cmd = lpfc_get_scsi_buf(phba, ndlp); | 4594 | lpfc_cmd = lpfc_get_scsi_buf(phba, ndlp); |
| 4571 | if (lpfc_cmd == NULL) { | 4595 | if (lpfc_cmd == NULL) { |
| 4572 | lpfc_rampdown_queue_depth(phba); | 4596 | lpfc_rampdown_queue_depth(phba); |
diff --git a/drivers/scsi/lpfc/lpfc_scsi.h b/drivers/scsi/lpfc/lpfc_scsi.h index 5da7e15400cb..8e38e0204c47 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.h +++ b/drivers/scsi/lpfc/lpfc_scsi.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * | 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 5f5528a12308..cb17e2b2be81 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
| @@ -1,8 +1,7 @@ | |||
| 1 | |||
| 2 | /******************************************************************* | 1 | /******************************************************************* |
| 3 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 4 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 5 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 6 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 7 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * | 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * |
| 8 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -36,6 +35,9 @@ | |||
| 36 | #include <scsi/scsi_transport_fc.h> | 35 | #include <scsi/scsi_transport_fc.h> |
| 37 | #include <scsi/fc/fc_fs.h> | 36 | #include <scsi/fc/fc_fs.h> |
| 38 | #include <linux/aer.h> | 37 | #include <linux/aer.h> |
| 38 | #ifdef CONFIG_X86 | ||
| 39 | #include <asm/set_memory.h> | ||
| 40 | #endif | ||
| 39 | 41 | ||
| 40 | #include <linux/nvme-fc-driver.h> | 42 | #include <linux/nvme-fc-driver.h> |
| 41 | 43 | ||
| @@ -107,12 +109,14 @@ lpfc_get_iocb_from_iocbq(struct lpfc_iocbq *iocbq) | |||
| 107 | * The caller is expected to hold the hbalock when calling this routine. | 109 | * The caller is expected to hold the hbalock when calling this routine. |
| 108 | **/ | 110 | **/ |
| 109 | static int | 111 | static int |
| 110 | lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe) | 112 | lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe128 *wqe) |
| 111 | { | 113 | { |
| 112 | union lpfc_wqe *temp_wqe; | 114 | union lpfc_wqe *temp_wqe; |
| 113 | struct lpfc_register doorbell; | 115 | struct lpfc_register doorbell; |
| 114 | uint32_t host_index; | 116 | uint32_t host_index; |
| 115 | uint32_t idx; | 117 | uint32_t idx; |
| 118 | uint32_t i = 0; | ||
| 119 | uint8_t *tmp; | ||
| 116 | 120 | ||
| 117 | /* sanity check on queue memory */ | 121 | /* sanity check on queue memory */ |
| 118 | if (unlikely(!q)) | 122 | if (unlikely(!q)) |
| @@ -129,10 +133,25 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe) | |||
| 129 | /* set consumption flag every once in a while */ | 133 | /* set consumption flag every once in a while */ |
| 130 | if (!((q->host_index + 1) % q->entry_repost)) | 134 | if (!((q->host_index + 1) % q->entry_repost)) |
| 131 | bf_set(wqe_wqec, &wqe->generic.wqe_com, 1); | 135 | bf_set(wqe_wqec, &wqe->generic.wqe_com, 1); |
| 136 | else | ||
| 137 | bf_set(wqe_wqec, &wqe->generic.wqe_com, 0); | ||
| 132 | if (q->phba->sli3_options & LPFC_SLI4_PHWQ_ENABLED) | 138 | if (q->phba->sli3_options & LPFC_SLI4_PHWQ_ENABLED) |
| 133 | bf_set(wqe_wqid, &wqe->generic.wqe_com, q->queue_id); | 139 | bf_set(wqe_wqid, &wqe->generic.wqe_com, q->queue_id); |
| 134 | lpfc_sli_pcimem_bcopy(wqe, temp_wqe, q->entry_size); | 140 | lpfc_sli_pcimem_bcopy(wqe, temp_wqe, q->entry_size); |
| 135 | /* ensure WQE bcopy flushed before doorbell write */ | 141 | if (q->dpp_enable && q->phba->cfg_enable_dpp) { |
| 142 | /* write to DPP aperture taking advatage of Combined Writes */ | ||
| 143 | tmp = (uint8_t *)temp_wqe; | ||
| 144 | #ifdef __raw_writeq | ||
| 145 | for (i = 0; i < q->entry_size; i += sizeof(uint64_t)) | ||
| 146 | __raw_writeq(*((uint64_t *)(tmp + i)), | ||
| 147 | q->dpp_regaddr + i); | ||
| 148 | #else | ||
| 149 | for (i = 0; i < q->entry_size; i += sizeof(uint32_t)) | ||
| 150 | __raw_writel(*((uint32_t *)(tmp + i)), | ||
| 151 | q->dpp_regaddr + i); | ||
| 152 | #endif | ||
| 153 | } | ||
| 154 | /* ensure WQE bcopy and DPP flushed before doorbell write */ | ||
| 136 | wmb(); | 155 | wmb(); |
| 137 | 156 | ||
| 138 | /* Update the host index before invoking device */ | 157 | /* Update the host index before invoking device */ |
| @@ -143,9 +162,18 @@ lpfc_sli4_wq_put(struct lpfc_queue *q, union lpfc_wqe *wqe) | |||
| 143 | /* Ring Doorbell */ | 162 | /* Ring Doorbell */ |
| 144 | doorbell.word0 = 0; | 163 | doorbell.word0 = 0; |
| 145 | if (q->db_format == LPFC_DB_LIST_FORMAT) { | 164 | if (q->db_format == LPFC_DB_LIST_FORMAT) { |
| 146 | bf_set(lpfc_wq_db_list_fm_num_posted, &doorbell, 1); | 165 | if (q->dpp_enable && q->phba->cfg_enable_dpp) { |
| 147 | bf_set(lpfc_wq_db_list_fm_index, &doorbell, host_index); | 166 | bf_set(lpfc_if6_wq_db_list_fm_num_posted, &doorbell, 1); |
| 148 | bf_set(lpfc_wq_db_list_fm_id, &doorbell, q->queue_id); | 167 | bf_set(lpfc_if6_wq_db_list_fm_dpp, &doorbell, 1); |
| 168 | bf_set(lpfc_if6_wq_db_list_fm_dpp_id, &doorbell, | ||
| 169 | q->dpp_id); | ||
| 170 | bf_set(lpfc_if6_wq_db_list_fm_id, &doorbell, | ||
| 171 | q->queue_id); | ||
| 172 | } else { | ||
| 173 | bf_set(lpfc_wq_db_list_fm_num_posted, &doorbell, 1); | ||
| 174 | bf_set(lpfc_wq_db_list_fm_index, &doorbell, host_index); | ||
| 175 | bf_set(lpfc_wq_db_list_fm_id, &doorbell, q->queue_id); | ||
| 176 | } | ||
| 149 | } else if (q->db_format == LPFC_DB_RING_FORMAT) { | 177 | } else if (q->db_format == LPFC_DB_RING_FORMAT) { |
| 150 | bf_set(lpfc_wq_db_ring_fm_num_posted, &doorbell, 1); | 178 | bf_set(lpfc_wq_db_ring_fm_num_posted, &doorbell, 1); |
| 151 | bf_set(lpfc_wq_db_ring_fm_id, &doorbell, q->queue_id); | 179 | bf_set(lpfc_wq_db_ring_fm_id, &doorbell, q->queue_id); |
| @@ -262,16 +290,18 @@ lpfc_sli4_mq_release(struct lpfc_queue *q) | |||
| 262 | static struct lpfc_eqe * | 290 | static struct lpfc_eqe * |
| 263 | lpfc_sli4_eq_get(struct lpfc_queue *q) | 291 | lpfc_sli4_eq_get(struct lpfc_queue *q) |
| 264 | { | 292 | { |
| 293 | struct lpfc_hba *phba; | ||
| 265 | struct lpfc_eqe *eqe; | 294 | struct lpfc_eqe *eqe; |
| 266 | uint32_t idx; | 295 | uint32_t idx; |
| 267 | 296 | ||
| 268 | /* sanity check on queue memory */ | 297 | /* sanity check on queue memory */ |
| 269 | if (unlikely(!q)) | 298 | if (unlikely(!q)) |
| 270 | return NULL; | 299 | return NULL; |
| 300 | phba = q->phba; | ||
| 271 | eqe = q->qe[q->hba_index].eqe; | 301 | eqe = q->qe[q->hba_index].eqe; |
| 272 | 302 | ||
| 273 | /* If the next EQE is not valid then we are done */ | 303 | /* If the next EQE is not valid then we are done */ |
| 274 | if (!bf_get_le32(lpfc_eqe_valid, eqe)) | 304 | if (bf_get_le32(lpfc_eqe_valid, eqe) != q->qe_valid) |
| 275 | return NULL; | 305 | return NULL; |
| 276 | /* If the host has not yet processed the next entry then we are done */ | 306 | /* If the host has not yet processed the next entry then we are done */ |
| 277 | idx = ((q->hba_index + 1) % q->entry_count); | 307 | idx = ((q->hba_index + 1) % q->entry_count); |
| @@ -279,6 +309,10 @@ lpfc_sli4_eq_get(struct lpfc_queue *q) | |||
| 279 | return NULL; | 309 | return NULL; |
| 280 | 310 | ||
| 281 | q->hba_index = idx; | 311 | q->hba_index = idx; |
| 312 | /* if the index wrapped around, toggle the valid bit */ | ||
| 313 | if (phba->sli4_hba.pc_sli4_params.eqav && !q->hba_index) | ||
| 314 | q->qe_valid = (q->qe_valid) ? 0 : 1; | ||
| 315 | |||
| 282 | 316 | ||
| 283 | /* | 317 | /* |
| 284 | * insert barrier for instruction interlock : data from the hardware | 318 | * insert barrier for instruction interlock : data from the hardware |
| @@ -298,7 +332,7 @@ lpfc_sli4_eq_get(struct lpfc_queue *q) | |||
| 298 | * @q: The Event Queue to disable interrupts | 332 | * @q: The Event Queue to disable interrupts |
| 299 | * | 333 | * |
| 300 | **/ | 334 | **/ |
| 301 | static inline void | 335 | inline void |
| 302 | lpfc_sli4_eq_clr_intr(struct lpfc_queue *q) | 336 | lpfc_sli4_eq_clr_intr(struct lpfc_queue *q) |
| 303 | { | 337 | { |
| 304 | struct lpfc_register doorbell; | 338 | struct lpfc_register doorbell; |
| @@ -309,7 +343,26 @@ lpfc_sli4_eq_clr_intr(struct lpfc_queue *q) | |||
| 309 | bf_set(lpfc_eqcq_doorbell_eqid_hi, &doorbell, | 343 | bf_set(lpfc_eqcq_doorbell_eqid_hi, &doorbell, |
| 310 | (q->queue_id >> LPFC_EQID_HI_FIELD_SHIFT)); | 344 | (q->queue_id >> LPFC_EQID_HI_FIELD_SHIFT)); |
| 311 | bf_set(lpfc_eqcq_doorbell_eqid_lo, &doorbell, q->queue_id); | 345 | bf_set(lpfc_eqcq_doorbell_eqid_lo, &doorbell, q->queue_id); |
| 312 | writel(doorbell.word0, q->phba->sli4_hba.EQCQDBregaddr); | 346 | writel(doorbell.word0, q->phba->sli4_hba.EQDBregaddr); |
| 347 | } | ||
| 348 | |||
| 349 | /** | ||
| 350 | * lpfc_sli4_if6_eq_clr_intr - Turn off interrupts from this EQ | ||
| 351 | * @q: The Event Queue to disable interrupts | ||
| 352 | * | ||
| 353 | **/ | ||
| 354 | inline void | ||
| 355 | lpfc_sli4_if6_eq_clr_intr(struct lpfc_queue *q) | ||
| 356 | { | ||
| 357 | struct lpfc_register doorbell; | ||
| 358 | |||
| 359 | doorbell.word0 = 0; | ||
| 360 | bf_set(lpfc_eqcq_doorbell_eqci, &doorbell, 1); | ||
| 361 | bf_set(lpfc_eqcq_doorbell_qt, &doorbell, LPFC_QUEUE_TYPE_EVENT); | ||
| 362 | bf_set(lpfc_eqcq_doorbell_eqid_hi, &doorbell, | ||
| 363 | (q->queue_id >> LPFC_EQID_HI_FIELD_SHIFT)); | ||
| 364 | bf_set(lpfc_eqcq_doorbell_eqid_lo, &doorbell, q->queue_id); | ||
| 365 | writel(doorbell.word0, q->phba->sli4_hba.EQDBregaddr); | ||
| 313 | } | 366 | } |
| 314 | 367 | ||
| 315 | /** | 368 | /** |
| @@ -331,17 +384,21 @@ uint32_t | |||
| 331 | lpfc_sli4_eq_release(struct lpfc_queue *q, bool arm) | 384 | lpfc_sli4_eq_release(struct lpfc_queue *q, bool arm) |
| 332 | { | 385 | { |
| 333 | uint32_t released = 0; | 386 | uint32_t released = 0; |
| 387 | struct lpfc_hba *phba; | ||
| 334 | struct lpfc_eqe *temp_eqe; | 388 | struct lpfc_eqe *temp_eqe; |
| 335 | struct lpfc_register doorbell; | 389 | struct lpfc_register doorbell; |
| 336 | 390 | ||
| 337 | /* sanity check on queue memory */ | 391 | /* sanity check on queue memory */ |
| 338 | if (unlikely(!q)) | 392 | if (unlikely(!q)) |
| 339 | return 0; | 393 | return 0; |
| 394 | phba = q->phba; | ||
| 340 | 395 | ||
| 341 | /* while there are valid entries */ | 396 | /* while there are valid entries */ |
| 342 | while (q->hba_index != q->host_index) { | 397 | while (q->hba_index != q->host_index) { |
| 343 | temp_eqe = q->qe[q->host_index].eqe; | 398 | if (!phba->sli4_hba.pc_sli4_params.eqav) { |
| 344 | bf_set_le32(lpfc_eqe_valid, temp_eqe, 0); | 399 | temp_eqe = q->qe[q->host_index].eqe; |
| 400 | bf_set_le32(lpfc_eqe_valid, temp_eqe, 0); | ||
| 401 | } | ||
| 345 | released++; | 402 | released++; |
| 346 | q->host_index = ((q->host_index + 1) % q->entry_count); | 403 | q->host_index = ((q->host_index + 1) % q->entry_count); |
| 347 | } | 404 | } |
| @@ -359,10 +416,63 @@ lpfc_sli4_eq_release(struct lpfc_queue *q, bool arm) | |||
| 359 | bf_set(lpfc_eqcq_doorbell_eqid_hi, &doorbell, | 416 | bf_set(lpfc_eqcq_doorbell_eqid_hi, &doorbell, |
| 360 | (q->queue_id >> LPFC_EQID_HI_FIELD_SHIFT)); | 417 | (q->queue_id >> LPFC_EQID_HI_FIELD_SHIFT)); |
| 361 | bf_set(lpfc_eqcq_doorbell_eqid_lo, &doorbell, q->queue_id); | 418 | bf_set(lpfc_eqcq_doorbell_eqid_lo, &doorbell, q->queue_id); |
| 362 | writel(doorbell.word0, q->phba->sli4_hba.EQCQDBregaddr); | 419 | writel(doorbell.word0, q->phba->sli4_hba.EQDBregaddr); |
| 363 | /* PCI read to flush PCI pipeline on re-arming for INTx mode */ | 420 | /* PCI read to flush PCI pipeline on re-arming for INTx mode */ |
| 364 | if ((q->phba->intr_type == INTx) && (arm == LPFC_QUEUE_REARM)) | 421 | if ((q->phba->intr_type == INTx) && (arm == LPFC_QUEUE_REARM)) |
| 365 | readl(q->phba->sli4_hba.EQCQDBregaddr); | 422 | readl(q->phba->sli4_hba.EQDBregaddr); |
| 423 | return released; | ||
| 424 | } | ||
| 425 | |||
| 426 | /** | ||
| 427 | * lpfc_sli4_if6_eq_release - Indicates the host has finished processing an EQ | ||
| 428 | * @q: The Event Queue that the host has completed processing for. | ||
| 429 | * @arm: Indicates whether the host wants to arms this CQ. | ||
| 430 | * | ||
| 431 | * This routine will mark all Event Queue Entries on @q, from the last | ||
| 432 | * known completed entry to the last entry that was processed, as completed | ||
| 433 | * by clearing the valid bit for each completion queue entry. Then it will | ||
| 434 | * notify the HBA, by ringing the doorbell, that the EQEs have been processed. | ||
| 435 | * The internal host index in the @q will be updated by this routine to indicate | ||
| 436 | * that the host has finished processing the entries. The @arm parameter | ||
| 437 | * indicates that the queue should be rearmed when ringing the doorbell. | ||
| 438 | * | ||
| 439 | * This function will return the number of EQEs that were popped. | ||
| 440 | **/ | ||
| 441 | uint32_t | ||
| 442 | lpfc_sli4_if6_eq_release(struct lpfc_queue *q, bool arm) | ||
| 443 | { | ||
| 444 | uint32_t released = 0; | ||
| 445 | struct lpfc_hba *phba; | ||
| 446 | struct lpfc_eqe *temp_eqe; | ||
| 447 | struct lpfc_register doorbell; | ||
| 448 | |||
| 449 | /* sanity check on queue memory */ | ||
| 450 | if (unlikely(!q)) | ||
| 451 | return 0; | ||
| 452 | phba = q->phba; | ||
| 453 | |||
| 454 | /* while there are valid entries */ | ||
| 455 | while (q->hba_index != q->host_index) { | ||
| 456 | if (!phba->sli4_hba.pc_sli4_params.eqav) { | ||
| 457 | temp_eqe = q->qe[q->host_index].eqe; | ||
| 458 | bf_set_le32(lpfc_eqe_valid, temp_eqe, 0); | ||
| 459 | } | ||
| 460 | released++; | ||
| 461 | q->host_index = ((q->host_index + 1) % q->entry_count); | ||
| 462 | } | ||
| 463 | if (unlikely(released == 0 && !arm)) | ||
| 464 | return 0; | ||
| 465 | |||
| 466 | /* ring doorbell for number popped */ | ||
| 467 | doorbell.word0 = 0; | ||
| 468 | if (arm) | ||
| 469 | bf_set(lpfc_if6_eq_doorbell_arm, &doorbell, 1); | ||
| 470 | bf_set(lpfc_if6_eq_doorbell_num_released, &doorbell, released); | ||
| 471 | bf_set(lpfc_if6_eq_doorbell_eqid, &doorbell, q->queue_id); | ||
| 472 | writel(doorbell.word0, q->phba->sli4_hba.EQDBregaddr); | ||
| 473 | /* PCI read to flush PCI pipeline on re-arming for INTx mode */ | ||
| 474 | if ((q->phba->intr_type == INTx) && (arm == LPFC_QUEUE_REARM)) | ||
| 475 | readl(q->phba->sli4_hba.EQDBregaddr); | ||
| 366 | return released; | 476 | return released; |
| 367 | } | 477 | } |
| 368 | 478 | ||
| @@ -378,23 +488,28 @@ lpfc_sli4_eq_release(struct lpfc_queue *q, bool arm) | |||
| 378 | static struct lpfc_cqe * | 488 | static struct lpfc_cqe * |
| 379 | lpfc_sli4_cq_get(struct lpfc_queue *q) | 489 | lpfc_sli4_cq_get(struct lpfc_queue *q) |
| 380 | { | 490 | { |
| 491 | struct lpfc_hba *phba; | ||
| 381 | struct lpfc_cqe *cqe; | 492 | struct lpfc_cqe *cqe; |
| 382 | uint32_t idx; | 493 | uint32_t idx; |
| 383 | 494 | ||
| 384 | /* sanity check on queue memory */ | 495 | /* sanity check on queue memory */ |
| 385 | if (unlikely(!q)) | 496 | if (unlikely(!q)) |
| 386 | return NULL; | 497 | return NULL; |
| 498 | phba = q->phba; | ||
| 499 | cqe = q->qe[q->hba_index].cqe; | ||
| 387 | 500 | ||
| 388 | /* If the next CQE is not valid then we are done */ | 501 | /* If the next CQE is not valid then we are done */ |
| 389 | if (!bf_get_le32(lpfc_cqe_valid, q->qe[q->hba_index].cqe)) | 502 | if (bf_get_le32(lpfc_cqe_valid, cqe) != q->qe_valid) |
| 390 | return NULL; | 503 | return NULL; |
| 391 | /* If the host has not yet processed the next entry then we are done */ | 504 | /* If the host has not yet processed the next entry then we are done */ |
| 392 | idx = ((q->hba_index + 1) % q->entry_count); | 505 | idx = ((q->hba_index + 1) % q->entry_count); |
| 393 | if (idx == q->host_index) | 506 | if (idx == q->host_index) |
| 394 | return NULL; | 507 | return NULL; |
| 395 | 508 | ||
| 396 | cqe = q->qe[q->hba_index].cqe; | ||
| 397 | q->hba_index = idx; | 509 | q->hba_index = idx; |
| 510 | /* if the index wrapped around, toggle the valid bit */ | ||
| 511 | if (phba->sli4_hba.pc_sli4_params.cqav && !q->hba_index) | ||
| 512 | q->qe_valid = (q->qe_valid) ? 0 : 1; | ||
| 398 | 513 | ||
| 399 | /* | 514 | /* |
| 400 | * insert barrier for instruction interlock : data from the hardware | 515 | * insert barrier for instruction interlock : data from the hardware |
| @@ -427,16 +542,21 @@ uint32_t | |||
| 427 | lpfc_sli4_cq_release(struct lpfc_queue *q, bool arm) | 542 | lpfc_sli4_cq_release(struct lpfc_queue *q, bool arm) |
| 428 | { | 543 | { |
| 429 | uint32_t released = 0; | 544 | uint32_t released = 0; |
| 545 | struct lpfc_hba *phba; | ||
| 430 | struct lpfc_cqe *temp_qe; | 546 | struct lpfc_cqe *temp_qe; |
| 431 | struct lpfc_register doorbell; | 547 | struct lpfc_register doorbell; |
| 432 | 548 | ||
| 433 | /* sanity check on queue memory */ | 549 | /* sanity check on queue memory */ |
| 434 | if (unlikely(!q)) | 550 | if (unlikely(!q)) |
| 435 | return 0; | 551 | return 0; |
| 552 | phba = q->phba; | ||
| 553 | |||
| 436 | /* while there are valid entries */ | 554 | /* while there are valid entries */ |
| 437 | while (q->hba_index != q->host_index) { | 555 | while (q->hba_index != q->host_index) { |
| 438 | temp_qe = q->qe[q->host_index].cqe; | 556 | if (!phba->sli4_hba.pc_sli4_params.cqav) { |
| 439 | bf_set_le32(lpfc_cqe_valid, temp_qe, 0); | 557 | temp_qe = q->qe[q->host_index].cqe; |
| 558 | bf_set_le32(lpfc_cqe_valid, temp_qe, 0); | ||
| 559 | } | ||
| 440 | released++; | 560 | released++; |
| 441 | q->host_index = ((q->host_index + 1) % q->entry_count); | 561 | q->host_index = ((q->host_index + 1) % q->entry_count); |
| 442 | } | 562 | } |
| @@ -452,7 +572,57 @@ lpfc_sli4_cq_release(struct lpfc_queue *q, bool arm) | |||
| 452 | bf_set(lpfc_eqcq_doorbell_cqid_hi, &doorbell, | 572 | bf_set(lpfc_eqcq_doorbell_cqid_hi, &doorbell, |
| 453 | (q->queue_id >> LPFC_CQID_HI_FIELD_SHIFT)); | 573 | (q->queue_id >> LPFC_CQID_HI_FIELD_SHIFT)); |
| 454 | bf_set(lpfc_eqcq_doorbell_cqid_lo, &doorbell, q->queue_id); | 574 | bf_set(lpfc_eqcq_doorbell_cqid_lo, &doorbell, q->queue_id); |
| 455 | writel(doorbell.word0, q->phba->sli4_hba.EQCQDBregaddr); | 575 | writel(doorbell.word0, q->phba->sli4_hba.CQDBregaddr); |
| 576 | return released; | ||
| 577 | } | ||
| 578 | |||
| 579 | /** | ||
| 580 | * lpfc_sli4_if6_cq_release - Indicates the host has finished processing a CQ | ||
| 581 | * @q: The Completion Queue that the host has completed processing for. | ||
| 582 | * @arm: Indicates whether the host wants to arms this CQ. | ||
| 583 | * | ||
| 584 | * This routine will mark all Completion queue entries on @q, from the last | ||
| 585 | * known completed entry to the last entry that was processed, as completed | ||
| 586 | * by clearing the valid bit for each completion queue entry. Then it will | ||
| 587 | * notify the HBA, by ringing the doorbell, that the CQEs have been processed. | ||
| 588 | * The internal host index in the @q will be updated by this routine to indicate | ||
| 589 | * that the host has finished processing the entries. The @arm parameter | ||
| 590 | * indicates that the queue should be rearmed when ringing the doorbell. | ||
| 591 | * | ||
| 592 | * This function will return the number of CQEs that were released. | ||
| 593 | **/ | ||
| 594 | uint32_t | ||
| 595 | lpfc_sli4_if6_cq_release(struct lpfc_queue *q, bool arm) | ||
| 596 | { | ||
| 597 | uint32_t released = 0; | ||
| 598 | struct lpfc_hba *phba; | ||
| 599 | struct lpfc_cqe *temp_qe; | ||
| 600 | struct lpfc_register doorbell; | ||
| 601 | |||
| 602 | /* sanity check on queue memory */ | ||
| 603 | if (unlikely(!q)) | ||
| 604 | return 0; | ||
| 605 | phba = q->phba; | ||
| 606 | |||
| 607 | /* while there are valid entries */ | ||
| 608 | while (q->hba_index != q->host_index) { | ||
| 609 | if (!phba->sli4_hba.pc_sli4_params.cqav) { | ||
| 610 | temp_qe = q->qe[q->host_index].cqe; | ||
| 611 | bf_set_le32(lpfc_cqe_valid, temp_qe, 0); | ||
| 612 | } | ||
| 613 | released++; | ||
| 614 | q->host_index = ((q->host_index + 1) % q->entry_count); | ||
| 615 | } | ||
| 616 | if (unlikely(released == 0 && !arm)) | ||
| 617 | return 0; | ||
| 618 | |||
| 619 | /* ring doorbell for number popped */ | ||
| 620 | doorbell.word0 = 0; | ||
| 621 | if (arm) | ||
| 622 | bf_set(lpfc_if6_cq_doorbell_arm, &doorbell, 1); | ||
| 623 | bf_set(lpfc_if6_cq_doorbell_num_released, &doorbell, released); | ||
| 624 | bf_set(lpfc_if6_cq_doorbell_cqid, &doorbell, q->queue_id); | ||
| 625 | writel(doorbell.word0, q->phba->sli4_hba.CQDBregaddr); | ||
| 456 | return released; | 626 | return released; |
| 457 | } | 627 | } |
| 458 | 628 | ||
| @@ -2218,18 +2388,18 @@ lpfc_sli_chk_mbx_command(uint8_t mbxCommand) | |||
| 2218 | void | 2388 | void |
| 2219 | lpfc_sli_wake_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) | 2389 | lpfc_sli_wake_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq) |
| 2220 | { | 2390 | { |
| 2221 | wait_queue_head_t *pdone_q; | ||
| 2222 | unsigned long drvr_flag; | 2391 | unsigned long drvr_flag; |
| 2392 | struct completion *pmbox_done; | ||
| 2223 | 2393 | ||
| 2224 | /* | 2394 | /* |
| 2225 | * If pdone_q is empty, the driver thread gave up waiting and | 2395 | * If pmbox_done is empty, the driver thread gave up waiting and |
| 2226 | * continued running. | 2396 | * continued running. |
| 2227 | */ | 2397 | */ |
| 2228 | pmboxq->mbox_flag |= LPFC_MBX_WAKE; | 2398 | pmboxq->mbox_flag |= LPFC_MBX_WAKE; |
| 2229 | spin_lock_irqsave(&phba->hbalock, drvr_flag); | 2399 | spin_lock_irqsave(&phba->hbalock, drvr_flag); |
| 2230 | pdone_q = (wait_queue_head_t *) pmboxq->context1; | 2400 | pmbox_done = (struct completion *)pmboxq->context3; |
| 2231 | if (pdone_q) | 2401 | if (pmbox_done) |
| 2232 | wake_up_interruptible(pdone_q); | 2402 | complete(pmbox_done); |
| 2233 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); | 2403 | spin_unlock_irqrestore(&phba->hbalock, drvr_flag); |
| 2234 | return; | 2404 | return; |
| 2235 | } | 2405 | } |
| @@ -2330,7 +2500,7 @@ lpfc_sli4_unreg_rpi_cmpl_clr(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
| 2330 | if (pmb->u.mb.mbxCommand == MBX_UNREG_LOGIN) { | 2500 | if (pmb->u.mb.mbxCommand == MBX_UNREG_LOGIN) { |
| 2331 | if (phba->sli_rev == LPFC_SLI_REV4 && | 2501 | if (phba->sli_rev == LPFC_SLI_REV4 && |
| 2332 | (bf_get(lpfc_sli_intf_if_type, | 2502 | (bf_get(lpfc_sli_intf_if_type, |
| 2333 | &phba->sli4_hba.sli_intf) == | 2503 | &phba->sli4_hba.sli_intf) >= |
| 2334 | LPFC_SLI_INTF_IF_TYPE_2)) { | 2504 | LPFC_SLI_INTF_IF_TYPE_2)) { |
| 2335 | if (ndlp) { | 2505 | if (ndlp) { |
| 2336 | lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI, | 2506 | lpfc_printf_vlog(vport, KERN_INFO, LOG_SLI, |
| @@ -3776,6 +3946,7 @@ lpfc_sli_flush_fcp_rings(struct lpfc_hba *phba) | |||
| 3776 | struct lpfc_sli *psli = &phba->sli; | 3946 | struct lpfc_sli *psli = &phba->sli; |
| 3777 | struct lpfc_sli_ring *pring; | 3947 | struct lpfc_sli_ring *pring; |
| 3778 | uint32_t i; | 3948 | uint32_t i; |
| 3949 | struct lpfc_iocbq *piocb, *next_iocb; | ||
| 3779 | 3950 | ||
| 3780 | spin_lock_irq(&phba->hbalock); | 3951 | spin_lock_irq(&phba->hbalock); |
| 3781 | /* Indicate the I/O queues are flushed */ | 3952 | /* Indicate the I/O queues are flushed */ |
| @@ -3790,6 +3961,9 @@ lpfc_sli_flush_fcp_rings(struct lpfc_hba *phba) | |||
| 3790 | spin_lock_irq(&pring->ring_lock); | 3961 | spin_lock_irq(&pring->ring_lock); |
| 3791 | /* Retrieve everything on txq */ | 3962 | /* Retrieve everything on txq */ |
| 3792 | list_splice_init(&pring->txq, &txq); | 3963 | list_splice_init(&pring->txq, &txq); |
| 3964 | list_for_each_entry_safe(piocb, next_iocb, | ||
| 3965 | &pring->txcmplq, list) | ||
| 3966 | piocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ; | ||
| 3793 | /* Retrieve everything on the txcmplq */ | 3967 | /* Retrieve everything on the txcmplq */ |
| 3794 | list_splice_init(&pring->txcmplq, &txcmplq); | 3968 | list_splice_init(&pring->txcmplq, &txcmplq); |
| 3795 | pring->txq_cnt = 0; | 3969 | pring->txq_cnt = 0; |
| @@ -3811,6 +3985,9 @@ lpfc_sli_flush_fcp_rings(struct lpfc_hba *phba) | |||
| 3811 | spin_lock_irq(&phba->hbalock); | 3985 | spin_lock_irq(&phba->hbalock); |
| 3812 | /* Retrieve everything on txq */ | 3986 | /* Retrieve everything on txq */ |
| 3813 | list_splice_init(&pring->txq, &txq); | 3987 | list_splice_init(&pring->txq, &txq); |
| 3988 | list_for_each_entry_safe(piocb, next_iocb, | ||
| 3989 | &pring->txcmplq, list) | ||
| 3990 | piocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ; | ||
| 3814 | /* Retrieve everything on the txcmplq */ | 3991 | /* Retrieve everything on the txcmplq */ |
| 3815 | list_splice_init(&pring->txcmplq, &txcmplq); | 3992 | list_splice_init(&pring->txcmplq, &txcmplq); |
| 3816 | pring->txq_cnt = 0; | 3993 | pring->txq_cnt = 0; |
| @@ -3842,6 +4019,7 @@ lpfc_sli_flush_nvme_rings(struct lpfc_hba *phba) | |||
| 3842 | LIST_HEAD(txcmplq); | 4019 | LIST_HEAD(txcmplq); |
| 3843 | struct lpfc_sli_ring *pring; | 4020 | struct lpfc_sli_ring *pring; |
| 3844 | uint32_t i; | 4021 | uint32_t i; |
| 4022 | struct lpfc_iocbq *piocb, *next_iocb; | ||
| 3845 | 4023 | ||
| 3846 | if (phba->sli_rev < LPFC_SLI_REV4) | 4024 | if (phba->sli_rev < LPFC_SLI_REV4) |
| 3847 | return; | 4025 | return; |
| @@ -3858,8 +4036,11 @@ lpfc_sli_flush_nvme_rings(struct lpfc_hba *phba) | |||
| 3858 | for (i = 0; i < phba->cfg_nvme_io_channel; i++) { | 4036 | for (i = 0; i < phba->cfg_nvme_io_channel; i++) { |
| 3859 | pring = phba->sli4_hba.nvme_wq[i]->pring; | 4037 | pring = phba->sli4_hba.nvme_wq[i]->pring; |
| 3860 | 4038 | ||
| 3861 | /* Retrieve everything on the txcmplq */ | ||
| 3862 | spin_lock_irq(&pring->ring_lock); | 4039 | spin_lock_irq(&pring->ring_lock); |
| 4040 | list_for_each_entry_safe(piocb, next_iocb, | ||
| 4041 | &pring->txcmplq, list) | ||
| 4042 | piocb->iocb_flag &= ~LPFC_IO_ON_TXCMPLQ; | ||
| 4043 | /* Retrieve everything on the txcmplq */ | ||
| 3863 | list_splice_init(&pring->txcmplq, &txcmplq); | 4044 | list_splice_init(&pring->txcmplq, &txcmplq); |
| 3864 | pring->txcmplq_cnt = 0; | 4045 | pring->txcmplq_cnt = 0; |
| 3865 | spin_unlock_irq(&pring->ring_lock); | 4046 | spin_unlock_irq(&pring->ring_lock); |
| @@ -4812,13 +4993,14 @@ lpfc_sli_config_port(struct lpfc_hba *phba, int sli_mode) | |||
| 4812 | phba->hbq_get = phba->mbox->us.s3_pgp.hbq_get; | 4993 | phba->hbq_get = phba->mbox->us.s3_pgp.hbq_get; |
| 4813 | phba->port_gp = phba->mbox->us.s3_pgp.port; | 4994 | phba->port_gp = phba->mbox->us.s3_pgp.port; |
| 4814 | 4995 | ||
| 4815 | if (phba->cfg_enable_bg) { | 4996 | if (phba->sli3_options & LPFC_SLI3_BG_ENABLED) { |
| 4816 | if (pmb->u.mb.un.varCfgPort.gbg) | 4997 | if (pmb->u.mb.un.varCfgPort.gbg == 0) { |
| 4817 | phba->sli3_options |= LPFC_SLI3_BG_ENABLED; | 4998 | phba->cfg_enable_bg = 0; |
| 4818 | else | 4999 | phba->sli3_options &= ~LPFC_SLI3_BG_ENABLED; |
| 4819 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 5000 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
| 4820 | "0443 Adapter did not grant " | 5001 | "0443 Adapter did not grant " |
| 4821 | "BlockGuard\n"); | 5002 | "BlockGuard\n"); |
| 5003 | } | ||
| 4822 | } | 5004 | } |
| 4823 | } else { | 5005 | } else { |
| 4824 | phba->hbq_get = NULL; | 5006 | phba->hbq_get = NULL; |
| @@ -5290,41 +5472,42 @@ static void | |||
| 5290 | lpfc_sli4_arm_cqeq_intr(struct lpfc_hba *phba) | 5472 | lpfc_sli4_arm_cqeq_intr(struct lpfc_hba *phba) |
| 5291 | { | 5473 | { |
| 5292 | int qidx; | 5474 | int qidx; |
| 5475 | struct lpfc_sli4_hba *sli4_hba = &phba->sli4_hba; | ||
| 5293 | 5476 | ||
| 5294 | lpfc_sli4_cq_release(phba->sli4_hba.mbx_cq, LPFC_QUEUE_REARM); | 5477 | sli4_hba->sli4_cq_release(sli4_hba->mbx_cq, LPFC_QUEUE_REARM); |
| 5295 | lpfc_sli4_cq_release(phba->sli4_hba.els_cq, LPFC_QUEUE_REARM); | 5478 | sli4_hba->sli4_cq_release(sli4_hba->els_cq, LPFC_QUEUE_REARM); |
| 5296 | if (phba->sli4_hba.nvmels_cq) | 5479 | if (sli4_hba->nvmels_cq) |
| 5297 | lpfc_sli4_cq_release(phba->sli4_hba.nvmels_cq, | 5480 | sli4_hba->sli4_cq_release(sli4_hba->nvmels_cq, |
| 5298 | LPFC_QUEUE_REARM); | 5481 | LPFC_QUEUE_REARM); |
| 5299 | 5482 | ||
| 5300 | if (phba->sli4_hba.fcp_cq) | 5483 | if (sli4_hba->fcp_cq) |
| 5301 | for (qidx = 0; qidx < phba->cfg_fcp_io_channel; qidx++) | 5484 | for (qidx = 0; qidx < phba->cfg_fcp_io_channel; qidx++) |
| 5302 | lpfc_sli4_cq_release(phba->sli4_hba.fcp_cq[qidx], | 5485 | sli4_hba->sli4_cq_release(sli4_hba->fcp_cq[qidx], |
| 5303 | LPFC_QUEUE_REARM); | 5486 | LPFC_QUEUE_REARM); |
| 5304 | 5487 | ||
| 5305 | if (phba->sli4_hba.nvme_cq) | 5488 | if (sli4_hba->nvme_cq) |
| 5306 | for (qidx = 0; qidx < phba->cfg_nvme_io_channel; qidx++) | 5489 | for (qidx = 0; qidx < phba->cfg_nvme_io_channel; qidx++) |
| 5307 | lpfc_sli4_cq_release(phba->sli4_hba.nvme_cq[qidx], | 5490 | sli4_hba->sli4_cq_release(sli4_hba->nvme_cq[qidx], |
| 5308 | LPFC_QUEUE_REARM); | 5491 | LPFC_QUEUE_REARM); |
| 5309 | 5492 | ||
| 5310 | if (phba->cfg_fof) | 5493 | if (phba->cfg_fof) |
| 5311 | lpfc_sli4_cq_release(phba->sli4_hba.oas_cq, LPFC_QUEUE_REARM); | 5494 | sli4_hba->sli4_cq_release(sli4_hba->oas_cq, LPFC_QUEUE_REARM); |
| 5312 | 5495 | ||
| 5313 | if (phba->sli4_hba.hba_eq) | 5496 | if (sli4_hba->hba_eq) |
| 5314 | for (qidx = 0; qidx < phba->io_channel_irqs; qidx++) | 5497 | for (qidx = 0; qidx < phba->io_channel_irqs; qidx++) |
| 5315 | lpfc_sli4_eq_release(phba->sli4_hba.hba_eq[qidx], | 5498 | sli4_hba->sli4_eq_release(sli4_hba->hba_eq[qidx], |
| 5316 | LPFC_QUEUE_REARM); | 5499 | LPFC_QUEUE_REARM); |
| 5317 | 5500 | ||
| 5318 | if (phba->nvmet_support) { | 5501 | if (phba->nvmet_support) { |
| 5319 | for (qidx = 0; qidx < phba->cfg_nvmet_mrq; qidx++) { | 5502 | for (qidx = 0; qidx < phba->cfg_nvmet_mrq; qidx++) { |
| 5320 | lpfc_sli4_cq_release( | 5503 | sli4_hba->sli4_cq_release( |
| 5321 | phba->sli4_hba.nvmet_cqset[qidx], | 5504 | sli4_hba->nvmet_cqset[qidx], |
| 5322 | LPFC_QUEUE_REARM); | 5505 | LPFC_QUEUE_REARM); |
| 5323 | } | 5506 | } |
| 5324 | } | 5507 | } |
| 5325 | 5508 | ||
| 5326 | if (phba->cfg_fof) | 5509 | if (phba->cfg_fof) |
| 5327 | lpfc_sli4_eq_release(phba->sli4_hba.fof_eq, LPFC_QUEUE_REARM); | 5510 | sli4_hba->sli4_eq_release(sli4_hba->fof_eq, LPFC_QUEUE_REARM); |
| 5328 | } | 5511 | } |
| 5329 | 5512 | ||
| 5330 | /** | 5513 | /** |
| @@ -6533,9 +6716,11 @@ lpfc_post_rq_buffer(struct lpfc_hba *phba, struct lpfc_queue *hrq, | |||
| 6533 | struct lpfc_rqe hrqe; | 6716 | struct lpfc_rqe hrqe; |
| 6534 | struct lpfc_rqe drqe; | 6717 | struct lpfc_rqe drqe; |
| 6535 | struct lpfc_rqb *rqbp; | 6718 | struct lpfc_rqb *rqbp; |
| 6719 | unsigned long flags; | ||
| 6536 | struct rqb_dmabuf *rqb_buffer; | 6720 | struct rqb_dmabuf *rqb_buffer; |
| 6537 | LIST_HEAD(rqb_buf_list); | 6721 | LIST_HEAD(rqb_buf_list); |
| 6538 | 6722 | ||
| 6723 | spin_lock_irqsave(&phba->hbalock, flags); | ||
| 6539 | rqbp = hrq->rqbp; | 6724 | rqbp = hrq->rqbp; |
| 6540 | for (i = 0; i < count; i++) { | 6725 | for (i = 0; i < count; i++) { |
| 6541 | /* IF RQ is already full, don't bother */ | 6726 | /* IF RQ is already full, don't bother */ |
| @@ -6559,6 +6744,15 @@ lpfc_post_rq_buffer(struct lpfc_hba *phba, struct lpfc_queue *hrq, | |||
| 6559 | drqe.address_hi = putPaddrHigh(rqb_buffer->dbuf.phys); | 6744 | drqe.address_hi = putPaddrHigh(rqb_buffer->dbuf.phys); |
| 6560 | rc = lpfc_sli4_rq_put(hrq, drq, &hrqe, &drqe); | 6745 | rc = lpfc_sli4_rq_put(hrq, drq, &hrqe, &drqe); |
| 6561 | if (rc < 0) { | 6746 | if (rc < 0) { |
| 6747 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
| 6748 | "6421 Cannot post to HRQ %d: %x %x %x " | ||
| 6749 | "DRQ %x %x\n", | ||
| 6750 | hrq->queue_id, | ||
| 6751 | hrq->host_index, | ||
| 6752 | hrq->hba_index, | ||
| 6753 | hrq->entry_count, | ||
| 6754 | drq->host_index, | ||
| 6755 | drq->hba_index); | ||
| 6562 | rqbp->rqb_free_buffer(phba, rqb_buffer); | 6756 | rqbp->rqb_free_buffer(phba, rqb_buffer); |
| 6563 | } else { | 6757 | } else { |
| 6564 | list_add_tail(&rqb_buffer->hbuf.list, | 6758 | list_add_tail(&rqb_buffer->hbuf.list, |
| @@ -6566,6 +6760,7 @@ lpfc_post_rq_buffer(struct lpfc_hba *phba, struct lpfc_queue *hrq, | |||
| 6566 | rqbp->buffer_count++; | 6760 | rqbp->buffer_count++; |
| 6567 | } | 6761 | } |
| 6568 | } | 6762 | } |
| 6763 | spin_unlock_irqrestore(&phba->hbalock, flags); | ||
| 6569 | return 1; | 6764 | return 1; |
| 6570 | } | 6765 | } |
| 6571 | 6766 | ||
| @@ -6693,6 +6888,18 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
| 6693 | /* Save information as VPD data */ | 6888 | /* Save information as VPD data */ |
| 6694 | phba->vpd.rev.biuRev = mqe->un.read_rev.first_hw_rev; | 6889 | phba->vpd.rev.biuRev = mqe->un.read_rev.first_hw_rev; |
| 6695 | phba->vpd.rev.smRev = mqe->un.read_rev.second_hw_rev; | 6890 | phba->vpd.rev.smRev = mqe->un.read_rev.second_hw_rev; |
| 6891 | |||
| 6892 | /* | ||
| 6893 | * This is because first G7 ASIC doesn't support the standard | ||
| 6894 | * 0x5a NVME cmd descriptor type/subtype | ||
| 6895 | */ | ||
| 6896 | if ((bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) == | ||
| 6897 | LPFC_SLI_INTF_IF_TYPE_6) && | ||
| 6898 | (phba->vpd.rev.biuRev == LPFC_G7_ASIC_1) && | ||
| 6899 | (phba->vpd.rev.smRev == 0) && | ||
| 6900 | (phba->cfg_nvme_embed_cmd == 1)) | ||
| 6901 | phba->cfg_nvme_embed_cmd = 0; | ||
| 6902 | |||
| 6696 | phba->vpd.rev.endecRev = mqe->un.read_rev.third_hw_rev; | 6903 | phba->vpd.rev.endecRev = mqe->un.read_rev.third_hw_rev; |
| 6697 | phba->vpd.rev.fcphHigh = bf_get(lpfc_mbx_rd_rev_fcph_high, | 6904 | phba->vpd.rev.fcphHigh = bf_get(lpfc_mbx_rd_rev_fcph_high, |
| 6698 | &mqe->un.read_rev); | 6905 | &mqe->un.read_rev); |
| @@ -6771,21 +6978,26 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba) | |||
| 6771 | "0378 No support for fcpi mode.\n"); | 6978 | "0378 No support for fcpi mode.\n"); |
| 6772 | ftr_rsp++; | 6979 | ftr_rsp++; |
| 6773 | } | 6980 | } |
| 6774 | if (bf_get(lpfc_mbx_rq_ftr_rsp_perfh, &mqe->un.req_ftrs)) | 6981 | |
| 6775 | phba->sli3_options |= LPFC_SLI4_PERFH_ENABLED; | 6982 | /* Performance Hints are ONLY for FCoE */ |
| 6776 | else | 6983 | if (phba->hba_flag & HBA_FCOE_MODE) { |
| 6777 | phba->sli3_options &= ~LPFC_SLI4_PERFH_ENABLED; | 6984 | if (bf_get(lpfc_mbx_rq_ftr_rsp_perfh, &mqe->un.req_ftrs)) |
| 6985 | phba->sli3_options |= LPFC_SLI4_PERFH_ENABLED; | ||
| 6986 | else | ||
| 6987 | phba->sli3_options &= ~LPFC_SLI4_PERFH_ENABLED; | ||
| 6988 | } | ||
| 6989 | |||
| 6778 | /* | 6990 | /* |
| 6779 | * If the port cannot support the host's requested features | 6991 | * If the port cannot support the host's requested features |
| 6780 | * then turn off the global config parameters to disable the | 6992 | * then turn off the global config parameters to disable the |
| 6781 | * feature in the driver. This is not a fatal error. | 6993 | * feature in the driver. This is not a fatal error. |
| 6782 | */ | 6994 | */ |
| 6783 | phba->sli3_options &= ~LPFC_SLI3_BG_ENABLED; | 6995 | if (phba->sli3_options & LPFC_SLI3_BG_ENABLED) { |
| 6784 | if (phba->cfg_enable_bg) { | 6996 | if (!(bf_get(lpfc_mbx_rq_ftr_rsp_dif, &mqe->un.req_ftrs))) { |
| 6785 | if (bf_get(lpfc_mbx_rq_ftr_rsp_dif, &mqe->un.req_ftrs)) | 6997 | phba->cfg_enable_bg = 0; |
| 6786 | phba->sli3_options |= LPFC_SLI3_BG_ENABLED; | 6998 | phba->sli3_options &= ~LPFC_SLI3_BG_ENABLED; |
| 6787 | else | ||
| 6788 | ftr_rsp++; | 6999 | ftr_rsp++; |
| 7000 | } | ||
| 6789 | } | 7001 | } |
| 6790 | 7002 | ||
| 6791 | if (phba->max_vpi && phba->cfg_enable_npiv && | 7003 | if (phba->max_vpi && phba->cfg_enable_npiv && |
| @@ -7209,6 +7421,7 @@ lpfc_sli4_mbox_completions_pending(struct lpfc_hba *phba) | |||
| 7209 | struct lpfc_queue *mcq; | 7421 | struct lpfc_queue *mcq; |
| 7210 | struct lpfc_mcqe *mcqe; | 7422 | struct lpfc_mcqe *mcqe; |
| 7211 | bool pending_completions = false; | 7423 | bool pending_completions = false; |
| 7424 | uint8_t qe_valid; | ||
| 7212 | 7425 | ||
| 7213 | if (unlikely(!phba) || (phba->sli_rev != LPFC_SLI_REV4)) | 7426 | if (unlikely(!phba) || (phba->sli_rev != LPFC_SLI_REV4)) |
| 7214 | return false; | 7427 | return false; |
| @@ -7217,7 +7430,8 @@ lpfc_sli4_mbox_completions_pending(struct lpfc_hba *phba) | |||
| 7217 | 7430 | ||
| 7218 | mcq = phba->sli4_hba.mbx_cq; | 7431 | mcq = phba->sli4_hba.mbx_cq; |
| 7219 | idx = mcq->hba_index; | 7432 | idx = mcq->hba_index; |
| 7220 | while (bf_get_le32(lpfc_cqe_valid, mcq->qe[idx].cqe)) { | 7433 | qe_valid = mcq->qe_valid; |
| 7434 | while (bf_get_le32(lpfc_cqe_valid, mcq->qe[idx].cqe) == qe_valid) { | ||
| 7221 | mcqe = (struct lpfc_mcqe *)mcq->qe[idx].cqe; | 7435 | mcqe = (struct lpfc_mcqe *)mcq->qe[idx].cqe; |
| 7222 | if (bf_get_le32(lpfc_trailer_completed, mcqe) && | 7436 | if (bf_get_le32(lpfc_trailer_completed, mcqe) && |
| 7223 | (!bf_get_le32(lpfc_trailer_async, mcqe))) { | 7437 | (!bf_get_le32(lpfc_trailer_async, mcqe))) { |
| @@ -7227,6 +7441,10 @@ lpfc_sli4_mbox_completions_pending(struct lpfc_hba *phba) | |||
| 7227 | idx = (idx + 1) % mcq->entry_count; | 7441 | idx = (idx + 1) % mcq->entry_count; |
| 7228 | if (mcq->hba_index == idx) | 7442 | if (mcq->hba_index == idx) |
| 7229 | break; | 7443 | break; |
| 7444 | |||
| 7445 | /* if the index wrapped around, toggle the valid bit */ | ||
| 7446 | if (phba->sli4_hba.pc_sli4_params.cqav && !idx) | ||
| 7447 | qe_valid = (qe_valid) ? 0 : 1; | ||
| 7230 | } | 7448 | } |
| 7231 | return pending_completions; | 7449 | return pending_completions; |
| 7232 | 7450 | ||
| @@ -7246,7 +7464,7 @@ lpfc_sli4_mbox_completions_pending(struct lpfc_hba *phba) | |||
| 7246 | bool | 7464 | bool |
| 7247 | lpfc_sli4_process_missed_mbox_completions(struct lpfc_hba *phba) | 7465 | lpfc_sli4_process_missed_mbox_completions(struct lpfc_hba *phba) |
| 7248 | { | 7466 | { |
| 7249 | 7467 | struct lpfc_sli4_hba *sli4_hba = &phba->sli4_hba; | |
| 7250 | uint32_t eqidx; | 7468 | uint32_t eqidx; |
| 7251 | struct lpfc_queue *fpeq = NULL; | 7469 | struct lpfc_queue *fpeq = NULL; |
| 7252 | struct lpfc_eqe *eqe; | 7470 | struct lpfc_eqe *eqe; |
| @@ -7257,11 +7475,11 @@ lpfc_sli4_process_missed_mbox_completions(struct lpfc_hba *phba) | |||
| 7257 | 7475 | ||
| 7258 | /* Find the eq associated with the mcq */ | 7476 | /* Find the eq associated with the mcq */ |
| 7259 | 7477 | ||
| 7260 | if (phba->sli4_hba.hba_eq) | 7478 | if (sli4_hba->hba_eq) |
| 7261 | for (eqidx = 0; eqidx < phba->io_channel_irqs; eqidx++) | 7479 | for (eqidx = 0; eqidx < phba->io_channel_irqs; eqidx++) |
| 7262 | if (phba->sli4_hba.hba_eq[eqidx]->queue_id == | 7480 | if (sli4_hba->hba_eq[eqidx]->queue_id == |
| 7263 | phba->sli4_hba.mbx_cq->assoc_qid) { | 7481 | sli4_hba->mbx_cq->assoc_qid) { |
| 7264 | fpeq = phba->sli4_hba.hba_eq[eqidx]; | 7482 | fpeq = sli4_hba->hba_eq[eqidx]; |
| 7265 | break; | 7483 | break; |
| 7266 | } | 7484 | } |
| 7267 | if (!fpeq) | 7485 | if (!fpeq) |
| @@ -7269,7 +7487,7 @@ lpfc_sli4_process_missed_mbox_completions(struct lpfc_hba *phba) | |||
| 7269 | 7487 | ||
| 7270 | /* Turn off interrupts from this EQ */ | 7488 | /* Turn off interrupts from this EQ */ |
| 7271 | 7489 | ||
| 7272 | lpfc_sli4_eq_clr_intr(fpeq); | 7490 | sli4_hba->sli4_eq_clr_intr(fpeq); |
| 7273 | 7491 | ||
| 7274 | /* Check to see if a mbox completion is pending */ | 7492 | /* Check to see if a mbox completion is pending */ |
| 7275 | 7493 | ||
| @@ -7290,7 +7508,7 @@ lpfc_sli4_process_missed_mbox_completions(struct lpfc_hba *phba) | |||
| 7290 | 7508 | ||
| 7291 | /* Always clear and re-arm the EQ */ | 7509 | /* Always clear and re-arm the EQ */ |
| 7292 | 7510 | ||
| 7293 | lpfc_sli4_eq_release(fpeq, LPFC_QUEUE_REARM); | 7511 | sli4_hba->sli4_eq_release(fpeq, LPFC_QUEUE_REARM); |
| 7294 | 7512 | ||
| 7295 | return mbox_pending; | 7513 | return mbox_pending; |
| 7296 | 7514 | ||
| @@ -8100,7 +8318,7 @@ lpfc_sli_issue_mbox_s4(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq, | |||
| 8100 | } else if (flag == MBX_POLL) { | 8318 | } else if (flag == MBX_POLL) { |
| 8101 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_SLI, | 8319 | lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_SLI, |
| 8102 | "(%d):2542 Try to issue mailbox command " | 8320 | "(%d):2542 Try to issue mailbox command " |
| 8103 | "x%x (x%x/x%x) synchronously ahead of async" | 8321 | "x%x (x%x/x%x) synchronously ahead of async " |
| 8104 | "mailbox command queue: x%x x%x\n", | 8322 | "mailbox command queue: x%x x%x\n", |
| 8105 | mboxq->vport ? mboxq->vport->vpi : 0, | 8323 | mboxq->vport ? mboxq->vport->vpi : 0, |
| 8106 | mboxq->u.mb.mbxCommand, | 8324 | mboxq->u.mb.mbxCommand, |
| @@ -8664,7 +8882,7 @@ lpfc_sli4_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, | |||
| 8664 | **/ | 8882 | **/ |
| 8665 | static int | 8883 | static int |
| 8666 | lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | 8884 | lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, |
| 8667 | union lpfc_wqe *wqe) | 8885 | union lpfc_wqe128 *wqe) |
| 8668 | { | 8886 | { |
| 8669 | uint32_t xmit_len = 0, total_len = 0; | 8887 | uint32_t xmit_len = 0, total_len = 0; |
| 8670 | uint8_t ct = 0; | 8888 | uint8_t ct = 0; |
| @@ -8767,7 +8985,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
| 8767 | iocbq->context2)->virt); | 8985 | iocbq->context2)->virt); |
| 8768 | if_type = bf_get(lpfc_sli_intf_if_type, | 8986 | if_type = bf_get(lpfc_sli_intf_if_type, |
| 8769 | &phba->sli4_hba.sli_intf); | 8987 | &phba->sli4_hba.sli_intf); |
| 8770 | if (if_type == LPFC_SLI_INTF_IF_TYPE_2) { | 8988 | if (if_type >= LPFC_SLI_INTF_IF_TYPE_2) { |
| 8771 | if (pcmd && (*pcmd == ELS_CMD_FLOGI || | 8989 | if (pcmd && (*pcmd == ELS_CMD_FLOGI || |
| 8772 | *pcmd == ELS_CMD_SCR || | 8990 | *pcmd == ELS_CMD_SCR || |
| 8773 | *pcmd == ELS_CMD_FDISC || | 8991 | *pcmd == ELS_CMD_FDISC || |
| @@ -8870,31 +9088,36 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
| 8870 | } | 9088 | } |
| 8871 | /* Note, word 10 is already initialized to 0 */ | 9089 | /* Note, word 10 is already initialized to 0 */ |
| 8872 | 9090 | ||
| 9091 | /* Don't set PBDE for Perf hints, just fcp_embed_pbde */ | ||
| 9092 | if (phba->fcp_embed_pbde) | ||
| 9093 | bf_set(wqe_pbde, &wqe->fcp_iwrite.wqe_com, 1); | ||
| 9094 | else | ||
| 9095 | bf_set(wqe_pbde, &wqe->fcp_iwrite.wqe_com, 0); | ||
| 9096 | |||
| 8873 | if (phba->fcp_embed_io) { | 9097 | if (phba->fcp_embed_io) { |
| 8874 | struct lpfc_scsi_buf *lpfc_cmd; | 9098 | struct lpfc_scsi_buf *lpfc_cmd; |
| 8875 | struct sli4_sge *sgl; | 9099 | struct sli4_sge *sgl; |
| 8876 | union lpfc_wqe128 *wqe128; | ||
| 8877 | struct fcp_cmnd *fcp_cmnd; | 9100 | struct fcp_cmnd *fcp_cmnd; |
| 8878 | uint32_t *ptr; | 9101 | uint32_t *ptr; |
| 8879 | 9102 | ||
| 8880 | /* 128 byte wqe support here */ | 9103 | /* 128 byte wqe support here */ |
| 8881 | wqe128 = (union lpfc_wqe128 *)wqe; | ||
| 8882 | 9104 | ||
| 8883 | lpfc_cmd = iocbq->context1; | 9105 | lpfc_cmd = iocbq->context1; |
| 8884 | sgl = (struct sli4_sge *)lpfc_cmd->fcp_bpl; | 9106 | sgl = (struct sli4_sge *)lpfc_cmd->fcp_bpl; |
| 8885 | fcp_cmnd = lpfc_cmd->fcp_cmnd; | 9107 | fcp_cmnd = lpfc_cmd->fcp_cmnd; |
| 8886 | 9108 | ||
| 8887 | /* Word 0-2 - FCP_CMND */ | 9109 | /* Word 0-2 - FCP_CMND */ |
| 8888 | wqe128->generic.bde.tus.f.bdeFlags = | 9110 | wqe->generic.bde.tus.f.bdeFlags = |
| 8889 | BUFF_TYPE_BDE_IMMED; | 9111 | BUFF_TYPE_BDE_IMMED; |
| 8890 | wqe128->generic.bde.tus.f.bdeSize = sgl->sge_len; | 9112 | wqe->generic.bde.tus.f.bdeSize = sgl->sge_len; |
| 8891 | wqe128->generic.bde.addrHigh = 0; | 9113 | wqe->generic.bde.addrHigh = 0; |
| 8892 | wqe128->generic.bde.addrLow = 88; /* Word 22 */ | 9114 | wqe->generic.bde.addrLow = 88; /* Word 22 */ |
| 8893 | 9115 | ||
| 8894 | bf_set(wqe_wqes, &wqe128->fcp_iwrite.wqe_com, 1); | 9116 | bf_set(wqe_wqes, &wqe->fcp_iwrite.wqe_com, 1); |
| 9117 | bf_set(wqe_dbde, &wqe->fcp_iwrite.wqe_com, 0); | ||
| 8895 | 9118 | ||
| 8896 | /* Word 22-29 FCP CMND Payload */ | 9119 | /* Word 22-29 FCP CMND Payload */ |
| 8897 | ptr = &wqe128->words[22]; | 9120 | ptr = &wqe->words[22]; |
| 8898 | memcpy(ptr, fcp_cmnd, sizeof(struct fcp_cmnd)); | 9121 | memcpy(ptr, fcp_cmnd, sizeof(struct fcp_cmnd)); |
| 8899 | } | 9122 | } |
| 8900 | break; | 9123 | break; |
| @@ -8929,31 +9152,36 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
| 8929 | } | 9152 | } |
| 8930 | /* Note, word 10 is already initialized to 0 */ | 9153 | /* Note, word 10 is already initialized to 0 */ |
| 8931 | 9154 | ||
| 9155 | /* Don't set PBDE for Perf hints, just fcp_embed_pbde */ | ||
| 9156 | if (phba->fcp_embed_pbde) | ||
| 9157 | bf_set(wqe_pbde, &wqe->fcp_iread.wqe_com, 1); | ||
| 9158 | else | ||
| 9159 | bf_set(wqe_pbde, &wqe->fcp_iread.wqe_com, 0); | ||
| 9160 | |||
| 8932 | if (phba->fcp_embed_io) { | 9161 | if (phba->fcp_embed_io) { |
| 8933 | struct lpfc_scsi_buf *lpfc_cmd; | 9162 | struct lpfc_scsi_buf *lpfc_cmd; |
| 8934 | struct sli4_sge *sgl; | 9163 | struct sli4_sge *sgl; |
| 8935 | union lpfc_wqe128 *wqe128; | ||
| 8936 | struct fcp_cmnd *fcp_cmnd; | 9164 | struct fcp_cmnd *fcp_cmnd; |
| 8937 | uint32_t *ptr; | 9165 | uint32_t *ptr; |
| 8938 | 9166 | ||
| 8939 | /* 128 byte wqe support here */ | 9167 | /* 128 byte wqe support here */ |
| 8940 | wqe128 = (union lpfc_wqe128 *)wqe; | ||
| 8941 | 9168 | ||
| 8942 | lpfc_cmd = iocbq->context1; | 9169 | lpfc_cmd = iocbq->context1; |
| 8943 | sgl = (struct sli4_sge *)lpfc_cmd->fcp_bpl; | 9170 | sgl = (struct sli4_sge *)lpfc_cmd->fcp_bpl; |
| 8944 | fcp_cmnd = lpfc_cmd->fcp_cmnd; | 9171 | fcp_cmnd = lpfc_cmd->fcp_cmnd; |
| 8945 | 9172 | ||
| 8946 | /* Word 0-2 - FCP_CMND */ | 9173 | /* Word 0-2 - FCP_CMND */ |
| 8947 | wqe128->generic.bde.tus.f.bdeFlags = | 9174 | wqe->generic.bde.tus.f.bdeFlags = |
| 8948 | BUFF_TYPE_BDE_IMMED; | 9175 | BUFF_TYPE_BDE_IMMED; |
| 8949 | wqe128->generic.bde.tus.f.bdeSize = sgl->sge_len; | 9176 | wqe->generic.bde.tus.f.bdeSize = sgl->sge_len; |
| 8950 | wqe128->generic.bde.addrHigh = 0; | 9177 | wqe->generic.bde.addrHigh = 0; |
| 8951 | wqe128->generic.bde.addrLow = 88; /* Word 22 */ | 9178 | wqe->generic.bde.addrLow = 88; /* Word 22 */ |
| 8952 | 9179 | ||
| 8953 | bf_set(wqe_wqes, &wqe128->fcp_iread.wqe_com, 1); | 9180 | bf_set(wqe_wqes, &wqe->fcp_iread.wqe_com, 1); |
| 9181 | bf_set(wqe_dbde, &wqe->fcp_iread.wqe_com, 0); | ||
| 8954 | 9182 | ||
| 8955 | /* Word 22-29 FCP CMND Payload */ | 9183 | /* Word 22-29 FCP CMND Payload */ |
| 8956 | ptr = &wqe128->words[22]; | 9184 | ptr = &wqe->words[22]; |
| 8957 | memcpy(ptr, fcp_cmnd, sizeof(struct fcp_cmnd)); | 9185 | memcpy(ptr, fcp_cmnd, sizeof(struct fcp_cmnd)); |
| 8958 | } | 9186 | } |
| 8959 | break; | 9187 | break; |
| @@ -8990,28 +9218,27 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
| 8990 | if (phba->fcp_embed_io) { | 9218 | if (phba->fcp_embed_io) { |
| 8991 | struct lpfc_scsi_buf *lpfc_cmd; | 9219 | struct lpfc_scsi_buf *lpfc_cmd; |
| 8992 | struct sli4_sge *sgl; | 9220 | struct sli4_sge *sgl; |
| 8993 | union lpfc_wqe128 *wqe128; | ||
| 8994 | struct fcp_cmnd *fcp_cmnd; | 9221 | struct fcp_cmnd *fcp_cmnd; |
| 8995 | uint32_t *ptr; | 9222 | uint32_t *ptr; |
| 8996 | 9223 | ||
| 8997 | /* 128 byte wqe support here */ | 9224 | /* 128 byte wqe support here */ |
| 8998 | wqe128 = (union lpfc_wqe128 *)wqe; | ||
| 8999 | 9225 | ||
| 9000 | lpfc_cmd = iocbq->context1; | 9226 | lpfc_cmd = iocbq->context1; |
| 9001 | sgl = (struct sli4_sge *)lpfc_cmd->fcp_bpl; | 9227 | sgl = (struct sli4_sge *)lpfc_cmd->fcp_bpl; |
| 9002 | fcp_cmnd = lpfc_cmd->fcp_cmnd; | 9228 | fcp_cmnd = lpfc_cmd->fcp_cmnd; |
| 9003 | 9229 | ||
| 9004 | /* Word 0-2 - FCP_CMND */ | 9230 | /* Word 0-2 - FCP_CMND */ |
| 9005 | wqe128->generic.bde.tus.f.bdeFlags = | 9231 | wqe->generic.bde.tus.f.bdeFlags = |
| 9006 | BUFF_TYPE_BDE_IMMED; | 9232 | BUFF_TYPE_BDE_IMMED; |
| 9007 | wqe128->generic.bde.tus.f.bdeSize = sgl->sge_len; | 9233 | wqe->generic.bde.tus.f.bdeSize = sgl->sge_len; |
| 9008 | wqe128->generic.bde.addrHigh = 0; | 9234 | wqe->generic.bde.addrHigh = 0; |
| 9009 | wqe128->generic.bde.addrLow = 88; /* Word 22 */ | 9235 | wqe->generic.bde.addrLow = 88; /* Word 22 */ |
| 9010 | 9236 | ||
| 9011 | bf_set(wqe_wqes, &wqe128->fcp_icmd.wqe_com, 1); | 9237 | bf_set(wqe_wqes, &wqe->fcp_icmd.wqe_com, 1); |
| 9238 | bf_set(wqe_dbde, &wqe->fcp_icmd.wqe_com, 0); | ||
| 9012 | 9239 | ||
| 9013 | /* Word 22-29 FCP CMND Payload */ | 9240 | /* Word 22-29 FCP CMND Payload */ |
| 9014 | ptr = &wqe128->words[22]; | 9241 | ptr = &wqe->words[22]; |
| 9015 | memcpy(ptr, fcp_cmnd, sizeof(struct fcp_cmnd)); | 9242 | memcpy(ptr, fcp_cmnd, sizeof(struct fcp_cmnd)); |
| 9016 | } | 9243 | } |
| 9017 | break; | 9244 | break; |
| @@ -9064,7 +9291,7 @@ lpfc_sli4_iocb2wqe(struct lpfc_hba *phba, struct lpfc_iocbq *iocbq, | |||
| 9064 | 9291 | ||
| 9065 | if_type = bf_get(lpfc_sli_intf_if_type, | 9292 | if_type = bf_get(lpfc_sli_intf_if_type, |
| 9066 | &phba->sli4_hba.sli_intf); | 9293 | &phba->sli4_hba.sli_intf); |
| 9067 | if (if_type == LPFC_SLI_INTF_IF_TYPE_2) { | 9294 | if (if_type >= LPFC_SLI_INTF_IF_TYPE_2) { |
| 9068 | if (iocbq->vport->fc_flag & FC_PT2PT) { | 9295 | if (iocbq->vport->fc_flag & FC_PT2PT) { |
| 9069 | bf_set(els_rsp64_sp, &wqe->xmit_els_rsp, 1); | 9296 | bf_set(els_rsp64_sp, &wqe->xmit_els_rsp, 1); |
| 9070 | bf_set(els_rsp64_sid, &wqe->xmit_els_rsp, | 9297 | bf_set(els_rsp64_sid, &wqe->xmit_els_rsp, |
| @@ -9249,8 +9476,7 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number, | |||
| 9249 | struct lpfc_iocbq *piocb, uint32_t flag) | 9476 | struct lpfc_iocbq *piocb, uint32_t flag) |
| 9250 | { | 9477 | { |
| 9251 | struct lpfc_sglq *sglq; | 9478 | struct lpfc_sglq *sglq; |
| 9252 | union lpfc_wqe *wqe; | 9479 | union lpfc_wqe128 wqe; |
| 9253 | union lpfc_wqe128 wqe128; | ||
| 9254 | struct lpfc_queue *wq; | 9480 | struct lpfc_queue *wq; |
| 9255 | struct lpfc_sli_ring *pring; | 9481 | struct lpfc_sli_ring *pring; |
| 9256 | 9482 | ||
| @@ -9270,9 +9496,7 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number, | |||
| 9270 | 9496 | ||
| 9271 | /* | 9497 | /* |
| 9272 | * The WQE can be either 64 or 128 bytes, | 9498 | * The WQE can be either 64 or 128 bytes, |
| 9273 | * so allocate space on the stack assuming the largest. | ||
| 9274 | */ | 9499 | */ |
| 9275 | wqe = (union lpfc_wqe *)&wqe128; | ||
| 9276 | 9500 | ||
| 9277 | lockdep_assert_held(&phba->hbalock); | 9501 | lockdep_assert_held(&phba->hbalock); |
| 9278 | 9502 | ||
| @@ -9322,10 +9546,10 @@ __lpfc_sli_issue_iocb_s4(struct lpfc_hba *phba, uint32_t ring_number, | |||
| 9322 | return IOCB_ERROR; | 9546 | return IOCB_ERROR; |
| 9323 | } | 9547 | } |
| 9324 | 9548 | ||
| 9325 | if (lpfc_sli4_iocb2wqe(phba, piocb, wqe)) | 9549 | if (lpfc_sli4_iocb2wqe(phba, piocb, &wqe)) |
| 9326 | return IOCB_ERROR; | 9550 | return IOCB_ERROR; |
| 9327 | 9551 | ||
| 9328 | if (lpfc_sli4_wq_put(wq, wqe)) | 9552 | if (lpfc_sli4_wq_put(wq, &wqe)) |
| 9329 | return IOCB_ERROR; | 9553 | return IOCB_ERROR; |
| 9330 | lpfc_sli_ringtxcmpl_put(phba, pring, piocb); | 9554 | lpfc_sli_ringtxcmpl_put(phba, pring, piocb); |
| 9331 | 9555 | ||
| @@ -9470,7 +9694,7 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, uint32_t ring_number, | |||
| 9470 | fpeq = phba->sli4_hba.hba_eq[idx]; | 9694 | fpeq = phba->sli4_hba.hba_eq[idx]; |
| 9471 | 9695 | ||
| 9472 | /* Turn off interrupts from this EQ */ | 9696 | /* Turn off interrupts from this EQ */ |
| 9473 | lpfc_sli4_eq_clr_intr(fpeq); | 9697 | phba->sli4_hba.sli4_eq_clr_intr(fpeq); |
| 9474 | 9698 | ||
| 9475 | /* | 9699 | /* |
| 9476 | * Process all the events on FCP EQ | 9700 | * Process all the events on FCP EQ |
| @@ -9482,7 +9706,7 @@ lpfc_sli_issue_iocb(struct lpfc_hba *phba, uint32_t ring_number, | |||
| 9482 | } | 9706 | } |
| 9483 | 9707 | ||
| 9484 | /* Always clear and re-arm the EQ */ | 9708 | /* Always clear and re-arm the EQ */ |
| 9485 | lpfc_sli4_eq_release(fpeq, | 9709 | phba->sli4_hba.sli4_eq_release(fpeq, |
| 9486 | LPFC_QUEUE_REARM); | 9710 | LPFC_QUEUE_REARM); |
| 9487 | } | 9711 | } |
| 9488 | atomic_inc(&hba_eq_hdl->hba_eq_in_use); | 9712 | atomic_inc(&hba_eq_hdl->hba_eq_in_use); |
| @@ -10695,7 +10919,7 @@ lpfc_sli4_abort_nvme_io(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
| 10695 | { | 10919 | { |
| 10696 | struct lpfc_vport *vport = cmdiocb->vport; | 10920 | struct lpfc_vport *vport = cmdiocb->vport; |
| 10697 | struct lpfc_iocbq *abtsiocbp; | 10921 | struct lpfc_iocbq *abtsiocbp; |
| 10698 | union lpfc_wqe *abts_wqe; | 10922 | union lpfc_wqe128 *abts_wqe; |
| 10699 | int retval; | 10923 | int retval; |
| 10700 | 10924 | ||
| 10701 | /* | 10925 | /* |
| @@ -11442,31 +11666,25 @@ int | |||
| 11442 | lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq, | 11666 | lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq, |
| 11443 | uint32_t timeout) | 11667 | uint32_t timeout) |
| 11444 | { | 11668 | { |
| 11445 | DECLARE_WAIT_QUEUE_HEAD_ONSTACK(done_q); | 11669 | struct completion mbox_done; |
| 11446 | MAILBOX_t *mb = NULL; | ||
| 11447 | int retval; | 11670 | int retval; |
| 11448 | unsigned long flag; | 11671 | unsigned long flag; |
| 11449 | 11672 | ||
| 11450 | /* The caller might set context1 for extended buffer */ | ||
| 11451 | if (pmboxq->context1) | ||
| 11452 | mb = (MAILBOX_t *)pmboxq->context1; | ||
| 11453 | |||
| 11454 | pmboxq->mbox_flag &= ~LPFC_MBX_WAKE; | 11673 | pmboxq->mbox_flag &= ~LPFC_MBX_WAKE; |
| 11455 | /* setup wake call as IOCB callback */ | 11674 | /* setup wake call as IOCB callback */ |
| 11456 | pmboxq->mbox_cmpl = lpfc_sli_wake_mbox_wait; | 11675 | pmboxq->mbox_cmpl = lpfc_sli_wake_mbox_wait; |
| 11457 | /* setup context field to pass wait_queue pointer to wake function */ | ||
| 11458 | pmboxq->context1 = &done_q; | ||
| 11459 | 11676 | ||
| 11677 | /* setup context3 field to pass wait_queue pointer to wake function */ | ||
| 11678 | init_completion(&mbox_done); | ||
| 11679 | pmboxq->context3 = &mbox_done; | ||
| 11460 | /* now issue the command */ | 11680 | /* now issue the command */ |
| 11461 | retval = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT); | 11681 | retval = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT); |
| 11462 | if (retval == MBX_BUSY || retval == MBX_SUCCESS) { | 11682 | if (retval == MBX_BUSY || retval == MBX_SUCCESS) { |
| 11463 | wait_event_interruptible_timeout(done_q, | 11683 | wait_for_completion_timeout(&mbox_done, |
| 11464 | pmboxq->mbox_flag & LPFC_MBX_WAKE, | 11684 | msecs_to_jiffies(timeout * 1000)); |
| 11465 | msecs_to_jiffies(timeout * 1000)); | ||
| 11466 | 11685 | ||
| 11467 | spin_lock_irqsave(&phba->hbalock, flag); | 11686 | spin_lock_irqsave(&phba->hbalock, flag); |
| 11468 | /* restore the possible extended buffer for free resource */ | 11687 | pmboxq->context3 = NULL; |
| 11469 | pmboxq->context1 = (uint8_t *)mb; | ||
| 11470 | /* | 11688 | /* |
| 11471 | * if LPFC_MBX_WAKE flag is set the mailbox is completed | 11689 | * if LPFC_MBX_WAKE flag is set the mailbox is completed |
| 11472 | * else do not free the resources. | 11690 | * else do not free the resources. |
| @@ -11478,11 +11696,7 @@ lpfc_sli_issue_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq, | |||
| 11478 | pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 11696 | pmboxq->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
| 11479 | } | 11697 | } |
| 11480 | spin_unlock_irqrestore(&phba->hbalock, flag); | 11698 | spin_unlock_irqrestore(&phba->hbalock, flag); |
| 11481 | } else { | ||
| 11482 | /* restore the possible extended buffer for free resource */ | ||
| 11483 | pmboxq->context1 = (uint8_t *)mb; | ||
| 11484 | } | 11699 | } |
| 11485 | |||
| 11486 | return retval; | 11700 | return retval; |
| 11487 | } | 11701 | } |
| 11488 | 11702 | ||
| @@ -11648,6 +11862,7 @@ lpfc_sli4_eratt_read(struct lpfc_hba *phba) | |||
| 11648 | } | 11862 | } |
| 11649 | break; | 11863 | break; |
| 11650 | case LPFC_SLI_INTF_IF_TYPE_2: | 11864 | case LPFC_SLI_INTF_IF_TYPE_2: |
| 11865 | case LPFC_SLI_INTF_IF_TYPE_6: | ||
| 11651 | if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr, | 11866 | if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr, |
| 11652 | &portstat_reg.word0) || | 11867 | &portstat_reg.word0) || |
| 11653 | lpfc_readl(phba->sli4_hba.PSMPHRregaddr, | 11868 | lpfc_readl(phba->sli4_hba.PSMPHRregaddr, |
| @@ -13112,7 +13327,7 @@ lpfc_sli4_sp_process_cq(struct work_struct *work) | |||
| 13112 | "(x%x), type (%d)\n", cq->queue_id, cq->type); | 13327 | "(x%x), type (%d)\n", cq->queue_id, cq->type); |
| 13113 | 13328 | ||
| 13114 | /* In any case, flash and re-arm the RCQ */ | 13329 | /* In any case, flash and re-arm the RCQ */ |
| 13115 | lpfc_sli4_cq_release(cq, LPFC_QUEUE_REARM); | 13330 | phba->sli4_hba.sli4_cq_release(cq, LPFC_QUEUE_REARM); |
| 13116 | 13331 | ||
| 13117 | /* wake up worker thread if there are works to be done */ | 13332 | /* wake up worker thread if there are works to be done */ |
| 13118 | if (workposted) | 13333 | if (workposted) |
| @@ -13230,6 +13445,8 @@ lpfc_sli4_fp_handle_rel_wcqe(struct lpfc_hba *phba, struct lpfc_queue *cq, | |||
| 13230 | if (childwq->queue_id == hba_wqid) { | 13445 | if (childwq->queue_id == hba_wqid) { |
| 13231 | lpfc_sli4_wq_release(childwq, | 13446 | lpfc_sli4_wq_release(childwq, |
| 13232 | bf_get(lpfc_wcqe_r_wqe_index, wcqe)); | 13447 | bf_get(lpfc_wcqe_r_wqe_index, wcqe)); |
| 13448 | if (childwq->q_flag & HBA_NVMET_WQFULL) | ||
| 13449 | lpfc_nvmet_wqfull_process(phba, childwq); | ||
| 13233 | wqid_matched = true; | 13450 | wqid_matched = true; |
| 13234 | break; | 13451 | break; |
| 13235 | } | 13452 | } |
| @@ -13542,7 +13759,7 @@ lpfc_sli4_hba_process_cq(struct work_struct *work) | |||
| 13542 | "queue fcpcqid=%d\n", cq->queue_id); | 13759 | "queue fcpcqid=%d\n", cq->queue_id); |
| 13543 | 13760 | ||
| 13544 | /* In any case, flash and re-arm the CQ */ | 13761 | /* In any case, flash and re-arm the CQ */ |
| 13545 | lpfc_sli4_cq_release(cq, LPFC_QUEUE_REARM); | 13762 | phba->sli4_hba.sli4_cq_release(cq, LPFC_QUEUE_REARM); |
| 13546 | 13763 | ||
| 13547 | /* wake up worker thread if there are works to be done */ | 13764 | /* wake up worker thread if there are works to be done */ |
| 13548 | if (workposted) | 13765 | if (workposted) |
| @@ -13559,7 +13776,7 @@ lpfc_sli4_eq_flush(struct lpfc_hba *phba, struct lpfc_queue *eq) | |||
| 13559 | ; | 13776 | ; |
| 13560 | 13777 | ||
| 13561 | /* Clear and re-arm the EQ */ | 13778 | /* Clear and re-arm the EQ */ |
| 13562 | lpfc_sli4_eq_release(eq, LPFC_QUEUE_REARM); | 13779 | phba->sli4_hba.sli4_eq_release(eq, LPFC_QUEUE_REARM); |
| 13563 | } | 13780 | } |
| 13564 | 13781 | ||
| 13565 | 13782 | ||
| @@ -13707,7 +13924,7 @@ lpfc_sli4_fof_intr_handler(int irq, void *dev_id) | |||
| 13707 | } | 13924 | } |
| 13708 | } | 13925 | } |
| 13709 | /* Always clear and re-arm the fast-path EQ */ | 13926 | /* Always clear and re-arm the fast-path EQ */ |
| 13710 | lpfc_sli4_eq_release(eq, LPFC_QUEUE_REARM); | 13927 | phba->sli4_hba.sli4_eq_release(eq, LPFC_QUEUE_REARM); |
| 13711 | return IRQ_HANDLED; | 13928 | return IRQ_HANDLED; |
| 13712 | } | 13929 | } |
| 13713 | 13930 | ||
| @@ -13765,7 +13982,7 @@ lpfc_sli4_hba_intr_handler(int irq, void *dev_id) | |||
| 13765 | 13982 | ||
| 13766 | if (lpfc_fcp_look_ahead) { | 13983 | if (lpfc_fcp_look_ahead) { |
| 13767 | if (atomic_dec_and_test(&hba_eq_hdl->hba_eq_in_use)) | 13984 | if (atomic_dec_and_test(&hba_eq_hdl->hba_eq_in_use)) |
| 13768 | lpfc_sli4_eq_clr_intr(fpeq); | 13985 | phba->sli4_hba.sli4_eq_clr_intr(fpeq); |
| 13769 | else { | 13986 | else { |
| 13770 | atomic_inc(&hba_eq_hdl->hba_eq_in_use); | 13987 | atomic_inc(&hba_eq_hdl->hba_eq_in_use); |
| 13771 | return IRQ_NONE; | 13988 | return IRQ_NONE; |
| @@ -13800,7 +14017,7 @@ lpfc_sli4_hba_intr_handler(int irq, void *dev_id) | |||
| 13800 | fpeq->EQ_max_eqe = ecount; | 14017 | fpeq->EQ_max_eqe = ecount; |
| 13801 | 14018 | ||
| 13802 | /* Always clear and re-arm the fast-path EQ */ | 14019 | /* Always clear and re-arm the fast-path EQ */ |
| 13803 | lpfc_sli4_eq_release(fpeq, LPFC_QUEUE_REARM); | 14020 | phba->sli4_hba.sli4_eq_release(fpeq, LPFC_QUEUE_REARM); |
| 13804 | 14021 | ||
| 13805 | if (unlikely(ecount == 0)) { | 14022 | if (unlikely(ecount == 0)) { |
| 13806 | fpeq->EQ_no_entry++; | 14023 | fpeq->EQ_no_entry++; |
| @@ -13948,6 +14165,7 @@ lpfc_sli4_queue_alloc(struct lpfc_hba *phba, uint32_t page_size, | |||
| 13948 | 14165 | ||
| 13949 | INIT_LIST_HEAD(&queue->list); | 14166 | INIT_LIST_HEAD(&queue->list); |
| 13950 | INIT_LIST_HEAD(&queue->wq_list); | 14167 | INIT_LIST_HEAD(&queue->wq_list); |
| 14168 | INIT_LIST_HEAD(&queue->wqfull_list); | ||
| 13951 | INIT_LIST_HEAD(&queue->page_list); | 14169 | INIT_LIST_HEAD(&queue->page_list); |
| 13952 | INIT_LIST_HEAD(&queue->child_list); | 14170 | INIT_LIST_HEAD(&queue->child_list); |
| 13953 | 14171 | ||
| @@ -14173,11 +14391,21 @@ lpfc_eq_create(struct lpfc_hba *phba, struct lpfc_queue *eq, uint32_t imax) | |||
| 14173 | LPFC_MBOX_OPCODE_EQ_CREATE, | 14391 | LPFC_MBOX_OPCODE_EQ_CREATE, |
| 14174 | length, LPFC_SLI4_MBX_EMBED); | 14392 | length, LPFC_SLI4_MBX_EMBED); |
| 14175 | eq_create = &mbox->u.mqe.un.eq_create; | 14393 | eq_create = &mbox->u.mqe.un.eq_create; |
| 14394 | shdr = (union lpfc_sli4_cfg_shdr *) &eq_create->header.cfg_shdr; | ||
| 14176 | bf_set(lpfc_mbx_eq_create_num_pages, &eq_create->u.request, | 14395 | bf_set(lpfc_mbx_eq_create_num_pages, &eq_create->u.request, |
| 14177 | eq->page_count); | 14396 | eq->page_count); |
| 14178 | bf_set(lpfc_eq_context_size, &eq_create->u.request.context, | 14397 | bf_set(lpfc_eq_context_size, &eq_create->u.request.context, |
| 14179 | LPFC_EQE_SIZE); | 14398 | LPFC_EQE_SIZE); |
| 14180 | bf_set(lpfc_eq_context_valid, &eq_create->u.request.context, 1); | 14399 | bf_set(lpfc_eq_context_valid, &eq_create->u.request.context, 1); |
| 14400 | |||
| 14401 | /* Use version 2 of CREATE_EQ if eqav is set */ | ||
| 14402 | if (phba->sli4_hba.pc_sli4_params.eqav) { | ||
| 14403 | bf_set(lpfc_mbox_hdr_version, &shdr->request, | ||
| 14404 | LPFC_Q_CREATE_VERSION_2); | ||
| 14405 | bf_set(lpfc_eq_context_autovalid, &eq_create->u.request.context, | ||
| 14406 | phba->sli4_hba.pc_sli4_params.eqav); | ||
| 14407 | } | ||
| 14408 | |||
| 14181 | /* don't setup delay multiplier using EQ_CREATE */ | 14409 | /* don't setup delay multiplier using EQ_CREATE */ |
| 14182 | dmult = 0; | 14410 | dmult = 0; |
| 14183 | bf_set(lpfc_eq_context_delay_multi, &eq_create->u.request.context, | 14411 | bf_set(lpfc_eq_context_delay_multi, &eq_create->u.request.context, |
| @@ -14222,7 +14450,6 @@ lpfc_eq_create(struct lpfc_hba *phba, struct lpfc_queue *eq, uint32_t imax) | |||
| 14222 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 14450 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
| 14223 | mbox->context1 = NULL; | 14451 | mbox->context1 = NULL; |
| 14224 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); | 14452 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL); |
| 14225 | shdr = (union lpfc_sli4_cfg_shdr *) &eq_create->header.cfg_shdr; | ||
| 14226 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); | 14453 | shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response); |
| 14227 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); | 14454 | shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response); |
| 14228 | if (shdr_status || shdr_add_status || rc) { | 14455 | if (shdr_status || shdr_add_status || rc) { |
| @@ -14305,6 +14532,8 @@ lpfc_cq_create(struct lpfc_hba *phba, struct lpfc_queue *cq, | |||
| 14305 | (cq->page_size / SLI4_PAGE_SIZE)); | 14532 | (cq->page_size / SLI4_PAGE_SIZE)); |
| 14306 | bf_set(lpfc_cq_eq_id_2, &cq_create->u.request.context, | 14533 | bf_set(lpfc_cq_eq_id_2, &cq_create->u.request.context, |
| 14307 | eq->queue_id); | 14534 | eq->queue_id); |
| 14535 | bf_set(lpfc_cq_context_autovalid, &cq_create->u.request.context, | ||
| 14536 | phba->sli4_hba.pc_sli4_params.cqav); | ||
| 14308 | } else { | 14537 | } else { |
| 14309 | bf_set(lpfc_cq_eq_id, &cq_create->u.request.context, | 14538 | bf_set(lpfc_cq_eq_id, &cq_create->u.request.context, |
| 14310 | eq->queue_id); | 14539 | eq->queue_id); |
| @@ -14476,6 +14705,9 @@ lpfc_cq_create_set(struct lpfc_hba *phba, struct lpfc_queue **cqp, | |||
| 14476 | &cq_set->u.request, 0); | 14705 | &cq_set->u.request, 0); |
| 14477 | bf_set(lpfc_mbx_cq_create_set_num_cq, | 14706 | bf_set(lpfc_mbx_cq_create_set_num_cq, |
| 14478 | &cq_set->u.request, numcq); | 14707 | &cq_set->u.request, numcq); |
| 14708 | bf_set(lpfc_mbx_cq_create_set_autovalid, | ||
| 14709 | &cq_set->u.request, | ||
| 14710 | phba->sli4_hba.pc_sli4_params.cqav); | ||
| 14479 | switch (cq->entry_count) { | 14711 | switch (cq->entry_count) { |
| 14480 | case 2048: | 14712 | case 2048: |
| 14481 | case 4096: | 14713 | case 4096: |
| @@ -14881,6 +15113,9 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq, | |||
| 14881 | void __iomem *bar_memmap_p; | 15113 | void __iomem *bar_memmap_p; |
| 14882 | uint32_t db_offset; | 15114 | uint32_t db_offset; |
| 14883 | uint16_t pci_barset; | 15115 | uint16_t pci_barset; |
| 15116 | uint8_t dpp_barset; | ||
| 15117 | uint32_t dpp_offset; | ||
| 15118 | unsigned long pg_addr; | ||
| 14884 | uint8_t wq_create_version; | 15119 | uint8_t wq_create_version; |
| 14885 | 15120 | ||
| 14886 | /* sanity check on queue memory */ | 15121 | /* sanity check on queue memory */ |
| @@ -14908,43 +15143,19 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq, | |||
| 14908 | bf_set(lpfc_mbox_hdr_version, &shdr->request, | 15143 | bf_set(lpfc_mbox_hdr_version, &shdr->request, |
| 14909 | phba->sli4_hba.pc_sli4_params.wqv); | 15144 | phba->sli4_hba.pc_sli4_params.wqv); |
| 14910 | 15145 | ||
| 15146 | if ((phba->sli4_hba.pc_sli4_params.wqsize & LPFC_WQ_SZ128_SUPPORT) || | ||
| 15147 | (wq->page_size > SLI4_PAGE_SIZE)) | ||
| 15148 | wq_create_version = LPFC_Q_CREATE_VERSION_1; | ||
| 15149 | else | ||
| 15150 | wq_create_version = LPFC_Q_CREATE_VERSION_0; | ||
| 15151 | |||
| 15152 | |||
| 14911 | if (phba->sli4_hba.pc_sli4_params.wqsize & LPFC_WQ_SZ128_SUPPORT) | 15153 | if (phba->sli4_hba.pc_sli4_params.wqsize & LPFC_WQ_SZ128_SUPPORT) |
| 14912 | wq_create_version = LPFC_Q_CREATE_VERSION_1; | 15154 | wq_create_version = LPFC_Q_CREATE_VERSION_1; |
| 14913 | else | 15155 | else |
| 14914 | wq_create_version = LPFC_Q_CREATE_VERSION_0; | 15156 | wq_create_version = LPFC_Q_CREATE_VERSION_0; |
| 14915 | 15157 | ||
| 14916 | switch (wq_create_version) { | 15158 | switch (wq_create_version) { |
| 14917 | case LPFC_Q_CREATE_VERSION_0: | ||
| 14918 | switch (wq->entry_size) { | ||
| 14919 | default: | ||
| 14920 | case 64: | ||
| 14921 | /* Nothing to do, version 0 ONLY supports 64 byte */ | ||
| 14922 | page = wq_create->u.request.page; | ||
| 14923 | break; | ||
| 14924 | case 128: | ||
| 14925 | if (!(phba->sli4_hba.pc_sli4_params.wqsize & | ||
| 14926 | LPFC_WQ_SZ128_SUPPORT)) { | ||
| 14927 | status = -ERANGE; | ||
| 14928 | goto out; | ||
| 14929 | } | ||
| 14930 | /* If we get here the HBA MUST also support V1 and | ||
| 14931 | * we MUST use it | ||
| 14932 | */ | ||
| 14933 | bf_set(lpfc_mbox_hdr_version, &shdr->request, | ||
| 14934 | LPFC_Q_CREATE_VERSION_1); | ||
| 14935 | |||
| 14936 | bf_set(lpfc_mbx_wq_create_wqe_count, | ||
| 14937 | &wq_create->u.request_1, wq->entry_count); | ||
| 14938 | bf_set(lpfc_mbx_wq_create_wqe_size, | ||
| 14939 | &wq_create->u.request_1, | ||
| 14940 | LPFC_WQ_WQE_SIZE_128); | ||
| 14941 | bf_set(lpfc_mbx_wq_create_page_size, | ||
| 14942 | &wq_create->u.request_1, | ||
| 14943 | LPFC_WQ_PAGE_SIZE_4096); | ||
| 14944 | page = wq_create->u.request_1.page; | ||
| 14945 | break; | ||
| 14946 | } | ||
| 14947 | break; | ||
| 14948 | case LPFC_Q_CREATE_VERSION_1: | 15159 | case LPFC_Q_CREATE_VERSION_1: |
| 14949 | bf_set(lpfc_mbx_wq_create_wqe_count, &wq_create->u.request_1, | 15160 | bf_set(lpfc_mbx_wq_create_wqe_count, &wq_create->u.request_1, |
| 14950 | wq->entry_count); | 15161 | wq->entry_count); |
| @@ -14959,24 +15170,21 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq, | |||
| 14959 | LPFC_WQ_WQE_SIZE_64); | 15170 | LPFC_WQ_WQE_SIZE_64); |
| 14960 | break; | 15171 | break; |
| 14961 | case 128: | 15172 | case 128: |
| 14962 | if (!(phba->sli4_hba.pc_sli4_params.wqsize & | ||
| 14963 | LPFC_WQ_SZ128_SUPPORT)) { | ||
| 14964 | status = -ERANGE; | ||
| 14965 | goto out; | ||
| 14966 | } | ||
| 14967 | bf_set(lpfc_mbx_wq_create_wqe_size, | 15173 | bf_set(lpfc_mbx_wq_create_wqe_size, |
| 14968 | &wq_create->u.request_1, | 15174 | &wq_create->u.request_1, |
| 14969 | LPFC_WQ_WQE_SIZE_128); | 15175 | LPFC_WQ_WQE_SIZE_128); |
| 14970 | break; | 15176 | break; |
| 14971 | } | 15177 | } |
| 15178 | /* Request DPP by default */ | ||
| 15179 | bf_set(lpfc_mbx_wq_create_dpp_req, &wq_create->u.request_1, 1); | ||
| 14972 | bf_set(lpfc_mbx_wq_create_page_size, | 15180 | bf_set(lpfc_mbx_wq_create_page_size, |
| 14973 | &wq_create->u.request_1, | 15181 | &wq_create->u.request_1, |
| 14974 | (wq->page_size / SLI4_PAGE_SIZE)); | 15182 | (wq->page_size / SLI4_PAGE_SIZE)); |
| 14975 | page = wq_create->u.request_1.page; | 15183 | page = wq_create->u.request_1.page; |
| 14976 | break; | 15184 | break; |
| 14977 | default: | 15185 | default: |
| 14978 | status = -ERANGE; | 15186 | page = wq_create->u.request.page; |
| 14979 | goto out; | 15187 | break; |
| 14980 | } | 15188 | } |
| 14981 | 15189 | ||
| 14982 | list_for_each_entry(dmabuf, &wq->page_list, list) { | 15190 | list_for_each_entry(dmabuf, &wq->page_list, list) { |
| @@ -15000,52 +15208,120 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq, | |||
| 15000 | status = -ENXIO; | 15208 | status = -ENXIO; |
| 15001 | goto out; | 15209 | goto out; |
| 15002 | } | 15210 | } |
| 15003 | wq->queue_id = bf_get(lpfc_mbx_wq_create_q_id, &wq_create->u.response); | 15211 | |
| 15212 | if (wq_create_version == LPFC_Q_CREATE_VERSION_0) | ||
| 15213 | wq->queue_id = bf_get(lpfc_mbx_wq_create_q_id, | ||
| 15214 | &wq_create->u.response); | ||
| 15215 | else | ||
| 15216 | wq->queue_id = bf_get(lpfc_mbx_wq_create_v1_q_id, | ||
| 15217 | &wq_create->u.response_1); | ||
| 15218 | |||
| 15004 | if (wq->queue_id == 0xFFFF) { | 15219 | if (wq->queue_id == 0xFFFF) { |
| 15005 | status = -ENXIO; | 15220 | status = -ENXIO; |
| 15006 | goto out; | 15221 | goto out; |
| 15007 | } | 15222 | } |
| 15008 | if (phba->sli4_hba.fw_func_mode & LPFC_DUA_MODE) { | 15223 | |
| 15009 | wq->db_format = bf_get(lpfc_mbx_wq_create_db_format, | 15224 | wq->db_format = LPFC_DB_LIST_FORMAT; |
| 15010 | &wq_create->u.response); | 15225 | if (wq_create_version == LPFC_Q_CREATE_VERSION_0) { |
| 15011 | if ((wq->db_format != LPFC_DB_LIST_FORMAT) && | 15226 | if (phba->sli4_hba.fw_func_mode & LPFC_DUA_MODE) { |
| 15012 | (wq->db_format != LPFC_DB_RING_FORMAT)) { | 15227 | wq->db_format = bf_get(lpfc_mbx_wq_create_db_format, |
| 15013 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 15228 | &wq_create->u.response); |
| 15014 | "3265 WQ[%d] doorbell format not " | 15229 | if ((wq->db_format != LPFC_DB_LIST_FORMAT) && |
| 15015 | "supported: x%x\n", wq->queue_id, | 15230 | (wq->db_format != LPFC_DB_RING_FORMAT)) { |
| 15016 | wq->db_format); | 15231 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
| 15017 | status = -EINVAL; | 15232 | "3265 WQ[%d] doorbell format " |
| 15018 | goto out; | 15233 | "not supported: x%x\n", |
| 15019 | } | 15234 | wq->queue_id, wq->db_format); |
| 15020 | pci_barset = bf_get(lpfc_mbx_wq_create_bar_set, | 15235 | status = -EINVAL; |
| 15021 | &wq_create->u.response); | 15236 | goto out; |
| 15022 | bar_memmap_p = lpfc_dual_chute_pci_bar_map(phba, pci_barset); | 15237 | } |
| 15023 | if (!bar_memmap_p) { | 15238 | pci_barset = bf_get(lpfc_mbx_wq_create_bar_set, |
| 15024 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 15239 | &wq_create->u.response); |
| 15025 | "3263 WQ[%d] failed to memmap pci " | 15240 | bar_memmap_p = lpfc_dual_chute_pci_bar_map(phba, |
| 15026 | "barset:x%x\n", wq->queue_id, | 15241 | pci_barset); |
| 15027 | pci_barset); | 15242 | if (!bar_memmap_p) { |
| 15028 | status = -ENOMEM; | 15243 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
| 15029 | goto out; | 15244 | "3263 WQ[%d] failed to memmap " |
| 15030 | } | 15245 | "pci barset:x%x\n", |
| 15031 | db_offset = wq_create->u.response.doorbell_offset; | 15246 | wq->queue_id, pci_barset); |
| 15032 | if ((db_offset != LPFC_ULP0_WQ_DOORBELL) && | 15247 | status = -ENOMEM; |
| 15033 | (db_offset != LPFC_ULP1_WQ_DOORBELL)) { | 15248 | goto out; |
| 15034 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | 15249 | } |
| 15035 | "3252 WQ[%d] doorbell offset not " | 15250 | db_offset = wq_create->u.response.doorbell_offset; |
| 15036 | "supported: x%x\n", wq->queue_id, | 15251 | if ((db_offset != LPFC_ULP0_WQ_DOORBELL) && |
| 15037 | db_offset); | 15252 | (db_offset != LPFC_ULP1_WQ_DOORBELL)) { |
| 15038 | status = -EINVAL; | 15253 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, |
| 15039 | goto out; | 15254 | "3252 WQ[%d] doorbell offset " |
| 15040 | } | 15255 | "not supported: x%x\n", |
| 15041 | wq->db_regaddr = bar_memmap_p + db_offset; | 15256 | wq->queue_id, db_offset); |
| 15042 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | 15257 | status = -EINVAL; |
| 15043 | "3264 WQ[%d]: barset:x%x, offset:x%x, " | 15258 | goto out; |
| 15044 | "format:x%x\n", wq->queue_id, pci_barset, | 15259 | } |
| 15045 | db_offset, wq->db_format); | 15260 | wq->db_regaddr = bar_memmap_p + db_offset; |
| 15261 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | ||
| 15262 | "3264 WQ[%d]: barset:x%x, offset:x%x, " | ||
| 15263 | "format:x%x\n", wq->queue_id, | ||
| 15264 | pci_barset, db_offset, wq->db_format); | ||
| 15265 | } else | ||
| 15266 | wq->db_regaddr = phba->sli4_hba.WQDBregaddr; | ||
| 15046 | } else { | 15267 | } else { |
| 15047 | wq->db_format = LPFC_DB_LIST_FORMAT; | 15268 | /* Check if DPP was honored by the firmware */ |
| 15048 | wq->db_regaddr = phba->sli4_hba.WQDBregaddr; | 15269 | wq->dpp_enable = bf_get(lpfc_mbx_wq_create_dpp_rsp, |
| 15270 | &wq_create->u.response_1); | ||
| 15271 | if (wq->dpp_enable) { | ||
| 15272 | pci_barset = bf_get(lpfc_mbx_wq_create_v1_bar_set, | ||
| 15273 | &wq_create->u.response_1); | ||
| 15274 | bar_memmap_p = lpfc_dual_chute_pci_bar_map(phba, | ||
| 15275 | pci_barset); | ||
| 15276 | if (!bar_memmap_p) { | ||
| 15277 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
| 15278 | "3267 WQ[%d] failed to memmap " | ||
| 15279 | "pci barset:x%x\n", | ||
| 15280 | wq->queue_id, pci_barset); | ||
| 15281 | status = -ENOMEM; | ||
| 15282 | goto out; | ||
| 15283 | } | ||
| 15284 | db_offset = wq_create->u.response_1.doorbell_offset; | ||
| 15285 | wq->db_regaddr = bar_memmap_p + db_offset; | ||
| 15286 | wq->dpp_id = bf_get(lpfc_mbx_wq_create_dpp_id, | ||
| 15287 | &wq_create->u.response_1); | ||
| 15288 | dpp_barset = bf_get(lpfc_mbx_wq_create_dpp_bar, | ||
| 15289 | &wq_create->u.response_1); | ||
| 15290 | bar_memmap_p = lpfc_dual_chute_pci_bar_map(phba, | ||
| 15291 | dpp_barset); | ||
| 15292 | if (!bar_memmap_p) { | ||
| 15293 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
| 15294 | "3268 WQ[%d] failed to memmap " | ||
| 15295 | "pci barset:x%x\n", | ||
| 15296 | wq->queue_id, dpp_barset); | ||
| 15297 | status = -ENOMEM; | ||
| 15298 | goto out; | ||
| 15299 | } | ||
| 15300 | dpp_offset = wq_create->u.response_1.dpp_offset; | ||
| 15301 | wq->dpp_regaddr = bar_memmap_p + dpp_offset; | ||
| 15302 | lpfc_printf_log(phba, KERN_INFO, LOG_INIT, | ||
| 15303 | "3271 WQ[%d]: barset:x%x, offset:x%x, " | ||
| 15304 | "dpp_id:x%x dpp_barset:x%x " | ||
| 15305 | "dpp_offset:x%x\n", | ||
| 15306 | wq->queue_id, pci_barset, db_offset, | ||
| 15307 | wq->dpp_id, dpp_barset, dpp_offset); | ||
| 15308 | |||
| 15309 | /* Enable combined writes for DPP aperture */ | ||
| 15310 | pg_addr = (unsigned long)(wq->dpp_regaddr) & PAGE_MASK; | ||
| 15311 | #ifdef CONFIG_X86 | ||
| 15312 | rc = set_memory_wc(pg_addr, 1); | ||
| 15313 | if (rc) { | ||
| 15314 | lpfc_printf_log(phba, KERN_ERR, LOG_INIT, | ||
| 15315 | "3272 Cannot setup Combined " | ||
| 15316 | "Write on WQ[%d] - disable DPP\n", | ||
| 15317 | wq->queue_id); | ||
| 15318 | phba->cfg_enable_dpp = 0; | ||
| 15319 | } | ||
| 15320 | #else | ||
| 15321 | phba->cfg_enable_dpp = 0; | ||
| 15322 | #endif | ||
| 15323 | } else | ||
| 15324 | wq->db_regaddr = phba->sli4_hba.WQDBregaddr; | ||
| 15049 | } | 15325 | } |
| 15050 | wq->pring = kzalloc(sizeof(struct lpfc_sli_ring), GFP_KERNEL); | 15326 | wq->pring = kzalloc(sizeof(struct lpfc_sli_ring), GFP_KERNEL); |
| 15051 | if (wq->pring == NULL) { | 15327 | if (wq->pring == NULL) { |
| @@ -18616,6 +18892,7 @@ lpfc_wr_object(struct lpfc_hba *phba, struct list_head *dmabuf_list, | |||
| 18616 | "status x%x add_status x%x, mbx status x%x\n", | 18892 | "status x%x add_status x%x, mbx status x%x\n", |
| 18617 | shdr_status, shdr_add_status, rc); | 18893 | shdr_status, shdr_add_status, rc); |
| 18618 | rc = -ENXIO; | 18894 | rc = -ENXIO; |
| 18895 | *offset = shdr_add_status; | ||
| 18619 | } else | 18896 | } else |
| 18620 | *offset += wr_object->u.response.actual_write_length; | 18897 | *offset += wr_object->u.response.actual_write_length; |
| 18621 | return rc; | 18898 | return rc; |
| @@ -18753,8 +19030,7 @@ lpfc_drain_txq(struct lpfc_hba *phba) | |||
| 18753 | unsigned long iflags = 0; | 19030 | unsigned long iflags = 0; |
| 18754 | char *fail_msg = NULL; | 19031 | char *fail_msg = NULL; |
| 18755 | struct lpfc_sglq *sglq; | 19032 | struct lpfc_sglq *sglq; |
| 18756 | union lpfc_wqe128 wqe128; | 19033 | union lpfc_wqe128 wqe; |
| 18757 | union lpfc_wqe *wqe = (union lpfc_wqe *) &wqe128; | ||
| 18758 | uint32_t txq_cnt = 0; | 19034 | uint32_t txq_cnt = 0; |
| 18759 | 19035 | ||
| 18760 | pring = lpfc_phba_elsring(phba); | 19036 | pring = lpfc_phba_elsring(phba); |
| @@ -18797,9 +19073,9 @@ lpfc_drain_txq(struct lpfc_hba *phba) | |||
| 18797 | piocbq->sli4_xritag = sglq->sli4_xritag; | 19073 | piocbq->sli4_xritag = sglq->sli4_xritag; |
| 18798 | if (NO_XRI == lpfc_sli4_bpl2sgl(phba, piocbq, sglq)) | 19074 | if (NO_XRI == lpfc_sli4_bpl2sgl(phba, piocbq, sglq)) |
| 18799 | fail_msg = "to convert bpl to sgl"; | 19075 | fail_msg = "to convert bpl to sgl"; |
| 18800 | else if (lpfc_sli4_iocb2wqe(phba, piocbq, wqe)) | 19076 | else if (lpfc_sli4_iocb2wqe(phba, piocbq, &wqe)) |
| 18801 | fail_msg = "to convert iocb to wqe"; | 19077 | fail_msg = "to convert iocb to wqe"; |
| 18802 | else if (lpfc_sli4_wq_put(phba->sli4_hba.els_wq, wqe)) | 19078 | else if (lpfc_sli4_wq_put(phba->sli4_hba.els_wq, &wqe)) |
| 18803 | fail_msg = " - Wq is full"; | 19079 | fail_msg = " - Wq is full"; |
| 18804 | else | 19080 | else |
| 18805 | lpfc_sli_ringtxcmpl_put(phba, pring, piocbq); | 19081 | lpfc_sli_ringtxcmpl_put(phba, pring, piocbq); |
| @@ -18849,7 +19125,7 @@ lpfc_wqe_bpl2sgl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeq, | |||
| 18849 | struct ulp_bde64 bde; | 19125 | struct ulp_bde64 bde; |
| 18850 | struct sli4_sge *sgl = NULL; | 19126 | struct sli4_sge *sgl = NULL; |
| 18851 | struct lpfc_dmabuf *dmabuf; | 19127 | struct lpfc_dmabuf *dmabuf; |
| 18852 | union lpfc_wqe *wqe; | 19128 | union lpfc_wqe128 *wqe; |
| 18853 | int numBdes = 0; | 19129 | int numBdes = 0; |
| 18854 | int i = 0; | 19130 | int i = 0; |
| 18855 | uint32_t offset = 0; /* accumulated offset in the sg request list */ | 19131 | uint32_t offset = 0; /* accumulated offset in the sg request list */ |
| @@ -18958,7 +19234,7 @@ int | |||
| 18958 | lpfc_sli4_issue_wqe(struct lpfc_hba *phba, uint32_t ring_number, | 19234 | lpfc_sli4_issue_wqe(struct lpfc_hba *phba, uint32_t ring_number, |
| 18959 | struct lpfc_iocbq *pwqe) | 19235 | struct lpfc_iocbq *pwqe) |
| 18960 | { | 19236 | { |
| 18961 | union lpfc_wqe *wqe = &pwqe->wqe; | 19237 | union lpfc_wqe128 *wqe = &pwqe->wqe; |
| 18962 | struct lpfc_nvmet_rcv_ctx *ctxp; | 19238 | struct lpfc_nvmet_rcv_ctx *ctxp; |
| 18963 | struct lpfc_queue *wq; | 19239 | struct lpfc_queue *wq; |
| 18964 | struct lpfc_sglq *sglq; | 19240 | struct lpfc_sglq *sglq; |
diff --git a/drivers/scsi/lpfc/lpfc_sli.h b/drivers/scsi/lpfc/lpfc_sli.h index a3b1b5145d2b..431754195505 100644 --- a/drivers/scsi/lpfc/lpfc_sli.h +++ b/drivers/scsi/lpfc/lpfc_sli.h | |||
| @@ -61,9 +61,8 @@ struct lpfc_iocbq { | |||
| 61 | struct lpfc_wcqe_complete wcqe_cmpl; /* WQE cmpl */ | 61 | struct lpfc_wcqe_complete wcqe_cmpl; /* WQE cmpl */ |
| 62 | uint64_t isr_timestamp; | 62 | uint64_t isr_timestamp; |
| 63 | 63 | ||
| 64 | /* Be careful here */ | 64 | union lpfc_wqe128 wqe; /* SLI-4 */ |
| 65 | union lpfc_wqe wqe; /* WQE cmd */ | 65 | IOCB_t iocb; /* SLI-3 */ |
| 66 | IOCB_t iocb; /* For IOCB cmd or if we want 128 byte WQE */ | ||
| 67 | 66 | ||
| 68 | uint8_t rsvd2; | 67 | uint8_t rsvd2; |
| 69 | uint8_t priority; /* OAS priority */ | 68 | uint8_t priority; /* OAS priority */ |
| @@ -148,6 +147,7 @@ typedef struct lpfcMboxq { | |||
| 148 | struct lpfc_vport *vport;/* virtual port pointer */ | 147 | struct lpfc_vport *vport;/* virtual port pointer */ |
| 149 | void *context1; /* caller context information */ | 148 | void *context1; /* caller context information */ |
| 150 | void *context2; /* caller context information */ | 149 | void *context2; /* caller context information */ |
| 150 | void *context3; | ||
| 151 | 151 | ||
| 152 | void (*mbox_cmpl) (struct lpfc_hba *, struct lpfcMboxq *); | 152 | void (*mbox_cmpl) (struct lpfc_hba *, struct lpfcMboxq *); |
| 153 | uint8_t mbox_flag; | 153 | uint8_t mbox_flag; |
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index 81fb58e59e60..cf64aca82bd0 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2009-2016 Emulex. All rights reserved. * | 6 | * Copyright (C) 2009-2016 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -145,6 +145,7 @@ struct lpfc_rqb { | |||
| 145 | struct lpfc_queue { | 145 | struct lpfc_queue { |
| 146 | struct list_head list; | 146 | struct list_head list; |
| 147 | struct list_head wq_list; | 147 | struct list_head wq_list; |
| 148 | struct list_head wqfull_list; | ||
| 148 | enum lpfc_sli4_queue_type type; | 149 | enum lpfc_sli4_queue_type type; |
| 149 | enum lpfc_sli4_queue_subtype subtype; | 150 | enum lpfc_sli4_queue_subtype subtype; |
| 150 | struct lpfc_hba *phba; | 151 | struct lpfc_hba *phba; |
| @@ -173,10 +174,16 @@ struct lpfc_queue { | |||
| 173 | #define LPFC_EXPANDED_PAGE_SIZE 16384 | 174 | #define LPFC_EXPANDED_PAGE_SIZE 16384 |
| 174 | #define LPFC_DEFAULT_PAGE_SIZE 4096 | 175 | #define LPFC_DEFAULT_PAGE_SIZE 4096 |
| 175 | uint16_t chann; /* IO channel this queue is associated with */ | 176 | uint16_t chann; /* IO channel this queue is associated with */ |
| 176 | uint16_t db_format; | 177 | uint8_t db_format; |
| 177 | #define LPFC_DB_RING_FORMAT 0x01 | 178 | #define LPFC_DB_RING_FORMAT 0x01 |
| 178 | #define LPFC_DB_LIST_FORMAT 0x02 | 179 | #define LPFC_DB_LIST_FORMAT 0x02 |
| 180 | uint8_t q_flag; | ||
| 181 | #define HBA_NVMET_WQFULL 0x1 /* We hit WQ Full condition for NVMET */ | ||
| 179 | void __iomem *db_regaddr; | 182 | void __iomem *db_regaddr; |
| 183 | uint16_t dpp_enable; | ||
| 184 | uint16_t dpp_id; | ||
| 185 | void __iomem *dpp_regaddr; | ||
| 186 | |||
| 180 | /* For q stats */ | 187 | /* For q stats */ |
| 181 | uint32_t q_cnt_1; | 188 | uint32_t q_cnt_1; |
| 182 | uint32_t q_cnt_2; | 189 | uint32_t q_cnt_2; |
| @@ -209,6 +216,7 @@ struct lpfc_queue { | |||
| 209 | struct work_struct spwork; | 216 | struct work_struct spwork; |
| 210 | 217 | ||
| 211 | uint64_t isr_timestamp; | 218 | uint64_t isr_timestamp; |
| 219 | uint8_t qe_valid; | ||
| 212 | struct lpfc_queue *assoc_qp; | 220 | struct lpfc_queue *assoc_qp; |
| 213 | union sli4_qe qe[1]; /* array to index entries (must be last) */ | 221 | union sli4_qe qe[1]; /* array to index entries (must be last) */ |
| 214 | }; | 222 | }; |
| @@ -479,12 +487,19 @@ struct lpfc_pc_sli4_params { | |||
| 479 | uint8_t mqv; | 487 | uint8_t mqv; |
| 480 | uint8_t wqv; | 488 | uint8_t wqv; |
| 481 | uint8_t rqv; | 489 | uint8_t rqv; |
| 490 | uint8_t eqav; | ||
| 491 | uint8_t cqav; | ||
| 482 | uint8_t wqsize; | 492 | uint8_t wqsize; |
| 483 | #define LPFC_WQ_SZ64_SUPPORT 1 | 493 | #define LPFC_WQ_SZ64_SUPPORT 1 |
| 484 | #define LPFC_WQ_SZ128_SUPPORT 2 | 494 | #define LPFC_WQ_SZ128_SUPPORT 2 |
| 485 | uint8_t wqpcnt; | 495 | uint8_t wqpcnt; |
| 486 | }; | 496 | }; |
| 487 | 497 | ||
| 498 | #define LPFC_CQ_4K_PAGE_SZ 0x1 | ||
| 499 | #define LPFC_CQ_16K_PAGE_SZ 0x4 | ||
| 500 | #define LPFC_WQ_4K_PAGE_SZ 0x1 | ||
| 501 | #define LPFC_WQ_16K_PAGE_SZ 0x4 | ||
| 502 | |||
| 488 | struct lpfc_iov { | 503 | struct lpfc_iov { |
| 489 | uint32_t pf_number; | 504 | uint32_t pf_number; |
| 490 | uint32_t vf_number; | 505 | uint32_t vf_number; |
| @@ -516,11 +531,17 @@ struct lpfc_vector_map_info { | |||
| 516 | /* SLI4 HBA data structure entries */ | 531 | /* SLI4 HBA data structure entries */ |
| 517 | struct lpfc_sli4_hba { | 532 | struct lpfc_sli4_hba { |
| 518 | void __iomem *conf_regs_memmap_p; /* Kernel memory mapped address for | 533 | void __iomem *conf_regs_memmap_p; /* Kernel memory mapped address for |
| 519 | PCI BAR0, config space registers */ | 534 | * config space registers |
| 535 | */ | ||
| 520 | void __iomem *ctrl_regs_memmap_p; /* Kernel memory mapped address for | 536 | void __iomem *ctrl_regs_memmap_p; /* Kernel memory mapped address for |
| 521 | PCI BAR1, control registers */ | 537 | * control registers |
| 538 | */ | ||
| 522 | void __iomem *drbl_regs_memmap_p; /* Kernel memory mapped address for | 539 | void __iomem *drbl_regs_memmap_p; /* Kernel memory mapped address for |
| 523 | PCI BAR2, doorbell registers */ | 540 | * doorbell registers |
| 541 | */ | ||
| 542 | void __iomem *dpp_regs_memmap_p; /* Kernel memory mapped address for | ||
| 543 | * dpp registers | ||
| 544 | */ | ||
| 524 | union { | 545 | union { |
| 525 | struct { | 546 | struct { |
| 526 | /* IF Type 0, BAR 0 PCI cfg space reg mem map */ | 547 | /* IF Type 0, BAR 0 PCI cfg space reg mem map */ |
| @@ -561,7 +582,8 @@ struct lpfc_sli4_hba { | |||
| 561 | /* IF type 0, BAR 0 and if type 2, BAR 0 doorbell register memory map */ | 582 | /* IF type 0, BAR 0 and if type 2, BAR 0 doorbell register memory map */ |
| 562 | void __iomem *RQDBregaddr; /* RQ_DOORBELL register */ | 583 | void __iomem *RQDBregaddr; /* RQ_DOORBELL register */ |
| 563 | void __iomem *WQDBregaddr; /* WQ_DOORBELL register */ | 584 | void __iomem *WQDBregaddr; /* WQ_DOORBELL register */ |
| 564 | void __iomem *EQCQDBregaddr; /* EQCQ_DOORBELL register */ | 585 | void __iomem *CQDBregaddr; /* CQ_DOORBELL register */ |
| 586 | void __iomem *EQDBregaddr; /* EQ_DOORBELL register */ | ||
| 565 | void __iomem *MQDBregaddr; /* MQ_DOORBELL register */ | 587 | void __iomem *MQDBregaddr; /* MQ_DOORBELL register */ |
| 566 | void __iomem *BMBXregaddr; /* BootStrap MBX register */ | 588 | void __iomem *BMBXregaddr; /* BootStrap MBX register */ |
| 567 | 589 | ||
| @@ -574,6 +596,10 @@ struct lpfc_sli4_hba { | |||
| 574 | struct lpfc_bbscn_params bbscn_params; | 596 | struct lpfc_bbscn_params bbscn_params; |
| 575 | struct lpfc_hba_eq_hdl *hba_eq_hdl; /* HBA per-WQ handle */ | 597 | struct lpfc_hba_eq_hdl *hba_eq_hdl; /* HBA per-WQ handle */ |
| 576 | 598 | ||
| 599 | void (*sli4_eq_clr_intr)(struct lpfc_queue *q); | ||
| 600 | uint32_t (*sli4_eq_release)(struct lpfc_queue *q, bool arm); | ||
| 601 | uint32_t (*sli4_cq_release)(struct lpfc_queue *q, bool arm); | ||
| 602 | |||
| 577 | /* Pointers to the constructed SLI4 queues */ | 603 | /* Pointers to the constructed SLI4 queues */ |
| 578 | struct lpfc_queue **hba_eq; /* Event queues for HBA */ | 604 | struct lpfc_queue **hba_eq; /* Event queues for HBA */ |
| 579 | struct lpfc_queue **fcp_cq; /* Fast-path FCP compl queue */ | 605 | struct lpfc_queue **fcp_cq; /* Fast-path FCP compl queue */ |
| @@ -840,8 +866,12 @@ void lpfc_sli_remove_dflt_fcf(struct lpfc_hba *); | |||
| 840 | int lpfc_sli4_get_els_iocb_cnt(struct lpfc_hba *); | 866 | int lpfc_sli4_get_els_iocb_cnt(struct lpfc_hba *); |
| 841 | int lpfc_sli4_get_iocb_cnt(struct lpfc_hba *phba); | 867 | int lpfc_sli4_get_iocb_cnt(struct lpfc_hba *phba); |
| 842 | int lpfc_sli4_init_vpi(struct lpfc_vport *); | 868 | int lpfc_sli4_init_vpi(struct lpfc_vport *); |
| 869 | inline void lpfc_sli4_eq_clr_intr(struct lpfc_queue *); | ||
| 843 | uint32_t lpfc_sli4_cq_release(struct lpfc_queue *, bool); | 870 | uint32_t lpfc_sli4_cq_release(struct lpfc_queue *, bool); |
| 844 | uint32_t lpfc_sli4_eq_release(struct lpfc_queue *, bool); | 871 | uint32_t lpfc_sli4_eq_release(struct lpfc_queue *, bool); |
| 872 | inline void lpfc_sli4_if6_eq_clr_intr(struct lpfc_queue *q); | ||
| 873 | uint32_t lpfc_sli4_if6_cq_release(struct lpfc_queue *q, bool arm); | ||
| 874 | uint32_t lpfc_sli4_if6_eq_release(struct lpfc_queue *q, bool arm); | ||
| 845 | void lpfc_sli4_fcfi_unreg(struct lpfc_hba *, uint16_t); | 875 | void lpfc_sli4_fcfi_unreg(struct lpfc_hba *, uint16_t); |
| 846 | int lpfc_sli4_fcf_scan_read_fcf_rec(struct lpfc_hba *, uint16_t); | 876 | int lpfc_sli4_fcf_scan_read_fcf_rec(struct lpfc_hba *, uint16_t); |
| 847 | int lpfc_sli4_fcf_rr_read_fcf_rec(struct lpfc_hba *, uint16_t); | 877 | int lpfc_sli4_fcf_rr_read_fcf_rec(struct lpfc_hba *, uint16_t); |
diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index c232bf0e8998..e8b089abbfb3 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /******************************************************************* | 1 | /******************************************************************* |
| 2 | * This file is part of the Emulex Linux Device Driver for * | 2 | * This file is part of the Emulex Linux Device Driver for * |
| 3 | * Fibre Channel Host Bus Adapters. * | 3 | * Fibre Channel Host Bus Adapters. * |
| 4 | * Copyright (C) 2017 Broadcom. All Rights Reserved. The term * | 4 | * Copyright (C) 2017-2018 Broadcom. All Rights Reserved. The term * |
| 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * | 5 | * “Broadcom” refers to Broadcom Limited and/or its subsidiaries. * |
| 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * | 6 | * Copyright (C) 2004-2016 Emulex. All rights reserved. * |
| 7 | * EMULEX and SLI are trademarks of Emulex. * | 7 | * EMULEX and SLI are trademarks of Emulex. * |
| @@ -20,7 +20,7 @@ | |||
| 20 | * included with this package. * | 20 | * included with this package. * |
| 21 | *******************************************************************/ | 21 | *******************************************************************/ |
| 22 | 22 | ||
| 23 | #define LPFC_DRIVER_VERSION "11.4.0.6" | 23 | #define LPFC_DRIVER_VERSION "12.0.0.1" |
| 24 | #define LPFC_DRIVER_NAME "lpfc" | 24 | #define LPFC_DRIVER_NAME "lpfc" |
| 25 | 25 | ||
| 26 | /* Used for SLI 2/3 */ | 26 | /* Used for SLI 2/3 */ |
| @@ -32,6 +32,6 @@ | |||
| 32 | 32 | ||
| 33 | #define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \ | 33 | #define LPFC_MODULE_DESC "Emulex LightPulse Fibre Channel SCSI driver " \ |
| 34 | LPFC_DRIVER_VERSION | 34 | LPFC_DRIVER_VERSION |
| 35 | #define LPFC_COPYRIGHT "Copyright (C) 2017 Broadcom. All Rights Reserved. " \ | 35 | #define LPFC_COPYRIGHT "Copyright (C) 2017-2018 Broadcom. All Rights " \ |
| 36 | "The term \"Broadcom\" refers to Broadcom Limited " \ | 36 | "Reserved. The term \"Broadcom\" refers to Broadcom Limited " \ |
| 37 | "and/or its subsidiaries." | 37 | "and/or its subsidiaries." |
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 7a37ace4239b..b89c6e6c0589 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c | |||
| @@ -4022,7 +4022,7 @@ static int megasas_create_frame_pool(struct megasas_instance *instance) | |||
| 4022 | 4022 | ||
| 4023 | cmd = instance->cmd_list[i]; | 4023 | cmd = instance->cmd_list[i]; |
| 4024 | 4024 | ||
| 4025 | cmd->frame = dma_pool_alloc(instance->frame_dma_pool, | 4025 | cmd->frame = dma_pool_zalloc(instance->frame_dma_pool, |
| 4026 | GFP_KERNEL, &cmd->frame_phys_addr); | 4026 | GFP_KERNEL, &cmd->frame_phys_addr); |
| 4027 | 4027 | ||
| 4028 | cmd->sense = dma_pool_alloc(instance->sense_dma_pool, | 4028 | cmd->sense = dma_pool_alloc(instance->sense_dma_pool, |
| @@ -4038,7 +4038,6 @@ static int megasas_create_frame_pool(struct megasas_instance *instance) | |||
| 4038 | return -ENOMEM; | 4038 | return -ENOMEM; |
| 4039 | } | 4039 | } |
| 4040 | 4040 | ||
| 4041 | memset(cmd->frame, 0, instance->mfi_frame_size); | ||
| 4042 | cmd->frame->io.context = cpu_to_le32(cmd->index); | 4041 | cmd->frame->io.context = cpu_to_le32(cmd->index); |
| 4043 | cmd->frame->io.pad_0 = 0; | 4042 | cmd->frame->io.pad_0 = 0; |
| 4044 | if ((instance->adapter_type == MFI_SERIES) && reset_devices) | 4043 | if ((instance->adapter_type == MFI_SERIES) && reset_devices) |
diff --git a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h index ee117106d0f7..0ad88deb3176 100644 --- a/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h +++ b/drivers/scsi/mpt3sas/mpi/mpi2_cnfg.h | |||
| @@ -524,6 +524,7 @@ typedef struct _MPI2_CONFIG_REPLY { | |||
| 524 | #define MPI2_MFGPAGE_DEVID_SAS2308_1 (0x0086) | 524 | #define MPI2_MFGPAGE_DEVID_SAS2308_1 (0x0086) |
| 525 | #define MPI2_MFGPAGE_DEVID_SAS2308_2 (0x0087) | 525 | #define MPI2_MFGPAGE_DEVID_SAS2308_2 (0x0087) |
| 526 | #define MPI2_MFGPAGE_DEVID_SAS2308_3 (0x006E) | 526 | #define MPI2_MFGPAGE_DEVID_SAS2308_3 (0x006E) |
| 527 | #define MPI2_MFGPAGE_DEVID_SAS2308_MPI_EP (0x02B0) | ||
| 527 | 528 | ||
| 528 | /*MPI v2.5 SAS products */ | 529 | /*MPI v2.5 SAS products */ |
| 529 | #define MPI25_MFGPAGE_DEVID_SAS3004 (0x0096) | 530 | #define MPI25_MFGPAGE_DEVID_SAS3004 (0x0096) |
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c index 0aafbfd1b746..61f93a134956 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.c +++ b/drivers/scsi/mpt3sas/mpt3sas_base.c | |||
| @@ -126,6 +126,362 @@ module_param_call(mpt3sas_fwfault_debug, _scsih_set_fwfault_debug, | |||
| 126 | param_get_int, &mpt3sas_fwfault_debug, 0644); | 126 | param_get_int, &mpt3sas_fwfault_debug, 0644); |
| 127 | 127 | ||
| 128 | /** | 128 | /** |
| 129 | * _base_clone_reply_to_sys_mem - copies reply to reply free iomem | ||
| 130 | * in BAR0 space. | ||
| 131 | * | ||
| 132 | * @ioc: per adapter object | ||
| 133 | * @reply: reply message frame(lower 32bit addr) | ||
| 134 | * @index: System request message index. | ||
| 135 | * | ||
| 136 | * @Returns - Nothing | ||
| 137 | */ | ||
| 138 | static void | ||
| 139 | _base_clone_reply_to_sys_mem(struct MPT3SAS_ADAPTER *ioc, u32 reply, | ||
| 140 | u32 index) | ||
| 141 | { | ||
| 142 | /* | ||
| 143 | * 256 is offset within sys register. | ||
| 144 | * 256 offset MPI frame starts. Max MPI frame supported is 32. | ||
| 145 | * 32 * 128 = 4K. From here, Clone of reply free for mcpu starts | ||
| 146 | */ | ||
| 147 | u16 cmd_credit = ioc->facts.RequestCredit + 1; | ||
| 148 | void __iomem *reply_free_iomem = (void __iomem *)ioc->chip + | ||
| 149 | MPI_FRAME_START_OFFSET + | ||
| 150 | (cmd_credit * ioc->request_sz) + (index * sizeof(u32)); | ||
| 151 | |||
| 152 | writel(reply, reply_free_iomem); | ||
| 153 | } | ||
| 154 | |||
| 155 | /** | ||
| 156 | * _base_clone_mpi_to_sys_mem - Writes/copies MPI frames | ||
| 157 | * to system/BAR0 region. | ||
| 158 | * | ||
| 159 | * @dst_iomem: Pointer to the destinaltion location in BAR0 space. | ||
| 160 | * @src: Pointer to the Source data. | ||
| 161 | * @size: Size of data to be copied. | ||
| 162 | */ | ||
| 163 | static void | ||
| 164 | _base_clone_mpi_to_sys_mem(void *dst_iomem, void *src, u32 size) | ||
| 165 | { | ||
| 166 | int i; | ||
| 167 | u32 *src_virt_mem = (u32 *)src; | ||
| 168 | |||
| 169 | for (i = 0; i < size/4; i++) | ||
| 170 | writel((u32)src_virt_mem[i], | ||
| 171 | (void __iomem *)dst_iomem + (i * 4)); | ||
| 172 | } | ||
| 173 | |||
| 174 | /** | ||
| 175 | * _base_clone_to_sys_mem - Writes/copies data to system/BAR0 region | ||
| 176 | * | ||
| 177 | * @dst_iomem: Pointer to the destination location in BAR0 space. | ||
| 178 | * @src: Pointer to the Source data. | ||
| 179 | * @size: Size of data to be copied. | ||
| 180 | */ | ||
| 181 | static void | ||
| 182 | _base_clone_to_sys_mem(void __iomem *dst_iomem, void *src, u32 size) | ||
| 183 | { | ||
| 184 | int i; | ||
| 185 | u32 *src_virt_mem = (u32 *)(src); | ||
| 186 | |||
| 187 | for (i = 0; i < size/4; i++) | ||
| 188 | writel((u32)src_virt_mem[i], | ||
| 189 | (void __iomem *)dst_iomem + (i * 4)); | ||
| 190 | } | ||
| 191 | |||
| 192 | /** | ||
| 193 | * _base_get_chain - Calculates and Returns virtual chain address | ||
| 194 | * for the provided smid in BAR0 space. | ||
| 195 | * | ||
| 196 | * @ioc: per adapter object | ||
| 197 | * @smid: system request message index | ||
| 198 | * @sge_chain_count: Scatter gather chain count. | ||
| 199 | * | ||
| 200 | * @Return: chain address. | ||
| 201 | */ | ||
| 202 | static inline void __iomem* | ||
| 203 | _base_get_chain(struct MPT3SAS_ADAPTER *ioc, u16 smid, | ||
| 204 | u8 sge_chain_count) | ||
| 205 | { | ||
| 206 | void __iomem *base_chain, *chain_virt; | ||
| 207 | u16 cmd_credit = ioc->facts.RequestCredit + 1; | ||
| 208 | |||
| 209 | base_chain = (void __iomem *)ioc->chip + MPI_FRAME_START_OFFSET + | ||
| 210 | (cmd_credit * ioc->request_sz) + | ||
| 211 | REPLY_FREE_POOL_SIZE; | ||
| 212 | chain_virt = base_chain + (smid * ioc->facts.MaxChainDepth * | ||
| 213 | ioc->request_sz) + (sge_chain_count * ioc->request_sz); | ||
| 214 | return chain_virt; | ||
| 215 | } | ||
| 216 | |||
| 217 | /** | ||
| 218 | * _base_get_chain_phys - Calculates and Returns physical address | ||
| 219 | * in BAR0 for scatter gather chains, for | ||
| 220 | * the provided smid. | ||
| 221 | * | ||
| 222 | * @ioc: per adapter object | ||
| 223 | * @smid: system request message index | ||
| 224 | * @sge_chain_count: Scatter gather chain count. | ||
| 225 | * | ||
| 226 | * @Return - Physical chain address. | ||
| 227 | */ | ||
| 228 | static inline phys_addr_t | ||
| 229 | _base_get_chain_phys(struct MPT3SAS_ADAPTER *ioc, u16 smid, | ||
| 230 | u8 sge_chain_count) | ||
| 231 | { | ||
| 232 | phys_addr_t base_chain_phys, chain_phys; | ||
| 233 | u16 cmd_credit = ioc->facts.RequestCredit + 1; | ||
| 234 | |||
| 235 | base_chain_phys = ioc->chip_phys + MPI_FRAME_START_OFFSET + | ||
| 236 | (cmd_credit * ioc->request_sz) + | ||
| 237 | REPLY_FREE_POOL_SIZE; | ||
| 238 | chain_phys = base_chain_phys + (smid * ioc->facts.MaxChainDepth * | ||
| 239 | ioc->request_sz) + (sge_chain_count * ioc->request_sz); | ||
| 240 | return chain_phys; | ||
| 241 | } | ||
| 242 | |||
| 243 | /** | ||
| 244 | * _base_get_buffer_bar0 - Calculates and Returns BAR0 mapped Host | ||
| 245 | * buffer address for the provided smid. | ||
| 246 | * (Each smid can have 64K starts from 17024) | ||
| 247 | * | ||
| 248 | * @ioc: per adapter object | ||
| 249 | * @smid: system request message index | ||
| 250 | * | ||
| 251 | * @Returns - Pointer to buffer location in BAR0. | ||
| 252 | */ | ||
| 253 | |||
| 254 | static void __iomem * | ||
| 255 | _base_get_buffer_bar0(struct MPT3SAS_ADAPTER *ioc, u16 smid) | ||
| 256 | { | ||
| 257 | u16 cmd_credit = ioc->facts.RequestCredit + 1; | ||
| 258 | // Added extra 1 to reach end of chain. | ||
| 259 | void __iomem *chain_end = _base_get_chain(ioc, | ||
| 260 | cmd_credit + 1, | ||
| 261 | ioc->facts.MaxChainDepth); | ||
| 262 | return chain_end + (smid * 64 * 1024); | ||
| 263 | } | ||
| 264 | |||
| 265 | /** | ||
| 266 | * _base_get_buffer_phys_bar0 - Calculates and Returns BAR0 mapped | ||
| 267 | * Host buffer Physical address for the provided smid. | ||
| 268 | * (Each smid can have 64K starts from 17024) | ||
| 269 | * | ||
| 270 | * @ioc: per adapter object | ||
| 271 | * @smid: system request message index | ||
| 272 | * | ||
| 273 | * @Returns - Pointer to buffer location in BAR0. | ||
| 274 | */ | ||
| 275 | static phys_addr_t | ||
| 276 | _base_get_buffer_phys_bar0(struct MPT3SAS_ADAPTER *ioc, u16 smid) | ||
| 277 | { | ||
| 278 | u16 cmd_credit = ioc->facts.RequestCredit + 1; | ||
| 279 | phys_addr_t chain_end_phys = _base_get_chain_phys(ioc, | ||
| 280 | cmd_credit + 1, | ||
| 281 | ioc->facts.MaxChainDepth); | ||
| 282 | return chain_end_phys + (smid * 64 * 1024); | ||
| 283 | } | ||
| 284 | |||
| 285 | /** | ||
| 286 | * _base_get_chain_buffer_dma_to_chain_buffer - Iterates chain | ||
| 287 | * lookup list and Provides chain_buffer | ||
| 288 | * address for the matching dma address. | ||
| 289 | * (Each smid can have 64K starts from 17024) | ||
| 290 | * | ||
| 291 | * @ioc: per adapter object | ||
| 292 | * @chain_buffer_dma: Chain buffer dma address. | ||
| 293 | * | ||
| 294 | * @Returns - Pointer to chain buffer. Or Null on Failure. | ||
| 295 | */ | ||
| 296 | static void * | ||
| 297 | _base_get_chain_buffer_dma_to_chain_buffer(struct MPT3SAS_ADAPTER *ioc, | ||
| 298 | dma_addr_t chain_buffer_dma) | ||
| 299 | { | ||
| 300 | u16 index; | ||
| 301 | |||
| 302 | for (index = 0; index < ioc->chain_depth; index++) { | ||
| 303 | if (ioc->chain_lookup[index].chain_buffer_dma == | ||
| 304 | chain_buffer_dma) | ||
| 305 | return ioc->chain_lookup[index].chain_buffer; | ||
| 306 | } | ||
| 307 | pr_info(MPT3SAS_FMT | ||
| 308 | "Provided chain_buffer_dma address is not in the lookup list\n", | ||
| 309 | ioc->name); | ||
| 310 | return NULL; | ||
| 311 | } | ||
| 312 | |||
| 313 | /** | ||
| 314 | * _clone_sg_entries - MPI EP's scsiio and config requests | ||
| 315 | * are handled here. Base function for | ||
| 316 | * double buffering, before submitting | ||
| 317 | * the requests. | ||
| 318 | * | ||
| 319 | * @ioc: per adapter object. | ||
| 320 | * @mpi_request: mf request pointer. | ||
| 321 | * @smid: system request message index. | ||
| 322 | * | ||
| 323 | * @Returns: Nothing. | ||
| 324 | */ | ||
| 325 | static void _clone_sg_entries(struct MPT3SAS_ADAPTER *ioc, | ||
| 326 | void *mpi_request, u16 smid) | ||
| 327 | { | ||
| 328 | Mpi2SGESimple32_t *sgel, *sgel_next; | ||
| 329 | u32 sgl_flags, sge_chain_count = 0; | ||
| 330 | bool is_write = 0; | ||
| 331 | u16 i = 0; | ||
| 332 | void __iomem *buffer_iomem; | ||
| 333 | phys_addr_t buffer_iomem_phys; | ||
| 334 | void __iomem *buff_ptr; | ||
| 335 | phys_addr_t buff_ptr_phys; | ||
| 336 | void __iomem *dst_chain_addr[MCPU_MAX_CHAINS_PER_IO]; | ||
| 337 | void *src_chain_addr[MCPU_MAX_CHAINS_PER_IO]; | ||
| 338 | phys_addr_t dst_addr_phys; | ||
| 339 | MPI2RequestHeader_t *request_hdr; | ||
| 340 | struct scsi_cmnd *scmd; | ||
| 341 | struct scatterlist *sg_scmd = NULL; | ||
| 342 | int is_scsiio_req = 0; | ||
| 343 | |||
| 344 | request_hdr = (MPI2RequestHeader_t *) mpi_request; | ||
| 345 | |||
| 346 | if (request_hdr->Function == MPI2_FUNCTION_SCSI_IO_REQUEST) { | ||
| 347 | Mpi25SCSIIORequest_t *scsiio_request = | ||
| 348 | (Mpi25SCSIIORequest_t *)mpi_request; | ||
| 349 | sgel = (Mpi2SGESimple32_t *) &scsiio_request->SGL; | ||
| 350 | is_scsiio_req = 1; | ||
| 351 | } else if (request_hdr->Function == MPI2_FUNCTION_CONFIG) { | ||
| 352 | Mpi2ConfigRequest_t *config_req = | ||
| 353 | (Mpi2ConfigRequest_t *)mpi_request; | ||
| 354 | sgel = (Mpi2SGESimple32_t *) &config_req->PageBufferSGE; | ||
| 355 | } else | ||
| 356 | return; | ||
| 357 | |||
| 358 | /* From smid we can get scsi_cmd, once we have sg_scmd, | ||
| 359 | * we just need to get sg_virt and sg_next to get virual | ||
| 360 | * address associated with sgel->Address. | ||
| 361 | */ | ||
| 362 | |||
| 363 | if (is_scsiio_req) { | ||
| 364 | /* Get scsi_cmd using smid */ | ||
| 365 | scmd = mpt3sas_scsih_scsi_lookup_get(ioc, smid); | ||
| 366 | if (scmd == NULL) { | ||
| 367 | pr_err(MPT3SAS_FMT "scmd is NULL\n", ioc->name); | ||
| 368 | return; | ||
| 369 | } | ||
| 370 | |||
| 371 | /* Get sg_scmd from scmd provided */ | ||
| 372 | sg_scmd = scsi_sglist(scmd); | ||
| 373 | } | ||
| 374 | |||
| 375 | /* | ||
| 376 | * 0 - 255 System register | ||
| 377 | * 256 - 4352 MPI Frame. (This is based on maxCredit 32) | ||
| 378 | * 4352 - 4864 Reply_free pool (512 byte is reserved | ||
| 379 | * considering maxCredit 32. Reply need extra | ||
| 380 | * room, for mCPU case kept four times of | ||
| 381 | * maxCredit). | ||
| 382 | * 4864 - 17152 SGE chain element. (32cmd * 3 chain of | ||
| 383 | * 128 byte size = 12288) | ||
| 384 | * 17152 - x Host buffer mapped with smid. | ||
| 385 | * (Each smid can have 64K Max IO.) | ||
| 386 | * BAR0+Last 1K MSIX Addr and Data | ||
| 387 | * Total size in use 2113664 bytes of 4MB BAR0 | ||
| 388 | */ | ||
| 389 | |||
| 390 | buffer_iomem = _base_get_buffer_bar0(ioc, smid); | ||
| 391 | buffer_iomem_phys = _base_get_buffer_phys_bar0(ioc, smid); | ||
| 392 | |||
| 393 | buff_ptr = buffer_iomem; | ||
| 394 | buff_ptr_phys = buffer_iomem_phys; | ||
| 395 | WARN_ON(buff_ptr_phys > U32_MAX); | ||
| 396 | |||
| 397 | if (sgel->FlagsLength & | ||
| 398 | (MPI2_SGE_FLAGS_HOST_TO_IOC << MPI2_SGE_FLAGS_SHIFT)) | ||
| 399 | is_write = 1; | ||
| 400 | |||
| 401 | for (i = 0; i < MPT_MIN_PHYS_SEGMENTS + ioc->facts.MaxChainDepth; i++) { | ||
| 402 | |||
| 403 | sgl_flags = (sgel->FlagsLength >> MPI2_SGE_FLAGS_SHIFT); | ||
| 404 | |||
| 405 | switch (sgl_flags & MPI2_SGE_FLAGS_ELEMENT_MASK) { | ||
| 406 | case MPI2_SGE_FLAGS_CHAIN_ELEMENT: | ||
| 407 | /* | ||
| 408 | * Helper function which on passing | ||
| 409 | * chain_buffer_dma returns chain_buffer. Get | ||
| 410 | * the virtual address for sgel->Address | ||
| 411 | */ | ||
| 412 | sgel_next = | ||
| 413 | _base_get_chain_buffer_dma_to_chain_buffer(ioc, | ||
| 414 | sgel->Address); | ||
| 415 | if (sgel_next == NULL) | ||
| 416 | return; | ||
| 417 | /* | ||
| 418 | * This is coping 128 byte chain | ||
| 419 | * frame (not a host buffer) | ||
| 420 | */ | ||
| 421 | dst_chain_addr[sge_chain_count] = | ||
| 422 | _base_get_chain(ioc, | ||
| 423 | smid, sge_chain_count); | ||
| 424 | src_chain_addr[sge_chain_count] = | ||
| 425 | (void *) sgel_next; | ||
| 426 | dst_addr_phys = _base_get_chain_phys(ioc, | ||
| 427 | smid, sge_chain_count); | ||
| 428 | WARN_ON(dst_addr_phys > U32_MAX); | ||
| 429 | sgel->Address = (u32)dst_addr_phys; | ||
| 430 | sgel = sgel_next; | ||
| 431 | sge_chain_count++; | ||
| 432 | break; | ||
| 433 | case MPI2_SGE_FLAGS_SIMPLE_ELEMENT: | ||
| 434 | if (is_write) { | ||
| 435 | if (is_scsiio_req) { | ||
| 436 | _base_clone_to_sys_mem(buff_ptr, | ||
| 437 | sg_virt(sg_scmd), | ||
| 438 | (sgel->FlagsLength & 0x00ffffff)); | ||
| 439 | /* | ||
| 440 | * FIXME: this relies on a a zero | ||
| 441 | * PCI mem_offset. | ||
| 442 | */ | ||
| 443 | sgel->Address = (u32)buff_ptr_phys; | ||
| 444 | } else { | ||
| 445 | _base_clone_to_sys_mem(buff_ptr, | ||
| 446 | ioc->config_vaddr, | ||
| 447 | (sgel->FlagsLength & 0x00ffffff)); | ||
| 448 | sgel->Address = (u32)buff_ptr_phys; | ||
| 449 | } | ||
| 450 | } | ||
| 451 | buff_ptr += (sgel->FlagsLength & 0x00ffffff); | ||
| 452 | buff_ptr_phys += (sgel->FlagsLength & 0x00ffffff); | ||
| 453 | if ((sgel->FlagsLength & | ||
| 454 | (MPI2_SGE_FLAGS_END_OF_BUFFER | ||
| 455 | << MPI2_SGE_FLAGS_SHIFT))) | ||
| 456 | goto eob_clone_chain; | ||
| 457 | else { | ||
| 458 | /* | ||
| 459 | * Every single element in MPT will have | ||
| 460 | * associated sg_next. Better to sanity that | ||
| 461 | * sg_next is not NULL, but it will be a bug | ||
| 462 | * if it is null. | ||
| 463 | */ | ||
| 464 | if (is_scsiio_req) { | ||
| 465 | sg_scmd = sg_next(sg_scmd); | ||
| 466 | if (sg_scmd) | ||
| 467 | sgel++; | ||
| 468 | else | ||
| 469 | goto eob_clone_chain; | ||
| 470 | } | ||
| 471 | } | ||
| 472 | break; | ||
| 473 | } | ||
| 474 | } | ||
| 475 | |||
| 476 | eob_clone_chain: | ||
| 477 | for (i = 0; i < sge_chain_count; i++) { | ||
| 478 | if (is_scsiio_req) | ||
| 479 | _base_clone_to_sys_mem(dst_chain_addr[i], | ||
| 480 | src_chain_addr[i], ioc->request_sz); | ||
| 481 | } | ||
| 482 | } | ||
| 483 | |||
| 484 | /** | ||
| 129 | * mpt3sas_remove_dead_ioc_func - kthread context to remove dead ioc | 485 | * mpt3sas_remove_dead_ioc_func - kthread context to remove dead ioc |
| 130 | * @arg: input argument, used to derive ioc | 486 | * @arg: input argument, used to derive ioc |
| 131 | * | 487 | * |
| @@ -875,7 +1231,7 @@ _base_async_event(struct MPT3SAS_ADAPTER *ioc, u8 msix_index, u32 reply) | |||
| 875 | ack_request->EventContext = mpi_reply->EventContext; | 1231 | ack_request->EventContext = mpi_reply->EventContext; |
| 876 | ack_request->VF_ID = 0; /* TODO */ | 1232 | ack_request->VF_ID = 0; /* TODO */ |
| 877 | ack_request->VP_ID = 0; | 1233 | ack_request->VP_ID = 0; |
| 878 | ioc->put_smid_default(ioc, smid); | 1234 | mpt3sas_base_put_smid_default(ioc, smid); |
| 879 | 1235 | ||
| 880 | out: | 1236 | out: |
| 881 | 1237 | ||
| @@ -1075,6 +1431,10 @@ _base_interrupt(int irq, void *bus_id) | |||
| 1075 | 0 : ioc->reply_free_host_index + 1; | 1431 | 0 : ioc->reply_free_host_index + 1; |
| 1076 | ioc->reply_free[ioc->reply_free_host_index] = | 1432 | ioc->reply_free[ioc->reply_free_host_index] = |
| 1077 | cpu_to_le32(reply); | 1433 | cpu_to_le32(reply); |
| 1434 | if (ioc->is_mcpu_endpoint) | ||
| 1435 | _base_clone_reply_to_sys_mem(ioc, | ||
| 1436 | cpu_to_le32(reply), | ||
| 1437 | ioc->reply_free_host_index); | ||
| 1078 | writel(ioc->reply_free_host_index, | 1438 | writel(ioc->reply_free_host_index, |
| 1079 | &ioc->chip->ReplyFreeHostIndex); | 1439 | &ioc->chip->ReplyFreeHostIndex); |
| 1080 | } | 1440 | } |
| @@ -2214,6 +2574,9 @@ _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev) | |||
| 2214 | struct sysinfo s; | 2574 | struct sysinfo s; |
| 2215 | u64 consistent_dma_mask; | 2575 | u64 consistent_dma_mask; |
| 2216 | 2576 | ||
| 2577 | if (ioc->is_mcpu_endpoint) | ||
| 2578 | goto try_32bit; | ||
| 2579 | |||
| 2217 | if (ioc->dma_mask) | 2580 | if (ioc->dma_mask) |
| 2218 | consistent_dma_mask = DMA_BIT_MASK(64); | 2581 | consistent_dma_mask = DMA_BIT_MASK(64); |
| 2219 | else | 2582 | else |
| @@ -2232,6 +2595,7 @@ _base_config_dma_addressing(struct MPT3SAS_ADAPTER *ioc, struct pci_dev *pdev) | |||
| 2232 | } | 2595 | } |
| 2233 | } | 2596 | } |
| 2234 | 2597 | ||
| 2598 | try_32bit: | ||
| 2235 | if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) | 2599 | if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) |
| 2236 | && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { | 2600 | && !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { |
| 2237 | ioc->base_add_sg_single = &_base_add_sg_single_32; | 2601 | ioc->base_add_sg_single = &_base_add_sg_single_32; |
| @@ -2581,7 +2945,7 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc) | |||
| 2581 | u32 pio_sz; | 2945 | u32 pio_sz; |
| 2582 | int i, r = 0; | 2946 | int i, r = 0; |
| 2583 | u64 pio_chip = 0; | 2947 | u64 pio_chip = 0; |
| 2584 | u64 chip_phys = 0; | 2948 | phys_addr_t chip_phys = 0; |
| 2585 | struct adapter_reply_queue *reply_q; | 2949 | struct adapter_reply_queue *reply_q; |
| 2586 | 2950 | ||
| 2587 | dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", | 2951 | dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", |
| @@ -2629,7 +2993,7 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc) | |||
| 2629 | if (memap_sz) | 2993 | if (memap_sz) |
| 2630 | continue; | 2994 | continue; |
| 2631 | ioc->chip_phys = pci_resource_start(pdev, i); | 2995 | ioc->chip_phys = pci_resource_start(pdev, i); |
| 2632 | chip_phys = (u64)ioc->chip_phys; | 2996 | chip_phys = ioc->chip_phys; |
| 2633 | memap_sz = pci_resource_len(pdev, i); | 2997 | memap_sz = pci_resource_len(pdev, i); |
| 2634 | ioc->chip = ioremap(ioc->chip_phys, memap_sz); | 2998 | ioc->chip = ioremap(ioc->chip_phys, memap_sz); |
| 2635 | } | 2999 | } |
| @@ -2704,8 +3068,8 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc) | |||
| 2704 | "IO-APIC enabled"), | 3068 | "IO-APIC enabled"), |
| 2705 | pci_irq_vector(ioc->pdev, reply_q->msix_index)); | 3069 | pci_irq_vector(ioc->pdev, reply_q->msix_index)); |
| 2706 | 3070 | ||
| 2707 | pr_info(MPT3SAS_FMT "iomem(0x%016llx), mapped(0x%p), size(%d)\n", | 3071 | pr_info(MPT3SAS_FMT "iomem(%pap), mapped(0x%p), size(%d)\n", |
| 2708 | ioc->name, (unsigned long long)chip_phys, ioc->chip, memap_sz); | 3072 | ioc->name, &chip_phys, ioc->chip, memap_sz); |
| 2709 | pr_info(MPT3SAS_FMT "ioport(0x%016llx), size(%d)\n", | 3073 | pr_info(MPT3SAS_FMT "ioport(0x%016llx), size(%d)\n", |
| 2710 | ioc->name, (unsigned long long)pio_chip, pio_sz); | 3074 | ioc->name, (unsigned long long)pio_chip, pio_sz); |
| 2711 | 3075 | ||
| @@ -2961,6 +3325,29 @@ mpt3sas_base_free_smid(struct MPT3SAS_ADAPTER *ioc, u16 smid) | |||
| 2961 | } | 3325 | } |
| 2962 | 3326 | ||
| 2963 | /** | 3327 | /** |
| 3328 | * _base_mpi_ep_writeq - 32 bit write to MMIO | ||
| 3329 | * @b: data payload | ||
| 3330 | * @addr: address in MMIO space | ||
| 3331 | * @writeq_lock: spin lock | ||
| 3332 | * | ||
| 3333 | * This special handling for MPI EP to take care of 32 bit | ||
| 3334 | * environment where its not quarenteed to send the entire word | ||
| 3335 | * in one transfer. | ||
| 3336 | */ | ||
| 3337 | static inline void | ||
| 3338 | _base_mpi_ep_writeq(__u64 b, volatile void __iomem *addr, | ||
| 3339 | spinlock_t *writeq_lock) | ||
| 3340 | { | ||
| 3341 | unsigned long flags; | ||
| 3342 | __u64 data_out = cpu_to_le64(b); | ||
| 3343 | |||
| 3344 | spin_lock_irqsave(writeq_lock, flags); | ||
| 3345 | writel((u32)(data_out), addr); | ||
| 3346 | writel((u32)(data_out >> 32), (addr + 4)); | ||
| 3347 | spin_unlock_irqrestore(writeq_lock, flags); | ||
| 3348 | } | ||
| 3349 | |||
| 3350 | /** | ||
| 2964 | * _base_writeq - 64 bit write to MMIO | 3351 | * _base_writeq - 64 bit write to MMIO |
| 2965 | * @ioc: per adapter object | 3352 | * @ioc: per adapter object |
| 2966 | * @b: data payload | 3353 | * @b: data payload |
| @@ -2981,17 +3368,41 @@ _base_writeq(__u64 b, volatile void __iomem *addr, spinlock_t *writeq_lock) | |||
| 2981 | static inline void | 3368 | static inline void |
| 2982 | _base_writeq(__u64 b, volatile void __iomem *addr, spinlock_t *writeq_lock) | 3369 | _base_writeq(__u64 b, volatile void __iomem *addr, spinlock_t *writeq_lock) |
| 2983 | { | 3370 | { |
| 2984 | unsigned long flags; | 3371 | _base_mpi_ep_writeq(b, addr, writeq_lock); |
| 2985 | __u64 data_out = cpu_to_le64(b); | ||
| 2986 | |||
| 2987 | spin_lock_irqsave(writeq_lock, flags); | ||
| 2988 | writel((u32)(data_out), addr); | ||
| 2989 | writel((u32)(data_out >> 32), (addr + 4)); | ||
| 2990 | spin_unlock_irqrestore(writeq_lock, flags); | ||
| 2991 | } | 3372 | } |
| 2992 | #endif | 3373 | #endif |
| 2993 | 3374 | ||
| 2994 | /** | 3375 | /** |
| 3376 | * _base_put_smid_mpi_ep_scsi_io - send SCSI_IO request to firmware | ||
| 3377 | * @ioc: per adapter object | ||
| 3378 | * @smid: system request message index | ||
| 3379 | * @handle: device handle | ||
| 3380 | * | ||
| 3381 | * Return nothing. | ||
| 3382 | */ | ||
| 3383 | static void | ||
| 3384 | _base_put_smid_mpi_ep_scsi_io(struct MPT3SAS_ADAPTER *ioc, u16 smid, u16 handle) | ||
| 3385 | { | ||
| 3386 | Mpi2RequestDescriptorUnion_t descriptor; | ||
| 3387 | u64 *request = (u64 *)&descriptor; | ||
| 3388 | void *mpi_req_iomem; | ||
| 3389 | __le32 *mfp = (__le32 *)mpt3sas_base_get_msg_frame(ioc, smid); | ||
| 3390 | |||
| 3391 | _clone_sg_entries(ioc, (void *) mfp, smid); | ||
| 3392 | mpi_req_iomem = (void *)ioc->chip + | ||
| 3393 | MPI_FRAME_START_OFFSET + (smid * ioc->request_sz); | ||
| 3394 | _base_clone_mpi_to_sys_mem(mpi_req_iomem, (void *)mfp, | ||
| 3395 | ioc->request_sz); | ||
| 3396 | descriptor.SCSIIO.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO; | ||
| 3397 | descriptor.SCSIIO.MSIxIndex = _base_get_msix_index(ioc); | ||
| 3398 | descriptor.SCSIIO.SMID = cpu_to_le16(smid); | ||
| 3399 | descriptor.SCSIIO.DevHandle = cpu_to_le16(handle); | ||
| 3400 | descriptor.SCSIIO.LMID = 0; | ||
| 3401 | _base_mpi_ep_writeq(*request, &ioc->chip->RequestDescriptorPostLow, | ||
| 3402 | &ioc->scsi_lookup_lock); | ||
| 3403 | } | ||
| 3404 | |||
| 3405 | /** | ||
| 2995 | * _base_put_smid_scsi_io - send SCSI_IO request to firmware | 3406 | * _base_put_smid_scsi_io - send SCSI_IO request to firmware |
| 2996 | * @ioc: per adapter object | 3407 | * @ioc: per adapter object |
| 2997 | * @smid: system request message index | 3408 | * @smid: system request message index |
| @@ -3016,15 +3427,15 @@ _base_put_smid_scsi_io(struct MPT3SAS_ADAPTER *ioc, u16 smid, u16 handle) | |||
| 3016 | } | 3427 | } |
| 3017 | 3428 | ||
| 3018 | /** | 3429 | /** |
| 3019 | * _base_put_smid_fast_path - send fast path request to firmware | 3430 | * mpt3sas_base_put_smid_fast_path - send fast path request to firmware |
| 3020 | * @ioc: per adapter object | 3431 | * @ioc: per adapter object |
| 3021 | * @smid: system request message index | 3432 | * @smid: system request message index |
| 3022 | * @handle: device handle | 3433 | * @handle: device handle |
| 3023 | * | 3434 | * |
| 3024 | * Return nothing. | 3435 | * Return nothing. |
| 3025 | */ | 3436 | */ |
| 3026 | static void | 3437 | void |
| 3027 | _base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid, | 3438 | mpt3sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid, |
| 3028 | u16 handle) | 3439 | u16 handle) |
| 3029 | { | 3440 | { |
| 3030 | Mpi2RequestDescriptorUnion_t descriptor; | 3441 | Mpi2RequestDescriptorUnion_t descriptor; |
| @@ -3041,18 +3452,34 @@ _base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid, | |||
| 3041 | } | 3452 | } |
| 3042 | 3453 | ||
| 3043 | /** | 3454 | /** |
| 3044 | * _base_put_smid_hi_priority - send Task Management request to firmware | 3455 | * mpt3sas_base_put_smid_hi_priority - send Task Management request to firmware |
| 3045 | * @ioc: per adapter object | 3456 | * @ioc: per adapter object |
| 3046 | * @smid: system request message index | 3457 | * @smid: system request message index |
| 3047 | * @msix_task: msix_task will be same as msix of IO incase of task abort else 0. | 3458 | * @msix_task: msix_task will be same as msix of IO incase of task abort else 0. |
| 3048 | * Return nothing. | 3459 | * Return nothing. |
| 3049 | */ | 3460 | */ |
| 3050 | static void | 3461 | void |
| 3051 | _base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid, | 3462 | mpt3sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid, |
| 3052 | u16 msix_task) | 3463 | u16 msix_task) |
| 3053 | { | 3464 | { |
| 3054 | Mpi2RequestDescriptorUnion_t descriptor; | 3465 | Mpi2RequestDescriptorUnion_t descriptor; |
| 3055 | u64 *request = (u64 *)&descriptor; | 3466 | void *mpi_req_iomem; |
| 3467 | u64 *request; | ||
| 3468 | |||
| 3469 | if (ioc->is_mcpu_endpoint) { | ||
| 3470 | MPI2RequestHeader_t *request_hdr; | ||
| 3471 | |||
| 3472 | __le32 *mfp = (__le32 *)mpt3sas_base_get_msg_frame(ioc, smid); | ||
| 3473 | |||
| 3474 | request_hdr = (MPI2RequestHeader_t *)mfp; | ||
| 3475 | /* TBD 256 is offset within sys register. */ | ||
| 3476 | mpi_req_iomem = (void *)ioc->chip + MPI_FRAME_START_OFFSET | ||
| 3477 | + (smid * ioc->request_sz); | ||
| 3478 | _base_clone_mpi_to_sys_mem(mpi_req_iomem, (void *)mfp, | ||
| 3479 | ioc->request_sz); | ||
| 3480 | } | ||
| 3481 | |||
| 3482 | request = (u64 *)&descriptor; | ||
| 3056 | 3483 | ||
| 3057 | descriptor.HighPriority.RequestFlags = | 3484 | descriptor.HighPriority.RequestFlags = |
| 3058 | MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY; | 3485 | MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY; |
| @@ -3060,20 +3487,25 @@ _base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid, | |||
| 3060 | descriptor.HighPriority.SMID = cpu_to_le16(smid); | 3487 | descriptor.HighPriority.SMID = cpu_to_le16(smid); |
| 3061 | descriptor.HighPriority.LMID = 0; | 3488 | descriptor.HighPriority.LMID = 0; |
| 3062 | descriptor.HighPriority.Reserved1 = 0; | 3489 | descriptor.HighPriority.Reserved1 = 0; |
| 3063 | _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow, | 3490 | if (ioc->is_mcpu_endpoint) |
| 3064 | &ioc->scsi_lookup_lock); | 3491 | _base_mpi_ep_writeq(*request, |
| 3492 | &ioc->chip->RequestDescriptorPostLow, | ||
| 3493 | &ioc->scsi_lookup_lock); | ||
| 3494 | else | ||
| 3495 | _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow, | ||
| 3496 | &ioc->scsi_lookup_lock); | ||
| 3065 | } | 3497 | } |
| 3066 | 3498 | ||
| 3067 | /** | 3499 | /** |
| 3068 | * _base_put_smid_nvme_encap - send NVMe encapsulated request to | 3500 | * mpt3sas_base_put_smid_nvme_encap - send NVMe encapsulated request to |
| 3069 | * firmware | 3501 | * firmware |
| 3070 | * @ioc: per adapter object | 3502 | * @ioc: per adapter object |
| 3071 | * @smid: system request message index | 3503 | * @smid: system request message index |
| 3072 | * | 3504 | * |
| 3073 | * Return nothing. | 3505 | * Return nothing. |
| 3074 | */ | 3506 | */ |
| 3075 | static void | 3507 | void |
| 3076 | _base_put_smid_nvme_encap(struct MPT3SAS_ADAPTER *ioc, u16 smid) | 3508 | mpt3sas_base_put_smid_nvme_encap(struct MPT3SAS_ADAPTER *ioc, u16 smid) |
| 3077 | { | 3509 | { |
| 3078 | Mpi2RequestDescriptorUnion_t descriptor; | 3510 | Mpi2RequestDescriptorUnion_t descriptor; |
| 3079 | u64 *request = (u64 *)&descriptor; | 3511 | u64 *request = (u64 *)&descriptor; |
| @@ -3089,135 +3521,45 @@ _base_put_smid_nvme_encap(struct MPT3SAS_ADAPTER *ioc, u16 smid) | |||
| 3089 | } | 3521 | } |
| 3090 | 3522 | ||
| 3091 | /** | 3523 | /** |
| 3092 | * _base_put_smid_default - Default, primarily used for config pages | 3524 | * mpt3sas_base_put_smid_default - Default, primarily used for config pages |
| 3093 | * @ioc: per adapter object | 3525 | * @ioc: per adapter object |
| 3094 | * @smid: system request message index | 3526 | * @smid: system request message index |
| 3095 | * | 3527 | * |
| 3096 | * Return nothing. | 3528 | * Return nothing. |
| 3097 | */ | 3529 | */ |
| 3098 | static void | 3530 | void |
| 3099 | _base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid) | 3531 | mpt3sas_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid) |
| 3100 | { | 3532 | { |
| 3101 | Mpi2RequestDescriptorUnion_t descriptor; | 3533 | Mpi2RequestDescriptorUnion_t descriptor; |
| 3102 | u64 *request = (u64 *)&descriptor; | 3534 | void *mpi_req_iomem; |
| 3535 | u64 *request; | ||
| 3536 | MPI2RequestHeader_t *request_hdr; | ||
| 3537 | |||
| 3538 | if (ioc->is_mcpu_endpoint) { | ||
| 3539 | __le32 *mfp = (__le32 *)mpt3sas_base_get_msg_frame(ioc, smid); | ||
| 3103 | 3540 | ||
| 3541 | request_hdr = (MPI2RequestHeader_t *)mfp; | ||
| 3542 | |||
| 3543 | _clone_sg_entries(ioc, (void *) mfp, smid); | ||
| 3544 | /* TBD 256 is offset within sys register */ | ||
| 3545 | mpi_req_iomem = (void *)ioc->chip + | ||
| 3546 | MPI_FRAME_START_OFFSET + (smid * ioc->request_sz); | ||
| 3547 | _base_clone_mpi_to_sys_mem(mpi_req_iomem, (void *)mfp, | ||
| 3548 | ioc->request_sz); | ||
| 3549 | } | ||
| 3550 | request = (u64 *)&descriptor; | ||
| 3104 | descriptor.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; | 3551 | descriptor.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; |
| 3105 | descriptor.Default.MSIxIndex = _base_get_msix_index(ioc); | 3552 | descriptor.Default.MSIxIndex = _base_get_msix_index(ioc); |
| 3106 | descriptor.Default.SMID = cpu_to_le16(smid); | 3553 | descriptor.Default.SMID = cpu_to_le16(smid); |
| 3107 | descriptor.Default.LMID = 0; | 3554 | descriptor.Default.LMID = 0; |
| 3108 | descriptor.Default.DescriptorTypeDependent = 0; | 3555 | descriptor.Default.DescriptorTypeDependent = 0; |
| 3109 | _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow, | 3556 | if (ioc->is_mcpu_endpoint) |
| 3110 | &ioc->scsi_lookup_lock); | 3557 | _base_mpi_ep_writeq(*request, |
| 3111 | } | 3558 | &ioc->chip->RequestDescriptorPostLow, |
| 3112 | 3559 | &ioc->scsi_lookup_lock); | |
| 3113 | /** | 3560 | else |
| 3114 | * _base_put_smid_scsi_io_atomic - send SCSI_IO request to firmware using | 3561 | _base_writeq(*request, &ioc->chip->RequestDescriptorPostLow, |
| 3115 | * Atomic Request Descriptor | 3562 | &ioc->scsi_lookup_lock); |
| 3116 | * @ioc: per adapter object | ||
| 3117 | * @smid: system request message index | ||
| 3118 | * @handle: device handle, unused in this function, for function type match | ||
| 3119 | * | ||
| 3120 | * Return nothing. | ||
| 3121 | */ | ||
| 3122 | static void | ||
| 3123 | _base_put_smid_scsi_io_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid, | ||
| 3124 | u16 handle) | ||
| 3125 | { | ||
| 3126 | Mpi26AtomicRequestDescriptor_t descriptor; | ||
| 3127 | u32 *request = (u32 *)&descriptor; | ||
| 3128 | |||
| 3129 | descriptor.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO; | ||
| 3130 | descriptor.MSIxIndex = _base_get_msix_index(ioc); | ||
| 3131 | descriptor.SMID = cpu_to_le16(smid); | ||
| 3132 | |||
| 3133 | writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost); | ||
| 3134 | } | ||
| 3135 | |||
| 3136 | /** | ||
| 3137 | * _base_put_smid_fast_path_atomic - send fast path request to firmware | ||
| 3138 | * using Atomic Request Descriptor | ||
| 3139 | * @ioc: per adapter object | ||
| 3140 | * @smid: system request message index | ||
| 3141 | * @handle: device handle, unused in this function, for function type match | ||
| 3142 | * Return nothing | ||
| 3143 | */ | ||
| 3144 | static void | ||
| 3145 | _base_put_smid_fast_path_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid, | ||
| 3146 | u16 handle) | ||
| 3147 | { | ||
| 3148 | Mpi26AtomicRequestDescriptor_t descriptor; | ||
| 3149 | u32 *request = (u32 *)&descriptor; | ||
| 3150 | |||
| 3151 | descriptor.RequestFlags = MPI25_REQ_DESCRIPT_FLAGS_FAST_PATH_SCSI_IO; | ||
| 3152 | descriptor.MSIxIndex = _base_get_msix_index(ioc); | ||
| 3153 | descriptor.SMID = cpu_to_le16(smid); | ||
| 3154 | |||
| 3155 | writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost); | ||
| 3156 | } | ||
| 3157 | |||
| 3158 | /** | ||
| 3159 | * _base_put_smid_hi_priority_atomic - send Task Management request to | ||
| 3160 | * firmware using Atomic Request Descriptor | ||
| 3161 | * @ioc: per adapter object | ||
| 3162 | * @smid: system request message index | ||
| 3163 | * @msix_task: msix_task will be same as msix of IO incase of task abort else 0 | ||
| 3164 | * | ||
| 3165 | * Return nothing. | ||
| 3166 | */ | ||
| 3167 | static void | ||
| 3168 | _base_put_smid_hi_priority_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid, | ||
| 3169 | u16 msix_task) | ||
| 3170 | { | ||
| 3171 | Mpi26AtomicRequestDescriptor_t descriptor; | ||
| 3172 | u32 *request = (u32 *)&descriptor; | ||
| 3173 | |||
| 3174 | descriptor.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY; | ||
| 3175 | descriptor.MSIxIndex = msix_task; | ||
| 3176 | descriptor.SMID = cpu_to_le16(smid); | ||
| 3177 | |||
| 3178 | writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost); | ||
| 3179 | } | ||
| 3180 | |||
| 3181 | /** | ||
| 3182 | * _base_put_smid_nvme_encap_atomic - send NVMe encapsulated request to | ||
| 3183 | * firmware using Atomic Request Descriptor | ||
| 3184 | * @ioc: per adapter object | ||
| 3185 | * @smid: system request message index | ||
| 3186 | * | ||
| 3187 | * Return nothing. | ||
| 3188 | */ | ||
| 3189 | static void | ||
| 3190 | _base_put_smid_nvme_encap_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid) | ||
| 3191 | { | ||
| 3192 | Mpi26AtomicRequestDescriptor_t descriptor; | ||
| 3193 | u32 *request = (u32 *)&descriptor; | ||
| 3194 | |||
| 3195 | descriptor.RequestFlags = MPI26_REQ_DESCRIPT_FLAGS_PCIE_ENCAPSULATED; | ||
| 3196 | descriptor.MSIxIndex = _base_get_msix_index(ioc); | ||
| 3197 | descriptor.SMID = cpu_to_le16(smid); | ||
| 3198 | |||
| 3199 | writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost); | ||
| 3200 | } | ||
| 3201 | |||
| 3202 | /** | ||
| 3203 | * _base_put_smid_default - Default, primarily used for config pages | ||
| 3204 | * use Atomic Request Descriptor | ||
| 3205 | * @ioc: per adapter object | ||
| 3206 | * @smid: system request message index | ||
| 3207 | * | ||
| 3208 | * Return nothing. | ||
| 3209 | */ | ||
| 3210 | static void | ||
| 3211 | _base_put_smid_default_atomic(struct MPT3SAS_ADAPTER *ioc, u16 smid) | ||
| 3212 | { | ||
| 3213 | Mpi26AtomicRequestDescriptor_t descriptor; | ||
| 3214 | u32 *request = (u32 *)&descriptor; | ||
| 3215 | |||
| 3216 | descriptor.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; | ||
| 3217 | descriptor.MSIxIndex = _base_get_msix_index(ioc); | ||
| 3218 | descriptor.SMID = cpu_to_le16(smid); | ||
| 3219 | |||
| 3220 | writel(cpu_to_le32(*request), &ioc->chip->AtomicRequestDescriptorPost); | ||
| 3221 | } | 3563 | } |
| 3222 | 3564 | ||
| 3223 | /** | 3565 | /** |
| @@ -3890,17 +4232,21 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc) | |||
| 3890 | sg_tablesize = min_t(unsigned short, sg_tablesize, | 4232 | sg_tablesize = min_t(unsigned short, sg_tablesize, |
| 3891 | MPT_KDUMP_MIN_PHYS_SEGMENTS); | 4233 | MPT_KDUMP_MIN_PHYS_SEGMENTS); |
| 3892 | 4234 | ||
| 3893 | if (sg_tablesize < MPT_MIN_PHYS_SEGMENTS) | 4235 | if (ioc->is_mcpu_endpoint) |
| 3894 | sg_tablesize = MPT_MIN_PHYS_SEGMENTS; | 4236 | ioc->shost->sg_tablesize = MPT_MIN_PHYS_SEGMENTS; |
| 3895 | else if (sg_tablesize > MPT_MAX_PHYS_SEGMENTS) { | 4237 | else { |
| 3896 | sg_tablesize = min_t(unsigned short, sg_tablesize, | 4238 | if (sg_tablesize < MPT_MIN_PHYS_SEGMENTS) |
| 3897 | SG_MAX_SEGMENTS); | 4239 | sg_tablesize = MPT_MIN_PHYS_SEGMENTS; |
| 3898 | pr_warn(MPT3SAS_FMT | 4240 | else if (sg_tablesize > MPT_MAX_PHYS_SEGMENTS) { |
| 3899 | "sg_tablesize(%u) is bigger than kernel" | 4241 | sg_tablesize = min_t(unsigned short, sg_tablesize, |
| 3900 | " defined SG_CHUNK_SIZE(%u)\n", ioc->name, | 4242 | SG_MAX_SEGMENTS); |
| 3901 | sg_tablesize, MPT_MAX_PHYS_SEGMENTS); | 4243 | pr_warn(MPT3SAS_FMT |
| 4244 | "sg_tablesize(%u) is bigger than kernel " | ||
| 4245 | "defined SG_CHUNK_SIZE(%u)\n", ioc->name, | ||
| 4246 | sg_tablesize, MPT_MAX_PHYS_SEGMENTS); | ||
| 4247 | } | ||
| 4248 | ioc->shost->sg_tablesize = sg_tablesize; | ||
| 3902 | } | 4249 | } |
| 3903 | ioc->shost->sg_tablesize = sg_tablesize; | ||
| 3904 | 4250 | ||
| 3905 | ioc->internal_depth = min_t(int, (facts->HighPriorityCredit + (5)), | 4251 | ioc->internal_depth = min_t(int, (facts->HighPriorityCredit + (5)), |
| 3906 | (facts->RequestCredit / 4)); | 4252 | (facts->RequestCredit / 4)); |
| @@ -3985,13 +4331,18 @@ _base_allocate_memory_pools(struct MPT3SAS_ADAPTER *ioc) | |||
| 3985 | /* reply free queue sizing - taking into account for 64 FW events */ | 4331 | /* reply free queue sizing - taking into account for 64 FW events */ |
| 3986 | ioc->reply_free_queue_depth = ioc->hba_queue_depth + 64; | 4332 | ioc->reply_free_queue_depth = ioc->hba_queue_depth + 64; |
| 3987 | 4333 | ||
| 3988 | /* calculate reply descriptor post queue depth */ | 4334 | /* mCPU manage single counters for simplicity */ |
| 3989 | ioc->reply_post_queue_depth = ioc->hba_queue_depth + | 4335 | if (ioc->is_mcpu_endpoint) |
| 3990 | ioc->reply_free_queue_depth + 1 ; | 4336 | ioc->reply_post_queue_depth = ioc->reply_free_queue_depth; |
| 3991 | /* align the reply post queue on the next 16 count boundary */ | 4337 | else { |
| 3992 | if (ioc->reply_post_queue_depth % 16) | 4338 | /* calculate reply descriptor post queue depth */ |
| 3993 | ioc->reply_post_queue_depth += 16 - | 4339 | ioc->reply_post_queue_depth = ioc->hba_queue_depth + |
| 3994 | (ioc->reply_post_queue_depth % 16); | 4340 | ioc->reply_free_queue_depth + 1; |
| 4341 | /* align the reply post queue on the next 16 count boundary */ | ||
| 4342 | if (ioc->reply_post_queue_depth % 16) | ||
| 4343 | ioc->reply_post_queue_depth += 16 - | ||
| 4344 | (ioc->reply_post_queue_depth % 16); | ||
| 4345 | } | ||
| 3995 | 4346 | ||
| 3996 | if (ioc->reply_post_queue_depth > | 4347 | if (ioc->reply_post_queue_depth > |
| 3997 | facts->MaxReplyDescriptorPostQueueDepth) { | 4348 | facts->MaxReplyDescriptorPostQueueDepth) { |
| @@ -4789,7 +5140,7 @@ mpt3sas_base_sas_iounit_control(struct MPT3SAS_ADAPTER *ioc, | |||
| 4789 | mpi_request->Operation == MPI2_SAS_OP_PHY_LINK_RESET) | 5140 | mpi_request->Operation == MPI2_SAS_OP_PHY_LINK_RESET) |
| 4790 | ioc->ioc_link_reset_in_progress = 1; | 5141 | ioc->ioc_link_reset_in_progress = 1; |
| 4791 | init_completion(&ioc->base_cmds.done); | 5142 | init_completion(&ioc->base_cmds.done); |
| 4792 | ioc->put_smid_default(ioc, smid); | 5143 | mpt3sas_base_put_smid_default(ioc, smid); |
| 4793 | wait_for_completion_timeout(&ioc->base_cmds.done, | 5144 | wait_for_completion_timeout(&ioc->base_cmds.done, |
| 4794 | msecs_to_jiffies(10000)); | 5145 | msecs_to_jiffies(10000)); |
| 4795 | if ((mpi_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET || | 5146 | if ((mpi_request->Operation == MPI2_SAS_OP_PHY_HARD_RESET || |
| @@ -4889,7 +5240,7 @@ mpt3sas_base_scsi_enclosure_processor(struct MPT3SAS_ADAPTER *ioc, | |||
| 4889 | ioc->base_cmds.smid = smid; | 5240 | ioc->base_cmds.smid = smid; |
| 4890 | memcpy(request, mpi_request, sizeof(Mpi2SepReply_t)); | 5241 | memcpy(request, mpi_request, sizeof(Mpi2SepReply_t)); |
| 4891 | init_completion(&ioc->base_cmds.done); | 5242 | init_completion(&ioc->base_cmds.done); |
| 4892 | ioc->put_smid_default(ioc, smid); | 5243 | mpt3sas_base_put_smid_default(ioc, smid); |
| 4893 | wait_for_completion_timeout(&ioc->base_cmds.done, | 5244 | wait_for_completion_timeout(&ioc->base_cmds.done, |
| 4894 | msecs_to_jiffies(10000)); | 5245 | msecs_to_jiffies(10000)); |
| 4895 | if (!(ioc->base_cmds.status & MPT3_CMD_COMPLETE)) { | 5246 | if (!(ioc->base_cmds.status & MPT3_CMD_COMPLETE)) { |
| @@ -5074,8 +5425,6 @@ _base_get_ioc_facts(struct MPT3SAS_ADAPTER *ioc) | |||
| 5074 | if ((facts->IOCCapabilities & | 5425 | if ((facts->IOCCapabilities & |
| 5075 | MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE) && (!reset_devices)) | 5426 | MPI2_IOCFACTS_CAPABILITY_RDPQ_ARRAY_CAPABLE) && (!reset_devices)) |
| 5076 | ioc->rdpq_array_capable = 1; | 5427 | ioc->rdpq_array_capable = 1; |
| 5077 | if (facts->IOCCapabilities & MPI26_IOCFACTS_CAPABILITY_ATOMIC_REQ) | ||
| 5078 | ioc->atomic_desc_capable = 1; | ||
| 5079 | facts->FWVersion.Word = le32_to_cpu(mpi_reply.FWVersion.Word); | 5428 | facts->FWVersion.Word = le32_to_cpu(mpi_reply.FWVersion.Word); |
| 5080 | facts->IOCRequestFrameSize = | 5429 | facts->IOCRequestFrameSize = |
| 5081 | le16_to_cpu(mpi_reply.IOCRequestFrameSize); | 5430 | le16_to_cpu(mpi_reply.IOCRequestFrameSize); |
| @@ -5317,7 +5666,7 @@ _base_send_port_enable(struct MPT3SAS_ADAPTER *ioc) | |||
| 5317 | mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE; | 5666 | mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE; |
| 5318 | 5667 | ||
| 5319 | init_completion(&ioc->port_enable_cmds.done); | 5668 | init_completion(&ioc->port_enable_cmds.done); |
| 5320 | ioc->put_smid_default(ioc, smid); | 5669 | mpt3sas_base_put_smid_default(ioc, smid); |
| 5321 | wait_for_completion_timeout(&ioc->port_enable_cmds.done, 300*HZ); | 5670 | wait_for_completion_timeout(&ioc->port_enable_cmds.done, 300*HZ); |
| 5322 | if (!(ioc->port_enable_cmds.status & MPT3_CMD_COMPLETE)) { | 5671 | if (!(ioc->port_enable_cmds.status & MPT3_CMD_COMPLETE)) { |
| 5323 | pr_err(MPT3SAS_FMT "%s: timeout\n", | 5672 | pr_err(MPT3SAS_FMT "%s: timeout\n", |
| @@ -5380,7 +5729,7 @@ mpt3sas_port_enable(struct MPT3SAS_ADAPTER *ioc) | |||
| 5380 | memset(mpi_request, 0, sizeof(Mpi2PortEnableRequest_t)); | 5729 | memset(mpi_request, 0, sizeof(Mpi2PortEnableRequest_t)); |
| 5381 | mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE; | 5730 | mpi_request->Function = MPI2_FUNCTION_PORT_ENABLE; |
| 5382 | 5731 | ||
| 5383 | ioc->put_smid_default(ioc, smid); | 5732 | mpt3sas_base_put_smid_default(ioc, smid); |
| 5384 | return 0; | 5733 | return 0; |
| 5385 | } | 5734 | } |
| 5386 | 5735 | ||
| @@ -5499,7 +5848,7 @@ _base_event_notification(struct MPT3SAS_ADAPTER *ioc) | |||
| 5499 | mpi_request->EventMasks[i] = | 5848 | mpi_request->EventMasks[i] = |
| 5500 | cpu_to_le32(ioc->event_masks[i]); | 5849 | cpu_to_le32(ioc->event_masks[i]); |
| 5501 | init_completion(&ioc->base_cmds.done); | 5850 | init_completion(&ioc->base_cmds.done); |
| 5502 | ioc->put_smid_default(ioc, smid); | 5851 | mpt3sas_base_put_smid_default(ioc, smid); |
| 5503 | wait_for_completion_timeout(&ioc->base_cmds.done, 30*HZ); | 5852 | wait_for_completion_timeout(&ioc->base_cmds.done, 30*HZ); |
| 5504 | if (!(ioc->base_cmds.status & MPT3_CMD_COMPLETE)) { | 5853 | if (!(ioc->base_cmds.status & MPT3_CMD_COMPLETE)) { |
| 5505 | pr_err(MPT3SAS_FMT "%s: timeout\n", | 5854 | pr_err(MPT3SAS_FMT "%s: timeout\n", |
| @@ -5819,8 +6168,12 @@ _base_make_ioc_operational(struct MPT3SAS_ADAPTER *ioc) | |||
| 5819 | /* initialize Reply Free Queue */ | 6168 | /* initialize Reply Free Queue */ |
| 5820 | for (i = 0, reply_address = (u32)ioc->reply_dma ; | 6169 | for (i = 0, reply_address = (u32)ioc->reply_dma ; |
| 5821 | i < ioc->reply_free_queue_depth ; i++, reply_address += | 6170 | i < ioc->reply_free_queue_depth ; i++, reply_address += |
| 5822 | ioc->reply_sz) | 6171 | ioc->reply_sz) { |
| 5823 | ioc->reply_free[i] = cpu_to_le32(reply_address); | 6172 | ioc->reply_free[i] = cpu_to_le32(reply_address); |
| 6173 | if (ioc->is_mcpu_endpoint) | ||
| 6174 | _base_clone_reply_to_sys_mem(ioc, | ||
| 6175 | (__le32)reply_address, i); | ||
| 6176 | } | ||
| 5824 | 6177 | ||
| 5825 | /* initialize reply queues */ | 6178 | /* initialize reply queues */ |
| 5826 | if (ioc->is_driver_loading) | 6179 | if (ioc->is_driver_loading) |
| @@ -6009,20 +6362,10 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc) | |||
| 6009 | break; | 6362 | break; |
| 6010 | } | 6363 | } |
| 6011 | 6364 | ||
| 6012 | if (ioc->atomic_desc_capable) { | 6365 | if (ioc->is_mcpu_endpoint) |
| 6013 | ioc->put_smid_default = &_base_put_smid_default_atomic; | 6366 | ioc->put_smid_scsi_io = &_base_put_smid_mpi_ep_scsi_io; |
| 6014 | ioc->put_smid_scsi_io = &_base_put_smid_scsi_io_atomic; | 6367 | else |
| 6015 | ioc->put_smid_fast_path = &_base_put_smid_fast_path_atomic; | ||
| 6016 | ioc->put_smid_hi_priority = &_base_put_smid_hi_priority_atomic; | ||
| 6017 | ioc->put_smid_nvme_encap = &_base_put_smid_nvme_encap_atomic; | ||
| 6018 | } else { | ||
| 6019 | ioc->put_smid_default = &_base_put_smid_default; | ||
| 6020 | ioc->put_smid_scsi_io = &_base_put_smid_scsi_io; | 6368 | ioc->put_smid_scsi_io = &_base_put_smid_scsi_io; |
| 6021 | ioc->put_smid_fast_path = &_base_put_smid_fast_path; | ||
| 6022 | ioc->put_smid_hi_priority = &_base_put_smid_hi_priority; | ||
| 6023 | ioc->put_smid_nvme_encap = &_base_put_smid_nvme_encap; | ||
| 6024 | } | ||
| 6025 | |||
| 6026 | 6369 | ||
| 6027 | /* | 6370 | /* |
| 6028 | * These function pointers for other requests that don't | 6371 | * These function pointers for other requests that don't |
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h index 99ccf83b8c51..ae36d8fb2f2b 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_base.h +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h | |||
| @@ -95,6 +95,8 @@ | |||
| 95 | #define MPT_MIN_PHYS_SEGMENTS 16 | 95 | #define MPT_MIN_PHYS_SEGMENTS 16 |
| 96 | #define MPT_KDUMP_MIN_PHYS_SEGMENTS 32 | 96 | #define MPT_KDUMP_MIN_PHYS_SEGMENTS 32 |
| 97 | 97 | ||
| 98 | #define MCPU_MAX_CHAINS_PER_IO 3 | ||
| 99 | |||
| 98 | #ifdef CONFIG_SCSI_MPT3SAS_MAX_SGE | 100 | #ifdef CONFIG_SCSI_MPT3SAS_MAX_SGE |
| 99 | #define MPT3SAS_SG_DEPTH CONFIG_SCSI_MPT3SAS_MAX_SGE | 101 | #define MPT3SAS_SG_DEPTH CONFIG_SCSI_MPT3SAS_MAX_SGE |
| 100 | #else | 102 | #else |
| @@ -120,6 +122,8 @@ | |||
| 120 | #define MPT3SAS_NVME_QUEUE_DEPTH 128 | 122 | #define MPT3SAS_NVME_QUEUE_DEPTH 128 |
| 121 | #define MPT_NAME_LENGTH 32 /* generic length of strings */ | 123 | #define MPT_NAME_LENGTH 32 /* generic length of strings */ |
| 122 | #define MPT_STRING_LENGTH 64 | 124 | #define MPT_STRING_LENGTH 64 |
| 125 | #define MPI_FRAME_START_OFFSET 256 | ||
| 126 | #define REPLY_FREE_POOL_SIZE 512 /*(32 maxcredix *4)*(4 times)*/ | ||
| 123 | 127 | ||
| 124 | #define MPT_MAX_CALLBACKS 32 | 128 | #define MPT_MAX_CALLBACKS 32 |
| 125 | 129 | ||
| @@ -1099,7 +1103,7 @@ struct MPT3SAS_ADAPTER { | |||
| 1099 | char tmp_string[MPT_STRING_LENGTH]; | 1103 | char tmp_string[MPT_STRING_LENGTH]; |
| 1100 | struct pci_dev *pdev; | 1104 | struct pci_dev *pdev; |
| 1101 | Mpi2SystemInterfaceRegs_t __iomem *chip; | 1105 | Mpi2SystemInterfaceRegs_t __iomem *chip; |
| 1102 | resource_size_t chip_phys; | 1106 | phys_addr_t chip_phys; |
| 1103 | int logging_level; | 1107 | int logging_level; |
| 1104 | int fwfault_debug; | 1108 | int fwfault_debug; |
| 1105 | u8 ir_firmware; | 1109 | u8 ir_firmware; |
| @@ -1236,6 +1240,7 @@ struct MPT3SAS_ADAPTER { | |||
| 1236 | u16 config_page_sz; | 1240 | u16 config_page_sz; |
| 1237 | void *config_page; | 1241 | void *config_page; |
| 1238 | dma_addr_t config_page_dma; | 1242 | dma_addr_t config_page_dma; |
| 1243 | void *config_vaddr; | ||
| 1239 | 1244 | ||
| 1240 | /* scsiio request */ | 1245 | /* scsiio request */ |
| 1241 | u16 hba_queue_depth; | 1246 | u16 hba_queue_depth; |
| @@ -1336,6 +1341,7 @@ struct MPT3SAS_ADAPTER { | |||
| 1336 | u32 ring_buffer_offset; | 1341 | u32 ring_buffer_offset; |
| 1337 | u32 ring_buffer_sz; | 1342 | u32 ring_buffer_sz; |
| 1338 | u8 is_warpdrive; | 1343 | u8 is_warpdrive; |
| 1344 | u8 is_mcpu_endpoint; | ||
| 1339 | u8 hide_ir_msg; | 1345 | u8 hide_ir_msg; |
| 1340 | u8 mfg_pg10_hide_flag; | 1346 | u8 mfg_pg10_hide_flag; |
| 1341 | u8 hide_drives; | 1347 | u8 hide_drives; |
| @@ -1348,12 +1354,7 @@ struct MPT3SAS_ADAPTER { | |||
| 1348 | void *device_remove_in_progress; | 1354 | void *device_remove_in_progress; |
| 1349 | u16 device_remove_in_progress_sz; | 1355 | u16 device_remove_in_progress_sz; |
| 1350 | u8 is_gen35_ioc; | 1356 | u8 is_gen35_ioc; |
| 1351 | u8 atomic_desc_capable; | ||
| 1352 | PUT_SMID_IO_FP_HIP put_smid_scsi_io; | 1357 | PUT_SMID_IO_FP_HIP put_smid_scsi_io; |
| 1353 | PUT_SMID_IO_FP_HIP put_smid_fast_path; | ||
| 1354 | PUT_SMID_IO_FP_HIP put_smid_hi_priority; | ||
| 1355 | PUT_SMID_DEFAULT put_smid_default; | ||
| 1356 | PUT_SMID_DEFAULT put_smid_nvme_encap; | ||
| 1357 | 1358 | ||
| 1358 | }; | 1359 | }; |
| 1359 | 1360 | ||
| @@ -1394,6 +1395,12 @@ void *mpt3sas_base_get_pcie_sgl(struct MPT3SAS_ADAPTER *ioc, u16 smid); | |||
| 1394 | dma_addr_t mpt3sas_base_get_pcie_sgl_dma(struct MPT3SAS_ADAPTER *ioc, u16 smid); | 1395 | dma_addr_t mpt3sas_base_get_pcie_sgl_dma(struct MPT3SAS_ADAPTER *ioc, u16 smid); |
| 1395 | void mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc); | 1396 | void mpt3sas_base_sync_reply_irqs(struct MPT3SAS_ADAPTER *ioc); |
| 1396 | 1397 | ||
| 1398 | void mpt3sas_base_put_smid_fast_path(struct MPT3SAS_ADAPTER *ioc, u16 smid, | ||
| 1399 | u16 handle); | ||
| 1400 | void mpt3sas_base_put_smid_hi_priority(struct MPT3SAS_ADAPTER *ioc, u16 smid, | ||
| 1401 | u16 msix_task); | ||
| 1402 | void mpt3sas_base_put_smid_nvme_encap(struct MPT3SAS_ADAPTER *ioc, u16 smid); | ||
| 1403 | void mpt3sas_base_put_smid_default(struct MPT3SAS_ADAPTER *ioc, u16 smid); | ||
| 1397 | /* hi-priority queue */ | 1404 | /* hi-priority queue */ |
| 1398 | u16 mpt3sas_base_get_smid_hpr(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx); | 1405 | u16 mpt3sas_base_get_smid_hpr(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx); |
| 1399 | u16 mpt3sas_base_get_smid_scsiio(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx, | 1406 | u16 mpt3sas_base_get_smid_scsiio(struct MPT3SAS_ADAPTER *ioc, u8 cb_idx, |
diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c b/drivers/scsi/mpt3sas/mpt3sas_config.c index 1c747cf419d5..e87c76a832f6 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_config.c +++ b/drivers/scsi/mpt3sas/mpt3sas_config.c | |||
| @@ -219,6 +219,7 @@ _config_alloc_config_dma_memory(struct MPT3SAS_ADAPTER *ioc, | |||
| 219 | mem->page = ioc->config_page; | 219 | mem->page = ioc->config_page; |
| 220 | mem->page_dma = ioc->config_page_dma; | 220 | mem->page_dma = ioc->config_page_dma; |
| 221 | } | 221 | } |
| 222 | ioc->config_vaddr = mem->page; | ||
| 222 | return r; | 223 | return r; |
| 223 | } | 224 | } |
| 224 | 225 | ||
| @@ -402,7 +403,7 @@ _config_request(struct MPT3SAS_ADAPTER *ioc, Mpi2ConfigRequest_t | |||
| 402 | memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t)); | 403 | memcpy(config_request, mpi_request, sizeof(Mpi2ConfigRequest_t)); |
| 403 | _config_display_some_debug(ioc, smid, "config_request", NULL); | 404 | _config_display_some_debug(ioc, smid, "config_request", NULL); |
| 404 | init_completion(&ioc->config_cmds.done); | 405 | init_completion(&ioc->config_cmds.done); |
| 405 | ioc->put_smid_default(ioc, smid); | 406 | mpt3sas_base_put_smid_default(ioc, smid); |
| 406 | wait_for_completion_timeout(&ioc->config_cmds.done, timeout*HZ); | 407 | wait_for_completion_timeout(&ioc->config_cmds.done, timeout*HZ); |
| 407 | if (!(ioc->config_cmds.status & MPT3_CMD_COMPLETE)) { | 408 | if (!(ioc->config_cmds.status & MPT3_CMD_COMPLETE)) { |
| 408 | pr_err(MPT3SAS_FMT "%s: timeout\n", | 409 | pr_err(MPT3SAS_FMT "%s: timeout\n", |
diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index 523971aeb4c1..d3cb387ba9f4 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c | |||
| @@ -820,7 +820,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, | |||
| 820 | ret = -EINVAL; | 820 | ret = -EINVAL; |
| 821 | goto out; | 821 | goto out; |
| 822 | } | 822 | } |
| 823 | ioc->put_smid_nvme_encap(ioc, smid); | 823 | mpt3sas_base_put_smid_nvme_encap(ioc, smid); |
| 824 | break; | 824 | break; |
| 825 | } | 825 | } |
| 826 | case MPI2_FUNCTION_SCSI_IO_REQUEST: | 826 | case MPI2_FUNCTION_SCSI_IO_REQUEST: |
| @@ -845,7 +845,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, | |||
| 845 | if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST) | 845 | if (mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST) |
| 846 | ioc->put_smid_scsi_io(ioc, smid, device_handle); | 846 | ioc->put_smid_scsi_io(ioc, smid, device_handle); |
| 847 | else | 847 | else |
| 848 | ioc->put_smid_default(ioc, smid); | 848 | mpt3sas_base_put_smid_default(ioc, smid); |
| 849 | break; | 849 | break; |
| 850 | } | 850 | } |
| 851 | case MPI2_FUNCTION_SCSI_TASK_MGMT: | 851 | case MPI2_FUNCTION_SCSI_TASK_MGMT: |
| @@ -882,7 +882,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, | |||
| 882 | tm_request->DevHandle)); | 882 | tm_request->DevHandle)); |
| 883 | ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz, | 883 | ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz, |
| 884 | data_in_dma, data_in_sz); | 884 | data_in_dma, data_in_sz); |
| 885 | ioc->put_smid_hi_priority(ioc, smid, 0); | 885 | mpt3sas_base_put_smid_hi_priority(ioc, smid, 0); |
| 886 | break; | 886 | break; |
| 887 | } | 887 | } |
| 888 | case MPI2_FUNCTION_SMP_PASSTHROUGH: | 888 | case MPI2_FUNCTION_SMP_PASSTHROUGH: |
| @@ -913,7 +913,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, | |||
| 913 | } | 913 | } |
| 914 | ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma, | 914 | ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma, |
| 915 | data_in_sz); | 915 | data_in_sz); |
| 916 | ioc->put_smid_default(ioc, smid); | 916 | mpt3sas_base_put_smid_default(ioc, smid); |
| 917 | break; | 917 | break; |
| 918 | } | 918 | } |
| 919 | case MPI2_FUNCTION_SATA_PASSTHROUGH: | 919 | case MPI2_FUNCTION_SATA_PASSTHROUGH: |
| @@ -928,7 +928,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, | |||
| 928 | } | 928 | } |
| 929 | ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma, | 929 | ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma, |
| 930 | data_in_sz); | 930 | data_in_sz); |
| 931 | ioc->put_smid_default(ioc, smid); | 931 | mpt3sas_base_put_smid_default(ioc, smid); |
| 932 | break; | 932 | break; |
| 933 | } | 933 | } |
| 934 | case MPI2_FUNCTION_FW_DOWNLOAD: | 934 | case MPI2_FUNCTION_FW_DOWNLOAD: |
| @@ -936,7 +936,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, | |||
| 936 | { | 936 | { |
| 937 | ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma, | 937 | ioc->build_sg(ioc, psge, data_out_dma, data_out_sz, data_in_dma, |
| 938 | data_in_sz); | 938 | data_in_sz); |
| 939 | ioc->put_smid_default(ioc, smid); | 939 | mpt3sas_base_put_smid_default(ioc, smid); |
| 940 | break; | 940 | break; |
| 941 | } | 941 | } |
| 942 | case MPI2_FUNCTION_TOOLBOX: | 942 | case MPI2_FUNCTION_TOOLBOX: |
| @@ -951,7 +951,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, | |||
| 951 | ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz, | 951 | ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz, |
| 952 | data_in_dma, data_in_sz); | 952 | data_in_dma, data_in_sz); |
| 953 | } | 953 | } |
| 954 | ioc->put_smid_default(ioc, smid); | 954 | mpt3sas_base_put_smid_default(ioc, smid); |
| 955 | break; | 955 | break; |
| 956 | } | 956 | } |
| 957 | case MPI2_FUNCTION_SAS_IO_UNIT_CONTROL: | 957 | case MPI2_FUNCTION_SAS_IO_UNIT_CONTROL: |
| @@ -970,7 +970,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, | |||
| 970 | default: | 970 | default: |
| 971 | ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz, | 971 | ioc->build_sg_mpi(ioc, psge, data_out_dma, data_out_sz, |
| 972 | data_in_dma, data_in_sz); | 972 | data_in_dma, data_in_sz); |
| 973 | ioc->put_smid_default(ioc, smid); | 973 | mpt3sas_base_put_smid_default(ioc, smid); |
| 974 | break; | 974 | break; |
| 975 | } | 975 | } |
| 976 | 976 | ||
| @@ -1601,7 +1601,7 @@ _ctl_diag_register_2(struct MPT3SAS_ADAPTER *ioc, | |||
| 1601 | cpu_to_le32(ioc->product_specific[buffer_type][i]); | 1601 | cpu_to_le32(ioc->product_specific[buffer_type][i]); |
| 1602 | 1602 | ||
| 1603 | init_completion(&ioc->ctl_cmds.done); | 1603 | init_completion(&ioc->ctl_cmds.done); |
| 1604 | ioc->put_smid_default(ioc, smid); | 1604 | mpt3sas_base_put_smid_default(ioc, smid); |
| 1605 | wait_for_completion_timeout(&ioc->ctl_cmds.done, | 1605 | wait_for_completion_timeout(&ioc->ctl_cmds.done, |
| 1606 | MPT3_IOCTL_DEFAULT_TIMEOUT*HZ); | 1606 | MPT3_IOCTL_DEFAULT_TIMEOUT*HZ); |
| 1607 | 1607 | ||
| @@ -1948,7 +1948,7 @@ mpt3sas_send_diag_release(struct MPT3SAS_ADAPTER *ioc, u8 buffer_type, | |||
| 1948 | mpi_request->VP_ID = 0; | 1948 | mpi_request->VP_ID = 0; |
| 1949 | 1949 | ||
| 1950 | init_completion(&ioc->ctl_cmds.done); | 1950 | init_completion(&ioc->ctl_cmds.done); |
| 1951 | ioc->put_smid_default(ioc, smid); | 1951 | mpt3sas_base_put_smid_default(ioc, smid); |
| 1952 | wait_for_completion_timeout(&ioc->ctl_cmds.done, | 1952 | wait_for_completion_timeout(&ioc->ctl_cmds.done, |
| 1953 | MPT3_IOCTL_DEFAULT_TIMEOUT*HZ); | 1953 | MPT3_IOCTL_DEFAULT_TIMEOUT*HZ); |
| 1954 | 1954 | ||
| @@ -2215,7 +2215,7 @@ _ctl_diag_read_buffer(struct MPT3SAS_ADAPTER *ioc, void __user *arg) | |||
| 2215 | mpi_request->VP_ID = 0; | 2215 | mpi_request->VP_ID = 0; |
| 2216 | 2216 | ||
| 2217 | init_completion(&ioc->ctl_cmds.done); | 2217 | init_completion(&ioc->ctl_cmds.done); |
| 2218 | ioc->put_smid_default(ioc, smid); | 2218 | mpt3sas_base_put_smid_default(ioc, smid); |
| 2219 | wait_for_completion_timeout(&ioc->ctl_cmds.done, | 2219 | wait_for_completion_timeout(&ioc->ctl_cmds.done, |
| 2220 | MPT3_IOCTL_DEFAULT_TIMEOUT*HZ); | 2220 | MPT3_IOCTL_DEFAULT_TIMEOUT*HZ); |
| 2221 | 2221 | ||
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index aee1a0e1c600..8cd3782fab49 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c | |||
| @@ -2679,7 +2679,7 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, | |||
| 2679 | int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN); | 2679 | int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN); |
| 2680 | mpt3sas_scsih_set_tm_flag(ioc, handle); | 2680 | mpt3sas_scsih_set_tm_flag(ioc, handle); |
| 2681 | init_completion(&ioc->tm_cmds.done); | 2681 | init_completion(&ioc->tm_cmds.done); |
| 2682 | ioc->put_smid_hi_priority(ioc, smid, msix_task); | 2682 | mpt3sas_base_put_smid_hi_priority(ioc, smid, msix_task); |
| 2683 | wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ); | 2683 | wait_for_completion_timeout(&ioc->tm_cmds.done, timeout*HZ); |
| 2684 | if (!(ioc->tm_cmds.status & MPT3_CMD_COMPLETE)) { | 2684 | if (!(ioc->tm_cmds.status & MPT3_CMD_COMPLETE)) { |
| 2685 | pr_err(MPT3SAS_FMT "%s: timeout\n", | 2685 | pr_err(MPT3SAS_FMT "%s: timeout\n", |
| @@ -3641,7 +3641,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle) | |||
| 3641 | mpi_request->DevHandle = cpu_to_le16(handle); | 3641 | mpi_request->DevHandle = cpu_to_le16(handle); |
| 3642 | mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; | 3642 | mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; |
| 3643 | set_bit(handle, ioc->device_remove_in_progress); | 3643 | set_bit(handle, ioc->device_remove_in_progress); |
| 3644 | ioc->put_smid_hi_priority(ioc, smid, 0); | 3644 | mpt3sas_base_put_smid_hi_priority(ioc, smid, 0); |
| 3645 | mpt3sas_trigger_master(ioc, MASTER_TRIGGER_DEVICE_REMOVAL); | 3645 | mpt3sas_trigger_master(ioc, MASTER_TRIGGER_DEVICE_REMOVAL); |
| 3646 | 3646 | ||
| 3647 | out: | 3647 | out: |
| @@ -3742,7 +3742,7 @@ _scsih_tm_tr_complete(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, | |||
| 3742 | mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; | 3742 | mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; |
| 3743 | mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE; | 3743 | mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE; |
| 3744 | mpi_request->DevHandle = mpi_request_tm->DevHandle; | 3744 | mpi_request->DevHandle = mpi_request_tm->DevHandle; |
| 3745 | ioc->put_smid_default(ioc, smid_sas_ctrl); | 3745 | mpt3sas_base_put_smid_default(ioc, smid_sas_ctrl); |
| 3746 | 3746 | ||
| 3747 | return _scsih_check_for_pending_tm(ioc, smid); | 3747 | return _scsih_check_for_pending_tm(ioc, smid); |
| 3748 | } | 3748 | } |
| @@ -3837,7 +3837,7 @@ _scsih_tm_tr_volume_send(struct MPT3SAS_ADAPTER *ioc, u16 handle) | |||
| 3837 | mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; | 3837 | mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT; |
| 3838 | mpi_request->DevHandle = cpu_to_le16(handle); | 3838 | mpi_request->DevHandle = cpu_to_le16(handle); |
| 3839 | mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; | 3839 | mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET; |
| 3840 | ioc->put_smid_hi_priority(ioc, smid, 0); | 3840 | mpt3sas_base_put_smid_hi_priority(ioc, smid, 0); |
| 3841 | } | 3841 | } |
| 3842 | 3842 | ||
| 3843 | /** | 3843 | /** |
| @@ -3929,7 +3929,7 @@ _scsih_issue_delayed_event_ack(struct MPT3SAS_ADAPTER *ioc, u16 smid, u16 event, | |||
| 3929 | ack_request->EventContext = event_context; | 3929 | ack_request->EventContext = event_context; |
| 3930 | ack_request->VF_ID = 0; /* TODO */ | 3930 | ack_request->VF_ID = 0; /* TODO */ |
| 3931 | ack_request->VP_ID = 0; | 3931 | ack_request->VP_ID = 0; |
| 3932 | ioc->put_smid_default(ioc, smid); | 3932 | mpt3sas_base_put_smid_default(ioc, smid); |
| 3933 | } | 3933 | } |
| 3934 | 3934 | ||
| 3935 | /** | 3935 | /** |
| @@ -3986,7 +3986,7 @@ _scsih_issue_delayed_sas_io_unit_ctrl(struct MPT3SAS_ADAPTER *ioc, | |||
| 3986 | mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; | 3986 | mpi_request->Function = MPI2_FUNCTION_SAS_IO_UNIT_CONTROL; |
| 3987 | mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE; | 3987 | mpi_request->Operation = MPI2_SAS_OP_REMOVE_DEVICE; |
| 3988 | mpi_request->DevHandle = handle; | 3988 | mpi_request->DevHandle = handle; |
| 3989 | ioc->put_smid_default(ioc, smid); | 3989 | mpt3sas_base_put_smid_default(ioc, smid); |
| 3990 | } | 3990 | } |
| 3991 | 3991 | ||
| 3992 | /** | 3992 | /** |
| @@ -4715,12 +4715,12 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd) | |||
| 4715 | if (sas_target_priv_data->flags & MPT_TARGET_FASTPATH_IO) { | 4715 | if (sas_target_priv_data->flags & MPT_TARGET_FASTPATH_IO) { |
| 4716 | mpi_request->IoFlags = cpu_to_le16(scmd->cmd_len | | 4716 | mpi_request->IoFlags = cpu_to_le16(scmd->cmd_len | |
| 4717 | MPI25_SCSIIO_IOFLAGS_FAST_PATH); | 4717 | MPI25_SCSIIO_IOFLAGS_FAST_PATH); |
| 4718 | ioc->put_smid_fast_path(ioc, smid, handle); | 4718 | mpt3sas_base_put_smid_fast_path(ioc, smid, handle); |
| 4719 | } else | 4719 | } else |
| 4720 | ioc->put_smid_scsi_io(ioc, smid, | 4720 | ioc->put_smid_scsi_io(ioc, smid, |
| 4721 | le16_to_cpu(mpi_request->DevHandle)); | 4721 | le16_to_cpu(mpi_request->DevHandle)); |
| 4722 | } else | 4722 | } else |
| 4723 | ioc->put_smid_default(ioc, smid); | 4723 | mpt3sas_base_put_smid_default(ioc, smid); |
| 4724 | return 0; | 4724 | return 0; |
| 4725 | 4725 | ||
| 4726 | out: | 4726 | out: |
| @@ -7609,7 +7609,7 @@ _scsih_ir_fastpath(struct MPT3SAS_ADAPTER *ioc, u16 handle, u8 phys_disk_num) | |||
| 7609 | handle, phys_disk_num)); | 7609 | handle, phys_disk_num)); |
| 7610 | 7610 | ||
| 7611 | init_completion(&ioc->scsih_cmds.done); | 7611 | init_completion(&ioc->scsih_cmds.done); |
| 7612 | ioc->put_smid_default(ioc, smid); | 7612 | mpt3sas_base_put_smid_default(ioc, smid); |
| 7613 | wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ); | 7613 | wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ); |
| 7614 | 7614 | ||
| 7615 | if (!(ioc->scsih_cmds.status & MPT3_CMD_COMPLETE)) { | 7615 | if (!(ioc->scsih_cmds.status & MPT3_CMD_COMPLETE)) { |
| @@ -9700,7 +9700,7 @@ _scsih_ir_shutdown(struct MPT3SAS_ADAPTER *ioc) | |||
| 9700 | if (!ioc->hide_ir_msg) | 9700 | if (!ioc->hide_ir_msg) |
| 9701 | pr_info(MPT3SAS_FMT "IR shutdown (sending)\n", ioc->name); | 9701 | pr_info(MPT3SAS_FMT "IR shutdown (sending)\n", ioc->name); |
| 9702 | init_completion(&ioc->scsih_cmds.done); | 9702 | init_completion(&ioc->scsih_cmds.done); |
| 9703 | ioc->put_smid_default(ioc, smid); | 9703 | mpt3sas_base_put_smid_default(ioc, smid); |
| 9704 | wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ); | 9704 | wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ); |
| 9705 | 9705 | ||
| 9706 | if (!(ioc->scsih_cmds.status & MPT3_CMD_COMPLETE)) { | 9706 | if (!(ioc->scsih_cmds.status & MPT3_CMD_COMPLETE)) { |
| @@ -10346,6 +10346,7 @@ _scsih_determine_hba_mpi_version(struct pci_dev *pdev) | |||
| 10346 | case MPI2_MFGPAGE_DEVID_SAS2308_1: | 10346 | case MPI2_MFGPAGE_DEVID_SAS2308_1: |
| 10347 | case MPI2_MFGPAGE_DEVID_SAS2308_2: | 10347 | case MPI2_MFGPAGE_DEVID_SAS2308_2: |
| 10348 | case MPI2_MFGPAGE_DEVID_SAS2308_3: | 10348 | case MPI2_MFGPAGE_DEVID_SAS2308_3: |
| 10349 | case MPI2_MFGPAGE_DEVID_SAS2308_MPI_EP: | ||
| 10349 | return MPI2_VERSION; | 10350 | return MPI2_VERSION; |
| 10350 | case MPI25_MFGPAGE_DEVID_SAS3004: | 10351 | case MPI25_MFGPAGE_DEVID_SAS3004: |
| 10351 | case MPI25_MFGPAGE_DEVID_SAS3008: | 10352 | case MPI25_MFGPAGE_DEVID_SAS3008: |
| @@ -10423,11 +10424,18 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 10423 | ioc->hba_mpi_version_belonged = hba_mpi_version; | 10424 | ioc->hba_mpi_version_belonged = hba_mpi_version; |
| 10424 | ioc->id = mpt2_ids++; | 10425 | ioc->id = mpt2_ids++; |
| 10425 | sprintf(ioc->driver_name, "%s", MPT2SAS_DRIVER_NAME); | 10426 | sprintf(ioc->driver_name, "%s", MPT2SAS_DRIVER_NAME); |
| 10426 | if (pdev->device == MPI2_MFGPAGE_DEVID_SSS6200) { | 10427 | switch (pdev->device) { |
| 10428 | case MPI2_MFGPAGE_DEVID_SSS6200: | ||
| 10427 | ioc->is_warpdrive = 1; | 10429 | ioc->is_warpdrive = 1; |
| 10428 | ioc->hide_ir_msg = 1; | 10430 | ioc->hide_ir_msg = 1; |
| 10429 | } else | 10431 | break; |
| 10432 | case MPI2_MFGPAGE_DEVID_SAS2308_MPI_EP: | ||
| 10433 | ioc->is_mcpu_endpoint = 1; | ||
| 10434 | break; | ||
| 10435 | default: | ||
| 10430 | ioc->mfg_pg10_hide_flag = MFG_PAGE10_EXPOSE_ALL_DISKS; | 10436 | ioc->mfg_pg10_hide_flag = MFG_PAGE10_EXPOSE_ALL_DISKS; |
| 10437 | break; | ||
| 10438 | } | ||
| 10431 | break; | 10439 | break; |
| 10432 | case MPI25_VERSION: | 10440 | case MPI25_VERSION: |
| 10433 | case MPI26_VERSION: | 10441 | case MPI26_VERSION: |
| @@ -10524,26 +10532,34 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 10524 | shost->transportt = mpt3sas_transport_template; | 10532 | shost->transportt = mpt3sas_transport_template; |
| 10525 | shost->unique_id = ioc->id; | 10533 | shost->unique_id = ioc->id; |
| 10526 | 10534 | ||
| 10527 | if (max_sectors != 0xFFFF) { | 10535 | if (ioc->is_mcpu_endpoint) { |
| 10528 | if (max_sectors < 64) { | 10536 | /* mCPU MPI support 64K max IO */ |
| 10529 | shost->max_sectors = 64; | 10537 | shost->max_sectors = 128; |
| 10530 | pr_warn(MPT3SAS_FMT "Invalid value %d passed " \ | 10538 | pr_info(MPT3SAS_FMT |
| 10531 | "for max_sectors, range is 64 to 32767. Assigning " | ||
| 10532 | "value of 64.\n", ioc->name, max_sectors); | ||
| 10533 | } else if (max_sectors > 32767) { | ||
| 10534 | shost->max_sectors = 32767; | ||
| 10535 | pr_warn(MPT3SAS_FMT "Invalid value %d passed " \ | ||
| 10536 | "for max_sectors, range is 64 to 32767. Assigning " | ||
| 10537 | "default value of 32767.\n", ioc->name, | ||
| 10538 | max_sectors); | ||
| 10539 | } else { | ||
| 10540 | shost->max_sectors = max_sectors & 0xFFFE; | ||
| 10541 | pr_info(MPT3SAS_FMT | ||
| 10542 | "The max_sectors value is set to %d\n", | 10539 | "The max_sectors value is set to %d\n", |
| 10543 | ioc->name, shost->max_sectors); | 10540 | ioc->name, shost->max_sectors); |
| 10541 | } else { | ||
| 10542 | if (max_sectors != 0xFFFF) { | ||
| 10543 | if (max_sectors < 64) { | ||
| 10544 | shost->max_sectors = 64; | ||
| 10545 | pr_warn(MPT3SAS_FMT "Invalid value %d passed " \ | ||
| 10546 | "for max_sectors, range is 64 to 32767. " \ | ||
| 10547 | "Assigning value of 64.\n", \ | ||
| 10548 | ioc->name, max_sectors); | ||
| 10549 | } else if (max_sectors > 32767) { | ||
| 10550 | shost->max_sectors = 32767; | ||
| 10551 | pr_warn(MPT3SAS_FMT "Invalid value %d passed " \ | ||
| 10552 | "for max_sectors, range is 64 to 32767." \ | ||
| 10553 | "Assigning default value of 32767.\n", \ | ||
| 10554 | ioc->name, max_sectors); | ||
| 10555 | } else { | ||
| 10556 | shost->max_sectors = max_sectors & 0xFFFE; | ||
| 10557 | pr_info(MPT3SAS_FMT | ||
| 10558 | "The max_sectors value is set to %d\n", | ||
| 10559 | ioc->name, shost->max_sectors); | ||
| 10560 | } | ||
| 10544 | } | 10561 | } |
| 10545 | } | 10562 | } |
| 10546 | |||
| 10547 | /* register EEDP capabilities with SCSI layer */ | 10563 | /* register EEDP capabilities with SCSI layer */ |
| 10548 | if (prot_mask > 0) | 10564 | if (prot_mask > 0) |
| 10549 | scsi_host_set_prot(shost, prot_mask); | 10565 | scsi_host_set_prot(shost, prot_mask); |
| @@ -10856,6 +10872,8 @@ static const struct pci_device_id mpt3sas_pci_table[] = { | |||
| 10856 | PCI_ANY_ID, PCI_ANY_ID }, | 10872 | PCI_ANY_ID, PCI_ANY_ID }, |
| 10857 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_3, | 10873 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_3, |
| 10858 | PCI_ANY_ID, PCI_ANY_ID }, | 10874 | PCI_ANY_ID, PCI_ANY_ID }, |
| 10875 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_MPI_EP, | ||
| 10876 | PCI_ANY_ID, PCI_ANY_ID }, | ||
| 10859 | /* SSS6200 */ | 10877 | /* SSS6200 */ |
| 10860 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SSS6200, | 10878 | { MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SSS6200, |
| 10861 | PCI_ANY_ID, PCI_ANY_ID }, | 10879 | PCI_ANY_ID, PCI_ANY_ID }, |
diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c b/drivers/scsi/mpt3sas/mpt3sas_transport.c index d3940c5d079d..3a143bb5ca72 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_transport.c +++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c | |||
| @@ -392,7 +392,7 @@ _transport_expander_report_manufacture(struct MPT3SAS_ADAPTER *ioc, | |||
| 392 | "report_manufacture - send to sas_addr(0x%016llx)\n", | 392 | "report_manufacture - send to sas_addr(0x%016llx)\n", |
| 393 | ioc->name, (unsigned long long)sas_address)); | 393 | ioc->name, (unsigned long long)sas_address)); |
| 394 | init_completion(&ioc->transport_cmds.done); | 394 | init_completion(&ioc->transport_cmds.done); |
| 395 | ioc->put_smid_default(ioc, smid); | 395 | mpt3sas_base_put_smid_default(ioc, smid); |
| 396 | wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ); | 396 | wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ); |
| 397 | 397 | ||
| 398 | if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) { | 398 | if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) { |
| @@ -1198,7 +1198,7 @@ _transport_get_expander_phy_error_log(struct MPT3SAS_ADAPTER *ioc, | |||
| 1198 | ioc->name, (unsigned long long)phy->identify.sas_address, | 1198 | ioc->name, (unsigned long long)phy->identify.sas_address, |
| 1199 | phy->number)); | 1199 | phy->number)); |
| 1200 | init_completion(&ioc->transport_cmds.done); | 1200 | init_completion(&ioc->transport_cmds.done); |
| 1201 | ioc->put_smid_default(ioc, smid); | 1201 | mpt3sas_base_put_smid_default(ioc, smid); |
| 1202 | wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ); | 1202 | wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ); |
| 1203 | 1203 | ||
| 1204 | if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) { | 1204 | if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) { |
| @@ -1514,7 +1514,7 @@ _transport_expander_phy_control(struct MPT3SAS_ADAPTER *ioc, | |||
| 1514 | ioc->name, (unsigned long long)phy->identify.sas_address, | 1514 | ioc->name, (unsigned long long)phy->identify.sas_address, |
| 1515 | phy->number, phy_operation)); | 1515 | phy->number, phy_operation)); |
| 1516 | init_completion(&ioc->transport_cmds.done); | 1516 | init_completion(&ioc->transport_cmds.done); |
| 1517 | ioc->put_smid_default(ioc, smid); | 1517 | mpt3sas_base_put_smid_default(ioc, smid); |
| 1518 | wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ); | 1518 | wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ); |
| 1519 | 1519 | ||
| 1520 | if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) { | 1520 | if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) { |
| @@ -2014,7 +2014,7 @@ _transport_smp_handler(struct bsg_job *job, struct Scsi_Host *shost, | |||
| 2014 | "%s - sending smp request\n", ioc->name, __func__)); | 2014 | "%s - sending smp request\n", ioc->name, __func__)); |
| 2015 | 2015 | ||
| 2016 | init_completion(&ioc->transport_cmds.done); | 2016 | init_completion(&ioc->transport_cmds.done); |
| 2017 | ioc->put_smid_default(ioc, smid); | 2017 | mpt3sas_base_put_smid_default(ioc, smid); |
| 2018 | wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ); | 2018 | wait_for_completion_timeout(&ioc->transport_cmds.done, 10*HZ); |
| 2019 | 2019 | ||
| 2020 | if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) { | 2020 | if (!(ioc->transport_cmds.status & MPT3_CMD_COMPLETE)) { |
diff --git a/drivers/scsi/mvme147.c b/drivers/scsi/mvme147.c index e6b2b681fda3..7d1ab414b78f 100644 --- a/drivers/scsi/mvme147.c +++ b/drivers/scsi/mvme147.c | |||
| @@ -3,6 +3,9 @@ | |||
| 3 | #include <linux/mm.h> | 3 | #include <linux/mm.h> |
| 4 | #include <linux/blkdev.h> | 4 | #include <linux/blkdev.h> |
| 5 | #include <linux/interrupt.h> | 5 | #include <linux/interrupt.h> |
| 6 | #include <linux/init.h> | ||
| 7 | #include <linux/kernel.h> | ||
| 8 | #include <linux/module.h> | ||
| 6 | 9 | ||
| 7 | #include <asm/page.h> | 10 | #include <asm/page.h> |
| 8 | #include <asm/pgtable.h> | 11 | #include <asm/pgtable.h> |
| @@ -14,9 +17,6 @@ | |||
| 14 | #include "wd33c93.h" | 17 | #include "wd33c93.h" |
| 15 | #include "mvme147.h" | 18 | #include "mvme147.h" |
| 16 | 19 | ||
| 17 | #include <linux/stat.h> | ||
| 18 | |||
| 19 | |||
| 20 | static irqreturn_t mvme147_intr(int irq, void *data) | 20 | static irqreturn_t mvme147_intr(int irq, void *data) |
| 21 | { | 21 | { |
| 22 | struct Scsi_Host *instance = data; | 22 | struct Scsi_Host *instance = data; |
| @@ -65,40 +65,57 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, | |||
| 65 | m147_pcc->dma_cntrl = 0; | 65 | m147_pcc->dma_cntrl = 0; |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | int mvme147_detect(struct scsi_host_template *tpnt) | 68 | static struct scsi_host_template mvme147_host_template = { |
| 69 | .module = THIS_MODULE, | ||
| 70 | .proc_name = "MVME147", | ||
| 71 | .name = "MVME147 built-in SCSI", | ||
| 72 | .queuecommand = wd33c93_queuecommand, | ||
| 73 | .eh_abort_handler = wd33c93_abort, | ||
| 74 | .eh_host_reset_handler = wd33c93_host_reset, | ||
| 75 | .show_info = wd33c93_show_info, | ||
| 76 | .write_info = wd33c93_write_info, | ||
| 77 | .can_queue = CAN_QUEUE, | ||
| 78 | .this_id = 7, | ||
| 79 | .sg_tablesize = SG_ALL, | ||
| 80 | .cmd_per_lun = CMD_PER_LUN, | ||
| 81 | .use_clustering = ENABLE_CLUSTERING | ||
| 82 | }; | ||
| 83 | |||
| 84 | static struct Scsi_Host *mvme147_shost; | ||
| 85 | |||
| 86 | static int __init mvme147_init(void) | ||
| 69 | { | 87 | { |
| 70 | static unsigned char called = 0; | ||
| 71 | struct Scsi_Host *instance; | ||
| 72 | wd33c93_regs regs; | 88 | wd33c93_regs regs; |
| 73 | struct WD33C93_hostdata *hdata; | 89 | struct WD33C93_hostdata *hdata; |
| 90 | int error = -ENOMEM; | ||
| 74 | 91 | ||
| 75 | if (!MACH_IS_MVME147 || called) | 92 | if (!MACH_IS_MVME147) |
| 76 | return 0; | 93 | return 0; |
| 77 | called++; | ||
| 78 | 94 | ||
| 79 | tpnt->proc_name = "MVME147"; | 95 | mvme147_shost = scsi_host_alloc(&mvme147_host_template, |
| 80 | tpnt->show_info = wd33c93_show_info, | 96 | sizeof(struct WD33C93_hostdata)); |
| 81 | tpnt->write_info = wd33c93_write_info, | 97 | if (!mvme147_shost) |
| 82 | |||
| 83 | instance = scsi_register(tpnt, sizeof(struct WD33C93_hostdata)); | ||
| 84 | if (!instance) | ||
| 85 | goto err_out; | 98 | goto err_out; |
| 99 | mvme147_shost->base = 0xfffe4000; | ||
| 100 | mvme147_shost->irq = MVME147_IRQ_SCSI_PORT; | ||
| 86 | 101 | ||
| 87 | instance->base = 0xfffe4000; | ||
| 88 | instance->irq = MVME147_IRQ_SCSI_PORT; | ||
| 89 | regs.SASR = (volatile unsigned char *)0xfffe4000; | 102 | regs.SASR = (volatile unsigned char *)0xfffe4000; |
| 90 | regs.SCMD = (volatile unsigned char *)0xfffe4001; | 103 | regs.SCMD = (volatile unsigned char *)0xfffe4001; |
| 91 | hdata = shost_priv(instance); | 104 | |
| 105 | hdata = shost_priv(mvme147_shost); | ||
| 92 | hdata->no_sync = 0xff; | 106 | hdata->no_sync = 0xff; |
| 93 | hdata->fast = 0; | 107 | hdata->fast = 0; |
| 94 | hdata->dma_mode = CTRL_DMA; | 108 | hdata->dma_mode = CTRL_DMA; |
| 95 | wd33c93_init(instance, regs, dma_setup, dma_stop, WD33C93_FS_8_10); | ||
| 96 | 109 | ||
| 97 | if (request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0, | 110 | wd33c93_init(mvme147_shost, regs, dma_setup, dma_stop, WD33C93_FS_8_10); |
| 98 | "MVME147 SCSI PORT", instance)) | 111 | |
| 112 | error = request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0, | ||
| 113 | "MVME147 SCSI PORT", mvme147_shost); | ||
| 114 | if (error) | ||
| 99 | goto err_unregister; | 115 | goto err_unregister; |
| 100 | if (request_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr, 0, | 116 | error = request_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr, 0, |
| 101 | "MVME147 SCSI DMA", instance)) | 117 | "MVME147 SCSI DMA", mvme147_shost); |
| 118 | if (error) | ||
| 102 | goto err_free_irq; | 119 | goto err_free_irq; |
| 103 | #if 0 /* Disabled; causes problems booting */ | 120 | #if 0 /* Disabled; causes problems booting */ |
| 104 | m147_pcc->scsi_interrupt = 0x10; /* Assert SCSI bus reset */ | 121 | m147_pcc->scsi_interrupt = 0x10; /* Assert SCSI bus reset */ |
| @@ -112,40 +129,30 @@ int mvme147_detect(struct scsi_host_template *tpnt) | |||
| 112 | m147_pcc->dma_cntrl = 0x00; /* ensure DMA is stopped */ | 129 | m147_pcc->dma_cntrl = 0x00; /* ensure DMA is stopped */ |
| 113 | m147_pcc->dma_intr = 0x89; /* Ack and enable ints */ | 130 | m147_pcc->dma_intr = 0x89; /* Ack and enable ints */ |
| 114 | 131 | ||
| 115 | return 1; | 132 | error = scsi_add_host(mvme147_shost, NULL); |
| 133 | if (error) | ||
| 134 | goto err_free_irq; | ||
| 135 | scsi_scan_host(mvme147_shost); | ||
| 136 | return 0; | ||
| 116 | 137 | ||
| 117 | err_free_irq: | 138 | err_free_irq: |
| 118 | free_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr); | 139 | free_irq(MVME147_IRQ_SCSI_PORT, mvme147_shost); |
| 119 | err_unregister: | 140 | err_unregister: |
| 120 | scsi_unregister(instance); | 141 | scsi_host_put(mvme147_shost); |
| 121 | err_out: | 142 | err_out: |
| 122 | return 0; | 143 | return error; |
| 123 | } | 144 | } |
| 124 | 145 | ||
| 125 | static struct scsi_host_template driver_template = { | 146 | static void __exit mvme147_exit(void) |
| 126 | .proc_name = "MVME147", | ||
| 127 | .name = "MVME147 built-in SCSI", | ||
| 128 | .detect = mvme147_detect, | ||
| 129 | .release = mvme147_release, | ||
| 130 | .queuecommand = wd33c93_queuecommand, | ||
| 131 | .eh_abort_handler = wd33c93_abort, | ||
| 132 | .eh_host_reset_handler = wd33c93_host_reset, | ||
| 133 | .can_queue = CAN_QUEUE, | ||
| 134 | .this_id = 7, | ||
| 135 | .sg_tablesize = SG_ALL, | ||
| 136 | .cmd_per_lun = CMD_PER_LUN, | ||
| 137 | .use_clustering = ENABLE_CLUSTERING | ||
| 138 | }; | ||
| 139 | |||
| 140 | |||
| 141 | #include "scsi_module.c" | ||
| 142 | |||
| 143 | int mvme147_release(struct Scsi_Host *instance) | ||
| 144 | { | 147 | { |
| 145 | #ifdef MODULE | 148 | scsi_remove_host(mvme147_shost); |
| 149 | |||
| 146 | /* XXX Make sure DMA is stopped! */ | 150 | /* XXX Make sure DMA is stopped! */ |
| 147 | free_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr); | 151 | free_irq(MVME147_IRQ_SCSI_PORT, mvme147_shost); |
| 148 | free_irq(MVME147_IRQ_SCSI_DMA, mvme147_intr); | 152 | free_irq(MVME147_IRQ_SCSI_DMA, mvme147_shost); |
| 149 | #endif | 153 | |
| 150 | return 1; | 154 | scsi_host_put(mvme147_shost); |
| 151 | } | 155 | } |
| 156 | |||
| 157 | module_init(mvme147_init); | ||
| 158 | module_exit(mvme147_exit); | ||
diff --git a/drivers/scsi/mvsas/mv_94xx.c b/drivers/scsi/mvsas/mv_94xx.c index 7de5d8d75480..eb5471bc7263 100644 --- a/drivers/scsi/mvsas/mv_94xx.c +++ b/drivers/scsi/mvsas/mv_94xx.c | |||
| @@ -1080,16 +1080,16 @@ static int mvs_94xx_gpio_write(struct mvs_prv_info *mvs_prv, | |||
| 1080 | void __iomem *regs = mvi->regs_ex - 0x10200; | 1080 | void __iomem *regs = mvi->regs_ex - 0x10200; |
| 1081 | 1081 | ||
| 1082 | int drive = (i/3) & (4-1); /* drive number on host */ | 1082 | int drive = (i/3) & (4-1); /* drive number on host */ |
| 1083 | u32 block = mr32(MVS_SGPIO_DCTRL + | 1083 | int driveshift = drive * 8; /* bit offset of drive */ |
| 1084 | u32 block = ioread32be(regs + MVS_SGPIO_DCTRL + | ||
| 1084 | MVS_SGPIO_HOST_OFFSET * mvi->id); | 1085 | MVS_SGPIO_HOST_OFFSET * mvi->id); |
| 1085 | 1086 | ||
| 1086 | |||
| 1087 | /* | 1087 | /* |
| 1088 | * if bit is set then create a mask with the first | 1088 | * if bit is set then create a mask with the first |
| 1089 | * bit of the drive set in the mask ... | 1089 | * bit of the drive set in the mask ... |
| 1090 | */ | 1090 | */ |
| 1091 | u32 bit = (write_data[i/8] & (1 << (i&(8-1)))) ? | 1091 | u32 bit = get_unaligned_be32(write_data) & (1 << i) ? |
| 1092 | 1<<(24-drive*8) : 0; | 1092 | 1 << driveshift : 0; |
| 1093 | 1093 | ||
| 1094 | /* | 1094 | /* |
| 1095 | * ... and then shift it to the right position based | 1095 | * ... and then shift it to the right position based |
| @@ -1098,26 +1098,27 @@ static int mvs_94xx_gpio_write(struct mvs_prv_info *mvs_prv, | |||
| 1098 | switch (i%3) { | 1098 | switch (i%3) { |
| 1099 | case 0: /* activity */ | 1099 | case 0: /* activity */ |
| 1100 | block &= ~((0x7 << MVS_SGPIO_DCTRL_ACT_SHIFT) | 1100 | block &= ~((0x7 << MVS_SGPIO_DCTRL_ACT_SHIFT) |
| 1101 | << (24-drive*8)); | 1101 | << driveshift); |
| 1102 | /* hardwire activity bit to SOF */ | 1102 | /* hardwire activity bit to SOF */ |
| 1103 | block |= LED_BLINKA_SOF << ( | 1103 | block |= LED_BLINKA_SOF << ( |
| 1104 | MVS_SGPIO_DCTRL_ACT_SHIFT + | 1104 | MVS_SGPIO_DCTRL_ACT_SHIFT + |
| 1105 | (24-drive*8)); | 1105 | driveshift); |
| 1106 | break; | 1106 | break; |
| 1107 | case 1: /* id */ | 1107 | case 1: /* id */ |
| 1108 | block &= ~((0x3 << MVS_SGPIO_DCTRL_LOC_SHIFT) | 1108 | block &= ~((0x3 << MVS_SGPIO_DCTRL_LOC_SHIFT) |
| 1109 | << (24-drive*8)); | 1109 | << driveshift); |
| 1110 | block |= bit << MVS_SGPIO_DCTRL_LOC_SHIFT; | 1110 | block |= bit << MVS_SGPIO_DCTRL_LOC_SHIFT; |
| 1111 | break; | 1111 | break; |
| 1112 | case 2: /* fail */ | 1112 | case 2: /* fail */ |
| 1113 | block &= ~((0x7 << MVS_SGPIO_DCTRL_ERR_SHIFT) | 1113 | block &= ~((0x7 << MVS_SGPIO_DCTRL_ERR_SHIFT) |
| 1114 | << (24-drive*8)); | 1114 | << driveshift); |
| 1115 | block |= bit << MVS_SGPIO_DCTRL_ERR_SHIFT; | 1115 | block |= bit << MVS_SGPIO_DCTRL_ERR_SHIFT; |
| 1116 | break; | 1116 | break; |
| 1117 | } | 1117 | } |
| 1118 | 1118 | ||
| 1119 | mw32(MVS_SGPIO_DCTRL + MVS_SGPIO_HOST_OFFSET * mvi->id, | 1119 | iowrite32be(block, |
| 1120 | block); | 1120 | regs + MVS_SGPIO_DCTRL + |
| 1121 | MVS_SGPIO_HOST_OFFSET * mvi->id); | ||
| 1121 | 1122 | ||
| 1122 | } | 1123 | } |
| 1123 | 1124 | ||
| @@ -1132,7 +1133,7 @@ static int mvs_94xx_gpio_write(struct mvs_prv_info *mvs_prv, | |||
| 1132 | void __iomem *regs = mvi->regs_ex - 0x10200; | 1133 | void __iomem *regs = mvi->regs_ex - 0x10200; |
| 1133 | 1134 | ||
| 1134 | mw32(MVS_SGPIO_DCTRL + MVS_SGPIO_HOST_OFFSET * mvi->id, | 1135 | mw32(MVS_SGPIO_DCTRL + MVS_SGPIO_HOST_OFFSET * mvi->id, |
| 1135 | be32_to_cpu(((u32 *) write_data)[i])); | 1136 | ((u32 *) write_data)[i]); |
| 1136 | } | 1137 | } |
| 1137 | return reg_count; | 1138 | return reg_count; |
| 1138 | } | 1139 | } |
diff --git a/drivers/scsi/pcmcia/Kconfig b/drivers/scsi/pcmcia/Kconfig index ecc855c550aa..2d435f105b16 100644 --- a/drivers/scsi/pcmcia/Kconfig +++ b/drivers/scsi/pcmcia/Kconfig | |||
| @@ -19,15 +19,6 @@ config PCMCIA_AHA152X | |||
| 19 | To compile this driver as a module, choose M here: the | 19 | To compile this driver as a module, choose M here: the |
| 20 | module will be called aha152x_cs. | 20 | module will be called aha152x_cs. |
| 21 | 21 | ||
| 22 | config PCMCIA_FDOMAIN | ||
| 23 | tristate "Future Domain PCMCIA support" | ||
| 24 | help | ||
| 25 | Say Y here if you intend to attach this type of PCMCIA SCSI host | ||
| 26 | adapter to your computer. | ||
| 27 | |||
| 28 | To compile this driver as a module, choose M here: the | ||
| 29 | module will be called fdomain_cs. | ||
| 30 | |||
| 31 | config PCMCIA_NINJA_SCSI | 22 | config PCMCIA_NINJA_SCSI |
| 32 | tristate "NinjaSCSI-3 / NinjaSCSI-32Bi (16bit) PCMCIA support" | 23 | tristate "NinjaSCSI-3 / NinjaSCSI-32Bi (16bit) PCMCIA support" |
| 33 | depends on !64BIT | 24 | depends on !64BIT |
diff --git a/drivers/scsi/pcmcia/Makefile b/drivers/scsi/pcmcia/Makefile index 44eea2d43143..faa87a4b2d2b 100644 --- a/drivers/scsi/pcmcia/Makefile +++ b/drivers/scsi/pcmcia/Makefile | |||
| @@ -4,11 +4,9 @@ ccflags-y := -Idrivers/scsi | |||
| 4 | 4 | ||
| 5 | # 16-bit client drivers | 5 | # 16-bit client drivers |
| 6 | obj-$(CONFIG_PCMCIA_QLOGIC) += qlogic_cs.o | 6 | obj-$(CONFIG_PCMCIA_QLOGIC) += qlogic_cs.o |
| 7 | obj-$(CONFIG_PCMCIA_FDOMAIN) += fdomain_cs.o | ||
| 8 | obj-$(CONFIG_PCMCIA_AHA152X) += aha152x_cs.o | 7 | obj-$(CONFIG_PCMCIA_AHA152X) += aha152x_cs.o |
| 9 | obj-$(CONFIG_PCMCIA_NINJA_SCSI) += nsp_cs.o | 8 | obj-$(CONFIG_PCMCIA_NINJA_SCSI) += nsp_cs.o |
| 10 | obj-$(CONFIG_PCMCIA_SYM53C500) += sym53c500_cs.o | 9 | obj-$(CONFIG_PCMCIA_SYM53C500) += sym53c500_cs.o |
| 11 | 10 | ||
| 12 | aha152x_cs-objs := aha152x_stub.o aha152x_core.o | 11 | aha152x_cs-objs := aha152x_stub.o aha152x_core.o |
| 13 | fdomain_cs-objs := fdomain_stub.o fdomain_core.o | ||
| 14 | qlogic_cs-objs := qlogic_stub.o | 12 | qlogic_cs-objs := qlogic_stub.o |
diff --git a/drivers/scsi/pcmcia/fdomain_core.c b/drivers/scsi/pcmcia/fdomain_core.c deleted file mode 100644 index a48913791868..000000000000 --- a/drivers/scsi/pcmcia/fdomain_core.c +++ /dev/null | |||
| @@ -1,2 +0,0 @@ | |||
| 1 | #define PCMCIA 1 | ||
| 2 | #include "fdomain.c" | ||
diff --git a/drivers/scsi/pcmcia/fdomain_stub.c b/drivers/scsi/pcmcia/fdomain_stub.c deleted file mode 100644 index 953a792150ae..000000000000 --- a/drivers/scsi/pcmcia/fdomain_stub.c +++ /dev/null | |||
| @@ -1,209 +0,0 @@ | |||
| 1 | /*====================================================================== | ||
| 2 | |||
| 3 | A driver for Future Domain-compatible PCMCIA SCSI cards | ||
| 4 | |||
| 5 | fdomain_cs.c 1.47 2001/10/13 00:08:52 | ||
| 6 | |||
| 7 | The contents of this file are subject to the Mozilla Public | ||
| 8 | License Version 1.1 (the "License"); you may not use this file | ||
| 9 | except in compliance with the License. You may obtain a copy of | ||
| 10 | the License at http://www.mozilla.org/MPL/ | ||
| 11 | |||
| 12 | Software distributed under the License is distributed on an "AS | ||
| 13 | IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or | ||
| 14 | implied. See the License for the specific language governing | ||
| 15 | rights and limitations under the License. | ||
| 16 | |||
| 17 | The initial developer of the original code is David A. Hinds | ||
| 18 | <dahinds@users.sourceforge.net>. Portions created by David A. Hinds | ||
| 19 | are Copyright (C) 1999 David A. Hinds. All Rights Reserved. | ||
| 20 | |||
| 21 | Alternatively, the contents of this file may be used under the | ||
| 22 | terms of the GNU General Public License version 2 (the "GPL"), in | ||
| 23 | which case the provisions of the GPL are applicable instead of the | ||
| 24 | above. If you wish to allow the use of your version of this file | ||
| 25 | only under the terms of the GPL and not to allow others to use | ||
| 26 | your version of this file under the MPL, indicate your decision | ||
| 27 | by deleting the provisions above and replace them with the notice | ||
| 28 | and other provisions required by the GPL. If you do not delete | ||
| 29 | the provisions above, a recipient may use your version of this | ||
| 30 | file under either the MPL or the GPL. | ||
| 31 | |||
| 32 | ======================================================================*/ | ||
| 33 | |||
| 34 | #include <linux/module.h> | ||
| 35 | #include <linux/init.h> | ||
| 36 | #include <linux/kernel.h> | ||
| 37 | #include <linux/slab.h> | ||
| 38 | #include <linux/string.h> | ||
| 39 | #include <linux/ioport.h> | ||
| 40 | #include <scsi/scsi.h> | ||
| 41 | #include <linux/major.h> | ||
| 42 | #include <linux/blkdev.h> | ||
| 43 | #include <scsi/scsi_ioctl.h> | ||
| 44 | |||
| 45 | #include "scsi.h" | ||
| 46 | #include <scsi/scsi_host.h> | ||
| 47 | #include "fdomain.h" | ||
| 48 | |||
| 49 | #include <pcmcia/cistpl.h> | ||
| 50 | #include <pcmcia/ds.h> | ||
| 51 | |||
| 52 | /*====================================================================*/ | ||
| 53 | |||
| 54 | /* Module parameters */ | ||
| 55 | |||
| 56 | MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>"); | ||
| 57 | MODULE_DESCRIPTION("Future Domain PCMCIA SCSI driver"); | ||
| 58 | MODULE_LICENSE("Dual MPL/GPL"); | ||
| 59 | |||
| 60 | /*====================================================================*/ | ||
| 61 | |||
| 62 | typedef struct scsi_info_t { | ||
| 63 | struct pcmcia_device *p_dev; | ||
| 64 | struct Scsi_Host *host; | ||
| 65 | } scsi_info_t; | ||
| 66 | |||
| 67 | |||
| 68 | static void fdomain_release(struct pcmcia_device *link); | ||
| 69 | static void fdomain_detach(struct pcmcia_device *p_dev); | ||
| 70 | static int fdomain_config(struct pcmcia_device *link); | ||
| 71 | |||
| 72 | static int fdomain_probe(struct pcmcia_device *link) | ||
| 73 | { | ||
| 74 | scsi_info_t *info; | ||
| 75 | |||
| 76 | dev_dbg(&link->dev, "fdomain_attach()\n"); | ||
| 77 | |||
| 78 | /* Create new SCSI device */ | ||
| 79 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
| 80 | if (!info) | ||
| 81 | return -ENOMEM; | ||
| 82 | |||
| 83 | info->p_dev = link; | ||
| 84 | link->priv = info; | ||
| 85 | link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; | ||
| 86 | link->config_regs = PRESENT_OPTION; | ||
| 87 | |||
| 88 | return fdomain_config(link); | ||
| 89 | } /* fdomain_attach */ | ||
| 90 | |||
| 91 | /*====================================================================*/ | ||
| 92 | |||
| 93 | static void fdomain_detach(struct pcmcia_device *link) | ||
| 94 | { | ||
| 95 | dev_dbg(&link->dev, "fdomain_detach\n"); | ||
| 96 | |||
| 97 | fdomain_release(link); | ||
| 98 | |||
| 99 | kfree(link->priv); | ||
| 100 | } /* fdomain_detach */ | ||
| 101 | |||
| 102 | /*====================================================================*/ | ||
| 103 | |||
| 104 | static int fdomain_config_check(struct pcmcia_device *p_dev, void *priv_data) | ||
| 105 | { | ||
| 106 | p_dev->io_lines = 10; | ||
| 107 | p_dev->resource[0]->end = 0x10; | ||
| 108 | p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH; | ||
| 109 | p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO; | ||
| 110 | return pcmcia_request_io(p_dev); | ||
| 111 | } | ||
| 112 | |||
| 113 | |||
| 114 | static int fdomain_config(struct pcmcia_device *link) | ||
| 115 | { | ||
| 116 | scsi_info_t *info = link->priv; | ||
| 117 | int ret; | ||
| 118 | char str[22]; | ||
| 119 | struct Scsi_Host *host; | ||
| 120 | |||
| 121 | dev_dbg(&link->dev, "fdomain_config\n"); | ||
| 122 | |||
| 123 | ret = pcmcia_loop_config(link, fdomain_config_check, NULL); | ||
| 124 | if (ret) | ||
| 125 | goto failed; | ||
| 126 | |||
| 127 | if (!link->irq) | ||
| 128 | goto failed; | ||
| 129 | ret = pcmcia_enable_device(link); | ||
| 130 | if (ret) | ||
| 131 | goto failed; | ||
| 132 | |||
| 133 | /* A bad hack... */ | ||
| 134 | release_region(link->resource[0]->start, resource_size(link->resource[0])); | ||
| 135 | |||
| 136 | /* Set configuration options for the fdomain driver */ | ||
| 137 | sprintf(str, "%d,%d", (unsigned int) link->resource[0]->start, link->irq); | ||
| 138 | fdomain_setup(str); | ||
| 139 | |||
| 140 | host = __fdomain_16x0_detect(&fdomain_driver_template); | ||
| 141 | if (!host) { | ||
| 142 | printk(KERN_INFO "fdomain_cs: no SCSI devices found\n"); | ||
| 143 | goto failed; | ||
| 144 | } | ||
| 145 | |||
| 146 | if (scsi_add_host(host, NULL)) | ||
| 147 | goto failed; | ||
| 148 | scsi_scan_host(host); | ||
| 149 | |||
| 150 | info->host = host; | ||
| 151 | |||
| 152 | return 0; | ||
| 153 | |||
| 154 | failed: | ||
| 155 | fdomain_release(link); | ||
| 156 | return -ENODEV; | ||
| 157 | } /* fdomain_config */ | ||
| 158 | |||
| 159 | /*====================================================================*/ | ||
| 160 | |||
| 161 | static void fdomain_release(struct pcmcia_device *link) | ||
| 162 | { | ||
| 163 | scsi_info_t *info = link->priv; | ||
| 164 | |||
| 165 | dev_dbg(&link->dev, "fdomain_release\n"); | ||
| 166 | |||
| 167 | scsi_remove_host(info->host); | ||
| 168 | pcmcia_disable_device(link); | ||
| 169 | scsi_unregister(info->host); | ||
| 170 | } | ||
| 171 | |||
| 172 | /*====================================================================*/ | ||
| 173 | |||
| 174 | static int fdomain_resume(struct pcmcia_device *link) | ||
| 175 | { | ||
| 176 | fdomain_16x0_host_reset(NULL); | ||
| 177 | |||
| 178 | return 0; | ||
| 179 | } | ||
| 180 | |||
| 181 | static const struct pcmcia_device_id fdomain_ids[] = { | ||
| 182 | PCMCIA_DEVICE_PROD_ID12("IBM Corp.", "SCSI PCMCIA Card", 0xe3736c88, 0x859cad20), | ||
| 183 | PCMCIA_DEVICE_PROD_ID1("SCSI PCMCIA Adapter Card", 0x8dacb57e), | ||
| 184 | PCMCIA_DEVICE_PROD_ID12(" SIMPLE TECHNOLOGY Corporation", "SCSI PCMCIA Credit Card Controller", 0x182bdafe, 0xc80d106f), | ||
| 185 | PCMCIA_DEVICE_NULL, | ||
| 186 | }; | ||
| 187 | MODULE_DEVICE_TABLE(pcmcia, fdomain_ids); | ||
| 188 | |||
| 189 | static struct pcmcia_driver fdomain_cs_driver = { | ||
| 190 | .owner = THIS_MODULE, | ||
| 191 | .name = "fdomain_cs", | ||
| 192 | .probe = fdomain_probe, | ||
| 193 | .remove = fdomain_detach, | ||
| 194 | .id_table = fdomain_ids, | ||
| 195 | .resume = fdomain_resume, | ||
| 196 | }; | ||
| 197 | |||
| 198 | static int __init init_fdomain_cs(void) | ||
| 199 | { | ||
| 200 | return pcmcia_register_driver(&fdomain_cs_driver); | ||
| 201 | } | ||
| 202 | |||
| 203 | static void __exit exit_fdomain_cs(void) | ||
| 204 | { | ||
| 205 | pcmcia_unregister_driver(&fdomain_cs_driver); | ||
| 206 | } | ||
| 207 | |||
| 208 | module_init(init_fdomain_cs); | ||
| 209 | module_exit(exit_fdomain_cs); | ||
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index 201c8de1853d..95530393872d 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c | |||
| @@ -1025,7 +1025,7 @@ static void pmcraid_get_fwversion_done(struct pmcraid_cmd *cmd) | |||
| 1025 | static void pmcraid_get_fwversion(struct pmcraid_cmd *cmd) | 1025 | static void pmcraid_get_fwversion(struct pmcraid_cmd *cmd) |
| 1026 | { | 1026 | { |
| 1027 | struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb; | 1027 | struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb; |
| 1028 | struct pmcraid_ioadl_desc *ioadl = ioarcb->add_data.u.ioadl; | 1028 | struct pmcraid_ioadl_desc *ioadl; |
| 1029 | struct pmcraid_instance *pinstance = cmd->drv_inst; | 1029 | struct pmcraid_instance *pinstance = cmd->drv_inst; |
| 1030 | u16 data_size = sizeof(struct pmcraid_inquiry_data); | 1030 | u16 data_size = sizeof(struct pmcraid_inquiry_data); |
| 1031 | 1031 | ||
| @@ -3175,7 +3175,7 @@ static int pmcraid_build_ioadl( | |||
| 3175 | 3175 | ||
| 3176 | struct scsi_cmnd *scsi_cmd = cmd->scsi_cmd; | 3176 | struct scsi_cmnd *scsi_cmd = cmd->scsi_cmd; |
| 3177 | struct pmcraid_ioarcb *ioarcb = &(cmd->ioa_cb->ioarcb); | 3177 | struct pmcraid_ioarcb *ioarcb = &(cmd->ioa_cb->ioarcb); |
| 3178 | struct pmcraid_ioadl_desc *ioadl = ioarcb->add_data.u.ioadl; | 3178 | struct pmcraid_ioadl_desc *ioadl; |
| 3179 | 3179 | ||
| 3180 | u32 length = scsi_bufflen(scsi_cmd); | 3180 | u32 length = scsi_bufflen(scsi_cmd); |
| 3181 | 3181 | ||
| @@ -3225,12 +3225,7 @@ static int pmcraid_build_ioadl( | |||
| 3225 | */ | 3225 | */ |
| 3226 | static void pmcraid_free_sglist(struct pmcraid_sglist *sglist) | 3226 | static void pmcraid_free_sglist(struct pmcraid_sglist *sglist) |
| 3227 | { | 3227 | { |
| 3228 | int i; | 3228 | sgl_free_order(sglist->scatterlist, sglist->order); |
| 3229 | |||
| 3230 | for (i = 0; i < sglist->num_sg; i++) | ||
| 3231 | __free_pages(sg_page(&(sglist->scatterlist[i])), | ||
| 3232 | sglist->order); | ||
| 3233 | |||
| 3234 | kfree(sglist); | 3229 | kfree(sglist); |
| 3235 | } | 3230 | } |
| 3236 | 3231 | ||
| @@ -3247,50 +3242,20 @@ static void pmcraid_free_sglist(struct pmcraid_sglist *sglist) | |||
| 3247 | static struct pmcraid_sglist *pmcraid_alloc_sglist(int buflen) | 3242 | static struct pmcraid_sglist *pmcraid_alloc_sglist(int buflen) |
| 3248 | { | 3243 | { |
| 3249 | struct pmcraid_sglist *sglist; | 3244 | struct pmcraid_sglist *sglist; |
| 3250 | struct scatterlist *scatterlist; | ||
| 3251 | struct page *page; | ||
| 3252 | int num_elem, i, j; | ||
| 3253 | int sg_size; | 3245 | int sg_size; |
| 3254 | int order; | 3246 | int order; |
| 3255 | int bsize_elem; | ||
| 3256 | 3247 | ||
| 3257 | sg_size = buflen / (PMCRAID_MAX_IOADLS - 1); | 3248 | sg_size = buflen / (PMCRAID_MAX_IOADLS - 1); |
| 3258 | order = (sg_size > 0) ? get_order(sg_size) : 0; | 3249 | order = (sg_size > 0) ? get_order(sg_size) : 0; |
| 3259 | bsize_elem = PAGE_SIZE * (1 << order); | ||
| 3260 | |||
| 3261 | /* Determine the actual number of sg entries needed */ | ||
| 3262 | if (buflen % bsize_elem) | ||
| 3263 | num_elem = (buflen / bsize_elem) + 1; | ||
| 3264 | else | ||
| 3265 | num_elem = buflen / bsize_elem; | ||
| 3266 | 3250 | ||
| 3267 | /* Allocate a scatter/gather list for the DMA */ | 3251 | /* Allocate a scatter/gather list for the DMA */ |
| 3268 | sglist = kzalloc(sizeof(struct pmcraid_sglist) + | 3252 | sglist = kzalloc(sizeof(struct pmcraid_sglist), GFP_KERNEL); |
| 3269 | (sizeof(struct scatterlist) * (num_elem - 1)), | ||
| 3270 | GFP_KERNEL); | ||
| 3271 | |||
| 3272 | if (sglist == NULL) | 3253 | if (sglist == NULL) |
| 3273 | return NULL; | 3254 | return NULL; |
| 3274 | 3255 | ||
| 3275 | scatterlist = sglist->scatterlist; | ||
| 3276 | sg_init_table(scatterlist, num_elem); | ||
| 3277 | sglist->order = order; | 3256 | sglist->order = order; |
| 3278 | sglist->num_sg = num_elem; | 3257 | sgl_alloc_order(buflen, order, false, |
| 3279 | sg_size = buflen; | 3258 | GFP_KERNEL | GFP_DMA | __GFP_ZERO, &sglist->num_sg); |
| 3280 | |||
| 3281 | for (i = 0; i < num_elem; i++) { | ||
| 3282 | page = alloc_pages(GFP_KERNEL|GFP_DMA|__GFP_ZERO, order); | ||
| 3283 | if (!page) { | ||
| 3284 | for (j = i - 1; j >= 0; j--) | ||
| 3285 | __free_pages(sg_page(&scatterlist[j]), order); | ||
| 3286 | kfree(sglist); | ||
| 3287 | return NULL; | ||
| 3288 | } | ||
| 3289 | |||
| 3290 | sg_set_page(&scatterlist[i], page, | ||
| 3291 | sg_size < bsize_elem ? sg_size : bsize_elem, 0); | ||
| 3292 | sg_size -= bsize_elem; | ||
| 3293 | } | ||
| 3294 | 3259 | ||
| 3295 | return sglist; | 3260 | return sglist; |
| 3296 | } | 3261 | } |
| @@ -5492,7 +5457,7 @@ static void pmcraid_set_timestamp(struct pmcraid_cmd *cmd) | |||
| 5492 | struct pmcraid_instance *pinstance = cmd->drv_inst; | 5457 | struct pmcraid_instance *pinstance = cmd->drv_inst; |
| 5493 | struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb; | 5458 | struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb; |
| 5494 | __be32 time_stamp_len = cpu_to_be32(PMCRAID_TIMESTAMP_LEN); | 5459 | __be32 time_stamp_len = cpu_to_be32(PMCRAID_TIMESTAMP_LEN); |
| 5495 | struct pmcraid_ioadl_desc *ioadl = ioarcb->add_data.u.ioadl; | 5460 | struct pmcraid_ioadl_desc *ioadl; |
| 5496 | u64 timestamp; | 5461 | u64 timestamp; |
| 5497 | 5462 | ||
| 5498 | timestamp = ktime_get_real_seconds() * 1000; | 5463 | timestamp = ktime_get_real_seconds() * 1000; |
| @@ -5665,7 +5630,7 @@ static void pmcraid_init_res_table(struct pmcraid_cmd *cmd) | |||
| 5665 | static void pmcraid_querycfg(struct pmcraid_cmd *cmd) | 5630 | static void pmcraid_querycfg(struct pmcraid_cmd *cmd) |
| 5666 | { | 5631 | { |
| 5667 | struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb; | 5632 | struct pmcraid_ioarcb *ioarcb = &cmd->ioa_cb->ioarcb; |
| 5668 | struct pmcraid_ioadl_desc *ioadl = ioarcb->add_data.u.ioadl; | 5633 | struct pmcraid_ioadl_desc *ioadl; |
| 5669 | struct pmcraid_instance *pinstance = cmd->drv_inst; | 5634 | struct pmcraid_instance *pinstance = cmd->drv_inst; |
| 5670 | __be32 cfg_table_size = cpu_to_be32(sizeof(struct pmcraid_config_table)); | 5635 | __be32 cfg_table_size = cpu_to_be32(sizeof(struct pmcraid_config_table)); |
| 5671 | 5636 | ||
diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h index 8bfac72a242b..754ef30927e2 100644 --- a/drivers/scsi/pmcraid.h +++ b/drivers/scsi/pmcraid.h | |||
| @@ -542,8 +542,7 @@ struct pmcraid_sglist { | |||
| 542 | u32 order; | 542 | u32 order; |
| 543 | u32 num_sg; | 543 | u32 num_sg; |
| 544 | u32 num_dma_sg; | 544 | u32 num_dma_sg; |
| 545 | u32 buffer_len; | 545 | struct scatterlist *scatterlist; |
| 546 | struct scatterlist scatterlist[1]; | ||
| 547 | }; | 546 | }; |
| 548 | 547 | ||
| 549 | /* page D0 inquiry data of focal point resource */ | 548 | /* page D0 inquiry data of focal point resource */ |
diff --git a/drivers/scsi/qedf/qedf_dbg.c b/drivers/scsi/qedf/qedf_dbg.c index e023f5d0dc12..bd1cef25a900 100644 --- a/drivers/scsi/qedf/qedf_dbg.c +++ b/drivers/scsi/qedf/qedf_dbg.c | |||
| @@ -160,7 +160,7 @@ qedf_uevent_emit(struct Scsi_Host *shost, u32 code, char *msg) | |||
| 160 | switch (code) { | 160 | switch (code) { |
| 161 | case QEDF_UEVENT_CODE_GRCDUMP: | 161 | case QEDF_UEVENT_CODE_GRCDUMP: |
| 162 | if (msg) | 162 | if (msg) |
| 163 | strncpy(event_string, msg, strlen(msg)); | 163 | strscpy(event_string, msg, sizeof(event_string)); |
| 164 | else | 164 | else |
| 165 | sprintf(event_string, "GRCDUMP=%u", shost->host_no); | 165 | sprintf(event_string, "GRCDUMP=%u", shost->host_no); |
| 166 | break; | 166 | break; |
diff --git a/drivers/scsi/qedf/qedf_dbg.h b/drivers/scsi/qedf/qedf_dbg.h index 50083cae84c3..77c27e888969 100644 --- a/drivers/scsi/qedf/qedf_dbg.h +++ b/drivers/scsi/qedf/qedf_dbg.h | |||
| @@ -116,6 +116,14 @@ extern int qedf_create_sysfs_attr(struct Scsi_Host *shost, | |||
| 116 | extern void qedf_remove_sysfs_attr(struct Scsi_Host *shost, | 116 | extern void qedf_remove_sysfs_attr(struct Scsi_Host *shost, |
| 117 | struct sysfs_bin_attrs *iter); | 117 | struct sysfs_bin_attrs *iter); |
| 118 | 118 | ||
| 119 | struct qedf_debugfs_ops { | ||
| 120 | char *name; | ||
| 121 | struct qedf_list_of_funcs *qedf_funcs; | ||
| 122 | }; | ||
| 123 | |||
| 124 | extern const struct qedf_debugfs_ops qedf_debugfs_ops[]; | ||
| 125 | extern const struct file_operations qedf_dbg_fops[]; | ||
| 126 | |||
| 119 | #ifdef CONFIG_DEBUG_FS | 127 | #ifdef CONFIG_DEBUG_FS |
| 120 | /* DebugFS related code */ | 128 | /* DebugFS related code */ |
| 121 | struct qedf_list_of_funcs { | 129 | struct qedf_list_of_funcs { |
| @@ -123,11 +131,6 @@ struct qedf_list_of_funcs { | |||
| 123 | ssize_t (*oper_func)(struct qedf_dbg_ctx *qedf); | 131 | ssize_t (*oper_func)(struct qedf_dbg_ctx *qedf); |
| 124 | }; | 132 | }; |
| 125 | 133 | ||
| 126 | struct qedf_debugfs_ops { | ||
| 127 | char *name; | ||
| 128 | struct qedf_list_of_funcs *qedf_funcs; | ||
| 129 | }; | ||
| 130 | |||
| 131 | #define qedf_dbg_fileops(drv, ops) \ | 134 | #define qedf_dbg_fileops(drv, ops) \ |
| 132 | { \ | 135 | { \ |
| 133 | .owner = THIS_MODULE, \ | 136 | .owner = THIS_MODULE, \ |
| @@ -147,8 +150,8 @@ struct qedf_debugfs_ops { | |||
| 147 | } | 150 | } |
| 148 | 151 | ||
| 149 | extern void qedf_dbg_host_init(struct qedf_dbg_ctx *qedf, | 152 | extern void qedf_dbg_host_init(struct qedf_dbg_ctx *qedf, |
| 150 | struct qedf_debugfs_ops *dops, | 153 | const struct qedf_debugfs_ops *dops, |
| 151 | struct file_operations *fops); | 154 | const struct file_operations *fops); |
| 152 | extern void qedf_dbg_host_exit(struct qedf_dbg_ctx *qedf); | 155 | extern void qedf_dbg_host_exit(struct qedf_dbg_ctx *qedf); |
| 153 | extern void qedf_dbg_init(char *drv_name); | 156 | extern void qedf_dbg_init(char *drv_name); |
| 154 | extern void qedf_dbg_exit(void); | 157 | extern void qedf_dbg_exit(void); |
diff --git a/drivers/scsi/qedf/qedf_debugfs.c b/drivers/scsi/qedf/qedf_debugfs.c index 2b1ef3075e93..c539a7ae3a7e 100644 --- a/drivers/scsi/qedf/qedf_debugfs.c +++ b/drivers/scsi/qedf/qedf_debugfs.c | |||
| @@ -23,8 +23,8 @@ static struct dentry *qedf_dbg_root; | |||
| 23 | **/ | 23 | **/ |
| 24 | void | 24 | void |
| 25 | qedf_dbg_host_init(struct qedf_dbg_ctx *qedf, | 25 | qedf_dbg_host_init(struct qedf_dbg_ctx *qedf, |
| 26 | struct qedf_debugfs_ops *dops, | 26 | const struct qedf_debugfs_ops *dops, |
| 27 | struct file_operations *fops) | 27 | const struct file_operations *fops) |
| 28 | { | 28 | { |
| 29 | char host_dirname[32]; | 29 | char host_dirname[32]; |
| 30 | struct dentry *file_dentry = NULL; | 30 | struct dentry *file_dentry = NULL; |
| @@ -99,7 +99,7 @@ qedf_dbg_exit(void) | |||
| 99 | qedf_dbg_root = NULL; | 99 | qedf_dbg_root = NULL; |
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | struct qedf_debugfs_ops qedf_debugfs_ops[] = { | 102 | const struct qedf_debugfs_ops qedf_debugfs_ops[] = { |
| 103 | { "fp_int", NULL }, | 103 | { "fp_int", NULL }, |
| 104 | { "io_trace", NULL }, | 104 | { "io_trace", NULL }, |
| 105 | { "debug", NULL }, | 105 | { "debug", NULL }, |
diff --git a/drivers/scsi/qedf/qedf_io.c b/drivers/scsi/qedf/qedf_io.c index b15e69586a36..50a50c4249d0 100644 --- a/drivers/scsi/qedf/qedf_io.c +++ b/drivers/scsi/qedf/qedf_io.c | |||
| @@ -917,7 +917,7 @@ qedf_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc_cmd) | |||
| 917 | struct qedf_ctx *qedf = lport_priv(lport); | 917 | struct qedf_ctx *qedf = lport_priv(lport); |
| 918 | struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device)); | 918 | struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device)); |
| 919 | struct fc_rport_libfc_priv *rp = rport->dd_data; | 919 | struct fc_rport_libfc_priv *rp = rport->dd_data; |
| 920 | struct qedf_rport *fcport = rport->dd_data; | 920 | struct qedf_rport *fcport; |
| 921 | struct qedf_ioreq *io_req; | 921 | struct qedf_ioreq *io_req; |
| 922 | int rc = 0; | 922 | int rc = 0; |
| 923 | int rval; | 923 | int rval; |
diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c index ccd9a08ea030..284ccb566b19 100644 --- a/drivers/scsi/qedf/qedf_main.c +++ b/drivers/scsi/qedf/qedf_main.c | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/if_vlan.h> | 23 | #include <linux/if_vlan.h> |
| 24 | #include <linux/cpu.h> | 24 | #include <linux/cpu.h> |
| 25 | #include "qedf.h" | 25 | #include "qedf.h" |
| 26 | #include "qedf_dbg.h" | ||
| 26 | #include <uapi/linux/pci_regs.h> | 27 | #include <uapi/linux/pci_regs.h> |
| 27 | 28 | ||
| 28 | const struct qed_fcoe_ops *qed_ops; | 29 | const struct qed_fcoe_ops *qed_ops; |
| @@ -30,9 +31,6 @@ const struct qed_fcoe_ops *qed_ops; | |||
| 30 | static int qedf_probe(struct pci_dev *pdev, const struct pci_device_id *id); | 31 | static int qedf_probe(struct pci_dev *pdev, const struct pci_device_id *id); |
| 31 | static void qedf_remove(struct pci_dev *pdev); | 32 | static void qedf_remove(struct pci_dev *pdev); |
| 32 | 33 | ||
| 33 | extern struct qedf_debugfs_ops qedf_debugfs_ops; | ||
| 34 | extern struct file_operations qedf_dbg_fops; | ||
| 35 | |||
| 36 | /* | 34 | /* |
| 37 | * Driver module parameters. | 35 | * Driver module parameters. |
| 38 | */ | 36 | */ |
| @@ -3155,8 +3153,8 @@ static int __qedf_probe(struct pci_dev *pdev, int mode) | |||
| 3155 | } | 3153 | } |
| 3156 | 3154 | ||
| 3157 | #ifdef CONFIG_DEBUG_FS | 3155 | #ifdef CONFIG_DEBUG_FS |
| 3158 | qedf_dbg_host_init(&(qedf->dbg_ctx), &qedf_debugfs_ops, | 3156 | qedf_dbg_host_init(&(qedf->dbg_ctx), qedf_debugfs_ops, |
| 3159 | &qedf_dbg_fops); | 3157 | qedf_dbg_fops); |
| 3160 | #endif | 3158 | #endif |
| 3161 | 3159 | ||
| 3162 | /* Start LL2 */ | 3160 | /* Start LL2 */ |
diff --git a/drivers/scsi/qedi/qedi_dbg.h b/drivers/scsi/qedi/qedi_dbg.h index c55572badfb0..0bc9c31d5a4f 100644 --- a/drivers/scsi/qedi/qedi_dbg.h +++ b/drivers/scsi/qedi/qedi_dbg.h | |||
| @@ -103,7 +103,6 @@ int qedi_create_sysfs_attr(struct Scsi_Host *shost, | |||
| 103 | void qedi_remove_sysfs_attr(struct Scsi_Host *shost, | 103 | void qedi_remove_sysfs_attr(struct Scsi_Host *shost, |
| 104 | struct sysfs_bin_attrs *iter); | 104 | struct sysfs_bin_attrs *iter); |
| 105 | 105 | ||
| 106 | #ifdef CONFIG_DEBUG_FS | ||
| 107 | /* DebugFS related code */ | 106 | /* DebugFS related code */ |
| 108 | struct qedi_list_of_funcs { | 107 | struct qedi_list_of_funcs { |
| 109 | char *oper_str; | 108 | char *oper_str; |
| @@ -134,11 +133,10 @@ struct qedi_debugfs_ops { | |||
| 134 | } | 133 | } |
| 135 | 134 | ||
| 136 | void qedi_dbg_host_init(struct qedi_dbg_ctx *qedi, | 135 | void qedi_dbg_host_init(struct qedi_dbg_ctx *qedi, |
| 137 | struct qedi_debugfs_ops *dops, | 136 | const struct qedi_debugfs_ops *dops, |
| 138 | const struct file_operations *fops); | 137 | const struct file_operations *fops); |
| 139 | void qedi_dbg_host_exit(struct qedi_dbg_ctx *qedi); | 138 | void qedi_dbg_host_exit(struct qedi_dbg_ctx *qedi); |
| 140 | void qedi_dbg_init(char *drv_name); | 139 | void qedi_dbg_init(char *drv_name); |
| 141 | void qedi_dbg_exit(void); | 140 | void qedi_dbg_exit(void); |
| 142 | #endif /* CONFIG_DEBUG_FS */ | ||
| 143 | 141 | ||
| 144 | #endif /* _QEDI_DBG_H_ */ | 142 | #endif /* _QEDI_DBG_H_ */ |
diff --git a/drivers/scsi/qedi/qedi_debugfs.c b/drivers/scsi/qedi/qedi_debugfs.c index fd8a1eea3163..fd914ca4149a 100644 --- a/drivers/scsi/qedi/qedi_debugfs.c +++ b/drivers/scsi/qedi/qedi_debugfs.c | |||
| @@ -19,7 +19,7 @@ static struct dentry *qedi_dbg_root; | |||
| 19 | 19 | ||
| 20 | void | 20 | void |
| 21 | qedi_dbg_host_init(struct qedi_dbg_ctx *qedi, | 21 | qedi_dbg_host_init(struct qedi_dbg_ctx *qedi, |
| 22 | struct qedi_debugfs_ops *dops, | 22 | const struct qedi_debugfs_ops *dops, |
| 23 | const struct file_operations *fops) | 23 | const struct file_operations *fops) |
| 24 | { | 24 | { |
| 25 | char host_dirname[32]; | 25 | char host_dirname[32]; |
| @@ -99,7 +99,7 @@ static struct qedi_list_of_funcs qedi_dbg_do_not_recover_ops[] = { | |||
| 99 | { NULL, NULL } | 99 | { NULL, NULL } |
| 100 | }; | 100 | }; |
| 101 | 101 | ||
| 102 | struct qedi_debugfs_ops qedi_debugfs_ops[] = { | 102 | const struct qedi_debugfs_ops qedi_debugfs_ops[] = { |
| 103 | { "gbl_ctx", NULL }, | 103 | { "gbl_ctx", NULL }, |
| 104 | { "do_not_recover", qedi_dbg_do_not_recover_ops}, | 104 | { "do_not_recover", qedi_dbg_do_not_recover_ops}, |
| 105 | { "io_trace", NULL }, | 105 | { "io_trace", NULL }, |
diff --git a/drivers/scsi/qedi/qedi_gbl.h b/drivers/scsi/qedi/qedi_gbl.h index f5b5a31999aa..a2aa06ed1620 100644 --- a/drivers/scsi/qedi/qedi_gbl.h +++ b/drivers/scsi/qedi/qedi_gbl.h | |||
| @@ -23,8 +23,8 @@ extern uint qedi_io_tracing; | |||
| 23 | extern struct scsi_host_template qedi_host_template; | 23 | extern struct scsi_host_template qedi_host_template; |
| 24 | extern struct iscsi_transport qedi_iscsi_transport; | 24 | extern struct iscsi_transport qedi_iscsi_transport; |
| 25 | extern const struct qed_iscsi_ops *qedi_ops; | 25 | extern const struct qed_iscsi_ops *qedi_ops; |
| 26 | extern struct qedi_debugfs_ops qedi_debugfs_ops; | 26 | extern const struct qedi_debugfs_ops qedi_debugfs_ops[]; |
| 27 | extern const struct file_operations qedi_dbg_fops; | 27 | extern const struct file_operations qedi_dbg_fops[]; |
| 28 | extern struct device_attribute *qedi_shost_attrs[]; | 28 | extern struct device_attribute *qedi_shost_attrs[]; |
| 29 | 29 | ||
| 30 | int qedi_alloc_sq(struct qedi_ctx *qedi, struct qedi_endpoint *ep); | 30 | int qedi_alloc_sq(struct qedi_ctx *qedi, struct qedi_endpoint *ep); |
diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c index f57a94b4f0d9..4da3592aec0f 100644 --- a/drivers/scsi/qedi/qedi_main.c +++ b/drivers/scsi/qedi/qedi_main.c | |||
| @@ -2300,8 +2300,8 @@ static int __qedi_probe(struct pci_dev *pdev, int mode) | |||
| 2300 | } | 2300 | } |
| 2301 | 2301 | ||
| 2302 | #ifdef CONFIG_DEBUG_FS | 2302 | #ifdef CONFIG_DEBUG_FS |
| 2303 | qedi_dbg_host_init(&qedi->dbg_ctx, &qedi_debugfs_ops, | 2303 | qedi_dbg_host_init(&qedi->dbg_ctx, qedi_debugfs_ops, |
| 2304 | &qedi_dbg_fops); | 2304 | qedi_dbg_fops); |
| 2305 | #endif | 2305 | #endif |
| 2306 | QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO, | 2306 | QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO, |
| 2307 | "QLogic FastLinQ iSCSI Module qedi %s, FW %d.%d.%d.%d\n", | 2307 | "QLogic FastLinQ iSCSI Module qedi %s, FW %d.%d.%d.%d\n", |
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index e2d5d3ca0f57..c11a89be292c 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c | |||
| @@ -1035,7 +1035,7 @@ qla84xx_updatefw(struct bsg_job *bsg_job) | |||
| 1035 | sg_copy_to_buffer(bsg_job->request_payload.sg_list, | 1035 | sg_copy_to_buffer(bsg_job->request_payload.sg_list, |
| 1036 | bsg_job->request_payload.sg_cnt, fw_buf, data_len); | 1036 | bsg_job->request_payload.sg_cnt, fw_buf, data_len); |
| 1037 | 1037 | ||
| 1038 | mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma); | 1038 | mn = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma); |
| 1039 | if (!mn) { | 1039 | if (!mn) { |
| 1040 | ql_log(ql_log_warn, vha, 0x7036, | 1040 | ql_log(ql_log_warn, vha, 0x7036, |
| 1041 | "DMA alloc failed for fw buffer.\n"); | 1041 | "DMA alloc failed for fw buffer.\n"); |
| @@ -1046,7 +1046,6 @@ qla84xx_updatefw(struct bsg_job *bsg_job) | |||
| 1046 | flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1]; | 1046 | flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1]; |
| 1047 | fw_ver = le32_to_cpu(*((uint32_t *)((uint32_t *)fw_buf + 2))); | 1047 | fw_ver = le32_to_cpu(*((uint32_t *)((uint32_t *)fw_buf + 2))); |
| 1048 | 1048 | ||
| 1049 | memset(mn, 0, sizeof(struct access_chip_84xx)); | ||
| 1050 | mn->entry_type = VERIFY_CHIP_IOCB_TYPE; | 1049 | mn->entry_type = VERIFY_CHIP_IOCB_TYPE; |
| 1051 | mn->entry_count = 1; | 1050 | mn->entry_count = 1; |
| 1052 | 1051 | ||
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 3e9dc54b89a3..5fd44c50bbac 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | * | Module Init and Probe | 0x0193 | 0x0146 | | 14 | * | Module Init and Probe | 0x0193 | 0x0146 | |
| 15 | * | | | 0x015b-0x0160 | | 15 | * | | | 0x015b-0x0160 | |
| 16 | * | | | 0x016e | | 16 | * | | | 0x016e | |
| 17 | * | Mailbox commands | 0x1205 | 0x11a2-0x11ff | | 17 | * | Mailbox commands | 0x1206 | 0x11a2-0x11ff | |
| 18 | * | Device Discovery | 0x2134 | 0x210e-0x2116 | | 18 | * | Device Discovery | 0x2134 | 0x210e-0x2116 | |
| 19 | * | | | 0x211a | | 19 | * | | | 0x211a | |
| 20 | * | | | 0x211c-0x2128 | | 20 | * | | | 0x211c-0x2128 | |
| @@ -60,7 +60,7 @@ | |||
| 60 | * | | | 0xb13c-0xb140 | | 60 | * | | | 0xb13c-0xb140 | |
| 61 | * | | | 0xb149 | | 61 | * | | | 0xb149 | |
| 62 | * | MultiQ | 0xc010 | | | 62 | * | MultiQ | 0xc010 | | |
| 63 | * | Misc | 0xd302 | 0xd031-0xd0ff | | 63 | * | Misc | 0xd303 | 0xd031-0xd0ff | |
| 64 | * | | | 0xd101-0xd1fe | | 64 | * | | | 0xd101-0xd1fe | |
| 65 | * | | | 0xd214-0xd2fe | | 65 | * | | | 0xd214-0xd2fe | |
| 66 | * | Target Mode | 0xe081 | | | 66 | * | Target Mode | 0xe081 | | |
| @@ -717,7 +717,7 @@ qla2xxx_dump_post_process(scsi_qla_host_t *vha, int rval) | |||
| 717 | 717 | ||
| 718 | /** | 718 | /** |
| 719 | * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. | 719 | * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. |
| 720 | * @ha: HA context | 720 | * @vha: HA context |
| 721 | * @hardware_locked: Called with the hardware_lock | 721 | * @hardware_locked: Called with the hardware_lock |
| 722 | */ | 722 | */ |
| 723 | void | 723 | void |
| @@ -887,7 +887,7 @@ qla2300_fw_dump_failed: | |||
| 887 | 887 | ||
| 888 | /** | 888 | /** |
| 889 | * qla2100_fw_dump() - Dumps binary data from the 2100/2200 firmware. | 889 | * qla2100_fw_dump() - Dumps binary data from the 2100/2200 firmware. |
| 890 | * @ha: HA context | 890 | * @vha: HA context |
| 891 | * @hardware_locked: Called with the hardware_lock | 891 | * @hardware_locked: Called with the hardware_lock |
| 892 | */ | 892 | */ |
| 893 | void | 893 | void |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index c9689f97c307..eb2ec1fb07cb 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
| @@ -2356,6 +2356,8 @@ typedef struct fc_port { | |||
| 2356 | #define NVME_PRLI_SP_DISCOVERY BIT_3 | 2356 | #define NVME_PRLI_SP_DISCOVERY BIT_3 |
| 2357 | uint8_t nvme_flag; | 2357 | uint8_t nvme_flag; |
| 2358 | #define NVME_FLAG_REGISTERED 4 | 2358 | #define NVME_FLAG_REGISTERED 4 |
| 2359 | #define NVME_FLAG_DELETING 2 | ||
| 2360 | #define NVME_FLAG_RESETTING 1 | ||
| 2359 | 2361 | ||
| 2360 | struct fc_port *conflict; | 2362 | struct fc_port *conflict; |
| 2361 | unsigned char logout_completed; | 2363 | unsigned char logout_completed; |
| @@ -2981,8 +2983,14 @@ enum scan_flags_t { | |||
| 2981 | SF_QUEUED = BIT_1, | 2983 | SF_QUEUED = BIT_1, |
| 2982 | }; | 2984 | }; |
| 2983 | 2985 | ||
| 2986 | enum fc4type_t { | ||
| 2987 | FS_FC4TYPE_FCP = BIT_0, | ||
| 2988 | FS_FC4TYPE_NVME = BIT_1, | ||
| 2989 | }; | ||
| 2990 | |||
| 2984 | struct fab_scan_rp { | 2991 | struct fab_scan_rp { |
| 2985 | port_id_t id; | 2992 | port_id_t id; |
| 2993 | enum fc4type_t fc4type; | ||
| 2986 | u8 port_name[8]; | 2994 | u8 port_name[8]; |
| 2987 | u8 node_name[8]; | 2995 | u8 node_name[8]; |
| 2988 | }; | 2996 | }; |
| @@ -3274,6 +3282,7 @@ struct qla_work_evt { | |||
| 3274 | } nack; | 3282 | } nack; |
| 3275 | struct { | 3283 | struct { |
| 3276 | u8 fc4_type; | 3284 | u8 fc4_type; |
| 3285 | srb_t *sp; | ||
| 3277 | } gpnft; | 3286 | } gpnft; |
| 3278 | } u; | 3287 | } u; |
| 3279 | }; | 3288 | }; |
| @@ -3463,7 +3472,6 @@ struct qla_qpair { | |||
| 3463 | struct work_struct q_work; | 3472 | struct work_struct q_work; |
| 3464 | struct list_head qp_list_elem; /* vha->qp_list */ | 3473 | struct list_head qp_list_elem; /* vha->qp_list */ |
| 3465 | struct list_head hints_list; | 3474 | struct list_head hints_list; |
| 3466 | struct list_head nvme_done_list; | ||
| 3467 | uint16_t cpuid; | 3475 | uint16_t cpuid; |
| 3468 | struct qla_tgt_counters tgt_counters; | 3476 | struct qla_tgt_counters tgt_counters; |
| 3469 | }; | 3477 | }; |
| @@ -4281,8 +4289,6 @@ typedef struct scsi_qla_host { | |||
| 4281 | struct nvme_fc_local_port *nvme_local_port; | 4289 | struct nvme_fc_local_port *nvme_local_port; |
| 4282 | struct completion nvme_del_done; | 4290 | struct completion nvme_del_done; |
| 4283 | struct list_head nvme_rport_list; | 4291 | struct list_head nvme_rport_list; |
| 4284 | atomic_t nvme_active_aen_cnt; | ||
| 4285 | uint16_t nvme_last_rptd_aen; | ||
| 4286 | 4292 | ||
| 4287 | uint16_t fcoe_vlan_id; | 4293 | uint16_t fcoe_vlan_id; |
| 4288 | uint16_t fcoe_fcf_idx; | 4294 | uint16_t fcoe_fcf_idx; |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index e9295398050c..3c4c84ed0f0f 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
| @@ -658,7 +658,7 @@ void qla24xx_handle_gpsc_event(scsi_qla_host_t *, struct event_arg *); | |||
| 658 | int qla2x00_mgmt_svr_login(scsi_qla_host_t *); | 658 | int qla2x00_mgmt_svr_login(scsi_qla_host_t *); |
| 659 | void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea); | 659 | void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea); |
| 660 | int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport); | 660 | int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport); |
| 661 | int qla24xx_async_gpnft(scsi_qla_host_t *, u8); | 661 | int qla24xx_async_gpnft(scsi_qla_host_t *, u8, srb_t *); |
| 662 | void qla24xx_async_gpnft_done(scsi_qla_host_t *, srb_t *); | 662 | void qla24xx_async_gpnft_done(scsi_qla_host_t *, srb_t *); |
| 663 | void qla24xx_async_gnnft_done(scsi_qla_host_t *, srb_t *); | 663 | void qla24xx_async_gnnft_done(scsi_qla_host_t *, srb_t *); |
| 664 | int qla24xx_async_gnnid(scsi_qla_host_t *, fc_port_t *); | 664 | int qla24xx_async_gnnid(scsi_qla_host_t *, fc_port_t *); |
| @@ -896,6 +896,4 @@ void qlt_update_host_map(struct scsi_qla_host *, port_id_t); | |||
| 896 | void qlt_remove_target_resources(struct qla_hw_data *); | 896 | void qlt_remove_target_resources(struct qla_hw_data *); |
| 897 | void qlt_clr_qp_table(struct scsi_qla_host *vha); | 897 | void qlt_clr_qp_table(struct scsi_qla_host *vha); |
| 898 | 898 | ||
| 899 | void qla_nvme_cmpl_io(struct srb_iocb *); | ||
| 900 | |||
| 901 | #endif /* _QLA_GBL_H */ | 899 | #endif /* _QLA_GBL_H */ |
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 403fa096f8c8..2288757b5c9e 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c | |||
| @@ -21,11 +21,10 @@ static int qla_async_rsnn_nn(scsi_qla_host_t *); | |||
| 21 | 21 | ||
| 22 | /** | 22 | /** |
| 23 | * qla2x00_prep_ms_iocb() - Prepare common MS/CT IOCB fields for SNS CT query. | 23 | * qla2x00_prep_ms_iocb() - Prepare common MS/CT IOCB fields for SNS CT query. |
| 24 | * @ha: HA context | 24 | * @vha: HA context |
| 25 | * @req_size: request size in bytes | 25 | * @arg: CT arguments |
| 26 | * @rsp_size: response size in bytes | ||
| 27 | * | 26 | * |
| 28 | * Returns a pointer to the @ha's ms_iocb. | 27 | * Returns a pointer to the @vha's ms_iocb. |
| 29 | */ | 28 | */ |
| 30 | void * | 29 | void * |
| 31 | qla2x00_prep_ms_iocb(scsi_qla_host_t *vha, struct ct_arg *arg) | 30 | qla2x00_prep_ms_iocb(scsi_qla_host_t *vha, struct ct_arg *arg) |
| @@ -61,9 +60,8 @@ qla2x00_prep_ms_iocb(scsi_qla_host_t *vha, struct ct_arg *arg) | |||
| 61 | 60 | ||
| 62 | /** | 61 | /** |
| 63 | * qla24xx_prep_ms_iocb() - Prepare common CT IOCB fields for SNS CT query. | 62 | * qla24xx_prep_ms_iocb() - Prepare common CT IOCB fields for SNS CT query. |
| 64 | * @ha: HA context | 63 | * @vha: HA context |
| 65 | * @req_size: request size in bytes | 64 | * @arg: CT arguments |
| 66 | * @rsp_size: response size in bytes | ||
| 67 | * | 65 | * |
| 68 | * Returns a pointer to the @ha's ms_iocb. | 66 | * Returns a pointer to the @ha's ms_iocb. |
| 69 | */ | 67 | */ |
| @@ -101,7 +99,7 @@ qla24xx_prep_ms_iocb(scsi_qla_host_t *vha, struct ct_arg *arg) | |||
| 101 | 99 | ||
| 102 | /** | 100 | /** |
| 103 | * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query. | 101 | * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query. |
| 104 | * @ct_req: CT request buffer | 102 | * @p: CT request buffer |
| 105 | * @cmd: GS command | 103 | * @cmd: GS command |
| 106 | * @rsp_size: response size in bytes | 104 | * @rsp_size: response size in bytes |
| 107 | * | 105 | * |
| @@ -196,7 +194,7 @@ qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t *ms_pkt, | |||
| 196 | 194 | ||
| 197 | /** | 195 | /** |
| 198 | * qla2x00_ga_nxt() - SNS scan for fabric devices via GA_NXT command. | 196 | * qla2x00_ga_nxt() - SNS scan for fabric devices via GA_NXT command. |
| 199 | * @ha: HA context | 197 | * @vha: HA context |
| 200 | * @fcport: fcport entry to updated | 198 | * @fcport: fcport entry to updated |
| 201 | * | 199 | * |
| 202 | * Returns 0 on success. | 200 | * Returns 0 on success. |
| @@ -283,7 +281,7 @@ qla2x00_gid_pt_rsp_size(scsi_qla_host_t *vha) | |||
| 283 | 281 | ||
| 284 | /** | 282 | /** |
| 285 | * qla2x00_gid_pt() - SNS scan for fabric devices via GID_PT command. | 283 | * qla2x00_gid_pt() - SNS scan for fabric devices via GID_PT command. |
| 286 | * @ha: HA context | 284 | * @vha: HA context |
| 287 | * @list: switch info entries to populate | 285 | * @list: switch info entries to populate |
| 288 | * | 286 | * |
| 289 | * NOTE: Non-Nx_Ports are not requested. | 287 | * NOTE: Non-Nx_Ports are not requested. |
| @@ -371,7 +369,7 @@ qla2x00_gid_pt(scsi_qla_host_t *vha, sw_info_t *list) | |||
| 371 | 369 | ||
| 372 | /** | 370 | /** |
| 373 | * qla2x00_gpn_id() - SNS Get Port Name (GPN_ID) query. | 371 | * qla2x00_gpn_id() - SNS Get Port Name (GPN_ID) query. |
| 374 | * @ha: HA context | 372 | * @vha: HA context |
| 375 | * @list: switch info entries to populate | 373 | * @list: switch info entries to populate |
| 376 | * | 374 | * |
| 377 | * Returns 0 on success. | 375 | * Returns 0 on success. |
| @@ -441,7 +439,7 @@ qla2x00_gpn_id(scsi_qla_host_t *vha, sw_info_t *list) | |||
| 441 | 439 | ||
| 442 | /** | 440 | /** |
| 443 | * qla2x00_gnn_id() - SNS Get Node Name (GNN_ID) query. | 441 | * qla2x00_gnn_id() - SNS Get Node Name (GNN_ID) query. |
| 444 | * @ha: HA context | 442 | * @vha: HA context |
| 445 | * @list: switch info entries to populate | 443 | * @list: switch info entries to populate |
| 446 | * | 444 | * |
| 447 | * Returns 0 on success. | 445 | * Returns 0 on success. |
| @@ -583,7 +581,7 @@ err2: | |||
| 583 | 581 | ||
| 584 | /** | 582 | /** |
| 585 | * qla2x00_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA. | 583 | * qla2x00_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA. |
| 586 | * @ha: HA context | 584 | * @vha: HA context |
| 587 | * | 585 | * |
| 588 | * Returns 0 on success. | 586 | * Returns 0 on success. |
| 589 | */ | 587 | */ |
| @@ -675,7 +673,8 @@ done: | |||
| 675 | 673 | ||
| 676 | /** | 674 | /** |
| 677 | * qla2x00_rff_id() - SNS Register FC-4 Features (RFF_ID) supported by the HBA. | 675 | * qla2x00_rff_id() - SNS Register FC-4 Features (RFF_ID) supported by the HBA. |
| 678 | * @ha: HA context | 676 | * @vha: HA context |
| 677 | * @type: not used | ||
| 679 | * | 678 | * |
| 680 | * Returns 0 on success. | 679 | * Returns 0 on success. |
| 681 | */ | 680 | */ |
| @@ -769,7 +768,7 @@ done: | |||
| 769 | 768 | ||
| 770 | /** | 769 | /** |
| 771 | * qla2x00_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA. | 770 | * qla2x00_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA. |
| 772 | * @ha: HA context | 771 | * @vha: HA context |
| 773 | * | 772 | * |
| 774 | * Returns 0 on success. | 773 | * Returns 0 on success. |
| 775 | */ | 774 | */ |
| @@ -874,7 +873,7 @@ qla2x00_get_sym_node_name(scsi_qla_host_t *vha, uint8_t *snn, size_t size) | |||
| 874 | 873 | ||
| 875 | /** | 874 | /** |
| 876 | * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA. | 875 | * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA. |
| 877 | * @ha: HA context | 876 | * @vha: HA context |
| 878 | * | 877 | * |
| 879 | * Returns 0 on success. | 878 | * Returns 0 on success. |
| 880 | */ | 879 | */ |
| @@ -970,7 +969,7 @@ done: | |||
| 970 | 969 | ||
| 971 | /** | 970 | /** |
| 972 | * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query. | 971 | * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query. |
| 973 | * @ha: HA context | 972 | * @vha: HA context |
| 974 | * @cmd: GS command | 973 | * @cmd: GS command |
| 975 | * @scmd_len: Subcommand length | 974 | * @scmd_len: Subcommand length |
| 976 | * @data_size: response size in bytes | 975 | * @data_size: response size in bytes |
| @@ -1003,7 +1002,7 @@ qla2x00_prep_sns_cmd(scsi_qla_host_t *vha, uint16_t cmd, uint16_t scmd_len, | |||
| 1003 | 1002 | ||
| 1004 | /** | 1003 | /** |
| 1005 | * qla2x00_sns_ga_nxt() - SNS scan for fabric devices via GA_NXT command. | 1004 | * qla2x00_sns_ga_nxt() - SNS scan for fabric devices via GA_NXT command. |
| 1006 | * @ha: HA context | 1005 | * @vha: HA context |
| 1007 | * @fcport: fcport entry to updated | 1006 | * @fcport: fcport entry to updated |
| 1008 | * | 1007 | * |
| 1009 | * This command uses the old Exectute SNS Command mailbox routine. | 1008 | * This command uses the old Exectute SNS Command mailbox routine. |
| @@ -1067,7 +1066,7 @@ qla2x00_sns_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport) | |||
| 1067 | 1066 | ||
| 1068 | /** | 1067 | /** |
| 1069 | * qla2x00_sns_gid_pt() - SNS scan for fabric devices via GID_PT command. | 1068 | * qla2x00_sns_gid_pt() - SNS scan for fabric devices via GID_PT command. |
| 1070 | * @ha: HA context | 1069 | * @vha: HA context |
| 1071 | * @list: switch info entries to populate | 1070 | * @list: switch info entries to populate |
| 1072 | * | 1071 | * |
| 1073 | * This command uses the old Exectute SNS Command mailbox routine. | 1072 | * This command uses the old Exectute SNS Command mailbox routine. |
| @@ -1140,7 +1139,7 @@ qla2x00_sns_gid_pt(scsi_qla_host_t *vha, sw_info_t *list) | |||
| 1140 | 1139 | ||
| 1141 | /** | 1140 | /** |
| 1142 | * qla2x00_sns_gpn_id() - SNS Get Port Name (GPN_ID) query. | 1141 | * qla2x00_sns_gpn_id() - SNS Get Port Name (GPN_ID) query. |
| 1143 | * @ha: HA context | 1142 | * @vha: HA context |
| 1144 | * @list: switch info entries to populate | 1143 | * @list: switch info entries to populate |
| 1145 | * | 1144 | * |
| 1146 | * This command uses the old Exectute SNS Command mailbox routine. | 1145 | * This command uses the old Exectute SNS Command mailbox routine. |
| @@ -1196,7 +1195,7 @@ qla2x00_sns_gpn_id(scsi_qla_host_t *vha, sw_info_t *list) | |||
| 1196 | 1195 | ||
| 1197 | /** | 1196 | /** |
| 1198 | * qla2x00_sns_gnn_id() - SNS Get Node Name (GNN_ID) query. | 1197 | * qla2x00_sns_gnn_id() - SNS Get Node Name (GNN_ID) query. |
| 1199 | * @ha: HA context | 1198 | * @vha: HA context |
| 1200 | * @list: switch info entries to populate | 1199 | * @list: switch info entries to populate |
| 1201 | * | 1200 | * |
| 1202 | * This command uses the old Exectute SNS Command mailbox routine. | 1201 | * This command uses the old Exectute SNS Command mailbox routine. |
| @@ -1259,7 +1258,7 @@ qla2x00_sns_gnn_id(scsi_qla_host_t *vha, sw_info_t *list) | |||
| 1259 | 1258 | ||
| 1260 | /** | 1259 | /** |
| 1261 | * qla2x00_snd_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA. | 1260 | * qla2x00_snd_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA. |
| 1262 | * @ha: HA context | 1261 | * @vha: HA context |
| 1263 | * | 1262 | * |
| 1264 | * This command uses the old Exectute SNS Command mailbox routine. | 1263 | * This command uses the old Exectute SNS Command mailbox routine. |
| 1265 | * | 1264 | * |
| @@ -1308,8 +1307,7 @@ qla2x00_sns_rft_id(scsi_qla_host_t *vha) | |||
| 1308 | 1307 | ||
| 1309 | /** | 1308 | /** |
| 1310 | * qla2x00_sns_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA. | 1309 | * qla2x00_sns_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA. |
| 1311 | * HBA. | 1310 | * @vha: HA context |
| 1312 | * @ha: HA context | ||
| 1313 | * | 1311 | * |
| 1314 | * This command uses the old Exectute SNS Command mailbox routine. | 1312 | * This command uses the old Exectute SNS Command mailbox routine. |
| 1315 | * | 1313 | * |
| @@ -1365,7 +1363,7 @@ qla2x00_sns_rnn_id(scsi_qla_host_t *vha) | |||
| 1365 | 1363 | ||
| 1366 | /** | 1364 | /** |
| 1367 | * qla2x00_mgmt_svr_login() - Login to fabric Management Service. | 1365 | * qla2x00_mgmt_svr_login() - Login to fabric Management Service. |
| 1368 | * @ha: HA context | 1366 | * @vha: HA context |
| 1369 | * | 1367 | * |
| 1370 | * Returns 0 on success. | 1368 | * Returns 0 on success. |
| 1371 | */ | 1369 | */ |
| @@ -1401,7 +1399,7 @@ qla2x00_mgmt_svr_login(scsi_qla_host_t *vha) | |||
| 1401 | 1399 | ||
| 1402 | /** | 1400 | /** |
| 1403 | * qla2x00_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query. | 1401 | * qla2x00_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query. |
| 1404 | * @ha: HA context | 1402 | * @vha: HA context |
| 1405 | * @req_size: request size in bytes | 1403 | * @req_size: request size in bytes |
| 1406 | * @rsp_size: response size in bytes | 1404 | * @rsp_size: response size in bytes |
| 1407 | * | 1405 | * |
| @@ -1439,7 +1437,7 @@ qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size, | |||
| 1439 | 1437 | ||
| 1440 | /** | 1438 | /** |
| 1441 | * qla24xx_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query. | 1439 | * qla24xx_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query. |
| 1442 | * @ha: HA context | 1440 | * @vha: HA context |
| 1443 | * @req_size: request size in bytes | 1441 | * @req_size: request size in bytes |
| 1444 | * @rsp_size: response size in bytes | 1442 | * @rsp_size: response size in bytes |
| 1445 | * | 1443 | * |
| @@ -1496,7 +1494,7 @@ qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size) | |||
| 1496 | 1494 | ||
| 1497 | /** | 1495 | /** |
| 1498 | * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query. | 1496 | * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query. |
| 1499 | * @ct_req: CT request buffer | 1497 | * @p: CT request buffer |
| 1500 | * @cmd: GS command | 1498 | * @cmd: GS command |
| 1501 | * @rsp_size: response size in bytes | 1499 | * @rsp_size: response size in bytes |
| 1502 | * | 1500 | * |
| @@ -1518,8 +1516,8 @@ qla2x00_prep_ct_fdmi_req(struct ct_sns_pkt *p, uint16_t cmd, | |||
| 1518 | } | 1516 | } |
| 1519 | 1517 | ||
| 1520 | /** | 1518 | /** |
| 1521 | * qla2x00_fdmi_rhba() - | 1519 | * qla2x00_fdmi_rhba() - perform RHBA FDMI registration |
| 1522 | * @ha: HA context | 1520 | * @vha: HA context |
| 1523 | * | 1521 | * |
| 1524 | * Returns 0 on success. | 1522 | * Returns 0 on success. |
| 1525 | */ | 1523 | */ |
| @@ -1728,8 +1726,8 @@ qla2x00_fdmi_rhba(scsi_qla_host_t *vha) | |||
| 1728 | } | 1726 | } |
| 1729 | 1727 | ||
| 1730 | /** | 1728 | /** |
| 1731 | * qla2x00_fdmi_rpa() - | 1729 | * qla2x00_fdmi_rpa() - perform RPA registration |
| 1732 | * @ha: HA context | 1730 | * @vha: HA context |
| 1733 | * | 1731 | * |
| 1734 | * Returns 0 on success. | 1732 | * Returns 0 on success. |
| 1735 | */ | 1733 | */ |
| @@ -1940,8 +1938,8 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *vha) | |||
| 1940 | } | 1938 | } |
| 1941 | 1939 | ||
| 1942 | /** | 1940 | /** |
| 1943 | * qla2x00_fdmiv2_rhba() - | 1941 | * qla2x00_fdmiv2_rhba() - perform RHBA FDMI v2 registration |
| 1944 | * @ha: HA context | 1942 | * @vha: HA context |
| 1945 | * | 1943 | * |
| 1946 | * Returns 0 on success. | 1944 | * Returns 0 on success. |
| 1947 | */ | 1945 | */ |
| @@ -2257,7 +2255,7 @@ qla2x00_fdmiv2_rhba(scsi_qla_host_t *vha) | |||
| 2257 | 2255 | ||
| 2258 | /** | 2256 | /** |
| 2259 | * qla2x00_fdmi_dhba() - | 2257 | * qla2x00_fdmi_dhba() - |
| 2260 | * @ha: HA context | 2258 | * @vha: HA context |
| 2261 | * | 2259 | * |
| 2262 | * Returns 0 on success. | 2260 | * Returns 0 on success. |
| 2263 | */ | 2261 | */ |
| @@ -2305,7 +2303,7 @@ qla2x00_fdmi_dhba(scsi_qla_host_t *vha) | |||
| 2305 | 2303 | ||
| 2306 | /** | 2304 | /** |
| 2307 | * qla2x00_fdmiv2_rpa() - | 2305 | * qla2x00_fdmiv2_rpa() - |
| 2308 | * @ha: HA context | 2306 | * @vha: HA context |
| 2309 | * | 2307 | * |
| 2310 | * Returns 0 on success. | 2308 | * Returns 0 on success. |
| 2311 | */ | 2309 | */ |
| @@ -2635,7 +2633,7 @@ qla2x00_fdmiv2_rpa(scsi_qla_host_t *vha) | |||
| 2635 | 2633 | ||
| 2636 | /** | 2634 | /** |
| 2637 | * qla2x00_fdmi_register() - | 2635 | * qla2x00_fdmi_register() - |
| 2638 | * @ha: HA context | 2636 | * @vha: HA context |
| 2639 | * | 2637 | * |
| 2640 | * Returns 0 on success. | 2638 | * Returns 0 on success. |
| 2641 | */ | 2639 | */ |
| @@ -2693,7 +2691,7 @@ out: | |||
| 2693 | 2691 | ||
| 2694 | /** | 2692 | /** |
| 2695 | * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query. | 2693 | * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query. |
| 2696 | * @ha: HA context | 2694 | * @vha: HA context |
| 2697 | * @list: switch info entries to populate | 2695 | * @list: switch info entries to populate |
| 2698 | * | 2696 | * |
| 2699 | * Returns 0 on success. | 2697 | * Returns 0 on success. |
| @@ -2778,7 +2776,7 @@ qla24xx_prep_ct_fm_req(struct ct_sns_pkt *p, uint16_t cmd, | |||
| 2778 | 2776 | ||
| 2779 | /** | 2777 | /** |
| 2780 | * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query. | 2778 | * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query. |
| 2781 | * @ha: HA context | 2779 | * @vha: HA context |
| 2782 | * @list: switch info entries to populate | 2780 | * @list: switch info entries to populate |
| 2783 | * | 2781 | * |
| 2784 | * Returns 0 on success. | 2782 | * Returns 0 on success. |
| @@ -2892,7 +2890,7 @@ qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list) | |||
| 2892 | /** | 2890 | /** |
| 2893 | * qla2x00_gff_id() - SNS Get FC-4 Features (GFF_ID) query. | 2891 | * qla2x00_gff_id() - SNS Get FC-4 Features (GFF_ID) query. |
| 2894 | * | 2892 | * |
| 2895 | * @ha: HA context | 2893 | * @vha: HA context |
| 2896 | * @list: switch info entries to populate | 2894 | * @list: switch info entries to populate |
| 2897 | * | 2895 | * |
| 2898 | */ | 2896 | */ |
| @@ -3862,7 +3860,6 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) | |||
| 3862 | fc_port_t *fcport; | 3860 | fc_port_t *fcport; |
| 3863 | u32 i, rc; | 3861 | u32 i, rc; |
| 3864 | bool found; | 3862 | bool found; |
| 3865 | u8 fc4type = sp->gen2; | ||
| 3866 | struct fab_scan_rp *rp; | 3863 | struct fab_scan_rp *rp; |
| 3867 | unsigned long flags; | 3864 | unsigned long flags; |
| 3868 | 3865 | ||
| @@ -3935,7 +3932,7 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) | |||
| 3935 | "%s %d %8phC post new sess\n", | 3932 | "%s %d %8phC post new sess\n", |
| 3936 | __func__, __LINE__, rp->port_name); | 3933 | __func__, __LINE__, rp->port_name); |
| 3937 | qla24xx_post_newsess_work(vha, &rp->id, rp->port_name, | 3934 | qla24xx_post_newsess_work(vha, &rp->id, rp->port_name, |
| 3938 | rp->node_name, NULL, fc4type); | 3935 | rp->node_name, NULL, rp->fc4type); |
| 3939 | } | 3936 | } |
| 3940 | } | 3937 | } |
| 3941 | 3938 | ||
| @@ -3973,24 +3970,114 @@ out: | |||
| 3973 | spin_lock_irqsave(&vha->work_lock, flags); | 3970 | spin_lock_irqsave(&vha->work_lock, flags); |
| 3974 | vha->scan.scan_flags &= ~SF_SCANNING; | 3971 | vha->scan.scan_flags &= ~SF_SCANNING; |
| 3975 | spin_unlock_irqrestore(&vha->work_lock, flags); | 3972 | spin_unlock_irqrestore(&vha->work_lock, flags); |
| 3976 | |||
| 3977 | if ((fc4type == FC4_TYPE_FCP_SCSI) && vha->flags.nvme_enabled) | ||
| 3978 | qla24xx_async_gpnft(vha, FC4_TYPE_NVME); | ||
| 3979 | } | 3973 | } |
| 3980 | 3974 | ||
| 3981 | static void qla2x00_async_gpnft_gnnft_sp_done(void *s, int res) | 3975 | static void qla2x00_find_free_fcp_nvme_slot(struct scsi_qla_host *vha, |
| 3976 | struct srb *sp) | ||
| 3982 | { | 3977 | { |
| 3983 | struct srb *sp = s; | 3978 | struct qla_hw_data *ha = vha->hw; |
| 3984 | struct scsi_qla_host *vha = sp->vha; | 3979 | int num_fibre_dev = ha->max_fibre_devices; |
| 3985 | struct qla_work_evt *e; | ||
| 3986 | struct ct_sns_req *ct_req = | 3980 | struct ct_sns_req *ct_req = |
| 3987 | (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req; | 3981 | (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req; |
| 3988 | struct ct_sns_gpnft_rsp *ct_rsp = | 3982 | struct ct_sns_gpnft_rsp *ct_rsp = |
| 3989 | (struct ct_sns_gpnft_rsp *)sp->u.iocb_cmd.u.ctarg.rsp; | 3983 | (struct ct_sns_gpnft_rsp *)sp->u.iocb_cmd.u.ctarg.rsp; |
| 3990 | struct ct_sns_gpn_ft_data *d; | 3984 | struct ct_sns_gpn_ft_data *d; |
| 3991 | struct fab_scan_rp *rp; | 3985 | struct fab_scan_rp *rp; |
| 3986 | u16 cmd = be16_to_cpu(ct_req->command); | ||
| 3987 | u8 fc4_type = sp->gen2; | ||
| 3992 | int i, j, k; | 3988 | int i, j, k; |
| 3989 | port_id_t id; | ||
| 3990 | u8 found; | ||
| 3991 | u64 wwn; | ||
| 3992 | |||
| 3993 | j = 0; | ||
| 3994 | for (i = 0; i < num_fibre_dev; i++) { | ||
| 3995 | d = &ct_rsp->entries[i]; | ||
| 3996 | |||
| 3997 | id.b.rsvd_1 = 0; | ||
| 3998 | id.b.domain = d->port_id[0]; | ||
| 3999 | id.b.area = d->port_id[1]; | ||
| 4000 | id.b.al_pa = d->port_id[2]; | ||
| 4001 | wwn = wwn_to_u64(d->port_name); | ||
| 4002 | |||
| 4003 | if (id.b24 == 0 || wwn == 0) | ||
| 4004 | continue; | ||
| 4005 | |||
| 4006 | if (fc4_type == FC4_TYPE_FCP_SCSI) { | ||
| 4007 | if (cmd == GPN_FT_CMD) { | ||
| 4008 | rp = &vha->scan.l[j]; | ||
| 4009 | rp->id = id; | ||
| 4010 | memcpy(rp->port_name, d->port_name, 8); | ||
| 4011 | j++; | ||
| 4012 | rp->fc4type = FS_FC4TYPE_FCP; | ||
| 4013 | } else { | ||
| 4014 | for (k = 0; k < num_fibre_dev; k++) { | ||
| 4015 | rp = &vha->scan.l[k]; | ||
| 4016 | if (id.b24 == rp->id.b24) { | ||
| 4017 | memcpy(rp->node_name, | ||
| 4018 | d->port_name, 8); | ||
| 4019 | break; | ||
| 4020 | } | ||
| 4021 | } | ||
| 4022 | } | ||
| 4023 | } else { | ||
| 4024 | /* Search if the fibre device supports FC4_TYPE_NVME */ | ||
| 4025 | if (cmd == GPN_FT_CMD) { | ||
| 4026 | found = 0; | ||
| 4027 | |||
| 4028 | for (k = 0; k < num_fibre_dev; k++) { | ||
| 4029 | rp = &vha->scan.l[k]; | ||
| 4030 | if (!memcmp(rp->port_name, | ||
| 4031 | d->port_name, 8)) { | ||
| 4032 | /* | ||
| 4033 | * Supports FC-NVMe & FCP | ||
| 4034 | */ | ||
| 4035 | rp->fc4type |= FS_FC4TYPE_NVME; | ||
| 4036 | found = 1; | ||
| 4037 | break; | ||
| 4038 | } | ||
| 4039 | } | ||
| 4040 | |||
| 4041 | /* We found new FC-NVMe only port */ | ||
| 4042 | if (!found) { | ||
| 4043 | for (k = 0; k < num_fibre_dev; k++) { | ||
| 4044 | rp = &vha->scan.l[k]; | ||
| 4045 | if (wwn_to_u64(rp->port_name)) { | ||
| 4046 | continue; | ||
| 4047 | } else { | ||
| 4048 | rp->id = id; | ||
| 4049 | memcpy(rp->port_name, | ||
| 4050 | d->port_name, 8); | ||
| 4051 | rp->fc4type = | ||
| 4052 | FS_FC4TYPE_NVME; | ||
| 4053 | break; | ||
| 4054 | } | ||
| 4055 | } | ||
| 4056 | } | ||
| 4057 | } else { | ||
| 4058 | for (k = 0; k < num_fibre_dev; k++) { | ||
| 4059 | rp = &vha->scan.l[k]; | ||
| 4060 | if (id.b24 == rp->id.b24) { | ||
| 4061 | memcpy(rp->node_name, | ||
| 4062 | d->port_name, 8); | ||
| 4063 | break; | ||
| 4064 | } | ||
| 4065 | } | ||
| 4066 | } | ||
| 4067 | } | ||
| 4068 | } | ||
| 4069 | } | ||
| 4070 | |||
| 4071 | static void qla2x00_async_gpnft_gnnft_sp_done(void *s, int res) | ||
| 4072 | { | ||
| 4073 | struct srb *sp = s; | ||
| 4074 | struct scsi_qla_host *vha = sp->vha; | ||
| 4075 | struct qla_work_evt *e; | ||
| 4076 | struct ct_sns_req *ct_req = | ||
| 4077 | (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req; | ||
| 3993 | u16 cmd = be16_to_cpu(ct_req->command); | 4078 | u16 cmd = be16_to_cpu(ct_req->command); |
| 4079 | u8 fc4_type = sp->gen2; | ||
| 4080 | unsigned long flags; | ||
| 3994 | 4081 | ||
| 3995 | /* gen2 field is holding the fc4type */ | 4082 | /* gen2 field is holding the fc4type */ |
| 3996 | ql_dbg(ql_dbg_disc, vha, 0xffff, | 4083 | ql_dbg(ql_dbg_disc, vha, 0xffff, |
| @@ -4018,40 +4105,51 @@ static void qla2x00_async_gpnft_gnnft_sp_done(void *s, int res) | |||
| 4018 | return; | 4105 | return; |
| 4019 | } | 4106 | } |
| 4020 | 4107 | ||
| 4021 | if (!res) { | 4108 | if (!res) |
| 4022 | port_id_t id; | 4109 | qla2x00_find_free_fcp_nvme_slot(vha, sp); |
| 4023 | u64 wwn; | ||
| 4024 | |||
| 4025 | j = 0; | ||
| 4026 | for (i = 0; i < vha->hw->max_fibre_devices; i++) { | ||
| 4027 | d = &ct_rsp->entries[i]; | ||
| 4028 | 4110 | ||
| 4029 | id.b.rsvd_1 = 0; | 4111 | if ((fc4_type == FC4_TYPE_FCP_SCSI) && vha->flags.nvme_enabled && |
| 4030 | id.b.domain = d->port_id[0]; | 4112 | cmd == GNN_FT_CMD) { |
| 4031 | id.b.area = d->port_id[1]; | 4113 | del_timer(&sp->u.iocb_cmd.timer); |
| 4032 | id.b.al_pa = d->port_id[2]; | 4114 | spin_lock_irqsave(&vha->work_lock, flags); |
| 4033 | wwn = wwn_to_u64(d->port_name); | 4115 | vha->scan.scan_flags &= ~SF_SCANNING; |
| 4034 | 4116 | spin_unlock_irqrestore(&vha->work_lock, flags); | |
| 4035 | if (id.b24 == 0 || wwn == 0) | ||
| 4036 | continue; | ||
| 4037 | 4117 | ||
| 4038 | if (cmd == GPN_FT_CMD) { | 4118 | e = qla2x00_alloc_work(vha, QLA_EVT_GPNFT); |
| 4039 | rp = &vha->scan.l[j]; | 4119 | if (!e) { |
| 4040 | rp->id = id; | 4120 | /* |
| 4041 | memcpy(rp->port_name, d->port_name, 8); | 4121 | * please ignore kernel warning. Otherwise, |
| 4042 | j++; | 4122 | * we have mem leak. |
| 4043 | } else {/* GNN_FT_CMD */ | 4123 | */ |
| 4044 | for (k = 0; k < vha->hw->max_fibre_devices; | 4124 | if (sp->u.iocb_cmd.u.ctarg.req) { |
| 4045 | k++) { | 4125 | dma_free_coherent(&vha->hw->pdev->dev, |
| 4046 | rp = &vha->scan.l[k]; | 4126 | sizeof(struct ct_sns_pkt), |
| 4047 | if (id.b24 == rp->id.b24) { | 4127 | sp->u.iocb_cmd.u.ctarg.req, |
| 4048 | memcpy(rp->node_name, | 4128 | sp->u.iocb_cmd.u.ctarg.req_dma); |
| 4049 | d->port_name, 8); | 4129 | sp->u.iocb_cmd.u.ctarg.req = NULL; |
| 4050 | break; | ||
| 4051 | } | ||
| 4052 | } | ||
| 4053 | } | 4130 | } |
| 4131 | if (sp->u.iocb_cmd.u.ctarg.rsp) { | ||
| 4132 | dma_free_coherent(&vha->hw->pdev->dev, | ||
| 4133 | sizeof(struct ct_sns_pkt), | ||
| 4134 | sp->u.iocb_cmd.u.ctarg.rsp, | ||
| 4135 | sp->u.iocb_cmd.u.ctarg.rsp_dma); | ||
| 4136 | sp->u.iocb_cmd.u.ctarg.rsp = NULL; | ||
| 4137 | } | ||
| 4138 | |||
| 4139 | ql_dbg(ql_dbg_disc, vha, 0xffff, | ||
| 4140 | "Async done-%s unable to alloc work element\n", | ||
| 4141 | sp->name); | ||
| 4142 | sp->free(sp); | ||
| 4143 | set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); | ||
| 4144 | set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); | ||
| 4145 | return; | ||
| 4054 | } | 4146 | } |
| 4147 | e->u.gpnft.fc4_type = FC4_TYPE_NVME; | ||
| 4148 | sp->rc = res; | ||
| 4149 | e->u.gpnft.sp = sp; | ||
| 4150 | |||
| 4151 | qla2x00_post_work(vha, e); | ||
| 4152 | return; | ||
| 4055 | } | 4153 | } |
| 4056 | 4154 | ||
| 4057 | if (cmd == GPN_FT_CMD) | 4155 | if (cmd == GPN_FT_CMD) |
| @@ -4102,9 +4200,12 @@ static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp, | |||
| 4102 | int rval = QLA_FUNCTION_FAILED; | 4200 | int rval = QLA_FUNCTION_FAILED; |
| 4103 | struct ct_sns_req *ct_req; | 4201 | struct ct_sns_req *ct_req; |
| 4104 | struct ct_sns_pkt *ct_sns; | 4202 | struct ct_sns_pkt *ct_sns; |
| 4203 | unsigned long flags; | ||
| 4105 | 4204 | ||
| 4106 | if (!vha->flags.online) { | 4205 | if (!vha->flags.online) { |
| 4206 | spin_lock_irqsave(&vha->work_lock, flags); | ||
| 4107 | vha->scan.scan_flags &= ~SF_SCANNING; | 4207 | vha->scan.scan_flags &= ~SF_SCANNING; |
| 4208 | spin_unlock_irqrestore(&vha->work_lock, flags); | ||
| 4108 | goto done_free_sp; | 4209 | goto done_free_sp; |
| 4109 | } | 4210 | } |
| 4110 | 4211 | ||
| @@ -4113,10 +4214,18 @@ static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp, | |||
| 4113 | "%s: req %p rsp %p are not setup\n", | 4214 | "%s: req %p rsp %p are not setup\n", |
| 4114 | __func__, sp->u.iocb_cmd.u.ctarg.req, | 4215 | __func__, sp->u.iocb_cmd.u.ctarg.req, |
| 4115 | sp->u.iocb_cmd.u.ctarg.rsp); | 4216 | sp->u.iocb_cmd.u.ctarg.rsp); |
| 4217 | spin_lock_irqsave(&vha->work_lock, flags); | ||
| 4116 | vha->scan.scan_flags &= ~SF_SCANNING; | 4218 | vha->scan.scan_flags &= ~SF_SCANNING; |
| 4219 | spin_unlock_irqrestore(&vha->work_lock, flags); | ||
| 4117 | WARN_ON(1); | 4220 | WARN_ON(1); |
| 4118 | goto done_free_sp; | 4221 | goto done_free_sp; |
| 4119 | } | 4222 | } |
| 4223 | |||
| 4224 | ql_dbg(ql_dbg_disc, vha, 0xfffff, | ||
| 4225 | "%s: FC4Type %x, CT-PASSTRHU %s command ctarg rsp size %d, ctarg req size %d\n", | ||
| 4226 | __func__, fc4_type, sp->name, sp->u.iocb_cmd.u.ctarg.rsp_size, | ||
| 4227 | sp->u.iocb_cmd.u.ctarg.req_size); | ||
| 4228 | |||
| 4120 | sp->type = SRB_CT_PTHRU_CMD; | 4229 | sp->type = SRB_CT_PTHRU_CMD; |
| 4121 | sp->name = "gnnft"; | 4230 | sp->name = "gnnft"; |
| 4122 | sp->gen1 = vha->hw->base_qpair->chip_reset; | 4231 | sp->gen1 = vha->hw->base_qpair->chip_reset; |
| @@ -4179,15 +4288,17 @@ void qla24xx_async_gpnft_done(scsi_qla_host_t *vha, srb_t *sp) | |||
| 4179 | } | 4288 | } |
| 4180 | 4289 | ||
| 4181 | /* Get WWPN list for certain fc4_type */ | 4290 | /* Get WWPN list for certain fc4_type */ |
| 4182 | int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type) | 4291 | int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) |
| 4183 | { | 4292 | { |
| 4184 | int rval = QLA_FUNCTION_FAILED; | 4293 | int rval = QLA_FUNCTION_FAILED; |
| 4185 | struct ct_sns_req *ct_req; | 4294 | struct ct_sns_req *ct_req; |
| 4186 | srb_t *sp; | ||
| 4187 | struct ct_sns_pkt *ct_sns; | 4295 | struct ct_sns_pkt *ct_sns; |
| 4188 | u32 rspsz; | 4296 | u32 rspsz; |
| 4189 | unsigned long flags; | 4297 | unsigned long flags; |
| 4190 | 4298 | ||
| 4299 | ql_dbg(ql_dbg_disc, vha, 0xffff, | ||
| 4300 | "%s enter\n", __func__); | ||
| 4301 | |||
| 4191 | if (!vha->flags.online) | 4302 | if (!vha->flags.online) |
| 4192 | return rval; | 4303 | return rval; |
| 4193 | 4304 | ||
| @@ -4200,9 +4311,58 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type) | |||
| 4200 | vha->scan.scan_flags |= SF_SCANNING; | 4311 | vha->scan.scan_flags |= SF_SCANNING; |
| 4201 | spin_unlock_irqrestore(&vha->work_lock, flags); | 4312 | spin_unlock_irqrestore(&vha->work_lock, flags); |
| 4202 | 4313 | ||
| 4203 | sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); | 4314 | if (fc4_type == FC4_TYPE_FCP_SCSI) { |
| 4204 | if (!sp) { | 4315 | ql_dbg(ql_dbg_disc, vha, 0xffff, |
| 4205 | vha->scan.scan_flags &= ~SF_SCANNING; | 4316 | "%s: Performing FCP Scan\n", __func__); |
| 4317 | |||
| 4318 | if (sp) | ||
| 4319 | sp->free(sp); /* should not happen */ | ||
| 4320 | |||
| 4321 | sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); | ||
| 4322 | if (!sp) { | ||
| 4323 | spin_lock_irqsave(&vha->work_lock, flags); | ||
| 4324 | vha->scan.scan_flags &= ~SF_SCANNING; | ||
| 4325 | spin_unlock_irqrestore(&vha->work_lock, flags); | ||
| 4326 | return rval; | ||
| 4327 | } | ||
| 4328 | |||
| 4329 | sp->u.iocb_cmd.u.ctarg.req = dma_zalloc_coherent( | ||
| 4330 | &vha->hw->pdev->dev, sizeof(struct ct_sns_pkt), | ||
| 4331 | &sp->u.iocb_cmd.u.ctarg.req_dma, GFP_KERNEL); | ||
| 4332 | if (!sp->u.iocb_cmd.u.ctarg.req) { | ||
| 4333 | ql_log(ql_log_warn, vha, 0xffff, | ||
| 4334 | "Failed to allocate ct_sns request.\n"); | ||
| 4335 | spin_lock_irqsave(&vha->work_lock, flags); | ||
| 4336 | vha->scan.scan_flags &= ~SF_SCANNING; | ||
| 4337 | spin_unlock_irqrestore(&vha->work_lock, flags); | ||
| 4338 | goto done_free_sp; | ||
| 4339 | } | ||
| 4340 | sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE; | ||
| 4341 | |||
| 4342 | rspsz = sizeof(struct ct_sns_gpnft_rsp) + | ||
| 4343 | ((vha->hw->max_fibre_devices - 1) * | ||
| 4344 | sizeof(struct ct_sns_gpn_ft_data)); | ||
| 4345 | |||
| 4346 | sp->u.iocb_cmd.u.ctarg.rsp = dma_zalloc_coherent( | ||
| 4347 | &vha->hw->pdev->dev, rspsz, | ||
| 4348 | &sp->u.iocb_cmd.u.ctarg.rsp_dma, GFP_KERNEL); | ||
| 4349 | if (!sp->u.iocb_cmd.u.ctarg.rsp) { | ||
| 4350 | ql_log(ql_log_warn, vha, 0xffff, | ||
| 4351 | "Failed to allocate ct_sns request.\n"); | ||
| 4352 | spin_lock_irqsave(&vha->work_lock, flags); | ||
| 4353 | vha->scan.scan_flags &= ~SF_SCANNING; | ||
| 4354 | spin_unlock_irqrestore(&vha->work_lock, flags); | ||
| 4355 | goto done_free_sp; | ||
| 4356 | } | ||
| 4357 | sp->u.iocb_cmd.u.ctarg.rsp_size = rspsz; | ||
| 4358 | |||
| 4359 | ql_dbg(ql_dbg_disc, vha, 0xffff, | ||
| 4360 | "%s scan list size %d\n", __func__, vha->scan.size); | ||
| 4361 | |||
| 4362 | memset(vha->scan.l, 0, vha->scan.size); | ||
| 4363 | } else if (!sp) { | ||
| 4364 | ql_dbg(ql_dbg_disc, vha, 0xffff, | ||
| 4365 | "NVME scan did not provide SP\n"); | ||
| 4206 | return rval; | 4366 | return rval; |
| 4207 | } | 4367 | } |
| 4208 | 4368 | ||
| @@ -4212,31 +4372,10 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type) | |||
| 4212 | sp->gen2 = fc4_type; | 4372 | sp->gen2 = fc4_type; |
| 4213 | qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); | 4373 | qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); |
| 4214 | 4374 | ||
| 4215 | sp->u.iocb_cmd.u.ctarg.req = dma_zalloc_coherent(&vha->hw->pdev->dev, | ||
| 4216 | sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma, | ||
| 4217 | GFP_KERNEL); | ||
| 4218 | if (!sp->u.iocb_cmd.u.ctarg.req) { | ||
| 4219 | ql_log(ql_log_warn, vha, 0xffff, | ||
| 4220 | "Failed to allocate ct_sns request.\n"); | ||
| 4221 | vha->scan.scan_flags &= ~SF_SCANNING; | ||
| 4222 | goto done_free_sp; | ||
| 4223 | } | ||
| 4224 | |||
| 4225 | rspsz = sizeof(struct ct_sns_gpnft_rsp) + | 4375 | rspsz = sizeof(struct ct_sns_gpnft_rsp) + |
| 4226 | ((vha->hw->max_fibre_devices - 1) * | 4376 | ((vha->hw->max_fibre_devices - 1) * |
| 4227 | sizeof(struct ct_sns_gpn_ft_data)); | 4377 | sizeof(struct ct_sns_gpn_ft_data)); |
| 4228 | 4378 | ||
| 4229 | sp->u.iocb_cmd.u.ctarg.rsp = dma_zalloc_coherent(&vha->hw->pdev->dev, | ||
| 4230 | rspsz, &sp->u.iocb_cmd.u.ctarg.rsp_dma, GFP_KERNEL); | ||
| 4231 | if (!sp->u.iocb_cmd.u.ctarg.rsp) { | ||
| 4232 | ql_log(ql_log_warn, vha, 0xffff, | ||
| 4233 | "Failed to allocate ct_sns request.\n"); | ||
| 4234 | vha->scan.scan_flags &= ~SF_SCANNING; | ||
| 4235 | goto done_free_sp; | ||
| 4236 | } | ||
| 4237 | |||
| 4238 | memset(vha->scan.l, 0, vha->scan.size); | ||
| 4239 | |||
| 4240 | ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req; | 4379 | ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req; |
| 4241 | /* CT_IU preamble */ | 4380 | /* CT_IU preamble */ |
| 4242 | ct_req = qla2x00_prep_ct_req(ct_sns, GPN_FT_CMD, rspsz); | 4381 | ct_req = qla2x00_prep_ct_req(ct_sns, GPN_FT_CMD, rspsz); |
| @@ -4244,8 +4383,6 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type) | |||
| 4244 | /* GPN_FT req */ | 4383 | /* GPN_FT req */ |
| 4245 | ct_req->req.gpn_ft.port_type = fc4_type; | 4384 | ct_req->req.gpn_ft.port_type = fc4_type; |
| 4246 | 4385 | ||
| 4247 | sp->u.iocb_cmd.u.ctarg.req_size = GPN_FT_REQ_SIZE; | ||
| 4248 | sp->u.iocb_cmd.u.ctarg.rsp_size = rspsz; | ||
| 4249 | sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; | 4386 | sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; |
| 4250 | 4387 | ||
| 4251 | sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; | 4388 | sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; |
| @@ -4253,7 +4390,9 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type) | |||
| 4253 | 4390 | ||
| 4254 | rval = qla2x00_start_sp(sp); | 4391 | rval = qla2x00_start_sp(sp); |
| 4255 | if (rval != QLA_SUCCESS) { | 4392 | if (rval != QLA_SUCCESS) { |
| 4393 | spin_lock_irqsave(&vha->work_lock, flags); | ||
| 4256 | vha->scan.scan_flags &= ~SF_SCANNING; | 4394 | vha->scan.scan_flags &= ~SF_SCANNING; |
| 4395 | spin_unlock_irqrestore(&vha->work_lock, flags); | ||
| 4257 | goto done_free_sp; | 4396 | goto done_free_sp; |
| 4258 | } | 4397 | } |
| 4259 | 4398 | ||
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 8d7fab3cd01d..8aeb0ed524a1 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
| @@ -875,7 +875,6 @@ qla24xx_async_prli(struct scsi_qla_host *vha, fc_port_t *fcport) | |||
| 875 | return rval; | 875 | return rval; |
| 876 | 876 | ||
| 877 | if (fcport->fw_login_state == DSC_LS_PLOGI_PEND || | 877 | if (fcport->fw_login_state == DSC_LS_PLOGI_PEND || |
| 878 | fcport->fw_login_state == DSC_LS_PLOGI_COMP || | ||
| 879 | fcport->fw_login_state == DSC_LS_PRLI_PEND) | 878 | fcport->fw_login_state == DSC_LS_PRLI_PEND) |
| 880 | return rval; | 879 | return rval; |
| 881 | 880 | ||
| @@ -1240,6 +1239,11 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport) | |||
| 1240 | qla2x00_post_async_adisc_work(vha, fcport, data); | 1239 | qla2x00_post_async_adisc_work(vha, fcport, data); |
| 1241 | break; | 1240 | break; |
| 1242 | 1241 | ||
| 1242 | case DSC_LOGIN_PEND: | ||
| 1243 | if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) | ||
| 1244 | qla24xx_post_prli_work(vha, fcport); | ||
| 1245 | break; | ||
| 1246 | |||
| 1243 | default: | 1247 | default: |
| 1244 | break; | 1248 | break; |
| 1245 | } | 1249 | } |
| @@ -1643,6 +1647,13 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea) | |||
| 1643 | qla24xx_post_gpdb_work(vha, ea->fcport, 0); | 1647 | qla24xx_post_gpdb_work(vha, ea->fcport, 0); |
| 1644 | break; | 1648 | break; |
| 1645 | default: | 1649 | default: |
| 1650 | if ((ea->iop[0] == LSC_SCODE_ELS_REJECT) && | ||
| 1651 | (ea->iop[1] == 0x50000)) { /* reson 5=busy expl:0x0 */ | ||
| 1652 | set_bit(RELOGIN_NEEDED, &vha->dpc_flags); | ||
| 1653 | ea->fcport->fw_login_state = DSC_LS_PLOGI_COMP; | ||
| 1654 | break; | ||
| 1655 | } | ||
| 1656 | |||
| 1646 | if (ea->fcport->n2n_flag) { | 1657 | if (ea->fcport->n2n_flag) { |
| 1647 | ql_dbg(ql_dbg_disc, vha, 0x2118, | 1658 | ql_dbg(ql_dbg_disc, vha, 0x2118, |
| 1648 | "%s %d %8phC post fc4 prli\n", | 1659 | "%s %d %8phC post fc4 prli\n", |
| @@ -2049,7 +2060,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha) | |||
| 2049 | 2060 | ||
| 2050 | /** | 2061 | /** |
| 2051 | * qla2100_pci_config() - Setup ISP21xx PCI configuration registers. | 2062 | * qla2100_pci_config() - Setup ISP21xx PCI configuration registers. |
| 2052 | * @ha: HA context | 2063 | * @vha: HA context |
| 2053 | * | 2064 | * |
| 2054 | * Returns 0 on success. | 2065 | * Returns 0 on success. |
| 2055 | */ | 2066 | */ |
| @@ -2080,7 +2091,7 @@ qla2100_pci_config(scsi_qla_host_t *vha) | |||
| 2080 | 2091 | ||
| 2081 | /** | 2092 | /** |
| 2082 | * qla2300_pci_config() - Setup ISP23xx PCI configuration registers. | 2093 | * qla2300_pci_config() - Setup ISP23xx PCI configuration registers. |
| 2083 | * @ha: HA context | 2094 | * @vha: HA context |
| 2084 | * | 2095 | * |
| 2085 | * Returns 0 on success. | 2096 | * Returns 0 on success. |
| 2086 | */ | 2097 | */ |
| @@ -2162,7 +2173,7 @@ qla2300_pci_config(scsi_qla_host_t *vha) | |||
| 2162 | 2173 | ||
| 2163 | /** | 2174 | /** |
| 2164 | * qla24xx_pci_config() - Setup ISP24xx PCI configuration registers. | 2175 | * qla24xx_pci_config() - Setup ISP24xx PCI configuration registers. |
| 2165 | * @ha: HA context | 2176 | * @vha: HA context |
| 2166 | * | 2177 | * |
| 2167 | * Returns 0 on success. | 2178 | * Returns 0 on success. |
| 2168 | */ | 2179 | */ |
| @@ -2206,7 +2217,7 @@ qla24xx_pci_config(scsi_qla_host_t *vha) | |||
| 2206 | 2217 | ||
| 2207 | /** | 2218 | /** |
| 2208 | * qla25xx_pci_config() - Setup ISP25xx PCI configuration registers. | 2219 | * qla25xx_pci_config() - Setup ISP25xx PCI configuration registers. |
| 2209 | * @ha: HA context | 2220 | * @vha: HA context |
| 2210 | * | 2221 | * |
| 2211 | * Returns 0 on success. | 2222 | * Returns 0 on success. |
| 2212 | */ | 2223 | */ |
| @@ -2237,7 +2248,7 @@ qla25xx_pci_config(scsi_qla_host_t *vha) | |||
| 2237 | 2248 | ||
| 2238 | /** | 2249 | /** |
| 2239 | * qla2x00_isp_firmware() - Choose firmware image. | 2250 | * qla2x00_isp_firmware() - Choose firmware image. |
| 2240 | * @ha: HA context | 2251 | * @vha: HA context |
| 2241 | * | 2252 | * |
| 2242 | * Returns 0 on success. | 2253 | * Returns 0 on success. |
| 2243 | */ | 2254 | */ |
| @@ -2273,7 +2284,7 @@ qla2x00_isp_firmware(scsi_qla_host_t *vha) | |||
| 2273 | 2284 | ||
| 2274 | /** | 2285 | /** |
| 2275 | * qla2x00_reset_chip() - Reset ISP chip. | 2286 | * qla2x00_reset_chip() - Reset ISP chip. |
| 2276 | * @ha: HA context | 2287 | * @vha: HA context |
| 2277 | * | 2288 | * |
| 2278 | * Returns 0 on success. | 2289 | * Returns 0 on success. |
| 2279 | */ | 2290 | */ |
| @@ -2417,6 +2428,7 @@ qla2x00_reset_chip(scsi_qla_host_t *vha) | |||
| 2417 | 2428 | ||
| 2418 | /** | 2429 | /** |
| 2419 | * qla81xx_reset_mpi() - Reset's MPI FW via Write MPI Register MBC. | 2430 | * qla81xx_reset_mpi() - Reset's MPI FW via Write MPI Register MBC. |
| 2431 | * @vha: HA context | ||
| 2420 | * | 2432 | * |
| 2421 | * Returns 0 on success. | 2433 | * Returns 0 on success. |
| 2422 | */ | 2434 | */ |
| @@ -2433,7 +2445,7 @@ qla81xx_reset_mpi(scsi_qla_host_t *vha) | |||
| 2433 | 2445 | ||
| 2434 | /** | 2446 | /** |
| 2435 | * qla24xx_reset_risc() - Perform full reset of ISP24xx RISC. | 2447 | * qla24xx_reset_risc() - Perform full reset of ISP24xx RISC. |
| 2436 | * @ha: HA context | 2448 | * @vha: HA context |
| 2437 | * | 2449 | * |
| 2438 | * Returns 0 on success. | 2450 | * Returns 0 on success. |
| 2439 | */ | 2451 | */ |
| @@ -2648,7 +2660,7 @@ acquired: | |||
| 2648 | 2660 | ||
| 2649 | /** | 2661 | /** |
| 2650 | * qla24xx_reset_chip() - Reset ISP24xx chip. | 2662 | * qla24xx_reset_chip() - Reset ISP24xx chip. |
| 2651 | * @ha: HA context | 2663 | * @vha: HA context |
| 2652 | * | 2664 | * |
| 2653 | * Returns 0 on success. | 2665 | * Returns 0 on success. |
| 2654 | */ | 2666 | */ |
| @@ -2672,7 +2684,7 @@ qla24xx_reset_chip(scsi_qla_host_t *vha) | |||
| 2672 | 2684 | ||
| 2673 | /** | 2685 | /** |
| 2674 | * qla2x00_chip_diag() - Test chip for proper operation. | 2686 | * qla2x00_chip_diag() - Test chip for proper operation. |
| 2675 | * @ha: HA context | 2687 | * @vha: HA context |
| 2676 | * | 2688 | * |
| 2677 | * Returns 0 on success. | 2689 | * Returns 0 on success. |
| 2678 | */ | 2690 | */ |
| @@ -2691,8 +2703,8 @@ qla2x00_chip_diag(scsi_qla_host_t *vha) | |||
| 2691 | /* Assume a failed state */ | 2703 | /* Assume a failed state */ |
| 2692 | rval = QLA_FUNCTION_FAILED; | 2704 | rval = QLA_FUNCTION_FAILED; |
| 2693 | 2705 | ||
| 2694 | ql_dbg(ql_dbg_init, vha, 0x007b, | 2706 | ql_dbg(ql_dbg_init, vha, 0x007b, "Testing device at %p.\n", |
| 2695 | "Testing device at %lx.\n", (u_long)®->flash_address); | 2707 | ®->flash_address); |
| 2696 | 2708 | ||
| 2697 | spin_lock_irqsave(&ha->hardware_lock, flags); | 2709 | spin_lock_irqsave(&ha->hardware_lock, flags); |
| 2698 | 2710 | ||
| @@ -2796,7 +2808,7 @@ chip_diag_failed: | |||
| 2796 | 2808 | ||
| 2797 | /** | 2809 | /** |
| 2798 | * qla24xx_chip_diag() - Test ISP24xx for proper operation. | 2810 | * qla24xx_chip_diag() - Test ISP24xx for proper operation. |
| 2799 | * @ha: HA context | 2811 | * @vha: HA context |
| 2800 | * | 2812 | * |
| 2801 | * Returns 0 on success. | 2813 | * Returns 0 on success. |
| 2802 | */ | 2814 | */ |
| @@ -3264,7 +3276,7 @@ out: | |||
| 3264 | 3276 | ||
| 3265 | /** | 3277 | /** |
| 3266 | * qla2x00_setup_chip() - Load and start RISC firmware. | 3278 | * qla2x00_setup_chip() - Load and start RISC firmware. |
| 3267 | * @ha: HA context | 3279 | * @vha: HA context |
| 3268 | * | 3280 | * |
| 3269 | * Returns 0 on success. | 3281 | * Returns 0 on success. |
| 3270 | */ | 3282 | */ |
| @@ -3419,7 +3431,7 @@ failed: | |||
| 3419 | 3431 | ||
| 3420 | /** | 3432 | /** |
| 3421 | * qla2x00_init_response_q_entries() - Initializes response queue entries. | 3433 | * qla2x00_init_response_q_entries() - Initializes response queue entries. |
| 3422 | * @ha: HA context | 3434 | * @rsp: response queue |
| 3423 | * | 3435 | * |
| 3424 | * Beginning of request ring has initialization control block already built | 3436 | * Beginning of request ring has initialization control block already built |
| 3425 | * by nvram config routine. | 3437 | * by nvram config routine. |
| @@ -3444,7 +3456,7 @@ qla2x00_init_response_q_entries(struct rsp_que *rsp) | |||
| 3444 | 3456 | ||
| 3445 | /** | 3457 | /** |
| 3446 | * qla2x00_update_fw_options() - Read and process firmware options. | 3458 | * qla2x00_update_fw_options() - Read and process firmware options. |
| 3447 | * @ha: HA context | 3459 | * @vha: HA context |
| 3448 | * | 3460 | * |
| 3449 | * Returns 0 on success. | 3461 | * Returns 0 on success. |
| 3450 | */ | 3462 | */ |
| @@ -3707,7 +3719,7 @@ qla24xx_config_rings(struct scsi_qla_host *vha) | |||
| 3707 | 3719 | ||
| 3708 | /** | 3720 | /** |
| 3709 | * qla2x00_init_rings() - Initializes firmware. | 3721 | * qla2x00_init_rings() - Initializes firmware. |
| 3710 | * @ha: HA context | 3722 | * @vha: HA context |
| 3711 | * | 3723 | * |
| 3712 | * Beginning of request ring has initialization control block already built | 3724 | * Beginning of request ring has initialization control block already built |
| 3713 | * by nvram config routine. | 3725 | * by nvram config routine. |
| @@ -3815,7 +3827,7 @@ next_check: | |||
| 3815 | 3827 | ||
| 3816 | /** | 3828 | /** |
| 3817 | * qla2x00_fw_ready() - Waits for firmware ready. | 3829 | * qla2x00_fw_ready() - Waits for firmware ready. |
| 3818 | * @ha: HA context | 3830 | * @vha: HA context |
| 3819 | * | 3831 | * |
| 3820 | * Returns 0 on success. | 3832 | * Returns 0 on success. |
| 3821 | */ | 3833 | */ |
| @@ -4483,7 +4495,7 @@ qla2x00_rport_del(void *data) | |||
| 4483 | 4495 | ||
| 4484 | /** | 4496 | /** |
| 4485 | * qla2x00_alloc_fcport() - Allocate a generic fcport. | 4497 | * qla2x00_alloc_fcport() - Allocate a generic fcport. |
| 4486 | * @ha: HA context | 4498 | * @vha: HA context |
| 4487 | * @flags: allocation flags | 4499 | * @flags: allocation flags |
| 4488 | * | 4500 | * |
| 4489 | * Returns a pointer to the allocated fcport, or NULL, if none available. | 4501 | * Returns a pointer to the allocated fcport, or NULL, if none available. |
| @@ -5027,9 +5039,9 @@ qla2x00_iidma_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) | |||
| 5027 | fcport->port_name, rval, fcport->fp_speed, mb[0], mb[1]); | 5039 | fcport->port_name, rval, fcport->fp_speed, mb[0], mb[1]); |
| 5028 | } else { | 5040 | } else { |
| 5029 | ql_dbg(ql_dbg_disc, vha, 0x2005, | 5041 | ql_dbg(ql_dbg_disc, vha, 0x2005, |
| 5030 | "iIDMA adjusted to %s GB/s on %8phN.\n", | 5042 | "iIDMA adjusted to %s GB/s (%X) on %8phN.\n", |
| 5031 | qla2x00_get_link_speed_str(ha, fcport->fp_speed), | 5043 | qla2x00_get_link_speed_str(ha, fcport->fp_speed), |
| 5032 | fcport->port_name); | 5044 | fcport->fp_speed, fcport->port_name); |
| 5033 | } | 5045 | } |
| 5034 | } | 5046 | } |
| 5035 | 5047 | ||
| @@ -5109,13 +5121,14 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) | |||
| 5109 | fcport->deleted = 0; | 5121 | fcport->deleted = 0; |
| 5110 | fcport->logout_on_delete = 1; | 5122 | fcport->logout_on_delete = 1; |
| 5111 | 5123 | ||
| 5124 | qla2x00_set_fcport_state(fcport, FCS_ONLINE); | ||
| 5125 | qla2x00_iidma_fcport(vha, fcport); | ||
| 5126 | |||
| 5112 | if (fcport->fc4f_nvme) { | 5127 | if (fcport->fc4f_nvme) { |
| 5113 | qla_nvme_register_remote(vha, fcport); | 5128 | qla_nvme_register_remote(vha, fcport); |
| 5114 | return; | 5129 | return; |
| 5115 | } | 5130 | } |
| 5116 | 5131 | ||
| 5117 | qla2x00_set_fcport_state(fcport, FCS_ONLINE); | ||
| 5118 | qla2x00_iidma_fcport(vha, fcport); | ||
| 5119 | qla24xx_update_fcport_fcp_prio(vha, fcport); | 5132 | qla24xx_update_fcport_fcp_prio(vha, fcport); |
| 5120 | 5133 | ||
| 5121 | reg_port: | 5134 | reg_port: |
| @@ -5254,8 +5267,8 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha) | |||
| 5254 | qlt_do_generation_tick(vha, &discovery_gen); | 5267 | qlt_do_generation_tick(vha, &discovery_gen); |
| 5255 | 5268 | ||
| 5256 | if (USE_ASYNC_SCAN(ha)) { | 5269 | if (USE_ASYNC_SCAN(ha)) { |
| 5257 | rval = QLA_SUCCESS; | 5270 | rval = qla24xx_async_gpnft(vha, FC4_TYPE_FCP_SCSI, |
| 5258 | rval = qla24xx_async_gpnft(vha, FC4_TYPE_FCP_SCSI); | 5271 | NULL); |
| 5259 | if (rval) | 5272 | if (rval) |
| 5260 | set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); | 5273 | set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); |
| 5261 | } else { | 5274 | } else { |
| @@ -5518,6 +5531,14 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha) | |||
| 5518 | break; | 5531 | break; |
| 5519 | } | 5532 | } |
| 5520 | 5533 | ||
| 5534 | if (fcport->fc4f_nvme) { | ||
| 5535 | if (fcport->disc_state == DSC_DELETE_PEND) { | ||
| 5536 | fcport->disc_state = DSC_GNL; | ||
| 5537 | vha->fcport_count--; | ||
| 5538 | fcport->login_succ = 0; | ||
| 5539 | } | ||
| 5540 | } | ||
| 5541 | |||
| 5521 | if (found) { | 5542 | if (found) { |
| 5522 | spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); | 5543 | spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); |
| 5523 | continue; | 5544 | continue; |
| @@ -8398,7 +8419,6 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, | |||
| 8398 | qpair->vp_idx = vp_idx; | 8419 | qpair->vp_idx = vp_idx; |
| 8399 | qpair->fw_started = ha->flags.fw_started; | 8420 | qpair->fw_started = ha->flags.fw_started; |
| 8400 | INIT_LIST_HEAD(&qpair->hints_list); | 8421 | INIT_LIST_HEAD(&qpair->hints_list); |
| 8401 | INIT_LIST_HEAD(&qpair->nvme_done_list); | ||
| 8402 | qpair->chip_reset = ha->base_qpair->chip_reset; | 8422 | qpair->chip_reset = ha->base_qpair->chip_reset; |
| 8403 | qpair->enable_class_2 = ha->base_qpair->enable_class_2; | 8423 | qpair->enable_class_2 = ha->base_qpair->enable_class_2; |
| 8404 | qpair->enable_explicit_conf = | 8424 | qpair->enable_explicit_conf = |
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h index 4d32426393c7..b7a05aebf065 100644 --- a/drivers/scsi/qla2xxx/qla_inline.h +++ b/drivers/scsi/qla2xxx/qla_inline.h | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | * qla24xx_calc_iocbs() - Determine number of Command Type 3 and | 10 | * qla24xx_calc_iocbs() - Determine number of Command Type 3 and |
| 11 | * Continuation Type 1 IOCBs to allocate. | 11 | * Continuation Type 1 IOCBs to allocate. |
| 12 | * | 12 | * |
| 13 | * @vha: HA context | ||
| 13 | * @dsds: number of data segment decriptors needed | 14 | * @dsds: number of data segment decriptors needed |
| 14 | * | 15 | * |
| 15 | * Returns the number of IOCB entries needed to store @dsds. | 16 | * Returns the number of IOCB entries needed to store @dsds. |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 8d00d559bd26..f74ff7b550b6 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | 14 | ||
| 15 | /** | 15 | /** |
| 16 | * qla2x00_get_cmd_direction() - Determine control_flag data direction. | 16 | * qla2x00_get_cmd_direction() - Determine control_flag data direction. |
| 17 | * @cmd: SCSI command | 17 | * @sp: SCSI command |
| 18 | * | 18 | * |
| 19 | * Returns the proper CF_* direction based on CDB. | 19 | * Returns the proper CF_* direction based on CDB. |
| 20 | */ | 20 | */ |
| @@ -86,7 +86,7 @@ qla2x00_calc_iocbs_64(uint16_t dsds) | |||
| 86 | 86 | ||
| 87 | /** | 87 | /** |
| 88 | * qla2x00_prep_cont_type0_iocb() - Initialize a Continuation Type 0 IOCB. | 88 | * qla2x00_prep_cont_type0_iocb() - Initialize a Continuation Type 0 IOCB. |
| 89 | * @ha: HA context | 89 | * @vha: HA context |
| 90 | * | 90 | * |
| 91 | * Returns a pointer to the Continuation Type 0 IOCB packet. | 91 | * Returns a pointer to the Continuation Type 0 IOCB packet. |
| 92 | */ | 92 | */ |
| @@ -114,7 +114,8 @@ qla2x00_prep_cont_type0_iocb(struct scsi_qla_host *vha) | |||
| 114 | 114 | ||
| 115 | /** | 115 | /** |
| 116 | * qla2x00_prep_cont_type1_iocb() - Initialize a Continuation Type 1 IOCB. | 116 | * qla2x00_prep_cont_type1_iocb() - Initialize a Continuation Type 1 IOCB. |
| 117 | * @ha: HA context | 117 | * @vha: HA context |
| 118 | * @req: request queue | ||
| 118 | * | 119 | * |
| 119 | * Returns a pointer to the continuation type 1 IOCB packet. | 120 | * Returns a pointer to the continuation type 1 IOCB packet. |
| 120 | */ | 121 | */ |
| @@ -445,6 +446,8 @@ queuing_error: | |||
| 445 | 446 | ||
| 446 | /** | 447 | /** |
| 447 | * qla2x00_start_iocbs() - Execute the IOCB command | 448 | * qla2x00_start_iocbs() - Execute the IOCB command |
| 449 | * @vha: HA context | ||
| 450 | * @req: request queue | ||
| 448 | */ | 451 | */ |
| 449 | void | 452 | void |
| 450 | qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req) | 453 | qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req) |
| @@ -486,7 +489,9 @@ qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req) | |||
| 486 | 489 | ||
| 487 | /** | 490 | /** |
| 488 | * qla2x00_marker() - Send a marker IOCB to the firmware. | 491 | * qla2x00_marker() - Send a marker IOCB to the firmware. |
| 489 | * @ha: HA context | 492 | * @vha: HA context |
| 493 | * @req: request queue | ||
| 494 | * @rsp: response queue | ||
| 490 | * @loop_id: loop ID | 495 | * @loop_id: loop ID |
| 491 | * @lun: LUN | 496 | * @lun: LUN |
| 492 | * @type: marker modifier | 497 | * @type: marker modifier |
| @@ -1190,6 +1195,8 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, | |||
| 1190 | * @sp: SRB command to process | 1195 | * @sp: SRB command to process |
| 1191 | * @cmd_pkt: Command type 3 IOCB | 1196 | * @cmd_pkt: Command type 3 IOCB |
| 1192 | * @tot_dsds: Total number of segments to transfer | 1197 | * @tot_dsds: Total number of segments to transfer |
| 1198 | * @tot_prot_dsds: | ||
| 1199 | * @fw_prot_opts: | ||
| 1193 | */ | 1200 | */ |
| 1194 | inline int | 1201 | inline int |
| 1195 | qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | 1202 | qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, |
| @@ -1203,7 +1210,6 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
| 1203 | uint32_t dif_bytes; | 1210 | uint32_t dif_bytes; |
| 1204 | uint8_t bundling = 1; | 1211 | uint8_t bundling = 1; |
| 1205 | uint16_t blk_size; | 1212 | uint16_t blk_size; |
| 1206 | uint8_t *clr_ptr; | ||
| 1207 | struct crc_context *crc_ctx_pkt = NULL; | 1213 | struct crc_context *crc_ctx_pkt = NULL; |
| 1208 | struct qla_hw_data *ha; | 1214 | struct qla_hw_data *ha; |
| 1209 | uint8_t additional_fcpcdb_len; | 1215 | uint8_t additional_fcpcdb_len; |
| @@ -1245,15 +1251,11 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
| 1245 | 1251 | ||
| 1246 | /* Allocate CRC context from global pool */ | 1252 | /* Allocate CRC context from global pool */ |
| 1247 | crc_ctx_pkt = sp->u.scmd.ctx = | 1253 | crc_ctx_pkt = sp->u.scmd.ctx = |
| 1248 | dma_pool_alloc(ha->dl_dma_pool, GFP_ATOMIC, &crc_ctx_dma); | 1254 | dma_pool_zalloc(ha->dl_dma_pool, GFP_ATOMIC, &crc_ctx_dma); |
| 1249 | 1255 | ||
| 1250 | if (!crc_ctx_pkt) | 1256 | if (!crc_ctx_pkt) |
| 1251 | goto crc_queuing_error; | 1257 | goto crc_queuing_error; |
| 1252 | 1258 | ||
| 1253 | /* Zero out CTX area. */ | ||
| 1254 | clr_ptr = (uint8_t *)crc_ctx_pkt; | ||
| 1255 | memset(clr_ptr, 0, sizeof(*crc_ctx_pkt)); | ||
| 1256 | |||
| 1257 | crc_ctx_pkt->crc_ctx_dma = crc_ctx_dma; | 1259 | crc_ctx_pkt->crc_ctx_dma = crc_ctx_dma; |
| 1258 | 1260 | ||
| 1259 | sp->flags |= SRB_CRC_CTX_DMA_VALID; | 1261 | sp->flags |= SRB_CRC_CTX_DMA_VALID; |
| @@ -3067,7 +3069,7 @@ sufficient_dsds: | |||
| 3067 | } | 3069 | } |
| 3068 | 3070 | ||
| 3069 | memset(ctx, 0, sizeof(struct ct6_dsd)); | 3071 | memset(ctx, 0, sizeof(struct ct6_dsd)); |
| 3070 | ctx->fcp_cmnd = dma_pool_alloc(ha->fcp_cmnd_dma_pool, | 3072 | ctx->fcp_cmnd = dma_pool_zalloc(ha->fcp_cmnd_dma_pool, |
| 3071 | GFP_ATOMIC, &ctx->fcp_cmnd_dma); | 3073 | GFP_ATOMIC, &ctx->fcp_cmnd_dma); |
| 3072 | if (!ctx->fcp_cmnd) { | 3074 | if (!ctx->fcp_cmnd) { |
| 3073 | ql_log(ql_log_fatal, vha, 0x3011, | 3075 | ql_log(ql_log_fatal, vha, 0x3011, |
| @@ -3120,7 +3122,6 @@ sufficient_dsds: | |||
| 3120 | host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); | 3122 | host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); |
| 3121 | 3123 | ||
| 3122 | /* build FCP_CMND IU */ | 3124 | /* build FCP_CMND IU */ |
| 3123 | memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd)); | ||
| 3124 | int_to_scsilun(cmd->device->lun, &ctx->fcp_cmnd->lun); | 3125 | int_to_scsilun(cmd->device->lun, &ctx->fcp_cmnd->lun); |
| 3125 | ctx->fcp_cmnd->additional_cdb_len = additional_cdb_len; | 3126 | ctx->fcp_cmnd->additional_cdb_len = additional_cdb_len; |
| 3126 | 3127 | ||
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 89f93ebd819d..7cacdc3408fa 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
| @@ -259,7 +259,7 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
| 259 | 259 | ||
| 260 | /** | 260 | /** |
| 261 | * qla2x00_mbx_completion() - Process mailbox command completions. | 261 | * qla2x00_mbx_completion() - Process mailbox command completions. |
| 262 | * @ha: SCSI driver HA context | 262 | * @vha: SCSI driver HA context |
| 263 | * @mb0: Mailbox0 register | 263 | * @mb0: Mailbox0 register |
| 264 | */ | 264 | */ |
| 265 | static void | 265 | static void |
| @@ -613,7 +613,8 @@ qla2x00_find_fcport_by_nportid(scsi_qla_host_t *vha, port_id_t *id, | |||
| 613 | 613 | ||
| 614 | /** | 614 | /** |
| 615 | * qla2x00_async_event() - Process aynchronous events. | 615 | * qla2x00_async_event() - Process aynchronous events. |
| 616 | * @ha: SCSI driver HA context | 616 | * @vha: SCSI driver HA context |
| 617 | * @rsp: response queue | ||
| 617 | * @mb: Mailbox registers (0 - 3) | 618 | * @mb: Mailbox registers (0 - 3) |
| 618 | */ | 619 | */ |
| 619 | void | 620 | void |
| @@ -767,7 +768,6 @@ skip_rio: | |||
| 767 | 768 | ||
| 768 | case MBA_LIP_OCCURRED: /* Loop Initialization Procedure */ | 769 | case MBA_LIP_OCCURRED: /* Loop Initialization Procedure */ |
| 769 | ha->flags.lip_ae = 1; | 770 | ha->flags.lip_ae = 1; |
| 770 | ha->flags.n2n_ae = 0; | ||
| 771 | 771 | ||
| 772 | ql_dbg(ql_dbg_async, vha, 0x5009, | 772 | ql_dbg(ql_dbg_async, vha, 0x5009, |
| 773 | "LIP occurred (%x).\n", mb[1]); | 773 | "LIP occurred (%x).\n", mb[1]); |
| @@ -811,7 +811,6 @@ skip_rio: | |||
| 811 | 811 | ||
| 812 | case MBA_LOOP_DOWN: /* Loop Down Event */ | 812 | case MBA_LOOP_DOWN: /* Loop Down Event */ |
| 813 | SAVE_TOPO(ha); | 813 | SAVE_TOPO(ha); |
| 814 | ha->flags.n2n_ae = 0; | ||
| 815 | ha->flags.lip_ae = 0; | 814 | ha->flags.lip_ae = 0; |
| 816 | ha->current_topology = 0; | 815 | ha->current_topology = 0; |
| 817 | 816 | ||
| @@ -885,7 +884,6 @@ skip_rio: | |||
| 885 | /* case MBA_DCBX_COMPLETE: */ | 884 | /* case MBA_DCBX_COMPLETE: */ |
| 886 | case MBA_POINT_TO_POINT: /* Point-to-Point */ | 885 | case MBA_POINT_TO_POINT: /* Point-to-Point */ |
| 887 | ha->flags.lip_ae = 0; | 886 | ha->flags.lip_ae = 0; |
| 888 | ha->flags.n2n_ae = 1; | ||
| 889 | 887 | ||
| 890 | if (IS_QLA2100(ha)) | 888 | if (IS_QLA2100(ha)) |
| 891 | break; | 889 | break; |
| @@ -1256,7 +1254,8 @@ global_port_update: | |||
| 1256 | 1254 | ||
| 1257 | /** | 1255 | /** |
| 1258 | * qla2x00_process_completed_request() - Process a Fast Post response. | 1256 | * qla2x00_process_completed_request() - Process a Fast Post response. |
| 1259 | * @ha: SCSI driver HA context | 1257 | * @vha: SCSI driver HA context |
| 1258 | * @req: request queue | ||
| 1260 | * @index: SRB index | 1259 | * @index: SRB index |
| 1261 | */ | 1260 | */ |
| 1262 | void | 1261 | void |
| @@ -1839,31 +1838,23 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk) | |||
| 1839 | sp->done(sp, 0); | 1838 | sp->done(sp, 0); |
| 1840 | } | 1839 | } |
| 1841 | 1840 | ||
| 1842 | static void | 1841 | static void qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, |
| 1843 | qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk) | 1842 | void *tsk, srb_t *sp) |
| 1844 | { | 1843 | { |
| 1845 | const char func[] = "NVME-IOCB"; | ||
| 1846 | fc_port_t *fcport; | 1844 | fc_port_t *fcport; |
| 1847 | srb_t *sp; | ||
| 1848 | struct srb_iocb *iocb; | 1845 | struct srb_iocb *iocb; |
| 1849 | struct sts_entry_24xx *sts = (struct sts_entry_24xx *)tsk; | 1846 | struct sts_entry_24xx *sts = (struct sts_entry_24xx *)tsk; |
| 1850 | uint16_t state_flags; | 1847 | uint16_t state_flags; |
| 1851 | struct nvmefc_fcp_req *fd; | 1848 | struct nvmefc_fcp_req *fd; |
| 1852 | uint16_t ret = 0; | 1849 | uint16_t ret = 0; |
| 1853 | struct srb_iocb *nvme; | ||
| 1854 | |||
| 1855 | sp = qla2x00_get_sp_from_handle(vha, func, req, tsk); | ||
| 1856 | if (!sp) | ||
| 1857 | return; | ||
| 1858 | 1850 | ||
| 1859 | iocb = &sp->u.iocb_cmd; | 1851 | iocb = &sp->u.iocb_cmd; |
| 1860 | fcport = sp->fcport; | 1852 | fcport = sp->fcport; |
| 1861 | iocb->u.nvme.comp_status = le16_to_cpu(sts->comp_status); | 1853 | iocb->u.nvme.comp_status = le16_to_cpu(sts->comp_status); |
| 1862 | state_flags = le16_to_cpu(sts->state_flags); | 1854 | state_flags = le16_to_cpu(sts->state_flags); |
| 1863 | fd = iocb->u.nvme.desc; | 1855 | fd = iocb->u.nvme.desc; |
| 1864 | nvme = &sp->u.iocb_cmd; | ||
| 1865 | 1856 | ||
| 1866 | if (unlikely(nvme->u.nvme.aen_op)) | 1857 | if (unlikely(iocb->u.nvme.aen_op)) |
| 1867 | atomic_dec(&sp->vha->hw->nvme_active_aen_cnt); | 1858 | atomic_dec(&sp->vha->hw->nvme_active_aen_cnt); |
| 1868 | 1859 | ||
| 1869 | /* | 1860 | /* |
| @@ -1897,42 +1888,30 @@ qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk) | |||
| 1897 | fd->transferred_length = fd->payload_length - | 1888 | fd->transferred_length = fd->payload_length - |
| 1898 | le32_to_cpu(sts->residual_len); | 1889 | le32_to_cpu(sts->residual_len); |
| 1899 | 1890 | ||
| 1900 | /* | 1891 | switch (le16_to_cpu(sts->comp_status)) { |
| 1901 | * If transport error then Failure (HBA rejects request) | 1892 | case CS_COMPLETE: |
| 1902 | * otherwise transport will handle. | 1893 | ret = QLA_SUCCESS; |
| 1903 | */ | 1894 | break; |
| 1904 | if (sts->entry_status) { | 1895 | case CS_ABORTED: |
| 1905 | ql_log(ql_log_warn, fcport->vha, 0x5038, | 1896 | case CS_RESET: |
| 1906 | "NVME-%s error - hdl=%x entry-status(%x).\n", | 1897 | case CS_PORT_UNAVAILABLE: |
| 1907 | sp->name, sp->handle, sts->entry_status); | 1898 | case CS_PORT_LOGGED_OUT: |
| 1899 | case CS_PORT_BUSY: | ||
| 1900 | ql_log(ql_log_warn, fcport->vha, 0x5060, | ||
| 1901 | "NVME-%s ERR Handling - hdl=%x completion status(%x) resid=%x ox_id=%x\n", | ||
| 1902 | sp->name, sp->handle, sts->comp_status, | ||
| 1903 | le32_to_cpu(sts->residual_len), sts->ox_id); | ||
| 1904 | fd->transferred_length = 0; | ||
| 1905 | iocb->u.nvme.rsp_pyld_len = 0; | ||
| 1906 | ret = QLA_ABORTED; | ||
| 1907 | break; | ||
| 1908 | default: | ||
| 1909 | ql_log(ql_log_warn, fcport->vha, 0x5060, | ||
| 1910 | "NVME-%s error - hdl=%x completion status(%x) resid=%x ox_id=%x\n", | ||
| 1911 | sp->name, sp->handle, sts->comp_status, | ||
| 1912 | le32_to_cpu(sts->residual_len), sts->ox_id); | ||
| 1908 | ret = QLA_FUNCTION_FAILED; | 1913 | ret = QLA_FUNCTION_FAILED; |
| 1909 | } else { | 1914 | break; |
| 1910 | switch (le16_to_cpu(sts->comp_status)) { | ||
| 1911 | case CS_COMPLETE: | ||
| 1912 | ret = 0; | ||
| 1913 | break; | ||
| 1914 | |||
| 1915 | case CS_ABORTED: | ||
| 1916 | case CS_RESET: | ||
| 1917 | case CS_PORT_UNAVAILABLE: | ||
| 1918 | case CS_PORT_LOGGED_OUT: | ||
| 1919 | case CS_PORT_BUSY: | ||
| 1920 | ql_log(ql_log_warn, fcport->vha, 0x5060, | ||
| 1921 | "NVME-%s ERR Handling - hdl=%x completion status(%x) resid=%x ox_id=%x\n", | ||
| 1922 | sp->name, sp->handle, sts->comp_status, | ||
| 1923 | le32_to_cpu(sts->residual_len), sts->ox_id); | ||
| 1924 | fd->transferred_length = fd->payload_length; | ||
| 1925 | ret = QLA_ABORTED; | ||
| 1926 | break; | ||
| 1927 | |||
| 1928 | default: | ||
| 1929 | ql_log(ql_log_warn, fcport->vha, 0x5060, | ||
| 1930 | "NVME-%s error - hdl=%x completion status(%x) resid=%x ox_id=%x\n", | ||
| 1931 | sp->name, sp->handle, sts->comp_status, | ||
| 1932 | le32_to_cpu(sts->residual_len), sts->ox_id); | ||
| 1933 | ret = QLA_FUNCTION_FAILED; | ||
| 1934 | break; | ||
| 1935 | } | ||
| 1936 | } | 1915 | } |
| 1937 | sp->done(sp, ret); | 1916 | sp->done(sp, ret); |
| 1938 | } | 1917 | } |
| @@ -1970,7 +1949,7 @@ static void qla_ctrlvp_completed(scsi_qla_host_t *vha, struct req_que *req, | |||
| 1970 | 1949 | ||
| 1971 | /** | 1950 | /** |
| 1972 | * qla2x00_process_response_queue() - Process response queue entries. | 1951 | * qla2x00_process_response_queue() - Process response queue entries. |
| 1973 | * @ha: SCSI driver HA context | 1952 | * @rsp: response queue |
| 1974 | */ | 1953 | */ |
| 1975 | void | 1954 | void |
| 1976 | qla2x00_process_response_queue(struct rsp_que *rsp) | 1955 | qla2x00_process_response_queue(struct rsp_que *rsp) |
| @@ -2374,7 +2353,8 @@ done: | |||
| 2374 | 2353 | ||
| 2375 | /** | 2354 | /** |
| 2376 | * qla2x00_status_entry() - Process a Status IOCB entry. | 2355 | * qla2x00_status_entry() - Process a Status IOCB entry. |
| 2377 | * @ha: SCSI driver HA context | 2356 | * @vha: SCSI driver HA context |
| 2357 | * @rsp: response queue | ||
| 2378 | * @pkt: Entry pointer | 2358 | * @pkt: Entry pointer |
| 2379 | */ | 2359 | */ |
| 2380 | static void | 2360 | static void |
| @@ -2459,7 +2439,8 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) | |||
| 2459 | 2439 | ||
| 2460 | /* NVME completion. */ | 2440 | /* NVME completion. */ |
| 2461 | if (sp->type == SRB_NVME_CMD) { | 2441 | if (sp->type == SRB_NVME_CMD) { |
| 2462 | qla24xx_nvme_iocb_entry(vha, req, pkt); | 2442 | req->outstanding_cmds[handle] = NULL; |
| 2443 | qla24xx_nvme_iocb_entry(vha, req, pkt, sp); | ||
| 2463 | return; | 2444 | return; |
| 2464 | } | 2445 | } |
| 2465 | 2446 | ||
| @@ -2751,7 +2732,7 @@ out: | |||
| 2751 | 2732 | ||
| 2752 | /** | 2733 | /** |
| 2753 | * qla2x00_status_cont_entry() - Process a Status Continuations entry. | 2734 | * qla2x00_status_cont_entry() - Process a Status Continuations entry. |
| 2754 | * @ha: SCSI driver HA context | 2735 | * @rsp: response queue |
| 2755 | * @pkt: Entry pointer | 2736 | * @pkt: Entry pointer |
| 2756 | * | 2737 | * |
| 2757 | * Extended sense data. | 2738 | * Extended sense data. |
| @@ -2809,7 +2790,8 @@ qla2x00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt) | |||
| 2809 | 2790 | ||
| 2810 | /** | 2791 | /** |
| 2811 | * qla2x00_error_entry() - Process an error entry. | 2792 | * qla2x00_error_entry() - Process an error entry. |
| 2812 | * @ha: SCSI driver HA context | 2793 | * @vha: SCSI driver HA context |
| 2794 | * @rsp: response queue | ||
| 2813 | * @pkt: Entry pointer | 2795 | * @pkt: Entry pointer |
| 2814 | * return : 1=allow further error analysis. 0=no additional error analysis. | 2796 | * return : 1=allow further error analysis. 0=no additional error analysis. |
| 2815 | */ | 2797 | */ |
| @@ -2868,7 +2850,7 @@ fatal: | |||
| 2868 | 2850 | ||
| 2869 | /** | 2851 | /** |
| 2870 | * qla24xx_mbx_completion() - Process mailbox command completions. | 2852 | * qla24xx_mbx_completion() - Process mailbox command completions. |
| 2871 | * @ha: SCSI driver HA context | 2853 | * @vha: SCSI driver HA context |
| 2872 | * @mb0: Mailbox0 register | 2854 | * @mb0: Mailbox0 register |
| 2873 | */ | 2855 | */ |
| 2874 | static void | 2856 | static void |
| @@ -2937,7 +2919,8 @@ void qla24xx_nvme_ls4_iocb(struct scsi_qla_host *vha, | |||
| 2937 | 2919 | ||
| 2938 | /** | 2920 | /** |
| 2939 | * qla24xx_process_response_queue() - Process response queue entries. | 2921 | * qla24xx_process_response_queue() - Process response queue entries. |
| 2940 | * @ha: SCSI driver HA context | 2922 | * @vha: SCSI driver HA context |
| 2923 | * @rsp: response queue | ||
| 2941 | */ | 2924 | */ |
| 2942 | void qla24xx_process_response_queue(struct scsi_qla_host *vha, | 2925 | void qla24xx_process_response_queue(struct scsi_qla_host *vha, |
| 2943 | struct rsp_que *rsp) | 2926 | struct rsp_que *rsp) |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 7397aeddd96c..5db0262d5c94 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
| @@ -503,11 +503,19 @@ mbx_done: | |||
| 503 | } | 503 | } |
| 504 | pr_warn(" cmd=%x ****\n", command); | 504 | pr_warn(" cmd=%x ****\n", command); |
| 505 | } | 505 | } |
| 506 | ql_dbg(ql_dbg_mbx, vha, 0x1198, | 506 | if (IS_FWI2_CAPABLE(ha) && !(IS_P3P_TYPE(ha))) { |
| 507 | "host_status=%#x intr_ctrl=%#x intr_status=%#x\n", | 507 | ql_dbg(ql_dbg_mbx, vha, 0x1198, |
| 508 | RD_REG_DWORD(®->isp24.host_status), | 508 | "host_status=%#x intr_ctrl=%#x intr_status=%#x\n", |
| 509 | RD_REG_DWORD(®->isp24.ictrl), | 509 | RD_REG_DWORD(®->isp24.host_status), |
| 510 | RD_REG_DWORD(®->isp24.istatus)); | 510 | RD_REG_DWORD(®->isp24.ictrl), |
| 511 | RD_REG_DWORD(®->isp24.istatus)); | ||
| 512 | } else { | ||
| 513 | ql_dbg(ql_dbg_mbx, vha, 0x1206, | ||
| 514 | "ctrl_status=%#x ictrl=%#x istatus=%#x\n", | ||
| 515 | RD_REG_WORD(®->isp.ctrl_status), | ||
| 516 | RD_REG_WORD(®->isp.ictrl), | ||
| 517 | RD_REG_WORD(®->isp.istatus)); | ||
| 518 | } | ||
| 511 | } else { | 519 | } else { |
| 512 | ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__); | 520 | ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__); |
| 513 | } | 521 | } |
| @@ -1025,9 +1033,12 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha) | |||
| 1025 | * FW supports nvme and driver load parameter requested nvme. | 1033 | * FW supports nvme and driver load parameter requested nvme. |
| 1026 | * BIT 26 of fw_attributes indicates NVMe support. | 1034 | * BIT 26 of fw_attributes indicates NVMe support. |
| 1027 | */ | 1035 | */ |
| 1028 | if ((ha->fw_attributes_h & 0x400) && ql2xnvmeenable) | 1036 | if ((ha->fw_attributes_h & 0x400) && ql2xnvmeenable) { |
| 1029 | vha->flags.nvme_enabled = 1; | 1037 | vha->flags.nvme_enabled = 1; |
| 1030 | 1038 | ql_log(ql_log_info, vha, 0xd302, | |
| 1039 | "%s: FC-NVMe is Enabled (0x%x)\n", | ||
| 1040 | __func__, ha->fw_attributes_h); | ||
| 1041 | } | ||
| 1031 | } | 1042 | } |
| 1032 | 1043 | ||
| 1033 | if (IS_QLA27XX(ha)) { | 1044 | if (IS_QLA27XX(ha)) { |
| @@ -3385,7 +3396,10 @@ qla8044_read_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t *data) | |||
| 3385 | 3396 | ||
| 3386 | /** | 3397 | /** |
| 3387 | * qla2x00_set_serdes_params() - | 3398 | * qla2x00_set_serdes_params() - |
| 3388 | * @ha: HA context | 3399 | * @vha: HA context |
| 3400 | * @sw_em_1g: | ||
| 3401 | * @sw_em_2g: | ||
| 3402 | * @sw_em_4g: | ||
| 3389 | * | 3403 | * |
| 3390 | * Returns | 3404 | * Returns |
| 3391 | */ | 3405 | */ |
| @@ -3744,6 +3758,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, | |||
| 3744 | id.b.area = rptid_entry->port_id[1]; | 3758 | id.b.area = rptid_entry->port_id[1]; |
| 3745 | id.b.al_pa = rptid_entry->port_id[0]; | 3759 | id.b.al_pa = rptid_entry->port_id[0]; |
| 3746 | id.b.rsvd_1 = 0; | 3760 | id.b.rsvd_1 = 0; |
| 3761 | ha->flags.n2n_ae = 0; | ||
| 3747 | 3762 | ||
| 3748 | if (rptid_entry->format == 0) { | 3763 | if (rptid_entry->format == 0) { |
| 3749 | /* loop */ | 3764 | /* loop */ |
| @@ -3796,6 +3811,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, | |||
| 3796 | set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags); | 3811 | set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags); |
| 3797 | set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags); | 3812 | set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags); |
| 3798 | set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags); | 3813 | set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags); |
| 3814 | ha->flags.n2n_ae = 1; | ||
| 3799 | return; | 3815 | return; |
| 3800 | } | 3816 | } |
| 3801 | 3817 | ||
| @@ -3872,6 +3888,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, | |||
| 3872 | vha->d_id.b.area = rptid_entry->port_id[1]; | 3888 | vha->d_id.b.area = rptid_entry->port_id[1]; |
| 3873 | vha->d_id.b.al_pa = rptid_entry->port_id[0]; | 3889 | vha->d_id.b.al_pa = rptid_entry->port_id[0]; |
| 3874 | 3890 | ||
| 3891 | ha->flags.n2n_ae = 1; | ||
| 3875 | spin_lock_irqsave(&ha->vport_slock, flags); | 3892 | spin_lock_irqsave(&ha->vport_slock, flags); |
| 3876 | qlt_update_vp_map(vha, SET_AL_PA); | 3893 | qlt_update_vp_map(vha, SET_AL_PA); |
| 3877 | spin_unlock_irqrestore(&ha->vport_slock, flags); | 3894 | spin_unlock_irqrestore(&ha->vport_slock, flags); |
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index e965b16f21e3..da85cd89639f 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
| @@ -778,18 +778,12 @@ static void qla_do_work(struct work_struct *work) | |||
| 778 | struct qla_qpair *qpair = container_of(work, struct qla_qpair, q_work); | 778 | struct qla_qpair *qpair = container_of(work, struct qla_qpair, q_work); |
| 779 | struct scsi_qla_host *vha; | 779 | struct scsi_qla_host *vha; |
| 780 | struct qla_hw_data *ha = qpair->hw; | 780 | struct qla_hw_data *ha = qpair->hw; |
| 781 | struct srb_iocb *nvme, *nxt_nvme; | ||
| 782 | 781 | ||
| 783 | spin_lock_irqsave(&qpair->qp_lock, flags); | 782 | spin_lock_irqsave(&qpair->qp_lock, flags); |
| 784 | vha = pci_get_drvdata(ha->pdev); | 783 | vha = pci_get_drvdata(ha->pdev); |
| 785 | qla24xx_process_response_queue(vha, qpair->rsp); | 784 | qla24xx_process_response_queue(vha, qpair->rsp); |
| 786 | spin_unlock_irqrestore(&qpair->qp_lock, flags); | 785 | spin_unlock_irqrestore(&qpair->qp_lock, flags); |
| 787 | 786 | ||
| 788 | list_for_each_entry_safe(nvme, nxt_nvme, &qpair->nvme_done_list, | ||
| 789 | u.nvme.entry) { | ||
| 790 | list_del_init(&nvme->u.nvme.entry); | ||
| 791 | qla_nvme_cmpl_io(nvme); | ||
| 792 | } | ||
| 793 | } | 787 | } |
| 794 | 788 | ||
| 795 | /* create response queue */ | 789 | /* create response queue */ |
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c index d5da3981cefe..7113acf42ff3 100644 --- a/drivers/scsi/qla2xxx/qla_mr.c +++ b/drivers/scsi/qla2xxx/qla_mr.c | |||
| @@ -490,7 +490,7 @@ qlafx00_mbx_reg_test(scsi_qla_host_t *vha) | |||
| 490 | 490 | ||
| 491 | /** | 491 | /** |
| 492 | * qlafx00_pci_config() - Setup ISPFx00 PCI configuration registers. | 492 | * qlafx00_pci_config() - Setup ISPFx00 PCI configuration registers. |
| 493 | * @ha: HA context | 493 | * @vha: HA context |
| 494 | * | 494 | * |
| 495 | * Returns 0 on success. | 495 | * Returns 0 on success. |
| 496 | */ | 496 | */ |
| @@ -519,9 +519,9 @@ qlafx00_pci_config(scsi_qla_host_t *vha) | |||
| 519 | 519 | ||
| 520 | /** | 520 | /** |
| 521 | * qlafx00_warm_reset() - Perform warm reset of iSA(CPUs being reset on SOC). | 521 | * qlafx00_warm_reset() - Perform warm reset of iSA(CPUs being reset on SOC). |
| 522 | * @ha: HA context | 522 | * @vha: HA context |
| 523 | * | 523 | * |
| 524 | */ | 524 | */ |
| 525 | static inline void | 525 | static inline void |
| 526 | qlafx00_soc_cpu_reset(scsi_qla_host_t *vha) | 526 | qlafx00_soc_cpu_reset(scsi_qla_host_t *vha) |
| 527 | { | 527 | { |
| @@ -625,7 +625,7 @@ qlafx00_soc_cpu_reset(scsi_qla_host_t *vha) | |||
| 625 | 625 | ||
| 626 | /** | 626 | /** |
| 627 | * qlafx00_soft_reset() - Soft Reset ISPFx00. | 627 | * qlafx00_soft_reset() - Soft Reset ISPFx00. |
| 628 | * @ha: HA context | 628 | * @vha: HA context |
| 629 | * | 629 | * |
| 630 | * Returns 0 on success. | 630 | * Returns 0 on success. |
| 631 | */ | 631 | */ |
| @@ -644,7 +644,7 @@ qlafx00_soft_reset(scsi_qla_host_t *vha) | |||
| 644 | 644 | ||
| 645 | /** | 645 | /** |
| 646 | * qlafx00_chip_diag() - Test ISPFx00 for proper operation. | 646 | * qlafx00_chip_diag() - Test ISPFx00 for proper operation. |
| 647 | * @ha: HA context | 647 | * @vha: HA context |
| 648 | * | 648 | * |
| 649 | * Returns 0 on success. | 649 | * Returns 0 on success. |
| 650 | */ | 650 | */ |
| @@ -1408,7 +1408,7 @@ qlafx00_abort_isp_cleanup(scsi_qla_host_t *vha, bool critemp) | |||
| 1408 | 1408 | ||
| 1409 | /** | 1409 | /** |
| 1410 | * qlafx00_init_response_q_entries() - Initializes response queue entries. | 1410 | * qlafx00_init_response_q_entries() - Initializes response queue entries. |
| 1411 | * @ha: HA context | 1411 | * @rsp: response queue |
| 1412 | * | 1412 | * |
| 1413 | * Beginning of request ring has initialization control block already built | 1413 | * Beginning of request ring has initialization control block already built |
| 1414 | * by nvram config routine. | 1414 | * by nvram config routine. |
| @@ -2269,7 +2269,8 @@ qlafx00_ioctl_iosb_entry(scsi_qla_host_t *vha, struct req_que *req, | |||
| 2269 | 2269 | ||
| 2270 | /** | 2270 | /** |
| 2271 | * qlafx00_status_entry() - Process a Status IOCB entry. | 2271 | * qlafx00_status_entry() - Process a Status IOCB entry. |
| 2272 | * @ha: SCSI driver HA context | 2272 | * @vha: SCSI driver HA context |
| 2273 | * @rsp: response queue | ||
| 2273 | * @pkt: Entry pointer | 2274 | * @pkt: Entry pointer |
| 2274 | */ | 2275 | */ |
| 2275 | static void | 2276 | static void |
| @@ -2542,7 +2543,7 @@ check_scsi_status: | |||
| 2542 | 2543 | ||
| 2543 | /** | 2544 | /** |
| 2544 | * qlafx00_status_cont_entry() - Process a Status Continuations entry. | 2545 | * qlafx00_status_cont_entry() - Process a Status Continuations entry. |
| 2545 | * @ha: SCSI driver HA context | 2546 | * @rsp: response queue |
| 2546 | * @pkt: Entry pointer | 2547 | * @pkt: Entry pointer |
| 2547 | * | 2548 | * |
| 2548 | * Extended sense data. | 2549 | * Extended sense data. |
| @@ -2620,7 +2621,9 @@ qlafx00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt) | |||
| 2620 | 2621 | ||
| 2621 | /** | 2622 | /** |
| 2622 | * qlafx00_multistatus_entry() - Process Multi response queue entries. | 2623 | * qlafx00_multistatus_entry() - Process Multi response queue entries. |
| 2623 | * @ha: SCSI driver HA context | 2624 | * @vha: SCSI driver HA context |
| 2625 | * @rsp: response queue | ||
| 2626 | * @pkt: | ||
| 2624 | */ | 2627 | */ |
| 2625 | static void | 2628 | static void |
| 2626 | qlafx00_multistatus_entry(struct scsi_qla_host *vha, | 2629 | qlafx00_multistatus_entry(struct scsi_qla_host *vha, |
| @@ -2674,8 +2677,11 @@ qlafx00_multistatus_entry(struct scsi_qla_host *vha, | |||
| 2674 | 2677 | ||
| 2675 | /** | 2678 | /** |
| 2676 | * qlafx00_error_entry() - Process an error entry. | 2679 | * qlafx00_error_entry() - Process an error entry. |
| 2677 | * @ha: SCSI driver HA context | 2680 | * @vha: SCSI driver HA context |
| 2681 | * @rsp: response queue | ||
| 2678 | * @pkt: Entry pointer | 2682 | * @pkt: Entry pointer |
| 2683 | * @estatus: | ||
| 2684 | * @etype: | ||
| 2679 | */ | 2685 | */ |
| 2680 | static void | 2686 | static void |
| 2681 | qlafx00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, | 2687 | qlafx00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, |
| @@ -2705,7 +2711,8 @@ qlafx00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, | |||
| 2705 | 2711 | ||
| 2706 | /** | 2712 | /** |
| 2707 | * qlafx00_process_response_queue() - Process response queue entries. | 2713 | * qlafx00_process_response_queue() - Process response queue entries. |
| 2708 | * @ha: SCSI driver HA context | 2714 | * @vha: SCSI driver HA context |
| 2715 | * @rsp: response queue | ||
| 2709 | */ | 2716 | */ |
| 2710 | static void | 2717 | static void |
| 2711 | qlafx00_process_response_queue(struct scsi_qla_host *vha, | 2718 | qlafx00_process_response_queue(struct scsi_qla_host *vha, |
| @@ -2781,7 +2788,7 @@ qlafx00_process_response_queue(struct scsi_qla_host *vha, | |||
| 2781 | 2788 | ||
| 2782 | /** | 2789 | /** |
| 2783 | * qlafx00_async_event() - Process aynchronous events. | 2790 | * qlafx00_async_event() - Process aynchronous events. |
| 2784 | * @ha: SCSI driver HA context | 2791 | * @vha: SCSI driver HA context |
| 2785 | */ | 2792 | */ |
| 2786 | static void | 2793 | static void |
| 2787 | qlafx00_async_event(scsi_qla_host_t *vha) | 2794 | qlafx00_async_event(scsi_qla_host_t *vha) |
| @@ -2857,10 +2864,9 @@ qlafx00_async_event(scsi_qla_host_t *vha) | |||
| 2857 | } | 2864 | } |
| 2858 | 2865 | ||
| 2859 | /** | 2866 | /** |
| 2860 | * | ||
| 2861 | * qlafx00x_mbx_completion() - Process mailbox command completions. | 2867 | * qlafx00x_mbx_completion() - Process mailbox command completions. |
| 2862 | * @ha: SCSI driver HA context | 2868 | * @vha: SCSI driver HA context |
| 2863 | * @mb16: Mailbox16 register | 2869 | * @mb0: |
| 2864 | */ | 2870 | */ |
| 2865 | static void | 2871 | static void |
| 2866 | qlafx00_mbx_completion(scsi_qla_host_t *vha, uint32_t mb0) | 2872 | qlafx00_mbx_completion(scsi_qla_host_t *vha, uint32_t mb0) |
diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c index 6b33a1f24f56..c5a963c2c86e 100644 --- a/drivers/scsi/qla2xxx/qla_nvme.c +++ b/drivers/scsi/qla2xxx/qla_nvme.c | |||
| @@ -16,15 +16,13 @@ static void qla_nvme_unregister_remote_port(struct work_struct *); | |||
| 16 | 16 | ||
| 17 | int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport) | 17 | int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport) |
| 18 | { | 18 | { |
| 19 | struct nvme_rport *rport; | 19 | struct qla_nvme_rport *rport; |
| 20 | struct nvme_fc_port_info req; | ||
| 20 | int ret; | 21 | int ret; |
| 21 | 22 | ||
| 22 | if (!IS_ENABLED(CONFIG_NVME_FC)) | 23 | if (!IS_ENABLED(CONFIG_NVME_FC)) |
| 23 | return 0; | 24 | return 0; |
| 24 | 25 | ||
| 25 | if (fcport->nvme_flag & NVME_FLAG_REGISTERED) | ||
| 26 | return 0; | ||
| 27 | |||
| 28 | if (!vha->flags.nvme_enabled) { | 26 | if (!vha->flags.nvme_enabled) { |
| 29 | ql_log(ql_log_info, vha, 0x2100, | 27 | ql_log(ql_log_info, vha, 0x2100, |
| 30 | "%s: Not registering target since Host NVME is not enabled\n", | 28 | "%s: Not registering target since Host NVME is not enabled\n", |
| @@ -33,38 +31,36 @@ int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport) | |||
| 33 | } | 31 | } |
| 34 | 32 | ||
| 35 | if (!(fcport->nvme_prli_service_param & | 33 | if (!(fcport->nvme_prli_service_param & |
| 36 | (NVME_PRLI_SP_TARGET | NVME_PRLI_SP_DISCOVERY))) | 34 | (NVME_PRLI_SP_TARGET | NVME_PRLI_SP_DISCOVERY)) || |
| 35 | (fcport->nvme_flag & NVME_FLAG_REGISTERED)) | ||
| 37 | return 0; | 36 | return 0; |
| 38 | 37 | ||
| 39 | INIT_WORK(&fcport->nvme_del_work, qla_nvme_unregister_remote_port); | 38 | INIT_WORK(&fcport->nvme_del_work, qla_nvme_unregister_remote_port); |
| 40 | rport = kzalloc(sizeof(*rport), GFP_KERNEL); | 39 | fcport->nvme_flag &= ~NVME_FLAG_RESETTING; |
| 41 | if (!rport) { | ||
| 42 | ql_log(ql_log_warn, vha, 0x2101, | ||
| 43 | "%s: unable to alloc memory\n", __func__); | ||
| 44 | return -ENOMEM; | ||
| 45 | } | ||
| 46 | 40 | ||
| 47 | rport->req.port_name = wwn_to_u64(fcport->port_name); | 41 | memset(&req, 0, sizeof(struct nvme_fc_port_info)); |
| 48 | rport->req.node_name = wwn_to_u64(fcport->node_name); | 42 | req.port_name = wwn_to_u64(fcport->port_name); |
| 49 | rport->req.port_role = 0; | 43 | req.node_name = wwn_to_u64(fcport->node_name); |
| 44 | req.port_role = 0; | ||
| 45 | req.dev_loss_tmo = NVME_FC_DEV_LOSS_TMO; | ||
| 50 | 46 | ||
| 51 | if (fcport->nvme_prli_service_param & NVME_PRLI_SP_INITIATOR) | 47 | if (fcport->nvme_prli_service_param & NVME_PRLI_SP_INITIATOR) |
| 52 | rport->req.port_role = FC_PORT_ROLE_NVME_INITIATOR; | 48 | req.port_role = FC_PORT_ROLE_NVME_INITIATOR; |
| 53 | 49 | ||
| 54 | if (fcport->nvme_prli_service_param & NVME_PRLI_SP_TARGET) | 50 | if (fcport->nvme_prli_service_param & NVME_PRLI_SP_TARGET) |
| 55 | rport->req.port_role |= FC_PORT_ROLE_NVME_TARGET; | 51 | req.port_role |= FC_PORT_ROLE_NVME_TARGET; |
| 56 | 52 | ||
| 57 | if (fcport->nvme_prli_service_param & NVME_PRLI_SP_DISCOVERY) | 53 | if (fcport->nvme_prli_service_param & NVME_PRLI_SP_DISCOVERY) |
| 58 | rport->req.port_role |= FC_PORT_ROLE_NVME_DISCOVERY; | 54 | req.port_role |= FC_PORT_ROLE_NVME_DISCOVERY; |
| 59 | 55 | ||
| 60 | rport->req.port_id = fcport->d_id.b24; | 56 | req.port_id = fcport->d_id.b24; |
| 61 | 57 | ||
| 62 | ql_log(ql_log_info, vha, 0x2102, | 58 | ql_log(ql_log_info, vha, 0x2102, |
| 63 | "%s: traddr=nn-0x%016llx:pn-0x%016llx PortID:%06x\n", | 59 | "%s: traddr=nn-0x%016llx:pn-0x%016llx PortID:%06x\n", |
| 64 | __func__, rport->req.node_name, rport->req.port_name, | 60 | __func__, req.node_name, req.port_name, |
| 65 | rport->req.port_id); | 61 | req.port_id); |
| 66 | 62 | ||
| 67 | ret = nvme_fc_register_remoteport(vha->nvme_local_port, &rport->req, | 63 | ret = nvme_fc_register_remoteport(vha->nvme_local_port, &req, |
| 68 | &fcport->nvme_remote_port); | 64 | &fcport->nvme_remote_port); |
| 69 | if (ret) { | 65 | if (ret) { |
| 70 | ql_log(ql_log_warn, vha, 0x212e, | 66 | ql_log(ql_log_warn, vha, 0x212e, |
| @@ -73,10 +69,11 @@ int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport) | |||
| 73 | return ret; | 69 | return ret; |
| 74 | } | 70 | } |
| 75 | 71 | ||
| 76 | fcport->nvme_remote_port->private = fcport; | 72 | rport = fcport->nvme_remote_port->private; |
| 77 | fcport->nvme_flag |= NVME_FLAG_REGISTERED; | ||
| 78 | rport->fcport = fcport; | 73 | rport->fcport = fcport; |
| 79 | list_add_tail(&rport->list, &vha->nvme_rport_list); | 74 | list_add_tail(&rport->list, &vha->nvme_rport_list); |
| 75 | |||
| 76 | fcport->nvme_flag |= NVME_FLAG_REGISTERED; | ||
| 80 | return 0; | 77 | return 0; |
| 81 | } | 78 | } |
| 82 | 79 | ||
| @@ -113,8 +110,6 @@ static int qla_nvme_alloc_queue(struct nvme_fc_local_port *lport, | |||
| 113 | return 0; | 110 | return 0; |
| 114 | } | 111 | } |
| 115 | 112 | ||
| 116 | ql_log(ql_log_warn, vha, 0xffff, | ||
| 117 | "allocating q for idx=%x w/o cpu mask\n", qidx); | ||
| 118 | qpair = qla2xxx_create_qpair(vha, 5, vha->vp_idx, true); | 113 | qpair = qla2xxx_create_qpair(vha, 5, vha->vp_idx, true); |
| 119 | if (qpair == NULL) { | 114 | if (qpair == NULL) { |
| 120 | ql_log(ql_log_warn, vha, 0x2122, | 115 | ql_log(ql_log_warn, vha, 0x2122, |
| @@ -154,16 +149,6 @@ static void qla_nvme_sp_ls_done(void *ptr, int res) | |||
| 154 | qla2x00_rel_sp(sp); | 149 | qla2x00_rel_sp(sp); |
| 155 | } | 150 | } |
| 156 | 151 | ||
| 157 | void qla_nvme_cmpl_io(struct srb_iocb *nvme) | ||
| 158 | { | ||
| 159 | srb_t *sp; | ||
| 160 | struct nvmefc_fcp_req *fd = nvme->u.nvme.desc; | ||
| 161 | |||
| 162 | sp = container_of(nvme, srb_t, u.iocb_cmd); | ||
| 163 | fd->done(fd); | ||
| 164 | qla2xxx_rel_qpair_sp(sp->qpair, sp); | ||
| 165 | } | ||
| 166 | |||
| 167 | static void qla_nvme_sp_done(void *ptr, int res) | 152 | static void qla_nvme_sp_done(void *ptr, int res) |
| 168 | { | 153 | { |
| 169 | srb_t *sp = ptr; | 154 | srb_t *sp = ptr; |
| @@ -176,36 +161,42 @@ static void qla_nvme_sp_done(void *ptr, int res) | |||
| 176 | if (!atomic_dec_and_test(&sp->ref_count)) | 161 | if (!atomic_dec_and_test(&sp->ref_count)) |
| 177 | return; | 162 | return; |
| 178 | 163 | ||
| 179 | if (!(sp->fcport->nvme_flag & NVME_FLAG_REGISTERED)) | 164 | if (res == QLA_SUCCESS) |
| 180 | goto rel; | ||
| 181 | |||
| 182 | if (unlikely(res == QLA_FUNCTION_FAILED)) | ||
| 183 | fd->status = NVME_SC_INTERNAL; | ||
| 184 | else | ||
| 185 | fd->status = 0; | 165 | fd->status = 0; |
| 166 | else | ||
| 167 | fd->status = NVME_SC_INTERNAL; | ||
| 186 | 168 | ||
| 187 | fd->rcv_rsplen = nvme->u.nvme.rsp_pyld_len; | 169 | fd->rcv_rsplen = nvme->u.nvme.rsp_pyld_len; |
| 188 | list_add_tail(&nvme->u.nvme.entry, &sp->qpair->nvme_done_list); | 170 | fd->done(fd); |
| 189 | return; | ||
| 190 | rel: | ||
| 191 | qla2xxx_rel_qpair_sp(sp->qpair, sp); | 171 | qla2xxx_rel_qpair_sp(sp->qpair, sp); |
| 172 | |||
| 173 | return; | ||
| 192 | } | 174 | } |
| 193 | 175 | ||
| 194 | static void qla_nvme_ls_abort(struct nvme_fc_local_port *lport, | 176 | static void qla_nvme_abort_work(struct work_struct *work) |
| 195 | struct nvme_fc_remote_port *rport, struct nvmefc_ls_req *fd) | ||
| 196 | { | 177 | { |
| 197 | struct nvme_private *priv = fd->private; | 178 | struct nvme_private *priv = |
| 198 | fc_port_t *fcport = rport->private; | 179 | container_of(work, struct nvme_private, abort_work); |
| 199 | srb_t *sp = priv->sp; | 180 | srb_t *sp = priv->sp; |
| 200 | int rval; | 181 | fc_port_t *fcport = sp->fcport; |
| 201 | struct qla_hw_data *ha = fcport->vha->hw; | 182 | struct qla_hw_data *ha = fcport->vha->hw; |
| 183 | int rval; | ||
| 202 | 184 | ||
| 203 | rval = ha->isp_ops->abort_command(sp); | 185 | rval = ha->isp_ops->abort_command(sp); |
| 204 | 186 | ||
| 205 | ql_dbg(ql_dbg_io, fcport->vha, 0x212b, | 187 | ql_dbg(ql_dbg_io, fcport->vha, 0x212b, |
| 206 | "%s: %s LS command for sp=%p on fcport=%p rval=%x\n", __func__, | 188 | "%s: %s command for sp=%p, handle=%x on fcport=%p rval=%x\n", |
| 207 | (rval != QLA_SUCCESS) ? "Failed to abort" : "Aborted", | 189 | __func__, (rval != QLA_SUCCESS) ? "Failed to abort" : "Aborted", |
| 208 | sp, fcport, rval); | 190 | sp, sp->handle, fcport, rval); |
| 191 | } | ||
| 192 | |||
| 193 | static void qla_nvme_ls_abort(struct nvme_fc_local_port *lport, | ||
| 194 | struct nvme_fc_remote_port *rport, struct nvmefc_ls_req *fd) | ||
| 195 | { | ||
| 196 | struct nvme_private *priv = fd->private; | ||
| 197 | |||
| 198 | INIT_WORK(&priv->abort_work, qla_nvme_abort_work); | ||
| 199 | schedule_work(&priv->abort_work); | ||
| 209 | } | 200 | } |
| 210 | 201 | ||
| 211 | static void qla_nvme_ls_complete(struct work_struct *work) | 202 | static void qla_nvme_ls_complete(struct work_struct *work) |
| @@ -220,7 +211,8 @@ static void qla_nvme_ls_complete(struct work_struct *work) | |||
| 220 | static int qla_nvme_ls_req(struct nvme_fc_local_port *lport, | 211 | static int qla_nvme_ls_req(struct nvme_fc_local_port *lport, |
| 221 | struct nvme_fc_remote_port *rport, struct nvmefc_ls_req *fd) | 212 | struct nvme_fc_remote_port *rport, struct nvmefc_ls_req *fd) |
| 222 | { | 213 | { |
| 223 | fc_port_t *fcport = rport->private; | 214 | struct qla_nvme_rport *qla_rport = rport->private; |
| 215 | fc_port_t *fcport = qla_rport->fcport; | ||
| 224 | struct srb_iocb *nvme; | 216 | struct srb_iocb *nvme; |
| 225 | struct nvme_private *priv = fd->private; | 217 | struct nvme_private *priv = fd->private; |
| 226 | struct scsi_qla_host *vha; | 218 | struct scsi_qla_host *vha; |
| @@ -228,9 +220,6 @@ static int qla_nvme_ls_req(struct nvme_fc_local_port *lport, | |||
| 228 | struct qla_hw_data *ha; | 220 | struct qla_hw_data *ha; |
| 229 | srb_t *sp; | 221 | srb_t *sp; |
| 230 | 222 | ||
| 231 | if (!(fcport->nvme_flag & NVME_FLAG_REGISTERED)) | ||
| 232 | return rval; | ||
| 233 | |||
| 234 | vha = fcport->vha; | 223 | vha = fcport->vha; |
| 235 | ha = vha->hw; | 224 | ha = vha->hw; |
| 236 | /* Alloc SRB structure */ | 225 | /* Alloc SRB structure */ |
| @@ -275,32 +264,23 @@ static void qla_nvme_fcp_abort(struct nvme_fc_local_port *lport, | |||
| 275 | struct nvmefc_fcp_req *fd) | 264 | struct nvmefc_fcp_req *fd) |
| 276 | { | 265 | { |
| 277 | struct nvme_private *priv = fd->private; | 266 | struct nvme_private *priv = fd->private; |
| 278 | srb_t *sp = priv->sp; | ||
| 279 | int rval; | ||
| 280 | fc_port_t *fcport = rport->private; | ||
| 281 | struct qla_hw_data *ha = fcport->vha->hw; | ||
| 282 | |||
| 283 | rval = ha->isp_ops->abort_command(sp); | ||
| 284 | 267 | ||
| 285 | ql_dbg(ql_dbg_io, fcport->vha, 0x2127, | 268 | INIT_WORK(&priv->abort_work, qla_nvme_abort_work); |
| 286 | "%s: %s command for sp=%p on fcport=%p rval=%x\n", __func__, | 269 | schedule_work(&priv->abort_work); |
| 287 | (rval != QLA_SUCCESS) ? "Failed to abort" : "Aborted", | ||
| 288 | sp, fcport, rval); | ||
| 289 | } | 270 | } |
| 290 | 271 | ||
| 291 | static void qla_nvme_poll(struct nvme_fc_local_port *lport, void *hw_queue_handle) | 272 | static void qla_nvme_poll(struct nvme_fc_local_port *lport, void *hw_queue_handle) |
| 292 | { | 273 | { |
| 293 | struct scsi_qla_host *vha = lport->private; | ||
| 294 | unsigned long flags; | ||
| 295 | struct qla_qpair *qpair = hw_queue_handle; | 274 | struct qla_qpair *qpair = hw_queue_handle; |
| 275 | unsigned long flags; | ||
| 276 | struct scsi_qla_host *vha = lport->private; | ||
| 296 | 277 | ||
| 297 | /* Acquire ring specific lock */ | ||
| 298 | spin_lock_irqsave(&qpair->qp_lock, flags); | 278 | spin_lock_irqsave(&qpair->qp_lock, flags); |
| 299 | qla24xx_process_response_queue(vha, qpair->rsp); | 279 | qla24xx_process_response_queue(vha, qpair->rsp); |
| 300 | spin_unlock_irqrestore(&qpair->qp_lock, flags); | 280 | spin_unlock_irqrestore(&qpair->qp_lock, flags); |
| 301 | } | 281 | } |
| 302 | 282 | ||
| 303 | static int qla2x00_start_nvme_mq(srb_t *sp) | 283 | static inline int qla2x00_start_nvme_mq(srb_t *sp) |
| 304 | { | 284 | { |
| 305 | unsigned long flags; | 285 | unsigned long flags; |
| 306 | uint32_t *clr_ptr; | 286 | uint32_t *clr_ptr; |
| @@ -313,7 +293,6 @@ static int qla2x00_start_nvme_mq(srb_t *sp) | |||
| 313 | uint16_t avail_dsds; | 293 | uint16_t avail_dsds; |
| 314 | uint32_t *cur_dsd; | 294 | uint32_t *cur_dsd; |
| 315 | struct req_que *req = NULL; | 295 | struct req_que *req = NULL; |
| 316 | struct rsp_que *rsp = NULL; | ||
| 317 | struct scsi_qla_host *vha = sp->fcport->vha; | 296 | struct scsi_qla_host *vha = sp->fcport->vha; |
| 318 | struct qla_hw_data *ha = vha->hw; | 297 | struct qla_hw_data *ha = vha->hw; |
| 319 | struct qla_qpair *qpair = sp->qpair; | 298 | struct qla_qpair *qpair = sp->qpair; |
| @@ -322,15 +301,13 @@ static int qla2x00_start_nvme_mq(srb_t *sp) | |||
| 322 | struct nvmefc_fcp_req *fd = nvme->u.nvme.desc; | 301 | struct nvmefc_fcp_req *fd = nvme->u.nvme.desc; |
| 323 | uint32_t rval = QLA_SUCCESS; | 302 | uint32_t rval = QLA_SUCCESS; |
| 324 | 303 | ||
| 304 | /* Setup qpair pointers */ | ||
| 305 | req = qpair->req; | ||
| 325 | tot_dsds = fd->sg_cnt; | 306 | tot_dsds = fd->sg_cnt; |
| 326 | 307 | ||
| 327 | /* Acquire qpair specific lock */ | 308 | /* Acquire qpair specific lock */ |
| 328 | spin_lock_irqsave(&qpair->qp_lock, flags); | 309 | spin_lock_irqsave(&qpair->qp_lock, flags); |
| 329 | 310 | ||
| 330 | /* Setup qpair pointers */ | ||
| 331 | req = qpair->req; | ||
| 332 | rsp = qpair->rsp; | ||
| 333 | |||
| 334 | /* Check for room in outstanding command list. */ | 311 | /* Check for room in outstanding command list. */ |
| 335 | handle = req->current_outstanding_cmd; | 312 | handle = req->current_outstanding_cmd; |
| 336 | for (index = 1; index < req->num_outstanding_cmds; index++) { | 313 | for (index = 1; index < req->num_outstanding_cmds; index++) { |
| @@ -342,7 +319,7 @@ static int qla2x00_start_nvme_mq(srb_t *sp) | |||
| 342 | } | 319 | } |
| 343 | 320 | ||
| 344 | if (index == req->num_outstanding_cmds) { | 321 | if (index == req->num_outstanding_cmds) { |
| 345 | rval = -1; | 322 | rval = -EBUSY; |
| 346 | goto queuing_error; | 323 | goto queuing_error; |
| 347 | } | 324 | } |
| 348 | req_cnt = qla24xx_calc_iocbs(vha, tot_dsds); | 325 | req_cnt = qla24xx_calc_iocbs(vha, tot_dsds); |
| @@ -356,7 +333,7 @@ static int qla2x00_start_nvme_mq(srb_t *sp) | |||
| 356 | req->cnt = req->length - (req->ring_index - cnt); | 333 | req->cnt = req->length - (req->ring_index - cnt); |
| 357 | 334 | ||
| 358 | if (req->cnt < (req_cnt + 2)){ | 335 | if (req->cnt < (req_cnt + 2)){ |
| 359 | rval = -1; | 336 | rval = -EBUSY; |
| 360 | goto queuing_error; | 337 | goto queuing_error; |
| 361 | } | 338 | } |
| 362 | } | 339 | } |
| @@ -365,7 +342,7 @@ static int qla2x00_start_nvme_mq(srb_t *sp) | |||
| 365 | struct nvme_fc_cmd_iu *cmd = fd->cmdaddr; | 342 | struct nvme_fc_cmd_iu *cmd = fd->cmdaddr; |
| 366 | if (cmd->sqe.common.opcode == nvme_admin_async_event) { | 343 | if (cmd->sqe.common.opcode == nvme_admin_async_event) { |
| 367 | nvme->u.nvme.aen_op = 1; | 344 | nvme->u.nvme.aen_op = 1; |
| 368 | atomic_inc(&vha->hw->nvme_active_aen_cnt); | 345 | atomic_inc(&ha->nvme_active_aen_cnt); |
| 369 | } | 346 | } |
| 370 | } | 347 | } |
| 371 | 348 | ||
| @@ -478,11 +455,6 @@ static int qla2x00_start_nvme_mq(srb_t *sp) | |||
| 478 | /* Set chip new ring index. */ | 455 | /* Set chip new ring index. */ |
| 479 | WRT_REG_DWORD(req->req_q_in, req->ring_index); | 456 | WRT_REG_DWORD(req->req_q_in, req->ring_index); |
| 480 | 457 | ||
| 481 | /* Manage unprocessed RIO/ZIO commands in response queue. */ | ||
| 482 | if (vha->flags.process_response_queue && | ||
| 483 | rsp->ring_ptr->signature != RESPONSE_PROCESSED) | ||
| 484 | qla24xx_process_response_queue(vha, rsp); | ||
| 485 | |||
| 486 | queuing_error: | 458 | queuing_error: |
| 487 | spin_unlock_irqrestore(&qpair->qp_lock, flags); | 459 | spin_unlock_irqrestore(&qpair->qp_lock, flags); |
| 488 | return rval; | 460 | return rval; |
| @@ -496,31 +468,44 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport, | |||
| 496 | fc_port_t *fcport; | 468 | fc_port_t *fcport; |
| 497 | struct srb_iocb *nvme; | 469 | struct srb_iocb *nvme; |
| 498 | struct scsi_qla_host *vha; | 470 | struct scsi_qla_host *vha; |
| 499 | int rval = QLA_FUNCTION_FAILED; | 471 | int rval = -ENODEV; |
| 500 | srb_t *sp; | 472 | srb_t *sp; |
| 501 | struct qla_qpair *qpair = hw_queue_handle; | 473 | struct qla_qpair *qpair = hw_queue_handle; |
| 502 | struct nvme_private *priv; | 474 | struct nvme_private *priv; |
| 475 | struct qla_nvme_rport *qla_rport = rport->private; | ||
| 503 | 476 | ||
| 504 | if (!fd) { | 477 | if (!fd || !qpair) { |
| 505 | ql_log(ql_log_warn, NULL, 0x2134, "NO NVMe FCP request\n"); | 478 | ql_log(ql_log_warn, NULL, 0x2134, |
| 479 | "NO NVMe request or Queue Handle\n"); | ||
| 506 | return rval; | 480 | return rval; |
| 507 | } | 481 | } |
| 508 | 482 | ||
| 509 | priv = fd->private; | 483 | priv = fd->private; |
| 510 | fcport = rport->private; | 484 | fcport = qla_rport->fcport; |
| 511 | if (!fcport) { | 485 | if (!fcport) { |
| 512 | ql_log(ql_log_warn, NULL, 0x210e, "No fcport ptr\n"); | 486 | ql_log(ql_log_warn, NULL, 0x210e, "No fcport ptr\n"); |
| 513 | return rval; | 487 | return rval; |
| 514 | } | 488 | } |
| 515 | 489 | ||
| 516 | vha = fcport->vha; | 490 | vha = fcport->vha; |
| 517 | if ((!qpair) || (!(fcport->nvme_flag & NVME_FLAG_REGISTERED))) | 491 | |
| 492 | if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) | ||
| 493 | return rval; | ||
| 494 | |||
| 495 | /* | ||
| 496 | * If we know the dev is going away while the transport is still sending | ||
| 497 | * IO's return busy back to stall the IO Q. This happens when the | ||
| 498 | * link goes away and fw hasn't notified us yet, but IO's are being | ||
| 499 | * returned. If the dev comes back quickly we won't exhaust the IO | ||
| 500 | * retry count at the core. | ||
| 501 | */ | ||
| 502 | if (fcport->nvme_flag & NVME_FLAG_RESETTING) | ||
| 518 | return -EBUSY; | 503 | return -EBUSY; |
| 519 | 504 | ||
| 520 | /* Alloc SRB structure */ | 505 | /* Alloc SRB structure */ |
| 521 | sp = qla2xxx_get_qpair_sp(qpair, fcport, GFP_ATOMIC); | 506 | sp = qla2xxx_get_qpair_sp(qpair, fcport, GFP_ATOMIC); |
| 522 | if (!sp) | 507 | if (!sp) |
| 523 | return -EIO; | 508 | return -EBUSY; |
| 524 | 509 | ||
| 525 | atomic_set(&sp->ref_count, 1); | 510 | atomic_set(&sp->ref_count, 1); |
| 526 | init_waitqueue_head(&sp->nvme_ls_waitq); | 511 | init_waitqueue_head(&sp->nvme_ls_waitq); |
| @@ -538,7 +523,6 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport, | |||
| 538 | "qla2x00_start_nvme_mq failed = %d\n", rval); | 523 | "qla2x00_start_nvme_mq failed = %d\n", rval); |
| 539 | atomic_dec(&sp->ref_count); | 524 | atomic_dec(&sp->ref_count); |
| 540 | wake_up(&sp->nvme_ls_waitq); | 525 | wake_up(&sp->nvme_ls_waitq); |
| 541 | return -EIO; | ||
| 542 | } | 526 | } |
| 543 | 527 | ||
| 544 | return rval; | 528 | return rval; |
| @@ -557,22 +541,27 @@ static void qla_nvme_localport_delete(struct nvme_fc_local_port *lport) | |||
| 557 | static void qla_nvme_remoteport_delete(struct nvme_fc_remote_port *rport) | 541 | static void qla_nvme_remoteport_delete(struct nvme_fc_remote_port *rport) |
| 558 | { | 542 | { |
| 559 | fc_port_t *fcport; | 543 | fc_port_t *fcport; |
| 560 | struct nvme_rport *r_port, *trport; | 544 | struct qla_nvme_rport *qla_rport = rport->private, *trport; |
| 561 | 545 | ||
| 562 | fcport = rport->private; | 546 | fcport = qla_rport->fcport; |
| 563 | fcport->nvme_remote_port = NULL; | 547 | fcport->nvme_remote_port = NULL; |
| 564 | fcport->nvme_flag &= ~NVME_FLAG_REGISTERED; | 548 | fcport->nvme_flag &= ~NVME_FLAG_REGISTERED; |
| 565 | 549 | ||
| 566 | list_for_each_entry_safe(r_port, trport, | 550 | list_for_each_entry_safe(qla_rport, trport, |
| 567 | &fcport->vha->nvme_rport_list, list) { | 551 | &fcport->vha->nvme_rport_list, list) { |
| 568 | if (r_port->fcport == fcport) { | 552 | if (qla_rport->fcport == fcport) { |
| 569 | list_del(&r_port->list); | 553 | list_del(&qla_rport->list); |
| 570 | break; | 554 | break; |
| 571 | } | 555 | } |
| 572 | } | 556 | } |
| 573 | kfree(r_port); | ||
| 574 | complete(&fcport->nvme_del_done); | 557 | complete(&fcport->nvme_del_done); |
| 575 | 558 | ||
| 559 | if (!test_bit(UNLOADING, &fcport->vha->dpc_flags)) { | ||
| 560 | INIT_WORK(&fcport->free_work, qlt_free_session_done); | ||
| 561 | schedule_work(&fcport->free_work); | ||
| 562 | } | ||
| 563 | |||
| 564 | fcport->nvme_flag &= ~(NVME_FLAG_REGISTERED | NVME_FLAG_DELETING); | ||
| 576 | ql_log(ql_log_info, fcport->vha, 0x2110, | 565 | ql_log(ql_log_info, fcport->vha, 0x2110, |
| 577 | "remoteport_delete of %p completed.\n", fcport); | 566 | "remoteport_delete of %p completed.\n", fcport); |
| 578 | } | 567 | } |
| @@ -592,7 +581,7 @@ static struct nvme_fc_port_template qla_nvme_fc_transport = { | |||
| 592 | .max_dif_sgl_segments = 64, | 581 | .max_dif_sgl_segments = 64, |
| 593 | .dma_boundary = 0xFFFFFFFF, | 582 | .dma_boundary = 0xFFFFFFFF, |
| 594 | .local_priv_sz = 8, | 583 | .local_priv_sz = 8, |
| 595 | .remote_priv_sz = 0, | 584 | .remote_priv_sz = sizeof(struct qla_nvme_rport), |
| 596 | .lsrqst_priv_sz = sizeof(struct nvme_private), | 585 | .lsrqst_priv_sz = sizeof(struct nvme_private), |
| 597 | .fcprqst_priv_sz = sizeof(struct nvme_private), | 586 | .fcprqst_priv_sz = sizeof(struct nvme_private), |
| 598 | }; | 587 | }; |
| @@ -611,37 +600,25 @@ static int qla_nvme_wait_on_command(srb_t *sp) | |||
| 611 | return ret; | 600 | return ret; |
| 612 | } | 601 | } |
| 613 | 602 | ||
| 614 | static int qla_nvme_wait_on_rport_del(fc_port_t *fcport) | 603 | void qla_nvme_abort(struct qla_hw_data *ha, struct srb *sp, int res) |
| 615 | { | ||
| 616 | int ret = QLA_SUCCESS; | ||
| 617 | int timeout; | ||
| 618 | |||
| 619 | timeout = wait_for_completion_timeout(&fcport->nvme_del_done, | ||
| 620 | msecs_to_jiffies(2000)); | ||
| 621 | if (!timeout) { | ||
| 622 | ret = QLA_FUNCTION_FAILED; | ||
| 623 | ql_log(ql_log_info, fcport->vha, 0x2111, | ||
| 624 | "timed out waiting for fcport=%p to delete\n", fcport); | ||
| 625 | } | ||
| 626 | |||
| 627 | return ret; | ||
| 628 | } | ||
| 629 | |||
| 630 | void qla_nvme_abort(struct qla_hw_data *ha, struct srb *sp) | ||
| 631 | { | 604 | { |
| 632 | int rval; | 605 | int rval; |
| 633 | 606 | ||
| 634 | rval = ha->isp_ops->abort_command(sp); | 607 | if (!test_bit(ABORT_ISP_ACTIVE, &sp->vha->dpc_flags)) { |
| 635 | if (!rval && !qla_nvme_wait_on_command(sp)) | 608 | rval = ha->isp_ops->abort_command(sp); |
| 636 | ql_log(ql_log_warn, NULL, 0x2112, | 609 | if (!rval && !qla_nvme_wait_on_command(sp)) |
| 637 | "nvme_wait_on_comand timed out waiting on sp=%p\n", sp); | 610 | ql_log(ql_log_warn, NULL, 0x2112, |
| 611 | "timed out waiting on sp=%p\n", sp); | ||
| 612 | } else { | ||
| 613 | sp->done(sp, res); | ||
| 614 | } | ||
| 638 | } | 615 | } |
| 639 | 616 | ||
| 640 | static void qla_nvme_unregister_remote_port(struct work_struct *work) | 617 | static void qla_nvme_unregister_remote_port(struct work_struct *work) |
| 641 | { | 618 | { |
| 642 | struct fc_port *fcport = container_of(work, struct fc_port, | 619 | struct fc_port *fcport = container_of(work, struct fc_port, |
| 643 | nvme_del_work); | 620 | nvme_del_work); |
| 644 | struct nvme_rport *rport, *trport; | 621 | struct qla_nvme_rport *qla_rport, *trport; |
| 645 | 622 | ||
| 646 | if (!IS_ENABLED(CONFIG_NVME_FC)) | 623 | if (!IS_ENABLED(CONFIG_NVME_FC)) |
| 647 | return; | 624 | return; |
| @@ -649,51 +626,53 @@ static void qla_nvme_unregister_remote_port(struct work_struct *work) | |||
| 649 | ql_log(ql_log_warn, NULL, 0x2112, | 626 | ql_log(ql_log_warn, NULL, 0x2112, |
| 650 | "%s: unregister remoteport on %p\n",__func__, fcport); | 627 | "%s: unregister remoteport on %p\n",__func__, fcport); |
| 651 | 628 | ||
| 652 | list_for_each_entry_safe(rport, trport, | 629 | list_for_each_entry_safe(qla_rport, trport, |
| 653 | &fcport->vha->nvme_rport_list, list) { | 630 | &fcport->vha->nvme_rport_list, list) { |
| 654 | if (rport->fcport == fcport) { | 631 | if (qla_rport->fcport == fcport) { |
| 655 | ql_log(ql_log_info, fcport->vha, 0x2113, | 632 | ql_log(ql_log_info, fcport->vha, 0x2113, |
| 656 | "%s: fcport=%p\n", __func__, fcport); | 633 | "%s: fcport=%p\n", __func__, fcport); |
| 657 | init_completion(&fcport->nvme_del_done); | 634 | init_completion(&fcport->nvme_del_done); |
| 658 | nvme_fc_unregister_remoteport( | 635 | nvme_fc_unregister_remoteport( |
| 659 | fcport->nvme_remote_port); | 636 | fcport->nvme_remote_port); |
| 660 | qla_nvme_wait_on_rport_del(fcport); | 637 | wait_for_completion(&fcport->nvme_del_done); |
| 638 | break; | ||
| 661 | } | 639 | } |
| 662 | } | 640 | } |
| 663 | } | 641 | } |
| 664 | 642 | ||
| 665 | void qla_nvme_delete(struct scsi_qla_host *vha) | 643 | void qla_nvme_delete(struct scsi_qla_host *vha) |
| 666 | { | 644 | { |
| 667 | struct nvme_rport *rport, *trport; | 645 | struct qla_nvme_rport *qla_rport, *trport; |
| 668 | fc_port_t *fcport; | 646 | fc_port_t *fcport; |
| 669 | int nv_ret; | 647 | int nv_ret; |
| 670 | 648 | ||
| 671 | if (!IS_ENABLED(CONFIG_NVME_FC)) | 649 | if (!IS_ENABLED(CONFIG_NVME_FC)) |
| 672 | return; | 650 | return; |
| 673 | 651 | ||
| 674 | list_for_each_entry_safe(rport, trport, &vha->nvme_rport_list, list) { | 652 | list_for_each_entry_safe(qla_rport, trport, |
| 675 | fcport = rport->fcport; | 653 | &vha->nvme_rport_list, list) { |
| 654 | fcport = qla_rport->fcport; | ||
| 676 | 655 | ||
| 677 | ql_log(ql_log_info, fcport->vha, 0x2114, "%s: fcport=%p\n", | 656 | ql_log(ql_log_info, fcport->vha, 0x2114, "%s: fcport=%p\n", |
| 678 | __func__, fcport); | 657 | __func__, fcport); |
| 679 | 658 | ||
| 659 | nvme_fc_set_remoteport_devloss(fcport->nvme_remote_port, 0); | ||
| 680 | init_completion(&fcport->nvme_del_done); | 660 | init_completion(&fcport->nvme_del_done); |
| 681 | nvme_fc_unregister_remoteport(fcport->nvme_remote_port); | 661 | nvme_fc_unregister_remoteport(fcport->nvme_remote_port); |
| 682 | qla_nvme_wait_on_rport_del(fcport); | 662 | wait_for_completion(&fcport->nvme_del_done); |
| 683 | } | 663 | } |
| 684 | 664 | ||
| 685 | if (vha->nvme_local_port) { | 665 | if (vha->nvme_local_port) { |
| 686 | init_completion(&vha->nvme_del_done); | 666 | init_completion(&vha->nvme_del_done); |
| 667 | ql_log(ql_log_info, vha, 0x2116, | ||
| 668 | "unregister localport=%p\n", | ||
| 669 | vha->nvme_local_port); | ||
| 687 | nv_ret = nvme_fc_unregister_localport(vha->nvme_local_port); | 670 | nv_ret = nvme_fc_unregister_localport(vha->nvme_local_port); |
| 688 | if (nv_ret == 0) | 671 | if (nv_ret) |
| 689 | ql_log(ql_log_info, vha, 0x2116, | ||
| 690 | "unregistered localport=%p\n", | ||
| 691 | vha->nvme_local_port); | ||
| 692 | else | ||
| 693 | ql_log(ql_log_info, vha, 0x2115, | 672 | ql_log(ql_log_info, vha, 0x2115, |
| 694 | "Unregister of localport failed\n"); | 673 | "Unregister of localport failed\n"); |
| 695 | wait_for_completion_timeout(&vha->nvme_del_done, | 674 | else |
| 696 | msecs_to_jiffies(5000)); | 675 | wait_for_completion(&vha->nvme_del_done); |
| 697 | } | 676 | } |
| 698 | } | 677 | } |
| 699 | 678 | ||
diff --git a/drivers/scsi/qla2xxx/qla_nvme.h b/drivers/scsi/qla2xxx/qla_nvme.h index 7f05fa1c77db..816854ada654 100644 --- a/drivers/scsi/qla2xxx/qla_nvme.h +++ b/drivers/scsi/qla2xxx/qla_nvme.h | |||
| @@ -14,6 +14,9 @@ | |||
| 14 | 14 | ||
| 15 | #include "qla_def.h" | 15 | #include "qla_def.h" |
| 16 | 16 | ||
| 17 | /* default dev loss time (seconds) before transport tears down ctrl */ | ||
| 18 | #define NVME_FC_DEV_LOSS_TMO 30 | ||
| 19 | |||
| 17 | #define NVME_ATIO_CMD_OFF 32 | 20 | #define NVME_ATIO_CMD_OFF 32 |
| 18 | #define NVME_FIRST_PACKET_CMDLEN (64 - NVME_ATIO_CMD_OFF) | 21 | #define NVME_FIRST_PACKET_CMDLEN (64 - NVME_ATIO_CMD_OFF) |
| 19 | #define Q2T_NVME_NUM_TAGS 2048 | 22 | #define Q2T_NVME_NUM_TAGS 2048 |
| @@ -28,11 +31,11 @@ struct nvme_private { | |||
| 28 | struct srb *sp; | 31 | struct srb *sp; |
| 29 | struct nvmefc_ls_req *fd; | 32 | struct nvmefc_ls_req *fd; |
| 30 | struct work_struct ls_work; | 33 | struct work_struct ls_work; |
| 34 | struct work_struct abort_work; | ||
| 31 | int comp_status; | 35 | int comp_status; |
| 32 | }; | 36 | }; |
| 33 | 37 | ||
| 34 | struct nvme_rport { | 38 | struct qla_nvme_rport { |
| 35 | struct nvme_fc_port_info req; | ||
| 36 | struct list_head list; | 39 | struct list_head list; |
| 37 | struct fc_port *fcport; | 40 | struct fc_port *fcport; |
| 38 | }; | 41 | }; |
| @@ -142,7 +145,7 @@ struct pt_ls4_rx_unsol { | |||
| 142 | void qla_nvme_register_hba(struct scsi_qla_host *); | 145 | void qla_nvme_register_hba(struct scsi_qla_host *); |
| 143 | int qla_nvme_register_remote(struct scsi_qla_host *, struct fc_port *); | 146 | int qla_nvme_register_remote(struct scsi_qla_host *, struct fc_port *); |
| 144 | void qla_nvme_delete(struct scsi_qla_host *); | 147 | void qla_nvme_delete(struct scsi_qla_host *); |
| 145 | void qla_nvme_abort(struct qla_hw_data *, struct srb *sp); | 148 | void qla_nvme_abort(struct qla_hw_data *, struct srb *sp, int res); |
| 146 | void qla24xx_nvme_ls4_iocb(struct scsi_qla_host *, struct pt_ls4_request *, | 149 | void qla24xx_nvme_ls4_iocb(struct scsi_qla_host *, struct pt_ls4_request *, |
| 147 | struct req_que *); | 150 | struct req_que *); |
| 148 | void qla24xx_async_gffid_sp_done(void *, int); | 151 | void qla24xx_async_gffid_sp_done(void *, int); |
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index a77c33987703..872d66dd79cd 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c | |||
| @@ -1732,7 +1732,7 @@ iospace_error_exit: | |||
| 1732 | 1732 | ||
| 1733 | /** | 1733 | /** |
| 1734 | * qla82xx_pci_config() - Setup ISP82xx PCI configuration registers. | 1734 | * qla82xx_pci_config() - Setup ISP82xx PCI configuration registers. |
| 1735 | * @ha: HA context | 1735 | * @vha: HA context |
| 1736 | * | 1736 | * |
| 1737 | * Returns 0 on success. | 1737 | * Returns 0 on success. |
| 1738 | */ | 1738 | */ |
| @@ -1753,7 +1753,7 @@ qla82xx_pci_config(scsi_qla_host_t *vha) | |||
| 1753 | 1753 | ||
| 1754 | /** | 1754 | /** |
| 1755 | * qla82xx_reset_chip() - Setup ISP82xx PCI configuration registers. | 1755 | * qla82xx_reset_chip() - Setup ISP82xx PCI configuration registers. |
| 1756 | * @ha: HA context | 1756 | * @vha: HA context |
| 1757 | * | 1757 | * |
| 1758 | * Returns 0 on success. | 1758 | * Returns 0 on success. |
| 1759 | */ | 1759 | */ |
| @@ -2008,11 +2008,10 @@ qla82xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0) | |||
| 2008 | "MBX pointer ERROR.\n"); | 2008 | "MBX pointer ERROR.\n"); |
| 2009 | } | 2009 | } |
| 2010 | 2010 | ||
| 2011 | /* | 2011 | /** |
| 2012 | * qla82xx_intr_handler() - Process interrupts for the ISP23xx and ISP63xx. | 2012 | * qla82xx_intr_handler() - Process interrupts for the ISP23xx and ISP63xx. |
| 2013 | * @irq: | 2013 | * @irq: |
| 2014 | * @dev_id: SCSI driver HA context | 2014 | * @dev_id: SCSI driver HA context |
| 2015 | * @regs: | ||
| 2016 | * | 2015 | * |
| 2017 | * Called by system whenever the host adapter generates an interrupt. | 2016 | * Called by system whenever the host adapter generates an interrupt. |
| 2018 | * | 2017 | * |
diff --git a/drivers/scsi/qla2xxx/qla_nx2.c b/drivers/scsi/qla2xxx/qla_nx2.c index 525ac35a757b..3a2b0282df14 100644 --- a/drivers/scsi/qla2xxx/qla_nx2.c +++ b/drivers/scsi/qla2xxx/qla_nx2.c | |||
| @@ -280,9 +280,8 @@ qla8044_clear_qsnt_ready(struct scsi_qla_host *vha) | |||
| 280 | } | 280 | } |
| 281 | 281 | ||
| 282 | /** | 282 | /** |
| 283 | * | ||
| 284 | * qla8044_lock_recovery - Recovers the idc_lock. | 283 | * qla8044_lock_recovery - Recovers the idc_lock. |
| 285 | * @ha : Pointer to adapter structure | 284 | * @vha : Pointer to adapter structure |
| 286 | * | 285 | * |
| 287 | * Lock Recovery Register | 286 | * Lock Recovery Register |
| 288 | * 5-2 Lock recovery owner: Function ID of driver doing lock recovery, | 287 | * 5-2 Lock recovery owner: Function ID of driver doing lock recovery, |
| @@ -1639,10 +1638,10 @@ qla8044_set_rst_ready(struct scsi_qla_host *vha) | |||
| 1639 | 1638 | ||
| 1640 | /** | 1639 | /** |
| 1641 | * qla8044_need_reset_handler - Code to start reset sequence | 1640 | * qla8044_need_reset_handler - Code to start reset sequence |
| 1642 | * @ha: pointer to adapter structure | 1641 | * @vha: pointer to adapter structure |
| 1643 | * | 1642 | * |
| 1644 | * Note: IDC lock must be held upon entry | 1643 | * Note: IDC lock must be held upon entry |
| 1645 | **/ | 1644 | */ |
| 1646 | static void | 1645 | static void |
| 1647 | qla8044_need_reset_handler(struct scsi_qla_host *vha) | 1646 | qla8044_need_reset_handler(struct scsi_qla_host *vha) |
| 1648 | { | 1647 | { |
| @@ -1859,8 +1858,8 @@ exit_update_idc_reg: | |||
| 1859 | 1858 | ||
| 1860 | /** | 1859 | /** |
| 1861 | * qla8044_need_qsnt_handler - Code to start qsnt | 1860 | * qla8044_need_qsnt_handler - Code to start qsnt |
| 1862 | * @ha: pointer to adapter structure | 1861 | * @vha: pointer to adapter structure |
| 1863 | **/ | 1862 | */ |
| 1864 | static void | 1863 | static void |
| 1865 | qla8044_need_qsnt_handler(struct scsi_qla_host *vha) | 1864 | qla8044_need_qsnt_handler(struct scsi_qla_host *vha) |
| 1866 | { | 1865 | { |
| @@ -2031,10 +2030,10 @@ exit_error: | |||
| 2031 | 2030 | ||
| 2032 | /** | 2031 | /** |
| 2033 | * qla4_8xxx_check_temp - Check the ISP82XX temperature. | 2032 | * qla4_8xxx_check_temp - Check the ISP82XX temperature. |
| 2034 | * @ha: adapter block pointer. | 2033 | * @vha: adapter block pointer. |
| 2035 | * | 2034 | * |
| 2036 | * Note: The caller should not hold the idc lock. | 2035 | * Note: The caller should not hold the idc lock. |
| 2037 | **/ | 2036 | */ |
| 2038 | static int | 2037 | static int |
| 2039 | qla8044_check_temp(struct scsi_qla_host *vha) | 2038 | qla8044_check_temp(struct scsi_qla_host *vha) |
| 2040 | { | 2039 | { |
| @@ -2071,10 +2070,10 @@ int qla8044_read_temperature(scsi_qla_host_t *vha) | |||
| 2071 | 2070 | ||
| 2072 | /** | 2071 | /** |
| 2073 | * qla8044_check_fw_alive - Check firmware health | 2072 | * qla8044_check_fw_alive - Check firmware health |
| 2074 | * @ha: Pointer to host adapter structure. | 2073 | * @vha: Pointer to host adapter structure. |
| 2075 | * | 2074 | * |
| 2076 | * Context: Interrupt | 2075 | * Context: Interrupt |
| 2077 | **/ | 2076 | */ |
| 2078 | int | 2077 | int |
| 2079 | qla8044_check_fw_alive(struct scsi_qla_host *vha) | 2078 | qla8044_check_fw_alive(struct scsi_qla_host *vha) |
| 2080 | { | 2079 | { |
diff --git a/drivers/scsi/qla2xxx/qla_nx2.h b/drivers/scsi/qla2xxx/qla_nx2.h index 83c1b7e17c80..8ba7c1db07c3 100644 --- a/drivers/scsi/qla2xxx/qla_nx2.h +++ b/drivers/scsi/qla2xxx/qla_nx2.h | |||
| @@ -23,10 +23,6 @@ | |||
| 23 | #define MD_MIU_TEST_AGT_WRDATA_HI 0x410000A4 | 23 | #define MD_MIU_TEST_AGT_WRDATA_HI 0x410000A4 |
| 24 | #define MD_MIU_TEST_AGT_WRDATA_ULO 0x410000B0 | 24 | #define MD_MIU_TEST_AGT_WRDATA_ULO 0x410000B0 |
| 25 | #define MD_MIU_TEST_AGT_WRDATA_UHI 0x410000B4 | 25 | #define MD_MIU_TEST_AGT_WRDATA_UHI 0x410000B4 |
| 26 | #define MD_MIU_TEST_AGT_RDDATA_LO 0x410000A8 | ||
| 27 | #define MD_MIU_TEST_AGT_RDDATA_HI 0x410000AC | ||
| 28 | #define MD_MIU_TEST_AGT_RDDATA_ULO 0x410000B8 | ||
| 29 | #define MD_MIU_TEST_AGT_RDDATA_UHI 0x410000BC | ||
| 30 | 26 | ||
| 31 | /* MIU_TEST_AGT_CTRL flags. work for SIU as well */ | 27 | /* MIU_TEST_AGT_CTRL flags. work for SIU as well */ |
| 32 | #define MIU_TA_CTL_WRITE_ENABLE (MIU_TA_CTL_WRITE | MIU_TA_CTL_ENABLE) | 28 | #define MIU_TA_CTL_WRITE_ENABLE (MIU_TA_CTL_WRITE | MIU_TA_CTL_ENABLE) |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 822d22336e15..2bbf0bff0da0 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
| @@ -397,7 +397,6 @@ static void qla_init_base_qpair(struct scsi_qla_host *vha, struct req_que *req, | |||
| 397 | ha->base_qpair->use_shadow_reg = IS_SHADOW_REG_CAPABLE(ha) ? 1 : 0; | 397 | ha->base_qpair->use_shadow_reg = IS_SHADOW_REG_CAPABLE(ha) ? 1 : 0; |
| 398 | ha->base_qpair->msix = &ha->msix_entries[QLA_MSIX_RSP_Q]; | 398 | ha->base_qpair->msix = &ha->msix_entries[QLA_MSIX_RSP_Q]; |
| 399 | INIT_LIST_HEAD(&ha->base_qpair->hints_list); | 399 | INIT_LIST_HEAD(&ha->base_qpair->hints_list); |
| 400 | INIT_LIST_HEAD(&ha->base_qpair->nvme_done_list); | ||
| 401 | ha->base_qpair->enable_class_2 = ql2xenableclass2; | 400 | ha->base_qpair->enable_class_2 = ql2xenableclass2; |
| 402 | /* init qpair to this cpu. Will adjust at run time. */ | 401 | /* init qpair to this cpu. Will adjust at run time. */ |
| 403 | qla_cpu_update(rsp->qpair, raw_smp_processor_id()); | 402 | qla_cpu_update(rsp->qpair, raw_smp_processor_id()); |
| @@ -496,7 +495,7 @@ static void qla2x00_free_rsp_que(struct qla_hw_data *ha, struct rsp_que *rsp) | |||
| 496 | return; | 495 | return; |
| 497 | 496 | ||
| 498 | if (IS_QLAFX00(ha)) { | 497 | if (IS_QLAFX00(ha)) { |
| 499 | if (rsp && rsp->ring) | 498 | if (rsp && rsp->ring_fx00) |
| 500 | dma_free_coherent(&ha->pdev->dev, | 499 | dma_free_coherent(&ha->pdev->dev, |
| 501 | (rsp->length_fx00 + 1) * sizeof(request_t), | 500 | (rsp->length_fx00 + 1) * sizeof(request_t), |
| 502 | rsp->ring_fx00, rsp->dma_fx00); | 501 | rsp->ring_fx00, rsp->dma_fx00); |
| @@ -1744,7 +1743,7 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res) | |||
| 1744 | sp_get(sp); | 1743 | sp_get(sp); |
| 1745 | spin_unlock_irqrestore(qp->qp_lock_ptr, | 1744 | spin_unlock_irqrestore(qp->qp_lock_ptr, |
| 1746 | flags); | 1745 | flags); |
| 1747 | qla_nvme_abort(ha, sp); | 1746 | qla_nvme_abort(ha, sp, res); |
| 1748 | spin_lock_irqsave(qp->qp_lock_ptr, | 1747 | spin_lock_irqsave(qp->qp_lock_ptr, |
| 1749 | flags); | 1748 | flags); |
| 1750 | } else if (GET_CMD_SP(sp) && | 1749 | } else if (GET_CMD_SP(sp) && |
| @@ -4822,12 +4821,14 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e) | |||
| 4822 | fcport->d_id = e->u.new_sess.id; | 4821 | fcport->d_id = e->u.new_sess.id; |
| 4823 | fcport->flags |= FCF_FABRIC_DEVICE; | 4822 | fcport->flags |= FCF_FABRIC_DEVICE; |
| 4824 | fcport->fw_login_state = DSC_LS_PLOGI_PEND; | 4823 | fcport->fw_login_state = DSC_LS_PLOGI_PEND; |
| 4825 | if (e->u.new_sess.fc4_type == FC4_TYPE_FCP_SCSI) { | 4824 | if (e->u.new_sess.fc4_type & FS_FC4TYPE_FCP) |
| 4826 | fcport->fc4_type = FC4_TYPE_FCP_SCSI; | 4825 | fcport->fc4_type = FC4_TYPE_FCP_SCSI; |
| 4827 | } else if (e->u.new_sess.fc4_type == FC4_TYPE_NVME) { | 4826 | |
| 4827 | if (e->u.new_sess.fc4_type & FS_FC4TYPE_NVME) { | ||
| 4828 | fcport->fc4_type = FC4_TYPE_OTHER; | 4828 | fcport->fc4_type = FC4_TYPE_OTHER; |
| 4829 | fcport->fc4f_nvme = FC4_TYPE_NVME; | 4829 | fcport->fc4f_nvme = FC4_TYPE_NVME; |
| 4830 | } | 4830 | } |
| 4831 | |||
| 4831 | memcpy(fcport->port_name, e->u.new_sess.port_name, | 4832 | memcpy(fcport->port_name, e->u.new_sess.port_name, |
| 4832 | WWN_SIZE); | 4833 | WWN_SIZE); |
| 4833 | } else { | 4834 | } else { |
| @@ -5047,7 +5048,8 @@ qla2x00_do_work(struct scsi_qla_host *vha) | |||
| 5047 | e->u.logio.data); | 5048 | e->u.logio.data); |
| 5048 | break; | 5049 | break; |
| 5049 | case QLA_EVT_GPNFT: | 5050 | case QLA_EVT_GPNFT: |
| 5050 | qla24xx_async_gpnft(vha, e->u.gpnft.fc4_type); | 5051 | qla24xx_async_gpnft(vha, e->u.gpnft.fc4_type, |
| 5052 | e->u.gpnft.sp); | ||
| 5051 | break; | 5053 | break; |
| 5052 | case QLA_EVT_GPNFT_DONE: | 5054 | case QLA_EVT_GPNFT_DONE: |
| 5053 | qla24xx_async_gpnft_done(vha, e->u.iosb.sp); | 5055 | qla24xx_async_gpnft_done(vha, e->u.iosb.sp); |
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index d2db86ea06b2..04458eb19d38 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
| @@ -2226,6 +2226,7 @@ qla2x00_erase_flash_sector(struct qla_hw_data *ha, uint32_t addr, | |||
| 2226 | 2226 | ||
| 2227 | /** | 2227 | /** |
| 2228 | * qla2x00_get_flash_manufacturer() - Read manufacturer ID from flash chip. | 2228 | * qla2x00_get_flash_manufacturer() - Read manufacturer ID from flash chip. |
| 2229 | * @ha: | ||
| 2229 | * @man_id: Flash manufacturer ID | 2230 | * @man_id: Flash manufacturer ID |
| 2230 | * @flash_id: Flash ID | 2231 | * @flash_id: Flash ID |
| 2231 | */ | 2232 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index b49ac85f3de2..5546ac9c3d9d 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c | |||
| @@ -961,7 +961,7 @@ qlt_send_first_logo(struct scsi_qla_host *vha, qlt_port_logo_t *logo) | |||
| 961 | logo->cmd_count, res); | 961 | logo->cmd_count, res); |
| 962 | } | 962 | } |
| 963 | 963 | ||
| 964 | static void qlt_free_session_done(struct work_struct *work) | 964 | void qlt_free_session_done(struct work_struct *work) |
| 965 | { | 965 | { |
| 966 | struct fc_port *sess = container_of(work, struct fc_port, | 966 | struct fc_port *sess = container_of(work, struct fc_port, |
| 967 | free_work); | 967 | free_work); |
| @@ -1169,11 +1169,14 @@ void qlt_unreg_sess(struct fc_port *sess) | |||
| 1169 | sess->last_rscn_gen = sess->rscn_gen; | 1169 | sess->last_rscn_gen = sess->rscn_gen; |
| 1170 | sess->last_login_gen = sess->login_gen; | 1170 | sess->last_login_gen = sess->login_gen; |
| 1171 | 1171 | ||
| 1172 | if (sess->nvme_flag & NVME_FLAG_REGISTERED) | 1172 | if (sess->nvme_flag & NVME_FLAG_REGISTERED && |
| 1173 | !(sess->nvme_flag & NVME_FLAG_DELETING)) { | ||
| 1174 | sess->nvme_flag |= NVME_FLAG_DELETING; | ||
| 1173 | schedule_work(&sess->nvme_del_work); | 1175 | schedule_work(&sess->nvme_del_work); |
| 1174 | 1176 | } else { | |
| 1175 | INIT_WORK(&sess->free_work, qlt_free_session_done); | 1177 | INIT_WORK(&sess->free_work, qlt_free_session_done); |
| 1176 | schedule_work(&sess->free_work); | 1178 | schedule_work(&sess->free_work); |
| 1179 | } | ||
| 1177 | } | 1180 | } |
| 1178 | EXPORT_SYMBOL(qlt_unreg_sess); | 1181 | EXPORT_SYMBOL(qlt_unreg_sess); |
| 1179 | 1182 | ||
| @@ -2023,7 +2026,7 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha, | |||
| 2023 | sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id); | 2026 | sess = ha->tgt.tgt_ops->find_sess_by_s_id(vha, s_id); |
| 2024 | if (!sess) { | 2027 | if (!sess) { |
| 2025 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf012, | 2028 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf012, |
| 2026 | "qla_target(%d): task abort for non-existant session\n", | 2029 | "qla_target(%d): task abort for non-existent session\n", |
| 2027 | vha->vp_idx); | 2030 | vha->vp_idx); |
| 2028 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); | 2031 | spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); |
| 2029 | 2032 | ||
| @@ -2866,7 +2869,6 @@ qlt_build_ctio_crc2_pkt(struct qla_qpair *qpair, struct qla_tgt_prm *prm) | |||
| 2866 | uint32_t data_bytes; | 2869 | uint32_t data_bytes; |
| 2867 | uint32_t dif_bytes; | 2870 | uint32_t dif_bytes; |
| 2868 | uint8_t bundling = 1; | 2871 | uint8_t bundling = 1; |
| 2869 | uint8_t *clr_ptr; | ||
| 2870 | struct crc_context *crc_ctx_pkt = NULL; | 2872 | struct crc_context *crc_ctx_pkt = NULL; |
| 2871 | struct qla_hw_data *ha; | 2873 | struct qla_hw_data *ha; |
| 2872 | struct ctio_crc2_to_fw *pkt; | 2874 | struct ctio_crc2_to_fw *pkt; |
| @@ -2995,15 +2997,11 @@ qlt_build_ctio_crc2_pkt(struct qla_qpair *qpair, struct qla_tgt_prm *prm) | |||
| 2995 | 2997 | ||
| 2996 | /* Allocate CRC context from global pool */ | 2998 | /* Allocate CRC context from global pool */ |
| 2997 | crc_ctx_pkt = cmd->ctx = | 2999 | crc_ctx_pkt = cmd->ctx = |
| 2998 | dma_pool_alloc(ha->dl_dma_pool, GFP_ATOMIC, &crc_ctx_dma); | 3000 | dma_pool_zalloc(ha->dl_dma_pool, GFP_ATOMIC, &crc_ctx_dma); |
| 2999 | 3001 | ||
| 3000 | if (!crc_ctx_pkt) | 3002 | if (!crc_ctx_pkt) |
| 3001 | goto crc_queuing_error; | 3003 | goto crc_queuing_error; |
| 3002 | 3004 | ||
| 3003 | /* Zero out CTX area. */ | ||
| 3004 | clr_ptr = (uint8_t *)crc_ctx_pkt; | ||
| 3005 | memset(clr_ptr, 0, sizeof(*crc_ctx_pkt)); | ||
| 3006 | |||
| 3007 | crc_ctx_pkt->crc_ctx_dma = crc_ctx_dma; | 3005 | crc_ctx_pkt->crc_ctx_dma = crc_ctx_dma; |
| 3008 | INIT_LIST_HEAD(&crc_ctx_pkt->dsd_list); | 3006 | INIT_LIST_HEAD(&crc_ctx_pkt->dsd_list); |
| 3009 | 3007 | ||
| @@ -6292,10 +6290,11 @@ static void qlt_lport_dump(struct scsi_qla_host *vha, u64 wwpn, | |||
| 6292 | /** | 6290 | /** |
| 6293 | * qla_tgt_lport_register - register lport with external module | 6291 | * qla_tgt_lport_register - register lport with external module |
| 6294 | * | 6292 | * |
| 6295 | * @qla_tgt_ops: Pointer for tcm_qla2xxx qla_tgt_ops | ||
| 6296 | * @wwpn: Passwd FC target WWPN | ||
| 6297 | * @callback: lport initialization callback for tcm_qla2xxx code | ||
| 6298 | * @target_lport_ptr: pointer for tcm_qla2xxx specific lport data | 6293 | * @target_lport_ptr: pointer for tcm_qla2xxx specific lport data |
| 6294 | * @phys_wwpn: | ||
| 6295 | * @npiv_wwpn: | ||
| 6296 | * @npiv_wwnn: | ||
| 6297 | * @callback: lport initialization callback for tcm_qla2xxx code | ||
| 6299 | */ | 6298 | */ |
| 6300 | int qlt_lport_register(void *target_lport_ptr, u64 phys_wwpn, | 6299 | int qlt_lport_register(void *target_lport_ptr, u64 phys_wwpn, |
| 6301 | u64 npiv_wwpn, u64 npiv_wwnn, | 6300 | u64 npiv_wwpn, u64 npiv_wwnn, |
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h index bb67b5a284a8..728ce74358e7 100644 --- a/drivers/scsi/qla2xxx/qla_target.h +++ b/drivers/scsi/qla2xxx/qla_target.h | |||
| @@ -1016,7 +1016,7 @@ extern void qlt_fc_port_deleted(struct scsi_qla_host *, fc_port_t *, int); | |||
| 1016 | extern int __init qlt_init(void); | 1016 | extern int __init qlt_init(void); |
| 1017 | extern void qlt_exit(void); | 1017 | extern void qlt_exit(void); |
| 1018 | extern void qlt_update_vp_map(struct scsi_qla_host *, int); | 1018 | extern void qlt_update_vp_map(struct scsi_qla_host *, int); |
| 1019 | 1019 | extern void qlt_free_session_done(struct work_struct *); | |
| 1020 | /* | 1020 | /* |
| 1021 | * This macro is used during early initializations when host->active_mode | 1021 | * This macro is used during early initializations when host->active_mode |
| 1022 | * is not set. Right now, ha value is ignored. | 1022 | * is not set. Right now, ha value is ignored. |
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 549bef9afddd..0c55d7057280 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | /* | 7 | /* |
| 8 | * Driver version | 8 | * Driver version |
| 9 | */ | 9 | */ |
| 10 | #define QLA2XXX_VERSION "10.00.00.05-k" | 10 | #define QLA2XXX_VERSION "10.00.00.06-k" |
| 11 | 11 | ||
| 12 | #define QLA_DRIVER_MAJOR_VER 10 | 12 | #define QLA_DRIVER_MAJOR_VER 10 |
| 13 | #define QLA_DRIVER_MINOR_VER 0 | 13 | #define QLA_DRIVER_MINOR_VER 0 |
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index bda2e64ee5ca..5d56904687b9 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c | |||
| @@ -1584,12 +1584,11 @@ int qla4xxx_get_chap(struct scsi_qla_host *ha, char *username, char *password, | |||
| 1584 | struct ql4_chap_table *chap_table; | 1584 | struct ql4_chap_table *chap_table; |
| 1585 | dma_addr_t chap_dma; | 1585 | dma_addr_t chap_dma; |
| 1586 | 1586 | ||
| 1587 | chap_table = dma_pool_alloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma); | 1587 | chap_table = dma_pool_zalloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma); |
| 1588 | if (chap_table == NULL) | 1588 | if (chap_table == NULL) |
| 1589 | return -ENOMEM; | 1589 | return -ENOMEM; |
| 1590 | 1590 | ||
| 1591 | chap_size = sizeof(struct ql4_chap_table); | 1591 | chap_size = sizeof(struct ql4_chap_table); |
| 1592 | memset(chap_table, 0, chap_size); | ||
| 1593 | 1592 | ||
| 1594 | if (is_qla40XX(ha)) | 1593 | if (is_qla40XX(ha)) |
| 1595 | offset = FLASH_CHAP_OFFSET | (idx * chap_size); | 1594 | offset = FLASH_CHAP_OFFSET | (idx * chap_size); |
| @@ -1648,13 +1647,12 @@ int qla4xxx_set_chap(struct scsi_qla_host *ha, char *username, char *password, | |||
| 1648 | uint32_t chap_size = 0; | 1647 | uint32_t chap_size = 0; |
| 1649 | dma_addr_t chap_dma; | 1648 | dma_addr_t chap_dma; |
| 1650 | 1649 | ||
| 1651 | chap_table = dma_pool_alloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma); | 1650 | chap_table = dma_pool_zalloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma); |
| 1652 | if (chap_table == NULL) { | 1651 | if (chap_table == NULL) { |
| 1653 | ret = -ENOMEM; | 1652 | ret = -ENOMEM; |
| 1654 | goto exit_set_chap; | 1653 | goto exit_set_chap; |
| 1655 | } | 1654 | } |
| 1656 | 1655 | ||
| 1657 | memset(chap_table, 0, sizeof(struct ql4_chap_table)); | ||
| 1658 | if (bidi) | 1656 | if (bidi) |
| 1659 | chap_table->flags |= BIT_6; /* peer */ | 1657 | chap_table->flags |= BIT_6; /* peer */ |
| 1660 | else | 1658 | else |
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index 968bd85610f8..43f73583ef5c 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c | |||
| @@ -45,6 +45,8 @@ qla4_8xxx_pci_base_offsetfset(struct scsi_qla_host *ha, unsigned long off) | |||
| 45 | return NULL; | 45 | return NULL; |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | static const int MD_MIU_TEST_AGT_RDDATA[] = { 0x410000A8, | ||
| 49 | 0x410000AC, 0x410000B8, 0x410000BC }; | ||
| 48 | #define MAX_CRB_XFORM 60 | 50 | #define MAX_CRB_XFORM 60 |
| 49 | static unsigned long crb_addr_xform[MAX_CRB_XFORM]; | 51 | static unsigned long crb_addr_xform[MAX_CRB_XFORM]; |
| 50 | static int qla4_8xxx_crb_table_initialized; | 52 | static int qla4_8xxx_crb_table_initialized; |
diff --git a/drivers/scsi/qla4xxx/ql4_nx.h b/drivers/scsi/qla4xxx/ql4_nx.h index 337d9fcf6417..98fe78613eb7 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.h +++ b/drivers/scsi/qla4xxx/ql4_nx.h | |||
| @@ -1022,11 +1022,4 @@ struct qla8xxx_minidump_entry_queue { | |||
| 1022 | #define MD_MIU_TEST_AGT_WRDATA_ULO 0x410000B0 | 1022 | #define MD_MIU_TEST_AGT_WRDATA_ULO 0x410000B0 |
| 1023 | #define MD_MIU_TEST_AGT_WRDATA_UHI 0x410000B4 | 1023 | #define MD_MIU_TEST_AGT_WRDATA_UHI 0x410000B4 |
| 1024 | 1024 | ||
| 1025 | #define MD_MIU_TEST_AGT_RDDATA_LO 0x410000A8 | ||
| 1026 | #define MD_MIU_TEST_AGT_RDDATA_HI 0x410000AC | ||
| 1027 | #define MD_MIU_TEST_AGT_RDDATA_ULO 0x410000B8 | ||
| 1028 | #define MD_MIU_TEST_AGT_RDDATA_UHI 0x410000BC | ||
| 1029 | |||
| 1030 | static const int MD_MIU_TEST_AGT_RDDATA[] = { 0x410000A8, | ||
| 1031 | 0x410000AC, 0x410000B8, 0x410000BC }; | ||
| 1032 | #endif | 1025 | #endif |
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index fc2c97d9a0d6..94c14ce94da2 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c | |||
| @@ -843,12 +843,10 @@ static int qla4xxx_delete_chap(struct Scsi_Host *shost, uint16_t chap_tbl_idx) | |||
| 843 | uint32_t chap_size; | 843 | uint32_t chap_size; |
| 844 | int ret = 0; | 844 | int ret = 0; |
| 845 | 845 | ||
| 846 | chap_table = dma_pool_alloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma); | 846 | chap_table = dma_pool_zalloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma); |
| 847 | if (chap_table == NULL) | 847 | if (chap_table == NULL) |
| 848 | return -ENOMEM; | 848 | return -ENOMEM; |
| 849 | 849 | ||
| 850 | memset(chap_table, 0, sizeof(struct ql4_chap_table)); | ||
| 851 | |||
| 852 | if (is_qla80XX(ha)) | 850 | if (is_qla80XX(ha)) |
| 853 | max_chap_entries = (ha->hw.flt_chap_size / 2) / | 851 | max_chap_entries = (ha->hw.flt_chap_size / 2) / |
| 854 | sizeof(struct ql4_chap_table); | 852 | sizeof(struct ql4_chap_table); |
diff --git a/drivers/scsi/raid_class.c b/drivers/scsi/raid_class.c index 2c146b44d95f..ea88906d2cc5 100644 --- a/drivers/scsi/raid_class.c +++ b/drivers/scsi/raid_class.c | |||
| @@ -157,6 +157,7 @@ static struct { | |||
| 157 | { RAID_LEVEL_5, "raid5" }, | 157 | { RAID_LEVEL_5, "raid5" }, |
| 158 | { RAID_LEVEL_50, "raid50" }, | 158 | { RAID_LEVEL_50, "raid50" }, |
| 159 | { RAID_LEVEL_6, "raid6" }, | 159 | { RAID_LEVEL_6, "raid6" }, |
| 160 | { RAID_LEVEL_JBOD, "jbod" }, | ||
| 160 | }; | 161 | }; |
| 161 | 162 | ||
| 162 | static const char *raid_level_name(enum raid_level level) | 163 | static const char *raid_level_name(enum raid_level level) |
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index a7e4fba724b7..4c60c260c5da 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
| @@ -231,7 +231,7 @@ void scsi_finish_command(struct scsi_cmnd *cmd) | |||
| 231 | "(result %x)\n", cmd->result)); | 231 | "(result %x)\n", cmd->result)); |
| 232 | 232 | ||
| 233 | good_bytes = scsi_bufflen(cmd); | 233 | good_bytes = scsi_bufflen(cmd); |
| 234 | if (!blk_rq_is_passthrough(cmd->request)) { | 234 | if (!blk_rq_is_passthrough(cmd->request)) { |
| 235 | int old_good_bytes = good_bytes; | 235 | int old_good_bytes = good_bytes; |
| 236 | drv = scsi_cmd_to_driver(cmd); | 236 | drv = scsi_cmd_to_driver(cmd); |
| 237 | if (drv->done) | 237 | if (drv->done) |
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 1cb353f18d08..9ef5e3b810f6 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | * anything out of the ordinary is seen. | 6 | * anything out of the ordinary is seen. |
| 7 | * ^^^^^^^^^^^^^^^^^^^^^^^ Original ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | 7 | * ^^^^^^^^^^^^^^^^^^^^^^^ Original ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 8 | * | 8 | * |
| 9 | * Copyright (C) 2001 - 2017 Douglas Gilbert | 9 | * Copyright (C) 2001 - 2018 Douglas Gilbert |
| 10 | * | 10 | * |
| 11 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
| 12 | * it under the terms of the GNU General Public License as published by | 12 | * it under the terms of the GNU General Public License as published by |
| @@ -61,8 +61,8 @@ | |||
| 61 | #include "scsi_logging.h" | 61 | #include "scsi_logging.h" |
| 62 | 62 | ||
| 63 | /* make sure inq_product_rev string corresponds to this version */ | 63 | /* make sure inq_product_rev string corresponds to this version */ |
| 64 | #define SDEBUG_VERSION "0187" /* format to fit INQUIRY revision field */ | 64 | #define SDEBUG_VERSION "0188" /* format to fit INQUIRY revision field */ |
| 65 | static const char *sdebug_version_date = "20171202"; | 65 | static const char *sdebug_version_date = "20180128"; |
| 66 | 66 | ||
| 67 | #define MY_NAME "scsi_debug" | 67 | #define MY_NAME "scsi_debug" |
| 68 | 68 | ||
| @@ -234,6 +234,7 @@ static const char *sdebug_version_date = "20171202"; | |||
| 234 | #define F_INV_OP 0x200 | 234 | #define F_INV_OP 0x200 |
| 235 | #define F_FAKE_RW 0x400 | 235 | #define F_FAKE_RW 0x400 |
| 236 | #define F_M_ACCESS 0x800 /* media access */ | 236 | #define F_M_ACCESS 0x800 /* media access */ |
| 237 | #define F_LONG_DELAY 0x1000 | ||
| 237 | 238 | ||
| 238 | #define FF_RESPOND (F_RL_WLUN_OK | F_SKIP_UA | F_DELAY_OVERR) | 239 | #define FF_RESPOND (F_RL_WLUN_OK | F_SKIP_UA | F_DELAY_OVERR) |
| 239 | #define FF_MEDIA_IO (F_M_ACCESS | F_FAKE_RW) | 240 | #define FF_MEDIA_IO (F_M_ACCESS | F_FAKE_RW) |
| @@ -349,7 +350,7 @@ enum sdeb_opcode_index { | |||
| 349 | SDEB_I_XDWRITEREAD = 25, /* 10 only */ | 350 | SDEB_I_XDWRITEREAD = 25, /* 10 only */ |
| 350 | SDEB_I_WRITE_BUFFER = 26, | 351 | SDEB_I_WRITE_BUFFER = 26, |
| 351 | SDEB_I_WRITE_SAME = 27, /* 10, 16 */ | 352 | SDEB_I_WRITE_SAME = 27, /* 10, 16 */ |
| 352 | SDEB_I_SYNC_CACHE = 28, /* 10 only */ | 353 | SDEB_I_SYNC_CACHE = 28, /* 10, 16 */ |
| 353 | SDEB_I_COMP_WRITE = 29, | 354 | SDEB_I_COMP_WRITE = 29, |
| 354 | SDEB_I_LAST_ELEMENT = 30, /* keep this last (previous + 1) */ | 355 | SDEB_I_LAST_ELEMENT = 30, /* keep this last (previous + 1) */ |
| 355 | }; | 356 | }; |
| @@ -382,7 +383,7 @@ static const unsigned char opcode_ind_arr[256] = { | |||
| 382 | /* 0x80; 0x80->0x9f: 16 byte cdbs */ | 383 | /* 0x80; 0x80->0x9f: 16 byte cdbs */ |
| 383 | 0, 0, 0, 0, 0, SDEB_I_ATA_PT, 0, 0, | 384 | 0, 0, 0, 0, 0, SDEB_I_ATA_PT, 0, 0, |
| 384 | SDEB_I_READ, SDEB_I_COMP_WRITE, SDEB_I_WRITE, 0, 0, 0, 0, 0, | 385 | SDEB_I_READ, SDEB_I_COMP_WRITE, SDEB_I_WRITE, 0, 0, 0, 0, 0, |
| 385 | 0, 0, 0, SDEB_I_WRITE_SAME, 0, 0, 0, 0, | 386 | 0, SDEB_I_SYNC_CACHE, 0, SDEB_I_WRITE_SAME, 0, 0, 0, 0, |
| 386 | 0, 0, 0, 0, 0, 0, SDEB_I_SERV_ACT_IN_16, SDEB_I_SERV_ACT_OUT_16, | 387 | 0, 0, 0, 0, 0, 0, SDEB_I_SERV_ACT_IN_16, SDEB_I_SERV_ACT_OUT_16, |
| 387 | /* 0xa0; 0xa0->0xbf: 12 byte cdbs */ | 388 | /* 0xa0; 0xa0->0xbf: 12 byte cdbs */ |
| 388 | SDEB_I_REPORT_LUNS, SDEB_I_ATA_PT, 0, SDEB_I_MAINT_IN, | 389 | SDEB_I_REPORT_LUNS, SDEB_I_ATA_PT, 0, SDEB_I_MAINT_IN, |
| @@ -398,6 +399,14 @@ static const unsigned char opcode_ind_arr[256] = { | |||
| 398 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 399 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 399 | }; | 400 | }; |
| 400 | 401 | ||
| 402 | /* | ||
| 403 | * The following "response" functions return the SCSI mid-level's 4 byte | ||
| 404 | * tuple-in-an-int. To handle commands with an IMMED bit, for a faster | ||
| 405 | * command completion, they can mask their return value with | ||
| 406 | * SDEG_RES_IMMED_MASK . | ||
| 407 | */ | ||
| 408 | #define SDEG_RES_IMMED_MASK 0x40000000 | ||
| 409 | |||
| 401 | static int resp_inquiry(struct scsi_cmnd *, struct sdebug_dev_info *); | 410 | static int resp_inquiry(struct scsi_cmnd *, struct sdebug_dev_info *); |
| 402 | static int resp_report_luns(struct scsi_cmnd *, struct sdebug_dev_info *); | 411 | static int resp_report_luns(struct scsi_cmnd *, struct sdebug_dev_info *); |
| 403 | static int resp_requests(struct scsi_cmnd *, struct sdebug_dev_info *); | 412 | static int resp_requests(struct scsi_cmnd *, struct sdebug_dev_info *); |
| @@ -420,6 +429,7 @@ static int resp_write_same_16(struct scsi_cmnd *, struct sdebug_dev_info *); | |||
| 420 | static int resp_xdwriteread_10(struct scsi_cmnd *, struct sdebug_dev_info *); | 429 | static int resp_xdwriteread_10(struct scsi_cmnd *, struct sdebug_dev_info *); |
| 421 | static int resp_comp_write(struct scsi_cmnd *, struct sdebug_dev_info *); | 430 | static int resp_comp_write(struct scsi_cmnd *, struct sdebug_dev_info *); |
| 422 | static int resp_write_buffer(struct scsi_cmnd *, struct sdebug_dev_info *); | 431 | static int resp_write_buffer(struct scsi_cmnd *, struct sdebug_dev_info *); |
| 432 | static int resp_sync_cache(struct scsi_cmnd *, struct sdebug_dev_info *); | ||
| 423 | 433 | ||
| 424 | /* | 434 | /* |
| 425 | * The following are overflow arrays for cdbs that "hit" the same index in | 435 | * The following are overflow arrays for cdbs that "hit" the same index in |
| @@ -499,6 +509,12 @@ static const struct opcode_info_t release_iarr[] = { | |||
| 499 | {6, 0x1f, 0xff, 0, 0, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, | 509 | {6, 0x1f, 0xff, 0, 0, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, |
| 500 | }; | 510 | }; |
| 501 | 511 | ||
| 512 | static const struct opcode_info_t sync_cache_iarr[] = { | ||
| 513 | {0, 0x91, 0, F_LONG_DELAY | F_M_ACCESS, resp_sync_cache, NULL, | ||
| 514 | {16, 0x6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | ||
| 515 | 0xff, 0xff, 0xff, 0xff, 0x3f, 0xc7} }, /* SYNC_CACHE (16) */ | ||
| 516 | }; | ||
| 517 | |||
| 502 | 518 | ||
| 503 | /* This array is accessed via SDEB_I_* values. Make sure all are mapped, | 519 | /* This array is accessed via SDEB_I_* values. Make sure all are mapped, |
| 504 | * plus the terminating elements for logic that scans this table such as | 520 | * plus the terminating elements for logic that scans this table such as |
| @@ -536,8 +552,8 @@ static const struct opcode_info_t opcode_info_arr[SDEB_I_LAST_ELEMENT + 1] = { | |||
| 536 | {ARRAY_SIZE(write_iarr), 0x8a, 0, F_D_OUT | FF_MEDIA_IO, | 552 | {ARRAY_SIZE(write_iarr), 0x8a, 0, F_D_OUT | FF_MEDIA_IO, |
| 537 | resp_write_dt0, write_iarr, /* WRITE(16) */ | 553 | resp_write_dt0, write_iarr, /* WRITE(16) */ |
| 538 | {16, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, | 554 | {16, 0xfa, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, |
| 539 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7} }, /* WRITE(16) */ | 555 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7} }, |
| 540 | {0, 0x1b, 0, 0, resp_start_stop, NULL, /* START STOP UNIT */ | 556 | {0, 0x1b, 0, F_LONG_DELAY, resp_start_stop, NULL,/* START STOP UNIT */ |
| 541 | {6, 0x1, 0, 0xf, 0xf7, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, | 557 | {6, 0x1, 0, 0xf, 0xf7, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, |
| 542 | {ARRAY_SIZE(sa_in_16_iarr), 0x9e, 0x10, F_SA_LOW | F_D_IN, | 558 | {ARRAY_SIZE(sa_in_16_iarr), 0x9e, 0x10, F_SA_LOW | F_D_IN, |
| 543 | resp_readcap16, sa_in_16_iarr, /* SA_IN(16), READ CAPACITY(16) */ | 559 | resp_readcap16, sa_in_16_iarr, /* SA_IN(16), READ CAPACITY(16) */ |
| @@ -590,9 +606,10 @@ static const struct opcode_info_t opcode_info_arr[SDEB_I_LAST_ELEMENT + 1] = { | |||
| 590 | resp_write_same_10, write_same_iarr, /* WRITE SAME(10) */ | 606 | resp_write_same_10, write_same_iarr, /* WRITE SAME(10) */ |
| 591 | {10, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xc7, 0, | 607 | {10, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xc7, 0, |
| 592 | 0, 0, 0, 0, 0} }, | 608 | 0, 0, 0, 0, 0} }, |
| 593 | {0, 0x35, 0, F_DELAY_OVERR | FF_MEDIA_IO, NULL, NULL, /* SYNC_CACHE */ | 609 | {ARRAY_SIZE(sync_cache_iarr), 0x35, 0, F_LONG_DELAY | F_M_ACCESS, |
| 610 | resp_sync_cache, sync_cache_iarr, | ||
| 594 | {10, 0x7, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xc7, 0, 0, | 611 | {10, 0x7, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xc7, 0, 0, |
| 595 | 0, 0, 0, 0} }, | 612 | 0, 0, 0, 0} }, /* SYNC_CACHE (10) */ |
| 596 | {0, 0x89, 0, F_D_OUT | FF_MEDIA_IO, resp_comp_write, NULL, | 613 | {0, 0x89, 0, F_D_OUT | FF_MEDIA_IO, resp_comp_write, NULL, |
| 597 | {16, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, | 614 | {16, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, |
| 598 | 0, 0xff, 0x3f, 0xc7} }, /* COMPARE AND WRITE */ | 615 | 0, 0xff, 0x3f, 0xc7} }, /* COMPARE AND WRITE */ |
| @@ -616,6 +633,8 @@ static unsigned int sdebug_guard = DEF_GUARD; | |||
| 616 | static int sdebug_lowest_aligned = DEF_LOWEST_ALIGNED; | 633 | static int sdebug_lowest_aligned = DEF_LOWEST_ALIGNED; |
| 617 | static int sdebug_max_luns = DEF_MAX_LUNS; | 634 | static int sdebug_max_luns = DEF_MAX_LUNS; |
| 618 | static int sdebug_max_queue = SDEBUG_CANQUEUE; /* per submit queue */ | 635 | static int sdebug_max_queue = SDEBUG_CANQUEUE; /* per submit queue */ |
| 636 | static unsigned int sdebug_medium_error_start = OPT_MEDIUM_ERR_ADDR; | ||
| 637 | static int sdebug_medium_error_count = OPT_MEDIUM_ERR_NUM; | ||
| 619 | static atomic_t retired_max_queue; /* if > 0 then was prior max_queue */ | 638 | static atomic_t retired_max_queue; /* if > 0 then was prior max_queue */ |
| 620 | static int sdebug_ndelay = DEF_NDELAY; /* if > 0 then unit is nanoseconds */ | 639 | static int sdebug_ndelay = DEF_NDELAY; /* if > 0 then unit is nanoseconds */ |
| 621 | static int sdebug_no_lun_0 = DEF_NO_LUN_0; | 640 | static int sdebug_no_lun_0 = DEF_NO_LUN_0; |
| @@ -649,7 +668,6 @@ static bool sdebug_any_injecting_opt; | |||
| 649 | static bool sdebug_verbose; | 668 | static bool sdebug_verbose; |
| 650 | static bool have_dif_prot; | 669 | static bool have_dif_prot; |
| 651 | static bool sdebug_statistics = DEF_STATISTICS; | 670 | static bool sdebug_statistics = DEF_STATISTICS; |
| 652 | static bool sdebug_mq_active; | ||
| 653 | 671 | ||
| 654 | static unsigned int sdebug_store_sectors; | 672 | static unsigned int sdebug_store_sectors; |
| 655 | static sector_t sdebug_capacity; /* in sectors */ | 673 | static sector_t sdebug_capacity; /* in sectors */ |
| @@ -1155,8 +1173,8 @@ static int inquiry_vpd_84(unsigned char *arr) | |||
| 1155 | static int inquiry_vpd_85(unsigned char *arr) | 1173 | static int inquiry_vpd_85(unsigned char *arr) |
| 1156 | { | 1174 | { |
| 1157 | int num = 0; | 1175 | int num = 0; |
| 1158 | const char * na1 = "https://www.kernel.org/config"; | 1176 | const char *na1 = "https://www.kernel.org/config"; |
| 1159 | const char * na2 = "http://www.kernel.org/log"; | 1177 | const char *na2 = "http://www.kernel.org/log"; |
| 1160 | int plen, olen; | 1178 | int plen, olen; |
| 1161 | 1179 | ||
| 1162 | arr[num++] = 0x1; /* lu, storage config */ | 1180 | arr[num++] = 0x1; /* lu, storage config */ |
| @@ -1372,7 +1390,7 @@ static int inquiry_vpd_b2(unsigned char *arr) | |||
| 1372 | static int resp_inquiry(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) | 1390 | static int resp_inquiry(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) |
| 1373 | { | 1391 | { |
| 1374 | unsigned char pq_pdt; | 1392 | unsigned char pq_pdt; |
| 1375 | unsigned char * arr; | 1393 | unsigned char *arr; |
| 1376 | unsigned char *cmd = scp->cmnd; | 1394 | unsigned char *cmd = scp->cmnd; |
| 1377 | int alloc_len, n, ret; | 1395 | int alloc_len, n, ret; |
| 1378 | bool have_wlun, is_disk; | 1396 | bool have_wlun, is_disk; |
| @@ -1523,10 +1541,10 @@ static int resp_inquiry(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) | |||
| 1523 | static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, | 1541 | static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, |
| 1524 | 0, 0, 0x0, 0x0}; | 1542 | 0, 0, 0x0, 0x0}; |
| 1525 | 1543 | ||
| 1526 | static int resp_requests(struct scsi_cmnd * scp, | 1544 | static int resp_requests(struct scsi_cmnd *scp, |
| 1527 | struct sdebug_dev_info * devip) | 1545 | struct sdebug_dev_info *devip) |
| 1528 | { | 1546 | { |
| 1529 | unsigned char * sbuff; | 1547 | unsigned char *sbuff; |
| 1530 | unsigned char *cmd = scp->cmnd; | 1548 | unsigned char *cmd = scp->cmnd; |
| 1531 | unsigned char arr[SCSI_SENSE_BUFFERSIZE]; | 1549 | unsigned char arr[SCSI_SENSE_BUFFERSIZE]; |
| 1532 | bool dsense; | 1550 | bool dsense; |
| @@ -1584,8 +1602,8 @@ static int resp_requests(struct scsi_cmnd * scp, | |||
| 1584 | return fill_from_dev_buffer(scp, arr, len); | 1602 | return fill_from_dev_buffer(scp, arr, len); |
| 1585 | } | 1603 | } |
| 1586 | 1604 | ||
| 1587 | static int resp_start_stop(struct scsi_cmnd * scp, | 1605 | static int resp_start_stop(struct scsi_cmnd *scp, |
| 1588 | struct sdebug_dev_info * devip) | 1606 | struct sdebug_dev_info *devip) |
| 1589 | { | 1607 | { |
| 1590 | unsigned char *cmd = scp->cmnd; | 1608 | unsigned char *cmd = scp->cmnd; |
| 1591 | int power_cond, stop; | 1609 | int power_cond, stop; |
| @@ -1597,7 +1615,7 @@ static int resp_start_stop(struct scsi_cmnd * scp, | |||
| 1597 | } | 1615 | } |
| 1598 | stop = !(cmd[4] & 1); | 1616 | stop = !(cmd[4] & 1); |
| 1599 | atomic_xchg(&devip->stopped, stop); | 1617 | atomic_xchg(&devip->stopped, stop); |
| 1600 | return 0; | 1618 | return (cmd[1] & 0x1) ? SDEG_RES_IMMED_MASK : 0; /* check IMMED bit */ |
| 1601 | } | 1619 | } |
| 1602 | 1620 | ||
| 1603 | static sector_t get_sdebug_capacity(void) | 1621 | static sector_t get_sdebug_capacity(void) |
| @@ -1612,8 +1630,8 @@ static sector_t get_sdebug_capacity(void) | |||
| 1612 | } | 1630 | } |
| 1613 | 1631 | ||
| 1614 | #define SDEBUG_READCAP_ARR_SZ 8 | 1632 | #define SDEBUG_READCAP_ARR_SZ 8 |
| 1615 | static int resp_readcap(struct scsi_cmnd * scp, | 1633 | static int resp_readcap(struct scsi_cmnd *scp, |
| 1616 | struct sdebug_dev_info * devip) | 1634 | struct sdebug_dev_info *devip) |
| 1617 | { | 1635 | { |
| 1618 | unsigned char arr[SDEBUG_READCAP_ARR_SZ]; | 1636 | unsigned char arr[SDEBUG_READCAP_ARR_SZ]; |
| 1619 | unsigned int capac; | 1637 | unsigned int capac; |
| @@ -1631,8 +1649,8 @@ static int resp_readcap(struct scsi_cmnd * scp, | |||
| 1631 | } | 1649 | } |
| 1632 | 1650 | ||
| 1633 | #define SDEBUG_READCAP16_ARR_SZ 32 | 1651 | #define SDEBUG_READCAP16_ARR_SZ 32 |
| 1634 | static int resp_readcap16(struct scsi_cmnd * scp, | 1652 | static int resp_readcap16(struct scsi_cmnd *scp, |
| 1635 | struct sdebug_dev_info * devip) | 1653 | struct sdebug_dev_info *devip) |
| 1636 | { | 1654 | { |
| 1637 | unsigned char *cmd = scp->cmnd; | 1655 | unsigned char *cmd = scp->cmnd; |
| 1638 | unsigned char arr[SDEBUG_READCAP16_ARR_SZ]; | 1656 | unsigned char arr[SDEBUG_READCAP16_ARR_SZ]; |
| @@ -1670,11 +1688,11 @@ static int resp_readcap16(struct scsi_cmnd * scp, | |||
| 1670 | 1688 | ||
| 1671 | #define SDEBUG_MAX_TGTPGS_ARR_SZ 1412 | 1689 | #define SDEBUG_MAX_TGTPGS_ARR_SZ 1412 |
| 1672 | 1690 | ||
| 1673 | static int resp_report_tgtpgs(struct scsi_cmnd * scp, | 1691 | static int resp_report_tgtpgs(struct scsi_cmnd *scp, |
| 1674 | struct sdebug_dev_info * devip) | 1692 | struct sdebug_dev_info *devip) |
| 1675 | { | 1693 | { |
| 1676 | unsigned char *cmd = scp->cmnd; | 1694 | unsigned char *cmd = scp->cmnd; |
| 1677 | unsigned char * arr; | 1695 | unsigned char *arr; |
| 1678 | int host_no = devip->sdbg_host->shost->host_no; | 1696 | int host_no = devip->sdbg_host->shost->host_no; |
| 1679 | int n, ret, alen, rlen; | 1697 | int n, ret, alen, rlen; |
| 1680 | int port_group_a, port_group_b, port_a, port_b; | 1698 | int port_group_a, port_group_b, port_a, port_b; |
| @@ -1926,7 +1944,7 @@ static int resp_rsup_tmfs(struct scsi_cmnd *scp, | |||
| 1926 | 1944 | ||
| 1927 | /* <<Following mode page info copied from ST318451LW>> */ | 1945 | /* <<Following mode page info copied from ST318451LW>> */ |
| 1928 | 1946 | ||
| 1929 | static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target) | 1947 | static int resp_err_recov_pg(unsigned char *p, int pcontrol, int target) |
| 1930 | { /* Read-Write Error Recovery page for mode_sense */ | 1948 | { /* Read-Write Error Recovery page for mode_sense */ |
| 1931 | unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0, | 1949 | unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0, |
| 1932 | 5, 0, 0xff, 0xff}; | 1950 | 5, 0, 0xff, 0xff}; |
| @@ -1937,7 +1955,7 @@ static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target) | |||
| 1937 | return sizeof(err_recov_pg); | 1955 | return sizeof(err_recov_pg); |
| 1938 | } | 1956 | } |
| 1939 | 1957 | ||
| 1940 | static int resp_disconnect_pg(unsigned char * p, int pcontrol, int target) | 1958 | static int resp_disconnect_pg(unsigned char *p, int pcontrol, int target) |
| 1941 | { /* Disconnect-Reconnect page for mode_sense */ | 1959 | { /* Disconnect-Reconnect page for mode_sense */ |
| 1942 | unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0, | 1960 | unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0, |
| 1943 | 0, 0, 0, 0, 0, 0, 0, 0}; | 1961 | 0, 0, 0, 0, 0, 0, 0, 0}; |
| @@ -1948,7 +1966,7 @@ static int resp_disconnect_pg(unsigned char * p, int pcontrol, int target) | |||
| 1948 | return sizeof(disconnect_pg); | 1966 | return sizeof(disconnect_pg); |
| 1949 | } | 1967 | } |
| 1950 | 1968 | ||
| 1951 | static int resp_format_pg(unsigned char * p, int pcontrol, int target) | 1969 | static int resp_format_pg(unsigned char *p, int pcontrol, int target) |
| 1952 | { /* Format device page for mode_sense */ | 1970 | { /* Format device page for mode_sense */ |
| 1953 | unsigned char format_pg[] = {0x3, 0x16, 0, 0, 0, 0, 0, 0, | 1971 | unsigned char format_pg[] = {0x3, 0x16, 0, 0, 0, 0, 0, 0, |
| 1954 | 0, 0, 0, 0, 0, 0, 0, 0, | 1972 | 0, 0, 0, 0, 0, 0, 0, 0, |
| @@ -1968,7 +1986,7 @@ static unsigned char caching_pg[] = {0x8, 18, 0x14, 0, 0xff, 0xff, 0, 0, | |||
| 1968 | 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, | 1986 | 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, |
| 1969 | 0, 0, 0, 0}; | 1987 | 0, 0, 0, 0}; |
| 1970 | 1988 | ||
| 1971 | static int resp_caching_pg(unsigned char * p, int pcontrol, int target) | 1989 | static int resp_caching_pg(unsigned char *p, int pcontrol, int target) |
| 1972 | { /* Caching page for mode_sense */ | 1990 | { /* Caching page for mode_sense */ |
| 1973 | unsigned char ch_caching_pg[] = {/* 0x8, 18, */ 0x4, 0, 0, 0, 0, 0, | 1991 | unsigned char ch_caching_pg[] = {/* 0x8, 18, */ 0x4, 0, 0, 0, 0, 0, |
| 1974 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | 1992 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; |
| @@ -1988,7 +2006,7 @@ static int resp_caching_pg(unsigned char * p, int pcontrol, int target) | |||
| 1988 | static unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0, | 2006 | static unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0, |
| 1989 | 0, 0, 0x2, 0x4b}; | 2007 | 0, 0, 0x2, 0x4b}; |
| 1990 | 2008 | ||
| 1991 | static int resp_ctrl_m_pg(unsigned char * p, int pcontrol, int target) | 2009 | static int resp_ctrl_m_pg(unsigned char *p, int pcontrol, int target) |
| 1992 | { /* Control mode page for mode_sense */ | 2010 | { /* Control mode page for mode_sense */ |
| 1993 | unsigned char ch_ctrl_m_pg[] = {/* 0xa, 10, */ 0x6, 0, 0, 0, 0, 0, | 2011 | unsigned char ch_ctrl_m_pg[] = {/* 0xa, 10, */ 0x6, 0, 0, 0, 0, 0, |
| 1994 | 0, 0, 0, 0}; | 2012 | 0, 0, 0, 0}; |
| @@ -2012,7 +2030,7 @@ static int resp_ctrl_m_pg(unsigned char * p, int pcontrol, int target) | |||
| 2012 | } | 2030 | } |
| 2013 | 2031 | ||
| 2014 | 2032 | ||
| 2015 | static int resp_iec_m_pg(unsigned char * p, int pcontrol, int target) | 2033 | static int resp_iec_m_pg(unsigned char *p, int pcontrol, int target) |
| 2016 | { /* Informational Exceptions control mode page for mode_sense */ | 2034 | { /* Informational Exceptions control mode page for mode_sense */ |
| 2017 | unsigned char ch_iec_m_pg[] = {/* 0x1c, 0xa, */ 0x4, 0xf, 0, 0, 0, 0, | 2035 | unsigned char ch_iec_m_pg[] = {/* 0x1c, 0xa, */ 0x4, 0xf, 0, 0, 0, 0, |
| 2018 | 0, 0, 0x0, 0x0}; | 2036 | 0, 0, 0x0, 0x0}; |
| @@ -2027,7 +2045,7 @@ static int resp_iec_m_pg(unsigned char * p, int pcontrol, int target) | |||
| 2027 | return sizeof(iec_m_pg); | 2045 | return sizeof(iec_m_pg); |
| 2028 | } | 2046 | } |
| 2029 | 2047 | ||
| 2030 | static int resp_sas_sf_m_pg(unsigned char * p, int pcontrol, int target) | 2048 | static int resp_sas_sf_m_pg(unsigned char *p, int pcontrol, int target) |
| 2031 | { /* SAS SSP mode page - short format for mode_sense */ | 2049 | { /* SAS SSP mode page - short format for mode_sense */ |
| 2032 | unsigned char sas_sf_m_pg[] = {0x19, 0x6, | 2050 | unsigned char sas_sf_m_pg[] = {0x19, 0x6, |
| 2033 | 0x6, 0x0, 0x7, 0xd0, 0x0, 0x0}; | 2051 | 0x6, 0x0, 0x7, 0xd0, 0x0, 0x0}; |
| @@ -2039,7 +2057,7 @@ static int resp_sas_sf_m_pg(unsigned char * p, int pcontrol, int target) | |||
| 2039 | } | 2057 | } |
| 2040 | 2058 | ||
| 2041 | 2059 | ||
| 2042 | static int resp_sas_pcd_m_spg(unsigned char * p, int pcontrol, int target, | 2060 | static int resp_sas_pcd_m_spg(unsigned char *p, int pcontrol, int target, |
| 2043 | int target_dev_id) | 2061 | int target_dev_id) |
| 2044 | { /* SAS phy control and discover mode page for mode_sense */ | 2062 | { /* SAS phy control and discover mode page for mode_sense */ |
| 2045 | unsigned char sas_pcd_m_pg[] = {0x59, 0x1, 0, 0x64, 0, 0x6, 0, 2, | 2063 | unsigned char sas_pcd_m_pg[] = {0x59, 0x1, 0, 0x64, 0, 0x6, 0, 2, |
| @@ -2072,7 +2090,7 @@ static int resp_sas_pcd_m_spg(unsigned char * p, int pcontrol, int target, | |||
| 2072 | return sizeof(sas_pcd_m_pg); | 2090 | return sizeof(sas_pcd_m_pg); |
| 2073 | } | 2091 | } |
| 2074 | 2092 | ||
| 2075 | static int resp_sas_sha_m_spg(unsigned char * p, int pcontrol) | 2093 | static int resp_sas_sha_m_spg(unsigned char *p, int pcontrol) |
| 2076 | { /* SAS SSP shared protocol specific port mode subpage */ | 2094 | { /* SAS SSP shared protocol specific port mode subpage */ |
| 2077 | unsigned char sas_sha_m_pg[] = {0x59, 0x2, 0, 0xc, 0, 0x6, 0x10, 0, | 2095 | unsigned char sas_sha_m_pg[] = {0x59, 0x2, 0, 0xc, 0, 0x6, 0x10, 0, |
| 2078 | 0, 0, 0, 0, 0, 0, 0, 0, | 2096 | 0, 0, 0, 0, 0, 0, 0, 0, |
| @@ -2093,7 +2111,7 @@ static int resp_mode_sense(struct scsi_cmnd *scp, | |||
| 2093 | unsigned char dev_spec; | 2111 | unsigned char dev_spec; |
| 2094 | int alloc_len, offset, len, target_dev_id; | 2112 | int alloc_len, offset, len, target_dev_id; |
| 2095 | int target = scp->device->id; | 2113 | int target = scp->device->id; |
| 2096 | unsigned char * ap; | 2114 | unsigned char *ap; |
| 2097 | unsigned char arr[SDEBUG_MAX_MSENSE_SZ]; | 2115 | unsigned char arr[SDEBUG_MAX_MSENSE_SZ]; |
| 2098 | unsigned char *cmd = scp->cmnd; | 2116 | unsigned char *cmd = scp->cmnd; |
| 2099 | bool dbd, llbaa, msense_6, is_disk, bad_pcode; | 2117 | bool dbd, llbaa, msense_6, is_disk, bad_pcode; |
| @@ -2324,7 +2342,7 @@ set_mode_changed_ua: | |||
| 2324 | return 0; | 2342 | return 0; |
| 2325 | } | 2343 | } |
| 2326 | 2344 | ||
| 2327 | static int resp_temp_l_pg(unsigned char * arr) | 2345 | static int resp_temp_l_pg(unsigned char *arr) |
| 2328 | { | 2346 | { |
| 2329 | unsigned char temp_l_pg[] = {0x0, 0x0, 0x3, 0x2, 0x0, 38, | 2347 | unsigned char temp_l_pg[] = {0x0, 0x0, 0x3, 0x2, 0x0, 38, |
| 2330 | 0x0, 0x1, 0x3, 0x2, 0x0, 65, | 2348 | 0x0, 0x1, 0x3, 0x2, 0x0, 65, |
| @@ -2334,7 +2352,7 @@ static int resp_temp_l_pg(unsigned char * arr) | |||
| 2334 | return sizeof(temp_l_pg); | 2352 | return sizeof(temp_l_pg); |
| 2335 | } | 2353 | } |
| 2336 | 2354 | ||
| 2337 | static int resp_ie_l_pg(unsigned char * arr) | 2355 | static int resp_ie_l_pg(unsigned char *arr) |
| 2338 | { | 2356 | { |
| 2339 | unsigned char ie_l_pg[] = {0x0, 0x0, 0x3, 0x3, 0x0, 0x0, 38, | 2357 | unsigned char ie_l_pg[] = {0x0, 0x0, 0x3, 0x3, 0x0, 0x0, 38, |
| 2340 | }; | 2358 | }; |
| @@ -2712,8 +2730,8 @@ static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) | |||
| 2712 | } | 2730 | } |
| 2713 | 2731 | ||
| 2714 | if (unlikely((SDEBUG_OPT_MEDIUM_ERR & sdebug_opts) && | 2732 | if (unlikely((SDEBUG_OPT_MEDIUM_ERR & sdebug_opts) && |
| 2715 | (lba <= (OPT_MEDIUM_ERR_ADDR + OPT_MEDIUM_ERR_NUM - 1)) && | 2733 | (lba <= (sdebug_medium_error_start + sdebug_medium_error_count - 1)) && |
| 2716 | ((lba + num) > OPT_MEDIUM_ERR_ADDR))) { | 2734 | ((lba + num) > sdebug_medium_error_start))) { |
| 2717 | /* claim unrecoverable read error */ | 2735 | /* claim unrecoverable read error */ |
| 2718 | mk_sense_buffer(scp, MEDIUM_ERROR, UNRECOVERED_READ_ERR, 0); | 2736 | mk_sense_buffer(scp, MEDIUM_ERROR, UNRECOVERED_READ_ERR, 0); |
| 2719 | /* set info field and valid bit for fixed descriptor */ | 2737 | /* set info field and valid bit for fixed descriptor */ |
| @@ -3562,6 +3580,27 @@ static int resp_get_lba_status(struct scsi_cmnd *scp, | |||
| 3562 | return fill_from_dev_buffer(scp, arr, SDEBUG_GET_LBA_STATUS_LEN); | 3580 | return fill_from_dev_buffer(scp, arr, SDEBUG_GET_LBA_STATUS_LEN); |
| 3563 | } | 3581 | } |
| 3564 | 3582 | ||
| 3583 | static int resp_sync_cache(struct scsi_cmnd *scp, | ||
| 3584 | struct sdebug_dev_info *devip) | ||
| 3585 | { | ||
| 3586 | u64 lba; | ||
| 3587 | u32 num_blocks; | ||
| 3588 | u8 *cmd = scp->cmnd; | ||
| 3589 | |||
| 3590 | if (cmd[0] == SYNCHRONIZE_CACHE) { /* 10 byte cdb */ | ||
| 3591 | lba = get_unaligned_be32(cmd + 2); | ||
| 3592 | num_blocks = get_unaligned_be16(cmd + 7); | ||
| 3593 | } else { /* SYNCHRONIZE_CACHE(16) */ | ||
| 3594 | lba = get_unaligned_be64(cmd + 2); | ||
| 3595 | num_blocks = get_unaligned_be32(cmd + 10); | ||
| 3596 | } | ||
| 3597 | if (lba + num_blocks > sdebug_capacity) { | ||
| 3598 | mk_sense_buffer(scp, ILLEGAL_REQUEST, LBA_OUT_OF_RANGE, 0); | ||
| 3599 | return check_condition_result; | ||
| 3600 | } | ||
| 3601 | return (cmd[1] & 0x2) ? SDEG_RES_IMMED_MASK : 0; /* check IMMED bit */ | ||
| 3602 | } | ||
| 3603 | |||
| 3565 | #define RL_BUCKET_ELEMS 8 | 3604 | #define RL_BUCKET_ELEMS 8 |
| 3566 | 3605 | ||
| 3567 | /* Even though each pseudo target has a REPORT LUNS "well known logical unit" | 3606 | /* Even though each pseudo target has a REPORT LUNS "well known logical unit" |
| @@ -3727,20 +3766,13 @@ static int resp_xdwriteread_10(struct scsi_cmnd *scp, | |||
| 3727 | 3766 | ||
| 3728 | static struct sdebug_queue *get_queue(struct scsi_cmnd *cmnd) | 3767 | static struct sdebug_queue *get_queue(struct scsi_cmnd *cmnd) |
| 3729 | { | 3768 | { |
| 3730 | struct sdebug_queue *sqp = sdebug_q_arr; | 3769 | u32 tag = blk_mq_unique_tag(cmnd->request); |
| 3770 | u16 hwq = blk_mq_unique_tag_to_hwq(tag); | ||
| 3731 | 3771 | ||
| 3732 | if (sdebug_mq_active) { | 3772 | pr_debug("tag=%#x, hwq=%d\n", tag, hwq); |
| 3733 | u32 tag = blk_mq_unique_tag(cmnd->request); | 3773 | if (WARN_ON_ONCE(hwq >= submit_queues)) |
| 3734 | u16 hwq = blk_mq_unique_tag_to_hwq(tag); | 3774 | hwq = 0; |
| 3735 | 3775 | return sdebug_q_arr + hwq; | |
| 3736 | if (unlikely(hwq >= submit_queues)) { | ||
| 3737 | pr_warn("Unexpected hwq=%d, apply modulo\n", hwq); | ||
| 3738 | hwq %= submit_queues; | ||
| 3739 | } | ||
| 3740 | pr_debug("tag=%u, hwq=%d\n", tag, hwq); | ||
| 3741 | return sqp + hwq; | ||
| 3742 | } else | ||
| 3743 | return sqp; | ||
| 3744 | } | 3776 | } |
| 3745 | 3777 | ||
| 3746 | /* Queued (deferred) command completions converge here. */ | 3778 | /* Queued (deferred) command completions converge here. */ |
| @@ -4066,7 +4098,7 @@ static int scsi_debug_abort(struct scsi_cmnd *SCpnt) | |||
| 4066 | return SUCCESS; | 4098 | return SUCCESS; |
| 4067 | } | 4099 | } |
| 4068 | 4100 | ||
| 4069 | static int scsi_debug_device_reset(struct scsi_cmnd * SCpnt) | 4101 | static int scsi_debug_device_reset(struct scsi_cmnd *SCpnt) |
| 4070 | { | 4102 | { |
| 4071 | ++num_dev_resets; | 4103 | ++num_dev_resets; |
| 4072 | if (SCpnt && SCpnt->device) { | 4104 | if (SCpnt && SCpnt->device) { |
| @@ -4118,7 +4150,7 @@ lie: | |||
| 4118 | return SUCCESS; | 4150 | return SUCCESS; |
| 4119 | } | 4151 | } |
| 4120 | 4152 | ||
| 4121 | static int scsi_debug_bus_reset(struct scsi_cmnd * SCpnt) | 4153 | static int scsi_debug_bus_reset(struct scsi_cmnd *SCpnt) |
| 4122 | { | 4154 | { |
| 4123 | struct sdebug_host_info *sdbg_host; | 4155 | struct sdebug_host_info *sdbg_host; |
| 4124 | struct sdebug_dev_info *devip; | 4156 | struct sdebug_dev_info *devip; |
| @@ -4151,9 +4183,9 @@ lie: | |||
| 4151 | return SUCCESS; | 4183 | return SUCCESS; |
| 4152 | } | 4184 | } |
| 4153 | 4185 | ||
| 4154 | static int scsi_debug_host_reset(struct scsi_cmnd * SCpnt) | 4186 | static int scsi_debug_host_reset(struct scsi_cmnd *SCpnt) |
| 4155 | { | 4187 | { |
| 4156 | struct sdebug_host_info * sdbg_host; | 4188 | struct sdebug_host_info *sdbg_host; |
| 4157 | struct sdebug_dev_info *devip; | 4189 | struct sdebug_dev_info *devip; |
| 4158 | int k = 0; | 4190 | int k = 0; |
| 4159 | 4191 | ||
| @@ -4179,7 +4211,7 @@ static int scsi_debug_host_reset(struct scsi_cmnd * SCpnt) | |||
| 4179 | static void __init sdebug_build_parts(unsigned char *ramp, | 4211 | static void __init sdebug_build_parts(unsigned char *ramp, |
| 4180 | unsigned long store_size) | 4212 | unsigned long store_size) |
| 4181 | { | 4213 | { |
| 4182 | struct partition * pp; | 4214 | struct partition *pp; |
| 4183 | int starts[SDEBUG_MAX_PARTS + 2]; | 4215 | int starts[SDEBUG_MAX_PARTS + 2]; |
| 4184 | int sectors_per_part, num_sectors, k; | 4216 | int sectors_per_part, num_sectors, k; |
| 4185 | int heads_by_sects, start_sec, end_sec; | 4217 | int heads_by_sects, start_sec, end_sec; |
| @@ -4262,8 +4294,13 @@ static void clear_queue_stats(void) | |||
| 4262 | static void setup_inject(struct sdebug_queue *sqp, | 4294 | static void setup_inject(struct sdebug_queue *sqp, |
| 4263 | struct sdebug_queued_cmd *sqcp) | 4295 | struct sdebug_queued_cmd *sqcp) |
| 4264 | { | 4296 | { |
| 4265 | if ((atomic_read(&sdebug_cmnd_count) % abs(sdebug_every_nth)) > 0) | 4297 | if ((atomic_read(&sdebug_cmnd_count) % abs(sdebug_every_nth)) > 0) { |
| 4298 | if (sdebug_every_nth > 0) | ||
| 4299 | sqcp->inj_recovered = sqcp->inj_transport | ||
| 4300 | = sqcp->inj_dif | ||
| 4301 | = sqcp->inj_dix = sqcp->inj_short = 0; | ||
| 4266 | return; | 4302 | return; |
| 4303 | } | ||
| 4267 | sqcp->inj_recovered = !!(SDEBUG_OPT_RECOVERED_ERR & sdebug_opts); | 4304 | sqcp->inj_recovered = !!(SDEBUG_OPT_RECOVERED_ERR & sdebug_opts); |
| 4268 | sqcp->inj_transport = !!(SDEBUG_OPT_TRANSPORT_ERR & sdebug_opts); | 4305 | sqcp->inj_transport = !!(SDEBUG_OPT_TRANSPORT_ERR & sdebug_opts); |
| 4269 | sqcp->inj_dif = !!(SDEBUG_OPT_DIF_ERR & sdebug_opts); | 4306 | sqcp->inj_dif = !!(SDEBUG_OPT_DIF_ERR & sdebug_opts); |
| @@ -4278,7 +4315,10 @@ static void setup_inject(struct sdebug_queue *sqp, | |||
| 4278 | * SCSI_MLQUEUE_HOST_BUSY if temporarily out of resources. | 4315 | * SCSI_MLQUEUE_HOST_BUSY if temporarily out of resources. |
| 4279 | */ | 4316 | */ |
| 4280 | static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, | 4317 | static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, |
| 4281 | int scsi_result, int delta_jiff, int ndelay) | 4318 | int scsi_result, |
| 4319 | int (*pfp)(struct scsi_cmnd *, | ||
| 4320 | struct sdebug_dev_info *), | ||
| 4321 | int delta_jiff, int ndelay) | ||
| 4282 | { | 4322 | { |
| 4283 | unsigned long iflags; | 4323 | unsigned long iflags; |
| 4284 | int k, num_in_q, qdepth, inject; | 4324 | int k, num_in_q, qdepth, inject; |
| @@ -4294,9 +4334,6 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, | |||
| 4294 | } | 4334 | } |
| 4295 | sdp = cmnd->device; | 4335 | sdp = cmnd->device; |
| 4296 | 4336 | ||
| 4297 | if (unlikely(sdebug_verbose && scsi_result)) | ||
| 4298 | sdev_printk(KERN_INFO, sdp, "%s: non-zero result=0x%x\n", | ||
| 4299 | __func__, scsi_result); | ||
| 4300 | if (delta_jiff == 0) | 4337 | if (delta_jiff == 0) |
| 4301 | goto respond_in_thread; | 4338 | goto respond_in_thread; |
| 4302 | 4339 | ||
| @@ -4351,7 +4388,6 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, | |||
| 4351 | sqcp = &sqp->qc_arr[k]; | 4388 | sqcp = &sqp->qc_arr[k]; |
| 4352 | sqcp->a_cmnd = cmnd; | 4389 | sqcp->a_cmnd = cmnd; |
| 4353 | cmnd->host_scribble = (unsigned char *)sqcp; | 4390 | cmnd->host_scribble = (unsigned char *)sqcp; |
| 4354 | cmnd->result = scsi_result; | ||
| 4355 | sd_dp = sqcp->sd_dp; | 4391 | sd_dp = sqcp->sd_dp; |
| 4356 | spin_unlock_irqrestore(&sqp->qc_lock, iflags); | 4392 | spin_unlock_irqrestore(&sqp->qc_lock, iflags); |
| 4357 | if (unlikely(sdebug_every_nth && sdebug_any_injecting_opt)) | 4393 | if (unlikely(sdebug_every_nth && sdebug_any_injecting_opt)) |
| @@ -4361,6 +4397,22 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, | |||
| 4361 | if (sd_dp == NULL) | 4397 | if (sd_dp == NULL) |
| 4362 | return SCSI_MLQUEUE_HOST_BUSY; | 4398 | return SCSI_MLQUEUE_HOST_BUSY; |
| 4363 | } | 4399 | } |
| 4400 | |||
| 4401 | cmnd->result = pfp != NULL ? pfp(cmnd, devip) : 0; | ||
| 4402 | if (cmnd->result & SDEG_RES_IMMED_MASK) { | ||
| 4403 | /* | ||
| 4404 | * This is the F_DELAY_OVERR case. No delay. | ||
| 4405 | */ | ||
| 4406 | cmnd->result &= ~SDEG_RES_IMMED_MASK; | ||
| 4407 | delta_jiff = ndelay = 0; | ||
| 4408 | } | ||
| 4409 | if (cmnd->result == 0 && scsi_result != 0) | ||
| 4410 | cmnd->result = scsi_result; | ||
| 4411 | |||
| 4412 | if (unlikely(sdebug_verbose && cmnd->result)) | ||
| 4413 | sdev_printk(KERN_INFO, sdp, "%s: non-zero result=0x%x\n", | ||
| 4414 | __func__, cmnd->result); | ||
| 4415 | |||
| 4364 | if (delta_jiff > 0 || ndelay > 0) { | 4416 | if (delta_jiff > 0 || ndelay > 0) { |
| 4365 | ktime_t kt; | 4417 | ktime_t kt; |
| 4366 | 4418 | ||
| @@ -4403,7 +4455,10 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, | |||
| 4403 | return 0; | 4455 | return 0; |
| 4404 | 4456 | ||
| 4405 | respond_in_thread: /* call back to mid-layer using invocation thread */ | 4457 | respond_in_thread: /* call back to mid-layer using invocation thread */ |
| 4406 | cmnd->result = scsi_result; | 4458 | cmnd->result = pfp != NULL ? pfp(cmnd, devip) : 0; |
| 4459 | cmnd->result &= ~SDEG_RES_IMMED_MASK; | ||
| 4460 | if (cmnd->result == 0 && scsi_result != 0) | ||
| 4461 | cmnd->result = scsi_result; | ||
| 4407 | cmnd->scsi_done(cmnd); | 4462 | cmnd->scsi_done(cmnd); |
| 4408 | return 0; | 4463 | return 0; |
| 4409 | } | 4464 | } |
| @@ -4440,6 +4495,8 @@ module_param_named(lbprz, sdebug_lbprz, int, S_IRUGO); | |||
| 4440 | module_param_named(lowest_aligned, sdebug_lowest_aligned, int, S_IRUGO); | 4495 | module_param_named(lowest_aligned, sdebug_lowest_aligned, int, S_IRUGO); |
| 4441 | module_param_named(max_luns, sdebug_max_luns, int, S_IRUGO | S_IWUSR); | 4496 | module_param_named(max_luns, sdebug_max_luns, int, S_IRUGO | S_IWUSR); |
| 4442 | module_param_named(max_queue, sdebug_max_queue, int, S_IRUGO | S_IWUSR); | 4497 | module_param_named(max_queue, sdebug_max_queue, int, S_IRUGO | S_IWUSR); |
| 4498 | module_param_named(medium_error_start, sdebug_medium_error_start, int, S_IRUGO | S_IWUSR); | ||
| 4499 | module_param_named(medium_error_count, sdebug_medium_error_count, int, S_IRUGO | S_IWUSR); | ||
| 4443 | module_param_named(ndelay, sdebug_ndelay, int, S_IRUGO | S_IWUSR); | 4500 | module_param_named(ndelay, sdebug_ndelay, int, S_IRUGO | S_IWUSR); |
| 4444 | module_param_named(no_lun_0, sdebug_no_lun_0, int, S_IRUGO | S_IWUSR); | 4501 | module_param_named(no_lun_0, sdebug_no_lun_0, int, S_IRUGO | S_IWUSR); |
| 4445 | module_param_named(no_uld, sdebug_no_uld, int, S_IRUGO); | 4502 | module_param_named(no_uld, sdebug_no_uld, int, S_IRUGO); |
| @@ -4497,6 +4554,8 @@ MODULE_PARM_DESC(lbprz, | |||
| 4497 | MODULE_PARM_DESC(lowest_aligned, "lowest aligned lba (def=0)"); | 4554 | MODULE_PARM_DESC(lowest_aligned, "lowest aligned lba (def=0)"); |
| 4498 | MODULE_PARM_DESC(max_luns, "number of LUNs per target to simulate(def=1)"); | 4555 | MODULE_PARM_DESC(max_luns, "number of LUNs per target to simulate(def=1)"); |
| 4499 | MODULE_PARM_DESC(max_queue, "max number of queued commands (1 to max(def))"); | 4556 | MODULE_PARM_DESC(max_queue, "max number of queued commands (1 to max(def))"); |
| 4557 | MODULE_PARM_DESC(medium_error_start, "starting sector number to return MEDIUM error"); | ||
| 4558 | MODULE_PARM_DESC(medium_error_count, "count of sectors to return follow on MEDIUM error"); | ||
| 4500 | MODULE_PARM_DESC(ndelay, "response delay in nanoseconds (def=0 -> ignore)"); | 4559 | MODULE_PARM_DESC(ndelay, "response delay in nanoseconds (def=0 -> ignore)"); |
| 4501 | MODULE_PARM_DESC(no_lun_0, "no LU number 0 (def=0 -> have lun 0)"); | 4560 | MODULE_PARM_DESC(no_lun_0, "no LU number 0 (def=0 -> have lun 0)"); |
| 4502 | MODULE_PARM_DESC(no_uld, "stop ULD (e.g. sd driver) attaching (def=0))"); | 4561 | MODULE_PARM_DESC(no_uld, "stop ULD (e.g. sd driver) attaching (def=0))"); |
| @@ -4526,7 +4585,7 @@ MODULE_PARM_DESC(write_same_length, "Maximum blocks per WRITE SAME cmd (def=0xff | |||
| 4526 | #define SDEBUG_INFO_LEN 256 | 4585 | #define SDEBUG_INFO_LEN 256 |
| 4527 | static char sdebug_info[SDEBUG_INFO_LEN]; | 4586 | static char sdebug_info[SDEBUG_INFO_LEN]; |
| 4528 | 4587 | ||
| 4529 | static const char * scsi_debug_info(struct Scsi_Host * shp) | 4588 | static const char *scsi_debug_info(struct Scsi_Host *shp) |
| 4530 | { | 4589 | { |
| 4531 | int k; | 4590 | int k; |
| 4532 | 4591 | ||
| @@ -4587,9 +4646,8 @@ static int scsi_debug_show_info(struct seq_file *m, struct Scsi_Host *host) | |||
| 4587 | num_host_resets); | 4646 | num_host_resets); |
| 4588 | seq_printf(m, "dix_reads=%d, dix_writes=%d, dif_errors=%d\n", | 4647 | seq_printf(m, "dix_reads=%d, dix_writes=%d, dif_errors=%d\n", |
| 4589 | dix_reads, dix_writes, dif_errors); | 4648 | dix_reads, dix_writes, dif_errors); |
| 4590 | seq_printf(m, "usec_in_jiffy=%lu, %s=%d, mq_active=%d\n", | 4649 | seq_printf(m, "usec_in_jiffy=%lu, statistics=%d\n", TICK_NSEC / 1000, |
| 4591 | TICK_NSEC / 1000, "statistics", sdebug_statistics, | 4650 | sdebug_statistics); |
| 4592 | sdebug_mq_active); | ||
| 4593 | seq_printf(m, "cmnd_count=%d, completions=%d, %s=%d, a_tsf=%d\n", | 4651 | seq_printf(m, "cmnd_count=%d, completions=%d, %s=%d, a_tsf=%d\n", |
| 4594 | atomic_read(&sdebug_cmnd_count), | 4652 | atomic_read(&sdebug_cmnd_count), |
| 4595 | atomic_read(&sdebug_completions), | 4653 | atomic_read(&sdebug_completions), |
| @@ -5450,7 +5508,7 @@ static void __exit scsi_debug_exit(void) | |||
| 5450 | device_initcall(scsi_debug_init); | 5508 | device_initcall(scsi_debug_init); |
| 5451 | module_exit(scsi_debug_exit); | 5509 | module_exit(scsi_debug_exit); |
| 5452 | 5510 | ||
| 5453 | static void sdebug_release_adapter(struct device * dev) | 5511 | static void sdebug_release_adapter(struct device *dev) |
| 5454 | { | 5512 | { |
| 5455 | struct sdebug_host_info *sdbg_host; | 5513 | struct sdebug_host_info *sdbg_host; |
| 5456 | 5514 | ||
| @@ -5588,6 +5646,7 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost, | |||
| 5588 | struct sdebug_dev_info *devip; | 5646 | struct sdebug_dev_info *devip; |
| 5589 | u8 *cmd = scp->cmnd; | 5647 | u8 *cmd = scp->cmnd; |
| 5590 | int (*r_pfp)(struct scsi_cmnd *, struct sdebug_dev_info *); | 5648 | int (*r_pfp)(struct scsi_cmnd *, struct sdebug_dev_info *); |
| 5649 | int (*pfp)(struct scsi_cmnd *, struct sdebug_dev_info *) = NULL; | ||
| 5591 | int k, na; | 5650 | int k, na; |
| 5592 | int errsts = 0; | 5651 | int errsts = 0; |
| 5593 | u32 flags; | 5652 | u32 flags; |
| @@ -5612,13 +5671,8 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost, | |||
| 5612 | n += scnprintf(b + n, sb - n, "%02x ", | 5671 | n += scnprintf(b + n, sb - n, "%02x ", |
| 5613 | (u32)cmd[k]); | 5672 | (u32)cmd[k]); |
| 5614 | } | 5673 | } |
| 5615 | if (sdebug_mq_active) | 5674 | sdev_printk(KERN_INFO, sdp, "%s: tag=%#x, cmd %s\n", my_name, |
| 5616 | sdev_printk(KERN_INFO, sdp, "%s: tag=%u, cmd %s\n", | 5675 | blk_mq_unique_tag(scp->request), b); |
| 5617 | my_name, blk_mq_unique_tag(scp->request), | ||
| 5618 | b); | ||
| 5619 | else | ||
| 5620 | sdev_printk(KERN_INFO, sdp, "%s: cmd %s\n", my_name, | ||
| 5621 | b); | ||
| 5622 | } | 5676 | } |
| 5623 | if (fake_host_busy(scp)) | 5677 | if (fake_host_busy(scp)) |
| 5624 | return SCSI_MLQUEUE_HOST_BUSY; | 5678 | return SCSI_MLQUEUE_HOST_BUSY; |
| @@ -5714,20 +5768,30 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost, | |||
| 5714 | return 0; /* ignore command: make trouble */ | 5768 | return 0; /* ignore command: make trouble */ |
| 5715 | } | 5769 | } |
| 5716 | if (likely(oip->pfp)) | 5770 | if (likely(oip->pfp)) |
| 5717 | errsts = oip->pfp(scp, devip); /* calls a resp_* function */ | 5771 | pfp = oip->pfp; /* calls a resp_* function */ |
| 5718 | else if (r_pfp) /* if leaf function ptr NULL, try the root's */ | 5772 | else |
| 5719 | errsts = r_pfp(scp, devip); | 5773 | pfp = r_pfp; /* if leaf function ptr NULL, try the root's */ |
| 5720 | 5774 | ||
| 5721 | fini: | 5775 | fini: |
| 5722 | if (F_DELAY_OVERR & flags) | 5776 | if (F_DELAY_OVERR & flags) |
| 5723 | return schedule_resp(scp, devip, errsts, 0, 0); | 5777 | return schedule_resp(scp, devip, errsts, pfp, 0, 0); |
| 5724 | else | 5778 | else if ((sdebug_jdelay || sdebug_ndelay) && (flags & F_LONG_DELAY)) { |
| 5725 | return schedule_resp(scp, devip, errsts, sdebug_jdelay, | 5779 | /* |
| 5780 | * If any delay is active, want F_LONG_DELAY to be at least 1 | ||
| 5781 | * second and if sdebug_jdelay>0 want a long delay of that | ||
| 5782 | * many seconds. | ||
| 5783 | */ | ||
| 5784 | int jdelay = (sdebug_jdelay < 2) ? 1 : sdebug_jdelay; | ||
| 5785 | |||
| 5786 | jdelay = mult_frac(USER_HZ * jdelay, HZ, USER_HZ); | ||
| 5787 | return schedule_resp(scp, devip, errsts, pfp, jdelay, 0); | ||
| 5788 | } else | ||
| 5789 | return schedule_resp(scp, devip, errsts, pfp, sdebug_jdelay, | ||
| 5726 | sdebug_ndelay); | 5790 | sdebug_ndelay); |
| 5727 | check_cond: | 5791 | check_cond: |
| 5728 | return schedule_resp(scp, devip, check_condition_result, 0, 0); | 5792 | return schedule_resp(scp, devip, check_condition_result, NULL, 0, 0); |
| 5729 | err_out: | 5793 | err_out: |
| 5730 | return schedule_resp(scp, NULL, DID_NO_CONNECT << 16, 0, 0); | 5794 | return schedule_resp(scp, NULL, DID_NO_CONNECT << 16, NULL, 0, 0); |
| 5731 | } | 5795 | } |
| 5732 | 5796 | ||
| 5733 | static struct scsi_host_template sdebug_driver_template = { | 5797 | static struct scsi_host_template sdebug_driver_template = { |
| @@ -5757,7 +5821,7 @@ static struct scsi_host_template sdebug_driver_template = { | |||
| 5757 | .track_queue_depth = 1, | 5821 | .track_queue_depth = 1, |
| 5758 | }; | 5822 | }; |
| 5759 | 5823 | ||
| 5760 | static int sdebug_driver_probe(struct device * dev) | 5824 | static int sdebug_driver_probe(struct device *dev) |
| 5761 | { | 5825 | { |
| 5762 | int error = 0; | 5826 | int error = 0; |
| 5763 | struct sdebug_host_info *sdbg_host; | 5827 | struct sdebug_host_info *sdbg_host; |
| @@ -5782,8 +5846,7 @@ static int sdebug_driver_probe(struct device * dev) | |||
| 5782 | } | 5846 | } |
| 5783 | /* Decide whether to tell scsi subsystem that we want mq */ | 5847 | /* Decide whether to tell scsi subsystem that we want mq */ |
| 5784 | /* Following should give the same answer for each host */ | 5848 | /* Following should give the same answer for each host */ |
| 5785 | sdebug_mq_active = shost_use_blk_mq(hpnt) && (submit_queues > 1); | 5849 | if (shost_use_blk_mq(hpnt)) |
| 5786 | if (sdebug_mq_active) | ||
| 5787 | hpnt->nr_hw_queues = submit_queues; | 5850 | hpnt->nr_hw_queues = submit_queues; |
| 5788 | 5851 | ||
| 5789 | sdbg_host->shost = hpnt; | 5852 | sdbg_host->shost = hpnt; |
| @@ -5855,7 +5918,7 @@ static int sdebug_driver_probe(struct device * dev) | |||
| 5855 | return error; | 5918 | return error; |
| 5856 | } | 5919 | } |
| 5857 | 5920 | ||
| 5858 | static int sdebug_driver_remove(struct device * dev) | 5921 | static int sdebug_driver_remove(struct device *dev) |
| 5859 | { | 5922 | { |
| 5860 | struct sdebug_host_info *sdbg_host; | 5923 | struct sdebug_host_info *sdbg_host; |
| 5861 | struct sdebug_dev_info *sdbg_devinfo, *tmp; | 5924 | struct sdebug_dev_info *sdbg_devinfo, *tmp; |
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index f3b117246d47..e5370d718058 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c | |||
| @@ -175,11 +175,6 @@ static struct { | |||
| 175 | {"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_REPORTLUN2}, | 175 | {"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_REPORTLUN2}, |
| 176 | {"HITACHI", "HUS1530", "*", BLIST_NO_DIF}, | 176 | {"HITACHI", "HUS1530", "*", BLIST_NO_DIF}, |
| 177 | {"HITACHI", "OPEN-", "*", BLIST_REPORTLUN2 | BLIST_TRY_VPD_PAGES}, | 177 | {"HITACHI", "OPEN-", "*", BLIST_REPORTLUN2 | BLIST_TRY_VPD_PAGES}, |
| 178 | {"HITACHI", "OP-C-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, | ||
| 179 | {"HITACHI", "3380-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, | ||
| 180 | {"HITACHI", "3390-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, | ||
| 181 | {"HITACHI", "6586-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, | ||
| 182 | {"HITACHI", "6588-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, | ||
| 183 | {"HP", "A6189A", NULL, BLIST_SPARSELUN | BLIST_LARGELUN}, /* HP VA7400 */ | 178 | {"HP", "A6189A", NULL, BLIST_SPARSELUN | BLIST_LARGELUN}, /* HP VA7400 */ |
| 184 | {"HP", "OPEN-", "*", BLIST_REPORTLUN2 | BLIST_TRY_VPD_PAGES}, /* HP XP Arrays */ | 179 | {"HP", "OPEN-", "*", BLIST_REPORTLUN2 | BLIST_TRY_VPD_PAGES}, /* HP XP Arrays */ |
| 185 | {"HP", "NetRAID-4M", NULL, BLIST_FORCELUN}, | 180 | {"HP", "NetRAID-4M", NULL, BLIST_FORCELUN}, |
| @@ -187,13 +182,7 @@ static struct { | |||
| 187 | {"HP", "C1557A", NULL, BLIST_FORCELUN}, | 182 | {"HP", "C1557A", NULL, BLIST_FORCELUN}, |
| 188 | {"HP", "C3323-300", "4269", BLIST_NOTQ}, | 183 | {"HP", "C3323-300", "4269", BLIST_NOTQ}, |
| 189 | {"HP", "C5713A", NULL, BLIST_NOREPORTLUN}, | 184 | {"HP", "C5713A", NULL, BLIST_NOREPORTLUN}, |
| 190 | {"HP", "DF400", "*", BLIST_REPORTLUN2}, | 185 | {"HP", "DISK-SUBSYSTEM", "*", BLIST_REPORTLUN2}, |
| 191 | {"HP", "DF500", "*", BLIST_REPORTLUN2}, | ||
| 192 | {"HP", "OP-C-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, | ||
| 193 | {"HP", "3380-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, | ||
| 194 | {"HP", "3390-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, | ||
| 195 | {"HP", "6586-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, | ||
| 196 | {"HP", "6588-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, | ||
| 197 | {"IBM", "AuSaV1S2", NULL, BLIST_FORCELUN}, | 186 | {"IBM", "AuSaV1S2", NULL, BLIST_FORCELUN}, |
| 198 | {"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, | 187 | {"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, |
| 199 | {"IBM", "2105", NULL, BLIST_RETRY_HWERROR}, | 188 | {"IBM", "2105", NULL, BLIST_RETRY_HWERROR}, |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index ca53a5f785ee..946039117bf4 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
| @@ -117,6 +117,12 @@ static int scsi_host_eh_past_deadline(struct Scsi_Host *shost) | |||
| 117 | /** | 117 | /** |
| 118 | * scmd_eh_abort_handler - Handle command aborts | 118 | * scmd_eh_abort_handler - Handle command aborts |
| 119 | * @work: command to be aborted. | 119 | * @work: command to be aborted. |
| 120 | * | ||
| 121 | * Note: this function must be called only for a command that has timed out. | ||
| 122 | * Because the block layer marks a request as complete before it calls | ||
| 123 | * scsi_times_out(), a .scsi_done() call from the LLD for a command that has | ||
| 124 | * timed out do not have any effect. Hence it is safe to call | ||
| 125 | * scsi_finish_command() from this function. | ||
| 120 | */ | 126 | */ |
| 121 | void | 127 | void |
| 122 | scmd_eh_abort_handler(struct work_struct *work) | 128 | scmd_eh_abort_handler(struct work_struct *work) |
| @@ -1889,7 +1895,7 @@ int scsi_decide_disposition(struct scsi_cmnd *scmd) | |||
| 1889 | } | 1895 | } |
| 1890 | return FAILED; | 1896 | return FAILED; |
| 1891 | 1897 | ||
| 1892 | maybe_retry: | 1898 | maybe_retry: |
| 1893 | 1899 | ||
| 1894 | /* we requeue for retry because the error was retryable, and | 1900 | /* we requeue for retry because the error was retryable, and |
| 1895 | * the request was not marked fast fail. Note that above, | 1901 | * the request was not marked fast fail. Note that above, |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index ed79d3925860..0dfec0dedd5e 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
| @@ -191,7 +191,19 @@ static void __scsi_queue_insert(struct scsi_cmnd *cmd, int reason, bool unbusy) | |||
| 191 | */ | 191 | */ |
| 192 | cmd->result = 0; | 192 | cmd->result = 0; |
| 193 | if (q->mq_ops) { | 193 | if (q->mq_ops) { |
| 194 | scsi_mq_requeue_cmd(cmd); | 194 | /* |
| 195 | * Before a SCSI command is dispatched, | ||
| 196 | * get_device(&sdev->sdev_gendev) is called and the host, | ||
| 197 | * target and device busy counters are increased. Since | ||
| 198 | * requeuing a request causes these actions to be repeated and | ||
| 199 | * since scsi_device_unbusy() has already been called, | ||
| 200 | * put_device(&device->sdev_gendev) must still be called. Call | ||
| 201 | * put_device() after blk_mq_requeue_request() to avoid that | ||
| 202 | * removal of the SCSI device can start before requeueing has | ||
| 203 | * happened. | ||
| 204 | */ | ||
| 205 | blk_mq_requeue_request(cmd->request, true); | ||
| 206 | put_device(&device->sdev_gendev); | ||
| 195 | return; | 207 | return; |
| 196 | } | 208 | } |
| 197 | spin_lock_irqsave(q->queue_lock, flags); | 209 | spin_lock_irqsave(q->queue_lock, flags); |
| @@ -858,6 +870,17 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
| 858 | /* for passthrough error may be set */ | 870 | /* for passthrough error may be set */ |
| 859 | error = BLK_STS_OK; | 871 | error = BLK_STS_OK; |
| 860 | } | 872 | } |
| 873 | /* | ||
| 874 | * Another corner case: the SCSI status byte is non-zero but 'good'. | ||
| 875 | * Example: PRE-FETCH command returns SAM_STAT_CONDITION_MET when | ||
| 876 | * it is able to fit nominated LBs in its cache (and SAM_STAT_GOOD | ||
| 877 | * if it can't fit). Treat SAM_STAT_CONDITION_MET and the related | ||
| 878 | * intermediate statuses (both obsolete in SAM-4) as good. | ||
| 879 | */ | ||
| 880 | if (status_byte(result) && scsi_status_is_good(result)) { | ||
| 881 | result = 0; | ||
| 882 | error = BLK_STS_OK; | ||
| 883 | } | ||
| 861 | 884 | ||
| 862 | /* | 885 | /* |
| 863 | * special case: failed zero length commands always need to | 886 | * special case: failed zero length commands always need to |
| @@ -2611,7 +2634,7 @@ scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries, | |||
| 2611 | /* try to eat the UNIT_ATTENTION if there are enough retries */ | 2634 | /* try to eat the UNIT_ATTENTION if there are enough retries */ |
| 2612 | do { | 2635 | do { |
| 2613 | result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0, sshdr, | 2636 | result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, 0, sshdr, |
| 2614 | timeout, retries, NULL); | 2637 | timeout, 1, NULL); |
| 2615 | if (sdev->removable && scsi_sense_valid(sshdr) && | 2638 | if (sdev->removable && scsi_sense_valid(sshdr) && |
| 2616 | sshdr->sense_key == UNIT_ATTENTION) | 2639 | sshdr->sense_key == UNIT_ATTENTION) |
| 2617 | sdev->changed = 1; | 2640 | sdev->changed = 1; |
diff --git a/drivers/scsi/scsi_module.c b/drivers/scsi/scsi_module.c deleted file mode 100644 index 489175833709..000000000000 --- a/drivers/scsi/scsi_module.c +++ /dev/null | |||
| @@ -1,73 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2003 Christoph Hellwig. | ||
| 3 | * Released under GPL v2. | ||
| 4 | * | ||
| 5 | * Support for old-style host templates. | ||
| 6 | * | ||
| 7 | * NOTE: Do not use this for new drivers ever. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/init.h> | ||
| 11 | #include <linux/kernel.h> | ||
| 12 | #include <linux/module.h> | ||
| 13 | |||
| 14 | #include <scsi/scsi_host.h> | ||
| 15 | |||
| 16 | |||
| 17 | static int __init init_this_scsi_driver(void) | ||
| 18 | { | ||
| 19 | struct scsi_host_template *sht = &driver_template; | ||
| 20 | struct Scsi_Host *shost; | ||
| 21 | struct list_head *l; | ||
| 22 | int error; | ||
| 23 | |||
| 24 | if (!sht->release) { | ||
| 25 | printk(KERN_ERR | ||
| 26 | "scsi HBA driver %s didn't set a release method.\n", | ||
| 27 | sht->name); | ||
| 28 | return -EINVAL; | ||
| 29 | } | ||
| 30 | |||
| 31 | sht->module = THIS_MODULE; | ||
| 32 | INIT_LIST_HEAD(&sht->legacy_hosts); | ||
| 33 | |||
| 34 | sht->detect(sht); | ||
| 35 | if (list_empty(&sht->legacy_hosts)) | ||
| 36 | return -ENODEV; | ||
| 37 | |||
| 38 | list_for_each_entry(shost, &sht->legacy_hosts, sht_legacy_list) { | ||
| 39 | error = scsi_add_host(shost, NULL); | ||
| 40 | if (error) | ||
| 41 | goto fail; | ||
| 42 | scsi_scan_host(shost); | ||
| 43 | } | ||
| 44 | return 0; | ||
| 45 | fail: | ||
| 46 | l = &shost->sht_legacy_list; | ||
| 47 | while ((l = l->prev) != &sht->legacy_hosts) | ||
| 48 | scsi_remove_host(list_entry(l, struct Scsi_Host, sht_legacy_list)); | ||
| 49 | return error; | ||
| 50 | } | ||
| 51 | |||
| 52 | static void __exit exit_this_scsi_driver(void) | ||
| 53 | { | ||
| 54 | struct scsi_host_template *sht = &driver_template; | ||
| 55 | struct Scsi_Host *shost, *s; | ||
| 56 | |||
| 57 | list_for_each_entry(shost, &sht->legacy_hosts, sht_legacy_list) | ||
| 58 | scsi_remove_host(shost); | ||
| 59 | list_for_each_entry_safe(shost, s, &sht->legacy_hosts, sht_legacy_list) | ||
| 60 | sht->release(shost); | ||
| 61 | |||
| 62 | if (list_empty(&sht->legacy_hosts)) | ||
| 63 | return; | ||
| 64 | |||
| 65 | printk(KERN_WARNING "%s did not call scsi_unregister\n", sht->name); | ||
| 66 | dump_stack(); | ||
| 67 | |||
| 68 | list_for_each_entry_safe(shost, s, &sht->legacy_hosts, sht_legacy_list) | ||
| 69 | scsi_unregister(shost); | ||
| 70 | } | ||
| 71 | |||
| 72 | module_init(init_this_scsi_driver); | ||
| 73 | module_exit(exit_this_scsi_driver); | ||
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 7142c8be1099..1e36c9a9ad17 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
| @@ -1309,6 +1309,13 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) | |||
| 1309 | } | 1309 | } |
| 1310 | } | 1310 | } |
| 1311 | 1311 | ||
| 1312 | if (sdev->host->hostt->sdev_groups) { | ||
| 1313 | error = sysfs_create_groups(&sdev->sdev_gendev.kobj, | ||
| 1314 | sdev->host->hostt->sdev_groups); | ||
| 1315 | if (error) | ||
| 1316 | return error; | ||
| 1317 | } | ||
| 1318 | |||
| 1312 | scsi_autopm_put_device(sdev); | 1319 | scsi_autopm_put_device(sdev); |
| 1313 | return error; | 1320 | return error; |
| 1314 | } | 1321 | } |
| @@ -1348,6 +1355,10 @@ void __scsi_remove_device(struct scsi_device *sdev) | |||
| 1348 | if (res != 0) | 1355 | if (res != 0) |
| 1349 | return; | 1356 | return; |
| 1350 | 1357 | ||
| 1358 | if (sdev->host->hostt->sdev_groups) | ||
| 1359 | sysfs_remove_groups(&sdev->sdev_gendev.kobj, | ||
| 1360 | sdev->host->hostt->sdev_groups); | ||
| 1361 | |||
| 1351 | bsg_unregister_queue(sdev->request_queue); | 1362 | bsg_unregister_queue(sdev->request_queue); |
| 1352 | device_unregister(&sdev->sdev_dev); | 1363 | device_unregister(&sdev->sdev_dev); |
| 1353 | transport_remove_device(dev); | 1364 | transport_remove_device(dev); |
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index 871ea582029e..2ca150b16764 100644 --- a/drivers/scsi/scsi_transport_spi.c +++ b/drivers/scsi/scsi_transport_spi.c | |||
| @@ -822,11 +822,11 @@ spi_dv_device_get_echo_buffer(struct scsi_device *sdev, u8 *buffer) | |||
| 822 | * fails, the device won't let us write to the echo buffer | 822 | * fails, the device won't let us write to the echo buffer |
| 823 | * so just return failure */ | 823 | * so just return failure */ |
| 824 | 824 | ||
| 825 | const char spi_test_unit_ready[] = { | 825 | static const char spi_test_unit_ready[] = { |
| 826 | TEST_UNIT_READY, 0, 0, 0, 0, 0 | 826 | TEST_UNIT_READY, 0, 0, 0, 0, 0 |
| 827 | }; | 827 | }; |
| 828 | 828 | ||
| 829 | const char spi_read_buffer_descriptor[] = { | 829 | static const char spi_read_buffer_descriptor[] = { |
| 830 | READ_BUFFER, 0x0b, 0, 0, 0, 0, 0, 0, 4, 0 | 830 | READ_BUFFER, 0x0b, 0, 0, 0, 0, 0, 0, 4, 0 |
| 831 | }; | 831 | }; |
| 832 | 832 | ||
diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c index 89cf4498f535..41df75eea57b 100644 --- a/drivers/scsi/sd_zbc.c +++ b/drivers/scsi/sd_zbc.c | |||
| @@ -515,7 +515,8 @@ static inline unsigned long *sd_zbc_alloc_zone_bitmap(struct scsi_disk *sdkp) | |||
| 515 | * sd_zbc_get_seq_zones - Parse report zones reply to identify sequential zones | 515 | * sd_zbc_get_seq_zones - Parse report zones reply to identify sequential zones |
| 516 | * @sdkp: disk used | 516 | * @sdkp: disk used |
| 517 | * @buf: report reply buffer | 517 | * @buf: report reply buffer |
| 518 | * @seq_zone_bitamp: bitmap of sequential zones to set | 518 | * @buflen: length of @buf |
| 519 | * @seq_zones_bitmap: bitmap of sequential zones to set | ||
| 519 | * | 520 | * |
| 520 | * Parse reported zone descriptors in @buf to identify sequential zones and | 521 | * Parse reported zone descriptors in @buf to identify sequential zones and |
| 521 | * set the reported zone bit in @seq_zones_bitmap accordingly. | 522 | * set the reported zone bit in @seq_zones_bitmap accordingly. |
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 10c94011c8a8..592b6dbf8b35 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c | |||
| @@ -40,11 +40,11 @@ | |||
| 40 | #define BUILD_TIMESTAMP | 40 | #define BUILD_TIMESTAMP |
| 41 | #endif | 41 | #endif |
| 42 | 42 | ||
| 43 | #define DRIVER_VERSION "1.1.2-126" | 43 | #define DRIVER_VERSION "1.1.4-115" |
| 44 | #define DRIVER_MAJOR 1 | 44 | #define DRIVER_MAJOR 1 |
| 45 | #define DRIVER_MINOR 1 | 45 | #define DRIVER_MINOR 1 |
| 46 | #define DRIVER_RELEASE 2 | 46 | #define DRIVER_RELEASE 4 |
| 47 | #define DRIVER_REVISION 126 | 47 | #define DRIVER_REVISION 115 |
| 48 | 48 | ||
| 49 | #define DRIVER_NAME "Microsemi PQI Driver (v" \ | 49 | #define DRIVER_NAME "Microsemi PQI Driver (v" \ |
| 50 | DRIVER_VERSION BUILD_TIMESTAMP ")" | 50 | DRIVER_VERSION BUILD_TIMESTAMP ")" |
| @@ -3898,29 +3898,6 @@ static int pqi_validate_device_capability(struct pqi_ctrl_info *ctrl_info) | |||
| 3898 | return 0; | 3898 | return 0; |
| 3899 | } | 3899 | } |
| 3900 | 3900 | ||
| 3901 | static int pqi_delete_operational_queue(struct pqi_ctrl_info *ctrl_info, | ||
| 3902 | bool inbound_queue, u16 queue_id) | ||
| 3903 | { | ||
| 3904 | struct pqi_general_admin_request request; | ||
| 3905 | struct pqi_general_admin_response response; | ||
| 3906 | |||
| 3907 | memset(&request, 0, sizeof(request)); | ||
| 3908 | request.header.iu_type = PQI_REQUEST_IU_GENERAL_ADMIN; | ||
| 3909 | put_unaligned_le16(PQI_GENERAL_ADMIN_IU_LENGTH, | ||
| 3910 | &request.header.iu_length); | ||
| 3911 | if (inbound_queue) | ||
| 3912 | request.function_code = | ||
| 3913 | PQI_GENERAL_ADMIN_FUNCTION_DELETE_IQ; | ||
| 3914 | else | ||
| 3915 | request.function_code = | ||
| 3916 | PQI_GENERAL_ADMIN_FUNCTION_DELETE_OQ; | ||
| 3917 | put_unaligned_le16(queue_id, | ||
| 3918 | &request.data.delete_operational_queue.queue_id); | ||
| 3919 | |||
| 3920 | return pqi_submit_admin_request_synchronous(ctrl_info, &request, | ||
| 3921 | &response); | ||
| 3922 | } | ||
| 3923 | |||
| 3924 | static int pqi_create_event_queue(struct pqi_ctrl_info *ctrl_info) | 3901 | static int pqi_create_event_queue(struct pqi_ctrl_info *ctrl_info) |
| 3925 | { | 3902 | { |
| 3926 | int rc; | 3903 | int rc; |
| @@ -4038,7 +4015,7 @@ static int pqi_create_queue_group(struct pqi_ctrl_info *ctrl_info, | |||
| 4038 | if (rc) { | 4015 | if (rc) { |
| 4039 | dev_err(&ctrl_info->pci_dev->dev, | 4016 | dev_err(&ctrl_info->pci_dev->dev, |
| 4040 | "error creating inbound AIO queue\n"); | 4017 | "error creating inbound AIO queue\n"); |
| 4041 | goto delete_inbound_queue_raid; | 4018 | return rc; |
| 4042 | } | 4019 | } |
| 4043 | 4020 | ||
| 4044 | queue_group->iq_pi[AIO_PATH] = ctrl_info->iomem_base + | 4021 | queue_group->iq_pi[AIO_PATH] = ctrl_info->iomem_base + |
| @@ -4066,7 +4043,7 @@ static int pqi_create_queue_group(struct pqi_ctrl_info *ctrl_info, | |||
| 4066 | if (rc) { | 4043 | if (rc) { |
| 4067 | dev_err(&ctrl_info->pci_dev->dev, | 4044 | dev_err(&ctrl_info->pci_dev->dev, |
| 4068 | "error changing queue property\n"); | 4045 | "error changing queue property\n"); |
| 4069 | goto delete_inbound_queue_aio; | 4046 | return rc; |
| 4070 | } | 4047 | } |
| 4071 | 4048 | ||
| 4072 | /* | 4049 | /* |
| @@ -4096,7 +4073,7 @@ static int pqi_create_queue_group(struct pqi_ctrl_info *ctrl_info, | |||
| 4096 | if (rc) { | 4073 | if (rc) { |
| 4097 | dev_err(&ctrl_info->pci_dev->dev, | 4074 | dev_err(&ctrl_info->pci_dev->dev, |
| 4098 | "error creating outbound queue\n"); | 4075 | "error creating outbound queue\n"); |
| 4099 | goto delete_inbound_queue_aio; | 4076 | return rc; |
| 4100 | } | 4077 | } |
| 4101 | 4078 | ||
| 4102 | queue_group->oq_ci = ctrl_info->iomem_base + | 4079 | queue_group->oq_ci = ctrl_info->iomem_base + |
| @@ -4105,16 +4082,6 @@ static int pqi_create_queue_group(struct pqi_ctrl_info *ctrl_info, | |||
| 4105 | &response.data.create_operational_oq.oq_ci_offset); | 4082 | &response.data.create_operational_oq.oq_ci_offset); |
| 4106 | 4083 | ||
| 4107 | return 0; | 4084 | return 0; |
| 4108 | |||
| 4109 | delete_inbound_queue_aio: | ||
| 4110 | pqi_delete_operational_queue(ctrl_info, true, | ||
| 4111 | queue_group->iq_id[AIO_PATH]); | ||
| 4112 | |||
| 4113 | delete_inbound_queue_raid: | ||
| 4114 | pqi_delete_operational_queue(ctrl_info, true, | ||
| 4115 | queue_group->iq_id[RAID_PATH]); | ||
| 4116 | |||
| 4117 | return rc; | ||
| 4118 | } | 4085 | } |
| 4119 | 4086 | ||
| 4120 | static int pqi_create_queues(struct pqi_ctrl_info *ctrl_info) | 4087 | static int pqi_create_queues(struct pqi_ctrl_info *ctrl_info) |
| @@ -6797,6 +6764,14 @@ static __maybe_unused int pqi_resume(struct pci_dev *pci_dev) | |||
| 6797 | static const struct pci_device_id pqi_pci_id_table[] = { | 6764 | static const struct pci_device_id pqi_pci_id_table[] = { |
| 6798 | { | 6765 | { |
| 6799 | PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, | 6766 | PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, |
| 6767 | 0x105b, 0x1211) | ||
| 6768 | }, | ||
| 6769 | { | ||
| 6770 | PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, | ||
| 6771 | 0x105b, 0x1321) | ||
| 6772 | }, | ||
| 6773 | { | ||
| 6774 | PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, | ||
| 6800 | 0x152d, 0x8a22) | 6775 | 0x152d, 0x8a22) |
| 6801 | }, | 6776 | }, |
| 6802 | { | 6777 | { |
| @@ -6817,6 +6792,38 @@ static const struct pci_device_id pqi_pci_id_table[] = { | |||
| 6817 | }, | 6792 | }, |
| 6818 | { | 6793 | { |
| 6819 | PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, | 6794 | PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, |
| 6795 | 0x193d, 0x8460) | ||
| 6796 | }, | ||
| 6797 | { | ||
| 6798 | PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, | ||
| 6799 | 0x193d, 0x8461) | ||
| 6800 | }, | ||
| 6801 | { | ||
| 6802 | PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, | ||
| 6803 | 0x193d, 0xf460) | ||
| 6804 | }, | ||
| 6805 | { | ||
| 6806 | PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, | ||
| 6807 | 0x193d, 0xf461) | ||
| 6808 | }, | ||
| 6809 | { | ||
| 6810 | PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, | ||
| 6811 | 0x1bd4, 0x0045) | ||
| 6812 | }, | ||
| 6813 | { | ||
| 6814 | PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, | ||
| 6815 | 0x1bd4, 0x0046) | ||
| 6816 | }, | ||
| 6817 | { | ||
| 6818 | PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, | ||
| 6819 | 0x1bd4, 0x0047) | ||
| 6820 | }, | ||
| 6821 | { | ||
| 6822 | PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, | ||
| 6823 | 0x1bd4, 0x0048) | ||
| 6824 | }, | ||
| 6825 | { | ||
| 6826 | PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, | ||
| 6820 | PCI_VENDOR_ID_ADAPTEC2, 0x0110) | 6827 | PCI_VENDOR_ID_ADAPTEC2, 0x0110) |
| 6821 | }, | 6828 | }, |
| 6822 | { | 6829 | { |
| @@ -6917,6 +6924,10 @@ static const struct pci_device_id pqi_pci_id_table[] = { | |||
| 6917 | }, | 6924 | }, |
| 6918 | { | 6925 | { |
| 6919 | PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, | 6926 | PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, |
| 6927 | PCI_VENDOR_ID_ADAPTEC2, 0x1282) | ||
| 6928 | }, | ||
| 6929 | { | ||
| 6930 | PCI_DEVICE_SUB(PCI_VENDOR_ID_ADAPTEC2, 0x028f, | ||
| 6920 | PCI_VENDOR_ID_ADAPTEC2, 0x1300) | 6931 | PCI_VENDOR_ID_ADAPTEC2, 0x1300) |
| 6921 | }, | 6932 | }, |
| 6922 | { | 6933 | { |
diff --git a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c index d50c5ed8f428..0b1421cdf8a0 100644 --- a/drivers/scsi/sun3x_esp.c +++ b/drivers/scsi/sun3x_esp.c | |||
| @@ -210,7 +210,7 @@ static int esp_sun3x_probe(struct platform_device *dev) | |||
| 210 | esp = shost_priv(host); | 210 | esp = shost_priv(host); |
| 211 | 211 | ||
| 212 | esp->host = host; | 212 | esp->host = host; |
| 213 | esp->dev = dev; | 213 | esp->dev = &dev->dev; |
| 214 | esp->ops = &sun3x_esp_ops; | 214 | esp->ops = &sun3x_esp_ops; |
| 215 | 215 | ||
| 216 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | 216 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); |
diff --git a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c deleted file mode 100644 index 5bdcbe8fa958..000000000000 --- a/drivers/scsi/sym53c416.c +++ /dev/null | |||
| @@ -1,844 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * sym53c416.c | ||
| 3 | * Low-level SCSI driver for sym53c416 chip. | ||
| 4 | * Copyright (C) 1998 Lieven Willems (lw_linux@hotmail.com) | ||
| 5 | * | ||
| 6 | * Changes : | ||
| 7 | * | ||
| 8 | * Marcelo Tosatti <marcelo@conectiva.com.br> : Added io_request_lock locking | ||
| 9 | * Alan Cox <alan@lxorguk.ukuu.org.uk> : Cleaned up code formatting | ||
| 10 | * Fixed an irq locking bug | ||
| 11 | * Added ISAPnP support | ||
| 12 | * Bjoern A. Zeeb <bzeeb@zabbadoz.net> : Initial irq locking updates | ||
| 13 | * Added another card with ISAPnP support | ||
| 14 | * | ||
| 15 | * LILO command line usage: sym53c416=<PORTBASE>[,<IRQ>] | ||
| 16 | * | ||
| 17 | * This program is free software; you can redistribute it and/or modify it | ||
| 18 | * under the terms of the GNU General Public License as published by the | ||
| 19 | * Free Software Foundation; either version 2, or (at your option) any | ||
| 20 | * later version. | ||
| 21 | * | ||
| 22 | * This program is distributed in the hope that it will be useful, but | ||
| 23 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 25 | * General Public License for more details. | ||
| 26 | * | ||
| 27 | */ | ||
| 28 | |||
| 29 | #include <linux/module.h> | ||
| 30 | #include <linux/kernel.h> | ||
| 31 | #include <linux/types.h> | ||
| 32 | #include <linux/init.h> | ||
| 33 | #include <linux/string.h> | ||
| 34 | #include <linux/ioport.h> | ||
| 35 | #include <linux/interrupt.h> | ||
| 36 | #include <linux/delay.h> | ||
| 37 | #include <linux/proc_fs.h> | ||
| 38 | #include <linux/spinlock.h> | ||
| 39 | #include <asm/dma.h> | ||
| 40 | #include <asm/io.h> | ||
| 41 | #include <linux/blkdev.h> | ||
| 42 | #include <linux/isapnp.h> | ||
| 43 | #include "scsi.h" | ||
| 44 | #include <scsi/scsi_host.h> | ||
| 45 | #include "sym53c416.h" | ||
| 46 | |||
| 47 | #define VERSION_STRING "Version 1.0.0-ac" | ||
| 48 | |||
| 49 | #define TC_LOW 0x00 /* Transfer counter low */ | ||
| 50 | #define TC_MID 0x01 /* Transfer counter mid */ | ||
| 51 | #define SCSI_FIFO 0x02 /* SCSI FIFO register */ | ||
| 52 | #define COMMAND_REG 0x03 /* Command Register */ | ||
| 53 | #define STATUS_REG 0x04 /* Status Register (READ) */ | ||
| 54 | #define DEST_BUS_ID 0x04 /* Destination Bus ID (WRITE) */ | ||
| 55 | #define INT_REG 0x05 /* Interrupt Register (READ) */ | ||
| 56 | #define TOM 0x05 /* Time out multiplier (WRITE) */ | ||
| 57 | #define STP 0x06 /* Synchronous Transfer period */ | ||
| 58 | #define SYNC_OFFSET 0x07 /* Synchronous Offset */ | ||
| 59 | #define CONF_REG_1 0x08 /* Configuration register 1 */ | ||
| 60 | #define CONF_REG_2 0x0B /* Configuration register 2 */ | ||
| 61 | #define CONF_REG_3 0x0C /* Configuration register 3 */ | ||
| 62 | #define CONF_REG_4 0x0D /* Configuration register 4 */ | ||
| 63 | #define TC_HIGH 0x0E /* Transfer counter high */ | ||
| 64 | #define PIO_FIFO_1 0x10 /* PIO FIFO register 1 */ | ||
| 65 | #define PIO_FIFO_2 0x11 /* PIO FIFO register 2 */ | ||
| 66 | #define PIO_FIFO_3 0x12 /* PIO FIFO register 3 */ | ||
| 67 | #define PIO_FIFO_4 0x13 /* PIO FIFO register 4 */ | ||
| 68 | #define PIO_FIFO_CNT 0x14 /* PIO FIFO count */ | ||
| 69 | #define PIO_INT_REG 0x15 /* PIO interrupt register */ | ||
| 70 | #define CONF_REG_5 0x16 /* Configuration register 5 */ | ||
| 71 | #define FEATURE_EN 0x1D /* Feature Enable register */ | ||
| 72 | |||
| 73 | /* Configuration register 1 entries: */ | ||
| 74 | /* Bits 2-0: SCSI ID of host adapter */ | ||
| 75 | #define SCM 0x80 /* Slow Cable Mode */ | ||
| 76 | #define SRID 0x40 /* SCSI Reset Interrupt Disable */ | ||
| 77 | #define PTM 0x20 /* Parity Test Mode */ | ||
| 78 | #define EPC 0x10 /* Enable Parity Checking */ | ||
| 79 | #define CTME 0x08 /* Special Test Mode */ | ||
| 80 | |||
| 81 | /* Configuration register 2 entries: */ | ||
| 82 | #define FE 0x40 /* Features Enable */ | ||
| 83 | #define SCSI2 0x08 /* SCSI 2 Enable */ | ||
| 84 | #define TBPA 0x04 /* Target Bad Parity Abort */ | ||
| 85 | |||
| 86 | /* Configuration register 3 entries: */ | ||
| 87 | #define IDMRC 0x80 /* ID Message Reserved Check */ | ||
| 88 | #define QTE 0x40 /* Queue Tag Enable */ | ||
| 89 | #define CDB10 0x20 /* Command Descriptor Block 10 */ | ||
| 90 | #define FSCSI 0x10 /* FastSCSI */ | ||
| 91 | #define FCLK 0x08 /* FastClock */ | ||
| 92 | |||
| 93 | /* Configuration register 4 entries: */ | ||
| 94 | #define RBS 0x08 /* Register bank select */ | ||
| 95 | #define EAN 0x04 /* Enable Active Negotiation */ | ||
| 96 | |||
| 97 | /* Configuration register 5 entries: */ | ||
| 98 | #define LPSR 0x80 /* Lower Power SCSI Reset */ | ||
| 99 | #define IE 0x20 /* Interrupt Enable */ | ||
| 100 | #define LPM 0x02 /* Low Power Mode */ | ||
| 101 | #define WSE0 0x01 /* 0WS Enable */ | ||
| 102 | |||
| 103 | /* Interrupt register entries: */ | ||
| 104 | #define SRST 0x80 /* SCSI Reset */ | ||
| 105 | #define ILCMD 0x40 /* Illegal Command */ | ||
| 106 | #define DIS 0x20 /* Disconnect */ | ||
| 107 | #define BS 0x10 /* Bus Service */ | ||
| 108 | #define FC 0x08 /* Function Complete */ | ||
| 109 | #define RESEL 0x04 /* Reselected */ | ||
| 110 | #define SI 0x03 /* Selection Interrupt */ | ||
| 111 | |||
| 112 | /* Status Register Entries: */ | ||
| 113 | #define SCI 0x80 /* SCSI Core Int */ | ||
| 114 | #define GE 0x40 /* Gross Error */ | ||
| 115 | #define PE 0x20 /* Parity Error */ | ||
| 116 | #define TC 0x10 /* Terminal Count */ | ||
| 117 | #define VGC 0x08 /* Valid Group Code */ | ||
| 118 | #define PHBITS 0x07 /* Phase bits */ | ||
| 119 | |||
| 120 | /* PIO Interrupt Register Entries: */ | ||
| 121 | #define SCI 0x80 /* SCSI Core Int */ | ||
| 122 | #define PFI 0x40 /* PIO FIFO Interrupt */ | ||
| 123 | #define FULL 0x20 /* PIO FIFO Full */ | ||
| 124 | #define EMPTY 0x10 /* PIO FIFO Empty */ | ||
| 125 | #define CE 0x08 /* Collision Error */ | ||
| 126 | #define OUE 0x04 /* Overflow / Underflow error */ | ||
| 127 | #define FIE 0x02 /* Full Interrupt Enable */ | ||
| 128 | #define EIE 0x01 /* Empty Interrupt Enable */ | ||
| 129 | |||
| 130 | /* SYM53C416 SCSI phases (lower 3 bits of SYM53C416_STATUS_REG) */ | ||
| 131 | #define PHASE_DATA_OUT 0x00 | ||
| 132 | #define PHASE_DATA_IN 0x01 | ||
| 133 | #define PHASE_COMMAND 0x02 | ||
| 134 | #define PHASE_STATUS 0x03 | ||
| 135 | #define PHASE_RESERVED_1 0x04 | ||
| 136 | #define PHASE_RESERVED_2 0x05 | ||
| 137 | #define PHASE_MESSAGE_OUT 0x06 | ||
| 138 | #define PHASE_MESSAGE_IN 0x07 | ||
| 139 | |||
| 140 | /* SYM53C416 core commands */ | ||
| 141 | #define NOOP 0x00 | ||
| 142 | #define FLUSH_FIFO 0x01 | ||
| 143 | #define RESET_CHIP 0x02 | ||
| 144 | #define RESET_SCSI_BUS 0x03 | ||
| 145 | #define DISABLE_SEL_RESEL 0x45 | ||
| 146 | #define RESEL_SEQ 0x40 | ||
| 147 | #define SEL_WITHOUT_ATN_SEQ 0x41 | ||
| 148 | #define SEL_WITH_ATN_SEQ 0x42 | ||
| 149 | #define SEL_WITH_ATN_AND_STOP_SEQ 0x43 | ||
| 150 | #define ENABLE_SEL_RESEL 0x44 | ||
| 151 | #define SEL_WITH_ATN3_SEQ 0x46 | ||
| 152 | #define RESEL3_SEQ 0x47 | ||
| 153 | #define SND_MSG 0x20 | ||
| 154 | #define SND_STAT 0x21 | ||
| 155 | #define SND_DATA 0x22 | ||
| 156 | #define DISCONNECT_SEQ 0x23 | ||
| 157 | #define TERMINATE_SEQ 0x24 | ||
| 158 | #define TARGET_COMM_COMPLETE_SEQ 0x25 | ||
| 159 | #define DISCONN 0x27 | ||
| 160 | #define RECV_MSG_SEQ 0x28 | ||
| 161 | #define RECV_CMD 0x29 | ||
| 162 | #define RECV_DATA 0x2A | ||
| 163 | #define RECV_CMD_SEQ 0x2B | ||
| 164 | #define TARGET_ABORT_PIO 0x04 | ||
| 165 | #define TRANSFER_INFORMATION 0x10 | ||
| 166 | #define INIT_COMM_COMPLETE_SEQ 0x11 | ||
| 167 | #define MSG_ACCEPTED 0x12 | ||
| 168 | #define TRANSFER_PAD 0x18 | ||
| 169 | #define SET_ATN 0x1A | ||
| 170 | #define RESET_ATN 0x1B | ||
| 171 | #define ILLEGAL 0xFF | ||
| 172 | |||
| 173 | #define PIO_MODE 0x80 | ||
| 174 | |||
| 175 | #define IO_RANGE 0x20 /* 0x00 - 0x1F */ | ||
| 176 | #define ID "sym53c416" /* Attention: copied to the sym53c416.h */ | ||
| 177 | #define PIO_SIZE 128 /* Size of PIO fifo is 128 bytes */ | ||
| 178 | |||
| 179 | #define READ_TIMEOUT 150 | ||
| 180 | #define WRITE_TIMEOUT 150 | ||
| 181 | |||
| 182 | #ifdef MODULE | ||
| 183 | |||
| 184 | #define sym53c416_base sym53c416 | ||
| 185 | #define sym53c416_base_1 sym53c416_1 | ||
| 186 | #define sym53c416_base_2 sym53c416_2 | ||
| 187 | #define sym53c416_base_3 sym53c416_3 | ||
| 188 | |||
| 189 | static unsigned int sym53c416_base[2]; | ||
| 190 | static unsigned int sym53c416_base_1[2]; | ||
| 191 | static unsigned int sym53c416_base_2[2]; | ||
| 192 | static unsigned int sym53c416_base_3[2]; | ||
| 193 | |||
| 194 | #endif | ||
| 195 | |||
| 196 | #define MAXHOSTS 4 | ||
| 197 | |||
| 198 | #define SG_ADDRESS(buffer) ((char *) sg_virt((buffer))) | ||
| 199 | |||
| 200 | enum phases | ||
| 201 | { | ||
| 202 | idle, | ||
| 203 | data_out, | ||
| 204 | data_in, | ||
| 205 | command_ph, | ||
| 206 | status_ph, | ||
| 207 | message_out, | ||
| 208 | message_in | ||
| 209 | }; | ||
| 210 | |||
| 211 | typedef struct | ||
| 212 | { | ||
| 213 | int base; | ||
| 214 | int irq; | ||
| 215 | int scsi_id; | ||
| 216 | } host; | ||
| 217 | |||
| 218 | static host hosts[MAXHOSTS] = { | ||
| 219 | {0, 0, SYM53C416_SCSI_ID}, | ||
| 220 | {0, 0, SYM53C416_SCSI_ID}, | ||
| 221 | {0, 0, SYM53C416_SCSI_ID}, | ||
| 222 | {0, 0, SYM53C416_SCSI_ID} | ||
| 223 | }; | ||
| 224 | |||
| 225 | static int host_index = 0; | ||
| 226 | static char info[120]; | ||
| 227 | static Scsi_Cmnd *current_command = NULL; | ||
| 228 | static int fastpio = 1; | ||
| 229 | |||
| 230 | static int probeaddrs[] = {0x200, 0x220, 0x240, 0}; | ||
| 231 | |||
| 232 | static void sym53c416_set_transfer_counter(int base, unsigned int len) | ||
| 233 | { | ||
| 234 | /* Program Transfer Counter */ | ||
| 235 | outb(len & 0x0000FF, base + TC_LOW); | ||
| 236 | outb((len & 0x00FF00) >> 8, base + TC_MID); | ||
| 237 | outb((len & 0xFF0000) >> 16, base + TC_HIGH); | ||
| 238 | } | ||
| 239 | |||
| 240 | static DEFINE_SPINLOCK(sym53c416_lock); | ||
| 241 | |||
| 242 | /* Returns the number of bytes read */ | ||
| 243 | static __inline__ unsigned int sym53c416_read(int base, unsigned char *buffer, unsigned int len) | ||
| 244 | { | ||
| 245 | unsigned int orig_len = len; | ||
| 246 | unsigned long flags = 0; | ||
| 247 | unsigned int bytes_left; | ||
| 248 | unsigned long i; | ||
| 249 | int timeout = READ_TIMEOUT; | ||
| 250 | |||
| 251 | /* Do transfer */ | ||
| 252 | spin_lock_irqsave(&sym53c416_lock, flags); | ||
| 253 | while(len && timeout) | ||
| 254 | { | ||
| 255 | bytes_left = inb(base + PIO_FIFO_CNT); /* Number of bytes in the PIO FIFO */ | ||
| 256 | if(fastpio && bytes_left > 3) | ||
| 257 | { | ||
| 258 | insl(base + PIO_FIFO_1, buffer, bytes_left >> 2); | ||
| 259 | buffer += bytes_left & 0xFC; | ||
| 260 | len -= bytes_left & 0xFC; | ||
| 261 | } | ||
| 262 | else if(bytes_left > 0) | ||
| 263 | { | ||
| 264 | len -= bytes_left; | ||
| 265 | for(; bytes_left > 0; bytes_left--) | ||
| 266 | *(buffer++) = inb(base + PIO_FIFO_1); | ||
| 267 | } | ||
| 268 | else | ||
| 269 | { | ||
| 270 | i = jiffies + timeout; | ||
| 271 | spin_unlock_irqrestore(&sym53c416_lock, flags); | ||
| 272 | while(time_before(jiffies, i) && (inb(base + PIO_INT_REG) & EMPTY) && timeout) | ||
| 273 | if(inb(base + PIO_INT_REG) & SCI) | ||
| 274 | timeout = 0; | ||
| 275 | spin_lock_irqsave(&sym53c416_lock, flags); | ||
| 276 | if(inb(base + PIO_INT_REG) & EMPTY) | ||
| 277 | timeout = 0; | ||
| 278 | } | ||
| 279 | } | ||
| 280 | spin_unlock_irqrestore(&sym53c416_lock, flags); | ||
| 281 | return orig_len - len; | ||
| 282 | } | ||
| 283 | |||
| 284 | /* Returns the number of bytes written */ | ||
| 285 | static __inline__ unsigned int sym53c416_write(int base, unsigned char *buffer, unsigned int len) | ||
| 286 | { | ||
| 287 | unsigned int orig_len = len; | ||
| 288 | unsigned long flags = 0; | ||
| 289 | unsigned int bufferfree; | ||
| 290 | unsigned long i; | ||
| 291 | unsigned int timeout = WRITE_TIMEOUT; | ||
| 292 | |||
| 293 | /* Do transfer */ | ||
| 294 | spin_lock_irqsave(&sym53c416_lock, flags); | ||
| 295 | while(len && timeout) | ||
| 296 | { | ||
| 297 | bufferfree = PIO_SIZE - inb(base + PIO_FIFO_CNT); | ||
| 298 | if(bufferfree > len) | ||
| 299 | bufferfree = len; | ||
| 300 | if(fastpio && bufferfree > 3) | ||
| 301 | { | ||
| 302 | outsl(base + PIO_FIFO_1, buffer, bufferfree >> 2); | ||
| 303 | buffer += bufferfree & 0xFC; | ||
| 304 | len -= bufferfree & 0xFC; | ||
| 305 | } | ||
| 306 | else if(bufferfree > 0) | ||
| 307 | { | ||
| 308 | len -= bufferfree; | ||
| 309 | for(; bufferfree > 0; bufferfree--) | ||
| 310 | outb(*(buffer++), base + PIO_FIFO_1); | ||
| 311 | } | ||
| 312 | else | ||
| 313 | { | ||
| 314 | i = jiffies + timeout; | ||
| 315 | spin_unlock_irqrestore(&sym53c416_lock, flags); | ||
| 316 | while(time_before(jiffies, i) && (inb(base + PIO_INT_REG) & FULL) && timeout) | ||
| 317 | ; | ||
| 318 | spin_lock_irqsave(&sym53c416_lock, flags); | ||
| 319 | if(inb(base + PIO_INT_REG) & FULL) | ||
| 320 | timeout = 0; | ||
| 321 | } | ||
| 322 | } | ||
| 323 | spin_unlock_irqrestore(&sym53c416_lock, flags); | ||
| 324 | return orig_len - len; | ||
| 325 | } | ||
| 326 | |||
| 327 | static irqreturn_t sym53c416_intr_handle(int irq, void *dev_id) | ||
| 328 | { | ||
| 329 | struct Scsi_Host *dev = dev_id; | ||
| 330 | int base = dev->io_port; | ||
| 331 | int i; | ||
| 332 | unsigned long flags = 0; | ||
| 333 | unsigned char status_reg, pio_int_reg, int_reg; | ||
| 334 | struct scatterlist *sg; | ||
| 335 | unsigned int tot_trans = 0; | ||
| 336 | |||
| 337 | spin_lock_irqsave(dev->host_lock,flags); | ||
| 338 | status_reg = inb(base + STATUS_REG); | ||
| 339 | pio_int_reg = inb(base + PIO_INT_REG); | ||
| 340 | int_reg = inb(base + INT_REG); | ||
| 341 | spin_unlock_irqrestore(dev->host_lock, flags); | ||
| 342 | |||
| 343 | /* First, we handle error conditions */ | ||
| 344 | if(int_reg & SCI) /* SCSI Reset */ | ||
| 345 | { | ||
| 346 | printk(KERN_DEBUG "sym53c416: Reset received\n"); | ||
| 347 | current_command->SCp.phase = idle; | ||
| 348 | current_command->result = DID_RESET << 16; | ||
| 349 | spin_lock_irqsave(dev->host_lock, flags); | ||
| 350 | current_command->scsi_done(current_command); | ||
| 351 | spin_unlock_irqrestore(dev->host_lock, flags); | ||
| 352 | goto out; | ||
| 353 | } | ||
| 354 | if(int_reg & ILCMD) /* Illegal Command */ | ||
| 355 | { | ||
| 356 | printk(KERN_WARNING "sym53c416: Illegal Command: 0x%02x.\n", inb(base + COMMAND_REG)); | ||
| 357 | current_command->SCp.phase = idle; | ||
| 358 | current_command->result = DID_ERROR << 16; | ||
| 359 | spin_lock_irqsave(dev->host_lock, flags); | ||
| 360 | current_command->scsi_done(current_command); | ||
| 361 | spin_unlock_irqrestore(dev->host_lock, flags); | ||
| 362 | goto out; | ||
| 363 | } | ||
| 364 | if(status_reg & GE) /* Gross Error */ | ||
| 365 | { | ||
| 366 | printk(KERN_WARNING "sym53c416: Controller reports gross error.\n"); | ||
| 367 | current_command->SCp.phase = idle; | ||
| 368 | current_command->result = DID_ERROR << 16; | ||
| 369 | spin_lock_irqsave(dev->host_lock, flags); | ||
| 370 | current_command->scsi_done(current_command); | ||
| 371 | spin_unlock_irqrestore(dev->host_lock, flags); | ||
| 372 | goto out; | ||
| 373 | } | ||
| 374 | if(status_reg & PE) /* Parity Error */ | ||
| 375 | { | ||
| 376 | printk(KERN_WARNING "sym53c416:SCSI parity error.\n"); | ||
| 377 | current_command->SCp.phase = idle; | ||
| 378 | current_command->result = DID_PARITY << 16; | ||
| 379 | spin_lock_irqsave(dev->host_lock, flags); | ||
| 380 | current_command->scsi_done(current_command); | ||
| 381 | spin_unlock_irqrestore(dev->host_lock, flags); | ||
| 382 | goto out; | ||
| 383 | } | ||
| 384 | if(pio_int_reg & (CE | OUE)) | ||
| 385 | { | ||
| 386 | printk(KERN_WARNING "sym53c416: PIO interrupt error.\n"); | ||
| 387 | current_command->SCp.phase = idle; | ||
| 388 | current_command->result = DID_ERROR << 16; | ||
| 389 | spin_lock_irqsave(dev->host_lock, flags); | ||
| 390 | current_command->scsi_done(current_command); | ||
| 391 | spin_unlock_irqrestore(dev->host_lock, flags); | ||
| 392 | goto out; | ||
| 393 | } | ||
| 394 | if(int_reg & DIS) /* Disconnect */ | ||
| 395 | { | ||
| 396 | if(current_command->SCp.phase != message_in) | ||
| 397 | current_command->result = DID_NO_CONNECT << 16; | ||
| 398 | else | ||
| 399 | current_command->result = (current_command->SCp.Status & 0xFF) | ((current_command->SCp.Message & 0xFF) << 8) | (DID_OK << 16); | ||
| 400 | current_command->SCp.phase = idle; | ||
| 401 | spin_lock_irqsave(dev->host_lock, flags); | ||
| 402 | current_command->scsi_done(current_command); | ||
| 403 | spin_unlock_irqrestore(dev->host_lock, flags); | ||
| 404 | goto out; | ||
| 405 | } | ||
| 406 | /* Now we handle SCSI phases */ | ||
| 407 | |||
| 408 | switch(status_reg & PHBITS) /* Filter SCSI phase out of status reg */ | ||
| 409 | { | ||
| 410 | case PHASE_DATA_OUT: | ||
| 411 | { | ||
| 412 | if(int_reg & BS) | ||
| 413 | { | ||
| 414 | current_command->SCp.phase = data_out; | ||
| 415 | outb(FLUSH_FIFO, base + COMMAND_REG); | ||
| 416 | sym53c416_set_transfer_counter(base, | ||
| 417 | scsi_bufflen(current_command)); | ||
| 418 | outb(TRANSFER_INFORMATION | PIO_MODE, base + COMMAND_REG); | ||
| 419 | |||
| 420 | scsi_for_each_sg(current_command, | ||
| 421 | sg, scsi_sg_count(current_command), i) { | ||
| 422 | tot_trans += sym53c416_write(base, | ||
| 423 | SG_ADDRESS(sg), | ||
| 424 | sg->length); | ||
| 425 | } | ||
| 426 | if(tot_trans < current_command->underflow) | ||
| 427 | printk(KERN_WARNING "sym53c416: Underflow, wrote %d bytes, request for %d bytes.\n", tot_trans, current_command->underflow); | ||
| 428 | } | ||
| 429 | break; | ||
| 430 | } | ||
| 431 | |||
| 432 | case PHASE_DATA_IN: | ||
| 433 | { | ||
| 434 | if(int_reg & BS) | ||
| 435 | { | ||
| 436 | current_command->SCp.phase = data_in; | ||
| 437 | outb(FLUSH_FIFO, base + COMMAND_REG); | ||
| 438 | sym53c416_set_transfer_counter(base, | ||
| 439 | scsi_bufflen(current_command)); | ||
| 440 | |||
| 441 | outb(TRANSFER_INFORMATION | PIO_MODE, base + COMMAND_REG); | ||
| 442 | |||
| 443 | scsi_for_each_sg(current_command, | ||
| 444 | sg, scsi_sg_count(current_command), i) { | ||
| 445 | tot_trans += sym53c416_read(base, | ||
| 446 | SG_ADDRESS(sg), | ||
| 447 | sg->length); | ||
| 448 | } | ||
| 449 | if(tot_trans < current_command->underflow) | ||
| 450 | printk(KERN_WARNING "sym53c416: Underflow, read %d bytes, request for %d bytes.\n", tot_trans, current_command->underflow); | ||
| 451 | } | ||
| 452 | break; | ||
| 453 | } | ||
| 454 | |||
| 455 | case PHASE_COMMAND: | ||
| 456 | { | ||
| 457 | current_command->SCp.phase = command_ph; | ||
| 458 | printk(KERN_ERR "sym53c416: Unknown interrupt in command phase.\n"); | ||
| 459 | break; | ||
| 460 | } | ||
| 461 | |||
| 462 | case PHASE_STATUS: | ||
| 463 | { | ||
| 464 | current_command->SCp.phase = status_ph; | ||
| 465 | outb(FLUSH_FIFO, base + COMMAND_REG); | ||
| 466 | outb(INIT_COMM_COMPLETE_SEQ, base + COMMAND_REG); | ||
| 467 | break; | ||
| 468 | } | ||
| 469 | |||
| 470 | case PHASE_RESERVED_1: | ||
| 471 | case PHASE_RESERVED_2: | ||
| 472 | { | ||
| 473 | printk(KERN_ERR "sym53c416: Reserved phase occurred.\n"); | ||
| 474 | break; | ||
| 475 | } | ||
| 476 | |||
| 477 | case PHASE_MESSAGE_OUT: | ||
| 478 | { | ||
| 479 | current_command->SCp.phase = message_out; | ||
| 480 | outb(SET_ATN, base + COMMAND_REG); | ||
| 481 | outb(MSG_ACCEPTED, base + COMMAND_REG); | ||
| 482 | break; | ||
| 483 | } | ||
| 484 | |||
| 485 | case PHASE_MESSAGE_IN: | ||
| 486 | { | ||
| 487 | current_command->SCp.phase = message_in; | ||
| 488 | current_command->SCp.Status = inb(base + SCSI_FIFO); | ||
| 489 | current_command->SCp.Message = inb(base + SCSI_FIFO); | ||
| 490 | if(current_command->SCp.Message == SAVE_POINTERS || current_command->SCp.Message == DISCONNECT) | ||
| 491 | outb(SET_ATN, base + COMMAND_REG); | ||
| 492 | outb(MSG_ACCEPTED, base + COMMAND_REG); | ||
| 493 | break; | ||
| 494 | } | ||
| 495 | } | ||
| 496 | out: | ||
| 497 | return IRQ_HANDLED; | ||
| 498 | } | ||
| 499 | |||
| 500 | static void sym53c416_init(int base, int scsi_id) | ||
| 501 | { | ||
| 502 | outb(RESET_CHIP, base + COMMAND_REG); | ||
| 503 | outb(NOOP, base + COMMAND_REG); | ||
| 504 | outb(0x99, base + TOM); /* Time out of 250 ms */ | ||
| 505 | outb(0x05, base + STP); | ||
| 506 | outb(0x00, base + SYNC_OFFSET); | ||
| 507 | outb(EPC | scsi_id, base + CONF_REG_1); | ||
| 508 | outb(FE | SCSI2 | TBPA, base + CONF_REG_2); | ||
| 509 | outb(IDMRC | QTE | CDB10 | FSCSI | FCLK, base + CONF_REG_3); | ||
| 510 | outb(0x83 | EAN, base + CONF_REG_4); | ||
| 511 | outb(IE | WSE0, base + CONF_REG_5); | ||
| 512 | outb(0, base + FEATURE_EN); | ||
| 513 | } | ||
| 514 | |||
| 515 | static int sym53c416_probeirq(int base, int scsi_id) | ||
| 516 | { | ||
| 517 | int irq, irqs; | ||
| 518 | unsigned long i; | ||
| 519 | |||
| 520 | /* Clear interrupt register */ | ||
| 521 | inb(base + INT_REG); | ||
| 522 | /* Start probing for irq's */ | ||
| 523 | irqs = probe_irq_on(); | ||
| 524 | /* Reinit chip */ | ||
| 525 | sym53c416_init(base, scsi_id); | ||
| 526 | /* Cause interrupt */ | ||
| 527 | outb(NOOP, base + COMMAND_REG); | ||
| 528 | outb(ILLEGAL, base + COMMAND_REG); | ||
| 529 | outb(0x07, base + DEST_BUS_ID); | ||
| 530 | outb(0x00, base + DEST_BUS_ID); | ||
| 531 | /* Wait for interrupt to occur */ | ||
| 532 | i = jiffies + 20; | ||
| 533 | while(time_before(jiffies, i) && !(inb(base + STATUS_REG) & SCI)) | ||
| 534 | barrier(); | ||
| 535 | if(time_before_eq(i, jiffies)) /* timed out */ | ||
| 536 | return 0; | ||
| 537 | /* Get occurred irq */ | ||
| 538 | irq = probe_irq_off(irqs); | ||
| 539 | sym53c416_init(base, scsi_id); | ||
| 540 | return irq; | ||
| 541 | } | ||
| 542 | |||
| 543 | /* Setup: sym53c416=base,irq */ | ||
| 544 | void sym53c416_setup(char *str, int *ints) | ||
| 545 | { | ||
| 546 | int i; | ||
| 547 | |||
| 548 | if(host_index >= MAXHOSTS) | ||
| 549 | { | ||
| 550 | printk(KERN_WARNING "sym53c416: Too many hosts defined\n"); | ||
| 551 | return; | ||
| 552 | } | ||
| 553 | if(ints[0] < 1 || ints[0] > 2) | ||
| 554 | { | ||
| 555 | printk(KERN_ERR "sym53c416: Wrong number of parameters:\n"); | ||
| 556 | printk(KERN_ERR "sym53c416: usage: sym53c416=<base>[,<irq>]\n"); | ||
| 557 | return; | ||
| 558 | } | ||
| 559 | for(i = 0; i < host_index && i >= 0; i++) | ||
| 560 | if(hosts[i].base == ints[1]) | ||
| 561 | i = -2; | ||
| 562 | if(i >= 0) | ||
| 563 | { | ||
| 564 | hosts[host_index].base = ints[1]; | ||
| 565 | hosts[host_index].irq = (ints[0] == 2)? ints[2] : 0; | ||
| 566 | host_index++; | ||
| 567 | } | ||
| 568 | } | ||
| 569 | |||
| 570 | static int sym53c416_test(int base) | ||
| 571 | { | ||
| 572 | outb(RESET_CHIP, base + COMMAND_REG); | ||
| 573 | outb(NOOP, base + COMMAND_REG); | ||
| 574 | if(inb(base + COMMAND_REG) != NOOP) | ||
| 575 | return 0; | ||
| 576 | if(!inb(base + TC_HIGH) || inb(base + TC_HIGH) == 0xFF) | ||
| 577 | return 0; | ||
| 578 | if((inb(base + PIO_INT_REG) & (FULL | EMPTY | CE | OUE | FIE | EIE)) != EMPTY) | ||
| 579 | return 0; | ||
| 580 | return 1; | ||
| 581 | } | ||
| 582 | |||
| 583 | |||
| 584 | static struct isapnp_device_id id_table[] = { | ||
| 585 | { ISAPNP_ANY_ID, ISAPNP_ANY_ID, | ||
| 586 | ISAPNP_VENDOR('S','L','I'), ISAPNP_FUNCTION(0x4161), 0 }, | ||
| 587 | { ISAPNP_ANY_ID, ISAPNP_ANY_ID, | ||
| 588 | ISAPNP_VENDOR('S','L','I'), ISAPNP_FUNCTION(0x4163), 0 }, | ||
| 589 | { ISAPNP_DEVICE_SINGLE_END } | ||
| 590 | }; | ||
| 591 | |||
| 592 | MODULE_DEVICE_TABLE(isapnp, id_table); | ||
| 593 | |||
| 594 | static void sym53c416_probe(void) | ||
| 595 | { | ||
| 596 | int *base = probeaddrs; | ||
| 597 | int ints[2]; | ||
| 598 | |||
| 599 | ints[0] = 1; | ||
| 600 | for(; *base; base++) { | ||
| 601 | if (request_region(*base, IO_RANGE, ID)) { | ||
| 602 | if (sym53c416_test(*base)) { | ||
| 603 | ints[1] = *base; | ||
| 604 | sym53c416_setup(NULL, ints); | ||
| 605 | } | ||
| 606 | release_region(*base, IO_RANGE); | ||
| 607 | } | ||
| 608 | } | ||
| 609 | } | ||
| 610 | |||
| 611 | int __init sym53c416_detect(struct scsi_host_template *tpnt) | ||
| 612 | { | ||
| 613 | unsigned long flags; | ||
| 614 | struct Scsi_Host * shpnt = NULL; | ||
| 615 | int i; | ||
| 616 | int count; | ||
| 617 | struct pnp_dev *idev = NULL; | ||
| 618 | |||
| 619 | #ifdef MODULE | ||
| 620 | int ints[3]; | ||
| 621 | |||
| 622 | ints[0] = 2; | ||
| 623 | if(sym53c416_base[0]) | ||
| 624 | { | ||
| 625 | ints[1] = sym53c416_base[0]; | ||
| 626 | ints[2] = sym53c416_base[1]; | ||
| 627 | sym53c416_setup(NULL, ints); | ||
| 628 | } | ||
| 629 | if(sym53c416_base_1[0]) | ||
| 630 | { | ||
| 631 | ints[1] = sym53c416_base_1[0]; | ||
| 632 | ints[2] = sym53c416_base_1[1]; | ||
| 633 | sym53c416_setup(NULL, ints); | ||
| 634 | } | ||
| 635 | if(sym53c416_base_2[0]) | ||
| 636 | { | ||
| 637 | ints[1] = sym53c416_base_2[0]; | ||
| 638 | ints[2] = sym53c416_base_2[1]; | ||
| 639 | sym53c416_setup(NULL, ints); | ||
| 640 | } | ||
| 641 | if(sym53c416_base_3[0]) | ||
| 642 | { | ||
| 643 | ints[1] = sym53c416_base_3[0]; | ||
| 644 | ints[2] = sym53c416_base_3[1]; | ||
| 645 | sym53c416_setup(NULL, ints); | ||
| 646 | } | ||
| 647 | #endif | ||
| 648 | printk(KERN_INFO "sym53c416.c: %s\n", VERSION_STRING); | ||
| 649 | |||
| 650 | for (i=0; id_table[i].vendor != 0; i++) { | ||
| 651 | while((idev=pnp_find_dev(NULL, id_table[i].vendor, | ||
| 652 | id_table[i].function, idev))!=NULL) | ||
| 653 | { | ||
| 654 | int i[3]; | ||
| 655 | |||
| 656 | if(pnp_device_attach(idev)<0) | ||
| 657 | { | ||
| 658 | printk(KERN_WARNING "sym53c416: unable to attach PnP device.\n"); | ||
| 659 | continue; | ||
| 660 | } | ||
| 661 | if(pnp_activate_dev(idev) < 0) | ||
| 662 | { | ||
| 663 | printk(KERN_WARNING "sym53c416: unable to activate PnP device.\n"); | ||
| 664 | pnp_device_detach(idev); | ||
| 665 | continue; | ||
| 666 | |||
| 667 | } | ||
| 668 | |||
| 669 | i[0] = 2; | ||
| 670 | i[1] = pnp_port_start(idev, 0); | ||
| 671 | i[2] = pnp_irq(idev, 0); | ||
| 672 | |||
| 673 | printk(KERN_INFO "sym53c416: ISAPnP card found and configured at 0x%X, IRQ %d.\n", | ||
| 674 | i[1], i[2]); | ||
| 675 | sym53c416_setup(NULL, i); | ||
| 676 | } | ||
| 677 | } | ||
| 678 | sym53c416_probe(); | ||
| 679 | |||
| 680 | /* Now we register and set up each host adapter found... */ | ||
| 681 | for(count = 0, i = 0; i < host_index; i++) { | ||
| 682 | if (!request_region(hosts[i].base, IO_RANGE, ID)) | ||
| 683 | continue; | ||
| 684 | if (!sym53c416_test(hosts[i].base)) { | ||
| 685 | printk(KERN_WARNING "No sym53c416 found at address 0x%03x\n", hosts[i].base); | ||
| 686 | goto fail_release_region; | ||
| 687 | } | ||
| 688 | |||
| 689 | /* We don't have an irq yet, so we should probe for one */ | ||
| 690 | if (!hosts[i].irq) | ||
| 691 | hosts[i].irq = sym53c416_probeirq(hosts[i].base, hosts[i].scsi_id); | ||
| 692 | if (!hosts[i].irq) | ||
| 693 | goto fail_release_region; | ||
| 694 | |||
| 695 | shpnt = scsi_register(tpnt, 0); | ||
| 696 | if (!shpnt) | ||
| 697 | goto fail_release_region; | ||
| 698 | /* Request for specified IRQ */ | ||
| 699 | if (request_irq(hosts[i].irq, sym53c416_intr_handle, 0, ID, shpnt)) | ||
| 700 | goto fail_free_host; | ||
| 701 | |||
| 702 | spin_lock_irqsave(&sym53c416_lock, flags); | ||
| 703 | shpnt->unique_id = hosts[i].base; | ||
| 704 | shpnt->io_port = hosts[i].base; | ||
| 705 | shpnt->n_io_port = IO_RANGE; | ||
| 706 | shpnt->irq = hosts[i].irq; | ||
| 707 | shpnt->this_id = hosts[i].scsi_id; | ||
| 708 | sym53c416_init(hosts[i].base, hosts[i].scsi_id); | ||
| 709 | count++; | ||
| 710 | spin_unlock_irqrestore(&sym53c416_lock, flags); | ||
| 711 | continue; | ||
| 712 | |||
| 713 | fail_free_host: | ||
| 714 | scsi_unregister(shpnt); | ||
| 715 | fail_release_region: | ||
| 716 | release_region(hosts[i].base, IO_RANGE); | ||
| 717 | } | ||
| 718 | return count; | ||
| 719 | } | ||
| 720 | |||
| 721 | const char *sym53c416_info(struct Scsi_Host *SChost) | ||
| 722 | { | ||
| 723 | int i; | ||
| 724 | int base = SChost->io_port; | ||
| 725 | int irq = SChost->irq; | ||
| 726 | int scsi_id = 0; | ||
| 727 | int rev = inb(base + TC_HIGH); | ||
| 728 | |||
| 729 | for(i = 0; i < host_index; i++) | ||
| 730 | if(hosts[i].base == base) | ||
| 731 | scsi_id = hosts[i].scsi_id; | ||
| 732 | sprintf(info, "Symbios Logic 53c416 (rev. %d) at 0x%03x, irq %d, SCSI-ID %d, %s pio", rev, base, irq, scsi_id, (fastpio)? "fast" : "slow"); | ||
| 733 | return info; | ||
| 734 | } | ||
| 735 | |||
| 736 | static int sym53c416_queuecommand_lck(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) | ||
| 737 | { | ||
| 738 | int base; | ||
| 739 | unsigned long flags = 0; | ||
| 740 | int i; | ||
| 741 | |||
| 742 | /* Store base register as we can have more than one controller in the system */ | ||
| 743 | base = SCpnt->device->host->io_port; | ||
| 744 | current_command = SCpnt; /* set current command */ | ||
| 745 | current_command->scsi_done = done; /* set ptr to done function */ | ||
| 746 | current_command->SCp.phase = command_ph; /* currect phase is the command phase */ | ||
| 747 | current_command->SCp.Status = 0; | ||
| 748 | current_command->SCp.Message = 0; | ||
| 749 | |||
| 750 | spin_lock_irqsave(&sym53c416_lock, flags); | ||
| 751 | outb(scmd_id(SCpnt), base + DEST_BUS_ID); /* Set scsi id target */ | ||
| 752 | outb(FLUSH_FIFO, base + COMMAND_REG); /* Flush SCSI and PIO FIFO's */ | ||
| 753 | /* Write SCSI command into the SCSI fifo */ | ||
| 754 | for(i = 0; i < SCpnt->cmd_len; i++) | ||
| 755 | outb(SCpnt->cmnd[i], base + SCSI_FIFO); | ||
| 756 | /* Start selection sequence */ | ||
| 757 | outb(SEL_WITHOUT_ATN_SEQ, base + COMMAND_REG); | ||
| 758 | /* Now an interrupt will be generated which we will catch in out interrupt routine */ | ||
| 759 | spin_unlock_irqrestore(&sym53c416_lock, flags); | ||
| 760 | return 0; | ||
| 761 | } | ||
| 762 | |||
| 763 | DEF_SCSI_QCMD(sym53c416_queuecommand) | ||
| 764 | |||
| 765 | static int sym53c416_host_reset(Scsi_Cmnd *SCpnt) | ||
| 766 | { | ||
| 767 | int base; | ||
| 768 | int scsi_id = -1; | ||
| 769 | int i; | ||
| 770 | unsigned long flags; | ||
| 771 | |||
| 772 | spin_lock_irqsave(&sym53c416_lock, flags); | ||
| 773 | |||
| 774 | /* printk("sym53c416_reset\n"); */ | ||
| 775 | base = SCpnt->device->host->io_port; | ||
| 776 | /* search scsi_id - fixme, we shouldn't need to iterate for this! */ | ||
| 777 | for(i = 0; i < host_index && scsi_id == -1; i++) | ||
| 778 | if(hosts[i].base == base) | ||
| 779 | scsi_id = hosts[i].scsi_id; | ||
| 780 | outb(RESET_CHIP, base + COMMAND_REG); | ||
| 781 | outb(NOOP | PIO_MODE, base + COMMAND_REG); | ||
| 782 | outb(RESET_SCSI_BUS, base + COMMAND_REG); | ||
| 783 | sym53c416_init(base, scsi_id); | ||
| 784 | |||
| 785 | spin_unlock_irqrestore(&sym53c416_lock, flags); | ||
| 786 | return SUCCESS; | ||
| 787 | } | ||
| 788 | |||
| 789 | static int sym53c416_release(struct Scsi_Host *shost) | ||
| 790 | { | ||
| 791 | if (shost->irq) | ||
| 792 | free_irq(shost->irq, shost); | ||
| 793 | if (shost->io_port && shost->n_io_port) | ||
| 794 | release_region(shost->io_port, shost->n_io_port); | ||
| 795 | return 0; | ||
| 796 | } | ||
| 797 | |||
| 798 | static int sym53c416_bios_param(struct scsi_device *sdev, | ||
| 799 | struct block_device *dev, | ||
| 800 | sector_t capacity, int *ip) | ||
| 801 | { | ||
| 802 | int size; | ||
| 803 | |||
| 804 | size = capacity; | ||
| 805 | ip[0] = 64; /* heads */ | ||
| 806 | ip[1] = 32; /* sectors */ | ||
| 807 | if((ip[2] = size >> 11) > 1024) /* cylinders, test for big disk */ | ||
| 808 | { | ||
| 809 | ip[0] = 255; /* heads */ | ||
| 810 | ip[1] = 63; /* sectors */ | ||
| 811 | ip[2] = size / (255 * 63); /* cylinders */ | ||
| 812 | } | ||
| 813 | return 0; | ||
| 814 | } | ||
| 815 | |||
| 816 | /* Loadable module support */ | ||
| 817 | #ifdef MODULE | ||
| 818 | |||
| 819 | MODULE_AUTHOR("Lieven Willems"); | ||
| 820 | MODULE_LICENSE("GPL"); | ||
| 821 | |||
| 822 | module_param_array(sym53c416, uint, NULL, 0); | ||
| 823 | module_param_array(sym53c416_1, uint, NULL, 0); | ||
| 824 | module_param_array(sym53c416_2, uint, NULL, 0); | ||
| 825 | module_param_array(sym53c416_3, uint, NULL, 0); | ||
| 826 | |||
| 827 | #endif | ||
| 828 | |||
| 829 | static struct scsi_host_template driver_template = { | ||
| 830 | .proc_name = "sym53c416", | ||
| 831 | .name = "Symbios Logic 53c416", | ||
| 832 | .detect = sym53c416_detect, | ||
| 833 | .info = sym53c416_info, | ||
| 834 | .queuecommand = sym53c416_queuecommand, | ||
| 835 | .eh_host_reset_handler =sym53c416_host_reset, | ||
| 836 | .release = sym53c416_release, | ||
| 837 | .bios_param = sym53c416_bios_param, | ||
| 838 | .can_queue = 1, | ||
| 839 | .this_id = SYM53C416_SCSI_ID, | ||
| 840 | .sg_tablesize = 32, | ||
| 841 | .unchecked_isa_dma = 1, | ||
| 842 | .use_clustering = ENABLE_CLUSTERING, | ||
| 843 | }; | ||
| 844 | #include "scsi_module.c" | ||
diff --git a/drivers/scsi/sym53c416.h b/drivers/scsi/sym53c416.h deleted file mode 100644 index 387de5d80a70..000000000000 --- a/drivers/scsi/sym53c416.h +++ /dev/null | |||
| @@ -1,33 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * sym53c416.h | ||
| 3 | * | ||
| 4 | * Copyright (C) 1998 Lieven Willems (lw_linux@hotmail.com) | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms of the GNU General Public License as published by the | ||
| 8 | * Free Software Foundation; either version 2, or (at your option) any | ||
| 9 | * later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, but | ||
| 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 14 | * General Public License for more details. | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef _SYM53C416_H | ||
| 19 | #define _SYM53C416_H | ||
| 20 | |||
| 21 | #include <linux/types.h> | ||
| 22 | |||
| 23 | #define SYM53C416_SCSI_ID 7 | ||
| 24 | |||
| 25 | static int sym53c416_detect(struct scsi_host_template *); | ||
| 26 | static const char *sym53c416_info(struct Scsi_Host *); | ||
| 27 | static int sym53c416_release(struct Scsi_Host *); | ||
| 28 | static int sym53c416_queuecommand(struct Scsi_Host *, struct scsi_cmnd *); | ||
| 29 | static int sym53c416_host_reset(Scsi_Cmnd *); | ||
| 30 | static int sym53c416_bios_param(struct scsi_device *, struct block_device *, | ||
| 31 | sector_t, int *); | ||
| 32 | static void sym53c416_setup(char *str, int *ints); | ||
| 33 | #endif | ||
diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile index 9310c6c83041..918f5791202d 100644 --- a/drivers/scsi/ufs/Makefile +++ b/drivers/scsi/ufs/Makefile | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o tc-dwc-g210.o | 3 | obj-$(CONFIG_SCSI_UFS_DWC_TC_PCI) += tc-dwc-g210-pci.o ufshcd-dwc.o tc-dwc-g210.o |
| 4 | obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-dwc-g210.o | 4 | obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o ufshcd-dwc.o tc-dwc-g210.o |
| 5 | obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o | 5 | obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o |
| 6 | obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o | 6 | obj-$(CONFIG_SCSI_UFSHCD) += ufshcd-core.o |
| 7 | ufshcd-core-objs := ufshcd.o ufs-sysfs.o | ||
| 7 | obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o | 8 | obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o |
| 8 | obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o | 9 | obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o |
diff --git a/drivers/scsi/ufs/tc-dwc-g210-pci.c b/drivers/scsi/ufs/tc-dwc-g210-pci.c index 325d5e14fc0d..2f41722a8c28 100644 --- a/drivers/scsi/ufs/tc-dwc-g210-pci.c +++ b/drivers/scsi/ufs/tc-dwc-g210-pci.c | |||
| @@ -51,7 +51,7 @@ static int tc_dwc_g210_pci_runtime_idle(struct device *dev) | |||
| 51 | return ufshcd_runtime_idle(dev_get_drvdata(dev)); | 51 | return ufshcd_runtime_idle(dev_get_drvdata(dev)); |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | /** | 54 | /* |
| 55 | * struct ufs_hba_dwc_vops - UFS DWC specific variant operations | 55 | * struct ufs_hba_dwc_vops - UFS DWC specific variant operations |
| 56 | */ | 56 | */ |
| 57 | static struct ufs_hba_variant_ops tc_dwc_g210_pci_hba_vops = { | 57 | static struct ufs_hba_variant_ops tc_dwc_g210_pci_hba_vops = { |
| @@ -71,7 +71,7 @@ static void tc_dwc_g210_pci_shutdown(struct pci_dev *pdev) | |||
| 71 | /** | 71 | /** |
| 72 | * tc_dwc_g210_pci_remove - de-allocate PCI/SCSI host and host memory space | 72 | * tc_dwc_g210_pci_remove - de-allocate PCI/SCSI host and host memory space |
| 73 | * data structure memory | 73 | * data structure memory |
| 74 | * @pdev - pointer to PCI handle | 74 | * @pdev: pointer to PCI handle |
| 75 | */ | 75 | */ |
| 76 | static void tc_dwc_g210_pci_remove(struct pci_dev *pdev) | 76 | static void tc_dwc_g210_pci_remove(struct pci_dev *pdev) |
| 77 | { | 77 | { |
diff --git a/drivers/scsi/ufs/tc-dwc-g210-pltfrm.c b/drivers/scsi/ufs/tc-dwc-g210-pltfrm.c index 2d3f5270f875..6dfe5a9206e9 100644 --- a/drivers/scsi/ufs/tc-dwc-g210-pltfrm.c +++ b/drivers/scsi/ufs/tc-dwc-g210-pltfrm.c | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | #include "ufshcd-dwc.h" | 20 | #include "ufshcd-dwc.h" |
| 21 | #include "tc-dwc-g210.h" | 21 | #include "tc-dwc-g210.h" |
| 22 | 22 | ||
| 23 | /** | 23 | /* |
| 24 | * UFS DWC specific variant operations | 24 | * UFS DWC specific variant operations |
| 25 | */ | 25 | */ |
| 26 | static struct ufs_hba_variant_ops tc_dwc_g210_20bit_pltfm_hba_vops = { | 26 | static struct ufs_hba_variant_ops tc_dwc_g210_20bit_pltfm_hba_vops = { |
diff --git a/drivers/scsi/ufs/ufs-sysfs.c b/drivers/scsi/ufs/ufs-sysfs.c new file mode 100644 index 000000000000..8d9332bb7d0c --- /dev/null +++ b/drivers/scsi/ufs/ufs-sysfs.c | |||
| @@ -0,0 +1,817 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0 | ||
| 2 | // Copyright (C) 2018 Western Digital Corporation | ||
| 3 | |||
| 4 | #include <linux/err.h> | ||
| 5 | #include <linux/string.h> | ||
| 6 | #include <linux/bitfield.h> | ||
| 7 | #include <asm/unaligned.h> | ||
| 8 | |||
| 9 | #include "ufs.h" | ||
| 10 | #include "ufs-sysfs.h" | ||
| 11 | |||
| 12 | static const char *ufschd_uic_link_state_to_string( | ||
| 13 | enum uic_link_state state) | ||
| 14 | { | ||
| 15 | switch (state) { | ||
| 16 | case UIC_LINK_OFF_STATE: return "OFF"; | ||
| 17 | case UIC_LINK_ACTIVE_STATE: return "ACTIVE"; | ||
| 18 | case UIC_LINK_HIBERN8_STATE: return "HIBERN8"; | ||
| 19 | default: return "UNKNOWN"; | ||
| 20 | } | ||
| 21 | } | ||
| 22 | |||
| 23 | static const char *ufschd_ufs_dev_pwr_mode_to_string( | ||
| 24 | enum ufs_dev_pwr_mode state) | ||
| 25 | { | ||
| 26 | switch (state) { | ||
| 27 | case UFS_ACTIVE_PWR_MODE: return "ACTIVE"; | ||
| 28 | case UFS_SLEEP_PWR_MODE: return "SLEEP"; | ||
| 29 | case UFS_POWERDOWN_PWR_MODE: return "POWERDOWN"; | ||
| 30 | default: return "UNKNOWN"; | ||
| 31 | } | ||
| 32 | } | ||
| 33 | |||
| 34 | static inline ssize_t ufs_sysfs_pm_lvl_store(struct device *dev, | ||
| 35 | struct device_attribute *attr, | ||
| 36 | const char *buf, size_t count, | ||
| 37 | bool rpm) | ||
| 38 | { | ||
| 39 | struct ufs_hba *hba = dev_get_drvdata(dev); | ||
| 40 | unsigned long flags, value; | ||
| 41 | |||
| 42 | if (kstrtoul(buf, 0, &value)) | ||
| 43 | return -EINVAL; | ||
| 44 | |||
| 45 | if (value >= UFS_PM_LVL_MAX) | ||
| 46 | return -EINVAL; | ||
| 47 | |||
| 48 | spin_lock_irqsave(hba->host->host_lock, flags); | ||
| 49 | if (rpm) | ||
| 50 | hba->rpm_lvl = value; | ||
| 51 | else | ||
| 52 | hba->spm_lvl = value; | ||
| 53 | spin_unlock_irqrestore(hba->host->host_lock, flags); | ||
| 54 | return count; | ||
| 55 | } | ||
| 56 | |||
| 57 | static ssize_t rpm_lvl_show(struct device *dev, | ||
| 58 | struct device_attribute *attr, char *buf) | ||
| 59 | { | ||
| 60 | struct ufs_hba *hba = dev_get_drvdata(dev); | ||
| 61 | |||
| 62 | return sprintf(buf, "%d\n", hba->rpm_lvl); | ||
| 63 | } | ||
| 64 | |||
| 65 | static ssize_t rpm_lvl_store(struct device *dev, | ||
| 66 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 67 | { | ||
| 68 | return ufs_sysfs_pm_lvl_store(dev, attr, buf, count, true); | ||
| 69 | } | ||
| 70 | |||
| 71 | static ssize_t rpm_target_dev_state_show(struct device *dev, | ||
| 72 | struct device_attribute *attr, char *buf) | ||
| 73 | { | ||
| 74 | struct ufs_hba *hba = dev_get_drvdata(dev); | ||
| 75 | |||
| 76 | return sprintf(buf, "%s\n", ufschd_ufs_dev_pwr_mode_to_string( | ||
| 77 | ufs_pm_lvl_states[hba->rpm_lvl].dev_state)); | ||
| 78 | } | ||
| 79 | |||
| 80 | static ssize_t rpm_target_link_state_show(struct device *dev, | ||
| 81 | struct device_attribute *attr, char *buf) | ||
| 82 | { | ||
| 83 | struct ufs_hba *hba = dev_get_drvdata(dev); | ||
| 84 | |||
| 85 | return sprintf(buf, "%s\n", ufschd_uic_link_state_to_string( | ||
| 86 | ufs_pm_lvl_states[hba->rpm_lvl].link_state)); | ||
| 87 | } | ||
| 88 | |||
| 89 | static ssize_t spm_lvl_show(struct device *dev, | ||
| 90 | struct device_attribute *attr, char *buf) | ||
| 91 | { | ||
| 92 | struct ufs_hba *hba = dev_get_drvdata(dev); | ||
| 93 | |||
| 94 | return sprintf(buf, "%d\n", hba->spm_lvl); | ||
| 95 | } | ||
| 96 | |||
| 97 | static ssize_t spm_lvl_store(struct device *dev, | ||
| 98 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 99 | { | ||
| 100 | return ufs_sysfs_pm_lvl_store(dev, attr, buf, count, false); | ||
| 101 | } | ||
| 102 | |||
| 103 | static ssize_t spm_target_dev_state_show(struct device *dev, | ||
| 104 | struct device_attribute *attr, char *buf) | ||
| 105 | { | ||
| 106 | struct ufs_hba *hba = dev_get_drvdata(dev); | ||
| 107 | |||
| 108 | return sprintf(buf, "%s\n", ufschd_ufs_dev_pwr_mode_to_string( | ||
| 109 | ufs_pm_lvl_states[hba->spm_lvl].dev_state)); | ||
| 110 | } | ||
| 111 | |||
| 112 | static ssize_t spm_target_link_state_show(struct device *dev, | ||
| 113 | struct device_attribute *attr, char *buf) | ||
| 114 | { | ||
| 115 | struct ufs_hba *hba = dev_get_drvdata(dev); | ||
| 116 | |||
| 117 | return sprintf(buf, "%s\n", ufschd_uic_link_state_to_string( | ||
| 118 | ufs_pm_lvl_states[hba->spm_lvl].link_state)); | ||
| 119 | } | ||
| 120 | |||
| 121 | static void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit) | ||
| 122 | { | ||
| 123 | unsigned long flags; | ||
| 124 | |||
| 125 | if (!(hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT)) | ||
| 126 | return; | ||
| 127 | |||
| 128 | spin_lock_irqsave(hba->host->host_lock, flags); | ||
| 129 | if (hba->ahit == ahit) | ||
| 130 | goto out_unlock; | ||
| 131 | hba->ahit = ahit; | ||
| 132 | if (!pm_runtime_suspended(hba->dev)) | ||
| 133 | ufshcd_writel(hba, hba->ahit, REG_AUTO_HIBERNATE_IDLE_TIMER); | ||
| 134 | out_unlock: | ||
| 135 | spin_unlock_irqrestore(hba->host->host_lock, flags); | ||
| 136 | } | ||
| 137 | |||
| 138 | /* Convert Auto-Hibernate Idle Timer register value to microseconds */ | ||
| 139 | static int ufshcd_ahit_to_us(u32 ahit) | ||
| 140 | { | ||
| 141 | int timer = FIELD_GET(UFSHCI_AHIBERN8_TIMER_MASK, ahit); | ||
| 142 | int scale = FIELD_GET(UFSHCI_AHIBERN8_SCALE_MASK, ahit); | ||
| 143 | |||
| 144 | for (; scale > 0; --scale) | ||
| 145 | timer *= UFSHCI_AHIBERN8_SCALE_FACTOR; | ||
| 146 | |||
| 147 | return timer; | ||
| 148 | } | ||
| 149 | |||
| 150 | /* Convert microseconds to Auto-Hibernate Idle Timer register value */ | ||
| 151 | static u32 ufshcd_us_to_ahit(unsigned int timer) | ||
| 152 | { | ||
| 153 | unsigned int scale; | ||
| 154 | |||
| 155 | for (scale = 0; timer > UFSHCI_AHIBERN8_TIMER_MASK; ++scale) | ||
| 156 | timer /= UFSHCI_AHIBERN8_SCALE_FACTOR; | ||
| 157 | |||
| 158 | return FIELD_PREP(UFSHCI_AHIBERN8_TIMER_MASK, timer) | | ||
| 159 | FIELD_PREP(UFSHCI_AHIBERN8_SCALE_MASK, scale); | ||
| 160 | } | ||
| 161 | |||
| 162 | static ssize_t auto_hibern8_show(struct device *dev, | ||
| 163 | struct device_attribute *attr, char *buf) | ||
| 164 | { | ||
| 165 | struct ufs_hba *hba = dev_get_drvdata(dev); | ||
| 166 | |||
| 167 | if (!(hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT)) | ||
| 168 | return -EOPNOTSUPP; | ||
| 169 | |||
| 170 | return snprintf(buf, PAGE_SIZE, "%d\n", ufshcd_ahit_to_us(hba->ahit)); | ||
| 171 | } | ||
| 172 | |||
| 173 | static ssize_t auto_hibern8_store(struct device *dev, | ||
| 174 | struct device_attribute *attr, | ||
| 175 | const char *buf, size_t count) | ||
| 176 | { | ||
| 177 | struct ufs_hba *hba = dev_get_drvdata(dev); | ||
| 178 | unsigned int timer; | ||
| 179 | |||
| 180 | if (!(hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT)) | ||
| 181 | return -EOPNOTSUPP; | ||
| 182 | |||
| 183 | if (kstrtouint(buf, 0, &timer)) | ||
| 184 | return -EINVAL; | ||
| 185 | |||
| 186 | if (timer > UFSHCI_AHIBERN8_MAX) | ||
| 187 | return -EINVAL; | ||
| 188 | |||
| 189 | ufshcd_auto_hibern8_update(hba, ufshcd_us_to_ahit(timer)); | ||
| 190 | |||
| 191 | return count; | ||
| 192 | } | ||
| 193 | |||
| 194 | static DEVICE_ATTR_RW(rpm_lvl); | ||
| 195 | static DEVICE_ATTR_RO(rpm_target_dev_state); | ||
| 196 | static DEVICE_ATTR_RO(rpm_target_link_state); | ||
| 197 | static DEVICE_ATTR_RW(spm_lvl); | ||
| 198 | static DEVICE_ATTR_RO(spm_target_dev_state); | ||
| 199 | static DEVICE_ATTR_RO(spm_target_link_state); | ||
| 200 | static DEVICE_ATTR_RW(auto_hibern8); | ||
| 201 | |||
| 202 | static struct attribute *ufs_sysfs_ufshcd_attrs[] = { | ||
| 203 | &dev_attr_rpm_lvl.attr, | ||
| 204 | &dev_attr_rpm_target_dev_state.attr, | ||
| 205 | &dev_attr_rpm_target_link_state.attr, | ||
| 206 | &dev_attr_spm_lvl.attr, | ||
| 207 | &dev_attr_spm_target_dev_state.attr, | ||
| 208 | &dev_attr_spm_target_link_state.attr, | ||
| 209 | &dev_attr_auto_hibern8.attr, | ||
| 210 | NULL | ||
| 211 | }; | ||
| 212 | |||
| 213 | static const struct attribute_group ufs_sysfs_default_group = { | ||
| 214 | .attrs = ufs_sysfs_ufshcd_attrs, | ||
| 215 | }; | ||
| 216 | |||
| 217 | static ssize_t ufs_sysfs_read_desc_param(struct ufs_hba *hba, | ||
| 218 | enum desc_idn desc_id, | ||
| 219 | u8 desc_index, | ||
| 220 | u8 param_offset, | ||
| 221 | u8 *sysfs_buf, | ||
| 222 | u8 param_size) | ||
| 223 | { | ||
| 224 | u8 desc_buf[8] = {0}; | ||
| 225 | int ret; | ||
| 226 | |||
| 227 | if (param_size > 8) | ||
| 228 | return -EINVAL; | ||
| 229 | |||
| 230 | ret = ufshcd_read_desc_param(hba, desc_id, desc_index, | ||
| 231 | param_offset, desc_buf, param_size); | ||
| 232 | if (ret) | ||
| 233 | return -EINVAL; | ||
| 234 | switch (param_size) { | ||
| 235 | case 1: | ||
| 236 | ret = sprintf(sysfs_buf, "0x%02X\n", *desc_buf); | ||
| 237 | break; | ||
| 238 | case 2: | ||
| 239 | ret = sprintf(sysfs_buf, "0x%04X\n", | ||
| 240 | get_unaligned_be16(desc_buf)); | ||
| 241 | break; | ||
| 242 | case 4: | ||
| 243 | ret = sprintf(sysfs_buf, "0x%08X\n", | ||
| 244 | get_unaligned_be32(desc_buf)); | ||
| 245 | break; | ||
| 246 | case 8: | ||
| 247 | ret = sprintf(sysfs_buf, "0x%016llX\n", | ||
| 248 | get_unaligned_be64(desc_buf)); | ||
| 249 | break; | ||
| 250 | } | ||
| 251 | |||
| 252 | return ret; | ||
| 253 | } | ||
| 254 | |||
| 255 | #define UFS_DESC_PARAM(_name, _puname, _duname, _size) \ | ||
| 256 | static ssize_t _name##_show(struct device *dev, \ | ||
| 257 | struct device_attribute *attr, char *buf) \ | ||
| 258 | { \ | ||
| 259 | struct ufs_hba *hba = dev_get_drvdata(dev); \ | ||
| 260 | return ufs_sysfs_read_desc_param(hba, QUERY_DESC_IDN_##_duname, \ | ||
| 261 | 0, _duname##_DESC_PARAM##_puname, buf, _size); \ | ||
| 262 | } \ | ||
| 263 | static DEVICE_ATTR_RO(_name) | ||
| 264 | |||
| 265 | #define UFS_DEVICE_DESC_PARAM(_name, _uname, _size) \ | ||
| 266 | UFS_DESC_PARAM(_name, _uname, DEVICE, _size) | ||
| 267 | |||
| 268 | UFS_DEVICE_DESC_PARAM(device_type, _DEVICE_TYPE, 1); | ||
| 269 | UFS_DEVICE_DESC_PARAM(device_class, _DEVICE_CLASS, 1); | ||
| 270 | UFS_DEVICE_DESC_PARAM(device_sub_class, _DEVICE_SUB_CLASS, 1); | ||
| 271 | UFS_DEVICE_DESC_PARAM(protocol, _PRTCL, 1); | ||
| 272 | UFS_DEVICE_DESC_PARAM(number_of_luns, _NUM_LU, 1); | ||
| 273 | UFS_DEVICE_DESC_PARAM(number_of_wluns, _NUM_WLU, 1); | ||
| 274 | UFS_DEVICE_DESC_PARAM(boot_enable, _BOOT_ENBL, 1); | ||
| 275 | UFS_DEVICE_DESC_PARAM(descriptor_access_enable, _DESC_ACCSS_ENBL, 1); | ||
| 276 | UFS_DEVICE_DESC_PARAM(initial_power_mode, _INIT_PWR_MODE, 1); | ||
| 277 | UFS_DEVICE_DESC_PARAM(high_priority_lun, _HIGH_PR_LUN, 1); | ||
| 278 | UFS_DEVICE_DESC_PARAM(secure_removal_type, _SEC_RMV_TYPE, 1); | ||
| 279 | UFS_DEVICE_DESC_PARAM(support_security_lun, _SEC_LU, 1); | ||
| 280 | UFS_DEVICE_DESC_PARAM(bkops_termination_latency, _BKOP_TERM_LT, 1); | ||
| 281 | UFS_DEVICE_DESC_PARAM(initial_active_icc_level, _ACTVE_ICC_LVL, 1); | ||
| 282 | UFS_DEVICE_DESC_PARAM(specification_version, _SPEC_VER, 2); | ||
| 283 | UFS_DEVICE_DESC_PARAM(manufacturing_date, _MANF_DATE, 2); | ||
| 284 | UFS_DEVICE_DESC_PARAM(manufacturer_id, _MANF_ID, 2); | ||
| 285 | UFS_DEVICE_DESC_PARAM(rtt_capability, _RTT_CAP, 1); | ||
| 286 | UFS_DEVICE_DESC_PARAM(rtc_update, _FRQ_RTC, 2); | ||
| 287 | UFS_DEVICE_DESC_PARAM(ufs_features, _UFS_FEAT, 1); | ||
| 288 | UFS_DEVICE_DESC_PARAM(ffu_timeout, _FFU_TMT, 1); | ||
| 289 | UFS_DEVICE_DESC_PARAM(queue_depth, _Q_DPTH, 1); | ||
| 290 | UFS_DEVICE_DESC_PARAM(device_version, _DEV_VER, 2); | ||
| 291 | UFS_DEVICE_DESC_PARAM(number_of_secure_wpa, _NUM_SEC_WPA, 1); | ||
| 292 | UFS_DEVICE_DESC_PARAM(psa_max_data_size, _PSA_MAX_DATA, 4); | ||
| 293 | UFS_DEVICE_DESC_PARAM(psa_state_timeout, _PSA_TMT, 1); | ||
| 294 | |||
| 295 | static struct attribute *ufs_sysfs_device_descriptor[] = { | ||
| 296 | &dev_attr_device_type.attr, | ||
| 297 | &dev_attr_device_class.attr, | ||
| 298 | &dev_attr_device_sub_class.attr, | ||
| 299 | &dev_attr_protocol.attr, | ||
| 300 | &dev_attr_number_of_luns.attr, | ||
| 301 | &dev_attr_number_of_wluns.attr, | ||
| 302 | &dev_attr_boot_enable.attr, | ||
| 303 | &dev_attr_descriptor_access_enable.attr, | ||
| 304 | &dev_attr_initial_power_mode.attr, | ||
| 305 | &dev_attr_high_priority_lun.attr, | ||
| 306 | &dev_attr_secure_removal_type.attr, | ||
| 307 | &dev_attr_support_security_lun.attr, | ||
| 308 | &dev_attr_bkops_termination_latency.attr, | ||
| 309 | &dev_attr_initial_active_icc_level.attr, | ||
| 310 | &dev_attr_specification_version.attr, | ||
| 311 | &dev_attr_manufacturing_date.attr, | ||
| 312 | &dev_attr_manufacturer_id.attr, | ||
| 313 | &dev_attr_rtt_capability.attr, | ||
| 314 | &dev_attr_rtc_update.attr, | ||
| 315 | &dev_attr_ufs_features.attr, | ||
| 316 | &dev_attr_ffu_timeout.attr, | ||
| 317 | &dev_attr_queue_depth.attr, | ||
| 318 | &dev_attr_device_version.attr, | ||
| 319 | &dev_attr_number_of_secure_wpa.attr, | ||
| 320 | &dev_attr_psa_max_data_size.attr, | ||
| 321 | &dev_attr_psa_state_timeout.attr, | ||
| 322 | NULL, | ||
| 323 | }; | ||
| 324 | |||
| 325 | static const struct attribute_group ufs_sysfs_device_descriptor_group = { | ||
| 326 | .name = "device_descriptor", | ||
| 327 | .attrs = ufs_sysfs_device_descriptor, | ||
| 328 | }; | ||
| 329 | |||
| 330 | #define UFS_INTERCONNECT_DESC_PARAM(_name, _uname, _size) \ | ||
| 331 | UFS_DESC_PARAM(_name, _uname, INTERCONNECT, _size) | ||
| 332 | |||
| 333 | UFS_INTERCONNECT_DESC_PARAM(unipro_version, _UNIPRO_VER, 2); | ||
| 334 | UFS_INTERCONNECT_DESC_PARAM(mphy_version, _MPHY_VER, 2); | ||
| 335 | |||
| 336 | static struct attribute *ufs_sysfs_interconnect_descriptor[] = { | ||
| 337 | &dev_attr_unipro_version.attr, | ||
| 338 | &dev_attr_mphy_version.attr, | ||
| 339 | NULL, | ||
| 340 | }; | ||
| 341 | |||
| 342 | static const struct attribute_group ufs_sysfs_interconnect_descriptor_group = { | ||
| 343 | .name = "interconnect_descriptor", | ||
| 344 | .attrs = ufs_sysfs_interconnect_descriptor, | ||
| 345 | }; | ||
| 346 | |||
| 347 | #define UFS_GEOMETRY_DESC_PARAM(_name, _uname, _size) \ | ||
| 348 | UFS_DESC_PARAM(_name, _uname, GEOMETRY, _size) | ||
| 349 | |||
| 350 | UFS_GEOMETRY_DESC_PARAM(raw_device_capacity, _DEV_CAP, 8); | ||
| 351 | UFS_GEOMETRY_DESC_PARAM(max_number_of_luns, _MAX_NUM_LUN, 1); | ||
| 352 | UFS_GEOMETRY_DESC_PARAM(segment_size, _SEG_SIZE, 4); | ||
| 353 | UFS_GEOMETRY_DESC_PARAM(allocation_unit_size, _ALLOC_UNIT_SIZE, 1); | ||
| 354 | UFS_GEOMETRY_DESC_PARAM(min_addressable_block_size, _MIN_BLK_SIZE, 1); | ||
| 355 | UFS_GEOMETRY_DESC_PARAM(optimal_read_block_size, _OPT_RD_BLK_SIZE, 1); | ||
| 356 | UFS_GEOMETRY_DESC_PARAM(optimal_write_block_size, _OPT_WR_BLK_SIZE, 1); | ||
| 357 | UFS_GEOMETRY_DESC_PARAM(max_in_buffer_size, _MAX_IN_BUF_SIZE, 1); | ||
| 358 | UFS_GEOMETRY_DESC_PARAM(max_out_buffer_size, _MAX_OUT_BUF_SIZE, 1); | ||
| 359 | UFS_GEOMETRY_DESC_PARAM(rpmb_rw_size, _RPMB_RW_SIZE, 1); | ||
| 360 | UFS_GEOMETRY_DESC_PARAM(dyn_capacity_resource_policy, _DYN_CAP_RSRC_PLC, 1); | ||
| 361 | UFS_GEOMETRY_DESC_PARAM(data_ordering, _DATA_ORDER, 1); | ||
| 362 | UFS_GEOMETRY_DESC_PARAM(max_number_of_contexts, _MAX_NUM_CTX, 1); | ||
| 363 | UFS_GEOMETRY_DESC_PARAM(sys_data_tag_unit_size, _TAG_UNIT_SIZE, 1); | ||
| 364 | UFS_GEOMETRY_DESC_PARAM(sys_data_tag_resource_size, _TAG_RSRC_SIZE, 1); | ||
| 365 | UFS_GEOMETRY_DESC_PARAM(secure_removal_types, _SEC_RM_TYPES, 1); | ||
| 366 | UFS_GEOMETRY_DESC_PARAM(memory_types, _MEM_TYPES, 2); | ||
| 367 | UFS_GEOMETRY_DESC_PARAM(sys_code_memory_max_alloc_units, | ||
| 368 | _SCM_MAX_NUM_UNITS, 4); | ||
| 369 | UFS_GEOMETRY_DESC_PARAM(sys_code_memory_capacity_adjustment_factor, | ||
| 370 | _SCM_CAP_ADJ_FCTR, 2); | ||
| 371 | UFS_GEOMETRY_DESC_PARAM(non_persist_memory_max_alloc_units, | ||
| 372 | _NPM_MAX_NUM_UNITS, 4); | ||
| 373 | UFS_GEOMETRY_DESC_PARAM(non_persist_memory_capacity_adjustment_factor, | ||
| 374 | _NPM_CAP_ADJ_FCTR, 2); | ||
| 375 | UFS_GEOMETRY_DESC_PARAM(enh1_memory_max_alloc_units, | ||
| 376 | _ENM1_MAX_NUM_UNITS, 4); | ||
| 377 | UFS_GEOMETRY_DESC_PARAM(enh1_memory_capacity_adjustment_factor, | ||
| 378 | _ENM1_CAP_ADJ_FCTR, 2); | ||
| 379 | UFS_GEOMETRY_DESC_PARAM(enh2_memory_max_alloc_units, | ||
| 380 | _ENM2_MAX_NUM_UNITS, 4); | ||
| 381 | UFS_GEOMETRY_DESC_PARAM(enh2_memory_capacity_adjustment_factor, | ||
| 382 | _ENM2_CAP_ADJ_FCTR, 2); | ||
| 383 | UFS_GEOMETRY_DESC_PARAM(enh3_memory_max_alloc_units, | ||
| 384 | _ENM3_MAX_NUM_UNITS, 4); | ||
| 385 | UFS_GEOMETRY_DESC_PARAM(enh3_memory_capacity_adjustment_factor, | ||
| 386 | _ENM3_CAP_ADJ_FCTR, 2); | ||
| 387 | UFS_GEOMETRY_DESC_PARAM(enh4_memory_max_alloc_units, | ||
| 388 | _ENM4_MAX_NUM_UNITS, 4); | ||
| 389 | UFS_GEOMETRY_DESC_PARAM(enh4_memory_capacity_adjustment_factor, | ||
| 390 | _ENM4_CAP_ADJ_FCTR, 2); | ||
| 391 | |||
| 392 | static struct attribute *ufs_sysfs_geometry_descriptor[] = { | ||
| 393 | &dev_attr_raw_device_capacity.attr, | ||
| 394 | &dev_attr_max_number_of_luns.attr, | ||
| 395 | &dev_attr_segment_size.attr, | ||
| 396 | &dev_attr_allocation_unit_size.attr, | ||
| 397 | &dev_attr_min_addressable_block_size.attr, | ||
| 398 | &dev_attr_optimal_read_block_size.attr, | ||
| 399 | &dev_attr_optimal_write_block_size.attr, | ||
| 400 | &dev_attr_max_in_buffer_size.attr, | ||
| 401 | &dev_attr_max_out_buffer_size.attr, | ||
| 402 | &dev_attr_rpmb_rw_size.attr, | ||
| 403 | &dev_attr_dyn_capacity_resource_policy.attr, | ||
| 404 | &dev_attr_data_ordering.attr, | ||
| 405 | &dev_attr_max_number_of_contexts.attr, | ||
| 406 | &dev_attr_sys_data_tag_unit_size.attr, | ||
| 407 | &dev_attr_sys_data_tag_resource_size.attr, | ||
| 408 | &dev_attr_secure_removal_types.attr, | ||
| 409 | &dev_attr_memory_types.attr, | ||
| 410 | &dev_attr_sys_code_memory_max_alloc_units.attr, | ||
| 411 | &dev_attr_sys_code_memory_capacity_adjustment_factor.attr, | ||
| 412 | &dev_attr_non_persist_memory_max_alloc_units.attr, | ||
| 413 | &dev_attr_non_persist_memory_capacity_adjustment_factor.attr, | ||
| 414 | &dev_attr_enh1_memory_max_alloc_units.attr, | ||
| 415 | &dev_attr_enh1_memory_capacity_adjustment_factor.attr, | ||
| 416 | &dev_attr_enh2_memory_max_alloc_units.attr, | ||
| 417 | &dev_attr_enh2_memory_capacity_adjustment_factor.attr, | ||
| 418 | &dev_attr_enh3_memory_max_alloc_units.attr, | ||
| 419 | &dev_attr_enh3_memory_capacity_adjustment_factor.attr, | ||
| 420 | &dev_attr_enh4_memory_max_alloc_units.attr, | ||
| 421 | &dev_attr_enh4_memory_capacity_adjustment_factor.attr, | ||
| 422 | NULL, | ||
| 423 | }; | ||
| 424 | |||
| 425 | static const struct attribute_group ufs_sysfs_geometry_descriptor_group = { | ||
| 426 | .name = "geometry_descriptor", | ||
| 427 | .attrs = ufs_sysfs_geometry_descriptor, | ||
| 428 | }; | ||
| 429 | |||
| 430 | #define UFS_HEALTH_DESC_PARAM(_name, _uname, _size) \ | ||
| 431 | UFS_DESC_PARAM(_name, _uname, HEALTH, _size) | ||
| 432 | |||
| 433 | UFS_HEALTH_DESC_PARAM(eol_info, _EOL_INFO, 1); | ||
| 434 | UFS_HEALTH_DESC_PARAM(life_time_estimation_a, _LIFE_TIME_EST_A, 1); | ||
| 435 | UFS_HEALTH_DESC_PARAM(life_time_estimation_b, _LIFE_TIME_EST_B, 1); | ||
| 436 | |||
| 437 | static struct attribute *ufs_sysfs_health_descriptor[] = { | ||
| 438 | &dev_attr_eol_info.attr, | ||
| 439 | &dev_attr_life_time_estimation_a.attr, | ||
| 440 | &dev_attr_life_time_estimation_b.attr, | ||
| 441 | NULL, | ||
| 442 | }; | ||
| 443 | |||
| 444 | static const struct attribute_group ufs_sysfs_health_descriptor_group = { | ||
| 445 | .name = "health_descriptor", | ||
| 446 | .attrs = ufs_sysfs_health_descriptor, | ||
| 447 | }; | ||
| 448 | |||
| 449 | #define UFS_POWER_DESC_PARAM(_name, _uname, _index) \ | ||
| 450 | static ssize_t _name##_index##_show(struct device *dev, \ | ||
| 451 | struct device_attribute *attr, char *buf) \ | ||
| 452 | { \ | ||
| 453 | struct ufs_hba *hba = dev_get_drvdata(dev); \ | ||
| 454 | return ufs_sysfs_read_desc_param(hba, QUERY_DESC_IDN_POWER, 0, \ | ||
| 455 | PWR_DESC##_uname##_0 + _index * 2, buf, 2); \ | ||
| 456 | } \ | ||
| 457 | static DEVICE_ATTR_RO(_name##_index) | ||
| 458 | |||
| 459 | UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 0); | ||
| 460 | UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 1); | ||
| 461 | UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 2); | ||
| 462 | UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 3); | ||
| 463 | UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 4); | ||
| 464 | UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 5); | ||
| 465 | UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 6); | ||
| 466 | UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 7); | ||
| 467 | UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 8); | ||
| 468 | UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 9); | ||
| 469 | UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 10); | ||
| 470 | UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 11); | ||
| 471 | UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 12); | ||
| 472 | UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 13); | ||
| 473 | UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 14); | ||
| 474 | UFS_POWER_DESC_PARAM(active_icc_levels_vcc, _ACTIVE_LVLS_VCC, 15); | ||
| 475 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 0); | ||
| 476 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 1); | ||
| 477 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 2); | ||
| 478 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 3); | ||
| 479 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 4); | ||
| 480 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 5); | ||
| 481 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 6); | ||
| 482 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 7); | ||
| 483 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 8); | ||
| 484 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 9); | ||
| 485 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 10); | ||
| 486 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 11); | ||
| 487 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 12); | ||
| 488 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 13); | ||
| 489 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 14); | ||
| 490 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq, _ACTIVE_LVLS_VCCQ, 15); | ||
| 491 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 0); | ||
| 492 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 1); | ||
| 493 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 2); | ||
| 494 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 3); | ||
| 495 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 4); | ||
| 496 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 5); | ||
| 497 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 6); | ||
| 498 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 7); | ||
| 499 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 8); | ||
| 500 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 9); | ||
| 501 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 10); | ||
| 502 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 11); | ||
| 503 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 12); | ||
| 504 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 13); | ||
| 505 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 14); | ||
| 506 | UFS_POWER_DESC_PARAM(active_icc_levels_vccq2, _ACTIVE_LVLS_VCCQ2, 15); | ||
| 507 | |||
| 508 | static struct attribute *ufs_sysfs_power_descriptor[] = { | ||
| 509 | &dev_attr_active_icc_levels_vcc0.attr, | ||
| 510 | &dev_attr_active_icc_levels_vcc1.attr, | ||
| 511 | &dev_attr_active_icc_levels_vcc2.attr, | ||
| 512 | &dev_attr_active_icc_levels_vcc3.attr, | ||
| 513 | &dev_attr_active_icc_levels_vcc4.attr, | ||
| 514 | &dev_attr_active_icc_levels_vcc5.attr, | ||
| 515 | &dev_attr_active_icc_levels_vcc6.attr, | ||
| 516 | &dev_attr_active_icc_levels_vcc7.attr, | ||
| 517 | &dev_attr_active_icc_levels_vcc8.attr, | ||
| 518 | &dev_attr_active_icc_levels_vcc9.attr, | ||
| 519 | &dev_attr_active_icc_levels_vcc10.attr, | ||
| 520 | &dev_attr_active_icc_levels_vcc11.attr, | ||
| 521 | &dev_attr_active_icc_levels_vcc12.attr, | ||
| 522 | &dev_attr_active_icc_levels_vcc13.attr, | ||
| 523 | &dev_attr_active_icc_levels_vcc14.attr, | ||
| 524 | &dev_attr_active_icc_levels_vcc15.attr, | ||
| 525 | &dev_attr_active_icc_levels_vccq0.attr, | ||
| 526 | &dev_attr_active_icc_levels_vccq1.attr, | ||
| 527 | &dev_attr_active_icc_levels_vccq2.attr, | ||
| 528 | &dev_attr_active_icc_levels_vccq3.attr, | ||
| 529 | &dev_attr_active_icc_levels_vccq4.attr, | ||
| 530 | &dev_attr_active_icc_levels_vccq5.attr, | ||
| 531 | &dev_attr_active_icc_levels_vccq6.attr, | ||
| 532 | &dev_attr_active_icc_levels_vccq7.attr, | ||
| 533 | &dev_attr_active_icc_levels_vccq8.attr, | ||
| 534 | &dev_attr_active_icc_levels_vccq9.attr, | ||
| 535 | &dev_attr_active_icc_levels_vccq10.attr, | ||
| 536 | &dev_attr_active_icc_levels_vccq11.attr, | ||
| 537 | &dev_attr_active_icc_levels_vccq12.attr, | ||
| 538 | &dev_attr_active_icc_levels_vccq13.attr, | ||
| 539 | &dev_attr_active_icc_levels_vccq14.attr, | ||
| 540 | &dev_attr_active_icc_levels_vccq15.attr, | ||
| 541 | &dev_attr_active_icc_levels_vccq20.attr, | ||
| 542 | &dev_attr_active_icc_levels_vccq21.attr, | ||
| 543 | &dev_attr_active_icc_levels_vccq22.attr, | ||
| 544 | &dev_attr_active_icc_levels_vccq23.attr, | ||
| 545 | &dev_attr_active_icc_levels_vccq24.attr, | ||
| 546 | &dev_attr_active_icc_levels_vccq25.attr, | ||
| 547 | &dev_attr_active_icc_levels_vccq26.attr, | ||
| 548 | &dev_attr_active_icc_levels_vccq27.attr, | ||
| 549 | &dev_attr_active_icc_levels_vccq28.attr, | ||
| 550 | &dev_attr_active_icc_levels_vccq29.attr, | ||
| 551 | &dev_attr_active_icc_levels_vccq210.attr, | ||
| 552 | &dev_attr_active_icc_levels_vccq211.attr, | ||
| 553 | &dev_attr_active_icc_levels_vccq212.attr, | ||
| 554 | &dev_attr_active_icc_levels_vccq213.attr, | ||
| 555 | &dev_attr_active_icc_levels_vccq214.attr, | ||
| 556 | &dev_attr_active_icc_levels_vccq215.attr, | ||
| 557 | NULL, | ||
| 558 | }; | ||
| 559 | |||
| 560 | static const struct attribute_group ufs_sysfs_power_descriptor_group = { | ||
| 561 | .name = "power_descriptor", | ||
| 562 | .attrs = ufs_sysfs_power_descriptor, | ||
| 563 | }; | ||
| 564 | |||
| 565 | #define UFS_STRING_DESCRIPTOR(_name, _pname) \ | ||
| 566 | static ssize_t _name##_show(struct device *dev, \ | ||
| 567 | struct device_attribute *attr, char *buf) \ | ||
| 568 | { \ | ||
| 569 | u8 index; \ | ||
| 570 | struct ufs_hba *hba = dev_get_drvdata(dev); \ | ||
| 571 | int ret; \ | ||
| 572 | int desc_len = QUERY_DESC_MAX_SIZE; \ | ||
| 573 | u8 *desc_buf; \ | ||
| 574 | desc_buf = kzalloc(QUERY_DESC_MAX_SIZE, GFP_ATOMIC); \ | ||
| 575 | if (!desc_buf) \ | ||
| 576 | return -ENOMEM; \ | ||
| 577 | ret = ufshcd_query_descriptor_retry(hba, \ | ||
| 578 | UPIU_QUERY_OPCODE_READ_DESC, QUERY_DESC_IDN_DEVICE, \ | ||
| 579 | 0, 0, desc_buf, &desc_len); \ | ||
| 580 | if (ret) { \ | ||
| 581 | ret = -EINVAL; \ | ||
| 582 | goto out; \ | ||
| 583 | } \ | ||
| 584 | index = desc_buf[DEVICE_DESC_PARAM##_pname]; \ | ||
| 585 | memset(desc_buf, 0, QUERY_DESC_MAX_SIZE); \ | ||
| 586 | if (ufshcd_read_string_desc(hba, index, desc_buf, \ | ||
| 587 | QUERY_DESC_MAX_SIZE, true)) { \ | ||
| 588 | ret = -EINVAL; \ | ||
| 589 | goto out; \ | ||
| 590 | } \ | ||
| 591 | ret = snprintf(buf, PAGE_SIZE, "%s\n", \ | ||
| 592 | desc_buf + QUERY_DESC_HDR_SIZE); \ | ||
| 593 | out: \ | ||
| 594 | kfree(desc_buf); \ | ||
| 595 | return ret; \ | ||
| 596 | } \ | ||
| 597 | static DEVICE_ATTR_RO(_name) | ||
| 598 | |||
| 599 | UFS_STRING_DESCRIPTOR(manufacturer_name, _MANF_NAME); | ||
| 600 | UFS_STRING_DESCRIPTOR(product_name, _PRDCT_NAME); | ||
| 601 | UFS_STRING_DESCRIPTOR(oem_id, _OEM_ID); | ||
| 602 | UFS_STRING_DESCRIPTOR(serial_number, _SN); | ||
| 603 | UFS_STRING_DESCRIPTOR(product_revision, _PRDCT_REV); | ||
| 604 | |||
| 605 | static struct attribute *ufs_sysfs_string_descriptors[] = { | ||
| 606 | &dev_attr_manufacturer_name.attr, | ||
| 607 | &dev_attr_product_name.attr, | ||
| 608 | &dev_attr_oem_id.attr, | ||
| 609 | &dev_attr_serial_number.attr, | ||
| 610 | &dev_attr_product_revision.attr, | ||
| 611 | NULL, | ||
| 612 | }; | ||
| 613 | |||
| 614 | static const struct attribute_group ufs_sysfs_string_descriptors_group = { | ||
| 615 | .name = "string_descriptors", | ||
| 616 | .attrs = ufs_sysfs_string_descriptors, | ||
| 617 | }; | ||
| 618 | |||
| 619 | #define UFS_FLAG(_name, _uname) \ | ||
| 620 | static ssize_t _name##_show(struct device *dev, \ | ||
| 621 | struct device_attribute *attr, char *buf) \ | ||
| 622 | { \ | ||
| 623 | bool flag; \ | ||
| 624 | struct ufs_hba *hba = dev_get_drvdata(dev); \ | ||
| 625 | if (ufshcd_query_flag(hba, UPIU_QUERY_OPCODE_READ_FLAG, \ | ||
| 626 | QUERY_FLAG_IDN##_uname, &flag)) \ | ||
| 627 | return -EINVAL; \ | ||
| 628 | return sprintf(buf, "%s\n", flag ? "true" : "false"); \ | ||
| 629 | } \ | ||
| 630 | static DEVICE_ATTR_RO(_name) | ||
| 631 | |||
| 632 | UFS_FLAG(device_init, _FDEVICEINIT); | ||
| 633 | UFS_FLAG(permanent_wpe, _PERMANENT_WPE); | ||
| 634 | UFS_FLAG(power_on_wpe, _PWR_ON_WPE); | ||
| 635 | UFS_FLAG(bkops_enable, _BKOPS_EN); | ||
| 636 | UFS_FLAG(life_span_mode_enable, _LIFE_SPAN_MODE_ENABLE); | ||
| 637 | UFS_FLAG(phy_resource_removal, _FPHYRESOURCEREMOVAL); | ||
| 638 | UFS_FLAG(busy_rtc, _BUSY_RTC); | ||
| 639 | UFS_FLAG(disable_fw_update, _PERMANENTLY_DISABLE_FW_UPDATE); | ||
| 640 | |||
| 641 | static struct attribute *ufs_sysfs_device_flags[] = { | ||
| 642 | &dev_attr_device_init.attr, | ||
| 643 | &dev_attr_permanent_wpe.attr, | ||
| 644 | &dev_attr_power_on_wpe.attr, | ||
| 645 | &dev_attr_bkops_enable.attr, | ||
| 646 | &dev_attr_life_span_mode_enable.attr, | ||
| 647 | &dev_attr_phy_resource_removal.attr, | ||
| 648 | &dev_attr_busy_rtc.attr, | ||
| 649 | &dev_attr_disable_fw_update.attr, | ||
| 650 | NULL, | ||
| 651 | }; | ||
| 652 | |||
| 653 | static const struct attribute_group ufs_sysfs_flags_group = { | ||
| 654 | .name = "flags", | ||
| 655 | .attrs = ufs_sysfs_device_flags, | ||
| 656 | }; | ||
| 657 | |||
| 658 | #define UFS_ATTRIBUTE(_name, _uname) \ | ||
| 659 | static ssize_t _name##_show(struct device *dev, \ | ||
| 660 | struct device_attribute *attr, char *buf) \ | ||
| 661 | { \ | ||
| 662 | struct ufs_hba *hba = dev_get_drvdata(dev); \ | ||
| 663 | u32 value; \ | ||
| 664 | if (ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR, \ | ||
| 665 | QUERY_ATTR_IDN##_uname, 0, 0, &value)) \ | ||
| 666 | return -EINVAL; \ | ||
| 667 | return sprintf(buf, "0x%08X\n", value); \ | ||
| 668 | } \ | ||
| 669 | static DEVICE_ATTR_RO(_name) | ||
| 670 | |||
| 671 | UFS_ATTRIBUTE(boot_lun_enabled, _BOOT_LU_EN); | ||
| 672 | UFS_ATTRIBUTE(current_power_mode, _POWER_MODE); | ||
| 673 | UFS_ATTRIBUTE(active_icc_level, _ACTIVE_ICC_LVL); | ||
| 674 | UFS_ATTRIBUTE(ooo_data_enabled, _OOO_DATA_EN); | ||
| 675 | UFS_ATTRIBUTE(bkops_status, _BKOPS_STATUS); | ||
| 676 | UFS_ATTRIBUTE(purge_status, _PURGE_STATUS); | ||
| 677 | UFS_ATTRIBUTE(max_data_in_size, _MAX_DATA_IN); | ||
| 678 | UFS_ATTRIBUTE(max_data_out_size, _MAX_DATA_OUT); | ||
| 679 | UFS_ATTRIBUTE(reference_clock_frequency, _REF_CLK_FREQ); | ||
| 680 | UFS_ATTRIBUTE(configuration_descriptor_lock, _CONF_DESC_LOCK); | ||
| 681 | UFS_ATTRIBUTE(max_number_of_rtt, _MAX_NUM_OF_RTT); | ||
| 682 | UFS_ATTRIBUTE(exception_event_control, _EE_CONTROL); | ||
| 683 | UFS_ATTRIBUTE(exception_event_status, _EE_STATUS); | ||
| 684 | UFS_ATTRIBUTE(ffu_status, _FFU_STATUS); | ||
| 685 | UFS_ATTRIBUTE(psa_state, _PSA_STATE); | ||
| 686 | UFS_ATTRIBUTE(psa_data_size, _PSA_DATA_SIZE); | ||
| 687 | |||
| 688 | static struct attribute *ufs_sysfs_attributes[] = { | ||
| 689 | &dev_attr_boot_lun_enabled.attr, | ||
| 690 | &dev_attr_current_power_mode.attr, | ||
| 691 | &dev_attr_active_icc_level.attr, | ||
| 692 | &dev_attr_ooo_data_enabled.attr, | ||
| 693 | &dev_attr_bkops_status.attr, | ||
| 694 | &dev_attr_purge_status.attr, | ||
| 695 | &dev_attr_max_data_in_size.attr, | ||
| 696 | &dev_attr_max_data_out_size.attr, | ||
| 697 | &dev_attr_reference_clock_frequency.attr, | ||
| 698 | &dev_attr_configuration_descriptor_lock.attr, | ||
| 699 | &dev_attr_max_number_of_rtt.attr, | ||
| 700 | &dev_attr_exception_event_control.attr, | ||
| 701 | &dev_attr_exception_event_status.attr, | ||
| 702 | &dev_attr_ffu_status.attr, | ||
| 703 | &dev_attr_psa_state.attr, | ||
| 704 | &dev_attr_psa_data_size.attr, | ||
| 705 | NULL, | ||
| 706 | }; | ||
| 707 | |||
| 708 | static const struct attribute_group ufs_sysfs_attributes_group = { | ||
| 709 | .name = "attributes", | ||
| 710 | .attrs = ufs_sysfs_attributes, | ||
| 711 | }; | ||
| 712 | |||
| 713 | static const struct attribute_group *ufs_sysfs_groups[] = { | ||
| 714 | &ufs_sysfs_default_group, | ||
| 715 | &ufs_sysfs_device_descriptor_group, | ||
| 716 | &ufs_sysfs_interconnect_descriptor_group, | ||
| 717 | &ufs_sysfs_geometry_descriptor_group, | ||
| 718 | &ufs_sysfs_health_descriptor_group, | ||
| 719 | &ufs_sysfs_power_descriptor_group, | ||
| 720 | &ufs_sysfs_string_descriptors_group, | ||
| 721 | &ufs_sysfs_flags_group, | ||
| 722 | &ufs_sysfs_attributes_group, | ||
| 723 | NULL, | ||
| 724 | }; | ||
| 725 | |||
| 726 | #define UFS_LUN_DESC_PARAM(_pname, _puname, _duname, _size) \ | ||
| 727 | static ssize_t _pname##_show(struct device *dev, \ | ||
| 728 | struct device_attribute *attr, char *buf) \ | ||
| 729 | { \ | ||
| 730 | struct scsi_device *sdev = to_scsi_device(dev); \ | ||
| 731 | struct ufs_hba *hba = shost_priv(sdev->host); \ | ||
| 732 | u8 lun = ufshcd_scsi_to_upiu_lun(sdev->lun); \ | ||
| 733 | if (!ufs_is_valid_unit_desc_lun(lun)) \ | ||
| 734 | return -EINVAL; \ | ||
| 735 | return ufs_sysfs_read_desc_param(hba, QUERY_DESC_IDN_##_duname, \ | ||
| 736 | lun, _duname##_DESC_PARAM##_puname, buf, _size); \ | ||
| 737 | } \ | ||
| 738 | static DEVICE_ATTR_RO(_pname) | ||
| 739 | |||
| 740 | #define UFS_UNIT_DESC_PARAM(_name, _uname, _size) \ | ||
| 741 | UFS_LUN_DESC_PARAM(_name, _uname, UNIT, _size) | ||
| 742 | |||
| 743 | UFS_UNIT_DESC_PARAM(boot_lun_id, _BOOT_LUN_ID, 1); | ||
| 744 | UFS_UNIT_DESC_PARAM(lun_write_protect, _LU_WR_PROTECT, 1); | ||
| 745 | UFS_UNIT_DESC_PARAM(lun_queue_depth, _LU_Q_DEPTH, 1); | ||
| 746 | UFS_UNIT_DESC_PARAM(psa_sensitive, _PSA_SENSITIVE, 1); | ||
| 747 | UFS_UNIT_DESC_PARAM(lun_memory_type, _MEM_TYPE, 1); | ||
| 748 | UFS_UNIT_DESC_PARAM(data_reliability, _DATA_RELIABILITY, 1); | ||
| 749 | UFS_UNIT_DESC_PARAM(logical_block_size, _LOGICAL_BLK_SIZE, 1); | ||
| 750 | UFS_UNIT_DESC_PARAM(logical_block_count, _LOGICAL_BLK_COUNT, 8); | ||
| 751 | UFS_UNIT_DESC_PARAM(erase_block_size, _ERASE_BLK_SIZE, 4); | ||
| 752 | UFS_UNIT_DESC_PARAM(provisioning_type, _PROVISIONING_TYPE, 1); | ||
| 753 | UFS_UNIT_DESC_PARAM(physical_memory_resourse_count, _PHY_MEM_RSRC_CNT, 8); | ||
| 754 | UFS_UNIT_DESC_PARAM(context_capabilities, _CTX_CAPABILITIES, 2); | ||
| 755 | UFS_UNIT_DESC_PARAM(large_unit_granularity, _LARGE_UNIT_SIZE_M1, 1); | ||
| 756 | |||
| 757 | static struct attribute *ufs_sysfs_unit_descriptor[] = { | ||
| 758 | &dev_attr_boot_lun_id.attr, | ||
| 759 | &dev_attr_lun_write_protect.attr, | ||
| 760 | &dev_attr_lun_queue_depth.attr, | ||
| 761 | &dev_attr_psa_sensitive.attr, | ||
| 762 | &dev_attr_lun_memory_type.attr, | ||
| 763 | &dev_attr_data_reliability.attr, | ||
| 764 | &dev_attr_logical_block_size.attr, | ||
| 765 | &dev_attr_logical_block_count.attr, | ||
| 766 | &dev_attr_erase_block_size.attr, | ||
| 767 | &dev_attr_provisioning_type.attr, | ||
| 768 | &dev_attr_physical_memory_resourse_count.attr, | ||
| 769 | &dev_attr_context_capabilities.attr, | ||
| 770 | &dev_attr_large_unit_granularity.attr, | ||
| 771 | NULL, | ||
| 772 | }; | ||
| 773 | |||
| 774 | const struct attribute_group ufs_sysfs_unit_descriptor_group = { | ||
| 775 | .name = "unit_descriptor", | ||
| 776 | .attrs = ufs_sysfs_unit_descriptor, | ||
| 777 | }; | ||
| 778 | |||
| 779 | static ssize_t dyn_cap_needed_attribute_show(struct device *dev, | ||
| 780 | struct device_attribute *attr, char *buf) | ||
| 781 | { | ||
| 782 | u32 value; | ||
| 783 | struct scsi_device *sdev = to_scsi_device(dev); | ||
| 784 | struct ufs_hba *hba = shost_priv(sdev->host); | ||
| 785 | u8 lun = ufshcd_scsi_to_upiu_lun(sdev->lun); | ||
| 786 | |||
| 787 | if (ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_READ_ATTR, | ||
| 788 | QUERY_ATTR_IDN_DYN_CAP_NEEDED, lun, 0, &value)) | ||
| 789 | return -EINVAL; | ||
| 790 | return sprintf(buf, "0x%08X\n", value); | ||
| 791 | } | ||
| 792 | static DEVICE_ATTR_RO(dyn_cap_needed_attribute); | ||
| 793 | |||
| 794 | static struct attribute *ufs_sysfs_lun_attributes[] = { | ||
| 795 | &dev_attr_dyn_cap_needed_attribute.attr, | ||
| 796 | NULL, | ||
| 797 | }; | ||
| 798 | |||
| 799 | const struct attribute_group ufs_sysfs_lun_attributes_group = { | ||
| 800 | .attrs = ufs_sysfs_lun_attributes, | ||
| 801 | }; | ||
| 802 | |||
| 803 | void ufs_sysfs_add_nodes(struct device *dev) | ||
| 804 | { | ||
| 805 | int ret; | ||
| 806 | |||
| 807 | ret = sysfs_create_groups(&dev->kobj, ufs_sysfs_groups); | ||
| 808 | if (ret) | ||
| 809 | dev_err(dev, | ||
| 810 | "%s: sysfs groups creation failed (err = %d)\n", | ||
| 811 | __func__, ret); | ||
| 812 | } | ||
| 813 | |||
| 814 | void ufs_sysfs_remove_nodes(struct device *dev) | ||
| 815 | { | ||
| 816 | sysfs_remove_groups(&dev->kobj, ufs_sysfs_groups); | ||
| 817 | } | ||
diff --git a/drivers/scsi/ufs/ufs-sysfs.h b/drivers/scsi/ufs/ufs-sysfs.h new file mode 100644 index 000000000000..e5621e59a432 --- /dev/null +++ b/drivers/scsi/ufs/ufs-sysfs.h | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 | ||
| 2 | * Copyright (C) 2018 Western Digital Corporation | ||
| 3 | */ | ||
| 4 | |||
| 5 | #ifndef __UFS_SYSFS_H__ | ||
| 6 | #define __UFS_SYSFS_H__ | ||
| 7 | |||
| 8 | #include <linux/sysfs.h> | ||
| 9 | |||
| 10 | #include "ufshcd.h" | ||
| 11 | |||
| 12 | void ufs_sysfs_add_nodes(struct device *dev); | ||
| 13 | void ufs_sysfs_remove_nodes(struct device *dev); | ||
| 14 | |||
| 15 | extern const struct attribute_group ufs_sysfs_unit_descriptor_group; | ||
| 16 | extern const struct attribute_group ufs_sysfs_lun_attributes_group; | ||
| 17 | #endif | ||
diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h index 54deeb754db5..14e5bf7af0bb 100644 --- a/drivers/scsi/ufs/ufs.h +++ b/drivers/scsi/ufs/ufs.h | |||
| @@ -130,17 +130,44 @@ enum { | |||
| 130 | 130 | ||
| 131 | /* Flag idn for Query Requests*/ | 131 | /* Flag idn for Query Requests*/ |
| 132 | enum flag_idn { | 132 | enum flag_idn { |
| 133 | QUERY_FLAG_IDN_FDEVICEINIT = 0x01, | 133 | QUERY_FLAG_IDN_FDEVICEINIT = 0x01, |
| 134 | QUERY_FLAG_IDN_PWR_ON_WPE = 0x03, | 134 | QUERY_FLAG_IDN_PERMANENT_WPE = 0x02, |
| 135 | QUERY_FLAG_IDN_BKOPS_EN = 0x04, | 135 | QUERY_FLAG_IDN_PWR_ON_WPE = 0x03, |
| 136 | QUERY_FLAG_IDN_BKOPS_EN = 0x04, | ||
| 137 | QUERY_FLAG_IDN_LIFE_SPAN_MODE_ENABLE = 0x05, | ||
| 138 | QUERY_FLAG_IDN_PURGE_ENABLE = 0x06, | ||
| 139 | QUERY_FLAG_IDN_RESERVED2 = 0x07, | ||
| 140 | QUERY_FLAG_IDN_FPHYRESOURCEREMOVAL = 0x08, | ||
| 141 | QUERY_FLAG_IDN_BUSY_RTC = 0x09, | ||
| 142 | QUERY_FLAG_IDN_RESERVED3 = 0x0A, | ||
| 143 | QUERY_FLAG_IDN_PERMANENTLY_DISABLE_FW_UPDATE = 0x0B, | ||
| 136 | }; | 144 | }; |
| 137 | 145 | ||
| 138 | /* Attribute idn for Query requests */ | 146 | /* Attribute idn for Query requests */ |
| 139 | enum attr_idn { | 147 | enum attr_idn { |
| 140 | QUERY_ATTR_IDN_ACTIVE_ICC_LVL = 0x03, | 148 | QUERY_ATTR_IDN_BOOT_LU_EN = 0x00, |
| 141 | QUERY_ATTR_IDN_BKOPS_STATUS = 0x05, | 149 | QUERY_ATTR_IDN_RESERVED = 0x01, |
| 142 | QUERY_ATTR_IDN_EE_CONTROL = 0x0D, | 150 | QUERY_ATTR_IDN_POWER_MODE = 0x02, |
| 143 | QUERY_ATTR_IDN_EE_STATUS = 0x0E, | 151 | QUERY_ATTR_IDN_ACTIVE_ICC_LVL = 0x03, |
| 152 | QUERY_ATTR_IDN_OOO_DATA_EN = 0x04, | ||
| 153 | QUERY_ATTR_IDN_BKOPS_STATUS = 0x05, | ||
| 154 | QUERY_ATTR_IDN_PURGE_STATUS = 0x06, | ||
| 155 | QUERY_ATTR_IDN_MAX_DATA_IN = 0x07, | ||
| 156 | QUERY_ATTR_IDN_MAX_DATA_OUT = 0x08, | ||
| 157 | QUERY_ATTR_IDN_DYN_CAP_NEEDED = 0x09, | ||
| 158 | QUERY_ATTR_IDN_REF_CLK_FREQ = 0x0A, | ||
| 159 | QUERY_ATTR_IDN_CONF_DESC_LOCK = 0x0B, | ||
| 160 | QUERY_ATTR_IDN_MAX_NUM_OF_RTT = 0x0C, | ||
| 161 | QUERY_ATTR_IDN_EE_CONTROL = 0x0D, | ||
| 162 | QUERY_ATTR_IDN_EE_STATUS = 0x0E, | ||
| 163 | QUERY_ATTR_IDN_SECONDS_PASSED = 0x0F, | ||
| 164 | QUERY_ATTR_IDN_CNTX_CONF = 0x10, | ||
| 165 | QUERY_ATTR_IDN_CORR_PRG_BLK_NUM = 0x11, | ||
| 166 | QUERY_ATTR_IDN_RESERVED2 = 0x12, | ||
| 167 | QUERY_ATTR_IDN_RESERVED3 = 0x13, | ||
| 168 | QUERY_ATTR_IDN_FFU_STATUS = 0x14, | ||
| 169 | QUERY_ATTR_IDN_PSA_STATE = 0x15, | ||
| 170 | QUERY_ATTR_IDN_PSA_DATA_SIZE = 0x16, | ||
| 144 | }; | 171 | }; |
| 145 | 172 | ||
| 146 | /* Descriptor idn for Query requests */ | 173 | /* Descriptor idn for Query requests */ |
| @@ -154,6 +181,7 @@ enum desc_idn { | |||
| 154 | QUERY_DESC_IDN_RFU_1 = 0x6, | 181 | QUERY_DESC_IDN_RFU_1 = 0x6, |
| 155 | QUERY_DESC_IDN_GEOMETRY = 0x7, | 182 | QUERY_DESC_IDN_GEOMETRY = 0x7, |
| 156 | QUERY_DESC_IDN_POWER = 0x8, | 183 | QUERY_DESC_IDN_POWER = 0x8, |
| 184 | QUERY_DESC_IDN_HEALTH = 0x9, | ||
| 157 | QUERY_DESC_IDN_MAX, | 185 | QUERY_DESC_IDN_MAX, |
| 158 | }; | 186 | }; |
| 159 | 187 | ||
| @@ -169,6 +197,7 @@ enum ufs_desc_def_size { | |||
| 169 | QUERY_DESC_INTERCONNECT_DEF_SIZE = 0x06, | 197 | QUERY_DESC_INTERCONNECT_DEF_SIZE = 0x06, |
| 170 | QUERY_DESC_GEOMETRY_DEF_SIZE = 0x44, | 198 | QUERY_DESC_GEOMETRY_DEF_SIZE = 0x44, |
| 171 | QUERY_DESC_POWER_DEF_SIZE = 0x62, | 199 | QUERY_DESC_POWER_DEF_SIZE = 0x62, |
| 200 | QUERY_DESC_HEALTH_DEF_SIZE = 0x25, | ||
| 172 | }; | 201 | }; |
| 173 | 202 | ||
| 174 | /* Unit descriptor parameters offsets in bytes*/ | 203 | /* Unit descriptor parameters offsets in bytes*/ |
| @@ -180,6 +209,7 @@ enum unit_desc_param { | |||
| 180 | UNIT_DESC_PARAM_BOOT_LUN_ID = 0x4, | 209 | UNIT_DESC_PARAM_BOOT_LUN_ID = 0x4, |
| 181 | UNIT_DESC_PARAM_LU_WR_PROTECT = 0x5, | 210 | UNIT_DESC_PARAM_LU_WR_PROTECT = 0x5, |
| 182 | UNIT_DESC_PARAM_LU_Q_DEPTH = 0x6, | 211 | UNIT_DESC_PARAM_LU_Q_DEPTH = 0x6, |
| 212 | UNIT_DESC_PARAM_PSA_SENSITIVE = 0x7, | ||
| 183 | UNIT_DESC_PARAM_MEM_TYPE = 0x8, | 213 | UNIT_DESC_PARAM_MEM_TYPE = 0x8, |
| 184 | UNIT_DESC_PARAM_DATA_RELIABILITY = 0x9, | 214 | UNIT_DESC_PARAM_DATA_RELIABILITY = 0x9, |
| 185 | UNIT_DESC_PARAM_LOGICAL_BLK_SIZE = 0xA, | 215 | UNIT_DESC_PARAM_LOGICAL_BLK_SIZE = 0xA, |
| @@ -220,6 +250,67 @@ enum device_desc_param { | |||
| 220 | DEVICE_DESC_PARAM_UD_LEN = 0x1B, | 250 | DEVICE_DESC_PARAM_UD_LEN = 0x1B, |
| 221 | DEVICE_DESC_PARAM_RTT_CAP = 0x1C, | 251 | DEVICE_DESC_PARAM_RTT_CAP = 0x1C, |
| 222 | DEVICE_DESC_PARAM_FRQ_RTC = 0x1D, | 252 | DEVICE_DESC_PARAM_FRQ_RTC = 0x1D, |
| 253 | DEVICE_DESC_PARAM_UFS_FEAT = 0x1F, | ||
| 254 | DEVICE_DESC_PARAM_FFU_TMT = 0x20, | ||
| 255 | DEVICE_DESC_PARAM_Q_DPTH = 0x21, | ||
| 256 | DEVICE_DESC_PARAM_DEV_VER = 0x22, | ||
| 257 | DEVICE_DESC_PARAM_NUM_SEC_WPA = 0x24, | ||
| 258 | DEVICE_DESC_PARAM_PSA_MAX_DATA = 0x25, | ||
| 259 | DEVICE_DESC_PARAM_PSA_TMT = 0x29, | ||
| 260 | DEVICE_DESC_PARAM_PRDCT_REV = 0x2A, | ||
| 261 | }; | ||
| 262 | |||
| 263 | /* Interconnect descriptor parameters offsets in bytes*/ | ||
| 264 | enum interconnect_desc_param { | ||
| 265 | INTERCONNECT_DESC_PARAM_LEN = 0x0, | ||
| 266 | INTERCONNECT_DESC_PARAM_TYPE = 0x1, | ||
| 267 | INTERCONNECT_DESC_PARAM_UNIPRO_VER = 0x2, | ||
| 268 | INTERCONNECT_DESC_PARAM_MPHY_VER = 0x4, | ||
| 269 | }; | ||
| 270 | |||
| 271 | /* Geometry descriptor parameters offsets in bytes*/ | ||
| 272 | enum geometry_desc_param { | ||
| 273 | GEOMETRY_DESC_PARAM_LEN = 0x0, | ||
| 274 | GEOMETRY_DESC_PARAM_TYPE = 0x1, | ||
| 275 | GEOMETRY_DESC_PARAM_DEV_CAP = 0x4, | ||
| 276 | GEOMETRY_DESC_PARAM_MAX_NUM_LUN = 0xC, | ||
| 277 | GEOMETRY_DESC_PARAM_SEG_SIZE = 0xD, | ||
| 278 | GEOMETRY_DESC_PARAM_ALLOC_UNIT_SIZE = 0x11, | ||
| 279 | GEOMETRY_DESC_PARAM_MIN_BLK_SIZE = 0x12, | ||
| 280 | GEOMETRY_DESC_PARAM_OPT_RD_BLK_SIZE = 0x13, | ||
| 281 | GEOMETRY_DESC_PARAM_OPT_WR_BLK_SIZE = 0x14, | ||
| 282 | GEOMETRY_DESC_PARAM_MAX_IN_BUF_SIZE = 0x15, | ||
| 283 | GEOMETRY_DESC_PARAM_MAX_OUT_BUF_SIZE = 0x16, | ||
| 284 | GEOMETRY_DESC_PARAM_RPMB_RW_SIZE = 0x17, | ||
| 285 | GEOMETRY_DESC_PARAM_DYN_CAP_RSRC_PLC = 0x18, | ||
| 286 | GEOMETRY_DESC_PARAM_DATA_ORDER = 0x19, | ||
| 287 | GEOMETRY_DESC_PARAM_MAX_NUM_CTX = 0x1A, | ||
| 288 | GEOMETRY_DESC_PARAM_TAG_UNIT_SIZE = 0x1B, | ||
| 289 | GEOMETRY_DESC_PARAM_TAG_RSRC_SIZE = 0x1C, | ||
| 290 | GEOMETRY_DESC_PARAM_SEC_RM_TYPES = 0x1D, | ||
| 291 | GEOMETRY_DESC_PARAM_MEM_TYPES = 0x1E, | ||
| 292 | GEOMETRY_DESC_PARAM_SCM_MAX_NUM_UNITS = 0x20, | ||
| 293 | GEOMETRY_DESC_PARAM_SCM_CAP_ADJ_FCTR = 0x24, | ||
| 294 | GEOMETRY_DESC_PARAM_NPM_MAX_NUM_UNITS = 0x26, | ||
| 295 | GEOMETRY_DESC_PARAM_NPM_CAP_ADJ_FCTR = 0x2A, | ||
| 296 | GEOMETRY_DESC_PARAM_ENM1_MAX_NUM_UNITS = 0x2C, | ||
| 297 | GEOMETRY_DESC_PARAM_ENM1_CAP_ADJ_FCTR = 0x30, | ||
| 298 | GEOMETRY_DESC_PARAM_ENM2_MAX_NUM_UNITS = 0x32, | ||
| 299 | GEOMETRY_DESC_PARAM_ENM2_CAP_ADJ_FCTR = 0x36, | ||
| 300 | GEOMETRY_DESC_PARAM_ENM3_MAX_NUM_UNITS = 0x38, | ||
| 301 | GEOMETRY_DESC_PARAM_ENM3_CAP_ADJ_FCTR = 0x3C, | ||
| 302 | GEOMETRY_DESC_PARAM_ENM4_MAX_NUM_UNITS = 0x3E, | ||
| 303 | GEOMETRY_DESC_PARAM_ENM4_CAP_ADJ_FCTR = 0x42, | ||
| 304 | GEOMETRY_DESC_PARAM_OPT_LOG_BLK_SIZE = 0x44, | ||
| 305 | }; | ||
| 306 | |||
| 307 | /* Health descriptor parameters offsets in bytes*/ | ||
| 308 | enum health_desc_param { | ||
| 309 | HEALTH_DESC_PARAM_LEN = 0x0, | ||
| 310 | HEALTH_DESC_PARAM_TYPE = 0x1, | ||
| 311 | HEALTH_DESC_PARAM_EOL_INFO = 0x2, | ||
| 312 | HEALTH_DESC_PARAM_LIFE_TIME_EST_A = 0x3, | ||
| 313 | HEALTH_DESC_PARAM_LIFE_TIME_EST_B = 0x4, | ||
| 223 | }; | 314 | }; |
| 224 | 315 | ||
| 225 | /* | 316 | /* |
| @@ -529,4 +620,14 @@ struct ufs_dev_desc { | |||
| 529 | char model[MAX_MODEL_LEN + 1]; | 620 | char model[MAX_MODEL_LEN + 1]; |
| 530 | }; | 621 | }; |
| 531 | 622 | ||
| 623 | /** | ||
| 624 | * ufs_is_valid_unit_desc_lun - checks if the given LUN has a unit descriptor | ||
| 625 | * @lun: LU number to check | ||
| 626 | * @return: true if the lun has a matching unit descriptor, false otherwise | ||
| 627 | */ | ||
| 628 | static inline bool ufs_is_valid_unit_desc_lun(u8 lun) | ||
| 629 | { | ||
| 630 | return lun == UFS_UPIU_RPMB_WLUN || (lun < UFS_UPIU_MAX_GENERAL_LUN); | ||
| 631 | } | ||
| 632 | |||
| 532 | #endif /* End of Header */ | 633 | #endif /* End of Header */ |
diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/scsi/ufs/ufshcd-pci.c index 925b0ec7ec54..ffe6f82182ba 100644 --- a/drivers/scsi/ufs/ufshcd-pci.c +++ b/drivers/scsi/ufs/ufshcd-pci.c | |||
| @@ -75,8 +75,7 @@ static struct ufs_hba_variant_ops ufs_intel_cnl_hba_vops = { | |||
| 75 | #ifdef CONFIG_PM_SLEEP | 75 | #ifdef CONFIG_PM_SLEEP |
| 76 | /** | 76 | /** |
| 77 | * ufshcd_pci_suspend - suspend power management function | 77 | * ufshcd_pci_suspend - suspend power management function |
| 78 | * @pdev: pointer to PCI device handle | 78 | * @dev: pointer to PCI device handle |
| 79 | * @state: power state | ||
| 80 | * | 79 | * |
| 81 | * Returns 0 if successful | 80 | * Returns 0 if successful |
| 82 | * Returns non-zero otherwise | 81 | * Returns non-zero otherwise |
| @@ -88,7 +87,7 @@ static int ufshcd_pci_suspend(struct device *dev) | |||
| 88 | 87 | ||
| 89 | /** | 88 | /** |
| 90 | * ufshcd_pci_resume - resume power management function | 89 | * ufshcd_pci_resume - resume power management function |
| 91 | * @pdev: pointer to PCI device handle | 90 | * @dev: pointer to PCI device handle |
| 92 | * | 91 | * |
| 93 | * Returns 0 if successful | 92 | * Returns 0 if successful |
| 94 | * Returns non-zero otherwise | 93 | * Returns non-zero otherwise |
| @@ -126,7 +125,7 @@ static void ufshcd_pci_shutdown(struct pci_dev *pdev) | |||
| 126 | /** | 125 | /** |
| 127 | * ufshcd_pci_remove - de-allocate PCI/SCSI host and host memory space | 126 | * ufshcd_pci_remove - de-allocate PCI/SCSI host and host memory space |
| 128 | * data structure memory | 127 | * data structure memory |
| 129 | * @pdev - pointer to PCI handle | 128 | * @pdev: pointer to PCI handle |
| 130 | */ | 129 | */ |
| 131 | static void ufshcd_pci_remove(struct pci_dev *pdev) | 130 | static void ufshcd_pci_remove(struct pci_dev *pdev) |
| 132 | { | 131 | { |
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c index c7da2c185990..c5b1bf1cadcb 100644 --- a/drivers/scsi/ufs/ufshcd.c +++ b/drivers/scsi/ufs/ufshcd.c | |||
| @@ -41,9 +41,11 @@ | |||
| 41 | #include <linux/devfreq.h> | 41 | #include <linux/devfreq.h> |
| 42 | #include <linux/nls.h> | 42 | #include <linux/nls.h> |
| 43 | #include <linux/of.h> | 43 | #include <linux/of.h> |
| 44 | #include <linux/bitfield.h> | ||
| 44 | #include "ufshcd.h" | 45 | #include "ufshcd.h" |
| 45 | #include "ufs_quirks.h" | 46 | #include "ufs_quirks.h" |
| 46 | #include "unipro.h" | 47 | #include "unipro.h" |
| 48 | #include "ufs-sysfs.h" | ||
| 47 | 49 | ||
| 48 | #define CREATE_TRACE_POINTS | 50 | #define CREATE_TRACE_POINTS |
| 49 | #include <trace/events/ufs.h> | 51 | #include <trace/events/ufs.h> |
| @@ -150,7 +152,7 @@ enum { | |||
| 150 | #define ufshcd_is_ufs_dev_poweroff(h) \ | 152 | #define ufshcd_is_ufs_dev_poweroff(h) \ |
| 151 | ((h)->curr_dev_pwr_mode == UFS_POWERDOWN_PWR_MODE) | 153 | ((h)->curr_dev_pwr_mode == UFS_POWERDOWN_PWR_MODE) |
| 152 | 154 | ||
| 153 | static struct ufs_pm_lvl_states ufs_pm_lvl_states[] = { | 155 | struct ufs_pm_lvl_states ufs_pm_lvl_states[] = { |
| 154 | {UFS_ACTIVE_PWR_MODE, UIC_LINK_ACTIVE_STATE}, | 156 | {UFS_ACTIVE_PWR_MODE, UIC_LINK_ACTIVE_STATE}, |
| 155 | {UFS_ACTIVE_PWR_MODE, UIC_LINK_HIBERN8_STATE}, | 157 | {UFS_ACTIVE_PWR_MODE, UIC_LINK_HIBERN8_STATE}, |
| 156 | {UFS_SLEEP_PWR_MODE, UIC_LINK_ACTIVE_STATE}, | 158 | {UFS_SLEEP_PWR_MODE, UIC_LINK_ACTIVE_STATE}, |
| @@ -523,7 +525,7 @@ int ufshcd_wait_for_register(struct ufs_hba *hba, u32 reg, u32 mask, | |||
| 523 | 525 | ||
| 524 | /** | 526 | /** |
| 525 | * ufshcd_get_intr_mask - Get the interrupt bit mask | 527 | * ufshcd_get_intr_mask - Get the interrupt bit mask |
| 526 | * @hba - Pointer to adapter instance | 528 | * @hba: Pointer to adapter instance |
| 527 | * | 529 | * |
| 528 | * Returns interrupt bit mask per version | 530 | * Returns interrupt bit mask per version |
| 529 | */ | 531 | */ |
| @@ -550,7 +552,7 @@ static inline u32 ufshcd_get_intr_mask(struct ufs_hba *hba) | |||
| 550 | 552 | ||
| 551 | /** | 553 | /** |
| 552 | * ufshcd_get_ufs_version - Get the UFS version supported by the HBA | 554 | * ufshcd_get_ufs_version - Get the UFS version supported by the HBA |
| 553 | * @hba - Pointer to adapter instance | 555 | * @hba: Pointer to adapter instance |
| 554 | * | 556 | * |
| 555 | * Returns UFSHCI version supported by the controller | 557 | * Returns UFSHCI version supported by the controller |
| 556 | */ | 558 | */ |
| @@ -577,7 +579,7 @@ static inline bool ufshcd_is_device_present(struct ufs_hba *hba) | |||
| 577 | 579 | ||
| 578 | /** | 580 | /** |
| 579 | * ufshcd_get_tr_ocs - Get the UTRD Overall Command Status | 581 | * ufshcd_get_tr_ocs - Get the UTRD Overall Command Status |
| 580 | * @lrb: pointer to local command reference block | 582 | * @lrbp: pointer to local command reference block |
| 581 | * | 583 | * |
| 582 | * This function is used to get the OCS field from UTRD | 584 | * This function is used to get the OCS field from UTRD |
| 583 | * Returns the OCS field in the UTRD | 585 | * Returns the OCS field in the UTRD |
| @@ -813,28 +815,6 @@ static inline bool ufshcd_is_hba_active(struct ufs_hba *hba) | |||
| 813 | ? false : true; | 815 | ? false : true; |
| 814 | } | 816 | } |
| 815 | 817 | ||
| 816 | static const char *ufschd_uic_link_state_to_string( | ||
| 817 | enum uic_link_state state) | ||
| 818 | { | ||
| 819 | switch (state) { | ||
| 820 | case UIC_LINK_OFF_STATE: return "OFF"; | ||
| 821 | case UIC_LINK_ACTIVE_STATE: return "ACTIVE"; | ||
| 822 | case UIC_LINK_HIBERN8_STATE: return "HIBERN8"; | ||
| 823 | default: return "UNKNOWN"; | ||
| 824 | } | ||
| 825 | } | ||
| 826 | |||
| 827 | static const char *ufschd_ufs_dev_pwr_mode_to_string( | ||
| 828 | enum ufs_dev_pwr_mode state) | ||
| 829 | { | ||
| 830 | switch (state) { | ||
| 831 | case UFS_ACTIVE_PWR_MODE: return "ACTIVE"; | ||
| 832 | case UFS_SLEEP_PWR_MODE: return "SLEEP"; | ||
| 833 | case UFS_POWERDOWN_PWR_MODE: return "POWERDOWN"; | ||
| 834 | default: return "UNKNOWN"; | ||
| 835 | } | ||
| 836 | } | ||
| 837 | |||
| 838 | u32 ufshcd_get_local_unipro_ver(struct ufs_hba *hba) | 818 | u32 ufshcd_get_local_unipro_ver(struct ufs_hba *hba) |
| 839 | { | 819 | { |
| 840 | /* HCI version 1.0 and 1.1 supports UniPro 1.41 */ | 820 | /* HCI version 1.0 and 1.1 supports UniPro 1.41 */ |
| @@ -1759,7 +1739,7 @@ void ufshcd_send_command(struct ufs_hba *hba, unsigned int task_tag) | |||
| 1759 | 1739 | ||
| 1760 | /** | 1740 | /** |
| 1761 | * ufshcd_copy_sense_data - Copy sense data in case of check condition | 1741 | * ufshcd_copy_sense_data - Copy sense data in case of check condition |
| 1762 | * @lrb - pointer to local reference block | 1742 | * @lrbp: pointer to local reference block |
| 1763 | */ | 1743 | */ |
| 1764 | static inline void ufshcd_copy_sense_data(struct ufshcd_lrb *lrbp) | 1744 | static inline void ufshcd_copy_sense_data(struct ufshcd_lrb *lrbp) |
| 1765 | { | 1745 | { |
| @@ -1781,7 +1761,7 @@ static inline void ufshcd_copy_sense_data(struct ufshcd_lrb *lrbp) | |||
| 1781 | * ufshcd_copy_query_response() - Copy the Query Response and the data | 1761 | * ufshcd_copy_query_response() - Copy the Query Response and the data |
| 1782 | * descriptor | 1762 | * descriptor |
| 1783 | * @hba: per adapter instance | 1763 | * @hba: per adapter instance |
| 1784 | * @lrb - pointer to local reference block | 1764 | * @lrbp: pointer to local reference block |
| 1785 | */ | 1765 | */ |
| 1786 | static | 1766 | static |
| 1787 | int ufshcd_copy_query_response(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) | 1767 | int ufshcd_copy_query_response(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) |
| @@ -1882,7 +1862,7 @@ ufshcd_dispatch_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) | |||
| 1882 | /** | 1862 | /** |
| 1883 | * ufshcd_wait_for_uic_cmd - Wait complectioin of UIC command | 1863 | * ufshcd_wait_for_uic_cmd - Wait complectioin of UIC command |
| 1884 | * @hba: per adapter instance | 1864 | * @hba: per adapter instance |
| 1885 | * @uic_command: UIC command | 1865 | * @uic_cmd: UIC command |
| 1886 | * | 1866 | * |
| 1887 | * Must be called with mutex held. | 1867 | * Must be called with mutex held. |
| 1888 | * Returns 0 only if success. | 1868 | * Returns 0 only if success. |
| @@ -1965,7 +1945,8 @@ ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) | |||
| 1965 | 1945 | ||
| 1966 | /** | 1946 | /** |
| 1967 | * ufshcd_map_sg - Map scatter-gather list to prdt | 1947 | * ufshcd_map_sg - Map scatter-gather list to prdt |
| 1968 | * @lrbp - pointer to local reference block | 1948 | * @hba: per adapter instance |
| 1949 | * @lrbp: pointer to local reference block | ||
| 1969 | * | 1950 | * |
| 1970 | * Returns 0 in case of success, non-zero value in case of failure | 1951 | * Returns 0 in case of success, non-zero value in case of failure |
| 1971 | */ | 1952 | */ |
| @@ -2101,8 +2082,8 @@ static void ufshcd_prepare_req_desc_hdr(struct ufshcd_lrb *lrbp, | |||
| 2101 | /** | 2082 | /** |
| 2102 | * ufshcd_prepare_utp_scsi_cmd_upiu() - fills the utp_transfer_req_desc, | 2083 | * ufshcd_prepare_utp_scsi_cmd_upiu() - fills the utp_transfer_req_desc, |
| 2103 | * for scsi commands | 2084 | * for scsi commands |
| 2104 | * @lrbp - local reference block pointer | 2085 | * @lrbp: local reference block pointer |
| 2105 | * @upiu_flags - flags | 2086 | * @upiu_flags: flags |
| 2106 | */ | 2087 | */ |
| 2107 | static | 2088 | static |
| 2108 | void ufshcd_prepare_utp_scsi_cmd_upiu(struct ufshcd_lrb *lrbp, u32 upiu_flags) | 2089 | void ufshcd_prepare_utp_scsi_cmd_upiu(struct ufshcd_lrb *lrbp, u32 upiu_flags) |
| @@ -2190,8 +2171,8 @@ static inline void ufshcd_prepare_utp_nop_upiu(struct ufshcd_lrb *lrbp) | |||
| 2190 | /** | 2171 | /** |
| 2191 | * ufshcd_comp_devman_upiu - UFS Protocol Information Unit(UPIU) | 2172 | * ufshcd_comp_devman_upiu - UFS Protocol Information Unit(UPIU) |
| 2192 | * for Device Management Purposes | 2173 | * for Device Management Purposes |
| 2193 | * @hba - per adapter instance | 2174 | * @hba: per adapter instance |
| 2194 | * @lrb - pointer to local reference block | 2175 | * @lrbp: pointer to local reference block |
| 2195 | */ | 2176 | */ |
| 2196 | static int ufshcd_comp_devman_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) | 2177 | static int ufshcd_comp_devman_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) |
| 2197 | { | 2178 | { |
| @@ -2218,8 +2199,8 @@ static int ufshcd_comp_devman_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) | |||
| 2218 | /** | 2199 | /** |
| 2219 | * ufshcd_comp_scsi_upiu - UFS Protocol Information Unit(UPIU) | 2200 | * ufshcd_comp_scsi_upiu - UFS Protocol Information Unit(UPIU) |
| 2220 | * for SCSI Purposes | 2201 | * for SCSI Purposes |
| 2221 | * @hba - per adapter instance | 2202 | * @hba: per adapter instance |
| 2222 | * @lrb - pointer to local reference block | 2203 | * @lrbp: pointer to local reference block |
| 2223 | */ | 2204 | */ |
| 2224 | static int ufshcd_comp_scsi_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) | 2205 | static int ufshcd_comp_scsi_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) |
| 2225 | { | 2206 | { |
| @@ -2243,24 +2224,9 @@ static int ufshcd_comp_scsi_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) | |||
| 2243 | return ret; | 2224 | return ret; |
| 2244 | } | 2225 | } |
| 2245 | 2226 | ||
| 2246 | /* | ||
| 2247 | * ufshcd_scsi_to_upiu_lun - maps scsi LUN to UPIU LUN | ||
| 2248 | * @scsi_lun: scsi LUN id | ||
| 2249 | * | ||
| 2250 | * Returns UPIU LUN id | ||
| 2251 | */ | ||
| 2252 | static inline u8 ufshcd_scsi_to_upiu_lun(unsigned int scsi_lun) | ||
| 2253 | { | ||
| 2254 | if (scsi_is_wlun(scsi_lun)) | ||
| 2255 | return (scsi_lun & UFS_UPIU_MAX_UNIT_NUM_ID) | ||
| 2256 | | UFS_UPIU_WLUN_ID; | ||
| 2257 | else | ||
| 2258 | return scsi_lun & UFS_UPIU_MAX_UNIT_NUM_ID; | ||
| 2259 | } | ||
| 2260 | |||
| 2261 | /** | 2227 | /** |
| 2262 | * ufshcd_upiu_wlun_to_scsi_wlun - maps UPIU W-LUN id to SCSI W-LUN ID | 2228 | * ufshcd_upiu_wlun_to_scsi_wlun - maps UPIU W-LUN id to SCSI W-LUN ID |
| 2263 | * @scsi_lun: UPIU W-LUN id | 2229 | * @upiu_wlun_id: UPIU W-LUN id |
| 2264 | * | 2230 | * |
| 2265 | * Returns SCSI W-LUN id | 2231 | * Returns SCSI W-LUN id |
| 2266 | */ | 2232 | */ |
| @@ -2271,8 +2237,8 @@ static inline u16 ufshcd_upiu_wlun_to_scsi_wlun(u8 upiu_wlun_id) | |||
| 2271 | 2237 | ||
| 2272 | /** | 2238 | /** |
| 2273 | * ufshcd_queuecommand - main entry point for SCSI requests | 2239 | * ufshcd_queuecommand - main entry point for SCSI requests |
| 2240 | * @host: SCSI host pointer | ||
| 2274 | * @cmd: command from SCSI Midlayer | 2241 | * @cmd: command from SCSI Midlayer |
| 2275 | * @done: call back function | ||
| 2276 | * | 2242 | * |
| 2277 | * Returns 0 for success, non-zero in case of failure | 2243 | * Returns 0 for success, non-zero in case of failure |
| 2278 | */ | 2244 | */ |
| @@ -2513,7 +2479,7 @@ static int ufshcd_wait_for_dev_cmd(struct ufs_hba *hba, | |||
| 2513 | /** | 2479 | /** |
| 2514 | * ufshcd_get_dev_cmd_tag - Get device management command tag | 2480 | * ufshcd_get_dev_cmd_tag - Get device management command tag |
| 2515 | * @hba: per-adapter instance | 2481 | * @hba: per-adapter instance |
| 2516 | * @tag: pointer to variable with available slot value | 2482 | * @tag_out: pointer to variable with available slot value |
| 2517 | * | 2483 | * |
| 2518 | * Get a free slot and lock it until device management command | 2484 | * Get a free slot and lock it until device management command |
| 2519 | * completes. | 2485 | * completes. |
| @@ -2550,9 +2516,9 @@ static inline void ufshcd_put_dev_cmd_tag(struct ufs_hba *hba, int tag) | |||
| 2550 | 2516 | ||
| 2551 | /** | 2517 | /** |
| 2552 | * ufshcd_exec_dev_cmd - API for sending device management requests | 2518 | * ufshcd_exec_dev_cmd - API for sending device management requests |
| 2553 | * @hba - UFS hba | 2519 | * @hba: UFS hba |
| 2554 | * @cmd_type - specifies the type (NOP, Query...) | 2520 | * @cmd_type: specifies the type (NOP, Query...) |
| 2555 | * @timeout - time in seconds | 2521 | * @timeout: time in seconds |
| 2556 | * | 2522 | * |
| 2557 | * NOTE: Since there is only one available tag for device management commands, | 2523 | * NOTE: Since there is only one available tag for device management commands, |
| 2558 | * it is expected you hold the hba->dev_cmd.lock mutex. | 2524 | * it is expected you hold the hba->dev_cmd.lock mutex. |
| @@ -2649,10 +2615,10 @@ static int ufshcd_query_flag_retry(struct ufs_hba *hba, | |||
| 2649 | 2615 | ||
| 2650 | /** | 2616 | /** |
| 2651 | * ufshcd_query_flag() - API function for sending flag query requests | 2617 | * ufshcd_query_flag() - API function for sending flag query requests |
| 2652 | * hba: per-adapter instance | 2618 | * @hba: per-adapter instance |
| 2653 | * query_opcode: flag query to perform | 2619 | * @opcode: flag query to perform |
| 2654 | * idn: flag idn to access | 2620 | * @idn: flag idn to access |
| 2655 | * flag_res: the flag value after the query request completes | 2621 | * @flag_res: the flag value after the query request completes |
| 2656 | * | 2622 | * |
| 2657 | * Returns 0 for success, non-zero in case of failure | 2623 | * Returns 0 for success, non-zero in case of failure |
| 2658 | */ | 2624 | */ |
| @@ -2716,17 +2682,17 @@ out_unlock: | |||
| 2716 | 2682 | ||
| 2717 | /** | 2683 | /** |
| 2718 | * ufshcd_query_attr - API function for sending attribute requests | 2684 | * ufshcd_query_attr - API function for sending attribute requests |
| 2719 | * hba: per-adapter instance | 2685 | * @hba: per-adapter instance |
| 2720 | * opcode: attribute opcode | 2686 | * @opcode: attribute opcode |
| 2721 | * idn: attribute idn to access | 2687 | * @idn: attribute idn to access |
| 2722 | * index: index field | 2688 | * @index: index field |
| 2723 | * selector: selector field | 2689 | * @selector: selector field |
| 2724 | * attr_val: the attribute value after the query request completes | 2690 | * @attr_val: the attribute value after the query request completes |
| 2725 | * | 2691 | * |
| 2726 | * Returns 0 for success, non-zero in case of failure | 2692 | * Returns 0 for success, non-zero in case of failure |
| 2727 | */ | 2693 | */ |
| 2728 | static int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode, | 2694 | int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode, |
| 2729 | enum attr_idn idn, u8 index, u8 selector, u32 *attr_val) | 2695 | enum attr_idn idn, u8 index, u8 selector, u32 *attr_val) |
| 2730 | { | 2696 | { |
| 2731 | struct ufs_query_req *request = NULL; | 2697 | struct ufs_query_req *request = NULL; |
| 2732 | struct ufs_query_res *response = NULL; | 2698 | struct ufs_query_res *response = NULL; |
| @@ -2880,25 +2846,24 @@ out: | |||
| 2880 | } | 2846 | } |
| 2881 | 2847 | ||
| 2882 | /** | 2848 | /** |
| 2883 | * ufshcd_query_descriptor_retry - API function for sending descriptor | 2849 | * ufshcd_query_descriptor_retry - API function for sending descriptor requests |
| 2884 | * requests | 2850 | * @hba: per-adapter instance |
| 2885 | * hba: per-adapter instance | 2851 | * @opcode: attribute opcode |
| 2886 | * opcode: attribute opcode | 2852 | * @idn: attribute idn to access |
| 2887 | * idn: attribute idn to access | 2853 | * @index: index field |
| 2888 | * index: index field | 2854 | * @selector: selector field |
| 2889 | * selector: selector field | 2855 | * @desc_buf: the buffer that contains the descriptor |
| 2890 | * desc_buf: the buffer that contains the descriptor | 2856 | * @buf_len: length parameter passed to the device |
| 2891 | * buf_len: length parameter passed to the device | ||
| 2892 | * | 2857 | * |
| 2893 | * Returns 0 for success, non-zero in case of failure. | 2858 | * Returns 0 for success, non-zero in case of failure. |
| 2894 | * The buf_len parameter will contain, on return, the length parameter | 2859 | * The buf_len parameter will contain, on return, the length parameter |
| 2895 | * received on the response. | 2860 | * received on the response. |
| 2896 | */ | 2861 | */ |
| 2897 | static int ufshcd_query_descriptor_retry(struct ufs_hba *hba, | 2862 | int ufshcd_query_descriptor_retry(struct ufs_hba *hba, |
| 2898 | enum query_opcode opcode, | 2863 | enum query_opcode opcode, |
| 2899 | enum desc_idn idn, u8 index, | 2864 | enum desc_idn idn, u8 index, |
| 2900 | u8 selector, | 2865 | u8 selector, |
| 2901 | u8 *desc_buf, int *buf_len) | 2866 | u8 *desc_buf, int *buf_len) |
| 2902 | { | 2867 | { |
| 2903 | int err; | 2868 | int err; |
| 2904 | int retries; | 2869 | int retries; |
| @@ -2987,6 +2952,9 @@ int ufshcd_map_desc_id_to_length(struct ufs_hba *hba, | |||
| 2987 | case QUERY_DESC_IDN_STRING: | 2952 | case QUERY_DESC_IDN_STRING: |
| 2988 | *desc_len = QUERY_DESC_MAX_SIZE; | 2953 | *desc_len = QUERY_DESC_MAX_SIZE; |
| 2989 | break; | 2954 | break; |
| 2955 | case QUERY_DESC_IDN_HEALTH: | ||
| 2956 | *desc_len = hba->desc_size.hlth_desc; | ||
| 2957 | break; | ||
| 2990 | case QUERY_DESC_IDN_RFU_0: | 2958 | case QUERY_DESC_IDN_RFU_0: |
| 2991 | case QUERY_DESC_IDN_RFU_1: | 2959 | case QUERY_DESC_IDN_RFU_1: |
| 2992 | *desc_len = 0; | 2960 | *desc_len = 0; |
| @@ -3010,12 +2978,12 @@ EXPORT_SYMBOL(ufshcd_map_desc_id_to_length); | |||
| 3010 | * | 2978 | * |
| 3011 | * Return 0 in case of success, non-zero otherwise | 2979 | * Return 0 in case of success, non-zero otherwise |
| 3012 | */ | 2980 | */ |
| 3013 | static int ufshcd_read_desc_param(struct ufs_hba *hba, | 2981 | int ufshcd_read_desc_param(struct ufs_hba *hba, |
| 3014 | enum desc_idn desc_id, | 2982 | enum desc_idn desc_id, |
| 3015 | int desc_index, | 2983 | int desc_index, |
| 3016 | u8 param_offset, | 2984 | u8 param_offset, |
| 3017 | u8 *param_read_buf, | 2985 | u8 *param_read_buf, |
| 3018 | u8 param_size) | 2986 | u8 param_size) |
| 3019 | { | 2987 | { |
| 3020 | int ret; | 2988 | int ret; |
| 3021 | u8 *desc_buf; | 2989 | u8 *desc_buf; |
| @@ -3110,9 +3078,8 @@ static int ufshcd_read_device_desc(struct ufs_hba *hba, u8 *buf, u32 size) | |||
| 3110 | * | 3078 | * |
| 3111 | * Return 0 in case of success, non-zero otherwise | 3079 | * Return 0 in case of success, non-zero otherwise |
| 3112 | */ | 3080 | */ |
| 3113 | #define ASCII_STD true | 3081 | int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index, |
| 3114 | static int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index, | 3082 | u8 *buf, u32 size, bool ascii) |
| 3115 | u8 *buf, u32 size, bool ascii) | ||
| 3116 | { | 3083 | { |
| 3117 | int err = 0; | 3084 | int err = 0; |
| 3118 | 3085 | ||
| @@ -3189,7 +3156,7 @@ static inline int ufshcd_read_unit_desc_param(struct ufs_hba *hba, | |||
| 3189 | * Unit descriptors are only available for general purpose LUs (LUN id | 3156 | * Unit descriptors are only available for general purpose LUs (LUN id |
| 3190 | * from 0 to 7) and RPMB Well known LU. | 3157 | * from 0 to 7) and RPMB Well known LU. |
| 3191 | */ | 3158 | */ |
| 3192 | if (lun != UFS_UPIU_RPMB_WLUN && (lun >= UFS_UPIU_MAX_GENERAL_LUN)) | 3159 | if (!ufs_is_valid_unit_desc_lun(lun)) |
| 3193 | return -EOPNOTSUPP; | 3160 | return -EOPNOTSUPP; |
| 3194 | 3161 | ||
| 3195 | return ufshcd_read_desc_param(hba, QUERY_DESC_IDN_UNIT, lun, | 3162 | return ufshcd_read_desc_param(hba, QUERY_DESC_IDN_UNIT, lun, |
| @@ -3742,6 +3709,18 @@ static int ufshcd_uic_hibern8_exit(struct ufs_hba *hba) | |||
| 3742 | return ret; | 3709 | return ret; |
| 3743 | } | 3710 | } |
| 3744 | 3711 | ||
| 3712 | static void ufshcd_auto_hibern8_enable(struct ufs_hba *hba) | ||
| 3713 | { | ||
| 3714 | unsigned long flags; | ||
| 3715 | |||
| 3716 | if (!(hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT) || !hba->ahit) | ||
| 3717 | return; | ||
| 3718 | |||
| 3719 | spin_lock_irqsave(hba->host->host_lock, flags); | ||
| 3720 | ufshcd_writel(hba, hba->ahit, REG_AUTO_HIBERNATE_IDLE_TIMER); | ||
| 3721 | spin_unlock_irqrestore(hba->host->host_lock, flags); | ||
| 3722 | } | ||
| 3723 | |||
| 3745 | /** | 3724 | /** |
| 3746 | * ufshcd_init_pwr_info - setting the POR (power on reset) | 3725 | * ufshcd_init_pwr_info - setting the POR (power on reset) |
| 3747 | * values in hba power info | 3726 | * values in hba power info |
| @@ -3912,7 +3891,7 @@ static int ufshcd_config_pwr_mode(struct ufs_hba *hba, | |||
| 3912 | 3891 | ||
| 3913 | /** | 3892 | /** |
| 3914 | * ufshcd_complete_dev_init() - checks device readiness | 3893 | * ufshcd_complete_dev_init() - checks device readiness |
| 3915 | * hba: per-adapter instance | 3894 | * @hba: per-adapter instance |
| 3916 | * | 3895 | * |
| 3917 | * Set fDeviceInit flag and poll until device toggles it. | 3896 | * Set fDeviceInit flag and poll until device toggles it. |
| 3918 | */ | 3897 | */ |
| @@ -4453,7 +4432,7 @@ static int ufshcd_task_req_compl(struct ufs_hba *hba, u32 index, u8 *resp) | |||
| 4453 | 4432 | ||
| 4454 | /** | 4433 | /** |
| 4455 | * ufshcd_scsi_cmd_status - Update SCSI command result based on SCSI status | 4434 | * ufshcd_scsi_cmd_status - Update SCSI command result based on SCSI status |
| 4456 | * @lrb: pointer to local reference block of completed command | 4435 | * @lrbp: pointer to local reference block of completed command |
| 4457 | * @scsi_status: SCSI command status | 4436 | * @scsi_status: SCSI command status |
| 4458 | * | 4437 | * |
| 4459 | * Returns value base on SCSI command status | 4438 | * Returns value base on SCSI command status |
| @@ -4488,7 +4467,7 @@ ufshcd_scsi_cmd_status(struct ufshcd_lrb *lrbp, int scsi_status) | |||
| 4488 | /** | 4467 | /** |
| 4489 | * ufshcd_transfer_rsp_status - Get overall status of the response | 4468 | * ufshcd_transfer_rsp_status - Get overall status of the response |
| 4490 | * @hba: per adapter instance | 4469 | * @hba: per adapter instance |
| 4491 | * @lrb: pointer to local reference block of completed command | 4470 | * @lrbp: pointer to local reference block of completed command |
| 4492 | * | 4471 | * |
| 4493 | * Returns result of the command to notify SCSI midlayer | 4472 | * Returns result of the command to notify SCSI midlayer |
| 4494 | */ | 4473 | */ |
| @@ -5796,7 +5775,7 @@ static int ufshcd_reset_and_restore(struct ufs_hba *hba) | |||
| 5796 | 5775 | ||
| 5797 | /** | 5776 | /** |
| 5798 | * ufshcd_eh_host_reset_handler - host reset handler registered to scsi layer | 5777 | * ufshcd_eh_host_reset_handler - host reset handler registered to scsi layer |
| 5799 | * @cmd - SCSI command pointer | 5778 | * @cmd: SCSI command pointer |
| 5800 | * | 5779 | * |
| 5801 | * Returns SUCCESS/FAILED | 5780 | * Returns SUCCESS/FAILED |
| 5802 | */ | 5781 | */ |
| @@ -5981,11 +5960,11 @@ static void ufshcd_init_icc_levels(struct ufs_hba *hba) | |||
| 5981 | * will take effect only when its sent to "UFS device" well known logical unit | 5960 | * will take effect only when its sent to "UFS device" well known logical unit |
| 5982 | * hence we require the scsi_device instance to represent this logical unit in | 5961 | * hence we require the scsi_device instance to represent this logical unit in |
| 5983 | * order for the UFS host driver to send the SSU command for power management. | 5962 | * order for the UFS host driver to send the SSU command for power management. |
| 5984 | 5963 | * | |
| 5985 | * We also require the scsi_device instance for "RPMB" (Replay Protected Memory | 5964 | * We also require the scsi_device instance for "RPMB" (Replay Protected Memory |
| 5986 | * Block) LU so user space process can control this LU. User space may also | 5965 | * Block) LU so user space process can control this LU. User space may also |
| 5987 | * want to have access to BOOT LU. | 5966 | * want to have access to BOOT LU. |
| 5988 | 5967 | * | |
| 5989 | * This function adds scsi device instances for each of all well known LUs | 5968 | * This function adds scsi device instances for each of all well known LUs |
| 5990 | * (except "REPORT LUNS" LU). | 5969 | * (except "REPORT LUNS" LU). |
| 5991 | * | 5970 | * |
| @@ -6054,7 +6033,7 @@ static int ufs_get_device_desc(struct ufs_hba *hba, | |||
| 6054 | model_index = desc_buf[DEVICE_DESC_PARAM_PRDCT_NAME]; | 6033 | model_index = desc_buf[DEVICE_DESC_PARAM_PRDCT_NAME]; |
| 6055 | 6034 | ||
| 6056 | err = ufshcd_read_string_desc(hba, model_index, str_desc_buf, | 6035 | err = ufshcd_read_string_desc(hba, model_index, str_desc_buf, |
| 6057 | QUERY_DESC_MAX_SIZE, ASCII_STD); | 6036 | QUERY_DESC_MAX_SIZE, true/*ASCII*/); |
| 6058 | if (err) { | 6037 | if (err) { |
| 6059 | dev_err(hba->dev, "%s: Failed reading Product Name. err = %d\n", | 6038 | dev_err(hba->dev, "%s: Failed reading Product Name. err = %d\n", |
| 6060 | __func__, err); | 6039 | __func__, err); |
| @@ -6300,6 +6279,10 @@ static void ufshcd_init_desc_sizes(struct ufs_hba *hba) | |||
| 6300 | &hba->desc_size.geom_desc); | 6279 | &hba->desc_size.geom_desc); |
| 6301 | if (err) | 6280 | if (err) |
| 6302 | hba->desc_size.geom_desc = QUERY_DESC_GEOMETRY_DEF_SIZE; | 6281 | hba->desc_size.geom_desc = QUERY_DESC_GEOMETRY_DEF_SIZE; |
| 6282 | err = ufshcd_read_desc_length(hba, QUERY_DESC_IDN_HEALTH, 0, | ||
| 6283 | &hba->desc_size.hlth_desc); | ||
| 6284 | if (err) | ||
| 6285 | hba->desc_size.hlth_desc = QUERY_DESC_HEALTH_DEF_SIZE; | ||
| 6303 | } | 6286 | } |
| 6304 | 6287 | ||
| 6305 | static void ufshcd_def_desc_sizes(struct ufs_hba *hba) | 6288 | static void ufshcd_def_desc_sizes(struct ufs_hba *hba) |
| @@ -6310,6 +6293,7 @@ static void ufshcd_def_desc_sizes(struct ufs_hba *hba) | |||
| 6310 | hba->desc_size.conf_desc = QUERY_DESC_CONFIGURATION_DEF_SIZE; | 6293 | hba->desc_size.conf_desc = QUERY_DESC_CONFIGURATION_DEF_SIZE; |
| 6311 | hba->desc_size.unit_desc = QUERY_DESC_UNIT_DEF_SIZE; | 6294 | hba->desc_size.unit_desc = QUERY_DESC_UNIT_DEF_SIZE; |
| 6312 | hba->desc_size.geom_desc = QUERY_DESC_GEOMETRY_DEF_SIZE; | 6295 | hba->desc_size.geom_desc = QUERY_DESC_GEOMETRY_DEF_SIZE; |
| 6296 | hba->desc_size.hlth_desc = QUERY_DESC_HEALTH_DEF_SIZE; | ||
| 6313 | } | 6297 | } |
| 6314 | 6298 | ||
| 6315 | /** | 6299 | /** |
| @@ -6338,6 +6322,9 @@ static int ufshcd_probe_hba(struct ufs_hba *hba) | |||
| 6338 | /* UniPro link is active now */ | 6322 | /* UniPro link is active now */ |
| 6339 | ufshcd_set_link_active(hba); | 6323 | ufshcd_set_link_active(hba); |
| 6340 | 6324 | ||
| 6325 | /* Enable Auto-Hibernate if configured */ | ||
| 6326 | ufshcd_auto_hibern8_enable(hba); | ||
| 6327 | |||
| 6341 | ret = ufshcd_verify_dev_init(hba); | 6328 | ret = ufshcd_verify_dev_init(hba); |
| 6342 | if (ret) | 6329 | if (ret) |
| 6343 | goto out; | 6330 | goto out; |
| @@ -6496,6 +6483,12 @@ static enum blk_eh_timer_return ufshcd_eh_timed_out(struct scsi_cmnd *scmd) | |||
| 6496 | return found ? BLK_EH_NOT_HANDLED : BLK_EH_RESET_TIMER; | 6483 | return found ? BLK_EH_NOT_HANDLED : BLK_EH_RESET_TIMER; |
| 6497 | } | 6484 | } |
| 6498 | 6485 | ||
| 6486 | static const struct attribute_group *ufshcd_driver_groups[] = { | ||
| 6487 | &ufs_sysfs_unit_descriptor_group, | ||
| 6488 | &ufs_sysfs_lun_attributes_group, | ||
| 6489 | NULL, | ||
| 6490 | }; | ||
| 6491 | |||
| 6499 | static struct scsi_host_template ufshcd_driver_template = { | 6492 | static struct scsi_host_template ufshcd_driver_template = { |
| 6500 | .module = THIS_MODULE, | 6493 | .module = THIS_MODULE, |
| 6501 | .name = UFSHCD, | 6494 | .name = UFSHCD, |
| @@ -6515,6 +6508,7 @@ static struct scsi_host_template ufshcd_driver_template = { | |||
| 6515 | .can_queue = UFSHCD_CAN_QUEUE, | 6508 | .can_queue = UFSHCD_CAN_QUEUE, |
| 6516 | .max_host_blocked = 1, | 6509 | .max_host_blocked = 1, |
| 6517 | .track_queue_depth = 1, | 6510 | .track_queue_depth = 1, |
| 6511 | .sdev_groups = ufshcd_driver_groups, | ||
| 6518 | }; | 6512 | }; |
| 6519 | 6513 | ||
| 6520 | static int ufshcd_config_vreg_load(struct device *dev, struct ufs_vreg *vreg, | 6514 | static int ufshcd_config_vreg_load(struct device *dev, struct ufs_vreg *vreg, |
| @@ -7415,6 +7409,10 @@ static int ufshcd_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op) | |||
| 7415 | 7409 | ||
| 7416 | /* Schedule clock gating in case of no access to UFS device yet */ | 7410 | /* Schedule clock gating in case of no access to UFS device yet */ |
| 7417 | ufshcd_release(hba); | 7411 | ufshcd_release(hba); |
| 7412 | |||
| 7413 | /* Enable Auto-Hibernate if configured */ | ||
| 7414 | ufshcd_auto_hibern8_enable(hba); | ||
| 7415 | |||
| 7418 | goto out; | 7416 | goto out; |
| 7419 | 7417 | ||
| 7420 | set_old_link_state: | 7418 | set_old_link_state: |
| @@ -7436,7 +7434,6 @@ out: | |||
| 7436 | /** | 7434 | /** |
| 7437 | * ufshcd_system_suspend - system suspend routine | 7435 | * ufshcd_system_suspend - system suspend routine |
| 7438 | * @hba: per adapter instance | 7436 | * @hba: per adapter instance |
| 7439 | * @pm_op: runtime PM or system PM | ||
| 7440 | * | 7437 | * |
| 7441 | * Check the description of ufshcd_suspend() function for more details. | 7438 | * Check the description of ufshcd_suspend() function for more details. |
| 7442 | * | 7439 | * |
| @@ -7587,133 +7584,6 @@ int ufshcd_runtime_idle(struct ufs_hba *hba) | |||
| 7587 | } | 7584 | } |
| 7588 | EXPORT_SYMBOL(ufshcd_runtime_idle); | 7585 | EXPORT_SYMBOL(ufshcd_runtime_idle); |
| 7589 | 7586 | ||
| 7590 | static inline ssize_t ufshcd_pm_lvl_store(struct device *dev, | ||
| 7591 | struct device_attribute *attr, | ||
| 7592 | const char *buf, size_t count, | ||
| 7593 | bool rpm) | ||
| 7594 | { | ||
| 7595 | struct ufs_hba *hba = dev_get_drvdata(dev); | ||
| 7596 | unsigned long flags, value; | ||
| 7597 | |||
| 7598 | if (kstrtoul(buf, 0, &value)) | ||
| 7599 | return -EINVAL; | ||
| 7600 | |||
| 7601 | if (value >= UFS_PM_LVL_MAX) | ||
| 7602 | return -EINVAL; | ||
| 7603 | |||
| 7604 | spin_lock_irqsave(hba->host->host_lock, flags); | ||
| 7605 | if (rpm) | ||
| 7606 | hba->rpm_lvl = value; | ||
| 7607 | else | ||
| 7608 | hba->spm_lvl = value; | ||
| 7609 | spin_unlock_irqrestore(hba->host->host_lock, flags); | ||
| 7610 | return count; | ||
| 7611 | } | ||
| 7612 | |||
| 7613 | static ssize_t ufshcd_rpm_lvl_show(struct device *dev, | ||
| 7614 | struct device_attribute *attr, char *buf) | ||
| 7615 | { | ||
| 7616 | struct ufs_hba *hba = dev_get_drvdata(dev); | ||
| 7617 | int curr_len; | ||
| 7618 | u8 lvl; | ||
| 7619 | |||
| 7620 | curr_len = snprintf(buf, PAGE_SIZE, | ||
| 7621 | "\nCurrent Runtime PM level [%d] => dev_state [%s] link_state [%s]\n", | ||
| 7622 | hba->rpm_lvl, | ||
| 7623 | ufschd_ufs_dev_pwr_mode_to_string( | ||
| 7624 | ufs_pm_lvl_states[hba->rpm_lvl].dev_state), | ||
| 7625 | ufschd_uic_link_state_to_string( | ||
| 7626 | ufs_pm_lvl_states[hba->rpm_lvl].link_state)); | ||
| 7627 | |||
| 7628 | curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len), | ||
| 7629 | "\nAll available Runtime PM levels info:\n"); | ||
| 7630 | for (lvl = UFS_PM_LVL_0; lvl < UFS_PM_LVL_MAX; lvl++) | ||
| 7631 | curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len), | ||
| 7632 | "\tRuntime PM level [%d] => dev_state [%s] link_state [%s]\n", | ||
| 7633 | lvl, | ||
| 7634 | ufschd_ufs_dev_pwr_mode_to_string( | ||
| 7635 | ufs_pm_lvl_states[lvl].dev_state), | ||
| 7636 | ufschd_uic_link_state_to_string( | ||
| 7637 | ufs_pm_lvl_states[lvl].link_state)); | ||
| 7638 | |||
| 7639 | return curr_len; | ||
| 7640 | } | ||
| 7641 | |||
| 7642 | static ssize_t ufshcd_rpm_lvl_store(struct device *dev, | ||
| 7643 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 7644 | { | ||
| 7645 | return ufshcd_pm_lvl_store(dev, attr, buf, count, true); | ||
| 7646 | } | ||
| 7647 | |||
| 7648 | static void ufshcd_add_rpm_lvl_sysfs_nodes(struct ufs_hba *hba) | ||
| 7649 | { | ||
| 7650 | hba->rpm_lvl_attr.show = ufshcd_rpm_lvl_show; | ||
| 7651 | hba->rpm_lvl_attr.store = ufshcd_rpm_lvl_store; | ||
| 7652 | sysfs_attr_init(&hba->rpm_lvl_attr.attr); | ||
| 7653 | hba->rpm_lvl_attr.attr.name = "rpm_lvl"; | ||
| 7654 | hba->rpm_lvl_attr.attr.mode = 0644; | ||
| 7655 | if (device_create_file(hba->dev, &hba->rpm_lvl_attr)) | ||
| 7656 | dev_err(hba->dev, "Failed to create sysfs for rpm_lvl\n"); | ||
| 7657 | } | ||
| 7658 | |||
| 7659 | static ssize_t ufshcd_spm_lvl_show(struct device *dev, | ||
| 7660 | struct device_attribute *attr, char *buf) | ||
| 7661 | { | ||
| 7662 | struct ufs_hba *hba = dev_get_drvdata(dev); | ||
| 7663 | int curr_len; | ||
| 7664 | u8 lvl; | ||
| 7665 | |||
| 7666 | curr_len = snprintf(buf, PAGE_SIZE, | ||
| 7667 | "\nCurrent System PM level [%d] => dev_state [%s] link_state [%s]\n", | ||
| 7668 | hba->spm_lvl, | ||
| 7669 | ufschd_ufs_dev_pwr_mode_to_string( | ||
| 7670 | ufs_pm_lvl_states[hba->spm_lvl].dev_state), | ||
| 7671 | ufschd_uic_link_state_to_string( | ||
| 7672 | ufs_pm_lvl_states[hba->spm_lvl].link_state)); | ||
| 7673 | |||
| 7674 | curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len), | ||
| 7675 | "\nAll available System PM levels info:\n"); | ||
| 7676 | for (lvl = UFS_PM_LVL_0; lvl < UFS_PM_LVL_MAX; lvl++) | ||
| 7677 | curr_len += snprintf((buf + curr_len), (PAGE_SIZE - curr_len), | ||
| 7678 | "\tSystem PM level [%d] => dev_state [%s] link_state [%s]\n", | ||
| 7679 | lvl, | ||
| 7680 | ufschd_ufs_dev_pwr_mode_to_string( | ||
| 7681 | ufs_pm_lvl_states[lvl].dev_state), | ||
| 7682 | ufschd_uic_link_state_to_string( | ||
| 7683 | ufs_pm_lvl_states[lvl].link_state)); | ||
| 7684 | |||
| 7685 | return curr_len; | ||
| 7686 | } | ||
| 7687 | |||
| 7688 | static ssize_t ufshcd_spm_lvl_store(struct device *dev, | ||
| 7689 | struct device_attribute *attr, const char *buf, size_t count) | ||
| 7690 | { | ||
| 7691 | return ufshcd_pm_lvl_store(dev, attr, buf, count, false); | ||
| 7692 | } | ||
| 7693 | |||
| 7694 | static void ufshcd_add_spm_lvl_sysfs_nodes(struct ufs_hba *hba) | ||
| 7695 | { | ||
| 7696 | hba->spm_lvl_attr.show = ufshcd_spm_lvl_show; | ||
| 7697 | hba->spm_lvl_attr.store = ufshcd_spm_lvl_store; | ||
| 7698 | sysfs_attr_init(&hba->spm_lvl_attr.attr); | ||
| 7699 | hba->spm_lvl_attr.attr.name = "spm_lvl"; | ||
| 7700 | hba->spm_lvl_attr.attr.mode = 0644; | ||
| 7701 | if (device_create_file(hba->dev, &hba->spm_lvl_attr)) | ||
| 7702 | dev_err(hba->dev, "Failed to create sysfs for spm_lvl\n"); | ||
| 7703 | } | ||
| 7704 | |||
| 7705 | static inline void ufshcd_add_sysfs_nodes(struct ufs_hba *hba) | ||
| 7706 | { | ||
| 7707 | ufshcd_add_rpm_lvl_sysfs_nodes(hba); | ||
| 7708 | ufshcd_add_spm_lvl_sysfs_nodes(hba); | ||
| 7709 | } | ||
| 7710 | |||
| 7711 | static inline void ufshcd_remove_sysfs_nodes(struct ufs_hba *hba) | ||
| 7712 | { | ||
| 7713 | device_remove_file(hba->dev, &hba->rpm_lvl_attr); | ||
| 7714 | device_remove_file(hba->dev, &hba->spm_lvl_attr); | ||
| 7715 | } | ||
| 7716 | |||
| 7717 | /** | 7587 | /** |
| 7718 | * ufshcd_shutdown - shutdown routine | 7588 | * ufshcd_shutdown - shutdown routine |
| 7719 | * @hba: per adapter instance | 7589 | * @hba: per adapter instance |
| @@ -7747,11 +7617,11 @@ EXPORT_SYMBOL(ufshcd_shutdown); | |||
| 7747 | /** | 7617 | /** |
| 7748 | * ufshcd_remove - de-allocate SCSI host and host memory space | 7618 | * ufshcd_remove - de-allocate SCSI host and host memory space |
| 7749 | * data structure memory | 7619 | * data structure memory |
| 7750 | * @hba - per adapter instance | 7620 | * @hba: per adapter instance |
| 7751 | */ | 7621 | */ |
| 7752 | void ufshcd_remove(struct ufs_hba *hba) | 7622 | void ufshcd_remove(struct ufs_hba *hba) |
| 7753 | { | 7623 | { |
| 7754 | ufshcd_remove_sysfs_nodes(hba); | 7624 | ufs_sysfs_remove_nodes(hba->dev); |
| 7755 | scsi_remove_host(hba->host); | 7625 | scsi_remove_host(hba->host); |
| 7756 | /* disable interrupts */ | 7626 | /* disable interrupts */ |
| 7757 | ufshcd_disable_intr(hba, hba->intr_mask); | 7627 | ufshcd_disable_intr(hba, hba->intr_mask); |
| @@ -7986,6 +7856,12 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) | |||
| 7986 | UFS_SLEEP_PWR_MODE, | 7856 | UFS_SLEEP_PWR_MODE, |
| 7987 | UIC_LINK_HIBERN8_STATE); | 7857 | UIC_LINK_HIBERN8_STATE); |
| 7988 | 7858 | ||
| 7859 | /* Set the default auto-hiberate idle timer value to 150 ms */ | ||
| 7860 | if (hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT) { | ||
| 7861 | hba->ahit = FIELD_PREP(UFSHCI_AHIBERN8_TIMER_MASK, 150) | | ||
| 7862 | FIELD_PREP(UFSHCI_AHIBERN8_SCALE_MASK, 3); | ||
| 7863 | } | ||
| 7864 | |||
| 7989 | /* Hold auto suspend until async scan completes */ | 7865 | /* Hold auto suspend until async scan completes */ |
| 7990 | pm_runtime_get_sync(dev); | 7866 | pm_runtime_get_sync(dev); |
| 7991 | 7867 | ||
| @@ -7998,7 +7874,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) | |||
| 7998 | ufshcd_set_ufs_dev_active(hba); | 7874 | ufshcd_set_ufs_dev_active(hba); |
| 7999 | 7875 | ||
| 8000 | async_schedule(ufshcd_async_scan, hba); | 7876 | async_schedule(ufshcd_async_scan, hba); |
| 8001 | ufshcd_add_sysfs_nodes(hba); | 7877 | ufs_sysfs_add_nodes(hba->dev); |
| 8002 | 7878 | ||
| 8003 | return 0; | 7879 | return 0; |
| 8004 | 7880 | ||
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h index 1332e544da92..8110dcd04d22 100644 --- a/drivers/scsi/ufs/ufshcd.h +++ b/drivers/scsi/ufs/ufshcd.h | |||
| @@ -229,6 +229,7 @@ struct ufs_desc_size { | |||
| 229 | int interc_desc; | 229 | int interc_desc; |
| 230 | int unit_desc; | 230 | int unit_desc; |
| 231 | int conf_desc; | 231 | int conf_desc; |
| 232 | int hlth_desc; | ||
| 232 | }; | 233 | }; |
| 233 | 234 | ||
| 234 | /** | 235 | /** |
| @@ -530,6 +531,9 @@ struct ufs_hba { | |||
| 530 | struct device_attribute spm_lvl_attr; | 531 | struct device_attribute spm_lvl_attr; |
| 531 | int pm_op_in_progress; | 532 | int pm_op_in_progress; |
| 532 | 533 | ||
| 534 | /* Auto-Hibernate Idle Timer register value */ | ||
| 535 | u32 ahit; | ||
| 536 | |||
| 533 | struct ufshcd_lrb *lrb; | 537 | struct ufshcd_lrb *lrb; |
| 534 | unsigned long lrb_in_use; | 538 | unsigned long lrb_in_use; |
| 535 | 539 | ||
| @@ -841,8 +845,24 @@ static inline bool ufshcd_is_hs_mode(struct ufs_pa_layer_attr *pwr_info) | |||
| 841 | } | 845 | } |
| 842 | 846 | ||
| 843 | /* Expose Query-Request API */ | 847 | /* Expose Query-Request API */ |
| 848 | int ufshcd_query_descriptor_retry(struct ufs_hba *hba, | ||
| 849 | enum query_opcode opcode, | ||
| 850 | enum desc_idn idn, u8 index, | ||
| 851 | u8 selector, | ||
| 852 | u8 *desc_buf, int *buf_len); | ||
| 853 | int ufshcd_read_desc_param(struct ufs_hba *hba, | ||
| 854 | enum desc_idn desc_id, | ||
| 855 | int desc_index, | ||
| 856 | u8 param_offset, | ||
| 857 | u8 *param_read_buf, | ||
| 858 | u8 param_size); | ||
| 859 | int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode, | ||
| 860 | enum attr_idn idn, u8 index, u8 selector, u32 *attr_val); | ||
| 844 | int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode, | 861 | int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode, |
| 845 | enum flag_idn idn, bool *flag_res); | 862 | enum flag_idn idn, bool *flag_res); |
| 863 | int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index, | ||
| 864 | u8 *buf, u32 size, bool ascii); | ||
| 865 | |||
| 846 | int ufshcd_hold(struct ufs_hba *hba, bool async); | 866 | int ufshcd_hold(struct ufs_hba *hba, bool async); |
| 847 | void ufshcd_release(struct ufs_hba *hba); | 867 | void ufshcd_release(struct ufs_hba *hba); |
| 848 | 868 | ||
| @@ -985,4 +1005,21 @@ static inline void ufshcd_vops_dbg_register_dump(struct ufs_hba *hba) | |||
| 985 | hba->vops->dbg_register_dump(hba); | 1005 | hba->vops->dbg_register_dump(hba); |
| 986 | } | 1006 | } |
| 987 | 1007 | ||
| 1008 | extern struct ufs_pm_lvl_states ufs_pm_lvl_states[]; | ||
| 1009 | |||
| 1010 | /* | ||
| 1011 | * ufshcd_scsi_to_upiu_lun - maps scsi LUN to UPIU LUN | ||
| 1012 | * @scsi_lun: scsi LUN id | ||
| 1013 | * | ||
| 1014 | * Returns UPIU LUN id | ||
| 1015 | */ | ||
| 1016 | static inline u8 ufshcd_scsi_to_upiu_lun(unsigned int scsi_lun) | ||
| 1017 | { | ||
| 1018 | if (scsi_is_wlun(scsi_lun)) | ||
| 1019 | return (scsi_lun & UFS_UPIU_MAX_UNIT_NUM_ID) | ||
| 1020 | | UFS_UPIU_WLUN_ID; | ||
| 1021 | else | ||
| 1022 | return scsi_lun & UFS_UPIU_MAX_UNIT_NUM_ID; | ||
| 1023 | } | ||
| 1024 | |||
| 988 | #endif /* End of Header */ | 1025 | #endif /* End of Header */ |
diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h index 1a1b5d9fe514..bb5d9c7f3353 100644 --- a/drivers/scsi/ufs/ufshci.h +++ b/drivers/scsi/ufs/ufshci.h | |||
| @@ -86,6 +86,7 @@ enum { | |||
| 86 | enum { | 86 | enum { |
| 87 | MASK_TRANSFER_REQUESTS_SLOTS = 0x0000001F, | 87 | MASK_TRANSFER_REQUESTS_SLOTS = 0x0000001F, |
| 88 | MASK_TASK_MANAGEMENT_REQUEST_SLOTS = 0x00070000, | 88 | MASK_TASK_MANAGEMENT_REQUEST_SLOTS = 0x00070000, |
| 89 | MASK_AUTO_HIBERN8_SUPPORT = 0x00800000, | ||
| 89 | MASK_64_ADDRESSING_SUPPORT = 0x01000000, | 90 | MASK_64_ADDRESSING_SUPPORT = 0x01000000, |
| 90 | MASK_OUT_OF_ORDER_DATA_DELIVERY_SUPPORT = 0x02000000, | 91 | MASK_OUT_OF_ORDER_DATA_DELIVERY_SUPPORT = 0x02000000, |
| 91 | MASK_UIC_DME_TEST_MODE_SUPPORT = 0x04000000, | 92 | MASK_UIC_DME_TEST_MODE_SUPPORT = 0x04000000, |
| @@ -119,6 +120,12 @@ enum { | |||
| 119 | #define MANUFACTURE_ID_MASK UFS_MASK(0xFFFF, 0) | 120 | #define MANUFACTURE_ID_MASK UFS_MASK(0xFFFF, 0) |
| 120 | #define PRODUCT_ID_MASK UFS_MASK(0xFFFF, 16) | 121 | #define PRODUCT_ID_MASK UFS_MASK(0xFFFF, 16) |
| 121 | 122 | ||
| 123 | /* AHIT - Auto-Hibernate Idle Timer */ | ||
| 124 | #define UFSHCI_AHIBERN8_TIMER_MASK GENMASK(9, 0) | ||
| 125 | #define UFSHCI_AHIBERN8_SCALE_MASK GENMASK(12, 10) | ||
| 126 | #define UFSHCI_AHIBERN8_SCALE_FACTOR 10 | ||
| 127 | #define UFSHCI_AHIBERN8_MAX (1023 * 100000) | ||
| 128 | |||
| 122 | /* | 129 | /* |
| 123 | * IS - Interrupt Status - 20h | 130 | * IS - Interrupt Status - 20h |
| 124 | */ | 131 | */ |
diff --git a/include/linux/raid_class.h b/include/linux/raid_class.h index 31e1ff69efc8..ec8655514283 100644 --- a/include/linux/raid_class.h +++ b/include/linux/raid_class.h | |||
| @@ -38,6 +38,7 @@ enum raid_level { | |||
| 38 | RAID_LEVEL_5, | 38 | RAID_LEVEL_5, |
| 39 | RAID_LEVEL_50, | 39 | RAID_LEVEL_50, |
| 40 | RAID_LEVEL_6, | 40 | RAID_LEVEL_6, |
| 41 | RAID_LEVEL_JBOD, | ||
| 41 | }; | 42 | }; |
| 42 | 43 | ||
| 43 | struct raid_data { | 44 | struct raid_data { |
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index cb85eddb47ea..eb7853c1a23b 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h | |||
| @@ -47,6 +47,8 @@ static inline int scsi_status_is_good(int status) | |||
| 47 | */ | 47 | */ |
| 48 | status &= 0xfe; | 48 | status &= 0xfe; |
| 49 | return ((status == SAM_STAT_GOOD) || | 49 | return ((status == SAM_STAT_GOOD) || |
| 50 | (status == SAM_STAT_CONDITION_MET) || | ||
| 51 | /* Next two "intermediate" statuses are obsolete in SAM-4 */ | ||
| 50 | (status == SAM_STAT_INTERMEDIATE) || | 52 | (status == SAM_STAT_INTERMEDIATE) || |
| 51 | (status == SAM_STAT_INTERMEDIATE_CONDITION_MET) || | 53 | (status == SAM_STAT_INTERMEDIATE_CONDITION_MET) || |
| 52 | /* FIXME: this is obsolete in SAM-3 */ | 54 | /* FIXME: this is obsolete in SAM-3 */ |
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 9c1e4bad6581..12f454cb6f61 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h | |||
| @@ -52,21 +52,6 @@ struct scsi_host_template { | |||
| 52 | const char *name; | 52 | const char *name; |
| 53 | 53 | ||
| 54 | /* | 54 | /* |
| 55 | * Used to initialize old-style drivers. For new-style drivers | ||
| 56 | * just perform all work in your module initialization function. | ||
| 57 | * | ||
| 58 | * Status: OBSOLETE | ||
| 59 | */ | ||
| 60 | int (* detect)(struct scsi_host_template *); | ||
| 61 | |||
| 62 | /* | ||
| 63 | * Used as unload callback for hosts with old-style drivers. | ||
| 64 | * | ||
| 65 | * Status: OBSOLETE | ||
| 66 | */ | ||
| 67 | int (* release)(struct Scsi_Host *); | ||
| 68 | |||
| 69 | /* | ||
| 70 | * The info function will return whatever useful information the | 55 | * The info function will return whatever useful information the |
| 71 | * developer sees fit. If not provided, then the name field will | 56 | * developer sees fit. If not provided, then the name field will |
| 72 | * be used instead. | 57 | * be used instead. |
| @@ -480,13 +465,10 @@ struct scsi_host_template { | |||
| 480 | struct device_attribute **sdev_attrs; | 465 | struct device_attribute **sdev_attrs; |
| 481 | 466 | ||
| 482 | /* | 467 | /* |
| 483 | * List of hosts per template. | 468 | * Pointer to the SCSI device attribute groups for this host, |
| 484 | * | 469 | * NULL terminated. |
| 485 | * This is only for use by scsi_module.c for legacy templates. | ||
| 486 | * For these access to it is synchronized implicitly by | ||
| 487 | * module_init/module_exit. | ||
| 488 | */ | 470 | */ |
| 489 | struct list_head legacy_hosts; | 471 | const struct attribute_group **sdev_groups; |
| 490 | 472 | ||
| 491 | /* | 473 | /* |
| 492 | * Vendor Identifier associated with the host | 474 | * Vendor Identifier associated with the host |
| @@ -709,15 +691,6 @@ struct Scsi_Host { | |||
| 709 | struct device shost_gendev, shost_dev; | 691 | struct device shost_gendev, shost_dev; |
| 710 | 692 | ||
| 711 | /* | 693 | /* |
| 712 | * List of hosts per template. | ||
| 713 | * | ||
| 714 | * This is only for use by scsi_module.c for legacy templates. | ||
| 715 | * For these access to it is synchronized implicitly by | ||
| 716 | * module_init/module_exit. | ||
| 717 | */ | ||
| 718 | struct list_head sht_legacy_list; | ||
| 719 | |||
| 720 | /* | ||
| 721 | * Points to the transport data (if any) which is allocated | 694 | * Points to the transport data (if any) which is allocated |
| 722 | * separately | 695 | * separately |
| 723 | */ | 696 | */ |
| @@ -917,9 +890,6 @@ static inline unsigned char scsi_host_get_guard(struct Scsi_Host *shost) | |||
| 917 | return shost->prot_guard_type; | 890 | return shost->prot_guard_type; |
| 918 | } | 891 | } |
| 919 | 892 | ||
| 920 | /* legacy interfaces */ | ||
| 921 | extern struct Scsi_Host *scsi_register(struct scsi_host_template *, int); | ||
| 922 | extern void scsi_unregister(struct Scsi_Host *); | ||
| 923 | extern int scsi_host_set_state(struct Scsi_Host *, enum scsi_host_state); | 893 | extern int scsi_host_set_state(struct Scsi_Host *, enum scsi_host_state); |
| 924 | 894 | ||
| 925 | #endif /* _SCSI_SCSI_HOST_H */ | 895 | #endif /* _SCSI_SCSI_HOST_H */ |
