Skip to content

Commit

Permalink
[SCSI] isci: fix support for large smp requests
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Dan Williams authored and James Bottomley committed Oct 2, 2011
1 parent 6fbc769 commit 54b5e3a
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 35 deletions.
2 changes: 1 addition & 1 deletion drivers/scsi/isci/isci.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
#define SCU_MAX_COMPLETION_QUEUE_SHIFT (ilog2(SCU_MAX_COMPLETION_QUEUE_ENTRIES))

#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_IO_REQUEST_MAX_SGE_SIZE (0x00FFFFFF)
Expand Down
49 changes: 20 additions & 29 deletions drivers/scsi/isci/request.c
Original file line number Diff line number Diff line change
Expand Up @@ -1490,29 +1490,30 @@ sci_io_request_frame_handler(struct isci_request *ireq,
return SCI_SUCCESS;

case SCI_REQ_SMP_WAIT_RESP: {
struct smp_resp *rsp_hdr = &ireq->smp.rsp;
void *frame_header;
struct sas_task *task = isci_request_access_task(ireq);
struct scatterlist *sg = &task->smp_task.smp_resp;
void *frame_header, *kaddr;
u8 *rsp;

sci_unsolicited_frame_control_get_header(&ihost->uf_control,
frame_index,
&frame_header);

/* byte swap the header. */
word_cnt = SMP_RESP_HDR_SZ / sizeof(u32);
sci_swab32_cpy(rsp_hdr, frame_header, word_cnt);
frame_index,
&frame_header);
kaddr = kmap_atomic(sg_page(sg), KM_IRQ0);
rsp = kaddr + sg->offset;
sci_swab32_cpy(rsp, frame_header, 1);

if (rsp_hdr->frame_type == SMP_RESPONSE) {
if (rsp[0] == SMP_RESPONSE) {
void *smp_resp;

sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
frame_index,
&smp_resp);
frame_index,
&smp_resp);

word_cnt = (sizeof(struct smp_resp) - SMP_RESP_HDR_SZ) /
sizeof(u32);

sci_swab32_cpy(((u8 *) rsp_hdr) + SMP_RESP_HDR_SZ,
smp_resp, word_cnt);
word_cnt = (sg->length/4)-1;
if (word_cnt > 0)
word_cnt = min_t(unsigned int, word_cnt,
SCU_UNSOLICITED_FRAME_BUFFER_SIZE/4);
sci_swab32_cpy(rsp + 4, smp_resp, word_cnt);

ireq->scu_status = SCU_TASK_DONE_GOOD;
ireq->sci_status = SCI_SUCCESS;
Expand All @@ -1528,12 +1529,13 @@ sci_io_request_frame_handler(struct isci_request *ireq,
__func__,
ireq,
frame_index,
rsp_hdr->frame_type);
rsp[0]);

ireq->scu_status = SCU_TASK_DONE_SMP_FRM_TYPE_ERR;
ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
}
kunmap_atomic(kaddr, KM_IRQ0);

sci_controller_release_frame(ihost, frame_index);

Expand Down Expand Up @@ -2603,18 +2605,7 @@ static void isci_request_io_request_complete(struct isci_host *ihost,
status = SAM_STAT_GOOD;
set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);

if (task->task_proto == SAS_PROTOCOL_SMP) {
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) {
if (completion_status == SCI_IO_SUCCESS_IO_DONE_EARLY) {

/* This was an SSP / STP / SATA transfer.
* There is a possibility that less data than
Expand Down
3 changes: 0 additions & 3 deletions drivers/scsi/isci/request.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,6 @@ struct isci_request {
u8 rsp_buf[SSP_RESP_IU_MAX_SIZE];
};
} ssp;
struct {
struct smp_resp rsp;
} smp;
struct {
struct isci_stp_request req;
struct host_to_dev_fis cmd;
Expand Down
2 changes: 0 additions & 2 deletions drivers/scsi/isci/sas.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,6 @@ struct smp_req {
u8 req_data[0];
} __packed;

#define SMP_RESP_HDR_SZ 4

/*
* struct sci_sas_address - This structure depicts how a SAS address is
* represented by SCI.
Expand Down

0 comments on commit 54b5e3a

Please sign in to comment.