.. | .. |
---|
392 | 392 | #define CMPLT_HDR_ERROR_PHASE_MSK (0xff << CMPLT_HDR_ERROR_PHASE_OFF) |
---|
393 | 393 | #define CMPLT_HDR_RSPNS_XFRD_OFF 10 |
---|
394 | 394 | #define CMPLT_HDR_RSPNS_XFRD_MSK (0x1 << CMPLT_HDR_RSPNS_XFRD_OFF) |
---|
| 395 | +#define CMPLT_HDR_RSPNS_GOOD_OFF 11 |
---|
| 396 | +#define CMPLT_HDR_RSPNS_GOOD_MSK (0x1 << CMPLT_HDR_RSPNS_GOOD_OFF) |
---|
395 | 397 | #define CMPLT_HDR_ERX_OFF 12 |
---|
396 | 398 | #define CMPLT_HDR_ERX_MSK (0x1 << CMPLT_HDR_ERX_OFF) |
---|
397 | 399 | #define CMPLT_HDR_ABORT_STAT_OFF 13 |
---|
.. | .. |
---|
464 | 466 | |
---|
465 | 467 | #define RX_DATA_LEN_UNDERFLOW_OFF 6 |
---|
466 | 468 | #define RX_DATA_LEN_UNDERFLOW_MSK (1 << RX_DATA_LEN_UNDERFLOW_OFF) |
---|
| 469 | + |
---|
| 470 | +#define RX_FIS_STATUS_ERR_OFF 0 |
---|
| 471 | +#define RX_FIS_STATUS_ERR_MSK (1 << RX_FIS_STATUS_ERR_OFF) |
---|
467 | 472 | |
---|
468 | 473 | #define HISI_SAS_COMMAND_ENTRIES_V3_HW 4096 |
---|
469 | 474 | #define HISI_SAS_MSI_COUNT_V3_HW 32 |
---|
.. | .. |
---|
2115 | 2120 | return IRQ_HANDLED; |
---|
2116 | 2121 | } |
---|
2117 | 2122 | |
---|
2118 | | -static void |
---|
| 2123 | +static bool |
---|
2119 | 2124 | slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task, |
---|
2120 | 2125 | struct hisi_sas_slot *slot) |
---|
2121 | 2126 | { |
---|
.. | .. |
---|
2128 | 2133 | hisi_sas_status_buf_addr_mem(slot); |
---|
2129 | 2134 | u32 dma_rx_err_type = le32_to_cpu(record->dma_rx_err_type); |
---|
2130 | 2135 | u32 trans_tx_fail_type = le32_to_cpu(record->trans_tx_fail_type); |
---|
| 2136 | + u16 sipc_rx_err_type = le16_to_cpu(record->sipc_rx_err_type); |
---|
2131 | 2137 | u32 dw3 = le32_to_cpu(complete_hdr->dw3); |
---|
| 2138 | + u32 dw0 = le32_to_cpu(complete_hdr->dw0); |
---|
2132 | 2139 | |
---|
2133 | 2140 | switch (task->task_proto) { |
---|
2134 | 2141 | case SAS_PROTOCOL_SSP: |
---|
2135 | 2142 | if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) { |
---|
| 2143 | + /* |
---|
| 2144 | + * If returned response frame is incorrect because of data underflow, |
---|
| 2145 | + * but I/O information has been written to the host memory, we examine |
---|
| 2146 | + * response IU. |
---|
| 2147 | + */ |
---|
| 2148 | + if (!(dw0 & CMPLT_HDR_RSPNS_GOOD_MSK) && |
---|
| 2149 | + (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK)) |
---|
| 2150 | + return false; |
---|
| 2151 | + |
---|
2136 | 2152 | ts->residual = trans_tx_fail_type; |
---|
2137 | 2153 | ts->stat = SAS_DATA_UNDERRUN; |
---|
2138 | 2154 | } else if (dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) { |
---|
.. | .. |
---|
2146 | 2162 | case SAS_PROTOCOL_SATA: |
---|
2147 | 2163 | case SAS_PROTOCOL_STP: |
---|
2148 | 2164 | case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: |
---|
2149 | | - if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) { |
---|
| 2165 | + if ((dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) && |
---|
| 2166 | + (sipc_rx_err_type & RX_FIS_STATUS_ERR_MSK)) { |
---|
| 2167 | + ts->stat = SAS_PROTO_RESPONSE; |
---|
| 2168 | + } else if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) { |
---|
2150 | 2169 | ts->residual = trans_tx_fail_type; |
---|
2151 | 2170 | ts->stat = SAS_DATA_UNDERRUN; |
---|
2152 | 2171 | } else if (dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) { |
---|
.. | .. |
---|
2156 | 2175 | ts->stat = SAS_OPEN_REJECT; |
---|
2157 | 2176 | ts->open_rej_reason = SAS_OREJ_RSVD_RETRY; |
---|
2158 | 2177 | } |
---|
2159 | | - hisi_sas_sata_done(task, slot); |
---|
| 2178 | + if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) |
---|
| 2179 | + hisi_sas_sata_done(task, slot); |
---|
2160 | 2180 | break; |
---|
2161 | 2181 | case SAS_PROTOCOL_SMP: |
---|
2162 | | - ts->stat = SAM_STAT_CHECK_CONDITION; |
---|
| 2182 | + ts->stat = SAS_SAM_STAT_CHECK_CONDITION; |
---|
2163 | 2183 | break; |
---|
2164 | 2184 | default: |
---|
2165 | 2185 | break; |
---|
2166 | 2186 | } |
---|
| 2187 | + return true; |
---|
2167 | 2188 | } |
---|
2168 | 2189 | |
---|
2169 | 2190 | static void slot_complete_v3_hw(struct hisi_hba *hisi_hba, |
---|
.. | .. |
---|
2238 | 2259 | if ((dw0 & CMPLT_HDR_CMPLT_MSK) == 0x3) { |
---|
2239 | 2260 | u32 *error_info = hisi_sas_status_buf_addr_mem(slot); |
---|
2240 | 2261 | |
---|
2241 | | - slot_err_v3_hw(hisi_hba, task, slot); |
---|
2242 | | - if (ts->stat != SAS_DATA_UNDERRUN) |
---|
2243 | | - dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d CQ hdr: 0x%x 0x%x 0x%x 0x%x Error info: 0x%x 0x%x 0x%x 0x%x\n", |
---|
2244 | | - slot->idx, task, sas_dev->device_id, |
---|
2245 | | - dw0, dw1, complete_hdr->act, dw3, |
---|
2246 | | - error_info[0], error_info[1], |
---|
2247 | | - error_info[2], error_info[3]); |
---|
2248 | | - if (unlikely(slot->abort)) { |
---|
2249 | | - sas_task_abort(task); |
---|
2250 | | - return; |
---|
| 2262 | + if (slot_err_v3_hw(hisi_hba, task, slot)) { |
---|
| 2263 | + if (ts->stat != SAS_DATA_UNDERRUN) |
---|
| 2264 | + dev_info(dev, "erroneous completion iptt=%d task=%pK dev id=%d addr=%016llx CQ hdr: 0x%x 0x%x 0x%x 0x%x Error info: 0x%x 0x%x 0x%x 0x%x\n", |
---|
| 2265 | + slot->idx, task, sas_dev->device_id, |
---|
| 2266 | + SAS_ADDR(device->sas_addr), |
---|
| 2267 | + dw0, dw1, complete_hdr->act, dw3, |
---|
| 2268 | + error_info[0], error_info[1], |
---|
| 2269 | + error_info[2], error_info[3]); |
---|
| 2270 | + if (unlikely(slot->abort)) { |
---|
| 2271 | + sas_task_abort(task); |
---|
| 2272 | + return; |
---|
| 2273 | + } |
---|
| 2274 | + goto out; |
---|
2251 | 2275 | } |
---|
2252 | | - goto out; |
---|
2253 | 2276 | } |
---|
2254 | 2277 | |
---|
2255 | 2278 | switch (task->task_proto) { |
---|
.. | .. |
---|
2265 | 2288 | struct scatterlist *sg_resp = &task->smp_task.smp_resp; |
---|
2266 | 2289 | void *to = page_address(sg_page(sg_resp)); |
---|
2267 | 2290 | |
---|
2268 | | - ts->stat = SAM_STAT_GOOD; |
---|
| 2291 | + ts->stat = SAS_SAM_STAT_GOOD; |
---|
2269 | 2292 | |
---|
2270 | 2293 | dma_unmap_sg(dev, &task->smp_task.smp_req, 1, |
---|
2271 | 2294 | DMA_TO_DEVICE); |
---|
.. | .. |
---|
2278 | 2301 | case SAS_PROTOCOL_SATA: |
---|
2279 | 2302 | case SAS_PROTOCOL_STP: |
---|
2280 | 2303 | case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP: |
---|
2281 | | - ts->stat = SAM_STAT_GOOD; |
---|
2282 | | - hisi_sas_sata_done(task, slot); |
---|
| 2304 | + ts->stat = SAS_SAM_STAT_GOOD; |
---|
| 2305 | + if (dw0 & CMPLT_HDR_RSPNS_XFRD_MSK) |
---|
| 2306 | + hisi_sas_sata_done(task, slot); |
---|
2283 | 2307 | break; |
---|
2284 | 2308 | default: |
---|
2285 | | - ts->stat = SAM_STAT_CHECK_CONDITION; |
---|
| 2309 | + ts->stat = SAS_SAM_STAT_CHECK_CONDITION; |
---|
2286 | 2310 | break; |
---|
2287 | 2311 | } |
---|
2288 | 2312 | |
---|
.. | .. |
---|
2402 | 2426 | hisi_hba->cq_nvecs = vectors - BASE_VECTORS_V3_HW; |
---|
2403 | 2427 | shost->nr_hw_queues = hisi_hba->cq_nvecs; |
---|
2404 | 2428 | |
---|
2405 | | - devm_add_action(&pdev->dev, hisi_sas_v3_free_vectors, pdev); |
---|
2406 | | - return 0; |
---|
| 2429 | + return devm_add_action(&pdev->dev, hisi_sas_v3_free_vectors, pdev); |
---|
2407 | 2430 | } |
---|
2408 | 2431 | |
---|
2409 | 2432 | static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba) |
---|