diff options
Diffstat (limited to 'drivers/scsi/qla2xxx')
31 files changed, 1891 insertions, 443 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 07befcf365b8..16fe5196e6d9 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -664,7 +664,7 @@ do_read: | |||
664 | } | 664 | } |
665 | 665 | ||
666 | rval = qla2x00_read_sfp(vha, ha->sfp_data_dma, ha->sfp_data, | 666 | rval = qla2x00_read_sfp(vha, ha->sfp_data_dma, ha->sfp_data, |
667 | addr, offset, SFP_BLOCK_SIZE, 0); | 667 | addr, offset, SFP_BLOCK_SIZE, BIT_1); |
668 | if (rval != QLA_SUCCESS) { | 668 | if (rval != QLA_SUCCESS) { |
669 | ql_log(ql_log_warn, vha, 0x706d, | 669 | ql_log(ql_log_warn, vha, 0x706d, |
670 | "Unable to read SFP data (%x/%x/%x).\n", rval, | 670 | "Unable to read SFP data (%x/%x/%x).\n", rval, |
@@ -1495,7 +1495,7 @@ qla2x00_fw_dump_size_show(struct device *dev, struct device_attribute *attr, | |||
1495 | 1495 | ||
1496 | if (!ha->fw_dumped) | 1496 | if (!ha->fw_dumped) |
1497 | size = 0; | 1497 | size = 0; |
1498 | else if (IS_QLA82XX(ha)) | 1498 | else if (IS_P3P_TYPE(ha)) |
1499 | size = ha->md_template_size + ha->md_dump_size; | 1499 | size = ha->md_template_size + ha->md_dump_size; |
1500 | else | 1500 | else |
1501 | size = ha->fw_dump_len; | 1501 | size = ha->fw_dump_len; |
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 71ff340f6de4..524f9eb7fcd1 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2012 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -2054,9 +2054,49 @@ qla26xx_serdes_op(struct fc_bsg_job *bsg_job) | |||
2054 | bsg_job->reply->reply_payload_rcv_len = sizeof(sr); | 2054 | bsg_job->reply->reply_payload_rcv_len = sizeof(sr); |
2055 | break; | 2055 | break; |
2056 | default: | 2056 | default: |
2057 | ql_log(ql_log_warn, vha, 0x708c, | 2057 | ql_dbg(ql_dbg_user, vha, 0x708c, |
2058 | "Unknown serdes cmd %x.\n", sr.cmd); | 2058 | "Unknown serdes cmd %x.\n", sr.cmd); |
2059 | rval = -EDOM; | 2059 | rval = -EINVAL; |
2060 | break; | ||
2061 | } | ||
2062 | |||
2063 | bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = | ||
2064 | rval ? EXT_STATUS_MAILBOX : 0; | ||
2065 | |||
2066 | bsg_job->reply_len = sizeof(struct fc_bsg_reply); | ||
2067 | bsg_job->reply->result = DID_OK << 16; | ||
2068 | bsg_job->job_done(bsg_job); | ||
2069 | return 0; | ||
2070 | } | ||
2071 | |||
2072 | static int | ||
2073 | qla8044_serdes_op(struct fc_bsg_job *bsg_job) | ||
2074 | { | ||
2075 | struct Scsi_Host *host = bsg_job->shost; | ||
2076 | scsi_qla_host_t *vha = shost_priv(host); | ||
2077 | int rval = 0; | ||
2078 | struct qla_serdes_reg_ex sr; | ||
2079 | |||
2080 | memset(&sr, 0, sizeof(sr)); | ||
2081 | |||
2082 | sg_copy_to_buffer(bsg_job->request_payload.sg_list, | ||
2083 | bsg_job->request_payload.sg_cnt, &sr, sizeof(sr)); | ||
2084 | |||
2085 | switch (sr.cmd) { | ||
2086 | case INT_SC_SERDES_WRITE_REG: | ||
2087 | rval = qla8044_write_serdes_word(vha, sr.addr, sr.val); | ||
2088 | bsg_job->reply->reply_payload_rcv_len = 0; | ||
2089 | break; | ||
2090 | case INT_SC_SERDES_READ_REG: | ||
2091 | rval = qla8044_read_serdes_word(vha, sr.addr, &sr.val); | ||
2092 | sg_copy_from_buffer(bsg_job->reply_payload.sg_list, | ||
2093 | bsg_job->reply_payload.sg_cnt, &sr, sizeof(sr)); | ||
2094 | bsg_job->reply->reply_payload_rcv_len = sizeof(sr); | ||
2095 | break; | ||
2096 | default: | ||
2097 | ql_dbg(ql_dbg_user, vha, 0x70cf, | ||
2098 | "Unknown serdes cmd %x.\n", sr.cmd); | ||
2099 | rval = -EINVAL; | ||
2060 | break; | 2100 | break; |
2061 | } | 2101 | } |
2062 | 2102 | ||
@@ -2121,6 +2161,9 @@ qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job) | |||
2121 | case QL_VND_SERDES_OP: | 2161 | case QL_VND_SERDES_OP: |
2122 | return qla26xx_serdes_op(bsg_job); | 2162 | return qla26xx_serdes_op(bsg_job); |
2123 | 2163 | ||
2164 | case QL_VND_SERDES_OP_EX: | ||
2165 | return qla8044_serdes_op(bsg_job); | ||
2166 | |||
2124 | default: | 2167 | default: |
2125 | return -ENOSYS; | 2168 | return -ENOSYS; |
2126 | } | 2169 | } |
diff --git a/drivers/scsi/qla2xxx/qla_bsg.h b/drivers/scsi/qla2xxx/qla_bsg.h index e5c2126221e9..d38f9efa56fa 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.h +++ b/drivers/scsi/qla2xxx/qla_bsg.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -24,6 +24,7 @@ | |||
24 | #define QL_VND_READ_I2C 0x11 | 24 | #define QL_VND_READ_I2C 0x11 |
25 | #define QL_VND_FX00_MGMT_CMD 0x12 | 25 | #define QL_VND_FX00_MGMT_CMD 0x12 |
26 | #define QL_VND_SERDES_OP 0x13 | 26 | #define QL_VND_SERDES_OP 0x13 |
27 | #define QL_VND_SERDES_OP_EX 0x14 | ||
27 | 28 | ||
28 | /* BSG Vendor specific subcode returns */ | 29 | /* BSG Vendor specific subcode returns */ |
29 | #define EXT_STATUS_OK 0 | 30 | #define EXT_STATUS_OK 0 |
@@ -225,4 +226,10 @@ struct qla_serdes_reg { | |||
225 | uint16_t val; | 226 | uint16_t val; |
226 | } __packed; | 227 | } __packed; |
227 | 228 | ||
229 | struct qla_serdes_reg_ex { | ||
230 | uint16_t cmd; | ||
231 | uint32_t addr; | ||
232 | uint32_t val; | ||
233 | } __packed; | ||
234 | |||
228 | #endif | 235 | #endif |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 97255f7c3975..c72ee97bf3f7 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -15,7 +15,7 @@ | |||
15 | * | | | 0x0144,0x0146 | | 15 | * | | | 0x0144,0x0146 | |
16 | * | | | 0x015b-0x0160 | | 16 | * | | | 0x015b-0x0160 | |
17 | * | | | 0x016e-0x0170 | | 17 | * | | | 0x016e-0x0170 | |
18 | * | Mailbox commands | 0x1187 | 0x1018-0x1019 | | 18 | * | Mailbox commands | 0x118d | 0x1018-0x1019 | |
19 | * | | | 0x10ca | | 19 | * | | | 0x10ca | |
20 | * | | | 0x1115-0x1116 | | 20 | * | | | 0x1115-0x1116 | |
21 | * | | | 0x111a-0x111b | | 21 | * | | | 0x111a-0x111b | |
@@ -45,12 +45,16 @@ | |||
45 | * | | | 0x70ad-0x70ae | | 45 | * | | | 0x70ad-0x70ae | |
46 | * | | | 0x70d7-0x70db | | 46 | * | | | 0x70d7-0x70db | |
47 | * | | | 0x70de-0x70df | | 47 | * | | | 0x70de-0x70df | |
48 | * | Task Management | 0x803d | 0x8025-0x8026 | | 48 | * | Task Management | 0x803d | 0x8000,0x800b | |
49 | * | | | 0x800b,0x8039 | | 49 | * | | | 0x8019 | |
50 | * | | | 0x8025,0x8026 | | ||
51 | * | | | 0x8031,0x8032 | | ||
52 | * | | | 0x8039,0x803c | | ||
50 | * | AER/EEH | 0x9011 | | | 53 | * | AER/EEH | 0x9011 | | |
51 | * | Virtual Port | 0xa007 | | | 54 | * | Virtual Port | 0xa007 | | |
52 | * | ISP82XX Specific | 0xb14c | 0xb002,0xb024 | | 55 | * | ISP82XX Specific | 0xb157 | 0xb002,0xb024 | |
53 | * | | | 0xb09e,0xb0ae | | 56 | * | | | 0xb09e,0xb0ae | |
57 | * | | | 0xb0c3,0xb0c6 | | ||
54 | * | | | 0xb0e0-0xb0ef | | 58 | * | | | 0xb0e0-0xb0ef | |
55 | * | | | 0xb085,0xb0dc | | 59 | * | | | 0xb085,0xb0dc | |
56 | * | | | 0xb107,0xb108 | | 60 | * | | | 0xb107,0xb108 | |
@@ -60,12 +64,12 @@ | |||
60 | * | | | 0xb13c-0xb140 | | 64 | * | | | 0xb13c-0xb140 | |
61 | * | | | 0xb149 | | 65 | * | | | 0xb149 | |
62 | * | MultiQ | 0xc00c | | | 66 | * | MultiQ | 0xc00c | | |
63 | * | Misc | 0xd2ff | 0xd017-0xd019 | | 67 | * | Misc | 0xd212 | 0xd017-0xd019 | |
64 | * | | | 0xd020 | | 68 | * | | | 0xd020 | |
65 | * | | | 0xd02e-0xd0ff | | 69 | * | | | 0xd030-0xd0ff | |
66 | * | | | 0xd101-0xd1fe | | 70 | * | | | 0xd101-0xd1fe | |
67 | * | | | 0xd212-0xd2fe | | 71 | * | | | 0xd213-0xd2fe | |
68 | * | Target Mode | 0xe070 | 0xe021 | | 72 | * | Target Mode | 0xe078 | | |
69 | * | Target Mode Management | 0xf072 | 0xf002-0xf003 | | 73 | * | Target Mode Management | 0xf072 | 0xf002-0xf003 | |
70 | * | | | 0xf046-0xf049 | | 74 | * | | | 0xf046-0xf049 | |
71 | * | Target Mode Task Management | 0x1000b | | | 75 | * | Target Mode Task Management | 0x1000b | | |
@@ -277,9 +281,15 @@ qla24xx_dump_memory(struct qla_hw_data *ha, uint32_t *code_ram, | |||
277 | if (rval != QLA_SUCCESS) | 281 | if (rval != QLA_SUCCESS) |
278 | return rval; | 282 | return rval; |
279 | 283 | ||
284 | set_bit(RISC_SRAM_DUMP_CMPL, &ha->fw_dump_cap_flags); | ||
285 | |||
280 | /* External Memory. */ | 286 | /* External Memory. */ |
281 | return qla24xx_dump_ram(ha, 0x100000, *nxt, | 287 | rval = qla24xx_dump_ram(ha, 0x100000, *nxt, |
282 | ha->fw_memory_size - 0x100000 + 1, nxt); | 288 | ha->fw_memory_size - 0x100000 + 1, nxt); |
289 | if (rval == QLA_SUCCESS) | ||
290 | set_bit(RISC_EXT_MEM_DUMP_CMPL, &ha->fw_dump_cap_flags); | ||
291 | |||
292 | return rval; | ||
283 | } | 293 | } |
284 | 294 | ||
285 | static uint32_t * | 295 | static uint32_t * |
@@ -296,23 +306,15 @@ qla24xx_read_window(struct device_reg_24xx __iomem *reg, uint32_t iobase, | |||
296 | return buf; | 306 | return buf; |
297 | } | 307 | } |
298 | 308 | ||
299 | int | 309 | void |
300 | qla24xx_pause_risc(struct device_reg_24xx __iomem *reg) | 310 | qla24xx_pause_risc(struct device_reg_24xx __iomem *reg, struct qla_hw_data *ha) |
301 | { | 311 | { |
302 | int rval = QLA_SUCCESS; | ||
303 | uint32_t cnt; | ||
304 | |||
305 | WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_PAUSE); | 312 | WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_PAUSE); |
306 | for (cnt = 30000; | ||
307 | ((RD_REG_DWORD(®->host_status) & HSRX_RISC_PAUSED) == 0) && | ||
308 | rval == QLA_SUCCESS; cnt--) { | ||
309 | if (cnt) | ||
310 | udelay(100); | ||
311 | else | ||
312 | rval = QLA_FUNCTION_TIMEOUT; | ||
313 | } | ||
314 | 313 | ||
315 | return rval; | 314 | /* 100 usec delay is sufficient enough for hardware to pause RISC */ |
315 | udelay(100); | ||
316 | if (RD_REG_DWORD(®->host_status) & HSRX_RISC_PAUSED) | ||
317 | set_bit(RISC_PAUSE_CMPL, &ha->fw_dump_cap_flags); | ||
316 | } | 318 | } |
317 | 319 | ||
318 | int | 320 | int |
@@ -320,10 +322,14 @@ qla24xx_soft_reset(struct qla_hw_data *ha) | |||
320 | { | 322 | { |
321 | int rval = QLA_SUCCESS; | 323 | int rval = QLA_SUCCESS; |
322 | uint32_t cnt; | 324 | uint32_t cnt; |
323 | uint16_t mb0, wd; | 325 | uint16_t wd; |
324 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 326 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
325 | 327 | ||
326 | /* Reset RISC. */ | 328 | /* |
329 | * Reset RISC. The delay is dependent on system architecture. | ||
330 | * Driver can proceed with the reset sequence after waiting | ||
331 | * for a timeout period. | ||
332 | */ | ||
327 | WRT_REG_DWORD(®->ctrl_status, CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); | 333 | WRT_REG_DWORD(®->ctrl_status, CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); |
328 | for (cnt = 0; cnt < 30000; cnt++) { | 334 | for (cnt = 0; cnt < 30000; cnt++) { |
329 | if ((RD_REG_DWORD(®->ctrl_status) & CSRX_DMA_ACTIVE) == 0) | 335 | if ((RD_REG_DWORD(®->ctrl_status) & CSRX_DMA_ACTIVE) == 0) |
@@ -331,19 +337,14 @@ qla24xx_soft_reset(struct qla_hw_data *ha) | |||
331 | 337 | ||
332 | udelay(10); | 338 | udelay(10); |
333 | } | 339 | } |
340 | if (!(RD_REG_DWORD(®->ctrl_status) & CSRX_DMA_ACTIVE)) | ||
341 | set_bit(DMA_SHUTDOWN_CMPL, &ha->fw_dump_cap_flags); | ||
334 | 342 | ||
335 | WRT_REG_DWORD(®->ctrl_status, | 343 | WRT_REG_DWORD(®->ctrl_status, |
336 | CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); | 344 | CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); |
337 | pci_read_config_word(ha->pdev, PCI_COMMAND, &wd); | 345 | pci_read_config_word(ha->pdev, PCI_COMMAND, &wd); |
338 | 346 | ||
339 | udelay(100); | 347 | udelay(100); |
340 | /* Wait for firmware to complete NVRAM accesses. */ | ||
341 | mb0 = (uint32_t) RD_REG_WORD(®->mailbox0); | ||
342 | for (cnt = 10000 ; cnt && mb0; cnt--) { | ||
343 | udelay(5); | ||
344 | mb0 = (uint32_t) RD_REG_WORD(®->mailbox0); | ||
345 | barrier(); | ||
346 | } | ||
347 | 348 | ||
348 | /* Wait for soft-reset to complete. */ | 349 | /* Wait for soft-reset to complete. */ |
349 | for (cnt = 0; cnt < 30000; cnt++) { | 350 | for (cnt = 0; cnt < 30000; cnt++) { |
@@ -353,16 +354,21 @@ qla24xx_soft_reset(struct qla_hw_data *ha) | |||
353 | 354 | ||
354 | udelay(10); | 355 | udelay(10); |
355 | } | 356 | } |
357 | if (!(RD_REG_DWORD(®->ctrl_status) & CSRX_ISP_SOFT_RESET)) | ||
358 | set_bit(ISP_RESET_CMPL, &ha->fw_dump_cap_flags); | ||
359 | |||
356 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_RESET); | 360 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_RESET); |
357 | RD_REG_DWORD(®->hccr); /* PCI Posting. */ | 361 | RD_REG_DWORD(®->hccr); /* PCI Posting. */ |
358 | 362 | ||
359 | for (cnt = 30000; RD_REG_WORD(®->mailbox0) != 0 && | 363 | for (cnt = 10000; RD_REG_WORD(®->mailbox0) != 0 && |
360 | rval == QLA_SUCCESS; cnt--) { | 364 | rval == QLA_SUCCESS; cnt--) { |
361 | if (cnt) | 365 | if (cnt) |
362 | udelay(100); | 366 | udelay(10); |
363 | else | 367 | else |
364 | rval = QLA_FUNCTION_TIMEOUT; | 368 | rval = QLA_FUNCTION_TIMEOUT; |
365 | } | 369 | } |
370 | if (rval == QLA_SUCCESS) | ||
371 | set_bit(RISC_RDY_AFT_RESET, &ha->fw_dump_cap_flags); | ||
366 | 372 | ||
367 | return rval; | 373 | return rval; |
368 | } | 374 | } |
@@ -659,12 +665,13 @@ qla2xxx_dump_post_process(scsi_qla_host_t *vha, int rval) | |||
659 | 665 | ||
660 | if (rval != QLA_SUCCESS) { | 666 | if (rval != QLA_SUCCESS) { |
661 | ql_log(ql_log_warn, vha, 0xd000, | 667 | ql_log(ql_log_warn, vha, 0xd000, |
662 | "Failed to dump firmware (%x).\n", rval); | 668 | "Failed to dump firmware (%x), dump status flags (0x%lx).\n", |
669 | rval, ha->fw_dump_cap_flags); | ||
663 | ha->fw_dumped = 0; | 670 | ha->fw_dumped = 0; |
664 | } else { | 671 | } else { |
665 | ql_log(ql_log_info, vha, 0xd001, | 672 | ql_log(ql_log_info, vha, 0xd001, |
666 | "Firmware dump saved to temp buffer (%ld/%p).\n", | 673 | "Firmware dump saved to temp buffer (%ld/%p), dump status flags (0x%lx).\n", |
667 | vha->host_no, ha->fw_dump); | 674 | vha->host_no, ha->fw_dump, ha->fw_dump_cap_flags); |
668 | ha->fw_dumped = 1; | 675 | ha->fw_dumped = 1; |
669 | qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP); | 676 | qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP); |
670 | } | 677 | } |
@@ -1053,6 +1060,7 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
1053 | 1060 | ||
1054 | risc_address = ext_mem_cnt = 0; | 1061 | risc_address = ext_mem_cnt = 0; |
1055 | flags = 0; | 1062 | flags = 0; |
1063 | ha->fw_dump_cap_flags = 0; | ||
1056 | 1064 | ||
1057 | if (!hardware_locked) | 1065 | if (!hardware_locked) |
1058 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1066 | spin_lock_irqsave(&ha->hardware_lock, flags); |
@@ -1075,10 +1083,11 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
1075 | 1083 | ||
1076 | fw->host_status = htonl(RD_REG_DWORD(®->host_status)); | 1084 | fw->host_status = htonl(RD_REG_DWORD(®->host_status)); |
1077 | 1085 | ||
1078 | /* Pause RISC. */ | 1086 | /* |
1079 | rval = qla24xx_pause_risc(reg); | 1087 | * Pause RISC. No need to track timeout, as resetting the chip |
1080 | if (rval != QLA_SUCCESS) | 1088 | * is the right approach incase of pause timeout |
1081 | goto qla24xx_fw_dump_failed_0; | 1089 | */ |
1090 | qla24xx_pause_risc(reg, ha); | ||
1082 | 1091 | ||
1083 | /* Host interface registers. */ | 1092 | /* Host interface registers. */ |
1084 | dmp_reg = ®->flash_addr; | 1093 | dmp_reg = ®->flash_addr; |
@@ -1302,6 +1311,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
1302 | 1311 | ||
1303 | risc_address = ext_mem_cnt = 0; | 1312 | risc_address = ext_mem_cnt = 0; |
1304 | flags = 0; | 1313 | flags = 0; |
1314 | ha->fw_dump_cap_flags = 0; | ||
1305 | 1315 | ||
1306 | if (!hardware_locked) | 1316 | if (!hardware_locked) |
1307 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1317 | spin_lock_irqsave(&ha->hardware_lock, flags); |
@@ -1325,10 +1335,11 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
1325 | 1335 | ||
1326 | fw->host_status = htonl(RD_REG_DWORD(®->host_status)); | 1336 | fw->host_status = htonl(RD_REG_DWORD(®->host_status)); |
1327 | 1337 | ||
1328 | /* Pause RISC. */ | 1338 | /* |
1329 | rval = qla24xx_pause_risc(reg); | 1339 | * Pause RISC. No need to track timeout, as resetting the chip |
1330 | if (rval != QLA_SUCCESS) | 1340 | * is the right approach incase of pause timeout |
1331 | goto qla25xx_fw_dump_failed_0; | 1341 | */ |
1342 | qla24xx_pause_risc(reg, ha); | ||
1332 | 1343 | ||
1333 | /* Host/Risc registers. */ | 1344 | /* Host/Risc registers. */ |
1334 | iter_reg = fw->host_risc_reg; | 1345 | iter_reg = fw->host_risc_reg; |
@@ -1619,6 +1630,7 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
1619 | 1630 | ||
1620 | risc_address = ext_mem_cnt = 0; | 1631 | risc_address = ext_mem_cnt = 0; |
1621 | flags = 0; | 1632 | flags = 0; |
1633 | ha->fw_dump_cap_flags = 0; | ||
1622 | 1634 | ||
1623 | if (!hardware_locked) | 1635 | if (!hardware_locked) |
1624 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1636 | spin_lock_irqsave(&ha->hardware_lock, flags); |
@@ -1641,10 +1653,11 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
1641 | 1653 | ||
1642 | fw->host_status = htonl(RD_REG_DWORD(®->host_status)); | 1654 | fw->host_status = htonl(RD_REG_DWORD(®->host_status)); |
1643 | 1655 | ||
1644 | /* Pause RISC. */ | 1656 | /* |
1645 | rval = qla24xx_pause_risc(reg); | 1657 | * Pause RISC. No need to track timeout, as resetting the chip |
1646 | if (rval != QLA_SUCCESS) | 1658 | * is the right approach incase of pause timeout |
1647 | goto qla81xx_fw_dump_failed_0; | 1659 | */ |
1660 | qla24xx_pause_risc(reg, ha); | ||
1648 | 1661 | ||
1649 | /* Host/Risc registers. */ | 1662 | /* Host/Risc registers. */ |
1650 | iter_reg = fw->host_risc_reg; | 1663 | iter_reg = fw->host_risc_reg; |
@@ -1938,6 +1951,7 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
1938 | 1951 | ||
1939 | risc_address = ext_mem_cnt = 0; | 1952 | risc_address = ext_mem_cnt = 0; |
1940 | flags = 0; | 1953 | flags = 0; |
1954 | ha->fw_dump_cap_flags = 0; | ||
1941 | 1955 | ||
1942 | if (!hardware_locked) | 1956 | if (!hardware_locked) |
1943 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1957 | spin_lock_irqsave(&ha->hardware_lock, flags); |
@@ -1959,10 +1973,11 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
1959 | 1973 | ||
1960 | fw->host_status = htonl(RD_REG_DWORD(®->host_status)); | 1974 | fw->host_status = htonl(RD_REG_DWORD(®->host_status)); |
1961 | 1975 | ||
1962 | /* Pause RISC. */ | 1976 | /* |
1963 | rval = qla24xx_pause_risc(reg); | 1977 | * Pause RISC. No need to track timeout, as resetting the chip |
1964 | if (rval != QLA_SUCCESS) | 1978 | * is the right approach incase of pause timeout |
1965 | goto qla83xx_fw_dump_failed_0; | 1979 | */ |
1980 | qla24xx_pause_risc(reg, ha); | ||
1966 | 1981 | ||
1967 | WRT_REG_DWORD(®->iobase_addr, 0x6000); | 1982 | WRT_REG_DWORD(®->iobase_addr, 0x6000); |
1968 | dmp_reg = ®->iobase_window; | 1983 | dmp_reg = ®->iobase_window; |
@@ -2385,9 +2400,11 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked) | |||
2385 | nxt += sizeof(fw->code_ram); | 2400 | nxt += sizeof(fw->code_ram); |
2386 | nxt += (ha->fw_memory_size - 0x100000 + 1); | 2401 | nxt += (ha->fw_memory_size - 0x100000 + 1); |
2387 | goto copy_queue; | 2402 | goto copy_queue; |
2388 | } else | 2403 | } else { |
2404 | set_bit(RISC_RDY_AFT_RESET, &ha->fw_dump_cap_flags); | ||
2389 | ql_log(ql_log_warn, vha, 0xd010, | 2405 | ql_log(ql_log_warn, vha, 0xd010, |
2390 | "bigger hammer success?\n"); | 2406 | "bigger hammer success?\n"); |
2407 | } | ||
2391 | } | 2408 | } |
2392 | 2409 | ||
2393 | rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram), | 2410 | rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram), |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index cc961040f8b1..e1fc4e66966a 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -353,5 +353,6 @@ extern int qla27xx_dump_mpi_ram(struct qla_hw_data *, uint32_t, uint32_t *, | |||
353 | uint32_t, void **); | 353 | uint32_t, void **); |
354 | extern int qla24xx_dump_ram(struct qla_hw_data *, uint32_t, uint32_t *, | 354 | extern int qla24xx_dump_ram(struct qla_hw_data *, uint32_t, uint32_t *, |
355 | uint32_t, void **); | 355 | uint32_t, void **); |
356 | extern int qla24xx_pause_risc(struct device_reg_24xx __iomem *); | 356 | extern void qla24xx_pause_risc(struct device_reg_24xx __iomem *, |
357 | struct qla_hw_data *); | ||
357 | extern int qla24xx_soft_reset(struct qla_hw_data *); | 358 | extern int qla24xx_soft_reset(struct qla_hw_data *); |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 6a106136716c..1fa010448666 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -965,6 +965,13 @@ struct mbx_cmd_32 { | |||
965 | */ | 965 | */ |
966 | #define MBC_WRITE_MPI_REGISTER 0x01 /* Write MPI Register. */ | 966 | #define MBC_WRITE_MPI_REGISTER 0x01 /* Write MPI Register. */ |
967 | 967 | ||
968 | /* | ||
969 | * ISP8044 mailbox commands | ||
970 | */ | ||
971 | #define MBC_SET_GET_ETH_SERDES_REG 0x150 | ||
972 | #define HCS_WRITE_SERDES 0x3 | ||
973 | #define HCS_READ_SERDES 0x4 | ||
974 | |||
968 | /* Firmware return data sizes */ | 975 | /* Firmware return data sizes */ |
969 | #define FCAL_MAP_SIZE 128 | 976 | #define FCAL_MAP_SIZE 128 |
970 | 977 | ||
@@ -1622,10 +1629,20 @@ typedef struct { | |||
1622 | #define PO_MODE_DIF_PASS 2 | 1629 | #define PO_MODE_DIF_PASS 2 |
1623 | #define PO_MODE_DIF_REPLACE 3 | 1630 | #define PO_MODE_DIF_REPLACE 3 |
1624 | #define PO_MODE_DIF_TCP_CKSUM 6 | 1631 | #define PO_MODE_DIF_TCP_CKSUM 6 |
1625 | #define PO_ENABLE_DIF_BUNDLING BIT_8 | ||
1626 | #define PO_ENABLE_INCR_GUARD_SEED BIT_3 | 1632 | #define PO_ENABLE_INCR_GUARD_SEED BIT_3 |
1627 | #define PO_DISABLE_INCR_REF_TAG BIT_5 | ||
1628 | #define PO_DISABLE_GUARD_CHECK BIT_4 | 1633 | #define PO_DISABLE_GUARD_CHECK BIT_4 |
1634 | #define PO_DISABLE_INCR_REF_TAG BIT_5 | ||
1635 | #define PO_DIS_HEADER_MODE BIT_7 | ||
1636 | #define PO_ENABLE_DIF_BUNDLING BIT_8 | ||
1637 | #define PO_DIS_FRAME_MODE BIT_9 | ||
1638 | #define PO_DIS_VALD_APP_ESC BIT_10 /* Dis validation for escape tag/ffffh */ | ||
1639 | #define PO_DIS_VALD_APP_REF_ESC BIT_11 | ||
1640 | |||
1641 | #define PO_DIS_APP_TAG_REPL BIT_12 /* disable REG Tag replacement */ | ||
1642 | #define PO_DIS_REF_TAG_REPL BIT_13 | ||
1643 | #define PO_DIS_APP_TAG_VALD BIT_14 /* disable REF Tag validation */ | ||
1644 | #define PO_DIS_REF_TAG_VALD BIT_15 | ||
1645 | |||
1629 | /* | 1646 | /* |
1630 | * ISP queue - 64-Bit addressing, continuation crc entry structure definition. | 1647 | * ISP queue - 64-Bit addressing, continuation crc entry structure definition. |
1631 | */ | 1648 | */ |
@@ -1748,6 +1765,8 @@ typedef struct { | |||
1748 | #define CS_PORT_CONFIG_CHG 0x2A /* Port Configuration Changed */ | 1765 | #define CS_PORT_CONFIG_CHG 0x2A /* Port Configuration Changed */ |
1749 | #define CS_PORT_BUSY 0x2B /* Port Busy */ | 1766 | #define CS_PORT_BUSY 0x2B /* Port Busy */ |
1750 | #define CS_COMPLETE_CHKCOND 0x30 /* Error? */ | 1767 | #define CS_COMPLETE_CHKCOND 0x30 /* Error? */ |
1768 | #define CS_IOCB_ERROR 0x31 /* Generic error for IOCB request | ||
1769 | failure */ | ||
1751 | #define CS_BAD_PAYLOAD 0x80 /* Driver defined */ | 1770 | #define CS_BAD_PAYLOAD 0x80 /* Driver defined */ |
1752 | #define CS_UNKNOWN 0x81 /* Driver defined */ | 1771 | #define CS_UNKNOWN 0x81 /* Driver defined */ |
1753 | #define CS_RETRY 0x82 /* Driver defined */ | 1772 | #define CS_RETRY 0x82 /* Driver defined */ |
@@ -2676,6 +2695,7 @@ struct rsp_que { | |||
2676 | uint32_t __iomem *rsp_q_out; | 2695 | uint32_t __iomem *rsp_q_out; |
2677 | uint16_t ring_index; | 2696 | uint16_t ring_index; |
2678 | uint16_t out_ptr; | 2697 | uint16_t out_ptr; |
2698 | uint16_t *in_ptr; /* queue shadow in index */ | ||
2679 | uint16_t length; | 2699 | uint16_t length; |
2680 | uint16_t options; | 2700 | uint16_t options; |
2681 | uint16_t rid; | 2701 | uint16_t rid; |
@@ -2702,6 +2722,7 @@ struct req_que { | |||
2702 | uint32_t __iomem *req_q_out; | 2722 | uint32_t __iomem *req_q_out; |
2703 | uint16_t ring_index; | 2723 | uint16_t ring_index; |
2704 | uint16_t in_ptr; | 2724 | uint16_t in_ptr; |
2725 | uint16_t *out_ptr; /* queue shadow out index */ | ||
2705 | uint16_t cnt; | 2726 | uint16_t cnt; |
2706 | uint16_t length; | 2727 | uint16_t length; |
2707 | uint16_t options; | 2728 | uint16_t options; |
@@ -2907,6 +2928,8 @@ struct qla_hw_data { | |||
2907 | #define PCI_DEVICE_ID_QLOGIC_ISP8031 0x8031 | 2928 | #define PCI_DEVICE_ID_QLOGIC_ISP8031 0x8031 |
2908 | #define PCI_DEVICE_ID_QLOGIC_ISP2031 0x2031 | 2929 | #define PCI_DEVICE_ID_QLOGIC_ISP2031 0x2031 |
2909 | #define PCI_DEVICE_ID_QLOGIC_ISP2071 0x2071 | 2930 | #define PCI_DEVICE_ID_QLOGIC_ISP2071 0x2071 |
2931 | #define PCI_DEVICE_ID_QLOGIC_ISP2271 0x2271 | ||
2932 | |||
2910 | uint32_t device_type; | 2933 | uint32_t device_type; |
2911 | #define DT_ISP2100 BIT_0 | 2934 | #define DT_ISP2100 BIT_0 |
2912 | #define DT_ISP2200 BIT_1 | 2935 | #define DT_ISP2200 BIT_1 |
@@ -2928,7 +2951,8 @@ struct qla_hw_data { | |||
2928 | #define DT_ISPFX00 BIT_17 | 2951 | #define DT_ISPFX00 BIT_17 |
2929 | #define DT_ISP8044 BIT_18 | 2952 | #define DT_ISP8044 BIT_18 |
2930 | #define DT_ISP2071 BIT_19 | 2953 | #define DT_ISP2071 BIT_19 |
2931 | #define DT_ISP_LAST (DT_ISP2071 << 1) | 2954 | #define DT_ISP2271 BIT_20 |
2955 | #define DT_ISP_LAST (DT_ISP2271 << 1) | ||
2932 | 2956 | ||
2933 | #define DT_T10_PI BIT_25 | 2957 | #define DT_T10_PI BIT_25 |
2934 | #define DT_IIDMA BIT_26 | 2958 | #define DT_IIDMA BIT_26 |
@@ -2959,6 +2983,7 @@ struct qla_hw_data { | |||
2959 | #define IS_QLA8031(ha) (DT_MASK(ha) & DT_ISP8031) | 2983 | #define IS_QLA8031(ha) (DT_MASK(ha) & DT_ISP8031) |
2960 | #define IS_QLAFX00(ha) (DT_MASK(ha) & DT_ISPFX00) | 2984 | #define IS_QLAFX00(ha) (DT_MASK(ha) & DT_ISPFX00) |
2961 | #define IS_QLA2071(ha) (DT_MASK(ha) & DT_ISP2071) | 2985 | #define IS_QLA2071(ha) (DT_MASK(ha) & DT_ISP2071) |
2986 | #define IS_QLA2271(ha) (DT_MASK(ha) & DT_ISP2271) | ||
2962 | 2987 | ||
2963 | #define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \ | 2988 | #define IS_QLA23XX(ha) (IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \ |
2964 | IS_QLA6312(ha) || IS_QLA6322(ha)) | 2989 | IS_QLA6312(ha) || IS_QLA6322(ha)) |
@@ -2967,7 +2992,7 @@ struct qla_hw_data { | |||
2967 | #define IS_QLA25XX(ha) (IS_QLA2532(ha)) | 2992 | #define IS_QLA25XX(ha) (IS_QLA2532(ha)) |
2968 | #define IS_QLA83XX(ha) (IS_QLA2031(ha) || IS_QLA8031(ha)) | 2993 | #define IS_QLA83XX(ha) (IS_QLA2031(ha) || IS_QLA8031(ha)) |
2969 | #define IS_QLA84XX(ha) (IS_QLA8432(ha)) | 2994 | #define IS_QLA84XX(ha) (IS_QLA8432(ha)) |
2970 | #define IS_QLA27XX(ha) (IS_QLA2071(ha)) | 2995 | #define IS_QLA27XX(ha) (IS_QLA2071(ha) || IS_QLA2271(ha)) |
2971 | #define IS_QLA24XX_TYPE(ha) (IS_QLA24XX(ha) || IS_QLA54XX(ha) || \ | 2996 | #define IS_QLA24XX_TYPE(ha) (IS_QLA24XX(ha) || IS_QLA54XX(ha) || \ |
2972 | IS_QLA84XX(ha)) | 2997 | IS_QLA84XX(ha)) |
2973 | #define IS_CNA_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA82XX(ha) || \ | 2998 | #define IS_CNA_CAPABLE(ha) (IS_QLA81XX(ha) || IS_QLA82XX(ha) || \ |
@@ -3006,6 +3031,7 @@ struct qla_hw_data { | |||
3006 | (((ha)->fw_attributes_h << 16 | (ha)->fw_attributes) & BIT_22)) | 3031 | (((ha)->fw_attributes_h << 16 | (ha)->fw_attributes) & BIT_22)) |
3007 | #define IS_ATIO_MSIX_CAPABLE(ha) (IS_QLA83XX(ha)) | 3032 | #define IS_ATIO_MSIX_CAPABLE(ha) (IS_QLA83XX(ha)) |
3008 | #define IS_TGT_MODE_CAPABLE(ha) (ha->tgt.atio_q_length) | 3033 | #define IS_TGT_MODE_CAPABLE(ha) (ha->tgt.atio_q_length) |
3034 | #define IS_SHADOW_REG_CAPABLE(ha) (IS_QLA27XX(ha)) | ||
3009 | 3035 | ||
3010 | /* HBA serial number */ | 3036 | /* HBA serial number */ |
3011 | uint8_t serial0; | 3037 | uint8_t serial0; |
@@ -3136,7 +3162,15 @@ struct qla_hw_data { | |||
3136 | struct qla2xxx_fw_dump *fw_dump; | 3162 | struct qla2xxx_fw_dump *fw_dump; |
3137 | uint32_t fw_dump_len; | 3163 | uint32_t fw_dump_len; |
3138 | int fw_dumped; | 3164 | int fw_dumped; |
3165 | unsigned long fw_dump_cap_flags; | ||
3166 | #define RISC_PAUSE_CMPL 0 | ||
3167 | #define DMA_SHUTDOWN_CMPL 1 | ||
3168 | #define ISP_RESET_CMPL 2 | ||
3169 | #define RISC_RDY_AFT_RESET 3 | ||
3170 | #define RISC_SRAM_DUMP_CMPL 4 | ||
3171 | #define RISC_EXT_MEM_DUMP_CMPL 5 | ||
3139 | int fw_dump_reading; | 3172 | int fw_dump_reading; |
3173 | int prev_minidump_failed; | ||
3140 | dma_addr_t eft_dma; | 3174 | dma_addr_t eft_dma; |
3141 | void *eft; | 3175 | void *eft; |
3142 | /* Current size of mctp dump is 0x086064 bytes */ | 3176 | /* Current size of mctp dump is 0x086064 bytes */ |
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c index 32ab80957688..2ca39b8e7166 100644 --- a/drivers/scsi/qla2xxx/qla_dfs.c +++ b/drivers/scsi/qla2xxx/qla_dfs.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 3a7353eaccbd..eb8f57249f1d 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -371,7 +371,10 @@ struct init_cb_24xx { | |||
371 | * BIT 14 = Data Rate bit 1 | 371 | * BIT 14 = Data Rate bit 1 |
372 | * BIT 15 = Data Rate bit 2 | 372 | * BIT 15 = Data Rate bit 2 |
373 | * BIT 16 = Enable 75 ohm Termination Select | 373 | * BIT 16 = Enable 75 ohm Termination Select |
374 | * BIT 17-31 = Reserved | 374 | * BIT 17-28 = Reserved |
375 | * BIT 29 = Enable response queue 0 in index shadowing | ||
376 | * BIT 30 = Enable request queue 0 out index shadowing | ||
377 | * BIT 31 = Reserved | ||
375 | */ | 378 | */ |
376 | uint32_t firmware_options_3; | 379 | uint32_t firmware_options_3; |
377 | uint16_t qos; | 380 | uint16_t qos; |
@@ -1134,13 +1137,6 @@ struct device_reg_24xx { | |||
1134 | #define MIN_MULTI_ID_FABRIC 64 /* Must be power-of-2. */ | 1137 | #define MIN_MULTI_ID_FABRIC 64 /* Must be power-of-2. */ |
1135 | #define MAX_MULTI_ID_FABRIC 256 /* ... */ | 1138 | #define MAX_MULTI_ID_FABRIC 256 /* ... */ |
1136 | 1139 | ||
1137 | #define for_each_mapped_vp_idx(_ha, _idx) \ | ||
1138 | for (_idx = find_next_bit((_ha)->vp_idx_map, \ | ||
1139 | (_ha)->max_npiv_vports + 1, 1); \ | ||
1140 | _idx <= (_ha)->max_npiv_vports; \ | ||
1141 | _idx = find_next_bit((_ha)->vp_idx_map, \ | ||
1142 | (_ha)->max_npiv_vports + 1, _idx + 1)) \ | ||
1143 | |||
1144 | struct mid_conf_entry_24xx { | 1140 | struct mid_conf_entry_24xx { |
1145 | uint16_t reserved_1; | 1141 | uint16_t reserved_1; |
1146 | 1142 | ||
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index e665e8109933..d48dea8fab1b 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -220,6 +220,13 @@ extern unsigned long qla2x00_get_async_timeout(struct scsi_qla_host *); | |||
220 | 220 | ||
221 | extern void *qla2x00_alloc_iocbs(scsi_qla_host_t *, srb_t *); | 221 | extern void *qla2x00_alloc_iocbs(scsi_qla_host_t *, srb_t *); |
222 | extern int qla2x00_issue_marker(scsi_qla_host_t *, int); | 222 | extern int qla2x00_issue_marker(scsi_qla_host_t *, int); |
223 | extern int qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *, srb_t *, | ||
224 | uint32_t *, uint16_t, struct qla_tgt_cmd *); | ||
225 | extern int qla24xx_walk_and_build_sglist(struct qla_hw_data *, srb_t *, | ||
226 | uint32_t *, uint16_t, struct qla_tgt_cmd *); | ||
227 | extern int qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *, srb_t *, | ||
228 | uint32_t *, uint16_t, struct qla_tgt_cmd *); | ||
229 | |||
223 | 230 | ||
224 | /* | 231 | /* |
225 | * Global Function Prototypes in qla_mbx.c source file. | 232 | * Global Function Prototypes in qla_mbx.c source file. |
@@ -347,6 +354,11 @@ extern int | |||
347 | qla2x00_read_serdes_word(scsi_qla_host_t *, uint16_t, uint16_t *); | 354 | qla2x00_read_serdes_word(scsi_qla_host_t *, uint16_t, uint16_t *); |
348 | 355 | ||
349 | extern int | 356 | extern int |
357 | qla8044_write_serdes_word(scsi_qla_host_t *, uint32_t, uint32_t); | ||
358 | extern int | ||
359 | qla8044_read_serdes_word(scsi_qla_host_t *, uint32_t, uint32_t *); | ||
360 | |||
361 | extern int | ||
350 | qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); | 362 | qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); |
351 | 363 | ||
352 | extern int | 364 | extern int |
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index e377f9d2f92a..a0df3b1b3823 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 38aeb54cd9d8..e2184412617d 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -1476,6 +1476,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) | |||
1476 | } | 1476 | } |
1477 | 1477 | ||
1478 | ha->fw_dumped = 0; | 1478 | ha->fw_dumped = 0; |
1479 | ha->fw_dump_cap_flags = 0; | ||
1479 | dump_size = fixed_size = mem_size = eft_size = fce_size = mq_size = 0; | 1480 | dump_size = fixed_size = mem_size = eft_size = fce_size = mq_size = 0; |
1480 | req_q_size = rsp_q_size = 0; | 1481 | req_q_size = rsp_q_size = 0; |
1481 | 1482 | ||
@@ -2061,6 +2062,10 @@ qla24xx_config_rings(struct scsi_qla_host *vha) | |||
2061 | icb->atio_q_address[0] = cpu_to_le32(LSD(ha->tgt.atio_dma)); | 2062 | icb->atio_q_address[0] = cpu_to_le32(LSD(ha->tgt.atio_dma)); |
2062 | icb->atio_q_address[1] = cpu_to_le32(MSD(ha->tgt.atio_dma)); | 2063 | icb->atio_q_address[1] = cpu_to_le32(MSD(ha->tgt.atio_dma)); |
2063 | 2064 | ||
2065 | if (IS_SHADOW_REG_CAPABLE(ha)) | ||
2066 | icb->firmware_options_2 |= | ||
2067 | __constant_cpu_to_le32(BIT_30|BIT_29); | ||
2068 | |||
2064 | if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) { | 2069 | if (ha->mqenable || IS_QLA83XX(ha) || IS_QLA27XX(ha)) { |
2065 | icb->qos = __constant_cpu_to_le16(QLA_DEFAULT_QUE_QOS); | 2070 | icb->qos = __constant_cpu_to_le16(QLA_DEFAULT_QUE_QOS); |
2066 | icb->rid = __constant_cpu_to_le16(rid); | 2071 | icb->rid = __constant_cpu_to_le16(rid); |
@@ -2138,6 +2143,8 @@ qla2x00_init_rings(scsi_qla_host_t *vha) | |||
2138 | req = ha->req_q_map[que]; | 2143 | req = ha->req_q_map[que]; |
2139 | if (!req) | 2144 | if (!req) |
2140 | continue; | 2145 | continue; |
2146 | req->out_ptr = (void *)(req->ring + req->length); | ||
2147 | *req->out_ptr = 0; | ||
2141 | for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) | 2148 | for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) |
2142 | req->outstanding_cmds[cnt] = NULL; | 2149 | req->outstanding_cmds[cnt] = NULL; |
2143 | 2150 | ||
@@ -2153,6 +2160,8 @@ qla2x00_init_rings(scsi_qla_host_t *vha) | |||
2153 | rsp = ha->rsp_q_map[que]; | 2160 | rsp = ha->rsp_q_map[que]; |
2154 | if (!rsp) | 2161 | if (!rsp) |
2155 | continue; | 2162 | continue; |
2163 | rsp->in_ptr = (void *)(rsp->ring + rsp->length); | ||
2164 | *rsp->in_ptr = 0; | ||
2156 | /* Initialize response queue entries */ | 2165 | /* Initialize response queue entries */ |
2157 | if (IS_QLAFX00(ha)) | 2166 | if (IS_QLAFX00(ha)) |
2158 | qlafx00_init_response_q_entries(rsp); | 2167 | qlafx00_init_response_q_entries(rsp); |
@@ -3406,7 +3415,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha) | |||
3406 | fcport->d_id.b.domain, | 3415 | fcport->d_id.b.domain, |
3407 | fcport->d_id.b.area, | 3416 | fcport->d_id.b.area, |
3408 | fcport->d_id.b.al_pa); | 3417 | fcport->d_id.b.al_pa); |
3409 | fcport->loop_id = FC_NO_LOOP_ID; | 3418 | qla2x00_clear_loop_id(fcport); |
3410 | } | 3419 | } |
3411 | } | 3420 | } |
3412 | } | 3421 | } |
@@ -4727,7 +4736,6 @@ static int | |||
4727 | qla2x00_restart_isp(scsi_qla_host_t *vha) | 4736 | qla2x00_restart_isp(scsi_qla_host_t *vha) |
4728 | { | 4737 | { |
4729 | int status = 0; | 4738 | int status = 0; |
4730 | uint32_t wait_time; | ||
4731 | struct qla_hw_data *ha = vha->hw; | 4739 | struct qla_hw_data *ha = vha->hw; |
4732 | struct req_que *req = ha->req_q_map[0]; | 4740 | struct req_que *req = ha->req_q_map[0]; |
4733 | struct rsp_que *rsp = ha->rsp_q_map[0]; | 4741 | struct rsp_que *rsp = ha->rsp_q_map[0]; |
@@ -4744,14 +4752,12 @@ qla2x00_restart_isp(scsi_qla_host_t *vha) | |||
4744 | if (!status && !(status = qla2x00_init_rings(vha))) { | 4752 | if (!status && !(status = qla2x00_init_rings(vha))) { |
4745 | clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags); | 4753 | clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags); |
4746 | ha->flags.chip_reset_done = 1; | 4754 | ha->flags.chip_reset_done = 1; |
4755 | |||
4747 | /* Initialize the queues in use */ | 4756 | /* Initialize the queues in use */ |
4748 | qla25xx_init_queues(ha); | 4757 | qla25xx_init_queues(ha); |
4749 | 4758 | ||
4750 | status = qla2x00_fw_ready(vha); | 4759 | status = qla2x00_fw_ready(vha); |
4751 | if (!status) { | 4760 | if (!status) { |
4752 | ql_dbg(ql_dbg_taskm, vha, 0x8031, | ||
4753 | "Start configure loop status = %d.\n", status); | ||
4754 | |||
4755 | /* Issue a marker after FW becomes ready. */ | 4761 | /* Issue a marker after FW becomes ready. */ |
4756 | qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL); | 4762 | qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL); |
4757 | 4763 | ||
@@ -4766,24 +4772,12 @@ qla2x00_restart_isp(scsi_qla_host_t *vha) | |||
4766 | qlt_24xx_process_atio_queue(vha); | 4772 | qlt_24xx_process_atio_queue(vha); |
4767 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 4773 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
4768 | 4774 | ||
4769 | /* Wait at most MAX_TARGET RSCNs for a stable link. */ | 4775 | set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); |
4770 | wait_time = 256; | ||
4771 | do { | ||
4772 | clear_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); | ||
4773 | qla2x00_configure_loop(vha); | ||
4774 | wait_time--; | ||
4775 | } while (!atomic_read(&vha->loop_down_timer) && | ||
4776 | !(test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags)) | ||
4777 | && wait_time && (test_bit(LOOP_RESYNC_NEEDED, | ||
4778 | &vha->dpc_flags))); | ||
4779 | } | 4776 | } |
4780 | 4777 | ||
4781 | /* if no cable then assume it's good */ | 4778 | /* if no cable then assume it's good */ |
4782 | if ((vha->device_flags & DFLG_NO_CABLE)) | 4779 | if ((vha->device_flags & DFLG_NO_CABLE)) |
4783 | status = 0; | 4780 | status = 0; |
4784 | |||
4785 | ql_dbg(ql_dbg_taskm, vha, 0x8032, | ||
4786 | "Configure loop done, status = 0x%x.\n", status); | ||
4787 | } | 4781 | } |
4788 | return (status); | 4782 | return (status); |
4789 | } | 4783 | } |
@@ -6130,7 +6124,6 @@ int | |||
6130 | qla82xx_restart_isp(scsi_qla_host_t *vha) | 6124 | qla82xx_restart_isp(scsi_qla_host_t *vha) |
6131 | { | 6125 | { |
6132 | int status, rval; | 6126 | int status, rval; |
6133 | uint32_t wait_time; | ||
6134 | struct qla_hw_data *ha = vha->hw; | 6127 | struct qla_hw_data *ha = vha->hw; |
6135 | struct req_que *req = ha->req_q_map[0]; | 6128 | struct req_que *req = ha->req_q_map[0]; |
6136 | struct rsp_que *rsp = ha->rsp_q_map[0]; | 6129 | struct rsp_que *rsp = ha->rsp_q_map[0]; |
@@ -6144,31 +6137,15 @@ qla82xx_restart_isp(scsi_qla_host_t *vha) | |||
6144 | 6137 | ||
6145 | status = qla2x00_fw_ready(vha); | 6138 | status = qla2x00_fw_ready(vha); |
6146 | if (!status) { | 6139 | if (!status) { |
6147 | ql_log(ql_log_info, vha, 0x803c, | ||
6148 | "Start configure loop, status =%d.\n", status); | ||
6149 | |||
6150 | /* Issue a marker after FW becomes ready. */ | 6140 | /* Issue a marker after FW becomes ready. */ |
6151 | qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL); | 6141 | qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL); |
6152 | |||
6153 | vha->flags.online = 1; | 6142 | vha->flags.online = 1; |
6154 | /* Wait at most MAX_TARGET RSCNs for a stable link. */ | 6143 | set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); |
6155 | wait_time = 256; | ||
6156 | do { | ||
6157 | clear_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); | ||
6158 | qla2x00_configure_loop(vha); | ||
6159 | wait_time--; | ||
6160 | } while (!atomic_read(&vha->loop_down_timer) && | ||
6161 | !(test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags)) && | ||
6162 | wait_time && | ||
6163 | (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags))); | ||
6164 | } | 6144 | } |
6165 | 6145 | ||
6166 | /* if no cable then assume it's good */ | 6146 | /* if no cable then assume it's good */ |
6167 | if ((vha->device_flags & DFLG_NO_CABLE)) | 6147 | if ((vha->device_flags & DFLG_NO_CABLE)) |
6168 | status = 0; | 6148 | status = 0; |
6169 | |||
6170 | ql_log(ql_log_info, vha, 0x8000, | ||
6171 | "Configure loop done, status = 0x%x.\n", status); | ||
6172 | } | 6149 | } |
6173 | 6150 | ||
6174 | if (!status) { | 6151 | if (!status) { |
@@ -6182,8 +6159,6 @@ qla82xx_restart_isp(scsi_qla_host_t *vha) | |||
6182 | vha->marker_needed = 1; | 6159 | vha->marker_needed = 1; |
6183 | } | 6160 | } |
6184 | 6161 | ||
6185 | vha->flags.online = 1; | ||
6186 | |||
6187 | ha->isp_ops->enable_intrs(ha); | 6162 | ha->isp_ops->enable_intrs(ha); |
6188 | 6163 | ||
6189 | ha->isp_abort_cnt = 0; | 6164 | ha->isp_abort_cnt = 0; |
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h index ce8b5fb0f347..b3b1d6fc2d6c 100644 --- a/drivers/scsi/qla2xxx/qla_inline.h +++ b/drivers/scsi/qla2xxx/qla_inline.h | |||
@@ -1,10 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include "qla_target.h" | ||
8 | /** | 9 | /** |
9 | * qla24xx_calc_iocbs() - Determine number of Command Type 3 and | 10 | * qla24xx_calc_iocbs() - Determine number of Command Type 3 and |
10 | * Continuation Type 1 IOCBs to allocate. | 11 | * Continuation Type 1 IOCBs to allocate. |
@@ -128,12 +129,20 @@ qla2x00_clear_loop_id(fc_port_t *fcport) { | |||
128 | } | 129 | } |
129 | 130 | ||
130 | static inline void | 131 | static inline void |
131 | qla2x00_clean_dsd_pool(struct qla_hw_data *ha, srb_t *sp) | 132 | qla2x00_clean_dsd_pool(struct qla_hw_data *ha, srb_t *sp, |
133 | struct qla_tgt_cmd *tc) | ||
132 | { | 134 | { |
133 | struct dsd_dma *dsd_ptr, *tdsd_ptr; | 135 | struct dsd_dma *dsd_ptr, *tdsd_ptr; |
134 | struct crc_context *ctx; | 136 | struct crc_context *ctx; |
135 | 137 | ||
136 | ctx = (struct crc_context *)GET_CMD_CTX_SP(sp); | 138 | if (sp) |
139 | ctx = (struct crc_context *)GET_CMD_CTX_SP(sp); | ||
140 | else if (tc) | ||
141 | ctx = (struct crc_context *)tc->ctx; | ||
142 | else { | ||
143 | BUG(); | ||
144 | return; | ||
145 | } | ||
137 | 146 | ||
138 | /* clean up allocated prev pool */ | 147 | /* clean up allocated prev pool */ |
139 | list_for_each_entry_safe(dsd_ptr, tdsd_ptr, | 148 | list_for_each_entry_safe(dsd_ptr, tdsd_ptr, |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index e607568bce49..760931529592 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -936,9 +936,9 @@ qla24xx_get_one_block_sg(uint32_t blk_sz, struct qla2_sgx *sgx, | |||
936 | return 1; | 936 | return 1; |
937 | } | 937 | } |
938 | 938 | ||
939 | static int | 939 | int |
940 | qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp, | 940 | qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp, |
941 | uint32_t *dsd, uint16_t tot_dsds) | 941 | uint32_t *dsd, uint16_t tot_dsds, struct qla_tgt_cmd *tc) |
942 | { | 942 | { |
943 | void *next_dsd; | 943 | void *next_dsd; |
944 | uint8_t avail_dsds = 0; | 944 | uint8_t avail_dsds = 0; |
@@ -948,21 +948,35 @@ qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *ha, srb_t *sp, | |||
948 | uint32_t *cur_dsd = dsd; | 948 | uint32_t *cur_dsd = dsd; |
949 | uint16_t used_dsds = tot_dsds; | 949 | uint16_t used_dsds = tot_dsds; |
950 | 950 | ||
951 | uint32_t prot_int; | 951 | uint32_t prot_int; /* protection interval */ |
952 | uint32_t partial; | 952 | uint32_t partial; |
953 | struct qla2_sgx sgx; | 953 | struct qla2_sgx sgx; |
954 | dma_addr_t sle_dma; | 954 | dma_addr_t sle_dma; |
955 | uint32_t sle_dma_len, tot_prot_dma_len = 0; | 955 | uint32_t sle_dma_len, tot_prot_dma_len = 0; |
956 | struct scsi_cmnd *cmd = GET_CMD_SP(sp); | 956 | struct scsi_cmnd *cmd; |
957 | 957 | struct scsi_qla_host *vha; | |
958 | prot_int = cmd->device->sector_size; | ||
959 | 958 | ||
960 | memset(&sgx, 0, sizeof(struct qla2_sgx)); | 959 | memset(&sgx, 0, sizeof(struct qla2_sgx)); |
961 | sgx.tot_bytes = scsi_bufflen(cmd); | 960 | if (sp) { |
962 | sgx.cur_sg = scsi_sglist(cmd); | 961 | vha = sp->fcport->vha; |
963 | sgx.sp = sp; | 962 | cmd = GET_CMD_SP(sp); |
964 | 963 | prot_int = cmd->device->sector_size; | |
965 | sg_prot = scsi_prot_sglist(cmd); | 964 | |
965 | sgx.tot_bytes = scsi_bufflen(cmd); | ||
966 | sgx.cur_sg = scsi_sglist(cmd); | ||
967 | sgx.sp = sp; | ||
968 | |||
969 | sg_prot = scsi_prot_sglist(cmd); | ||
970 | } else if (tc) { | ||
971 | vha = tc->vha; | ||
972 | prot_int = tc->blk_sz; | ||
973 | sgx.tot_bytes = tc->bufflen; | ||
974 | sgx.cur_sg = tc->sg; | ||
975 | sg_prot = tc->prot_sg; | ||
976 | } else { | ||
977 | BUG(); | ||
978 | return 1; | ||
979 | } | ||
966 | 980 | ||
967 | while (qla24xx_get_one_block_sg(prot_int, &sgx, &partial)) { | 981 | while (qla24xx_get_one_block_sg(prot_int, &sgx, &partial)) { |
968 | 982 | ||
@@ -995,10 +1009,18 @@ alloc_and_fill: | |||
995 | return 1; | 1009 | return 1; |
996 | } | 1010 | } |
997 | 1011 | ||
998 | list_add_tail(&dsd_ptr->list, | 1012 | if (sp) { |
999 | &((struct crc_context *)sp->u.scmd.ctx)->dsd_list); | 1013 | list_add_tail(&dsd_ptr->list, |
1014 | &((struct crc_context *) | ||
1015 | sp->u.scmd.ctx)->dsd_list); | ||
1016 | |||
1017 | sp->flags |= SRB_CRC_CTX_DSD_VALID; | ||
1018 | } else { | ||
1019 | list_add_tail(&dsd_ptr->list, | ||
1020 | &(tc->ctx->dsd_list)); | ||
1021 | tc->ctx_dsd_alloced = 1; | ||
1022 | } | ||
1000 | 1023 | ||
1001 | sp->flags |= SRB_CRC_CTX_DSD_VALID; | ||
1002 | 1024 | ||
1003 | /* add new list to cmd iocb or last list */ | 1025 | /* add new list to cmd iocb or last list */ |
1004 | *cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); | 1026 | *cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); |
@@ -1033,21 +1055,35 @@ alloc_and_fill: | |||
1033 | return 0; | 1055 | return 0; |
1034 | } | 1056 | } |
1035 | 1057 | ||
1036 | static int | 1058 | int |
1037 | qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, | 1059 | qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, |
1038 | uint16_t tot_dsds) | 1060 | uint16_t tot_dsds, struct qla_tgt_cmd *tc) |
1039 | { | 1061 | { |
1040 | void *next_dsd; | 1062 | void *next_dsd; |
1041 | uint8_t avail_dsds = 0; | 1063 | uint8_t avail_dsds = 0; |
1042 | uint32_t dsd_list_len; | 1064 | uint32_t dsd_list_len; |
1043 | struct dsd_dma *dsd_ptr; | 1065 | struct dsd_dma *dsd_ptr; |
1044 | struct scatterlist *sg; | 1066 | struct scatterlist *sg, *sgl; |
1045 | uint32_t *cur_dsd = dsd; | 1067 | uint32_t *cur_dsd = dsd; |
1046 | int i; | 1068 | int i; |
1047 | uint16_t used_dsds = tot_dsds; | 1069 | uint16_t used_dsds = tot_dsds; |
1048 | struct scsi_cmnd *cmd = GET_CMD_SP(sp); | 1070 | struct scsi_cmnd *cmd; |
1071 | struct scsi_qla_host *vha; | ||
1072 | |||
1073 | if (sp) { | ||
1074 | cmd = GET_CMD_SP(sp); | ||
1075 | sgl = scsi_sglist(cmd); | ||
1076 | vha = sp->fcport->vha; | ||
1077 | } else if (tc) { | ||
1078 | sgl = tc->sg; | ||
1079 | vha = tc->vha; | ||
1080 | } else { | ||
1081 | BUG(); | ||
1082 | return 1; | ||
1083 | } | ||
1049 | 1084 | ||
1050 | scsi_for_each_sg(cmd, sg, tot_dsds, i) { | 1085 | |
1086 | for_each_sg(sgl, sg, tot_dsds, i) { | ||
1051 | dma_addr_t sle_dma; | 1087 | dma_addr_t sle_dma; |
1052 | 1088 | ||
1053 | /* Allocate additional continuation packets? */ | 1089 | /* Allocate additional continuation packets? */ |
@@ -1076,10 +1112,17 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, | |||
1076 | return 1; | 1112 | return 1; |
1077 | } | 1113 | } |
1078 | 1114 | ||
1079 | list_add_tail(&dsd_ptr->list, | 1115 | if (sp) { |
1080 | &((struct crc_context *)sp->u.scmd.ctx)->dsd_list); | 1116 | list_add_tail(&dsd_ptr->list, |
1117 | &((struct crc_context *) | ||
1118 | sp->u.scmd.ctx)->dsd_list); | ||
1081 | 1119 | ||
1082 | sp->flags |= SRB_CRC_CTX_DSD_VALID; | 1120 | sp->flags |= SRB_CRC_CTX_DSD_VALID; |
1121 | } else { | ||
1122 | list_add_tail(&dsd_ptr->list, | ||
1123 | &(tc->ctx->dsd_list)); | ||
1124 | tc->ctx_dsd_alloced = 1; | ||
1125 | } | ||
1083 | 1126 | ||
1084 | /* add new list to cmd iocb or last list */ | 1127 | /* add new list to cmd iocb or last list */ |
1085 | *cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); | 1128 | *cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); |
@@ -1102,23 +1145,37 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp, uint32_t *dsd, | |||
1102 | return 0; | 1145 | return 0; |
1103 | } | 1146 | } |
1104 | 1147 | ||
1105 | static int | 1148 | int |
1106 | qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, | 1149 | qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, |
1107 | uint32_t *dsd, | 1150 | uint32_t *dsd, uint16_t tot_dsds, struct qla_tgt_cmd *tc) |
1108 | uint16_t tot_dsds) | ||
1109 | { | 1151 | { |
1110 | void *next_dsd; | 1152 | void *next_dsd; |
1111 | uint8_t avail_dsds = 0; | 1153 | uint8_t avail_dsds = 0; |
1112 | uint32_t dsd_list_len; | 1154 | uint32_t dsd_list_len; |
1113 | struct dsd_dma *dsd_ptr; | 1155 | struct dsd_dma *dsd_ptr; |
1114 | struct scatterlist *sg; | 1156 | struct scatterlist *sg, *sgl; |
1115 | int i; | 1157 | int i; |
1116 | struct scsi_cmnd *cmd; | 1158 | struct scsi_cmnd *cmd; |
1117 | uint32_t *cur_dsd = dsd; | 1159 | uint32_t *cur_dsd = dsd; |
1118 | uint16_t used_dsds = tot_dsds; | 1160 | uint16_t used_dsds = tot_dsds; |
1161 | struct scsi_qla_host *vha; | ||
1162 | |||
1163 | if (sp) { | ||
1164 | cmd = GET_CMD_SP(sp); | ||
1165 | sgl = scsi_prot_sglist(cmd); | ||
1166 | vha = sp->fcport->vha; | ||
1167 | } else if (tc) { | ||
1168 | vha = tc->vha; | ||
1169 | sgl = tc->prot_sg; | ||
1170 | } else { | ||
1171 | BUG(); | ||
1172 | return 1; | ||
1173 | } | ||
1119 | 1174 | ||
1120 | cmd = GET_CMD_SP(sp); | 1175 | ql_dbg(ql_dbg_tgt, vha, 0xe021, |
1121 | scsi_for_each_prot_sg(cmd, sg, tot_dsds, i) { | 1176 | "%s: enter\n", __func__); |
1177 | |||
1178 | for_each_sg(sgl, sg, tot_dsds, i) { | ||
1122 | dma_addr_t sle_dma; | 1179 | dma_addr_t sle_dma; |
1123 | 1180 | ||
1124 | /* Allocate additional continuation packets? */ | 1181 | /* Allocate additional continuation packets? */ |
@@ -1147,10 +1204,17 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp, | |||
1147 | return 1; | 1204 | return 1; |
1148 | } | 1205 | } |
1149 | 1206 | ||
1150 | list_add_tail(&dsd_ptr->list, | 1207 | if (sp) { |
1151 | &((struct crc_context *)sp->u.scmd.ctx)->dsd_list); | 1208 | list_add_tail(&dsd_ptr->list, |
1209 | &((struct crc_context *) | ||
1210 | sp->u.scmd.ctx)->dsd_list); | ||
1152 | 1211 | ||
1153 | sp->flags |= SRB_CRC_CTX_DSD_VALID; | 1212 | sp->flags |= SRB_CRC_CTX_DSD_VALID; |
1213 | } else { | ||
1214 | list_add_tail(&dsd_ptr->list, | ||
1215 | &(tc->ctx->dsd_list)); | ||
1216 | tc->ctx_dsd_alloced = 1; | ||
1217 | } | ||
1154 | 1218 | ||
1155 | /* add new list to cmd iocb or last list */ | 1219 | /* add new list to cmd iocb or last list */ |
1156 | *cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); | 1220 | *cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma)); |
@@ -1386,10 +1450,10 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
1386 | 1450 | ||
1387 | if (!bundling && tot_prot_dsds) { | 1451 | if (!bundling && tot_prot_dsds) { |
1388 | if (qla24xx_walk_and_build_sglist_no_difb(ha, sp, | 1452 | if (qla24xx_walk_and_build_sglist_no_difb(ha, sp, |
1389 | cur_dsd, tot_dsds)) | 1453 | cur_dsd, tot_dsds, NULL)) |
1390 | goto crc_queuing_error; | 1454 | goto crc_queuing_error; |
1391 | } else if (qla24xx_walk_and_build_sglist(ha, sp, cur_dsd, | 1455 | } else if (qla24xx_walk_and_build_sglist(ha, sp, cur_dsd, |
1392 | (tot_dsds - tot_prot_dsds))) | 1456 | (tot_dsds - tot_prot_dsds), NULL)) |
1393 | goto crc_queuing_error; | 1457 | goto crc_queuing_error; |
1394 | 1458 | ||
1395 | if (bundling && tot_prot_dsds) { | 1459 | if (bundling && tot_prot_dsds) { |
@@ -1398,7 +1462,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
1398 | __constant_cpu_to_le16(CF_DIF_SEG_DESCR_ENABLE); | 1462 | __constant_cpu_to_le16(CF_DIF_SEG_DESCR_ENABLE); |
1399 | cur_dsd = (uint32_t *) &crc_ctx_pkt->u.bundling.dif_address; | 1463 | cur_dsd = (uint32_t *) &crc_ctx_pkt->u.bundling.dif_address; |
1400 | if (qla24xx_walk_and_build_prot_sglist(ha, sp, cur_dsd, | 1464 | if (qla24xx_walk_and_build_prot_sglist(ha, sp, cur_dsd, |
1401 | tot_prot_dsds)) | 1465 | tot_prot_dsds, NULL)) |
1402 | goto crc_queuing_error; | 1466 | goto crc_queuing_error; |
1403 | } | 1467 | } |
1404 | return QLA_SUCCESS; | 1468 | return QLA_SUCCESS; |
@@ -1478,8 +1542,8 @@ qla24xx_start_scsi(srb_t *sp) | |||
1478 | tot_dsds = nseg; | 1542 | tot_dsds = nseg; |
1479 | req_cnt = qla24xx_calc_iocbs(vha, tot_dsds); | 1543 | req_cnt = qla24xx_calc_iocbs(vha, tot_dsds); |
1480 | if (req->cnt < (req_cnt + 2)) { | 1544 | if (req->cnt < (req_cnt + 2)) { |
1481 | cnt = RD_REG_DWORD_RELAXED(req->req_q_out); | 1545 | cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr : |
1482 | 1546 | RD_REG_DWORD_RELAXED(req->req_q_out); | |
1483 | if (req->ring_index < cnt) | 1547 | if (req->ring_index < cnt) |
1484 | req->cnt = cnt - req->ring_index; | 1548 | req->cnt = cnt - req->ring_index; |
1485 | else | 1549 | else |
@@ -1697,8 +1761,8 @@ qla24xx_dif_start_scsi(srb_t *sp) | |||
1697 | tot_prot_dsds = nseg; | 1761 | tot_prot_dsds = nseg; |
1698 | tot_dsds += nseg; | 1762 | tot_dsds += nseg; |
1699 | if (req->cnt < (req_cnt + 2)) { | 1763 | if (req->cnt < (req_cnt + 2)) { |
1700 | cnt = RD_REG_DWORD_RELAXED(req->req_q_out); | 1764 | cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr : |
1701 | 1765 | RD_REG_DWORD_RELAXED(req->req_q_out); | |
1702 | if (req->ring_index < cnt) | 1766 | if (req->ring_index < cnt) |
1703 | req->cnt = cnt - req->ring_index; | 1767 | req->cnt = cnt - req->ring_index; |
1704 | else | 1768 | else |
@@ -2825,8 +2889,8 @@ qla2x00_start_bidir(srb_t *sp, struct scsi_qla_host *vha, uint32_t tot_dsds) | |||
2825 | 2889 | ||
2826 | /* Check for room on request queue. */ | 2890 | /* Check for room on request queue. */ |
2827 | if (req->cnt < req_cnt + 2) { | 2891 | if (req->cnt < req_cnt + 2) { |
2828 | cnt = RD_REG_DWORD_RELAXED(req->req_q_out); | 2892 | cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr : |
2829 | 2893 | RD_REG_DWORD_RELAXED(req->req_q_out); | |
2830 | if (req->ring_index < cnt) | 2894 | if (req->ring_index < cnt) |
2831 | req->cnt = cnt - req->ring_index; | 2895 | req->cnt = cnt - req->ring_index; |
2832 | else | 2896 | else |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 95314ef2e505..a56825c73c31 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -2009,11 +2009,13 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) | |||
2009 | ql_dbg(ql_dbg_io, vha, 0x3017, | 2009 | ql_dbg(ql_dbg_io, vha, 0x3017, |
2010 | "Invalid status handle (0x%x).\n", sts->handle); | 2010 | "Invalid status handle (0x%x).\n", sts->handle); |
2011 | 2011 | ||
2012 | if (IS_P3P_TYPE(ha)) | 2012 | if (!test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) { |
2013 | set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags); | 2013 | if (IS_P3P_TYPE(ha)) |
2014 | else | 2014 | set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags); |
2015 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); | 2015 | else |
2016 | qla2xxx_wake_dpc(vha); | 2016 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); |
2017 | qla2xxx_wake_dpc(vha); | ||
2018 | } | ||
2017 | return; | 2019 | return; |
2018 | } | 2020 | } |
2019 | 2021 | ||
@@ -2472,12 +2474,14 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, | |||
2472 | if (pkt->entry_status != 0) { | 2474 | if (pkt->entry_status != 0) { |
2473 | qla2x00_error_entry(vha, rsp, (sts_entry_t *) pkt); | 2475 | qla2x00_error_entry(vha, rsp, (sts_entry_t *) pkt); |
2474 | 2476 | ||
2475 | (void)qlt_24xx_process_response_error(vha, pkt); | 2477 | if (qlt_24xx_process_response_error(vha, pkt)) |
2478 | goto process_err; | ||
2476 | 2479 | ||
2477 | ((response_t *)pkt)->signature = RESPONSE_PROCESSED; | 2480 | ((response_t *)pkt)->signature = RESPONSE_PROCESSED; |
2478 | wmb(); | 2481 | wmb(); |
2479 | continue; | 2482 | continue; |
2480 | } | 2483 | } |
2484 | process_err: | ||
2481 | 2485 | ||
2482 | switch (pkt->entry_type) { | 2486 | switch (pkt->entry_type) { |
2483 | case STATUS_TYPE: | 2487 | case STATUS_TYPE: |
@@ -2494,10 +2498,10 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, | |||
2494 | qla24xx_logio_entry(vha, rsp->req, | 2498 | qla24xx_logio_entry(vha, rsp->req, |
2495 | (struct logio_entry_24xx *)pkt); | 2499 | (struct logio_entry_24xx *)pkt); |
2496 | break; | 2500 | break; |
2497 | case CT_IOCB_TYPE: | 2501 | case CT_IOCB_TYPE: |
2498 | qla24xx_els_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE); | 2502 | qla24xx_els_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE); |
2499 | break; | 2503 | break; |
2500 | case ELS_IOCB_TYPE: | 2504 | case ELS_IOCB_TYPE: |
2501 | qla24xx_els_ct_entry(vha, rsp->req, pkt, ELS_IOCB_TYPE); | 2505 | qla24xx_els_ct_entry(vha, rsp->req, pkt, ELS_IOCB_TYPE); |
2502 | break; | 2506 | break; |
2503 | case ABTS_RECV_24XX: | 2507 | case ABTS_RECV_24XX: |
@@ -2506,6 +2510,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, | |||
2506 | case ABTS_RESP_24XX: | 2510 | case ABTS_RESP_24XX: |
2507 | case CTIO_TYPE7: | 2511 | case CTIO_TYPE7: |
2508 | case NOTIFY_ACK_TYPE: | 2512 | case NOTIFY_ACK_TYPE: |
2513 | case CTIO_CRC2: | ||
2509 | qlt_response_pkt_all_vps(vha, (response_t *)pkt); | 2514 | qlt_response_pkt_all_vps(vha, (response_t *)pkt); |
2510 | break; | 2515 | break; |
2511 | case MARKER_TYPE: | 2516 | case MARKER_TYPE: |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 2528709c4add..1c33a77db5c2 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -1319,7 +1319,7 @@ qla2x00_get_node_name_list(scsi_qla_host_t *vha, void **out_data, int *out_len) | |||
1319 | 1319 | ||
1320 | left = 0; | 1320 | left = 0; |
1321 | 1321 | ||
1322 | list = kzalloc(dma_size, GFP_KERNEL); | 1322 | list = kmemdup(pmap, dma_size, GFP_KERNEL); |
1323 | if (!list) { | 1323 | if (!list) { |
1324 | ql_log(ql_log_warn, vha, 0x1140, | 1324 | ql_log(ql_log_warn, vha, 0x1140, |
1325 | "%s(%ld): failed to allocate node names list " | 1325 | "%s(%ld): failed to allocate node names list " |
@@ -1328,7 +1328,6 @@ qla2x00_get_node_name_list(scsi_qla_host_t *vha, void **out_data, int *out_len) | |||
1328 | goto out_free; | 1328 | goto out_free; |
1329 | } | 1329 | } |
1330 | 1330 | ||
1331 | memcpy(list, pmap, dma_size); | ||
1332 | restart: | 1331 | restart: |
1333 | dma_free_coherent(&ha->pdev->dev, dma_size, pmap, pmap_dma); | 1332 | dma_free_coherent(&ha->pdev->dev, dma_size, pmap, pmap_dma); |
1334 | } | 1333 | } |
@@ -2644,7 +2643,10 @@ qla24xx_abort_command(srb_t *sp) | |||
2644 | ql_dbg(ql_dbg_mbx, vha, 0x1090, | 2643 | ql_dbg(ql_dbg_mbx, vha, 0x1090, |
2645 | "Failed to complete IOCB -- completion status (%x).\n", | 2644 | "Failed to complete IOCB -- completion status (%x).\n", |
2646 | le16_to_cpu(abt->nport_handle)); | 2645 | le16_to_cpu(abt->nport_handle)); |
2647 | rval = QLA_FUNCTION_FAILED; | 2646 | if (abt->nport_handle == CS_IOCB_ERROR) |
2647 | rval = QLA_FUNCTION_PARAMETER_ERROR; | ||
2648 | else | ||
2649 | rval = QLA_FUNCTION_FAILED; | ||
2648 | } else { | 2650 | } else { |
2649 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1091, | 2651 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1091, |
2650 | "Done %s.\n", __func__); | 2652 | "Done %s.\n", __func__); |
@@ -2879,6 +2881,78 @@ qla2x00_read_serdes_word(scsi_qla_host_t *vha, uint16_t addr, uint16_t *data) | |||
2879 | return rval; | 2881 | return rval; |
2880 | } | 2882 | } |
2881 | 2883 | ||
2884 | int | ||
2885 | qla8044_write_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t data) | ||
2886 | { | ||
2887 | int rval; | ||
2888 | mbx_cmd_t mc; | ||
2889 | mbx_cmd_t *mcp = &mc; | ||
2890 | |||
2891 | if (!IS_QLA8044(vha->hw)) | ||
2892 | return QLA_FUNCTION_FAILED; | ||
2893 | |||
2894 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1186, | ||
2895 | "Entered %s.\n", __func__); | ||
2896 | |||
2897 | mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG; | ||
2898 | mcp->mb[1] = HCS_WRITE_SERDES; | ||
2899 | mcp->mb[3] = LSW(addr); | ||
2900 | mcp->mb[4] = MSW(addr); | ||
2901 | mcp->mb[5] = LSW(data); | ||
2902 | mcp->mb[6] = MSW(data); | ||
2903 | mcp->out_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_1|MBX_0; | ||
2904 | mcp->in_mb = MBX_0; | ||
2905 | mcp->tov = MBX_TOV_SECONDS; | ||
2906 | mcp->flags = 0; | ||
2907 | rval = qla2x00_mailbox_command(vha, mcp); | ||
2908 | |||
2909 | if (rval != QLA_SUCCESS) { | ||
2910 | ql_dbg(ql_dbg_mbx, vha, 0x1187, | ||
2911 | "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); | ||
2912 | } else { | ||
2913 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1188, | ||
2914 | "Done %s.\n", __func__); | ||
2915 | } | ||
2916 | |||
2917 | return rval; | ||
2918 | } | ||
2919 | |||
2920 | int | ||
2921 | qla8044_read_serdes_word(scsi_qla_host_t *vha, uint32_t addr, uint32_t *data) | ||
2922 | { | ||
2923 | int rval; | ||
2924 | mbx_cmd_t mc; | ||
2925 | mbx_cmd_t *mcp = &mc; | ||
2926 | |||
2927 | if (!IS_QLA8044(vha->hw)) | ||
2928 | return QLA_FUNCTION_FAILED; | ||
2929 | |||
2930 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1189, | ||
2931 | "Entered %s.\n", __func__); | ||
2932 | |||
2933 | mcp->mb[0] = MBC_SET_GET_ETH_SERDES_REG; | ||
2934 | mcp->mb[1] = HCS_READ_SERDES; | ||
2935 | mcp->mb[3] = LSW(addr); | ||
2936 | mcp->mb[4] = MSW(addr); | ||
2937 | mcp->out_mb = MBX_4|MBX_3|MBX_1|MBX_0; | ||
2938 | mcp->in_mb = MBX_2|MBX_1|MBX_0; | ||
2939 | mcp->tov = MBX_TOV_SECONDS; | ||
2940 | mcp->flags = 0; | ||
2941 | rval = qla2x00_mailbox_command(vha, mcp); | ||
2942 | |||
2943 | *data = mcp->mb[2] << 16 | mcp->mb[1]; | ||
2944 | |||
2945 | if (rval != QLA_SUCCESS) { | ||
2946 | ql_dbg(ql_dbg_mbx, vha, 0x118a, | ||
2947 | "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]); | ||
2948 | } else { | ||
2949 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118b, | ||
2950 | "Done %s.\n", __func__); | ||
2951 | } | ||
2952 | |||
2953 | return rval; | ||
2954 | } | ||
2955 | |||
2882 | /** | 2956 | /** |
2883 | * qla2x00_set_serdes_params() - | 2957 | * qla2x00_set_serdes_params() - |
2884 | * @ha: HA context | 2958 | * @ha: HA context |
@@ -3660,6 +3734,9 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req) | |||
3660 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d3, | 3734 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d3, |
3661 | "Entered %s.\n", __func__); | 3735 | "Entered %s.\n", __func__); |
3662 | 3736 | ||
3737 | if (IS_SHADOW_REG_CAPABLE(ha)) | ||
3738 | req->options |= BIT_13; | ||
3739 | |||
3663 | mcp->mb[0] = MBC_INITIALIZE_MULTIQ; | 3740 | mcp->mb[0] = MBC_INITIALIZE_MULTIQ; |
3664 | mcp->mb[1] = req->options; | 3741 | mcp->mb[1] = req->options; |
3665 | mcp->mb[2] = MSW(LSD(req->dma)); | 3742 | mcp->mb[2] = MSW(LSD(req->dma)); |
@@ -3679,7 +3756,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req) | |||
3679 | /* que in ptr index */ | 3756 | /* que in ptr index */ |
3680 | mcp->mb[8] = 0; | 3757 | mcp->mb[8] = 0; |
3681 | /* que out ptr index */ | 3758 | /* que out ptr index */ |
3682 | mcp->mb[9] = 0; | 3759 | mcp->mb[9] = *req->out_ptr = 0; |
3683 | mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7| | 3760 | mcp->out_mb = MBX_14|MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8|MBX_7| |
3684 | MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; | 3761 | MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; |
3685 | mcp->in_mb = MBX_0; | 3762 | mcp->in_mb = MBX_0; |
@@ -3688,7 +3765,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req) | |||
3688 | 3765 | ||
3689 | if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha)) | 3766 | if (IS_QLA81XX(ha) || IS_QLA83XX(ha) || IS_QLA27XX(ha)) |
3690 | mcp->in_mb |= MBX_1; | 3767 | mcp->in_mb |= MBX_1; |
3691 | if (IS_QLA83XX(ha) || !IS_QLA27XX(ha)) { | 3768 | if (IS_QLA83XX(ha) || IS_QLA27XX(ha)) { |
3692 | mcp->out_mb |= MBX_15; | 3769 | mcp->out_mb |= MBX_15; |
3693 | /* debug q create issue in SR-IOV */ | 3770 | /* debug q create issue in SR-IOV */ |
3694 | mcp->in_mb |= MBX_9 | MBX_8 | MBX_7; | 3771 | mcp->in_mb |= MBX_9 | MBX_8 | MBX_7; |
@@ -3697,7 +3774,7 @@ qla25xx_init_req_que(struct scsi_qla_host *vha, struct req_que *req) | |||
3697 | spin_lock_irqsave(&ha->hardware_lock, flags); | 3774 | spin_lock_irqsave(&ha->hardware_lock, flags); |
3698 | if (!(req->options & BIT_0)) { | 3775 | if (!(req->options & BIT_0)) { |
3699 | WRT_REG_DWORD(req->req_q_in, 0); | 3776 | WRT_REG_DWORD(req->req_q_in, 0); |
3700 | if (!IS_QLA83XX(ha) || !IS_QLA27XX(ha)) | 3777 | if (!IS_QLA83XX(ha) && !IS_QLA27XX(ha)) |
3701 | WRT_REG_DWORD(req->req_q_out, 0); | 3778 | WRT_REG_DWORD(req->req_q_out, 0); |
3702 | } | 3779 | } |
3703 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 3780 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
@@ -3726,6 +3803,9 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) | |||
3726 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d6, | 3803 | ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10d6, |
3727 | "Entered %s.\n", __func__); | 3804 | "Entered %s.\n", __func__); |
3728 | 3805 | ||
3806 | if (IS_SHADOW_REG_CAPABLE(ha)) | ||
3807 | rsp->options |= BIT_13; | ||
3808 | |||
3729 | mcp->mb[0] = MBC_INITIALIZE_MULTIQ; | 3809 | mcp->mb[0] = MBC_INITIALIZE_MULTIQ; |
3730 | mcp->mb[1] = rsp->options; | 3810 | mcp->mb[1] = rsp->options; |
3731 | mcp->mb[2] = MSW(LSD(rsp->dma)); | 3811 | mcp->mb[2] = MSW(LSD(rsp->dma)); |
@@ -3740,7 +3820,7 @@ qla25xx_init_rsp_que(struct scsi_qla_host *vha, struct rsp_que *rsp) | |||
3740 | 3820 | ||
3741 | mcp->mb[4] = rsp->id; | 3821 | mcp->mb[4] = rsp->id; |
3742 | /* que in ptr index */ | 3822 | /* que in ptr index */ |
3743 | mcp->mb[8] = 0; | 3823 | mcp->mb[8] = *rsp->in_ptr = 0; |
3744 | /* que out ptr index */ | 3824 | /* que out ptr index */ |
3745 | mcp->mb[9] = 0; | 3825 | mcp->mb[9] = 0; |
3746 | mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7 | 3826 | mcp->out_mb = MBX_14|MBX_13|MBX_9|MBX_8|MBX_7 |
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index f0a852257f99..89998244f48d 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_mr.c b/drivers/scsi/qla2xxx/qla_mr.c index 0aaf6a9c87d3..abeb3901498b 100644 --- a/drivers/scsi/qla2xxx/qla_mr.c +++ b/drivers/scsi/qla2xxx/qla_mr.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -527,21 +527,63 @@ qlafx00_soc_cpu_reset(scsi_qla_host_t *vha) | |||
527 | struct qla_hw_data *ha = vha->hw; | 527 | struct qla_hw_data *ha = vha->hw; |
528 | int i, core; | 528 | int i, core; |
529 | uint32_t cnt; | 529 | uint32_t cnt; |
530 | uint32_t reg_val; | ||
531 | |||
532 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
533 | |||
534 | QLAFX00_SET_HBA_SOC_REG(ha, 0x80004, 0); | ||
535 | QLAFX00_SET_HBA_SOC_REG(ha, 0x82004, 0); | ||
536 | |||
537 | /* stop the XOR DMA engines */ | ||
538 | QLAFX00_SET_HBA_SOC_REG(ha, 0x60920, 0x02); | ||
539 | QLAFX00_SET_HBA_SOC_REG(ha, 0x60924, 0x02); | ||
540 | QLAFX00_SET_HBA_SOC_REG(ha, 0xf0920, 0x02); | ||
541 | QLAFX00_SET_HBA_SOC_REG(ha, 0xf0924, 0x02); | ||
542 | |||
543 | /* stop the IDMA engines */ | ||
544 | reg_val = QLAFX00_GET_HBA_SOC_REG(ha, 0x60840); | ||
545 | reg_val &= ~(1<<12); | ||
546 | QLAFX00_SET_HBA_SOC_REG(ha, 0x60840, reg_val); | ||
547 | |||
548 | reg_val = QLAFX00_GET_HBA_SOC_REG(ha, 0x60844); | ||
549 | reg_val &= ~(1<<12); | ||
550 | QLAFX00_SET_HBA_SOC_REG(ha, 0x60844, reg_val); | ||
551 | |||
552 | reg_val = QLAFX00_GET_HBA_SOC_REG(ha, 0x60848); | ||
553 | reg_val &= ~(1<<12); | ||
554 | QLAFX00_SET_HBA_SOC_REG(ha, 0x60848, reg_val); | ||
555 | |||
556 | reg_val = QLAFX00_GET_HBA_SOC_REG(ha, 0x6084C); | ||
557 | reg_val &= ~(1<<12); | ||
558 | QLAFX00_SET_HBA_SOC_REG(ha, 0x6084C, reg_val); | ||
559 | |||
560 | for (i = 0; i < 100000; i++) { | ||
561 | if ((QLAFX00_GET_HBA_SOC_REG(ha, 0xd0000) & 0x10000000) == 0 && | ||
562 | (QLAFX00_GET_HBA_SOC_REG(ha, 0x10600) & 0x1) == 0) | ||
563 | break; | ||
564 | udelay(100); | ||
565 | } | ||
530 | 566 | ||
531 | /* Set all 4 cores in reset */ | 567 | /* Set all 4 cores in reset */ |
532 | for (i = 0; i < 4; i++) { | 568 | for (i = 0; i < 4; i++) { |
533 | QLAFX00_SET_HBA_SOC_REG(ha, | 569 | QLAFX00_SET_HBA_SOC_REG(ha, |
534 | (SOC_SW_RST_CONTROL_REG_CORE0 + 8*i), (0xF01)); | 570 | (SOC_SW_RST_CONTROL_REG_CORE0 + 8*i), (0xF01)); |
535 | } | ||
536 | |||
537 | /* Set all 4 core Clock gating control */ | ||
538 | for (i = 0; i < 4; i++) { | ||
539 | QLAFX00_SET_HBA_SOC_REG(ha, | 571 | QLAFX00_SET_HBA_SOC_REG(ha, |
540 | (SOC_SW_RST_CONTROL_REG_CORE0 + 4 + 8*i), (0x01010101)); | 572 | (SOC_SW_RST_CONTROL_REG_CORE0 + 4 + 8*i), (0x01010101)); |
541 | } | 573 | } |
542 | 574 | ||
543 | /* Reset all units in Fabric */ | 575 | /* Reset all units in Fabric */ |
544 | QLAFX00_SET_HBA_SOC_REG(ha, SOC_FABRIC_RST_CONTROL_REG, (0x11F0101)); | 576 | QLAFX00_SET_HBA_SOC_REG(ha, SOC_FABRIC_RST_CONTROL_REG, (0x011f0101)); |
577 | |||
578 | /* */ | ||
579 | QLAFX00_SET_HBA_SOC_REG(ha, 0x10610, 1); | ||
580 | QLAFX00_SET_HBA_SOC_REG(ha, 0x10600, 0); | ||
581 | |||
582 | /* Set all 4 core Memory Power Down Registers */ | ||
583 | for (i = 0; i < 5; i++) { | ||
584 | QLAFX00_SET_HBA_SOC_REG(ha, | ||
585 | (SOC_PWR_MANAGEMENT_PWR_DOWN_REG + 4*i), (0x0)); | ||
586 | } | ||
545 | 587 | ||
546 | /* Reset all interrupt control registers */ | 588 | /* Reset all interrupt control registers */ |
547 | for (i = 0; i < 115; i++) { | 589 | for (i = 0; i < 115; i++) { |
@@ -564,20 +606,19 @@ qlafx00_soc_cpu_reset(scsi_qla_host_t *vha) | |||
564 | QLAFX00_SET_HBA_SOC_REG(ha, SOC_FABRIC_CONTROL_REG, (0x2)); | 606 | QLAFX00_SET_HBA_SOC_REG(ha, SOC_FABRIC_CONTROL_REG, (0x2)); |
565 | QLAFX00_SET_HBA_SOC_REG(ha, SOC_FABRIC_CONFIG_REG, (0x3)); | 607 | QLAFX00_SET_HBA_SOC_REG(ha, SOC_FABRIC_CONFIG_REG, (0x3)); |
566 | 608 | ||
567 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
568 | |||
569 | /* Kick in Fabric units */ | 609 | /* Kick in Fabric units */ |
570 | QLAFX00_SET_HBA_SOC_REG(ha, SOC_FABRIC_RST_CONTROL_REG, (0x0)); | 610 | QLAFX00_SET_HBA_SOC_REG(ha, SOC_FABRIC_RST_CONTROL_REG, (0x0)); |
571 | 611 | ||
572 | /* Kick in Core0 to start boot process */ | 612 | /* Kick in Core0 to start boot process */ |
573 | QLAFX00_SET_HBA_SOC_REG(ha, SOC_SW_RST_CONTROL_REG_CORE0, (0xF00)); | 613 | QLAFX00_SET_HBA_SOC_REG(ha, SOC_SW_RST_CONTROL_REG_CORE0, (0xF00)); |
574 | 614 | ||
615 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
616 | |||
575 | /* Wait 10secs for soft-reset to complete. */ | 617 | /* Wait 10secs for soft-reset to complete. */ |
576 | for (cnt = 10; cnt; cnt--) { | 618 | for (cnt = 10; cnt; cnt--) { |
577 | msleep(1000); | 619 | msleep(1000); |
578 | barrier(); | 620 | barrier(); |
579 | } | 621 | } |
580 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
581 | } | 622 | } |
582 | 623 | ||
583 | /** | 624 | /** |
@@ -597,7 +638,6 @@ qlafx00_soft_reset(scsi_qla_host_t *vha) | |||
597 | 638 | ||
598 | ha->isp_ops->disable_intrs(ha); | 639 | ha->isp_ops->disable_intrs(ha); |
599 | qlafx00_soc_cpu_reset(vha); | 640 | qlafx00_soc_cpu_reset(vha); |
600 | ha->isp_ops->enable_intrs(ha); | ||
601 | } | 641 | } |
602 | 642 | ||
603 | /** | 643 | /** |
@@ -2675,7 +2715,7 @@ qlafx00_process_response_queue(struct scsi_qla_host *vha, | |||
2675 | uint16_t lreq_q_out = 0; | 2715 | uint16_t lreq_q_out = 0; |
2676 | 2716 | ||
2677 | lreq_q_in = RD_REG_DWORD(rsp->rsp_q_in); | 2717 | lreq_q_in = RD_REG_DWORD(rsp->rsp_q_in); |
2678 | lreq_q_out = RD_REG_DWORD(rsp->rsp_q_out); | 2718 | lreq_q_out = rsp->ring_index; |
2679 | 2719 | ||
2680 | while (lreq_q_in != lreq_q_out) { | 2720 | while (lreq_q_in != lreq_q_out) { |
2681 | lptr = rsp->ring_ptr; | 2721 | lptr = rsp->ring_ptr; |
@@ -3426,7 +3466,7 @@ qlafx00_fxdisc_iocb(srb_t *sp, struct fxdisc_entry_fx00 *pfxiocb) | |||
3426 | sp->fcport->vha, 0x3047, | 3466 | sp->fcport->vha, 0x3047, |
3427 | (uint8_t *)&fx_iocb, sizeof(struct fxdisc_entry_fx00)); | 3467 | (uint8_t *)&fx_iocb, sizeof(struct fxdisc_entry_fx00)); |
3428 | 3468 | ||
3429 | memcpy((void *)pfxiocb, &fx_iocb, | 3469 | memcpy_toio((void __iomem *)pfxiocb, &fx_iocb, |
3430 | sizeof(struct fxdisc_entry_fx00)); | 3470 | sizeof(struct fxdisc_entry_fx00)); |
3431 | wmb(); | 3471 | wmb(); |
3432 | } | 3472 | } |
diff --git a/drivers/scsi/qla2xxx/qla_mr.h b/drivers/scsi/qla2xxx/qla_mr.h index e529dfaeb854..aeaa1b40b1fc 100644 --- a/drivers/scsi/qla2xxx/qla_mr.h +++ b/drivers/scsi/qla2xxx/qla_mr.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -351,6 +351,7 @@ struct config_info_data { | |||
351 | #define SOC_FABRIC_RST_CONTROL_REG 0x0020840 | 351 | #define SOC_FABRIC_RST_CONTROL_REG 0x0020840 |
352 | #define SOC_FABRIC_CONTROL_REG 0x0020200 | 352 | #define SOC_FABRIC_CONTROL_REG 0x0020200 |
353 | #define SOC_FABRIC_CONFIG_REG 0x0020204 | 353 | #define SOC_FABRIC_CONFIG_REG 0x0020204 |
354 | #define SOC_PWR_MANAGEMENT_PWR_DOWN_REG 0x001820C | ||
354 | 355 | ||
355 | #define SOC_INTERRUPT_SOURCE_I_CONTROL_REG 0x0020B00 | 356 | #define SOC_INTERRUPT_SOURCE_I_CONTROL_REG 0x0020B00 |
356 | #define SOC_CORE_TIMER_REG 0x0021850 | 357 | #define SOC_CORE_TIMER_REG 0x0021850 |
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 5511e24b1f11..58f3c912d96e 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -848,6 +848,7 @@ qla82xx_rom_lock(struct qla_hw_data *ha) | |||
848 | { | 848 | { |
849 | int done = 0, timeout = 0; | 849 | int done = 0, timeout = 0; |
850 | uint32_t lock_owner = 0; | 850 | uint32_t lock_owner = 0; |
851 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); | ||
851 | 852 | ||
852 | while (!done) { | 853 | while (!done) { |
853 | /* acquire semaphore2 from PCI HW block */ | 854 | /* acquire semaphore2 from PCI HW block */ |
@@ -856,17 +857,21 @@ qla82xx_rom_lock(struct qla_hw_data *ha) | |||
856 | break; | 857 | break; |
857 | if (timeout >= qla82xx_rom_lock_timeout) { | 858 | if (timeout >= qla82xx_rom_lock_timeout) { |
858 | lock_owner = qla82xx_rd_32(ha, QLA82XX_ROM_LOCK_ID); | 859 | lock_owner = qla82xx_rd_32(ha, QLA82XX_ROM_LOCK_ID); |
860 | ql_log(ql_log_warn, vha, 0xb157, | ||
861 | "%s: Simultaneous flash access by following ports, active port = %d: accessing port = %d", | ||
862 | __func__, ha->portnum, lock_owner); | ||
859 | return -1; | 863 | return -1; |
860 | } | 864 | } |
861 | timeout++; | 865 | timeout++; |
862 | } | 866 | } |
863 | qla82xx_wr_32(ha, QLA82XX_ROM_LOCK_ID, ROM_LOCK_DRIVER); | 867 | qla82xx_wr_32(ha, QLA82XX_ROM_LOCK_ID, ha->portnum); |
864 | return 0; | 868 | return 0; |
865 | } | 869 | } |
866 | 870 | ||
867 | static void | 871 | static void |
868 | qla82xx_rom_unlock(struct qla_hw_data *ha) | 872 | qla82xx_rom_unlock(struct qla_hw_data *ha) |
869 | { | 873 | { |
874 | qla82xx_wr_32(ha, QLA82XX_ROM_LOCK_ID, 0xffffffff); | ||
870 | qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_UNLOCK)); | 875 | qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_UNLOCK)); |
871 | } | 876 | } |
872 | 877 | ||
@@ -950,6 +955,7 @@ static int | |||
950 | qla82xx_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp) | 955 | qla82xx_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp) |
951 | { | 956 | { |
952 | int ret, loops = 0; | 957 | int ret, loops = 0; |
958 | uint32_t lock_owner = 0; | ||
953 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); | 959 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); |
954 | 960 | ||
955 | while ((qla82xx_rom_lock(ha) != 0) && (loops < 50000)) { | 961 | while ((qla82xx_rom_lock(ha) != 0) && (loops < 50000)) { |
@@ -958,8 +964,10 @@ qla82xx_rom_fast_read(struct qla_hw_data *ha, int addr, int *valp) | |||
958 | loops++; | 964 | loops++; |
959 | } | 965 | } |
960 | if (loops >= 50000) { | 966 | if (loops >= 50000) { |
967 | lock_owner = qla82xx_rd_32(ha, QLA82XX_ROM_LOCK_ID); | ||
961 | ql_log(ql_log_fatal, vha, 0x00b9, | 968 | ql_log(ql_log_fatal, vha, 0x00b9, |
962 | "Failed to acquire SEM2 lock.\n"); | 969 | "Failed to acquire SEM2 lock, Lock Owner %u.\n", |
970 | lock_owner); | ||
963 | return -1; | 971 | return -1; |
964 | } | 972 | } |
965 | ret = qla82xx_do_rom_fast_read(ha, addr, valp); | 973 | ret = qla82xx_do_rom_fast_read(ha, addr, valp); |
@@ -1057,6 +1065,7 @@ static int | |||
1057 | ql82xx_rom_lock_d(struct qla_hw_data *ha) | 1065 | ql82xx_rom_lock_d(struct qla_hw_data *ha) |
1058 | { | 1066 | { |
1059 | int loops = 0; | 1067 | int loops = 0; |
1068 | uint32_t lock_owner = 0; | ||
1060 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); | 1069 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); |
1061 | 1070 | ||
1062 | while ((qla82xx_rom_lock(ha) != 0) && (loops < 50000)) { | 1071 | while ((qla82xx_rom_lock(ha) != 0) && (loops < 50000)) { |
@@ -1065,8 +1074,9 @@ ql82xx_rom_lock_d(struct qla_hw_data *ha) | |||
1065 | loops++; | 1074 | loops++; |
1066 | } | 1075 | } |
1067 | if (loops >= 50000) { | 1076 | if (loops >= 50000) { |
1077 | lock_owner = qla82xx_rd_32(ha, QLA82XX_ROM_LOCK_ID); | ||
1068 | ql_log(ql_log_warn, vha, 0xb010, | 1078 | ql_log(ql_log_warn, vha, 0xb010, |
1069 | "ROM lock failed.\n"); | 1079 | "ROM lock failed, Lock Owner %u.\n", lock_owner); |
1070 | return -1; | 1080 | return -1; |
1071 | } | 1081 | } |
1072 | return 0; | 1082 | return 0; |
@@ -2811,12 +2821,14 @@ static void | |||
2811 | qla82xx_rom_lock_recovery(struct qla_hw_data *ha) | 2821 | qla82xx_rom_lock_recovery(struct qla_hw_data *ha) |
2812 | { | 2822 | { |
2813 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); | 2823 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); |
2824 | uint32_t lock_owner = 0; | ||
2814 | 2825 | ||
2815 | if (qla82xx_rom_lock(ha)) | 2826 | if (qla82xx_rom_lock(ha)) { |
2827 | lock_owner = qla82xx_rd_32(ha, QLA82XX_ROM_LOCK_ID); | ||
2816 | /* Someone else is holding the lock. */ | 2828 | /* Someone else is holding the lock. */ |
2817 | ql_log(ql_log_info, vha, 0xb022, | 2829 | ql_log(ql_log_info, vha, 0xb022, |
2818 | "Resetting rom_lock.\n"); | 2830 | "Resetting rom_lock, Lock Owner %u.\n", lock_owner); |
2819 | 2831 | } | |
2820 | /* | 2832 | /* |
2821 | * Either we got the lock, or someone | 2833 | * Either we got the lock, or someone |
2822 | * else died while holding it. | 2834 | * else died while holding it. |
@@ -2840,47 +2852,30 @@ static int | |||
2840 | qla82xx_device_bootstrap(scsi_qla_host_t *vha) | 2852 | qla82xx_device_bootstrap(scsi_qla_host_t *vha) |
2841 | { | 2853 | { |
2842 | int rval = QLA_SUCCESS; | 2854 | int rval = QLA_SUCCESS; |
2843 | int i, timeout; | 2855 | int i; |
2844 | uint32_t old_count, count; | 2856 | uint32_t old_count, count; |
2845 | struct qla_hw_data *ha = vha->hw; | 2857 | struct qla_hw_data *ha = vha->hw; |
2846 | int need_reset = 0, peg_stuck = 1; | 2858 | int need_reset = 0; |
2847 | 2859 | ||
2848 | need_reset = qla82xx_need_reset(ha); | 2860 | need_reset = qla82xx_need_reset(ha); |
2849 | 2861 | ||
2850 | old_count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); | ||
2851 | |||
2852 | for (i = 0; i < 10; i++) { | ||
2853 | timeout = msleep_interruptible(200); | ||
2854 | if (timeout) { | ||
2855 | qla82xx_wr_32(ha, QLA82XX_CRB_DEV_STATE, | ||
2856 | QLA8XXX_DEV_FAILED); | ||
2857 | return QLA_FUNCTION_FAILED; | ||
2858 | } | ||
2859 | |||
2860 | count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); | ||
2861 | if (count != old_count) | ||
2862 | peg_stuck = 0; | ||
2863 | } | ||
2864 | |||
2865 | if (need_reset) { | 2862 | if (need_reset) { |
2866 | /* We are trying to perform a recovery here. */ | 2863 | /* We are trying to perform a recovery here. */ |
2867 | if (peg_stuck) | 2864 | if (ha->flags.isp82xx_fw_hung) |
2868 | qla82xx_rom_lock_recovery(ha); | 2865 | qla82xx_rom_lock_recovery(ha); |
2869 | goto dev_initialize; | ||
2870 | } else { | 2866 | } else { |
2871 | /* Start of day for this ha context. */ | 2867 | old_count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); |
2872 | if (peg_stuck) { | 2868 | for (i = 0; i < 10; i++) { |
2873 | /* Either we are the first or recovery in progress. */ | 2869 | msleep(200); |
2874 | qla82xx_rom_lock_recovery(ha); | 2870 | count = qla82xx_rd_32(ha, QLA82XX_PEG_ALIVE_COUNTER); |
2875 | goto dev_initialize; | 2871 | if (count != old_count) { |
2876 | } else | 2872 | rval = QLA_SUCCESS; |
2877 | /* Firmware already running. */ | 2873 | goto dev_ready; |
2878 | goto dev_ready; | 2874 | } |
2875 | } | ||
2876 | qla82xx_rom_lock_recovery(ha); | ||
2879 | } | 2877 | } |
2880 | 2878 | ||
2881 | return rval; | ||
2882 | |||
2883 | dev_initialize: | ||
2884 | /* set to DEV_INITIALIZING */ | 2879 | /* set to DEV_INITIALIZING */ |
2885 | ql_log(ql_log_info, vha, 0x009e, | 2880 | ql_log(ql_log_info, vha, 0x009e, |
2886 | "HW State: INITIALIZING.\n"); | 2881 | "HW State: INITIALIZING.\n"); |
@@ -3142,18 +3137,18 @@ qla82xx_check_md_needed(scsi_qla_host_t *vha) | |||
3142 | 3137 | ||
3143 | if (ql2xmdenable) { | 3138 | if (ql2xmdenable) { |
3144 | if (!ha->fw_dumped) { | 3139 | if (!ha->fw_dumped) { |
3145 | if (fw_major_version != ha->fw_major_version || | 3140 | if ((fw_major_version != ha->fw_major_version || |
3146 | fw_minor_version != ha->fw_minor_version || | 3141 | fw_minor_version != ha->fw_minor_version || |
3147 | fw_subminor_version != ha->fw_subminor_version) { | 3142 | fw_subminor_version != ha->fw_subminor_version) || |
3143 | (ha->prev_minidump_failed)) { | ||
3148 | ql_dbg(ql_dbg_p3p, vha, 0xb02d, | 3144 | ql_dbg(ql_dbg_p3p, vha, 0xb02d, |
3149 | "Firmware version differs " | 3145 | "Firmware version differs Previous version: %d:%d:%d - New version: %d:%d:%d, prev_minidump_failed: %d.\n", |
3150 | "Previous version: %d:%d:%d - " | ||
3151 | "New version: %d:%d:%d\n", | ||
3152 | fw_major_version, fw_minor_version, | 3146 | fw_major_version, fw_minor_version, |
3153 | fw_subminor_version, | 3147 | fw_subminor_version, |
3154 | ha->fw_major_version, | 3148 | ha->fw_major_version, |
3155 | ha->fw_minor_version, | 3149 | ha->fw_minor_version, |
3156 | ha->fw_subminor_version); | 3150 | ha->fw_subminor_version, |
3151 | ha->prev_minidump_failed); | ||
3157 | /* Release MiniDump resources */ | 3152 | /* Release MiniDump resources */ |
3158 | qla82xx_md_free(vha); | 3153 | qla82xx_md_free(vha); |
3159 | /* ALlocate MiniDump resources */ | 3154 | /* ALlocate MiniDump resources */ |
@@ -3682,8 +3677,10 @@ qla82xx_chip_reset_cleanup(scsi_qla_host_t *vha) | |||
3682 | for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { | 3677 | for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { |
3683 | sp = req->outstanding_cmds[cnt]; | 3678 | sp = req->outstanding_cmds[cnt]; |
3684 | if (sp) { | 3679 | if (sp) { |
3685 | if (!sp->u.scmd.ctx || | 3680 | if ((!sp->u.scmd.ctx || |
3686 | (sp->flags & SRB_FCP_CMND_DMA_VALID)) { | 3681 | (sp->flags & |
3682 | SRB_FCP_CMND_DMA_VALID)) && | ||
3683 | !ha->flags.isp82xx_fw_hung) { | ||
3687 | spin_unlock_irqrestore( | 3684 | spin_unlock_irqrestore( |
3688 | &ha->hardware_lock, flags); | 3685 | &ha->hardware_lock, flags); |
3689 | if (ha->isp_ops->abort_command(sp)) { | 3686 | if (ha->isp_ops->abort_command(sp)) { |
diff --git a/drivers/scsi/qla2xxx/qla_nx.h b/drivers/scsi/qla2xxx/qla_nx.h index 1bb93dbbccbb..59c477883a73 100644 --- a/drivers/scsi/qla2xxx/qla_nx.h +++ b/drivers/scsi/qla2xxx/qla_nx.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -333,9 +333,6 @@ | |||
333 | #define QLA82XX_ROMUSB_ROM_INSTR_OPCODE (ROMUSB_ROM + 0x0004) | 333 | #define QLA82XX_ROMUSB_ROM_INSTR_OPCODE (ROMUSB_ROM + 0x0004) |
334 | #define QLA82XX_ROMUSB_GLB_CAS_RST (ROMUSB_GLB + 0x0038) | 334 | #define QLA82XX_ROMUSB_GLB_CAS_RST (ROMUSB_GLB + 0x0038) |
335 | 335 | ||
336 | /* Lock IDs for ROM lock */ | ||
337 | #define ROM_LOCK_DRIVER 0x0d417340 | ||
338 | |||
339 | #define QLA82XX_PCI_CRB_WINDOWSIZE 0x00100000 /* all are 1MB windows */ | 336 | #define QLA82XX_PCI_CRB_WINDOWSIZE 0x00100000 /* all are 1MB windows */ |
340 | #define QLA82XX_PCI_CRB_WINDOW(A) \ | 337 | #define QLA82XX_PCI_CRB_WINDOW(A) \ |
341 | (QLA82XX_PCI_CRBSPACE + (A)*QLA82XX_PCI_CRB_WINDOWSIZE) | 338 | (QLA82XX_PCI_CRBSPACE + (A)*QLA82XX_PCI_CRB_WINDOWSIZE) |
@@ -1186,6 +1183,7 @@ static const int MD_MIU_TEST_AGT_RDDATA[] = { 0x410000A8, 0x410000AC, | |||
1186 | #define CRB_NIU_XG_PAUSE_CTL_P1 0x8 | 1183 | #define CRB_NIU_XG_PAUSE_CTL_P1 0x8 |
1187 | 1184 | ||
1188 | #define qla82xx_get_temp_val(x) ((x) >> 16) | 1185 | #define qla82xx_get_temp_val(x) ((x) >> 16) |
1186 | #define qla82xx_get_temp_val1(x) ((x) && 0x0000FFFF) | ||
1189 | #define qla82xx_get_temp_state(x) ((x) & 0xffff) | 1187 | #define qla82xx_get_temp_state(x) ((x) & 0xffff) |
1190 | #define qla82xx_encode_temp(val, state) (((val) << 16) | (state)) | 1188 | #define qla82xx_encode_temp(val, state) (((val) << 16) | (state)) |
1191 | 1189 | ||
diff --git a/drivers/scsi/qla2xxx/qla_nx2.c b/drivers/scsi/qla2xxx/qla_nx2.c index 86cf10815db0..da9e3902f219 100644 --- a/drivers/scsi/qla2xxx/qla_nx2.c +++ b/drivers/scsi/qla2xxx/qla_nx2.c | |||
@@ -1,17 +1,20 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <linux/vmalloc.h> | 8 | #include <linux/vmalloc.h> |
9 | #include <linux/delay.h> | ||
9 | 10 | ||
10 | #include "qla_def.h" | 11 | #include "qla_def.h" |
11 | #include "qla_gbl.h" | 12 | #include "qla_gbl.h" |
12 | 13 | ||
13 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
14 | 15 | ||
16 | #define TIMEOUT_100_MS 100 | ||
17 | |||
15 | /* 8044 Flash Read/Write functions */ | 18 | /* 8044 Flash Read/Write functions */ |
16 | uint32_t | 19 | uint32_t |
17 | qla8044_rd_reg(struct qla_hw_data *ha, ulong addr) | 20 | qla8044_rd_reg(struct qla_hw_data *ha, ulong addr) |
@@ -117,6 +120,95 @@ qla8044_read_write_crb_reg(struct scsi_qla_host *vha, | |||
117 | qla8044_wr_reg_indirect(vha, waddr, value); | 120 | qla8044_wr_reg_indirect(vha, waddr, value); |
118 | } | 121 | } |
119 | 122 | ||
123 | static int | ||
124 | qla8044_poll_wait_for_ready(struct scsi_qla_host *vha, uint32_t addr1, | ||
125 | uint32_t mask) | ||
126 | { | ||
127 | unsigned long timeout; | ||
128 | uint32_t temp; | ||
129 | |||
130 | /* jiffies after 100ms */ | ||
131 | timeout = jiffies + msecs_to_jiffies(TIMEOUT_100_MS); | ||
132 | do { | ||
133 | qla8044_rd_reg_indirect(vha, addr1, &temp); | ||
134 | if ((temp & mask) != 0) | ||
135 | break; | ||
136 | if (time_after_eq(jiffies, timeout)) { | ||
137 | ql_log(ql_log_warn, vha, 0xb151, | ||
138 | "Error in processing rdmdio entry\n"); | ||
139 | return -1; | ||
140 | } | ||
141 | } while (1); | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | static uint32_t | ||
147 | qla8044_ipmdio_rd_reg(struct scsi_qla_host *vha, | ||
148 | uint32_t addr1, uint32_t addr3, uint32_t mask, uint32_t addr) | ||
149 | { | ||
150 | uint32_t temp; | ||
151 | int ret = 0; | ||
152 | |||
153 | ret = qla8044_poll_wait_for_ready(vha, addr1, mask); | ||
154 | if (ret == -1) | ||
155 | return -1; | ||
156 | |||
157 | temp = (0x40000000 | addr); | ||
158 | qla8044_wr_reg_indirect(vha, addr1, temp); | ||
159 | |||
160 | ret = qla8044_poll_wait_for_ready(vha, addr1, mask); | ||
161 | if (ret == -1) | ||
162 | return 0; | ||
163 | |||
164 | qla8044_rd_reg_indirect(vha, addr3, &ret); | ||
165 | |||
166 | return ret; | ||
167 | } | ||
168 | |||
169 | |||
170 | static int | ||
171 | qla8044_poll_wait_ipmdio_bus_idle(struct scsi_qla_host *vha, | ||
172 | uint32_t addr1, uint32_t addr2, uint32_t addr3, uint32_t mask) | ||
173 | { | ||
174 | unsigned long timeout; | ||
175 | uint32_t temp; | ||
176 | |||
177 | /* jiffies after 100 msecs */ | ||
178 | timeout = jiffies + msecs_to_jiffies(TIMEOUT_100_MS); | ||
179 | do { | ||
180 | temp = qla8044_ipmdio_rd_reg(vha, addr1, addr3, mask, addr2); | ||
181 | if ((temp & 0x1) != 1) | ||
182 | break; | ||
183 | if (time_after_eq(jiffies, timeout)) { | ||
184 | ql_log(ql_log_warn, vha, 0xb152, | ||
185 | "Error in processing mdiobus idle\n"); | ||
186 | return -1; | ||
187 | } | ||
188 | } while (1); | ||
189 | |||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static int | ||
194 | qla8044_ipmdio_wr_reg(struct scsi_qla_host *vha, uint32_t addr1, | ||
195 | uint32_t addr3, uint32_t mask, uint32_t addr, uint32_t value) | ||
196 | { | ||
197 | int ret = 0; | ||
198 | |||
199 | ret = qla8044_poll_wait_for_ready(vha, addr1, mask); | ||
200 | if (ret == -1) | ||
201 | return -1; | ||
202 | |||
203 | qla8044_wr_reg_indirect(vha, addr3, value); | ||
204 | qla8044_wr_reg_indirect(vha, addr1, addr); | ||
205 | |||
206 | ret = qla8044_poll_wait_for_ready(vha, addr1, mask); | ||
207 | if (ret == -1) | ||
208 | return -1; | ||
209 | |||
210 | return 0; | ||
211 | } | ||
120 | /* | 212 | /* |
121 | * qla8044_rmw_crb_reg - Read value from raddr, AND with test_mask, | 213 | * qla8044_rmw_crb_reg - Read value from raddr, AND with test_mask, |
122 | * Shift Left,Right/OR/XOR with values RMW header and write value to waddr. | 214 | * Shift Left,Right/OR/XOR with values RMW header and write value to waddr. |
@@ -356,8 +448,8 @@ qla8044_flash_lock(scsi_qla_host_t *vha) | |||
356 | lock_owner = qla8044_rd_reg(ha, | 448 | lock_owner = qla8044_rd_reg(ha, |
357 | QLA8044_FLASH_LOCK_ID); | 449 | QLA8044_FLASH_LOCK_ID); |
358 | ql_log(ql_log_warn, vha, 0xb113, | 450 | ql_log(ql_log_warn, vha, 0xb113, |
359 | "%s: flash lock by %d failed, held by %d\n", | 451 | "%s: Simultaneous flash access by following ports, active port = %d: accessing port = %d", |
360 | __func__, ha->portnum, lock_owner); | 452 | __func__, ha->portnum, lock_owner); |
361 | ret_val = QLA_FUNCTION_FAILED; | 453 | ret_val = QLA_FUNCTION_FAILED; |
362 | break; | 454 | break; |
363 | } | 455 | } |
@@ -1541,7 +1633,7 @@ static void | |||
1541 | qla8044_need_reset_handler(struct scsi_qla_host *vha) | 1633 | qla8044_need_reset_handler(struct scsi_qla_host *vha) |
1542 | { | 1634 | { |
1543 | uint32_t dev_state = 0, drv_state, drv_active; | 1635 | uint32_t dev_state = 0, drv_state, drv_active; |
1544 | unsigned long reset_timeout, dev_init_timeout; | 1636 | unsigned long reset_timeout; |
1545 | struct qla_hw_data *ha = vha->hw; | 1637 | struct qla_hw_data *ha = vha->hw; |
1546 | 1638 | ||
1547 | ql_log(ql_log_fatal, vha, 0xb0c2, | 1639 | ql_log(ql_log_fatal, vha, 0xb0c2, |
@@ -1555,84 +1647,78 @@ qla8044_need_reset_handler(struct scsi_qla_host *vha) | |||
1555 | qla8044_idc_lock(ha); | 1647 | qla8044_idc_lock(ha); |
1556 | } | 1648 | } |
1557 | 1649 | ||
1650 | dev_state = qla8044_rd_direct(vha, | ||
1651 | QLA8044_CRB_DEV_STATE_INDEX); | ||
1558 | drv_state = qla8044_rd_direct(vha, | 1652 | drv_state = qla8044_rd_direct(vha, |
1559 | QLA8044_CRB_DRV_STATE_INDEX); | 1653 | QLA8044_CRB_DRV_STATE_INDEX); |
1560 | drv_active = qla8044_rd_direct(vha, | 1654 | drv_active = qla8044_rd_direct(vha, |
1561 | QLA8044_CRB_DRV_ACTIVE_INDEX); | 1655 | QLA8044_CRB_DRV_ACTIVE_INDEX); |
1562 | 1656 | ||
1563 | ql_log(ql_log_info, vha, 0xb0c5, | 1657 | ql_log(ql_log_info, vha, 0xb0c5, |
1564 | "%s(%ld): drv_state = 0x%x, drv_active = 0x%x\n", | 1658 | "%s(%ld): drv_state = 0x%x, drv_active = 0x%x dev_state = 0x%x\n", |
1565 | __func__, vha->host_no, drv_state, drv_active); | 1659 | __func__, vha->host_no, drv_state, drv_active, dev_state); |
1566 | 1660 | ||
1567 | if (!ha->flags.nic_core_reset_owner) { | 1661 | qla8044_set_rst_ready(vha); |
1568 | ql_dbg(ql_dbg_p3p, vha, 0xb0c3, | ||
1569 | "%s(%ld): reset acknowledged\n", | ||
1570 | __func__, vha->host_no); | ||
1571 | qla8044_set_rst_ready(vha); | ||
1572 | 1662 | ||
1573 | /* Non-reset owners ACK Reset and wait for device INIT state | 1663 | /* wait for 10 seconds for reset ack from all functions */ |
1574 | * as part of Reset Recovery by Reset Owner | 1664 | reset_timeout = jiffies + (ha->fcoe_reset_timeout * HZ); |
1575 | */ | ||
1576 | dev_init_timeout = jiffies + (ha->fcoe_reset_timeout * HZ); | ||
1577 | 1665 | ||
1578 | do { | 1666 | do { |
1579 | if (time_after_eq(jiffies, dev_init_timeout)) { | 1667 | if (time_after_eq(jiffies, reset_timeout)) { |
1580 | ql_log(ql_log_info, vha, 0xb0c4, | 1668 | ql_log(ql_log_info, vha, 0xb0c4, |
1581 | "%s: Non Reset owner: Reset Ack Timeout!\n", | 1669 | "%s: Function %d: Reset Ack Timeout!, drv_state: 0x%08x, drv_active: 0x%08x\n", |
1582 | __func__); | 1670 | __func__, ha->portnum, drv_state, drv_active); |
1583 | break; | 1671 | break; |
1584 | } | 1672 | } |
1585 | 1673 | ||
1586 | qla8044_idc_unlock(ha); | 1674 | qla8044_idc_unlock(ha); |
1587 | msleep(1000); | 1675 | msleep(1000); |
1588 | qla8044_idc_lock(ha); | 1676 | qla8044_idc_lock(ha); |
1589 | 1677 | ||
1590 | dev_state = qla8044_rd_direct(vha, | 1678 | dev_state = qla8044_rd_direct(vha, |
1591 | QLA8044_CRB_DEV_STATE_INDEX); | 1679 | QLA8044_CRB_DEV_STATE_INDEX); |
1592 | } while (((drv_state & drv_active) != drv_active) && | 1680 | drv_state = qla8044_rd_direct(vha, |
1593 | (dev_state == QLA8XXX_DEV_NEED_RESET)); | 1681 | QLA8044_CRB_DRV_STATE_INDEX); |
1682 | drv_active = qla8044_rd_direct(vha, | ||
1683 | QLA8044_CRB_DRV_ACTIVE_INDEX); | ||
1684 | } while (((drv_state & drv_active) != drv_active) && | ||
1685 | (dev_state == QLA8XXX_DEV_NEED_RESET)); | ||
1686 | |||
1687 | /* Remove IDC participation of functions not acknowledging */ | ||
1688 | if (drv_state != drv_active) { | ||
1689 | ql_log(ql_log_info, vha, 0xb0c7, | ||
1690 | "%s(%ld): Function %d turning off drv_active of non-acking function 0x%x\n", | ||
1691 | __func__, vha->host_no, ha->portnum, | ||
1692 | (drv_active ^ drv_state)); | ||
1693 | drv_active = drv_active & drv_state; | ||
1694 | qla8044_wr_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX, | ||
1695 | drv_active); | ||
1594 | } else { | 1696 | } else { |
1595 | qla8044_set_rst_ready(vha); | 1697 | /* |
1596 | 1698 | * Reset owner should execute reset recovery, | |
1597 | /* wait for 10 seconds for reset ack from all functions */ | 1699 | * if all functions acknowledged |
1598 | reset_timeout = jiffies + (ha->fcoe_reset_timeout * HZ); | 1700 | */ |
1599 | 1701 | if ((ha->flags.nic_core_reset_owner) && | |
1600 | while ((drv_state & drv_active) != drv_active) { | 1702 | (dev_state == QLA8XXX_DEV_NEED_RESET)) { |
1601 | if (time_after_eq(jiffies, reset_timeout)) { | 1703 | ha->flags.nic_core_reset_owner = 0; |
1602 | ql_log(ql_log_info, vha, 0xb0c6, | 1704 | qla8044_device_bootstrap(vha); |
1603 | "%s: RESET TIMEOUT!" | 1705 | return; |
1604 | "drv_state: 0x%08x, drv_active: 0x%08x\n", | ||
1605 | QLA2XXX_DRIVER_NAME, drv_state, drv_active); | ||
1606 | break; | ||
1607 | } | ||
1608 | |||
1609 | qla8044_idc_unlock(ha); | ||
1610 | msleep(1000); | ||
1611 | qla8044_idc_lock(ha); | ||
1612 | |||
1613 | drv_state = qla8044_rd_direct(vha, | ||
1614 | QLA8044_CRB_DRV_STATE_INDEX); | ||
1615 | drv_active = qla8044_rd_direct(vha, | ||
1616 | QLA8044_CRB_DRV_ACTIVE_INDEX); | ||
1617 | } | ||
1618 | |||
1619 | if (drv_state != drv_active) { | ||
1620 | ql_log(ql_log_info, vha, 0xb0c7, | ||
1621 | "%s(%ld): Reset_owner turning off drv_active " | ||
1622 | "of non-acking function 0x%x\n", __func__, | ||
1623 | vha->host_no, (drv_active ^ drv_state)); | ||
1624 | drv_active = drv_active & drv_state; | ||
1625 | qla8044_wr_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX, | ||
1626 | drv_active); | ||
1627 | } | 1706 | } |
1707 | } | ||
1628 | 1708 | ||
1629 | /* | 1709 | /* Exit if non active function */ |
1630 | * Clear RESET OWNER, will be set at next reset | 1710 | if (!(drv_active & (1 << ha->portnum))) { |
1631 | * by next RST_OWNER | ||
1632 | */ | ||
1633 | ha->flags.nic_core_reset_owner = 0; | 1711 | ha->flags.nic_core_reset_owner = 0; |
1712 | return; | ||
1713 | } | ||
1634 | 1714 | ||
1635 | /* Start Reset Recovery */ | 1715 | /* |
1716 | * Execute Reset Recovery if Reset Owner or Function 7 | ||
1717 | * is the only active function | ||
1718 | */ | ||
1719 | if (ha->flags.nic_core_reset_owner || | ||
1720 | ((drv_state & drv_active) == QLA8044_FUN7_ACTIVE_INDEX)) { | ||
1721 | ha->flags.nic_core_reset_owner = 0; | ||
1636 | qla8044_device_bootstrap(vha); | 1722 | qla8044_device_bootstrap(vha); |
1637 | } | 1723 | } |
1638 | } | 1724 | } |
@@ -1655,6 +1741,19 @@ qla8044_set_drv_active(struct scsi_qla_host *vha) | |||
1655 | qla8044_wr_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX, drv_active); | 1741 | qla8044_wr_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX, drv_active); |
1656 | } | 1742 | } |
1657 | 1743 | ||
1744 | static int | ||
1745 | qla8044_check_drv_active(struct scsi_qla_host *vha) | ||
1746 | { | ||
1747 | uint32_t drv_active; | ||
1748 | struct qla_hw_data *ha = vha->hw; | ||
1749 | |||
1750 | drv_active = qla8044_rd_direct(vha, QLA8044_CRB_DRV_ACTIVE_INDEX); | ||
1751 | if (drv_active & (1 << ha->portnum)) | ||
1752 | return QLA_SUCCESS; | ||
1753 | else | ||
1754 | return QLA_TEST_FAILED; | ||
1755 | } | ||
1756 | |||
1658 | static void | 1757 | static void |
1659 | qla8044_clear_idc_dontreset(struct scsi_qla_host *vha) | 1758 | qla8044_clear_idc_dontreset(struct scsi_qla_host *vha) |
1660 | { | 1759 | { |
@@ -1837,14 +1936,16 @@ qla8044_device_state_handler(struct scsi_qla_host *vha) | |||
1837 | 1936 | ||
1838 | while (1) { | 1937 | while (1) { |
1839 | if (time_after_eq(jiffies, dev_init_timeout)) { | 1938 | if (time_after_eq(jiffies, dev_init_timeout)) { |
1840 | ql_log(ql_log_warn, vha, 0xb0cf, | 1939 | if (qla8044_check_drv_active(vha) == QLA_SUCCESS) { |
1841 | "%s: Device Init Failed 0x%x = %s\n", | 1940 | ql_log(ql_log_warn, vha, 0xb0cf, |
1842 | QLA2XXX_DRIVER_NAME, dev_state, | 1941 | "%s: Device Init Failed 0x%x = %s\n", |
1843 | dev_state < MAX_STATES ? | 1942 | QLA2XXX_DRIVER_NAME, dev_state, |
1844 | qdev_state(dev_state) : "Unknown"); | 1943 | dev_state < MAX_STATES ? |
1845 | 1944 | qdev_state(dev_state) : "Unknown"); | |
1846 | qla8044_wr_direct(vha, QLA8044_CRB_DEV_STATE_INDEX, | 1945 | qla8044_wr_direct(vha, |
1847 | QLA8XXX_DEV_FAILED); | 1946 | QLA8044_CRB_DEV_STATE_INDEX, |
1947 | QLA8XXX_DEV_FAILED); | ||
1948 | } | ||
1848 | } | 1949 | } |
1849 | 1950 | ||
1850 | dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX); | 1951 | dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX); |
@@ -2017,6 +2118,13 @@ qla8044_watchdog(struct scsi_qla_host *vha) | |||
2017 | test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags))) { | 2118 | test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags))) { |
2018 | dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX); | 2119 | dev_state = qla8044_rd_direct(vha, QLA8044_CRB_DEV_STATE_INDEX); |
2019 | 2120 | ||
2121 | if (qla8044_check_fw_alive(vha)) { | ||
2122 | ha->flags.isp82xx_fw_hung = 1; | ||
2123 | ql_log(ql_log_warn, vha, 0xb10a, | ||
2124 | "Firmware hung.\n"); | ||
2125 | qla82xx_clear_pending_mbx(vha); | ||
2126 | } | ||
2127 | |||
2020 | if (qla8044_check_temp(vha)) { | 2128 | if (qla8044_check_temp(vha)) { |
2021 | set_bit(ISP_UNRECOVERABLE, &vha->dpc_flags); | 2129 | set_bit(ISP_UNRECOVERABLE, &vha->dpc_flags); |
2022 | ha->flags.isp82xx_fw_hung = 1; | 2130 | ha->flags.isp82xx_fw_hung = 1; |
@@ -2037,7 +2145,7 @@ qla8044_watchdog(struct scsi_qla_host *vha) | |||
2037 | qla2xxx_wake_dpc(vha); | 2145 | qla2xxx_wake_dpc(vha); |
2038 | } else { | 2146 | } else { |
2039 | /* Check firmware health */ | 2147 | /* Check firmware health */ |
2040 | if (qla8044_check_fw_alive(vha)) { | 2148 | if (ha->flags.isp82xx_fw_hung) { |
2041 | halt_status = qla8044_rd_direct(vha, | 2149 | halt_status = qla8044_rd_direct(vha, |
2042 | QLA8044_PEG_HALT_STATUS1_INDEX); | 2150 | QLA8044_PEG_HALT_STATUS1_INDEX); |
2043 | if (halt_status & | 2151 | if (halt_status & |
@@ -2073,12 +2181,8 @@ qla8044_watchdog(struct scsi_qla_host *vha) | |||
2073 | __func__); | 2181 | __func__); |
2074 | set_bit(ISP_ABORT_NEEDED, | 2182 | set_bit(ISP_ABORT_NEEDED, |
2075 | &vha->dpc_flags); | 2183 | &vha->dpc_flags); |
2076 | qla82xx_clear_pending_mbx(vha); | ||
2077 | } | 2184 | } |
2078 | } | 2185 | } |
2079 | ha->flags.isp82xx_fw_hung = 1; | ||
2080 | ql_log(ql_log_warn, vha, 0xb10a, | ||
2081 | "Firmware hung.\n"); | ||
2082 | qla2xxx_wake_dpc(vha); | 2186 | qla2xxx_wake_dpc(vha); |
2083 | } | 2187 | } |
2084 | } | 2188 | } |
@@ -2286,8 +2390,6 @@ qla8044_minidump_process_rdmem(struct scsi_qla_host *vha, | |||
2286 | } | 2390 | } |
2287 | 2391 | ||
2288 | if (j >= MAX_CTL_CHECK) { | 2392 | if (j >= MAX_CTL_CHECK) { |
2289 | printk_ratelimited(KERN_ERR | ||
2290 | "%s: failed to read through agent\n", __func__); | ||
2291 | write_unlock_irqrestore(&ha->hw_lock, flags); | 2393 | write_unlock_irqrestore(&ha->hw_lock, flags); |
2292 | return QLA_SUCCESS; | 2394 | return QLA_SUCCESS; |
2293 | } | 2395 | } |
@@ -2882,6 +2984,231 @@ error_exit: | |||
2882 | return rval; | 2984 | return rval; |
2883 | } | 2985 | } |
2884 | 2986 | ||
2987 | static uint32_t | ||
2988 | qla8044_minidump_process_rddfe(struct scsi_qla_host *vha, | ||
2989 | struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr) | ||
2990 | { | ||
2991 | int loop_cnt; | ||
2992 | uint32_t addr1, addr2, value, data, temp, wrVal; | ||
2993 | uint8_t stride, stride2; | ||
2994 | uint16_t count; | ||
2995 | uint32_t poll, mask, data_size, modify_mask; | ||
2996 | uint32_t wait_count = 0; | ||
2997 | |||
2998 | uint32_t *data_ptr = *d_ptr; | ||
2999 | |||
3000 | struct qla8044_minidump_entry_rddfe *rddfe; | ||
3001 | rddfe = (struct qla8044_minidump_entry_rddfe *) entry_hdr; | ||
3002 | |||
3003 | addr1 = rddfe->addr_1; | ||
3004 | value = rddfe->value; | ||
3005 | stride = rddfe->stride; | ||
3006 | stride2 = rddfe->stride2; | ||
3007 | count = rddfe->count; | ||
3008 | |||
3009 | poll = rddfe->poll; | ||
3010 | mask = rddfe->mask; | ||
3011 | modify_mask = rddfe->modify_mask; | ||
3012 | data_size = rddfe->data_size; | ||
3013 | |||
3014 | addr2 = addr1 + stride; | ||
3015 | |||
3016 | for (loop_cnt = 0x0; loop_cnt < count; loop_cnt++) { | ||
3017 | qla8044_wr_reg_indirect(vha, addr1, (0x40000000 | value)); | ||
3018 | |||
3019 | wait_count = 0; | ||
3020 | while (wait_count < poll) { | ||
3021 | qla8044_rd_reg_indirect(vha, addr1, &temp); | ||
3022 | if ((temp & mask) != 0) | ||
3023 | break; | ||
3024 | wait_count++; | ||
3025 | } | ||
3026 | |||
3027 | if (wait_count == poll) { | ||
3028 | ql_log(ql_log_warn, vha, 0xb153, | ||
3029 | "%s: TIMEOUT\n", __func__); | ||
3030 | goto error; | ||
3031 | } else { | ||
3032 | qla8044_rd_reg_indirect(vha, addr2, &temp); | ||
3033 | temp = temp & modify_mask; | ||
3034 | temp = (temp | ((loop_cnt << 16) | loop_cnt)); | ||
3035 | wrVal = ((temp << 16) | temp); | ||
3036 | |||
3037 | qla8044_wr_reg_indirect(vha, addr2, wrVal); | ||
3038 | qla8044_wr_reg_indirect(vha, addr1, value); | ||
3039 | |||
3040 | wait_count = 0; | ||
3041 | while (wait_count < poll) { | ||
3042 | qla8044_rd_reg_indirect(vha, addr1, &temp); | ||
3043 | if ((temp & mask) != 0) | ||
3044 | break; | ||
3045 | wait_count++; | ||
3046 | } | ||
3047 | if (wait_count == poll) { | ||
3048 | ql_log(ql_log_warn, vha, 0xb154, | ||
3049 | "%s: TIMEOUT\n", __func__); | ||
3050 | goto error; | ||
3051 | } | ||
3052 | |||
3053 | qla8044_wr_reg_indirect(vha, addr1, | ||
3054 | ((0x40000000 | value) + stride2)); | ||
3055 | wait_count = 0; | ||
3056 | while (wait_count < poll) { | ||
3057 | qla8044_rd_reg_indirect(vha, addr1, &temp); | ||
3058 | if ((temp & mask) != 0) | ||
3059 | break; | ||
3060 | wait_count++; | ||
3061 | } | ||
3062 | |||
3063 | if (wait_count == poll) { | ||
3064 | ql_log(ql_log_warn, vha, 0xb155, | ||
3065 | "%s: TIMEOUT\n", __func__); | ||
3066 | goto error; | ||
3067 | } | ||
3068 | |||
3069 | qla8044_rd_reg_indirect(vha, addr2, &data); | ||
3070 | |||
3071 | *data_ptr++ = wrVal; | ||
3072 | *data_ptr++ = data; | ||
3073 | } | ||
3074 | |||
3075 | } | ||
3076 | |||
3077 | *d_ptr = data_ptr; | ||
3078 | return QLA_SUCCESS; | ||
3079 | |||
3080 | error: | ||
3081 | return -1; | ||
3082 | |||
3083 | } | ||
3084 | |||
3085 | static uint32_t | ||
3086 | qla8044_minidump_process_rdmdio(struct scsi_qla_host *vha, | ||
3087 | struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr) | ||
3088 | { | ||
3089 | int ret = 0; | ||
3090 | uint32_t addr1, addr2, value1, value2, data, selVal; | ||
3091 | uint8_t stride1, stride2; | ||
3092 | uint32_t addr3, addr4, addr5, addr6, addr7; | ||
3093 | uint16_t count, loop_cnt; | ||
3094 | uint32_t poll, mask; | ||
3095 | uint32_t *data_ptr = *d_ptr; | ||
3096 | |||
3097 | struct qla8044_minidump_entry_rdmdio *rdmdio; | ||
3098 | |||
3099 | rdmdio = (struct qla8044_minidump_entry_rdmdio *) entry_hdr; | ||
3100 | |||
3101 | addr1 = rdmdio->addr_1; | ||
3102 | addr2 = rdmdio->addr_2; | ||
3103 | value1 = rdmdio->value_1; | ||
3104 | stride1 = rdmdio->stride_1; | ||
3105 | stride2 = rdmdio->stride_2; | ||
3106 | count = rdmdio->count; | ||
3107 | |||
3108 | poll = rdmdio->poll; | ||
3109 | mask = rdmdio->mask; | ||
3110 | value2 = rdmdio->value_2; | ||
3111 | |||
3112 | addr3 = addr1 + stride1; | ||
3113 | |||
3114 | for (loop_cnt = 0; loop_cnt < count; loop_cnt++) { | ||
3115 | ret = qla8044_poll_wait_ipmdio_bus_idle(vha, addr1, addr2, | ||
3116 | addr3, mask); | ||
3117 | if (ret == -1) | ||
3118 | goto error; | ||
3119 | |||
3120 | addr4 = addr2 - stride1; | ||
3121 | ret = qla8044_ipmdio_wr_reg(vha, addr1, addr3, mask, addr4, | ||
3122 | value2); | ||
3123 | if (ret == -1) | ||
3124 | goto error; | ||
3125 | |||
3126 | addr5 = addr2 - (2 * stride1); | ||
3127 | ret = qla8044_ipmdio_wr_reg(vha, addr1, addr3, mask, addr5, | ||
3128 | value1); | ||
3129 | if (ret == -1) | ||
3130 | goto error; | ||
3131 | |||
3132 | addr6 = addr2 - (3 * stride1); | ||
3133 | ret = qla8044_ipmdio_wr_reg(vha, addr1, addr3, mask, | ||
3134 | addr6, 0x2); | ||
3135 | if (ret == -1) | ||
3136 | goto error; | ||
3137 | |||
3138 | ret = qla8044_poll_wait_ipmdio_bus_idle(vha, addr1, addr2, | ||
3139 | addr3, mask); | ||
3140 | if (ret == -1) | ||
3141 | goto error; | ||
3142 | |||
3143 | addr7 = addr2 - (4 * stride1); | ||
3144 | data = qla8044_ipmdio_rd_reg(vha, addr1, addr3, | ||
3145 | mask, addr7); | ||
3146 | if (data == -1) | ||
3147 | goto error; | ||
3148 | |||
3149 | selVal = (value2 << 18) | (value1 << 2) | 2; | ||
3150 | |||
3151 | stride2 = rdmdio->stride_2; | ||
3152 | *data_ptr++ = selVal; | ||
3153 | *data_ptr++ = data; | ||
3154 | |||
3155 | value1 = value1 + stride2; | ||
3156 | *d_ptr = data_ptr; | ||
3157 | } | ||
3158 | |||
3159 | return 0; | ||
3160 | |||
3161 | error: | ||
3162 | return -1; | ||
3163 | } | ||
3164 | |||
3165 | static uint32_t qla8044_minidump_process_pollwr(struct scsi_qla_host *vha, | ||
3166 | struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr) | ||
3167 | { | ||
3168 | uint32_t addr1, addr2, value1, value2, poll, mask, r_value; | ||
3169 | uint32_t wait_count = 0; | ||
3170 | struct qla8044_minidump_entry_pollwr *pollwr_hdr; | ||
3171 | |||
3172 | pollwr_hdr = (struct qla8044_minidump_entry_pollwr *)entry_hdr; | ||
3173 | addr1 = pollwr_hdr->addr_1; | ||
3174 | addr2 = pollwr_hdr->addr_2; | ||
3175 | value1 = pollwr_hdr->value_1; | ||
3176 | value2 = pollwr_hdr->value_2; | ||
3177 | |||
3178 | poll = pollwr_hdr->poll; | ||
3179 | mask = pollwr_hdr->mask; | ||
3180 | |||
3181 | while (wait_count < poll) { | ||
3182 | qla8044_rd_reg_indirect(vha, addr1, &r_value); | ||
3183 | |||
3184 | if ((r_value & poll) != 0) | ||
3185 | break; | ||
3186 | wait_count++; | ||
3187 | } | ||
3188 | |||
3189 | if (wait_count == poll) { | ||
3190 | ql_log(ql_log_warn, vha, 0xb156, "%s: TIMEOUT\n", __func__); | ||
3191 | goto error; | ||
3192 | } | ||
3193 | |||
3194 | qla8044_wr_reg_indirect(vha, addr2, value2); | ||
3195 | qla8044_wr_reg_indirect(vha, addr1, value1); | ||
3196 | |||
3197 | wait_count = 0; | ||
3198 | while (wait_count < poll) { | ||
3199 | qla8044_rd_reg_indirect(vha, addr1, &r_value); | ||
3200 | |||
3201 | if ((r_value & poll) != 0) | ||
3202 | break; | ||
3203 | wait_count++; | ||
3204 | } | ||
3205 | |||
3206 | return QLA_SUCCESS; | ||
3207 | |||
3208 | error: | ||
3209 | return -1; | ||
3210 | } | ||
3211 | |||
2885 | /* | 3212 | /* |
2886 | * | 3213 | * |
2887 | * qla8044_collect_md_data - Retrieve firmware minidump data. | 3214 | * qla8044_collect_md_data - Retrieve firmware minidump data. |
@@ -3089,6 +3416,24 @@ qla8044_collect_md_data(struct scsi_qla_host *vha) | |||
3089 | if (rval != QLA_SUCCESS) | 3416 | if (rval != QLA_SUCCESS) |
3090 | qla8044_mark_entry_skipped(vha, entry_hdr, i); | 3417 | qla8044_mark_entry_skipped(vha, entry_hdr, i); |
3091 | break; | 3418 | break; |
3419 | case QLA8044_RDDFE: | ||
3420 | rval = qla8044_minidump_process_rddfe(vha, entry_hdr, | ||
3421 | &data_ptr); | ||
3422 | if (rval != QLA_SUCCESS) | ||
3423 | qla8044_mark_entry_skipped(vha, entry_hdr, i); | ||
3424 | break; | ||
3425 | case QLA8044_RDMDIO: | ||
3426 | rval = qla8044_minidump_process_rdmdio(vha, entry_hdr, | ||
3427 | &data_ptr); | ||
3428 | if (rval != QLA_SUCCESS) | ||
3429 | qla8044_mark_entry_skipped(vha, entry_hdr, i); | ||
3430 | break; | ||
3431 | case QLA8044_POLLWR: | ||
3432 | rval = qla8044_minidump_process_pollwr(vha, entry_hdr, | ||
3433 | &data_ptr); | ||
3434 | if (rval != QLA_SUCCESS) | ||
3435 | qla8044_mark_entry_skipped(vha, entry_hdr, i); | ||
3436 | break; | ||
3092 | case QLA82XX_RDNOP: | 3437 | case QLA82XX_RDNOP: |
3093 | default: | 3438 | default: |
3094 | qla8044_mark_entry_skipped(vha, entry_hdr, i); | 3439 | qla8044_mark_entry_skipped(vha, entry_hdr, i); |
@@ -3110,6 +3455,7 @@ skip_nxt_entry: | |||
3110 | "Dump data mismatch: Data collected: " | 3455 | "Dump data mismatch: Data collected: " |
3111 | "[0x%x], total_data_size:[0x%x]\n", | 3456 | "[0x%x], total_data_size:[0x%x]\n", |
3112 | data_collected, ha->md_dump_size); | 3457 | data_collected, ha->md_dump_size); |
3458 | rval = QLA_FUNCTION_FAILED; | ||
3113 | goto md_failed; | 3459 | goto md_failed; |
3114 | } | 3460 | } |
3115 | 3461 | ||
@@ -3134,10 +3480,12 @@ qla8044_get_minidump(struct scsi_qla_host *vha) | |||
3134 | 3480 | ||
3135 | if (!qla8044_collect_md_data(vha)) { | 3481 | if (!qla8044_collect_md_data(vha)) { |
3136 | ha->fw_dumped = 1; | 3482 | ha->fw_dumped = 1; |
3483 | ha->prev_minidump_failed = 0; | ||
3137 | } else { | 3484 | } else { |
3138 | ql_log(ql_log_fatal, vha, 0xb0db, | 3485 | ql_log(ql_log_fatal, vha, 0xb0db, |
3139 | "%s: Unable to collect minidump\n", | 3486 | "%s: Unable to collect minidump\n", |
3140 | __func__); | 3487 | __func__); |
3488 | ha->prev_minidump_failed = 1; | ||
3141 | } | 3489 | } |
3142 | } | 3490 | } |
3143 | 3491 | ||
diff --git a/drivers/scsi/qla2xxx/qla_nx2.h b/drivers/scsi/qla2xxx/qla_nx2.h index 2ab2eabab908..ada36057d7cd 100644 --- a/drivers/scsi/qla2xxx/qla_nx2.h +++ b/drivers/scsi/qla2xxx/qla_nx2.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -133,6 +133,7 @@ | |||
133 | #define QLA8044_LINK_SPEED(f) (0x36E0+(((f) >> 2) * 4)) | 133 | #define QLA8044_LINK_SPEED(f) (0x36E0+(((f) >> 2) * 4)) |
134 | #define QLA8044_MAX_LINK_SPEED(f) (0x36F0+(((f) / 4) * 4)) | 134 | #define QLA8044_MAX_LINK_SPEED(f) (0x36F0+(((f) / 4) * 4)) |
135 | #define QLA8044_LINK_SPEED_FACTOR 10 | 135 | #define QLA8044_LINK_SPEED_FACTOR 10 |
136 | #define QLA8044_FUN7_ACTIVE_INDEX 0x80 | ||
136 | 137 | ||
137 | /* FLASH API Defines */ | 138 | /* FLASH API Defines */ |
138 | #define QLA8044_FLASH_MAX_WAIT_USEC 100 | 139 | #define QLA8044_FLASH_MAX_WAIT_USEC 100 |
@@ -431,6 +432,50 @@ struct qla8044_minidump_entry_pollrd { | |||
431 | uint32_t rsvd_1; | 432 | uint32_t rsvd_1; |
432 | } __packed; | 433 | } __packed; |
433 | 434 | ||
435 | struct qla8044_minidump_entry_rddfe { | ||
436 | struct qla8044_minidump_entry_hdr h; | ||
437 | uint32_t addr_1; | ||
438 | uint32_t value; | ||
439 | uint8_t stride; | ||
440 | uint8_t stride2; | ||
441 | uint16_t count; | ||
442 | uint32_t poll; | ||
443 | uint32_t mask; | ||
444 | uint32_t modify_mask; | ||
445 | uint32_t data_size; | ||
446 | uint32_t rsvd; | ||
447 | |||
448 | } __packed; | ||
449 | |||
450 | struct qla8044_minidump_entry_rdmdio { | ||
451 | struct qla8044_minidump_entry_hdr h; | ||
452 | |||
453 | uint32_t addr_1; | ||
454 | uint32_t addr_2; | ||
455 | uint32_t value_1; | ||
456 | uint8_t stride_1; | ||
457 | uint8_t stride_2; | ||
458 | uint16_t count; | ||
459 | uint32_t poll; | ||
460 | uint32_t mask; | ||
461 | uint32_t value_2; | ||
462 | uint32_t data_size; | ||
463 | |||
464 | } __packed; | ||
465 | |||
466 | struct qla8044_minidump_entry_pollwr { | ||
467 | struct qla8044_minidump_entry_hdr h; | ||
468 | uint32_t addr_1; | ||
469 | uint32_t addr_2; | ||
470 | uint32_t value_1; | ||
471 | uint32_t value_2; | ||
472 | uint32_t poll; | ||
473 | uint32_t mask; | ||
474 | uint32_t data_size; | ||
475 | uint32_t rsvd; | ||
476 | |||
477 | } __packed; | ||
478 | |||
434 | /* RDMUX2 Entry */ | 479 | /* RDMUX2 Entry */ |
435 | struct qla8044_minidump_entry_rdmux2 { | 480 | struct qla8044_minidump_entry_rdmux2 { |
436 | struct qla8044_minidump_entry_hdr h; | 481 | struct qla8044_minidump_entry_hdr h; |
@@ -516,6 +561,9 @@ static const uint32_t qla8044_reg_tbl[] = { | |||
516 | #define QLA8044_DBG_RSVD_ARRAY_LEN 8 | 561 | #define QLA8044_DBG_RSVD_ARRAY_LEN 8 |
517 | #define QLA8044_DBG_OCM_WNDREG_ARRAY_LEN 16 | 562 | #define QLA8044_DBG_OCM_WNDREG_ARRAY_LEN 16 |
518 | #define QLA8044_SS_PCI_INDEX 0 | 563 | #define QLA8044_SS_PCI_INDEX 0 |
564 | #define QLA8044_RDDFE 38 | ||
565 | #define QLA8044_RDMDIO 39 | ||
566 | #define QLA8044_POLLWR 40 | ||
519 | 567 | ||
520 | struct qla8044_minidump_template_hdr { | 568 | struct qla8044_minidump_template_hdr { |
521 | uint32_t entry_type; | 569 | uint32_t entry_type; |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 19e99cc33724..d96bfb55e57b 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -616,7 +616,7 @@ qla2x00_sp_free_dma(void *vha, void *ptr) | |||
616 | 616 | ||
617 | if (sp->flags & SRB_CRC_CTX_DSD_VALID) { | 617 | if (sp->flags & SRB_CRC_CTX_DSD_VALID) { |
618 | /* List assured to be having elements */ | 618 | /* List assured to be having elements */ |
619 | qla2x00_clean_dsd_pool(ha, sp); | 619 | qla2x00_clean_dsd_pool(ha, sp, NULL); |
620 | sp->flags &= ~SRB_CRC_CTX_DSD_VALID; | 620 | sp->flags &= ~SRB_CRC_CTX_DSD_VALID; |
621 | } | 621 | } |
622 | 622 | ||
@@ -781,7 +781,7 @@ static int | |||
781 | qla2x00_eh_wait_on_command(struct scsi_cmnd *cmd) | 781 | qla2x00_eh_wait_on_command(struct scsi_cmnd *cmd) |
782 | { | 782 | { |
783 | #define ABORT_POLLING_PERIOD 1000 | 783 | #define ABORT_POLLING_PERIOD 1000 |
784 | #define ABORT_WAIT_ITER ((10 * 1000) / (ABORT_POLLING_PERIOD)) | 784 | #define ABORT_WAIT_ITER ((2 * 1000) / (ABORT_POLLING_PERIOD)) |
785 | unsigned long wait_iter = ABORT_WAIT_ITER; | 785 | unsigned long wait_iter = ABORT_WAIT_ITER; |
786 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); | 786 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); |
787 | struct qla_hw_data *ha = vha->hw; | 787 | struct qla_hw_data *ha = vha->hw; |
@@ -844,11 +844,8 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *vha) | |||
844 | } | 844 | } |
845 | 845 | ||
846 | /* | 846 | /* |
847 | * qla2x00_wait_for_reset_ready | 847 | * qla2x00_wait_for_hba_ready |
848 | * Wait till the HBA is online after going through | 848 | * Wait till the HBA is ready before doing driver unload |
849 | * <= MAX_RETRIES_OF_ISP_ABORT or | ||
850 | * finally HBA is disabled ie marked offline or flash | ||
851 | * operations are in progress. | ||
852 | * | 849 | * |
853 | * Input: | 850 | * Input: |
854 | * ha - pointer to host adapter structure | 851 | * ha - pointer to host adapter structure |
@@ -857,35 +854,15 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *vha) | |||
857 | * Does context switching-Release SPIN_LOCK | 854 | * Does context switching-Release SPIN_LOCK |
858 | * (if any) before calling this routine. | 855 | * (if any) before calling this routine. |
859 | * | 856 | * |
860 | * Return: | ||
861 | * Success (Adapter is online/no flash ops) : 0 | ||
862 | * Failed (Adapter is offline/disabled/flash ops in progress) : 1 | ||
863 | */ | 857 | */ |
864 | static int | 858 | static void |
865 | qla2x00_wait_for_reset_ready(scsi_qla_host_t *vha) | 859 | qla2x00_wait_for_hba_ready(scsi_qla_host_t *vha) |
866 | { | 860 | { |
867 | int return_status; | ||
868 | unsigned long wait_online; | ||
869 | struct qla_hw_data *ha = vha->hw; | 861 | struct qla_hw_data *ha = vha->hw; |
870 | scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); | ||
871 | 862 | ||
872 | wait_online = jiffies + (MAX_LOOP_TIMEOUT * HZ); | 863 | while ((!(vha->flags.online) || ha->dpc_active || |
873 | while (((test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) || | 864 | ha->flags.mbox_busy)) |
874 | test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) || | ||
875 | test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) || | ||
876 | ha->optrom_state != QLA_SWAITING || | ||
877 | ha->dpc_active) && time_before(jiffies, wait_online)) | ||
878 | msleep(1000); | 865 | msleep(1000); |
879 | |||
880 | if (base_vha->flags.online && ha->optrom_state == QLA_SWAITING) | ||
881 | return_status = QLA_SUCCESS; | ||
882 | else | ||
883 | return_status = QLA_FUNCTION_FAILED; | ||
884 | |||
885 | ql_dbg(ql_dbg_taskm, vha, 0x8019, | ||
886 | "%s return status=%d.\n", __func__, return_status); | ||
887 | |||
888 | return return_status; | ||
889 | } | 866 | } |
890 | 867 | ||
891 | int | 868 | int |
@@ -945,7 +922,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
945 | int ret; | 922 | int ret; |
946 | unsigned int id, lun; | 923 | unsigned int id, lun; |
947 | unsigned long flags; | 924 | unsigned long flags; |
948 | int wait = 0; | 925 | int rval, wait = 0; |
949 | struct qla_hw_data *ha = vha->hw; | 926 | struct qla_hw_data *ha = vha->hw; |
950 | 927 | ||
951 | if (!CMD_SP(cmd)) | 928 | if (!CMD_SP(cmd)) |
@@ -974,10 +951,20 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
974 | sp_get(sp); | 951 | sp_get(sp); |
975 | 952 | ||
976 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 953 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
977 | if (ha->isp_ops->abort_command(sp)) { | 954 | rval = ha->isp_ops->abort_command(sp); |
978 | ret = FAILED; | 955 | if (rval) { |
956 | if (rval == QLA_FUNCTION_PARAMETER_ERROR) { | ||
957 | /* | ||
958 | * Decrement the ref_count since we can't find the | ||
959 | * command | ||
960 | */ | ||
961 | atomic_dec(&sp->ref_count); | ||
962 | ret = SUCCESS; | ||
963 | } else | ||
964 | ret = FAILED; | ||
965 | |||
979 | ql_dbg(ql_dbg_taskm, vha, 0x8003, | 966 | ql_dbg(ql_dbg_taskm, vha, 0x8003, |
980 | "Abort command mbx failed cmd=%p.\n", cmd); | 967 | "Abort command mbx failed cmd=%p, rval=%x.\n", cmd, rval); |
981 | } else { | 968 | } else { |
982 | ql_dbg(ql_dbg_taskm, vha, 0x8004, | 969 | ql_dbg(ql_dbg_taskm, vha, 0x8004, |
983 | "Abort command mbx success cmd=%p.\n", cmd); | 970 | "Abort command mbx success cmd=%p.\n", cmd); |
@@ -985,6 +972,12 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
985 | } | 972 | } |
986 | 973 | ||
987 | spin_lock_irqsave(&ha->hardware_lock, flags); | 974 | spin_lock_irqsave(&ha->hardware_lock, flags); |
975 | /* | ||
976 | * Clear the slot in the oustanding_cmds array if we can't find the | ||
977 | * command to reclaim the resources. | ||
978 | */ | ||
979 | if (rval == QLA_FUNCTION_PARAMETER_ERROR) | ||
980 | vha->req->outstanding_cmds[sp->handle] = NULL; | ||
988 | sp->done(ha, sp, 0); | 981 | sp->done(ha, sp, 0); |
989 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 982 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
990 | 983 | ||
@@ -1236,7 +1229,11 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) | |||
1236 | ql_log(ql_log_info, vha, 0x8018, | 1229 | ql_log(ql_log_info, vha, 0x8018, |
1237 | "ADAPTER RESET ISSUED nexus=%ld:%d:%d.\n", vha->host_no, id, lun); | 1230 | "ADAPTER RESET ISSUED nexus=%ld:%d:%d.\n", vha->host_no, id, lun); |
1238 | 1231 | ||
1239 | if (qla2x00_wait_for_reset_ready(vha) != QLA_SUCCESS) | 1232 | /* |
1233 | * No point in issuing another reset if one is active. Also do not | ||
1234 | * attempt a reset if we are updating flash. | ||
1235 | */ | ||
1236 | if (qla2x00_reset_active(vha) || ha->optrom_state != QLA_SWAITING) | ||
1240 | goto eh_host_reset_lock; | 1237 | goto eh_host_reset_lock; |
1241 | 1238 | ||
1242 | if (vha != base_vha) { | 1239 | if (vha != base_vha) { |
@@ -2270,6 +2267,13 @@ qla2x00_set_isp_flags(struct qla_hw_data *ha) | |||
2270 | ha->device_type |= DT_IIDMA; | 2267 | ha->device_type |= DT_IIDMA; |
2271 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; | 2268 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; |
2272 | break; | 2269 | break; |
2270 | case PCI_DEVICE_ID_QLOGIC_ISP2271: | ||
2271 | ha->device_type |= DT_ISP2271; | ||
2272 | ha->device_type |= DT_ZIO_SUPPORTED; | ||
2273 | ha->device_type |= DT_FWI2; | ||
2274 | ha->device_type |= DT_IIDMA; | ||
2275 | ha->fw_srisc_address = RISC_START_ADDRESS_2400; | ||
2276 | break; | ||
2273 | } | 2277 | } |
2274 | 2278 | ||
2275 | if (IS_QLA82XX(ha)) | 2279 | if (IS_QLA82XX(ha)) |
@@ -2346,7 +2350,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2346 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8031 || | 2350 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8031 || |
2347 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISPF001 || | 2351 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISPF001 || |
2348 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8044 || | 2352 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8044 || |
2349 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2071) { | 2353 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2071 || |
2354 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2271) { | ||
2350 | bars = pci_select_bars(pdev, IORESOURCE_MEM); | 2355 | bars = pci_select_bars(pdev, IORESOURCE_MEM); |
2351 | mem_only = 1; | 2356 | mem_only = 1; |
2352 | ql_dbg_pci(ql_dbg_init, pdev, 0x0007, | 2357 | ql_dbg_pci(ql_dbg_init, pdev, 0x0007, |
@@ -2877,6 +2882,7 @@ skip_dpc: | |||
2877 | 2882 | ||
2878 | base_vha->flags.init_done = 1; | 2883 | base_vha->flags.init_done = 1; |
2879 | base_vha->flags.online = 1; | 2884 | base_vha->flags.online = 1; |
2885 | ha->prev_minidump_failed = 0; | ||
2880 | 2886 | ||
2881 | ql_dbg(ql_dbg_init, base_vha, 0x00f2, | 2887 | ql_dbg(ql_dbg_init, base_vha, 0x00f2, |
2882 | "Init done and hba is online.\n"); | 2888 | "Init done and hba is online.\n"); |
@@ -3136,6 +3142,8 @@ qla2x00_remove_one(struct pci_dev *pdev) | |||
3136 | base_vha = pci_get_drvdata(pdev); | 3142 | base_vha = pci_get_drvdata(pdev); |
3137 | ha = base_vha->hw; | 3143 | ha = base_vha->hw; |
3138 | 3144 | ||
3145 | qla2x00_wait_for_hba_ready(base_vha); | ||
3146 | |||
3139 | set_bit(UNLOADING, &base_vha->dpc_flags); | 3147 | set_bit(UNLOADING, &base_vha->dpc_flags); |
3140 | 3148 | ||
3141 | if (IS_QLAFX00(ha)) | 3149 | if (IS_QLAFX00(ha)) |
@@ -3645,6 +3653,7 @@ qla2x00_free_fw_dump(struct qla_hw_data *ha) | |||
3645 | ha->eft = NULL; | 3653 | ha->eft = NULL; |
3646 | ha->eft_dma = 0; | 3654 | ha->eft_dma = 0; |
3647 | ha->fw_dumped = 0; | 3655 | ha->fw_dumped = 0; |
3656 | ha->fw_dump_cap_flags = 0; | ||
3648 | ha->fw_dump_reading = 0; | 3657 | ha->fw_dump_reading = 0; |
3649 | ha->fw_dump = NULL; | 3658 | ha->fw_dump = NULL; |
3650 | ha->fw_dump_len = 0; | 3659 | ha->fw_dump_len = 0; |
@@ -4828,7 +4837,7 @@ qla2x00_do_dpc(void *data) | |||
4828 | ha = (struct qla_hw_data *)data; | 4837 | ha = (struct qla_hw_data *)data; |
4829 | base_vha = pci_get_drvdata(ha->pdev); | 4838 | base_vha = pci_get_drvdata(ha->pdev); |
4830 | 4839 | ||
4831 | set_user_nice(current, -20); | 4840 | set_user_nice(current, MIN_NICE); |
4832 | 4841 | ||
4833 | set_current_state(TASK_INTERRUPTIBLE); | 4842 | set_current_state(TASK_INTERRUPTIBLE); |
4834 | while (!kthread_should_stop()) { | 4843 | while (!kthread_should_stop()) { |
@@ -4913,12 +4922,13 @@ qla2x00_do_dpc(void *data) | |||
4913 | if (qlafx00_reset_initialize(base_vha)) { | 4922 | if (qlafx00_reset_initialize(base_vha)) { |
4914 | /* Failed. Abort isp later. */ | 4923 | /* Failed. Abort isp later. */ |
4915 | if (!test_bit(UNLOADING, | 4924 | if (!test_bit(UNLOADING, |
4916 | &base_vha->dpc_flags)) | 4925 | &base_vha->dpc_flags)) { |
4917 | set_bit(ISP_UNRECOVERABLE, | 4926 | set_bit(ISP_UNRECOVERABLE, |
4918 | &base_vha->dpc_flags); | 4927 | &base_vha->dpc_flags); |
4919 | ql_dbg(ql_dbg_dpc, base_vha, | 4928 | ql_dbg(ql_dbg_dpc, base_vha, |
4920 | 0x4021, | 4929 | 0x4021, |
4921 | "Reset Recovery Failed\n"); | 4930 | "Reset Recovery Failed\n"); |
4931 | } | ||
4922 | } | 4932 | } |
4923 | } | 4933 | } |
4924 | 4934 | ||
@@ -5077,8 +5087,10 @@ intr_on_check: | |||
5077 | ha->isp_ops->enable_intrs(ha); | 5087 | ha->isp_ops->enable_intrs(ha); |
5078 | 5088 | ||
5079 | if (test_and_clear_bit(BEACON_BLINK_NEEDED, | 5089 | if (test_and_clear_bit(BEACON_BLINK_NEEDED, |
5080 | &base_vha->dpc_flags)) | 5090 | &base_vha->dpc_flags)) { |
5081 | ha->isp_ops->beacon_blink(base_vha); | 5091 | if (ha->beacon_blink_led == 1) |
5092 | ha->isp_ops->beacon_blink(base_vha); | ||
5093 | } | ||
5082 | 5094 | ||
5083 | if (!IS_QLAFX00(ha)) | 5095 | if (!IS_QLAFX00(ha)) |
5084 | qla2x00_do_dpc_all_vps(base_vha); | 5096 | qla2x00_do_dpc_all_vps(base_vha); |
@@ -5325,7 +5337,7 @@ qla2x00_timer(scsi_qla_host_t *vha) | |||
5325 | #define FW_ISP82XX 7 | 5337 | #define FW_ISP82XX 7 |
5326 | #define FW_ISP2031 8 | 5338 | #define FW_ISP2031 8 |
5327 | #define FW_ISP8031 9 | 5339 | #define FW_ISP8031 9 |
5328 | #define FW_ISP2071 10 | 5340 | #define FW_ISP27XX 10 |
5329 | 5341 | ||
5330 | #define FW_FILE_ISP21XX "ql2100_fw.bin" | 5342 | #define FW_FILE_ISP21XX "ql2100_fw.bin" |
5331 | #define FW_FILE_ISP22XX "ql2200_fw.bin" | 5343 | #define FW_FILE_ISP22XX "ql2200_fw.bin" |
@@ -5337,7 +5349,7 @@ qla2x00_timer(scsi_qla_host_t *vha) | |||
5337 | #define FW_FILE_ISP82XX "ql8200_fw.bin" | 5349 | #define FW_FILE_ISP82XX "ql8200_fw.bin" |
5338 | #define FW_FILE_ISP2031 "ql2600_fw.bin" | 5350 | #define FW_FILE_ISP2031 "ql2600_fw.bin" |
5339 | #define FW_FILE_ISP8031 "ql8300_fw.bin" | 5351 | #define FW_FILE_ISP8031 "ql8300_fw.bin" |
5340 | #define FW_FILE_ISP2071 "ql2700_fw.bin" | 5352 | #define FW_FILE_ISP27XX "ql2700_fw.bin" |
5341 | 5353 | ||
5342 | 5354 | ||
5343 | static DEFINE_MUTEX(qla_fw_lock); | 5355 | static DEFINE_MUTEX(qla_fw_lock); |
@@ -5353,7 +5365,7 @@ static struct fw_blob qla_fw_blobs[FW_BLOBS] = { | |||
5353 | { .name = FW_FILE_ISP82XX, }, | 5365 | { .name = FW_FILE_ISP82XX, }, |
5354 | { .name = FW_FILE_ISP2031, }, | 5366 | { .name = FW_FILE_ISP2031, }, |
5355 | { .name = FW_FILE_ISP8031, }, | 5367 | { .name = FW_FILE_ISP8031, }, |
5356 | { .name = FW_FILE_ISP2071, }, | 5368 | { .name = FW_FILE_ISP27XX, }, |
5357 | }; | 5369 | }; |
5358 | 5370 | ||
5359 | struct fw_blob * | 5371 | struct fw_blob * |
@@ -5382,8 +5394,8 @@ qla2x00_request_firmware(scsi_qla_host_t *vha) | |||
5382 | blob = &qla_fw_blobs[FW_ISP2031]; | 5394 | blob = &qla_fw_blobs[FW_ISP2031]; |
5383 | } else if (IS_QLA8031(ha)) { | 5395 | } else if (IS_QLA8031(ha)) { |
5384 | blob = &qla_fw_blobs[FW_ISP8031]; | 5396 | blob = &qla_fw_blobs[FW_ISP8031]; |
5385 | } else if (IS_QLA2071(ha)) { | 5397 | } else if (IS_QLA27XX(ha)) { |
5386 | blob = &qla_fw_blobs[FW_ISP2071]; | 5398 | blob = &qla_fw_blobs[FW_ISP27XX]; |
5387 | } else { | 5399 | } else { |
5388 | return NULL; | 5400 | return NULL; |
5389 | } | 5401 | } |
@@ -5714,6 +5726,7 @@ static struct pci_device_id qla2xxx_pci_tbl[] = { | |||
5714 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISPF001) }, | 5726 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISPF001) }, |
5715 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8044) }, | 5727 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8044) }, |
5716 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2071) }, | 5728 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2071) }, |
5729 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2271) }, | ||
5717 | { 0 }, | 5730 | { 0 }, |
5718 | }; | 5731 | }; |
5719 | MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); | 5732 | MODULE_DEVICE_TABLE(pci, qla2xxx_pci_tbl); |
diff --git a/drivers/scsi/qla2xxx/qla_settings.h b/drivers/scsi/qla2xxx/qla_settings.h index 46ef0ac48f44..2fb7ebfbbc38 100644 --- a/drivers/scsi/qla2xxx/qla_settings.h +++ b/drivers/scsi/qla2xxx/qla_settings.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index f28123e8ed65..bca173e56f16 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -1727,11 +1727,8 @@ qla83xx_beacon_blink(struct scsi_qla_host *vha) | |||
1727 | if (IS_QLA2031(ha)) { | 1727 | if (IS_QLA2031(ha)) { |
1728 | led_select_value = qla83xx_select_led_port(ha); | 1728 | led_select_value = qla83xx_select_led_port(ha); |
1729 | 1729 | ||
1730 | qla83xx_wr_reg(vha, led_select_value, 0x40002000); | 1730 | qla83xx_wr_reg(vha, led_select_value, 0x40000230); |
1731 | qla83xx_wr_reg(vha, led_select_value + 4, 0x40002000); | 1731 | qla83xx_wr_reg(vha, led_select_value + 4, 0x40000230); |
1732 | msleep(1000); | ||
1733 | qla83xx_wr_reg(vha, led_select_value, 0x40004000); | ||
1734 | qla83xx_wr_reg(vha, led_select_value + 4, 0x40004000); | ||
1735 | } else if (IS_QLA8031(ha)) { | 1732 | } else if (IS_QLA8031(ha)) { |
1736 | led_select_value = qla83xx_select_led_port(ha); | 1733 | led_select_value = qla83xx_select_led_port(ha); |
1737 | 1734 | ||
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index bd9c725c08e1..8d85ed8d8917 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c | |||
@@ -181,6 +181,11 @@ struct scsi_qla_host *qlt_find_host_by_vp_idx(struct scsi_qla_host *vha, | |||
181 | void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha, | 181 | void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha, |
182 | struct atio_from_isp *atio) | 182 | struct atio_from_isp *atio) |
183 | { | 183 | { |
184 | ql_dbg(ql_dbg_tgt, vha, 0xe072, | ||
185 | "%s: qla_target(%d): type %x ox_id %04x\n", | ||
186 | __func__, vha->vp_idx, atio->u.raw.entry_type, | ||
187 | be16_to_cpu(atio->u.isp24.fcp_hdr.ox_id)); | ||
188 | |||
184 | switch (atio->u.raw.entry_type) { | 189 | switch (atio->u.raw.entry_type) { |
185 | case ATIO_TYPE7: | 190 | case ATIO_TYPE7: |
186 | { | 191 | { |
@@ -235,6 +240,10 @@ void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha, | |||
235 | void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt) | 240 | void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, response_t *pkt) |
236 | { | 241 | { |
237 | switch (pkt->entry_type) { | 242 | switch (pkt->entry_type) { |
243 | case CTIO_CRC2: | ||
244 | ql_dbg(ql_dbg_tgt, vha, 0xe073, | ||
245 | "qla_target(%d):%s: CRC2 Response pkt\n", | ||
246 | vha->vp_idx, __func__); | ||
238 | case CTIO_TYPE7: | 247 | case CTIO_TYPE7: |
239 | { | 248 | { |
240 | struct ctio7_from_24xx *entry = (struct ctio7_from_24xx *)pkt; | 249 | struct ctio7_from_24xx *entry = (struct ctio7_from_24xx *)pkt; |
@@ -1349,13 +1358,42 @@ static int qlt_pci_map_calc_cnt(struct qla_tgt_prm *prm) | |||
1349 | 1358 | ||
1350 | prm->cmd->sg_mapped = 1; | 1359 | prm->cmd->sg_mapped = 1; |
1351 | 1360 | ||
1352 | /* | 1361 | if (cmd->se_cmd.prot_op == TARGET_PROT_NORMAL) { |
1353 | * If greater than four sg entries then we need to allocate | 1362 | /* |
1354 | * the continuation entries | 1363 | * If greater than four sg entries then we need to allocate |
1355 | */ | 1364 | * the continuation entries |
1356 | if (prm->seg_cnt > prm->tgt->datasegs_per_cmd) | 1365 | */ |
1357 | prm->req_cnt += DIV_ROUND_UP(prm->seg_cnt - | 1366 | if (prm->seg_cnt > prm->tgt->datasegs_per_cmd) |
1358 | prm->tgt->datasegs_per_cmd, prm->tgt->datasegs_per_cont); | 1367 | prm->req_cnt += DIV_ROUND_UP(prm->seg_cnt - |
1368 | prm->tgt->datasegs_per_cmd, | ||
1369 | prm->tgt->datasegs_per_cont); | ||
1370 | } else { | ||
1371 | /* DIF */ | ||
1372 | if ((cmd->se_cmd.prot_op == TARGET_PROT_DIN_INSERT) || | ||
1373 | (cmd->se_cmd.prot_op == TARGET_PROT_DOUT_STRIP)) { | ||
1374 | prm->seg_cnt = DIV_ROUND_UP(cmd->bufflen, cmd->blk_sz); | ||
1375 | prm->tot_dsds = prm->seg_cnt; | ||
1376 | } else | ||
1377 | prm->tot_dsds = prm->seg_cnt; | ||
1378 | |||
1379 | if (cmd->prot_sg_cnt) { | ||
1380 | prm->prot_sg = cmd->prot_sg; | ||
1381 | prm->prot_seg_cnt = pci_map_sg(prm->tgt->ha->pdev, | ||
1382 | cmd->prot_sg, cmd->prot_sg_cnt, | ||
1383 | cmd->dma_data_direction); | ||
1384 | if (unlikely(prm->prot_seg_cnt == 0)) | ||
1385 | goto out_err; | ||
1386 | |||
1387 | if ((cmd->se_cmd.prot_op == TARGET_PROT_DIN_INSERT) || | ||
1388 | (cmd->se_cmd.prot_op == TARGET_PROT_DOUT_STRIP)) { | ||
1389 | /* Dif Bundling not support here */ | ||
1390 | prm->prot_seg_cnt = DIV_ROUND_UP(cmd->bufflen, | ||
1391 | cmd->blk_sz); | ||
1392 | prm->tot_dsds += prm->prot_seg_cnt; | ||
1393 | } else | ||
1394 | prm->tot_dsds += prm->prot_seg_cnt; | ||
1395 | } | ||
1396 | } | ||
1359 | 1397 | ||
1360 | ql_dbg(ql_dbg_tgt, prm->cmd->vha, 0xe009, "seg_cnt=%d, req_cnt=%d\n", | 1398 | ql_dbg(ql_dbg_tgt, prm->cmd->vha, 0xe009, "seg_cnt=%d, req_cnt=%d\n", |
1361 | prm->seg_cnt, prm->req_cnt); | 1399 | prm->seg_cnt, prm->req_cnt); |
@@ -1376,6 +1414,16 @@ static inline void qlt_unmap_sg(struct scsi_qla_host *vha, | |||
1376 | BUG_ON(!cmd->sg_mapped); | 1414 | BUG_ON(!cmd->sg_mapped); |
1377 | pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, cmd->dma_data_direction); | 1415 | pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, cmd->dma_data_direction); |
1378 | cmd->sg_mapped = 0; | 1416 | cmd->sg_mapped = 0; |
1417 | |||
1418 | if (cmd->prot_sg_cnt) | ||
1419 | pci_unmap_sg(ha->pdev, cmd->prot_sg, cmd->prot_sg_cnt, | ||
1420 | cmd->dma_data_direction); | ||
1421 | |||
1422 | if (cmd->ctx_dsd_alloced) | ||
1423 | qla2x00_clean_dsd_pool(ha, NULL, cmd); | ||
1424 | |||
1425 | if (cmd->ctx) | ||
1426 | dma_pool_free(ha->dl_dma_pool, cmd->ctx, cmd->ctx->crc_ctx_dma); | ||
1379 | } | 1427 | } |
1380 | 1428 | ||
1381 | static int qlt_check_reserve_free_req(struct scsi_qla_host *vha, | 1429 | static int qlt_check_reserve_free_req(struct scsi_qla_host *vha, |
@@ -1664,8 +1712,9 @@ static int qlt_pre_xmit_response(struct qla_tgt_cmd *cmd, | |||
1664 | return QLA_TGT_PRE_XMIT_RESP_CMD_ABORTED; | 1712 | return QLA_TGT_PRE_XMIT_RESP_CMD_ABORTED; |
1665 | } | 1713 | } |
1666 | 1714 | ||
1667 | ql_dbg(ql_dbg_tgt, vha, 0xe011, "qla_target(%d): tag=%u\n", | 1715 | ql_dbg(ql_dbg_tgt, vha, 0xe011, "qla_target(%d): tag=%u ox_id %04x\n", |
1668 | vha->vp_idx, cmd->tag); | 1716 | vha->vp_idx, cmd->tag, |
1717 | be16_to_cpu(cmd->atio.u.isp24.fcp_hdr.ox_id)); | ||
1669 | 1718 | ||
1670 | prm->cmd = cmd; | 1719 | prm->cmd = cmd; |
1671 | prm->tgt = tgt; | 1720 | prm->tgt = tgt; |
@@ -1901,6 +1950,323 @@ skip_explict_conf: | |||
1901 | /* Sense with len > 24, is it possible ??? */ | 1950 | /* Sense with len > 24, is it possible ??? */ |
1902 | } | 1951 | } |
1903 | 1952 | ||
1953 | |||
1954 | |||
1955 | /* diff */ | ||
1956 | static inline int | ||
1957 | qlt_hba_err_chk_enabled(struct se_cmd *se_cmd) | ||
1958 | { | ||
1959 | /* | ||
1960 | * Uncomment when corresponding SCSI changes are done. | ||
1961 | * | ||
1962 | if (!sp->cmd->prot_chk) | ||
1963 | return 0; | ||
1964 | * | ||
1965 | */ | ||
1966 | switch (se_cmd->prot_op) { | ||
1967 | case TARGET_PROT_DOUT_INSERT: | ||
1968 | case TARGET_PROT_DIN_STRIP: | ||
1969 | if (ql2xenablehba_err_chk >= 1) | ||
1970 | return 1; | ||
1971 | break; | ||
1972 | case TARGET_PROT_DOUT_PASS: | ||
1973 | case TARGET_PROT_DIN_PASS: | ||
1974 | if (ql2xenablehba_err_chk >= 2) | ||
1975 | return 1; | ||
1976 | break; | ||
1977 | case TARGET_PROT_DIN_INSERT: | ||
1978 | case TARGET_PROT_DOUT_STRIP: | ||
1979 | return 1; | ||
1980 | default: | ||
1981 | break; | ||
1982 | } | ||
1983 | return 0; | ||
1984 | } | ||
1985 | |||
1986 | /* | ||
1987 | * qla24xx_set_t10dif_tags_from_cmd - Extract Ref and App tags from SCSI command | ||
1988 | * | ||
1989 | */ | ||
1990 | static inline void | ||
1991 | qlt_set_t10dif_tags(struct se_cmd *se_cmd, struct crc_context *ctx) | ||
1992 | { | ||
1993 | uint32_t lba = 0xffffffff & se_cmd->t_task_lba; | ||
1994 | |||
1995 | /* wait til Mode Sense/Select cmd, modepage Ah, subpage 2 | ||
1996 | * have been immplemented by TCM, before AppTag is avail. | ||
1997 | * Look for modesense_handlers[] | ||
1998 | */ | ||
1999 | ctx->app_tag = __constant_cpu_to_le16(0); | ||
2000 | ctx->app_tag_mask[0] = 0x0; | ||
2001 | ctx->app_tag_mask[1] = 0x0; | ||
2002 | |||
2003 | switch (se_cmd->prot_type) { | ||
2004 | case TARGET_DIF_TYPE0_PROT: | ||
2005 | /* | ||
2006 | * No check for ql2xenablehba_err_chk, as it would be an | ||
2007 | * I/O error if hba tag generation is not done. | ||
2008 | */ | ||
2009 | ctx->ref_tag = cpu_to_le32(lba); | ||
2010 | |||
2011 | if (!qlt_hba_err_chk_enabled(se_cmd)) | ||
2012 | break; | ||
2013 | |||
2014 | /* enable ALL bytes of the ref tag */ | ||
2015 | ctx->ref_tag_mask[0] = 0xff; | ||
2016 | ctx->ref_tag_mask[1] = 0xff; | ||
2017 | ctx->ref_tag_mask[2] = 0xff; | ||
2018 | ctx->ref_tag_mask[3] = 0xff; | ||
2019 | break; | ||
2020 | /* | ||
2021 | * For TYpe 1 protection: 16 bit GUARD tag, 32 bit REF tag, and | ||
2022 | * 16 bit app tag. | ||
2023 | */ | ||
2024 | case TARGET_DIF_TYPE1_PROT: | ||
2025 | ctx->ref_tag = cpu_to_le32(lba); | ||
2026 | |||
2027 | if (!qlt_hba_err_chk_enabled(se_cmd)) | ||
2028 | break; | ||
2029 | |||
2030 | /* enable ALL bytes of the ref tag */ | ||
2031 | ctx->ref_tag_mask[0] = 0xff; | ||
2032 | ctx->ref_tag_mask[1] = 0xff; | ||
2033 | ctx->ref_tag_mask[2] = 0xff; | ||
2034 | ctx->ref_tag_mask[3] = 0xff; | ||
2035 | break; | ||
2036 | /* | ||
2037 | * For TYPE 2 protection: 16 bit GUARD + 32 bit REF tag has to | ||
2038 | * match LBA in CDB + N | ||
2039 | */ | ||
2040 | case TARGET_DIF_TYPE2_PROT: | ||
2041 | ctx->ref_tag = cpu_to_le32(lba); | ||
2042 | |||
2043 | if (!qlt_hba_err_chk_enabled(se_cmd)) | ||
2044 | break; | ||
2045 | |||
2046 | /* enable ALL bytes of the ref tag */ | ||
2047 | ctx->ref_tag_mask[0] = 0xff; | ||
2048 | ctx->ref_tag_mask[1] = 0xff; | ||
2049 | ctx->ref_tag_mask[2] = 0xff; | ||
2050 | ctx->ref_tag_mask[3] = 0xff; | ||
2051 | break; | ||
2052 | |||
2053 | /* For Type 3 protection: 16 bit GUARD only */ | ||
2054 | case TARGET_DIF_TYPE3_PROT: | ||
2055 | ctx->ref_tag_mask[0] = ctx->ref_tag_mask[1] = | ||
2056 | ctx->ref_tag_mask[2] = ctx->ref_tag_mask[3] = 0x00; | ||
2057 | break; | ||
2058 | } | ||
2059 | } | ||
2060 | |||
2061 | |||
2062 | static inline int | ||
2063 | qlt_build_ctio_crc2_pkt(struct qla_tgt_prm *prm, scsi_qla_host_t *vha) | ||
2064 | { | ||
2065 | uint32_t *cur_dsd; | ||
2066 | int sgc; | ||
2067 | uint32_t transfer_length = 0; | ||
2068 | uint32_t data_bytes; | ||
2069 | uint32_t dif_bytes; | ||
2070 | uint8_t bundling = 1; | ||
2071 | uint8_t *clr_ptr; | ||
2072 | struct crc_context *crc_ctx_pkt = NULL; | ||
2073 | struct qla_hw_data *ha; | ||
2074 | struct ctio_crc2_to_fw *pkt; | ||
2075 | dma_addr_t crc_ctx_dma; | ||
2076 | uint16_t fw_prot_opts = 0; | ||
2077 | struct qla_tgt_cmd *cmd = prm->cmd; | ||
2078 | struct se_cmd *se_cmd = &cmd->se_cmd; | ||
2079 | uint32_t h; | ||
2080 | struct atio_from_isp *atio = &prm->cmd->atio; | ||
2081 | |||
2082 | sgc = 0; | ||
2083 | ha = vha->hw; | ||
2084 | |||
2085 | pkt = (struct ctio_crc2_to_fw *)vha->req->ring_ptr; | ||
2086 | prm->pkt = pkt; | ||
2087 | memset(pkt, 0, sizeof(*pkt)); | ||
2088 | |||
2089 | ql_dbg(ql_dbg_tgt, vha, 0xe071, | ||
2090 | "qla_target(%d):%s: se_cmd[%p] CRC2 prot_op[0x%x] cmd prot sg:cnt[%p:%x] lba[%llu]\n", | ||
2091 | vha->vp_idx, __func__, se_cmd, se_cmd->prot_op, | ||
2092 | prm->prot_sg, prm->prot_seg_cnt, se_cmd->t_task_lba); | ||
2093 | |||
2094 | if ((se_cmd->prot_op == TARGET_PROT_DIN_INSERT) || | ||
2095 | (se_cmd->prot_op == TARGET_PROT_DOUT_STRIP)) | ||
2096 | bundling = 0; | ||
2097 | |||
2098 | /* Compute dif len and adjust data len to incude protection */ | ||
2099 | data_bytes = cmd->bufflen; | ||
2100 | dif_bytes = (data_bytes / cmd->blk_sz) * 8; | ||
2101 | |||
2102 | switch (se_cmd->prot_op) { | ||
2103 | case TARGET_PROT_DIN_INSERT: | ||
2104 | case TARGET_PROT_DOUT_STRIP: | ||
2105 | transfer_length = data_bytes; | ||
2106 | data_bytes += dif_bytes; | ||
2107 | break; | ||
2108 | |||
2109 | case TARGET_PROT_DIN_STRIP: | ||
2110 | case TARGET_PROT_DOUT_INSERT: | ||
2111 | case TARGET_PROT_DIN_PASS: | ||
2112 | case TARGET_PROT_DOUT_PASS: | ||
2113 | transfer_length = data_bytes + dif_bytes; | ||
2114 | break; | ||
2115 | |||
2116 | default: | ||
2117 | BUG(); | ||
2118 | break; | ||
2119 | } | ||
2120 | |||
2121 | if (!qlt_hba_err_chk_enabled(se_cmd)) | ||
2122 | fw_prot_opts |= 0x10; /* Disable Guard tag checking */ | ||
2123 | /* HBA error checking enabled */ | ||
2124 | else if (IS_PI_UNINIT_CAPABLE(ha)) { | ||
2125 | if ((se_cmd->prot_type == TARGET_DIF_TYPE1_PROT) || | ||
2126 | (se_cmd->prot_type == TARGET_DIF_TYPE2_PROT)) | ||
2127 | fw_prot_opts |= PO_DIS_VALD_APP_ESC; | ||
2128 | else if (se_cmd->prot_type == TARGET_DIF_TYPE3_PROT) | ||
2129 | fw_prot_opts |= PO_DIS_VALD_APP_REF_ESC; | ||
2130 | } | ||
2131 | |||
2132 | switch (se_cmd->prot_op) { | ||
2133 | case TARGET_PROT_DIN_INSERT: | ||
2134 | case TARGET_PROT_DOUT_INSERT: | ||
2135 | fw_prot_opts |= PO_MODE_DIF_INSERT; | ||
2136 | break; | ||
2137 | case TARGET_PROT_DIN_STRIP: | ||
2138 | case TARGET_PROT_DOUT_STRIP: | ||
2139 | fw_prot_opts |= PO_MODE_DIF_REMOVE; | ||
2140 | break; | ||
2141 | case TARGET_PROT_DIN_PASS: | ||
2142 | case TARGET_PROT_DOUT_PASS: | ||
2143 | fw_prot_opts |= PO_MODE_DIF_PASS; | ||
2144 | /* FUTURE: does tcm require T10CRC<->IPCKSUM conversion? */ | ||
2145 | break; | ||
2146 | default:/* Normal Request */ | ||
2147 | fw_prot_opts |= PO_MODE_DIF_PASS; | ||
2148 | break; | ||
2149 | } | ||
2150 | |||
2151 | |||
2152 | /* ---- PKT ---- */ | ||
2153 | /* Update entry type to indicate Command Type CRC_2 IOCB */ | ||
2154 | pkt->entry_type = CTIO_CRC2; | ||
2155 | pkt->entry_count = 1; | ||
2156 | pkt->vp_index = vha->vp_idx; | ||
2157 | |||
2158 | h = qlt_make_handle(vha); | ||
2159 | if (unlikely(h == QLA_TGT_NULL_HANDLE)) { | ||
2160 | /* | ||
2161 | * CTIO type 7 from the firmware doesn't provide a way to | ||
2162 | * know the initiator's LOOP ID, hence we can't find | ||
2163 | * the session and, so, the command. | ||
2164 | */ | ||
2165 | return -EAGAIN; | ||
2166 | } else | ||
2167 | ha->tgt.cmds[h-1] = prm->cmd; | ||
2168 | |||
2169 | |||
2170 | pkt->handle = h | CTIO_COMPLETION_HANDLE_MARK; | ||
2171 | pkt->nport_handle = prm->cmd->loop_id; | ||
2172 | pkt->timeout = __constant_cpu_to_le16(QLA_TGT_TIMEOUT); | ||
2173 | pkt->initiator_id[0] = atio->u.isp24.fcp_hdr.s_id[2]; | ||
2174 | pkt->initiator_id[1] = atio->u.isp24.fcp_hdr.s_id[1]; | ||
2175 | pkt->initiator_id[2] = atio->u.isp24.fcp_hdr.s_id[0]; | ||
2176 | pkt->exchange_addr = atio->u.isp24.exchange_addr; | ||
2177 | pkt->ox_id = swab16(atio->u.isp24.fcp_hdr.ox_id); | ||
2178 | pkt->flags |= (atio->u.isp24.attr << 9); | ||
2179 | pkt->relative_offset = cpu_to_le32(prm->cmd->offset); | ||
2180 | |||
2181 | /* Set transfer direction */ | ||
2182 | if (cmd->dma_data_direction == DMA_TO_DEVICE) | ||
2183 | pkt->flags = __constant_cpu_to_le16(CTIO7_FLAGS_DATA_IN); | ||
2184 | else if (cmd->dma_data_direction == DMA_FROM_DEVICE) | ||
2185 | pkt->flags = __constant_cpu_to_le16(CTIO7_FLAGS_DATA_OUT); | ||
2186 | |||
2187 | |||
2188 | pkt->dseg_count = prm->tot_dsds; | ||
2189 | /* Fibre channel byte count */ | ||
2190 | pkt->transfer_length = cpu_to_le32(transfer_length); | ||
2191 | |||
2192 | |||
2193 | /* ----- CRC context -------- */ | ||
2194 | |||
2195 | /* Allocate CRC context from global pool */ | ||
2196 | crc_ctx_pkt = cmd->ctx = | ||
2197 | dma_pool_alloc(ha->dl_dma_pool, GFP_ATOMIC, &crc_ctx_dma); | ||
2198 | |||
2199 | if (!crc_ctx_pkt) | ||
2200 | goto crc_queuing_error; | ||
2201 | |||
2202 | /* Zero out CTX area. */ | ||
2203 | clr_ptr = (uint8_t *)crc_ctx_pkt; | ||
2204 | memset(clr_ptr, 0, sizeof(*crc_ctx_pkt)); | ||
2205 | |||
2206 | crc_ctx_pkt->crc_ctx_dma = crc_ctx_dma; | ||
2207 | INIT_LIST_HEAD(&crc_ctx_pkt->dsd_list); | ||
2208 | |||
2209 | /* Set handle */ | ||
2210 | crc_ctx_pkt->handle = pkt->handle; | ||
2211 | |||
2212 | qlt_set_t10dif_tags(se_cmd, crc_ctx_pkt); | ||
2213 | |||
2214 | pkt->crc_context_address[0] = cpu_to_le32(LSD(crc_ctx_dma)); | ||
2215 | pkt->crc_context_address[1] = cpu_to_le32(MSD(crc_ctx_dma)); | ||
2216 | pkt->crc_context_len = CRC_CONTEXT_LEN_FW; | ||
2217 | |||
2218 | |||
2219 | if (!bundling) { | ||
2220 | cur_dsd = (uint32_t *) &crc_ctx_pkt->u.nobundling.data_address; | ||
2221 | } else { | ||
2222 | /* | ||
2223 | * Configure Bundling if we need to fetch interlaving | ||
2224 | * protection PCI accesses | ||
2225 | */ | ||
2226 | fw_prot_opts |= PO_ENABLE_DIF_BUNDLING; | ||
2227 | crc_ctx_pkt->u.bundling.dif_byte_count = cpu_to_le32(dif_bytes); | ||
2228 | crc_ctx_pkt->u.bundling.dseg_count = | ||
2229 | cpu_to_le16(prm->tot_dsds - prm->prot_seg_cnt); | ||
2230 | cur_dsd = (uint32_t *) &crc_ctx_pkt->u.bundling.data_address; | ||
2231 | } | ||
2232 | |||
2233 | /* Finish the common fields of CRC pkt */ | ||
2234 | crc_ctx_pkt->blk_size = cpu_to_le16(cmd->blk_sz); | ||
2235 | crc_ctx_pkt->prot_opts = cpu_to_le16(fw_prot_opts); | ||
2236 | crc_ctx_pkt->byte_count = cpu_to_le32(data_bytes); | ||
2237 | crc_ctx_pkt->guard_seed = __constant_cpu_to_le16(0); | ||
2238 | |||
2239 | |||
2240 | /* Walks data segments */ | ||
2241 | pkt->flags |= __constant_cpu_to_le16(CTIO7_FLAGS_DSD_PTR); | ||
2242 | |||
2243 | if (!bundling && prm->prot_seg_cnt) { | ||
2244 | if (qla24xx_walk_and_build_sglist_no_difb(ha, NULL, cur_dsd, | ||
2245 | prm->tot_dsds, cmd)) | ||
2246 | goto crc_queuing_error; | ||
2247 | } else if (qla24xx_walk_and_build_sglist(ha, NULL, cur_dsd, | ||
2248 | (prm->tot_dsds - prm->prot_seg_cnt), cmd)) | ||
2249 | goto crc_queuing_error; | ||
2250 | |||
2251 | if (bundling && prm->prot_seg_cnt) { | ||
2252 | /* Walks dif segments */ | ||
2253 | pkt->add_flags |= | ||
2254 | __constant_cpu_to_le16(CTIO_CRC2_AF_DIF_DSD_ENA); | ||
2255 | |||
2256 | cur_dsd = (uint32_t *) &crc_ctx_pkt->u.bundling.dif_address; | ||
2257 | if (qla24xx_walk_and_build_prot_sglist(ha, NULL, cur_dsd, | ||
2258 | prm->prot_seg_cnt, cmd)) | ||
2259 | goto crc_queuing_error; | ||
2260 | } | ||
2261 | return QLA_SUCCESS; | ||
2262 | |||
2263 | crc_queuing_error: | ||
2264 | /* Cleanup will be performed by the caller */ | ||
2265 | |||
2266 | return QLA_FUNCTION_FAILED; | ||
2267 | } | ||
2268 | |||
2269 | |||
1904 | /* | 2270 | /* |
1905 | * Callback to setup response of xmit_type of QLA_TGT_XMIT_DATA and * | 2271 | * Callback to setup response of xmit_type of QLA_TGT_XMIT_DATA and * |
1906 | * QLA_TGT_XMIT_STATUS for >= 24xx silicon | 2272 | * QLA_TGT_XMIT_STATUS for >= 24xx silicon |
@@ -1920,9 +2286,10 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, | |||
1920 | qlt_check_srr_debug(cmd, &xmit_type); | 2286 | qlt_check_srr_debug(cmd, &xmit_type); |
1921 | 2287 | ||
1922 | ql_dbg(ql_dbg_tgt, cmd->vha, 0xe018, | 2288 | ql_dbg(ql_dbg_tgt, cmd->vha, 0xe018, |
1923 | "is_send_status=%d, cmd->bufflen=%d, cmd->sg_cnt=%d, " | 2289 | "is_send_status=%d, cmd->bufflen=%d, cmd->sg_cnt=%d, cmd->dma_data_direction=%d se_cmd[%p]\n", |
1924 | "cmd->dma_data_direction=%d\n", (xmit_type & QLA_TGT_XMIT_STATUS) ? | 2290 | (xmit_type & QLA_TGT_XMIT_STATUS) ? |
1925 | 1 : 0, cmd->bufflen, cmd->sg_cnt, cmd->dma_data_direction); | 2291 | 1 : 0, cmd->bufflen, cmd->sg_cnt, cmd->dma_data_direction, |
2292 | &cmd->se_cmd); | ||
1926 | 2293 | ||
1927 | res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status, | 2294 | res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status, |
1928 | &full_req_cnt); | 2295 | &full_req_cnt); |
@@ -1940,7 +2307,10 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, | |||
1940 | if (unlikely(res)) | 2307 | if (unlikely(res)) |
1941 | goto out_unmap_unlock; | 2308 | goto out_unmap_unlock; |
1942 | 2309 | ||
1943 | res = qlt_24xx_build_ctio_pkt(&prm, vha); | 2310 | if (cmd->se_cmd.prot_op && (xmit_type & QLA_TGT_XMIT_DATA)) |
2311 | res = qlt_build_ctio_crc2_pkt(&prm, vha); | ||
2312 | else | ||
2313 | res = qlt_24xx_build_ctio_pkt(&prm, vha); | ||
1944 | if (unlikely(res != 0)) | 2314 | if (unlikely(res != 0)) |
1945 | goto out_unmap_unlock; | 2315 | goto out_unmap_unlock; |
1946 | 2316 | ||
@@ -1952,7 +2322,8 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, | |||
1952 | __constant_cpu_to_le16(CTIO7_FLAGS_DATA_IN | | 2322 | __constant_cpu_to_le16(CTIO7_FLAGS_DATA_IN | |
1953 | CTIO7_FLAGS_STATUS_MODE_0); | 2323 | CTIO7_FLAGS_STATUS_MODE_0); |
1954 | 2324 | ||
1955 | qlt_load_data_segments(&prm, vha); | 2325 | if (cmd->se_cmd.prot_op == TARGET_PROT_NORMAL) |
2326 | qlt_load_data_segments(&prm, vha); | ||
1956 | 2327 | ||
1957 | if (prm.add_status_pkt == 0) { | 2328 | if (prm.add_status_pkt == 0) { |
1958 | if (xmit_type & QLA_TGT_XMIT_STATUS) { | 2329 | if (xmit_type & QLA_TGT_XMIT_STATUS) { |
@@ -1982,8 +2353,14 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, | |||
1982 | ql_dbg(ql_dbg_tgt, vha, 0xe019, | 2353 | ql_dbg(ql_dbg_tgt, vha, 0xe019, |
1983 | "Building additional status packet\n"); | 2354 | "Building additional status packet\n"); |
1984 | 2355 | ||
2356 | /* | ||
2357 | * T10Dif: ctio_crc2_to_fw overlay ontop of | ||
2358 | * ctio7_to_24xx | ||
2359 | */ | ||
1985 | memcpy(ctio, pkt, sizeof(*ctio)); | 2360 | memcpy(ctio, pkt, sizeof(*ctio)); |
2361 | /* reset back to CTIO7 */ | ||
1986 | ctio->entry_count = 1; | 2362 | ctio->entry_count = 1; |
2363 | ctio->entry_type = CTIO_TYPE7; | ||
1987 | ctio->dseg_count = 0; | 2364 | ctio->dseg_count = 0; |
1988 | ctio->u.status1.flags &= ~__constant_cpu_to_le16( | 2365 | ctio->u.status1.flags &= ~__constant_cpu_to_le16( |
1989 | CTIO7_FLAGS_DATA_IN); | 2366 | CTIO7_FLAGS_DATA_IN); |
@@ -1992,6 +2369,11 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type, | |||
1992 | pkt->handle |= CTIO_INTERMEDIATE_HANDLE_MARK; | 2369 | pkt->handle |= CTIO_INTERMEDIATE_HANDLE_MARK; |
1993 | pkt->u.status0.flags |= __constant_cpu_to_le16( | 2370 | pkt->u.status0.flags |= __constant_cpu_to_le16( |
1994 | CTIO7_FLAGS_DONT_RET_CTIO); | 2371 | CTIO7_FLAGS_DONT_RET_CTIO); |
2372 | |||
2373 | /* qlt_24xx_init_ctio_to_isp will correct | ||
2374 | * all neccessary fields that's part of CTIO7. | ||
2375 | * There should be no residual of CTIO-CRC2 data. | ||
2376 | */ | ||
1995 | qlt_24xx_init_ctio_to_isp((struct ctio7_to_24xx *)ctio, | 2377 | qlt_24xx_init_ctio_to_isp((struct ctio7_to_24xx *)ctio, |
1996 | &prm); | 2378 | &prm); |
1997 | pr_debug("Status CTIO7: %p\n", ctio); | 2379 | pr_debug("Status CTIO7: %p\n", ctio); |
@@ -2040,8 +2422,10 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd) | |||
2040 | if (qlt_issue_marker(vha, 0) != QLA_SUCCESS) | 2422 | if (qlt_issue_marker(vha, 0) != QLA_SUCCESS) |
2041 | return -EIO; | 2423 | return -EIO; |
2042 | 2424 | ||
2043 | ql_dbg(ql_dbg_tgt, vha, 0xe01b, "CTIO_start: vha(%d)", | 2425 | ql_dbg(ql_dbg_tgt, vha, 0xe01b, |
2044 | (int)vha->vp_idx); | 2426 | "%s: CTIO_start: vha(%d) se_cmd %p ox_id %04x\n", |
2427 | __func__, (int)vha->vp_idx, &cmd->se_cmd, | ||
2428 | be16_to_cpu(cmd->atio.u.isp24.fcp_hdr.ox_id)); | ||
2045 | 2429 | ||
2046 | /* Calculate number of entries and segments required */ | 2430 | /* Calculate number of entries and segments required */ |
2047 | if (qlt_pci_map_calc_cnt(&prm) != 0) | 2431 | if (qlt_pci_map_calc_cnt(&prm) != 0) |
@@ -2053,14 +2437,19 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd) | |||
2053 | res = qlt_check_reserve_free_req(vha, prm.req_cnt); | 2437 | res = qlt_check_reserve_free_req(vha, prm.req_cnt); |
2054 | if (res != 0) | 2438 | if (res != 0) |
2055 | goto out_unlock_free_unmap; | 2439 | goto out_unlock_free_unmap; |
2440 | if (cmd->se_cmd.prot_op) | ||
2441 | res = qlt_build_ctio_crc2_pkt(&prm, vha); | ||
2442 | else | ||
2443 | res = qlt_24xx_build_ctio_pkt(&prm, vha); | ||
2056 | 2444 | ||
2057 | res = qlt_24xx_build_ctio_pkt(&prm, vha); | ||
2058 | if (unlikely(res != 0)) | 2445 | if (unlikely(res != 0)) |
2059 | goto out_unlock_free_unmap; | 2446 | goto out_unlock_free_unmap; |
2060 | pkt = (struct ctio7_to_24xx *)prm.pkt; | 2447 | pkt = (struct ctio7_to_24xx *)prm.pkt; |
2061 | pkt->u.status0.flags |= __constant_cpu_to_le16(CTIO7_FLAGS_DATA_OUT | | 2448 | pkt->u.status0.flags |= __constant_cpu_to_le16(CTIO7_FLAGS_DATA_OUT | |
2062 | CTIO7_FLAGS_STATUS_MODE_0); | 2449 | CTIO7_FLAGS_STATUS_MODE_0); |
2063 | qlt_load_data_segments(&prm, vha); | 2450 | |
2451 | if (cmd->se_cmd.prot_op == TARGET_PROT_NORMAL) | ||
2452 | qlt_load_data_segments(&prm, vha); | ||
2064 | 2453 | ||
2065 | cmd->state = QLA_TGT_STATE_NEED_DATA; | 2454 | cmd->state = QLA_TGT_STATE_NEED_DATA; |
2066 | 2455 | ||
@@ -2078,6 +2467,143 @@ out_unlock_free_unmap: | |||
2078 | } | 2467 | } |
2079 | EXPORT_SYMBOL(qlt_rdy_to_xfer); | 2468 | EXPORT_SYMBOL(qlt_rdy_to_xfer); |
2080 | 2469 | ||
2470 | |||
2471 | /* | ||
2472 | * Checks the guard or meta-data for the type of error | ||
2473 | * detected by the HBA. | ||
2474 | */ | ||
2475 | static inline int | ||
2476 | qlt_handle_dif_error(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd, | ||
2477 | struct ctio_crc_from_fw *sts) | ||
2478 | { | ||
2479 | uint8_t *ap = &sts->actual_dif[0]; | ||
2480 | uint8_t *ep = &sts->expected_dif[0]; | ||
2481 | uint32_t e_ref_tag, a_ref_tag; | ||
2482 | uint16_t e_app_tag, a_app_tag; | ||
2483 | uint16_t e_guard, a_guard; | ||
2484 | uint64_t lba = cmd->se_cmd.t_task_lba; | ||
2485 | |||
2486 | a_guard = be16_to_cpu(*(uint16_t *)(ap + 0)); | ||
2487 | a_app_tag = be16_to_cpu(*(uint16_t *)(ap + 2)); | ||
2488 | a_ref_tag = be32_to_cpu(*(uint32_t *)(ap + 4)); | ||
2489 | |||
2490 | e_guard = be16_to_cpu(*(uint16_t *)(ep + 0)); | ||
2491 | e_app_tag = be16_to_cpu(*(uint16_t *)(ep + 2)); | ||
2492 | e_ref_tag = be32_to_cpu(*(uint32_t *)(ep + 4)); | ||
2493 | |||
2494 | ql_dbg(ql_dbg_tgt, vha, 0xe075, | ||
2495 | "iocb(s) %p Returned STATUS.\n", sts); | ||
2496 | |||
2497 | ql_dbg(ql_dbg_tgt, vha, 0xf075, | ||
2498 | "dif check TGT cdb 0x%x lba 0x%llu: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x]\n", | ||
2499 | cmd->atio.u.isp24.fcp_cmnd.cdb[0], lba, | ||
2500 | a_ref_tag, e_ref_tag, a_app_tag, e_app_tag, a_guard, e_guard); | ||
2501 | |||
2502 | /* | ||
2503 | * Ignore sector if: | ||
2504 | * For type 3: ref & app tag is all 'f's | ||
2505 | * For type 0,1,2: app tag is all 'f's | ||
2506 | */ | ||
2507 | if ((a_app_tag == 0xffff) && | ||
2508 | ((cmd->se_cmd.prot_type != TARGET_DIF_TYPE3_PROT) || | ||
2509 | (a_ref_tag == 0xffffffff))) { | ||
2510 | uint32_t blocks_done; | ||
2511 | |||
2512 | /* 2TB boundary case covered automatically with this */ | ||
2513 | blocks_done = e_ref_tag - (uint32_t)lba + 1; | ||
2514 | cmd->se_cmd.bad_sector = e_ref_tag; | ||
2515 | cmd->se_cmd.pi_err = 0; | ||
2516 | ql_dbg(ql_dbg_tgt, vha, 0xf074, | ||
2517 | "need to return scsi good\n"); | ||
2518 | |||
2519 | /* Update protection tag */ | ||
2520 | if (cmd->prot_sg_cnt) { | ||
2521 | uint32_t i, j = 0, k = 0, num_ent; | ||
2522 | struct scatterlist *sg, *sgl; | ||
2523 | |||
2524 | |||
2525 | sgl = cmd->prot_sg; | ||
2526 | |||
2527 | /* Patch the corresponding protection tags */ | ||
2528 | for_each_sg(sgl, sg, cmd->prot_sg_cnt, i) { | ||
2529 | num_ent = sg_dma_len(sg) / 8; | ||
2530 | if (k + num_ent < blocks_done) { | ||
2531 | k += num_ent; | ||
2532 | continue; | ||
2533 | } | ||
2534 | j = blocks_done - k - 1; | ||
2535 | k = blocks_done; | ||
2536 | break; | ||
2537 | } | ||
2538 | |||
2539 | if (k != blocks_done) { | ||
2540 | ql_log(ql_log_warn, vha, 0xf076, | ||
2541 | "unexpected tag values tag:lba=%u:%llu)\n", | ||
2542 | e_ref_tag, (unsigned long long)lba); | ||
2543 | goto out; | ||
2544 | } | ||
2545 | |||
2546 | #if 0 | ||
2547 | struct sd_dif_tuple *spt; | ||
2548 | /* TODO: | ||
2549 | * This section came from initiator. Is it valid here? | ||
2550 | * should ulp be override with actual val??? | ||
2551 | */ | ||
2552 | spt = page_address(sg_page(sg)) + sg->offset; | ||
2553 | spt += j; | ||
2554 | |||
2555 | spt->app_tag = 0xffff; | ||
2556 | if (cmd->se_cmd.prot_type == SCSI_PROT_DIF_TYPE3) | ||
2557 | spt->ref_tag = 0xffffffff; | ||
2558 | #endif | ||
2559 | } | ||
2560 | |||
2561 | return 0; | ||
2562 | } | ||
2563 | |||
2564 | /* check guard */ | ||
2565 | if (e_guard != a_guard) { | ||
2566 | cmd->se_cmd.pi_err = TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED; | ||
2567 | cmd->se_cmd.bad_sector = cmd->se_cmd.t_task_lba; | ||
2568 | |||
2569 | ql_log(ql_log_warn, vha, 0xe076, | ||
2570 | "Guard ERR: cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x] cmd=%p\n", | ||
2571 | cmd->atio.u.isp24.fcp_cmnd.cdb[0], lba, | ||
2572 | a_ref_tag, e_ref_tag, a_app_tag, e_app_tag, | ||
2573 | a_guard, e_guard, cmd); | ||
2574 | goto out; | ||
2575 | } | ||
2576 | |||
2577 | /* check ref tag */ | ||
2578 | if (e_ref_tag != a_ref_tag) { | ||
2579 | cmd->se_cmd.pi_err = TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED; | ||
2580 | cmd->se_cmd.bad_sector = e_ref_tag; | ||
2581 | |||
2582 | ql_log(ql_log_warn, vha, 0xe077, | ||
2583 | "Ref Tag ERR: cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x] cmd=%p\n", | ||
2584 | cmd->atio.u.isp24.fcp_cmnd.cdb[0], lba, | ||
2585 | a_ref_tag, e_ref_tag, a_app_tag, e_app_tag, | ||
2586 | a_guard, e_guard, cmd); | ||
2587 | goto out; | ||
2588 | } | ||
2589 | |||
2590 | /* check appl tag */ | ||
2591 | if (e_app_tag != a_app_tag) { | ||
2592 | cmd->se_cmd.pi_err = TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED; | ||
2593 | cmd->se_cmd.bad_sector = cmd->se_cmd.t_task_lba; | ||
2594 | |||
2595 | ql_log(ql_log_warn, vha, 0xe078, | ||
2596 | "App Tag ERR: cdb 0x%x lba 0x%llx: [Actual|Expected] Ref Tag[0x%x|0x%x], App Tag [0x%x|0x%x], Guard [0x%x|0x%x] cmd=%p\n", | ||
2597 | cmd->atio.u.isp24.fcp_cmnd.cdb[0], lba, | ||
2598 | a_ref_tag, e_ref_tag, a_app_tag, e_app_tag, | ||
2599 | a_guard, e_guard, cmd); | ||
2600 | goto out; | ||
2601 | } | ||
2602 | out: | ||
2603 | return 1; | ||
2604 | } | ||
2605 | |||
2606 | |||
2081 | /* If hardware_lock held on entry, might drop it, then reaquire */ | 2607 | /* If hardware_lock held on entry, might drop it, then reaquire */ |
2082 | /* This function sends the appropriate CTIO to ISP 2xxx or 24xx */ | 2608 | /* This function sends the appropriate CTIO to ISP 2xxx or 24xx */ |
2083 | static int __qlt_send_term_exchange(struct scsi_qla_host *vha, | 2609 | static int __qlt_send_term_exchange(struct scsi_qla_host *vha, |
@@ -2154,20 +2680,38 @@ static void qlt_send_term_exchange(struct scsi_qla_host *vha, | |||
2154 | rc = __qlt_send_term_exchange(vha, cmd, atio); | 2680 | rc = __qlt_send_term_exchange(vha, cmd, atio); |
2155 | spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); | 2681 | spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); |
2156 | done: | 2682 | done: |
2157 | if (rc == 1) { | 2683 | /* |
2684 | * Terminate exchange will tell fw to release any active CTIO | ||
2685 | * that's in FW posession and cleanup the exchange. | ||
2686 | * | ||
2687 | * "cmd->state == QLA_TGT_STATE_ABORTED" means CTIO is still | ||
2688 | * down at FW. Free the cmd later when CTIO comes back later | ||
2689 | * w/aborted(0x2) status. | ||
2690 | * | ||
2691 | * "cmd->state != QLA_TGT_STATE_ABORTED" means CTIO is already | ||
2692 | * back w/some err. Free the cmd now. | ||
2693 | */ | ||
2694 | if ((rc == 1) && (cmd->state != QLA_TGT_STATE_ABORTED)) { | ||
2158 | if (!ha_locked && !in_interrupt()) | 2695 | if (!ha_locked && !in_interrupt()) |
2159 | msleep(250); /* just in case */ | 2696 | msleep(250); /* just in case */ |
2160 | 2697 | ||
2698 | if (cmd->sg_mapped) | ||
2699 | qlt_unmap_sg(vha, cmd); | ||
2161 | vha->hw->tgt.tgt_ops->free_cmd(cmd); | 2700 | vha->hw->tgt.tgt_ops->free_cmd(cmd); |
2162 | } | 2701 | } |
2702 | return; | ||
2163 | } | 2703 | } |
2164 | 2704 | ||
2165 | void qlt_free_cmd(struct qla_tgt_cmd *cmd) | 2705 | void qlt_free_cmd(struct qla_tgt_cmd *cmd) |
2166 | { | 2706 | { |
2167 | struct qla_tgt_sess *sess = cmd->sess; | 2707 | struct qla_tgt_sess *sess = cmd->sess; |
2168 | 2708 | ||
2169 | BUG_ON(cmd->sg_mapped); | 2709 | ql_dbg(ql_dbg_tgt, cmd->vha, 0xe074, |
2710 | "%s: se_cmd[%p] ox_id %04x\n", | ||
2711 | __func__, &cmd->se_cmd, | ||
2712 | be16_to_cpu(cmd->atio.u.isp24.fcp_hdr.ox_id)); | ||
2170 | 2713 | ||
2714 | BUG_ON(cmd->sg_mapped); | ||
2171 | if (unlikely(cmd->free_sg)) | 2715 | if (unlikely(cmd->free_sg)) |
2172 | kfree(cmd->sg); | 2716 | kfree(cmd->sg); |
2173 | 2717 | ||
@@ -2380,6 +2924,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle, | |||
2380 | case CTIO_LIP_RESET: | 2924 | case CTIO_LIP_RESET: |
2381 | case CTIO_TARGET_RESET: | 2925 | case CTIO_TARGET_RESET: |
2382 | case CTIO_ABORTED: | 2926 | case CTIO_ABORTED: |
2927 | /* driver request abort via Terminate exchange */ | ||
2383 | case CTIO_TIMEOUT: | 2928 | case CTIO_TIMEOUT: |
2384 | case CTIO_INVALID_RX_ID: | 2929 | case CTIO_INVALID_RX_ID: |
2385 | /* They are OK */ | 2930 | /* They are OK */ |
@@ -2410,18 +2955,58 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle, | |||
2410 | else | 2955 | else |
2411 | return; | 2956 | return; |
2412 | 2957 | ||
2958 | case CTIO_DIF_ERROR: { | ||
2959 | struct ctio_crc_from_fw *crc = | ||
2960 | (struct ctio_crc_from_fw *)ctio; | ||
2961 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf073, | ||
2962 | "qla_target(%d): CTIO with DIF_ERROR status %x received (state %x, se_cmd %p) actual_dif[0x%llx] expect_dif[0x%llx]\n", | ||
2963 | vha->vp_idx, status, cmd->state, se_cmd, | ||
2964 | *((u64 *)&crc->actual_dif[0]), | ||
2965 | *((u64 *)&crc->expected_dif[0])); | ||
2966 | |||
2967 | if (qlt_handle_dif_error(vha, cmd, ctio)) { | ||
2968 | if (cmd->state == QLA_TGT_STATE_NEED_DATA) { | ||
2969 | /* scsi Write/xfer rdy complete */ | ||
2970 | goto skip_term; | ||
2971 | } else { | ||
2972 | /* scsi read/xmit respond complete | ||
2973 | * call handle dif to send scsi status | ||
2974 | * rather than terminate exchange. | ||
2975 | */ | ||
2976 | cmd->state = QLA_TGT_STATE_PROCESSED; | ||
2977 | ha->tgt.tgt_ops->handle_dif_err(cmd); | ||
2978 | return; | ||
2979 | } | ||
2980 | } else { | ||
2981 | /* Need to generate a SCSI good completion. | ||
2982 | * because FW did not send scsi status. | ||
2983 | */ | ||
2984 | status = 0; | ||
2985 | goto skip_term; | ||
2986 | } | ||
2987 | break; | ||
2988 | } | ||
2413 | default: | 2989 | default: |
2414 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05b, | 2990 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf05b, |
2415 | "qla_target(%d): CTIO with error status " | 2991 | "qla_target(%d): CTIO with error status 0x%x received (state %x, se_cmd %p\n", |
2416 | "0x%x received (state %x, se_cmd %p\n", | ||
2417 | vha->vp_idx, status, cmd->state, se_cmd); | 2992 | vha->vp_idx, status, cmd->state, se_cmd); |
2418 | break; | 2993 | break; |
2419 | } | 2994 | } |
2420 | 2995 | ||
2421 | if (cmd->state != QLA_TGT_STATE_NEED_DATA) | 2996 | |
2997 | /* "cmd->state == QLA_TGT_STATE_ABORTED" means | ||
2998 | * cmd is already aborted/terminated, we don't | ||
2999 | * need to terminate again. The exchange is already | ||
3000 | * cleaned up/freed at FW level. Just cleanup at driver | ||
3001 | * level. | ||
3002 | */ | ||
3003 | if ((cmd->state != QLA_TGT_STATE_NEED_DATA) && | ||
3004 | (cmd->state != QLA_TGT_STATE_ABORTED)) { | ||
2422 | if (qlt_term_ctio_exchange(vha, ctio, cmd, status)) | 3005 | if (qlt_term_ctio_exchange(vha, ctio, cmd, status)) |
2423 | return; | 3006 | return; |
3007 | } | ||
2424 | } | 3008 | } |
3009 | skip_term: | ||
2425 | 3010 | ||
2426 | if (cmd->state == QLA_TGT_STATE_PROCESSED) { | 3011 | if (cmd->state == QLA_TGT_STATE_PROCESSED) { |
2427 | ql_dbg(ql_dbg_tgt, vha, 0xe01f, "Command %p finished\n", cmd); | 3012 | ql_dbg(ql_dbg_tgt, vha, 0xe01f, "Command %p finished\n", cmd); |
@@ -2450,7 +3035,8 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle, | |||
2450 | "not return a CTIO complete\n", vha->vp_idx, cmd->state); | 3035 | "not return a CTIO complete\n", vha->vp_idx, cmd->state); |
2451 | } | 3036 | } |
2452 | 3037 | ||
2453 | if (unlikely(status != CTIO_SUCCESS)) { | 3038 | if (unlikely(status != CTIO_SUCCESS) && |
3039 | (cmd->state != QLA_TGT_STATE_ABORTED)) { | ||
2454 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01f, "Finishing failed CTIO\n"); | 3040 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01f, "Finishing failed CTIO\n"); |
2455 | dump_stack(); | 3041 | dump_stack(); |
2456 | } | 3042 | } |
@@ -2533,8 +3119,9 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd) | |||
2533 | atio->u.isp24.fcp_cmnd.add_cdb_len])); | 3119 | atio->u.isp24.fcp_cmnd.add_cdb_len])); |
2534 | 3120 | ||
2535 | ql_dbg(ql_dbg_tgt, vha, 0xe022, | 3121 | ql_dbg(ql_dbg_tgt, vha, 0xe022, |
2536 | "qla_target: START qla command: %p lun: 0x%04x (tag %d)\n", | 3122 | "qla_target: START qla cmd: %p se_cmd %p lun: 0x%04x (tag %d) len(%d) ox_id %x\n", |
2537 | cmd, cmd->unpacked_lun, cmd->tag); | 3123 | cmd, &cmd->se_cmd, cmd->unpacked_lun, cmd->tag, data_length, |
3124 | cmd->atio.u.isp24.fcp_hdr.ox_id); | ||
2538 | 3125 | ||
2539 | ret = ha->tgt.tgt_ops->handle_cmd(vha, cmd, cdb, data_length, | 3126 | ret = ha->tgt.tgt_ops->handle_cmd(vha, cmd, cdb, data_length, |
2540 | fcp_task_attr, data_dir, bidi); | 3127 | fcp_task_attr, data_dir, bidi); |
@@ -3607,11 +4194,11 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, | |||
3607 | switch (atio->u.raw.entry_type) { | 4194 | switch (atio->u.raw.entry_type) { |
3608 | case ATIO_TYPE7: | 4195 | case ATIO_TYPE7: |
3609 | ql_dbg(ql_dbg_tgt, vha, 0xe02d, | 4196 | ql_dbg(ql_dbg_tgt, vha, 0xe02d, |
3610 | "ATIO_TYPE7 instance %d, lun %Lx, read/write %d/%d, " | 4197 | "ATIO_TYPE7 instance %d, lun %Lx, read/write %d/%d, cdb %x, add_cdb_len %x, data_length %04x, s_id %02x%02x%02x\n", |
3611 | "add_cdb_len %d, data_length %04x, s_id %x:%x:%x\n", | ||
3612 | vha->vp_idx, atio->u.isp24.fcp_cmnd.lun, | 4198 | vha->vp_idx, atio->u.isp24.fcp_cmnd.lun, |
3613 | atio->u.isp24.fcp_cmnd.rddata, | 4199 | atio->u.isp24.fcp_cmnd.rddata, |
3614 | atio->u.isp24.fcp_cmnd.wrdata, | 4200 | atio->u.isp24.fcp_cmnd.wrdata, |
4201 | atio->u.isp24.fcp_cmnd.cdb[0], | ||
3615 | atio->u.isp24.fcp_cmnd.add_cdb_len, | 4202 | atio->u.isp24.fcp_cmnd.add_cdb_len, |
3616 | be32_to_cpu(get_unaligned((uint32_t *) | 4203 | be32_to_cpu(get_unaligned((uint32_t *) |
3617 | &atio->u.isp24.fcp_cmnd.add_cdb[ | 4204 | &atio->u.isp24.fcp_cmnd.add_cdb[ |
@@ -3709,11 +4296,13 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt) | |||
3709 | tgt->irq_cmd_count++; | 4296 | tgt->irq_cmd_count++; |
3710 | 4297 | ||
3711 | switch (pkt->entry_type) { | 4298 | switch (pkt->entry_type) { |
4299 | case CTIO_CRC2: | ||
3712 | case CTIO_TYPE7: | 4300 | case CTIO_TYPE7: |
3713 | { | 4301 | { |
3714 | struct ctio7_from_24xx *entry = (struct ctio7_from_24xx *)pkt; | 4302 | struct ctio7_from_24xx *entry = (struct ctio7_from_24xx *)pkt; |
3715 | ql_dbg(ql_dbg_tgt, vha, 0xe030, "CTIO_TYPE7: instance %d\n", | 4303 | ql_dbg(ql_dbg_tgt, vha, 0xe030, |
3716 | vha->vp_idx); | 4304 | "CTIO[0x%x] 12/CTIO7 7A/CRC2: instance %d\n", |
4305 | entry->entry_type, vha->vp_idx); | ||
3717 | qlt_do_ctio_completion(vha, entry->handle, | 4306 | qlt_do_ctio_completion(vha, entry->handle, |
3718 | le16_to_cpu(entry->status)|(pkt->entry_status << 16), | 4307 | le16_to_cpu(entry->status)|(pkt->entry_status << 16), |
3719 | entry); | 4308 | entry); |
@@ -4848,6 +5437,7 @@ qlt_24xx_process_response_error(struct scsi_qla_host *vha, | |||
4848 | case ABTS_RESP_24XX: | 5437 | case ABTS_RESP_24XX: |
4849 | case CTIO_TYPE7: | 5438 | case CTIO_TYPE7: |
4850 | case NOTIFY_ACK_TYPE: | 5439 | case NOTIFY_ACK_TYPE: |
5440 | case CTIO_CRC2: | ||
4851 | return 1; | 5441 | return 1; |
4852 | default: | 5442 | default: |
4853 | return 0; | 5443 | return 0; |
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h index 63283c58fb33..5c9f185a8ebd 100644 --- a/drivers/scsi/qla2xxx/qla_target.h +++ b/drivers/scsi/qla2xxx/qla_target.h | |||
@@ -293,6 +293,7 @@ struct ctio_to_2xxx { | |||
293 | #define CTIO_ABORTED 0x02 | 293 | #define CTIO_ABORTED 0x02 |
294 | #define CTIO_INVALID_RX_ID 0x08 | 294 | #define CTIO_INVALID_RX_ID 0x08 |
295 | #define CTIO_TIMEOUT 0x0B | 295 | #define CTIO_TIMEOUT 0x0B |
296 | #define CTIO_DIF_ERROR 0x0C /* DIF error detected */ | ||
296 | #define CTIO_LIP_RESET 0x0E | 297 | #define CTIO_LIP_RESET 0x0E |
297 | #define CTIO_TARGET_RESET 0x17 | 298 | #define CTIO_TARGET_RESET 0x17 |
298 | #define CTIO_PORT_UNAVAILABLE 0x28 | 299 | #define CTIO_PORT_UNAVAILABLE 0x28 |
@@ -498,11 +499,12 @@ struct ctio7_from_24xx { | |||
498 | #define CTIO7_FLAGS_DONT_RET_CTIO BIT_8 | 499 | #define CTIO7_FLAGS_DONT_RET_CTIO BIT_8 |
499 | #define CTIO7_FLAGS_STATUS_MODE_0 0 | 500 | #define CTIO7_FLAGS_STATUS_MODE_0 0 |
500 | #define CTIO7_FLAGS_STATUS_MODE_1 BIT_6 | 501 | #define CTIO7_FLAGS_STATUS_MODE_1 BIT_6 |
502 | #define CTIO7_FLAGS_STATUS_MODE_2 BIT_7 | ||
501 | #define CTIO7_FLAGS_EXPLICIT_CONFORM BIT_5 | 503 | #define CTIO7_FLAGS_EXPLICIT_CONFORM BIT_5 |
502 | #define CTIO7_FLAGS_CONFIRM_SATISF BIT_4 | 504 | #define CTIO7_FLAGS_CONFIRM_SATISF BIT_4 |
503 | #define CTIO7_FLAGS_DSD_PTR BIT_2 | 505 | #define CTIO7_FLAGS_DSD_PTR BIT_2 |
504 | #define CTIO7_FLAGS_DATA_IN BIT_1 | 506 | #define CTIO7_FLAGS_DATA_IN BIT_1 /* data to initiator */ |
505 | #define CTIO7_FLAGS_DATA_OUT BIT_0 | 507 | #define CTIO7_FLAGS_DATA_OUT BIT_0 /* data from initiator */ |
506 | 508 | ||
507 | #define ELS_PLOGI 0x3 | 509 | #define ELS_PLOGI 0x3 |
508 | #define ELS_FLOGI 0x4 | 510 | #define ELS_FLOGI 0x4 |
@@ -514,6 +516,68 @@ struct ctio7_from_24xx { | |||
514 | #define ELS_ADISC 0x52 | 516 | #define ELS_ADISC 0x52 |
515 | 517 | ||
516 | /* | 518 | /* |
519 | *CTIO Type CRC_2 IOCB | ||
520 | */ | ||
521 | struct ctio_crc2_to_fw { | ||
522 | uint8_t entry_type; /* Entry type. */ | ||
523 | #define CTIO_CRC2 0x7A | ||
524 | uint8_t entry_count; /* Entry count. */ | ||
525 | uint8_t sys_define; /* System defined. */ | ||
526 | uint8_t entry_status; /* Entry Status. */ | ||
527 | |||
528 | uint32_t handle; /* System handle. */ | ||
529 | uint16_t nport_handle; /* N_PORT handle. */ | ||
530 | uint16_t timeout; /* Command timeout. */ | ||
531 | |||
532 | uint16_t dseg_count; /* Data segment count. */ | ||
533 | uint8_t vp_index; | ||
534 | uint8_t add_flags; /* additional flags */ | ||
535 | #define CTIO_CRC2_AF_DIF_DSD_ENA BIT_3 | ||
536 | |||
537 | uint8_t initiator_id[3]; /* initiator ID */ | ||
538 | uint8_t reserved1; | ||
539 | uint32_t exchange_addr; /* rcv exchange address */ | ||
540 | uint16_t reserved2; | ||
541 | uint16_t flags; /* refer to CTIO7 flags values */ | ||
542 | uint32_t residual; | ||
543 | uint16_t ox_id; | ||
544 | uint16_t scsi_status; | ||
545 | uint32_t relative_offset; | ||
546 | uint32_t reserved5; | ||
547 | uint32_t transfer_length; /* total fc transfer length */ | ||
548 | uint32_t reserved6; | ||
549 | uint32_t crc_context_address[2];/* Data segment address. */ | ||
550 | uint16_t crc_context_len; /* Data segment length. */ | ||
551 | uint16_t reserved_1; /* MUST be set to 0. */ | ||
552 | } __packed; | ||
553 | |||
554 | /* CTIO Type CRC_x Status IOCB */ | ||
555 | struct ctio_crc_from_fw { | ||
556 | uint8_t entry_type; /* Entry type. */ | ||
557 | uint8_t entry_count; /* Entry count. */ | ||
558 | uint8_t sys_define; /* System defined. */ | ||
559 | uint8_t entry_status; /* Entry Status. */ | ||
560 | |||
561 | uint32_t handle; /* System handle. */ | ||
562 | uint16_t status; | ||
563 | uint16_t timeout; /* Command timeout. */ | ||
564 | uint16_t dseg_count; /* Data segment count. */ | ||
565 | uint32_t reserved1; | ||
566 | uint16_t state_flags; | ||
567 | #define CTIO_CRC_SF_DIF_CHOPPED BIT_4 | ||
568 | |||
569 | uint32_t exchange_address; /* rcv exchange address */ | ||
570 | uint16_t reserved2; | ||
571 | uint16_t flags; | ||
572 | uint32_t resid_xfer_length; | ||
573 | uint16_t ox_id; | ||
574 | uint8_t reserved3[12]; | ||
575 | uint16_t runt_guard; /* reported runt blk guard */ | ||
576 | uint8_t actual_dif[8]; | ||
577 | uint8_t expected_dif[8]; | ||
578 | } __packed; | ||
579 | |||
580 | /* | ||
517 | * ISP queue - ABTS received/response entries structure definition for 24xx. | 581 | * ISP queue - ABTS received/response entries structure definition for 24xx. |
518 | */ | 582 | */ |
519 | #define ABTS_RECV_24XX 0x54 /* ABTS received (for 24xx) */ | 583 | #define ABTS_RECV_24XX 0x54 /* ABTS received (for 24xx) */ |
@@ -641,6 +705,7 @@ struct qla_tgt_func_tmpl { | |||
641 | int (*handle_cmd)(struct scsi_qla_host *, struct qla_tgt_cmd *, | 705 | int (*handle_cmd)(struct scsi_qla_host *, struct qla_tgt_cmd *, |
642 | unsigned char *, uint32_t, int, int, int); | 706 | unsigned char *, uint32_t, int, int, int); |
643 | void (*handle_data)(struct qla_tgt_cmd *); | 707 | void (*handle_data)(struct qla_tgt_cmd *); |
708 | void (*handle_dif_err)(struct qla_tgt_cmd *); | ||
644 | int (*handle_tmr)(struct qla_tgt_mgmt_cmd *, uint32_t, uint8_t, | 709 | int (*handle_tmr)(struct qla_tgt_mgmt_cmd *, uint32_t, uint8_t, |
645 | uint32_t); | 710 | uint32_t); |
646 | void (*free_cmd)(struct qla_tgt_cmd *); | 711 | void (*free_cmd)(struct qla_tgt_cmd *); |
@@ -835,9 +900,9 @@ struct qla_tgt_sess { | |||
835 | }; | 900 | }; |
836 | 901 | ||
837 | struct qla_tgt_cmd { | 902 | struct qla_tgt_cmd { |
903 | struct se_cmd se_cmd; | ||
838 | struct qla_tgt_sess *sess; | 904 | struct qla_tgt_sess *sess; |
839 | int state; | 905 | int state; |
840 | struct se_cmd se_cmd; | ||
841 | struct work_struct free_work; | 906 | struct work_struct free_work; |
842 | struct work_struct work; | 907 | struct work_struct work; |
843 | /* Sense buffer that will be mapped into outgoing status */ | 908 | /* Sense buffer that will be mapped into outgoing status */ |
@@ -849,6 +914,7 @@ struct qla_tgt_cmd { | |||
849 | unsigned int free_sg:1; | 914 | unsigned int free_sg:1; |
850 | unsigned int aborted:1; /* Needed in case of SRR */ | 915 | unsigned int aborted:1; /* Needed in case of SRR */ |
851 | unsigned int write_data_transferred:1; | 916 | unsigned int write_data_transferred:1; |
917 | unsigned int ctx_dsd_alloced:1; | ||
852 | 918 | ||
853 | struct scatterlist *sg; /* cmd data buffer SG vector */ | 919 | struct scatterlist *sg; /* cmd data buffer SG vector */ |
854 | int sg_cnt; /* SG segments count */ | 920 | int sg_cnt; /* SG segments count */ |
@@ -863,6 +929,12 @@ struct qla_tgt_cmd { | |||
863 | struct scsi_qla_host *vha; | 929 | struct scsi_qla_host *vha; |
864 | 930 | ||
865 | struct atio_from_isp atio; | 931 | struct atio_from_isp atio; |
932 | /* t10dif */ | ||
933 | struct scatterlist *prot_sg; | ||
934 | uint32_t prot_sg_cnt; | ||
935 | uint32_t blk_sz; | ||
936 | struct crc_context *ctx; | ||
937 | |||
866 | }; | 938 | }; |
867 | 939 | ||
868 | struct qla_tgt_sess_work_param { | 940 | struct qla_tgt_sess_work_param { |
@@ -907,6 +979,10 @@ struct qla_tgt_prm { | |||
907 | int sense_buffer_len; | 979 | int sense_buffer_len; |
908 | int residual; | 980 | int residual; |
909 | int add_status_pkt; | 981 | int add_status_pkt; |
982 | /* dif */ | ||
983 | struct scatterlist *prot_sg; | ||
984 | uint16_t prot_seg_cnt; | ||
985 | uint16_t tot_dsds; | ||
910 | }; | 986 | }; |
911 | 987 | ||
912 | struct qla_tgt_srr_imm { | 988 | struct qla_tgt_srr_imm { |
@@ -982,6 +1058,8 @@ extern void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *, | |||
982 | extern void qlt_response_pkt_all_vps(struct scsi_qla_host *, response_t *); | 1058 | extern void qlt_response_pkt_all_vps(struct scsi_qla_host *, response_t *); |
983 | extern int qlt_rdy_to_xfer(struct qla_tgt_cmd *); | 1059 | extern int qlt_rdy_to_xfer(struct qla_tgt_cmd *); |
984 | extern int qlt_xmit_response(struct qla_tgt_cmd *, int, uint8_t); | 1060 | extern int qlt_xmit_response(struct qla_tgt_cmd *, int, uint8_t); |
1061 | extern int qlt_rdy_to_xfer_dif(struct qla_tgt_cmd *); | ||
1062 | extern int qlt_xmit_response_dif(struct qla_tgt_cmd *, int, uint8_t); | ||
985 | extern void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *); | 1063 | extern void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *); |
986 | extern void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *); | 1064 | extern void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *); |
987 | extern void qlt_free_cmd(struct qla_tgt_cmd *cmd); | 1065 | extern void qlt_free_cmd(struct qla_tgt_cmd *cmd); |
diff --git a/drivers/scsi/qla2xxx/qla_tmpl.c b/drivers/scsi/qla2xxx/qla_tmpl.c index a804e9b744bb..cb9a0c4bc419 100644 --- a/drivers/scsi/qla2xxx/qla_tmpl.c +++ b/drivers/scsi/qla2xxx/qla_tmpl.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -201,7 +201,6 @@ qla27xx_read_reg(__iomem struct device_reg_24xx *reg, | |||
201 | ql_dbg(ql_dbg_misc, NULL, 0xd014, | 201 | ql_dbg(ql_dbg_misc, NULL, 0xd014, |
202 | "%s: @%x\n", __func__, offset); | 202 | "%s: @%x\n", __func__, offset); |
203 | } | 203 | } |
204 | qla27xx_insert32(offset, buf, len); | ||
205 | qla27xx_read32(window, buf, len); | 204 | qla27xx_read32(window, buf, len); |
206 | } | 205 | } |
207 | 206 | ||
@@ -220,7 +219,7 @@ qla27xx_write_reg(__iomem struct device_reg_24xx *reg, | |||
220 | 219 | ||
221 | static inline void | 220 | static inline void |
222 | qla27xx_read_window(__iomem struct device_reg_24xx *reg, | 221 | qla27xx_read_window(__iomem struct device_reg_24xx *reg, |
223 | uint32_t base, uint offset, uint count, uint width, void *buf, | 222 | uint32_t addr, uint offset, uint count, uint width, void *buf, |
224 | ulong *len) | 223 | ulong *len) |
225 | { | 224 | { |
226 | void *window = (void *)reg + offset; | 225 | void *window = (void *)reg + offset; |
@@ -229,14 +228,14 @@ qla27xx_read_window(__iomem struct device_reg_24xx *reg, | |||
229 | if (buf) { | 228 | if (buf) { |
230 | ql_dbg(ql_dbg_misc, NULL, 0xd016, | 229 | ql_dbg(ql_dbg_misc, NULL, 0xd016, |
231 | "%s: base=%x offset=%x count=%x width=%x\n", | 230 | "%s: base=%x offset=%x count=%x width=%x\n", |
232 | __func__, base, offset, count, width); | 231 | __func__, addr, offset, count, width); |
233 | } | 232 | } |
234 | qla27xx_write_reg(reg, IOBASE_ADDR, base, buf); | 233 | qla27xx_write_reg(reg, IOBASE_ADDR, addr, buf); |
235 | while (count--) { | 234 | while (count--) { |
236 | qla27xx_insert32(base, buf, len); | 235 | qla27xx_insert32(addr, buf, len); |
237 | readn(window, buf, len); | 236 | readn(window, buf, len); |
238 | window += width; | 237 | window += width; |
239 | base += width; | 238 | addr++; |
240 | } | 239 | } |
241 | } | 240 | } |
242 | 241 | ||
@@ -336,7 +335,8 @@ qla27xx_fwdt_entry_t260(struct scsi_qla_host *vha, | |||
336 | 335 | ||
337 | ql_dbg(ql_dbg_misc, vha, 0xd204, | 336 | ql_dbg(ql_dbg_misc, vha, 0xd204, |
338 | "%s: rdpci [%lx]\n", __func__, *len); | 337 | "%s: rdpci [%lx]\n", __func__, *len); |
339 | qla27xx_read_reg(reg, ent->t260.pci_addr, buf, len); | 338 | qla27xx_insert32(ent->t260.pci_offset, buf, len); |
339 | qla27xx_read_reg(reg, ent->t260.pci_offset, buf, len); | ||
340 | 340 | ||
341 | return false; | 341 | return false; |
342 | } | 342 | } |
@@ -349,7 +349,7 @@ qla27xx_fwdt_entry_t261(struct scsi_qla_host *vha, | |||
349 | 349 | ||
350 | ql_dbg(ql_dbg_misc, vha, 0xd205, | 350 | ql_dbg(ql_dbg_misc, vha, 0xd205, |
351 | "%s: wrpci [%lx]\n", __func__, *len); | 351 | "%s: wrpci [%lx]\n", __func__, *len); |
352 | qla27xx_write_reg(reg, ent->t261.pci_addr, ent->t261.write_data, buf); | 352 | qla27xx_write_reg(reg, ent->t261.pci_offset, ent->t261.write_data, buf); |
353 | 353 | ||
354 | return false; | 354 | return false; |
355 | } | 355 | } |
@@ -392,9 +392,9 @@ qla27xx_fwdt_entry_t262(struct scsi_qla_host *vha, | |||
392 | goto done; | 392 | goto done; |
393 | } | 393 | } |
394 | 394 | ||
395 | if (end < start) { | 395 | if (end < start || end == 0) { |
396 | ql_dbg(ql_dbg_misc, vha, 0xd023, | 396 | ql_dbg(ql_dbg_misc, vha, 0xd023, |
397 | "%s: bad range (start=%x end=%x)\n", __func__, | 397 | "%s: unusable range (start=%x end=%x)\n", __func__, |
398 | ent->t262.end_addr, ent->t262.start_addr); | 398 | ent->t262.end_addr, ent->t262.start_addr); |
399 | qla27xx_skip_entry(ent, buf); | 399 | qla27xx_skip_entry(ent, buf); |
400 | goto done; | 400 | goto done; |
@@ -452,17 +452,15 @@ qla27xx_fwdt_entry_t263(struct scsi_qla_host *vha, | |||
452 | ql_dbg(ql_dbg_misc, vha, 0xd025, | 452 | ql_dbg(ql_dbg_misc, vha, 0xd025, |
453 | "%s: unsupported atio queue\n", __func__); | 453 | "%s: unsupported atio queue\n", __func__); |
454 | qla27xx_skip_entry(ent, buf); | 454 | qla27xx_skip_entry(ent, buf); |
455 | goto done; | ||
456 | } else { | 455 | } else { |
457 | ql_dbg(ql_dbg_misc, vha, 0xd026, | 456 | ql_dbg(ql_dbg_misc, vha, 0xd026, |
458 | "%s: unknown queue %u\n", __func__, ent->t263.queue_type); | 457 | "%s: unknown queue %u\n", __func__, ent->t263.queue_type); |
459 | qla27xx_skip_entry(ent, buf); | 458 | qla27xx_skip_entry(ent, buf); |
460 | goto done; | ||
461 | } | 459 | } |
462 | 460 | ||
463 | if (buf) | 461 | if (buf) |
464 | ent->t263.num_queues = count; | 462 | ent->t263.num_queues = count; |
465 | done: | 463 | |
466 | return false; | 464 | return false; |
467 | } | 465 | } |
468 | 466 | ||
@@ -503,7 +501,7 @@ qla27xx_fwdt_entry_t265(struct scsi_qla_host *vha, | |||
503 | ql_dbg(ql_dbg_misc, vha, 0xd209, | 501 | ql_dbg(ql_dbg_misc, vha, 0xd209, |
504 | "%s: pause risc [%lx]\n", __func__, *len); | 502 | "%s: pause risc [%lx]\n", __func__, *len); |
505 | if (buf) | 503 | if (buf) |
506 | qla24xx_pause_risc(reg); | 504 | qla24xx_pause_risc(reg, vha->hw); |
507 | 505 | ||
508 | return false; | 506 | return false; |
509 | } | 507 | } |
@@ -590,7 +588,6 @@ qla27xx_fwdt_entry_t270(struct scsi_qla_host *vha, | |||
590 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | 588 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) |
591 | { | 589 | { |
592 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | 590 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); |
593 | void *window = (void *)reg + 0xc4; | ||
594 | ulong dwords = ent->t270.count; | 591 | ulong dwords = ent->t270.count; |
595 | ulong addr = ent->t270.addr; | 592 | ulong addr = ent->t270.addr; |
596 | 593 | ||
@@ -599,10 +596,9 @@ qla27xx_fwdt_entry_t270(struct scsi_qla_host *vha, | |||
599 | qla27xx_write_reg(reg, IOBASE_ADDR, 0x40, buf); | 596 | qla27xx_write_reg(reg, IOBASE_ADDR, 0x40, buf); |
600 | while (dwords--) { | 597 | while (dwords--) { |
601 | qla27xx_write_reg(reg, 0xc0, addr|0x80000000, buf); | 598 | qla27xx_write_reg(reg, 0xc0, addr|0x80000000, buf); |
602 | qla27xx_read_reg(reg, 0xc4, buf, len); | ||
603 | qla27xx_insert32(addr, buf, len); | 599 | qla27xx_insert32(addr, buf, len); |
604 | qla27xx_read32(window, buf, len); | 600 | qla27xx_read_reg(reg, 0xc4, buf, len); |
605 | addr++; | 601 | addr += sizeof(uint32_t); |
606 | } | 602 | } |
607 | 603 | ||
608 | return false; | 604 | return false; |
@@ -614,12 +610,12 @@ qla27xx_fwdt_entry_t271(struct scsi_qla_host *vha, | |||
614 | { | 610 | { |
615 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); | 611 | struct device_reg_24xx __iomem *reg = qla27xx_isp_reg(vha); |
616 | ulong addr = ent->t271.addr; | 612 | ulong addr = ent->t271.addr; |
613 | ulong data = ent->t271.data; | ||
617 | 614 | ||
618 | ql_dbg(ql_dbg_misc, vha, 0xd20f, | 615 | ql_dbg(ql_dbg_misc, vha, 0xd20f, |
619 | "%s: wrremreg [%lx]\n", __func__, *len); | 616 | "%s: wrremreg [%lx]\n", __func__, *len); |
620 | qla27xx_write_reg(reg, IOBASE_ADDR, 0x40, buf); | 617 | qla27xx_write_reg(reg, IOBASE_ADDR, 0x40, buf); |
621 | qla27xx_read_reg(reg, 0xc4, buf, len); | 618 | qla27xx_write_reg(reg, 0xc4, data, buf); |
622 | qla27xx_insert32(addr, buf, len); | ||
623 | qla27xx_write_reg(reg, 0xc0, addr, buf); | 619 | qla27xx_write_reg(reg, 0xc0, addr, buf); |
624 | 620 | ||
625 | return false; | 621 | return false; |
@@ -662,9 +658,59 @@ qla27xx_fwdt_entry_t273(struct scsi_qla_host *vha, | |||
662 | "%s: failed pcicfg read at %lx\n", __func__, addr); | 658 | "%s: failed pcicfg read at %lx\n", __func__, addr); |
663 | qla27xx_insert32(addr, buf, len); | 659 | qla27xx_insert32(addr, buf, len); |
664 | qla27xx_insert32(value, buf, len); | 660 | qla27xx_insert32(value, buf, len); |
665 | addr += 4; | 661 | addr += sizeof(uint32_t); |
662 | } | ||
663 | |||
664 | return false; | ||
665 | } | ||
666 | |||
667 | static int | ||
668 | qla27xx_fwdt_entry_t274(struct scsi_qla_host *vha, | ||
669 | struct qla27xx_fwdt_entry *ent, void *buf, ulong *len) | ||
670 | { | ||
671 | uint count = 0; | ||
672 | uint i; | ||
673 | |||
674 | ql_dbg(ql_dbg_misc, vha, 0xd212, | ||
675 | "%s: getqsh(%x) [%lx]\n", __func__, ent->t274.queue_type, *len); | ||
676 | if (ent->t274.queue_type == T274_QUEUE_TYPE_REQ_SHAD) { | ||
677 | for (i = 0; i < vha->hw->max_req_queues; i++) { | ||
678 | struct req_que *req = vha->hw->req_q_map[i]; | ||
679 | if (req || !buf) { | ||
680 | qla27xx_insert16(i, buf, len); | ||
681 | qla27xx_insert16(1, buf, len); | ||
682 | qla27xx_insert32(req && req->out_ptr ? | ||
683 | *req->out_ptr : 0, buf, len); | ||
684 | count++; | ||
685 | } | ||
686 | } | ||
687 | } else if (ent->t274.queue_type == T274_QUEUE_TYPE_RSP_SHAD) { | ||
688 | for (i = 0; i < vha->hw->max_rsp_queues; i++) { | ||
689 | struct rsp_que *rsp = vha->hw->rsp_q_map[i]; | ||
690 | if (rsp || !buf) { | ||
691 | qla27xx_insert16(i, buf, len); | ||
692 | qla27xx_insert16(1, buf, len); | ||
693 | qla27xx_insert32(rsp && rsp->in_ptr ? | ||
694 | *rsp->in_ptr : 0, buf, len); | ||
695 | count++; | ||
696 | } | ||
697 | } | ||
698 | } else if (ent->t274.queue_type == T274_QUEUE_TYPE_ATIO_SHAD) { | ||
699 | ql_dbg(ql_dbg_misc, vha, 0xd02e, | ||
700 | "%s: unsupported atio queue\n", __func__); | ||
701 | qla27xx_skip_entry(ent, buf); | ||
702 | } else { | ||
703 | ql_dbg(ql_dbg_misc, vha, 0xd02f, | ||
704 | "%s: unknown queue %u\n", __func__, ent->t274.queue_type); | ||
705 | qla27xx_skip_entry(ent, buf); | ||
666 | } | 706 | } |
667 | 707 | ||
708 | if (buf) | ||
709 | ent->t274.num_queues = count; | ||
710 | |||
711 | if (!count) | ||
712 | qla27xx_skip_entry(ent, buf); | ||
713 | |||
668 | return false; | 714 | return false; |
669 | } | 715 | } |
670 | 716 | ||
@@ -709,6 +755,7 @@ static struct qla27xx_fwdt_entry_call ql27xx_fwdt_entry_call_list[] = { | |||
709 | { ENTRY_TYPE_WRREMREG , qla27xx_fwdt_entry_t271 } , | 755 | { ENTRY_TYPE_WRREMREG , qla27xx_fwdt_entry_t271 } , |
710 | { ENTRY_TYPE_RDREMRAM , qla27xx_fwdt_entry_t272 } , | 756 | { ENTRY_TYPE_RDREMRAM , qla27xx_fwdt_entry_t272 } , |
711 | { ENTRY_TYPE_PCICFG , qla27xx_fwdt_entry_t273 } , | 757 | { ENTRY_TYPE_PCICFG , qla27xx_fwdt_entry_t273 } , |
758 | { ENTRY_TYPE_GET_SHADOW , qla27xx_fwdt_entry_t274 } , | ||
712 | { -1 , qla27xx_fwdt_entry_other } | 759 | { -1 , qla27xx_fwdt_entry_other } |
713 | }; | 760 | }; |
714 | 761 | ||
diff --git a/drivers/scsi/qla2xxx/qla_tmpl.h b/drivers/scsi/qla2xxx/qla_tmpl.h index c9d2fff4d964..1967424c8e64 100644 --- a/drivers/scsi/qla2xxx/qla_tmpl.h +++ b/drivers/scsi/qla2xxx/qla_tmpl.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
@@ -52,6 +52,7 @@ struct __packed qla27xx_fwdt_template { | |||
52 | #define ENTRY_TYPE_WRREMREG 271 | 52 | #define ENTRY_TYPE_WRREMREG 271 |
53 | #define ENTRY_TYPE_RDREMRAM 272 | 53 | #define ENTRY_TYPE_RDREMRAM 272 |
54 | #define ENTRY_TYPE_PCICFG 273 | 54 | #define ENTRY_TYPE_PCICFG 273 |
55 | #define ENTRY_TYPE_GET_SHADOW 274 | ||
55 | 56 | ||
56 | #define CAPTURE_FLAG_PHYS_ONLY BIT_0 | 57 | #define CAPTURE_FLAG_PHYS_ONLY BIT_0 |
57 | #define CAPTURE_FLAG_PHYS_VIRT BIT_1 | 58 | #define CAPTURE_FLAG_PHYS_VIRT BIT_1 |
@@ -109,12 +110,12 @@ struct __packed qla27xx_fwdt_entry { | |||
109 | } t259; | 110 | } t259; |
110 | 111 | ||
111 | struct __packed { | 112 | struct __packed { |
112 | uint8_t pci_addr; | 113 | uint8_t pci_offset; |
113 | uint8_t reserved[3]; | 114 | uint8_t reserved[3]; |
114 | } t260; | 115 | } t260; |
115 | 116 | ||
116 | struct __packed { | 117 | struct __packed { |
117 | uint8_t pci_addr; | 118 | uint8_t pci_offset; |
118 | uint8_t reserved[3]; | 119 | uint8_t reserved[3]; |
119 | uint32_t write_data; | 120 | uint32_t write_data; |
120 | } t261; | 121 | } t261; |
@@ -186,6 +187,12 @@ struct __packed qla27xx_fwdt_entry { | |||
186 | uint32_t addr; | 187 | uint32_t addr; |
187 | uint32_t count; | 188 | uint32_t count; |
188 | } t273; | 189 | } t273; |
190 | |||
191 | struct __packed { | ||
192 | uint32_t num_queues; | ||
193 | uint8_t queue_type; | ||
194 | uint8_t reserved[3]; | ||
195 | } t274; | ||
189 | }; | 196 | }; |
190 | }; | 197 | }; |
191 | 198 | ||
@@ -202,4 +209,8 @@ struct __packed qla27xx_fwdt_entry { | |||
202 | #define T268_BUF_TYPE_EXCH_BUFOFF 2 | 209 | #define T268_BUF_TYPE_EXCH_BUFOFF 2 |
203 | #define T268_BUF_TYPE_EXTD_LOGIN 3 | 210 | #define T268_BUF_TYPE_EXTD_LOGIN 3 |
204 | 211 | ||
212 | #define T274_QUEUE_TYPE_REQ_SHAD 1 | ||
213 | #define T274_QUEUE_TYPE_RSP_SHAD 2 | ||
214 | #define T274_QUEUE_TYPE_ATIO_SHAD 3 | ||
215 | |||
205 | #endif | 216 | #endif |
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index e36b94712544..4d2c98cbec4f 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -1,13 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | * QLogic Fibre Channel HBA Driver | 2 | * QLogic Fibre Channel HBA Driver |
3 | * Copyright (c) 2003-2013 QLogic Corporation | 3 | * Copyright (c) 2003-2014 QLogic Corporation |
4 | * | 4 | * |
5 | * See LICENSE.qla2xxx for copyright and licensing details. | 5 | * See LICENSE.qla2xxx for copyright and licensing details. |
6 | */ | 6 | */ |
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.07.00.02-k" | 10 | #define QLA2XXX_VERSION "8.07.00.08-k" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 7 | 13 | #define QLA_DRIVER_MINOR_VER 7 |
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 7b3a97026934..e2beab962096 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c | |||
@@ -472,6 +472,11 @@ static int tcm_qla2xxx_write_pending(struct se_cmd *se_cmd) | |||
472 | cmd->sg_cnt = se_cmd->t_data_nents; | 472 | cmd->sg_cnt = se_cmd->t_data_nents; |
473 | cmd->sg = se_cmd->t_data_sg; | 473 | cmd->sg = se_cmd->t_data_sg; |
474 | 474 | ||
475 | cmd->prot_sg_cnt = se_cmd->t_prot_nents; | ||
476 | cmd->prot_sg = se_cmd->t_prot_sg; | ||
477 | cmd->blk_sz = se_cmd->se_dev->dev_attrib.block_size; | ||
478 | se_cmd->pi_err = 0; | ||
479 | |||
475 | /* | 480 | /* |
476 | * qla_target.c:qlt_rdy_to_xfer() will call pci_map_sg() to setup | 481 | * qla_target.c:qlt_rdy_to_xfer() will call pci_map_sg() to setup |
477 | * the SGL mappings into PCIe memory for incoming FCP WRITE data. | 482 | * the SGL mappings into PCIe memory for incoming FCP WRITE data. |
@@ -567,8 +572,13 @@ static void tcm_qla2xxx_handle_data_work(struct work_struct *work) | |||
567 | return; | 572 | return; |
568 | } | 573 | } |
569 | 574 | ||
570 | transport_generic_request_failure(&cmd->se_cmd, | 575 | if (cmd->se_cmd.pi_err) |
571 | TCM_CHECK_CONDITION_ABORT_CMD); | 576 | transport_generic_request_failure(&cmd->se_cmd, |
577 | cmd->se_cmd.pi_err); | ||
578 | else | ||
579 | transport_generic_request_failure(&cmd->se_cmd, | ||
580 | TCM_CHECK_CONDITION_ABORT_CMD); | ||
581 | |||
572 | return; | 582 | return; |
573 | } | 583 | } |
574 | 584 | ||
@@ -584,6 +594,27 @@ static void tcm_qla2xxx_handle_data(struct qla_tgt_cmd *cmd) | |||
584 | queue_work(tcm_qla2xxx_free_wq, &cmd->work); | 594 | queue_work(tcm_qla2xxx_free_wq, &cmd->work); |
585 | } | 595 | } |
586 | 596 | ||
597 | static void tcm_qla2xxx_handle_dif_work(struct work_struct *work) | ||
598 | { | ||
599 | struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); | ||
600 | |||
601 | /* take an extra kref to prevent cmd free too early. | ||
602 | * need to wait for SCSI status/check condition to | ||
603 | * finish responding generate by transport_generic_request_failure. | ||
604 | */ | ||
605 | kref_get(&cmd->se_cmd.cmd_kref); | ||
606 | transport_generic_request_failure(&cmd->se_cmd, cmd->se_cmd.pi_err); | ||
607 | } | ||
608 | |||
609 | /* | ||
610 | * Called from qla_target.c:qlt_do_ctio_completion() | ||
611 | */ | ||
612 | static void tcm_qla2xxx_handle_dif_err(struct qla_tgt_cmd *cmd) | ||
613 | { | ||
614 | INIT_WORK(&cmd->work, tcm_qla2xxx_handle_dif_work); | ||
615 | queue_work(tcm_qla2xxx_free_wq, &cmd->work); | ||
616 | } | ||
617 | |||
587 | /* | 618 | /* |
588 | * Called from qla_target.c:qlt_issue_task_mgmt() | 619 | * Called from qla_target.c:qlt_issue_task_mgmt() |
589 | */ | 620 | */ |
@@ -610,6 +641,11 @@ static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd) | |||
610 | cmd->sg = se_cmd->t_data_sg; | 641 | cmd->sg = se_cmd->t_data_sg; |
611 | cmd->offset = 0; | 642 | cmd->offset = 0; |
612 | 643 | ||
644 | cmd->prot_sg_cnt = se_cmd->t_prot_nents; | ||
645 | cmd->prot_sg = se_cmd->t_prot_sg; | ||
646 | cmd->blk_sz = se_cmd->se_dev->dev_attrib.block_size; | ||
647 | se_cmd->pi_err = 0; | ||
648 | |||
613 | /* | 649 | /* |
614 | * Now queue completed DATA_IN the qla2xxx LLD and response ring | 650 | * Now queue completed DATA_IN the qla2xxx LLD and response ring |
615 | */ | 651 | */ |
@@ -1604,6 +1640,7 @@ static void tcm_qla2xxx_update_sess(struct qla_tgt_sess *sess, port_id_t s_id, | |||
1604 | static struct qla_tgt_func_tmpl tcm_qla2xxx_template = { | 1640 | static struct qla_tgt_func_tmpl tcm_qla2xxx_template = { |
1605 | .handle_cmd = tcm_qla2xxx_handle_cmd, | 1641 | .handle_cmd = tcm_qla2xxx_handle_cmd, |
1606 | .handle_data = tcm_qla2xxx_handle_data, | 1642 | .handle_data = tcm_qla2xxx_handle_data, |
1643 | .handle_dif_err = tcm_qla2xxx_handle_dif_err, | ||
1607 | .handle_tmr = tcm_qla2xxx_handle_tmr, | 1644 | .handle_tmr = tcm_qla2xxx_handle_tmr, |
1608 | .free_cmd = tcm_qla2xxx_free_cmd, | 1645 | .free_cmd = tcm_qla2xxx_free_cmd, |
1609 | .free_mcmd = tcm_qla2xxx_free_mcmd, | 1646 | .free_mcmd = tcm_qla2xxx_free_mcmd, |