aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2011-09-28 21:35:27 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-10-02 14:07:17 -0400
commit54b5e3a4bfa3452bc10cd4da672099ccc46b8c09 (patch)
treef07de6264a0ffb59845f8dfb62d2f158ba50e012 /drivers/scsi/isci
parent6fbc769219a7a8060ea33f397304f05b1cdf8a00 (diff)
[SCSI] isci: fix support for large smp requests
Kill the local smp response buffer. Besides being unnecessary, it is too small (currently truncates responses to 60 bytes). The mid-layer will have already allocated a sufficiently sized buffer, just kmap and copy into it directly. Cc: <stable@kernel.org> Reported-by: Derick Marks <derick.w.marks@intel.com> Tested-by: Derick Marks <derick.w.marks@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/isci')
-rw-r--r--drivers/scsi/isci/isci.h2
-rw-r--r--drivers/scsi/isci/request.c49
-rw-r--r--drivers/scsi/isci/request.h3
-rw-r--r--drivers/scsi/isci/sas.h2
4 files changed, 21 insertions, 35 deletions
diff --git a/drivers/scsi/isci/isci.h b/drivers/scsi/isci/isci.h
index d1de63312e7f..8efeb6b08321 100644
--- a/drivers/scsi/isci/isci.h
+++ b/drivers/scsi/isci/isci.h
@@ -97,7 +97,7 @@
97#define SCU_MAX_COMPLETION_QUEUE_SHIFT (ilog2(SCU_MAX_COMPLETION_QUEUE_ENTRIES)) 97#define SCU_MAX_COMPLETION_QUEUE_SHIFT (ilog2(SCU_MAX_COMPLETION_QUEUE_ENTRIES))
98 98
99#define SCU_ABSOLUTE_MAX_UNSOLICITED_FRAMES (4096) 99#define SCU_ABSOLUTE_MAX_UNSOLICITED_FRAMES (4096)
100#define SCU_UNSOLICITED_FRAME_BUFFER_SIZE (1024) 100#define SCU_UNSOLICITED_FRAME_BUFFER_SIZE (1024U)
101#define SCU_INVALID_FRAME_INDEX (0xFFFF) 101#define SCU_INVALID_FRAME_INDEX (0xFFFF)
102 102
103#define SCU_IO_REQUEST_MAX_SGE_SIZE (0x00FFFFFF) 103#define SCU_IO_REQUEST_MAX_SGE_SIZE (0x00FFFFFF)
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
diff --git a/drivers/scsi/isci/request.h b/drivers/scsi/isci/request.h
index 7a1d5a9778eb..58d70b6606ef 100644
--- a/drivers/scsi/isci/request.h
+++ b/drivers/scsi/isci/request.h
@@ -174,9 +174,6 @@ struct isci_request {
174 }; 174 };
175 } ssp; 175 } ssp;
176 struct { 176 struct {
177 struct smp_resp rsp;
178 } smp;
179 struct {
180 struct isci_stp_request req; 177 struct isci_stp_request req;
181 struct host_to_dev_fis cmd; 178 struct host_to_dev_fis cmd;
182 struct dev_to_host_fis rsp; 179 struct dev_to_host_fis rsp;
diff --git a/drivers/scsi/isci/sas.h b/drivers/scsi/isci/sas.h
index 462b15174d3f..dc26b4aea99e 100644
--- a/drivers/scsi/isci/sas.h
+++ b/drivers/scsi/isci/sas.h
@@ -204,8 +204,6 @@ struct smp_req {
204 u8 req_data[0]; 204 u8 req_data[0];
205} __packed; 205} __packed;
206 206
207#define SMP_RESP_HDR_SZ 4
208
209/* 207/*
210 * struct sci_sas_address - This structure depicts how a SAS address is 208 * struct sci_sas_address - This structure depicts how a SAS address is
211 * represented by SCI. 209 * represented by SCI.