Commit 54b5e3a4 authored by Dan Williams's avatar Dan Williams Committed by James Bottomley

[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: default avatarDerick Marks <derick.w.marks@intel.com>
Tested-by: default avatarDerick Marks <derick.w.marks@intel.com>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 6fbc7692
...@@ -97,7 +97,7 @@ ...@@ -97,7 +97,7 @@
#define SCU_MAX_COMPLETION_QUEUE_SHIFT (ilog2(SCU_MAX_COMPLETION_QUEUE_ENTRIES)) #define SCU_MAX_COMPLETION_QUEUE_SHIFT (ilog2(SCU_MAX_COMPLETION_QUEUE_ENTRIES))
#define SCU_ABSOLUTE_MAX_UNSOLICITED_FRAMES (4096) #define SCU_ABSOLUTE_MAX_UNSOLICITED_FRAMES (4096)
#define SCU_UNSOLICITED_FRAME_BUFFER_SIZE (1024) #define SCU_UNSOLICITED_FRAME_BUFFER_SIZE (1024U)
#define SCU_INVALID_FRAME_INDEX (0xFFFF) #define SCU_INVALID_FRAME_INDEX (0xFFFF)
#define SCU_IO_REQUEST_MAX_SGE_SIZE (0x00FFFFFF) #define SCU_IO_REQUEST_MAX_SGE_SIZE (0x00FFFFFF)
......
...@@ -1490,29 +1490,30 @@ sci_io_request_frame_handler(struct isci_request *ireq, ...@@ -1490,29 +1490,30 @@ sci_io_request_frame_handler(struct isci_request *ireq,
return SCI_SUCCESS; return SCI_SUCCESS;
case SCI_REQ_SMP_WAIT_RESP: { case SCI_REQ_SMP_WAIT_RESP: {
struct smp_resp *rsp_hdr = &ireq->smp.rsp; struct sas_task *task = isci_request_access_task(ireq);
void *frame_header; struct scatterlist *sg = &task->smp_task.smp_resp;
void *frame_header, *kaddr;
u8 *rsp;
sci_unsolicited_frame_control_get_header(&ihost->uf_control, sci_unsolicited_frame_control_get_header(&ihost->uf_control,
frame_index, frame_index,
&frame_header); &frame_header);
kaddr = kmap_atomic(sg_page(sg), KM_IRQ0);
/* byte swap the header. */ rsp = kaddr + sg->offset;
word_cnt = SMP_RESP_HDR_SZ / sizeof(u32); sci_swab32_cpy(rsp, frame_header, 1);
sci_swab32_cpy(rsp_hdr, frame_header, word_cnt);
if (rsp_hdr->frame_type == SMP_RESPONSE) { if (rsp[0] == SMP_RESPONSE) {
void *smp_resp; void *smp_resp;
sci_unsolicited_frame_control_get_buffer(&ihost->uf_control, sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
frame_index, frame_index,
&smp_resp); &smp_resp);
word_cnt = (sizeof(struct smp_resp) - SMP_RESP_HDR_SZ) / word_cnt = (sg->length/4)-1;
sizeof(u32); if (word_cnt > 0)
word_cnt = min_t(unsigned int, word_cnt,
sci_swab32_cpy(((u8 *) rsp_hdr) + SMP_RESP_HDR_SZ, SCU_UNSOLICITED_FRAME_BUFFER_SIZE/4);
smp_resp, word_cnt); sci_swab32_cpy(rsp + 4, smp_resp, word_cnt);
ireq->scu_status = SCU_TASK_DONE_GOOD; ireq->scu_status = SCU_TASK_DONE_GOOD;
ireq->sci_status = SCI_SUCCESS; ireq->sci_status = SCI_SUCCESS;
...@@ -1528,12 +1529,13 @@ sci_io_request_frame_handler(struct isci_request *ireq, ...@@ -1528,12 +1529,13 @@ sci_io_request_frame_handler(struct isci_request *ireq,
__func__, __func__,
ireq, ireq,
frame_index, frame_index,
rsp_hdr->frame_type); rsp[0]);
ireq->scu_status = SCU_TASK_DONE_SMP_FRM_TYPE_ERR; ireq->scu_status = SCU_TASK_DONE_SMP_FRM_TYPE_ERR;
ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR; ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
sci_change_state(&ireq->sm, SCI_REQ_COMPLETED); sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
} }
kunmap_atomic(kaddr, KM_IRQ0);
sci_controller_release_frame(ihost, frame_index); sci_controller_release_frame(ihost, frame_index);
...@@ -2603,18 +2605,7 @@ static void isci_request_io_request_complete(struct isci_host *ihost, ...@@ -2603,18 +2605,7 @@ static void isci_request_io_request_complete(struct isci_host *ihost,
status = SAM_STAT_GOOD; status = SAM_STAT_GOOD;
set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags); set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
if (task->task_proto == SAS_PROTOCOL_SMP) { if (completion_status == SCI_IO_SUCCESS_IO_DONE_EARLY) {
void *rsp = &request->smp.rsp;
dev_dbg(&ihost->pdev->dev,
"%s: SMP protocol completion\n",
__func__);
sg_copy_from_buffer(
&task->smp_task.smp_resp, 1,
rsp, sizeof(struct smp_resp));
} else if (completion_status
== SCI_IO_SUCCESS_IO_DONE_EARLY) {
/* This was an SSP / STP / SATA transfer. /* This was an SSP / STP / SATA transfer.
* There is a possibility that less data than * There is a possibility that less data than
......
...@@ -173,9 +173,6 @@ struct isci_request { ...@@ -173,9 +173,6 @@ struct isci_request {
u8 rsp_buf[SSP_RESP_IU_MAX_SIZE]; u8 rsp_buf[SSP_RESP_IU_MAX_SIZE];
}; };
} ssp; } ssp;
struct {
struct smp_resp rsp;
} smp;
struct { struct {
struct isci_stp_request req; struct isci_stp_request req;
struct host_to_dev_fis cmd; struct host_to_dev_fis cmd;
......
...@@ -204,8 +204,6 @@ struct smp_req { ...@@ -204,8 +204,6 @@ struct smp_req {
u8 req_data[0]; u8 req_data[0];
} __packed; } __packed;
#define SMP_RESP_HDR_SZ 4
/* /*
* struct sci_sas_address - This structure depicts how a SAS address is * struct sci_sas_address - This structure depicts how a SAS address is
* represented by SCI. * represented by SCI.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment