diff options
Diffstat (limited to 'drivers/scsi/isci/request.c')
-rw-r--r-- | drivers/scsi/isci/request.c | 49 |
1 files changed, 20 insertions, 29 deletions
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index b5d3a8c4d329..225b196800a2 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c | |||
@@ -1490,29 +1490,30 @@ sci_io_request_frame_handler(struct isci_request *ireq, | |||
1490 | return SCI_SUCCESS; | 1490 | return SCI_SUCCESS; |
1491 | 1491 | ||
1492 | case SCI_REQ_SMP_WAIT_RESP: { | 1492 | case SCI_REQ_SMP_WAIT_RESP: { |
1493 | struct smp_resp *rsp_hdr = &ireq->smp.rsp; | 1493 | struct sas_task *task = isci_request_access_task(ireq); |
1494 | void *frame_header; | 1494 | struct scatterlist *sg = &task->smp_task.smp_resp; |
1495 | void *frame_header, *kaddr; | ||
1496 | u8 *rsp; | ||
1495 | 1497 | ||
1496 | sci_unsolicited_frame_control_get_header(&ihost->uf_control, | 1498 | sci_unsolicited_frame_control_get_header(&ihost->uf_control, |
1497 | frame_index, | 1499 | frame_index, |
1498 | &frame_header); | 1500 | &frame_header); |
1499 | 1501 | kaddr = kmap_atomic(sg_page(sg), KM_IRQ0); | |
1500 | /* byte swap the header. */ | 1502 | rsp = kaddr + sg->offset; |
1501 | word_cnt = SMP_RESP_HDR_SZ / sizeof(u32); | 1503 | sci_swab32_cpy(rsp, frame_header, 1); |
1502 | sci_swab32_cpy(rsp_hdr, frame_header, word_cnt); | ||
1503 | 1504 | ||
1504 | if (rsp_hdr->frame_type == SMP_RESPONSE) { | 1505 | if (rsp[0] == SMP_RESPONSE) { |
1505 | void *smp_resp; | 1506 | void *smp_resp; |
1506 | 1507 | ||
1507 | sci_unsolicited_frame_control_get_buffer(&ihost->uf_control, | 1508 | sci_unsolicited_frame_control_get_buffer(&ihost->uf_control, |
1508 | frame_index, | 1509 | frame_index, |
1509 | &smp_resp); | 1510 | &smp_resp); |
1510 | 1511 | ||
1511 | word_cnt = (sizeof(struct smp_resp) - SMP_RESP_HDR_SZ) / | 1512 | word_cnt = (sg->length/4)-1; |
1512 | sizeof(u32); | 1513 | if (word_cnt > 0) |
1513 | 1514 | word_cnt = min_t(unsigned int, word_cnt, | |
1514 | sci_swab32_cpy(((u8 *) rsp_hdr) + SMP_RESP_HDR_SZ, | 1515 | SCU_UNSOLICITED_FRAME_BUFFER_SIZE/4); |
1515 | smp_resp, word_cnt); | 1516 | sci_swab32_cpy(rsp + 4, smp_resp, word_cnt); |
1516 | 1517 | ||
1517 | ireq->scu_status = SCU_TASK_DONE_GOOD; | 1518 | ireq->scu_status = SCU_TASK_DONE_GOOD; |
1518 | ireq->sci_status = SCI_SUCCESS; | 1519 | ireq->sci_status = SCI_SUCCESS; |
@@ -1528,12 +1529,13 @@ sci_io_request_frame_handler(struct isci_request *ireq, | |||
1528 | __func__, | 1529 | __func__, |
1529 | ireq, | 1530 | ireq, |
1530 | frame_index, | 1531 | frame_index, |
1531 | rsp_hdr->frame_type); | 1532 | rsp[0]); |
1532 | 1533 | ||
1533 | ireq->scu_status = SCU_TASK_DONE_SMP_FRM_TYPE_ERR; | 1534 | ireq->scu_status = SCU_TASK_DONE_SMP_FRM_TYPE_ERR; |
1534 | ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR; | 1535 | ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR; |
1535 | sci_change_state(&ireq->sm, SCI_REQ_COMPLETED); | 1536 | sci_change_state(&ireq->sm, SCI_REQ_COMPLETED); |
1536 | } | 1537 | } |
1538 | kunmap_atomic(kaddr, KM_IRQ0); | ||
1537 | 1539 | ||
1538 | sci_controller_release_frame(ihost, frame_index); | 1540 | sci_controller_release_frame(ihost, frame_index); |
1539 | 1541 | ||
@@ -2603,18 +2605,7 @@ static void isci_request_io_request_complete(struct isci_host *ihost, | |||
2603 | status = SAM_STAT_GOOD; | 2605 | status = SAM_STAT_GOOD; |
2604 | set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); | 2606 | set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); |
2605 | 2607 | ||
2606 | if (task->task_proto == SAS_PROTOCOL_SMP) { | 2608 | if (completion_status == SCI_IO_SUCCESS_IO_DONE_EARLY) { |
2607 | void *rsp = &request->smp.rsp; | ||
2608 | |||
2609 | dev_dbg(&ihost->pdev->dev, | ||
2610 | "%s: SMP protocol completion\n", | ||
2611 | __func__); | ||
2612 | |||
2613 | sg_copy_from_buffer( | ||
2614 | &task->smp_task.smp_resp, 1, | ||
2615 | rsp, sizeof(struct smp_resp)); | ||
2616 | } else if (completion_status | ||
2617 | == SCI_IO_SUCCESS_IO_DONE_EARLY) { | ||
2618 | 2609 | ||
2619 | /* This was an SSP / STP / SATA transfer. | 2610 | /* This was an SSP / STP / SATA transfer. |
2620 | * There is a possibility that less data than | 2611 | * There is a possibility that less data than |