[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>
This commit is contained in:
		
							parent
							
								
									6fbc769219
								
							
						
					
					
						commit
						54b5e3a4bf
					
				| @ -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) | ||||
|  | ||||
| @ -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); | ||||
| 							 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); | ||||
| 								 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 | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| @ -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. | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user