Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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)
+20 −29
Original line number Diff line number Diff line
@@ -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);
		kaddr = kmap_atomic(sg_page(sg), KM_IRQ0);
		rsp = kaddr + sg->offset;
		sci_swab32_cpy(rsp, frame_header, 1);

		/* byte swap the header. */
		word_cnt = SMP_RESP_HDR_SZ / sizeof(u32);
		sci_swab32_cpy(rsp_hdr, frame_header, word_cnt);

		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);

			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;
@@ -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);

@@ -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
+0 −3
Original line number Diff line number Diff line
@@ -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;
+0 −2
Original line number Diff line number Diff line
@@ -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.