aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/isci/request.c138
-rw-r--r--drivers/scsi/isci/request.h1
-rw-r--r--drivers/scsi/isci/sas.h11
3 files changed, 65 insertions, 85 deletions
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c
index 395084955150..1043fed2a40a 100644
--- a/drivers/scsi/isci/request.c
+++ b/drivers/scsi/isci/request.c
@@ -2943,6 +2943,20 @@ static void isci_request_io_request_complete(struct isci_host *isci_host,
2943 dma_unmap_sg(&isci_host->pdev->dev, task->scatter, 2943 dma_unmap_sg(&isci_host->pdev->dev, task->scatter,
2944 request->num_sg_entries, task->data_dir); 2944 request->num_sg_entries, task->data_dir);
2945 break; 2945 break;
2946 case SAS_PROTOCOL_SMP: {
2947 struct scatterlist *sg = &task->smp_task.smp_req;
2948 struct smp_req *smp_req;
2949 void *kaddr;
2950
2951 dma_unmap_sg(&isci_host->pdev->dev, sg, 1, DMA_TO_DEVICE);
2952
2953 /* need to swab it back in case the command buffer is re-used */
2954 kaddr = kmap_atomic(sg_page(sg), KM_IRQ0);
2955 smp_req = kaddr + sg->offset;
2956 sci_swab32_cpy(smp_req, smp_req, sg->length / sizeof(u32));
2957 kunmap_atomic(kaddr, KM_IRQ0);
2958 break;
2959 }
2946 default: 2960 default:
2947 break; 2961 break;
2948 } 2962 }
@@ -3160,7 +3174,7 @@ scic_io_request_construct(struct scic_sds_controller *scic,
3160 else if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) 3174 else if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP))
3161 memset(&sci_req->stp.cmd, 0, sizeof(sci_req->stp.cmd)); 3175 memset(&sci_req->stp.cmd, 0, sizeof(sci_req->stp.cmd));
3162 else if (dev_is_expander(dev)) 3176 else if (dev_is_expander(dev))
3163 memset(&sci_req->smp.cmd, 0, sizeof(sci_req->smp.cmd)); 3177 /* pass */;
3164 else 3178 else
3165 return SCI_FAILURE_UNSUPPORTED_PROTOCOL; 3179 return SCI_FAILURE_UNSUPPORTED_PROTOCOL;
3166 3180
@@ -3236,30 +3250,54 @@ static enum sci_status isci_request_stp_request_construct(
3236 return status; 3250 return status;
3237} 3251}
3238 3252
3239/* 3253static enum sci_status
3240 * This function will fill in the SCU Task Context for a SMP request. The 3254scic_io_request_construct_smp(struct device *dev,
3241 * following important settings are utilized: -# task_type == 3255 struct scic_sds_request *sci_req,
3242 * SCU_TASK_TYPE_SMP. This simply indicates that a normal request type 3256 struct sas_task *task)
3243 * (i.e. non-raw frame) is being utilized to perform task management. -#
3244 * control_frame == 1. This ensures that the proper endianess is set so
3245 * that the bytes are transmitted in the right order for a smp request frame.
3246 * @sci_req: This parameter specifies the smp request object being
3247 * constructed.
3248 *
3249 */
3250static void
3251scu_smp_request_construct_task_context(struct scic_sds_request *sci_req,
3252 ssize_t req_len)
3253{ 3257{
3254 dma_addr_t dma_addr; 3258 struct scatterlist *sg = &task->smp_task.smp_req;
3255 struct scic_sds_remote_device *sci_dev; 3259 struct scic_sds_remote_device *sci_dev;
3256 struct scic_sds_port *sci_port;
3257 struct scu_task_context *task_context; 3260 struct scu_task_context *task_context;
3258 ssize_t word_cnt = sizeof(struct smp_req) / sizeof(u32); 3261 struct scic_sds_port *sci_port;
3262 struct smp_req *smp_req;
3263 void *kaddr;
3264 u8 req_len;
3265 u32 cmd;
3266
3267 kaddr = kmap_atomic(sg_page(sg), KM_IRQ0);
3268 smp_req = kaddr + sg->offset;
3269 /*
3270 * Look at the SMP requests' header fields; for certain SAS 1.x SMP
3271 * functions under SAS 2.0, a zero request length really indicates
3272 * a non-zero default length.
3273 */
3274 if (smp_req->req_len == 0) {
3275 switch (smp_req->func) {
3276 case SMP_DISCOVER:
3277 case SMP_REPORT_PHY_ERR_LOG:
3278 case SMP_REPORT_PHY_SATA:
3279 case SMP_REPORT_ROUTE_INFO:
3280 smp_req->req_len = 2;
3281 break;
3282 case SMP_CONF_ROUTE_INFO:
3283 case SMP_PHY_CONTROL:
3284 case SMP_PHY_TEST_FUNCTION:
3285 smp_req->req_len = 9;
3286 break;
3287 /* Default - zero is a valid default for 2.0. */
3288 }
3289 }
3290 req_len = smp_req->req_len;
3291 sci_swab32_cpy(smp_req, smp_req, sg->length / sizeof(u32));
3292 cmd = *(u32 *) smp_req;
3293 kunmap_atomic(kaddr, KM_IRQ0);
3294
3295 if (!dma_map_sg(dev, sg, 1, DMA_TO_DEVICE))
3296 return SCI_FAILURE;
3297
3298 sci_req->protocol = SCIC_SMP_PROTOCOL;
3259 3299
3260 /* byte swap the smp request. */ 3300 /* byte swap the smp request. */
3261 sci_swab32_cpy(&sci_req->smp.cmd, &sci_req->smp.cmd,
3262 word_cnt);
3263 3301
3264 task_context = scic_sds_request_get_task_context(sci_req); 3302 task_context = scic_sds_request_get_task_context(sci_req);
3265 3303
@@ -3307,7 +3345,7 @@ scu_smp_request_construct_task_context(struct scic_sds_request *sci_req,
3307 * 18h ~ 30h, protocol specific 3345 * 18h ~ 30h, protocol specific
3308 * since commandIU has been build by framework at this point, we just 3346 * since commandIU has been build by framework at this point, we just
3309 * copy the frist DWord from command IU to this location. */ 3347 * copy the frist DWord from command IU to this location. */
3310 memcpy(&task_context->type.smp, &sci_req->smp.cmd, sizeof(u32)); 3348 memcpy(&task_context->type.smp, &cmd, sizeof(u32));
3311 3349
3312 /* 3350 /*
3313 * 40h 3351 * 40h
@@ -3347,48 +3385,12 @@ scu_smp_request_construct_task_context(struct scic_sds_request *sci_req,
3347 * Copy the physical address for the command buffer to the SCU Task 3385 * Copy the physical address for the command buffer to the SCU Task
3348 * Context command buffer should not contain command header. 3386 * Context command buffer should not contain command header.
3349 */ 3387 */
3350 dma_addr = scic_io_request_get_dma_addr(sci_req, 3388 task_context->command_iu_upper = upper_32_bits(sg_dma_address(sg));
3351 ((char *) &sci_req->smp.cmd) + 3389 task_context->command_iu_lower = lower_32_bits(sg_dma_address(sg) + sizeof(u32));
3352 sizeof(u32));
3353
3354 task_context->command_iu_upper = upper_32_bits(dma_addr);
3355 task_context->command_iu_lower = lower_32_bits(dma_addr);
3356 3390
3357 /* SMP response comes as UF, so no need to set response IU address. */ 3391 /* SMP response comes as UF, so no need to set response IU address. */
3358 task_context->response_iu_upper = 0; 3392 task_context->response_iu_upper = 0;
3359 task_context->response_iu_lower = 0; 3393 task_context->response_iu_lower = 0;
3360}
3361
3362static enum sci_status
3363scic_io_request_construct_smp(struct scic_sds_request *sci_req)
3364{
3365 struct smp_req *smp_req = &sci_req->smp.cmd;
3366
3367 sci_req->protocol = SCIC_SMP_PROTOCOL;
3368
3369 /*
3370 * Look at the SMP requests' header fields; for certain SAS 1.x SMP
3371 * functions under SAS 2.0, a zero request length really indicates
3372 * a non-zero default length.
3373 */
3374 if (smp_req->req_len == 0) {
3375 switch (smp_req->func) {
3376 case SMP_DISCOVER:
3377 case SMP_REPORT_PHY_ERR_LOG:
3378 case SMP_REPORT_PHY_SATA:
3379 case SMP_REPORT_ROUTE_INFO:
3380 smp_req->req_len = 2;
3381 break;
3382 case SMP_CONF_ROUTE_INFO:
3383 case SMP_PHY_CONTROL:
3384 case SMP_PHY_TEST_FUNCTION:
3385 smp_req->req_len = 9;
3386 break;
3387 /* Default - zero is a valid default for 2.0. */
3388 }
3389 }
3390
3391 scu_smp_request_construct_task_context(sci_req, smp_req->req_len);
3392 3394
3393 sci_change_state(&sci_req->sm, SCI_REQ_CONSTRUCTED); 3395 sci_change_state(&sci_req->sm, SCI_REQ_CONSTRUCTED);
3394 3396
@@ -3404,24 +3406,12 @@ scic_io_request_construct_smp(struct scic_sds_request *sci_req)
3404 */ 3406 */
3405static enum sci_status isci_smp_request_build(struct isci_request *ireq) 3407static enum sci_status isci_smp_request_build(struct isci_request *ireq)
3406{ 3408{
3407 enum sci_status status = SCI_FAILURE;
3408 struct sas_task *task = isci_request_access_task(ireq); 3409 struct sas_task *task = isci_request_access_task(ireq);
3410 struct device *dev = &ireq->isci_host->pdev->dev;
3409 struct scic_sds_request *sci_req = &ireq->sci; 3411 struct scic_sds_request *sci_req = &ireq->sci;
3412 enum sci_status status = SCI_FAILURE;
3410 3413
3411 dev_dbg(&ireq->isci_host->pdev->dev, 3414 status = scic_io_request_construct_smp(dev, sci_req, task);
3412 "%s: request = %p\n", __func__, ireq);
3413
3414 dev_dbg(&ireq->isci_host->pdev->dev,
3415 "%s: smp_req len = %d\n",
3416 __func__,
3417 task->smp_task.smp_req.length);
3418
3419 /* copy the smp_command to the address; */
3420 sg_copy_to_buffer(&task->smp_task.smp_req, 1,
3421 &sci_req->smp.cmd,
3422 sizeof(struct smp_req));
3423
3424 status = scic_io_request_construct_smp(sci_req);
3425 if (status != SCI_SUCCESS) 3415 if (status != SCI_SUCCESS)
3426 dev_warn(&ireq->isci_host->pdev->dev, 3416 dev_warn(&ireq->isci_host->pdev->dev,
3427 "%s: failed with status = %d\n", 3417 "%s: failed with status = %d\n",
diff --git a/drivers/scsi/isci/request.h b/drivers/scsi/isci/request.h
index 324fb7b3ab42..7c8b59a7c02c 100644
--- a/drivers/scsi/isci/request.h
+++ b/drivers/scsi/isci/request.h
@@ -244,7 +244,6 @@ struct scic_sds_request {
244 } ssp; 244 } ssp;
245 245
246 struct { 246 struct {
247 struct smp_req cmd;
248 struct smp_resp rsp; 247 struct smp_resp rsp;
249 } smp; 248 } smp;
250 249
diff --git a/drivers/scsi/isci/sas.h b/drivers/scsi/isci/sas.h
index 822a8dbd19ca..462b15174d3f 100644
--- a/drivers/scsi/isci/sas.h
+++ b/drivers/scsi/isci/sas.h
@@ -190,8 +190,6 @@ struct smp_req_phycntl {
190 u8 _r_h[3]; /* bytes 37-39 */ 190 u8 _r_h[3]; /* bytes 37-39 */
191} __packed; 191} __packed;
192 192
193#define SMP_REQ_VENDOR_SPECIFIC_MAX_LEN 1016
194
195/* 193/*
196 * struct smp_req - This structure simply unionizes the existing request 194 * struct smp_req - This structure simply unionizes the existing request
197 * structures into a common request type. 195 * structures into a common request type.
@@ -203,14 +201,7 @@ struct smp_req {
203 u8 func; /* byte 1 */ 201 u8 func; /* byte 1 */
204 u8 alloc_resp_len; /* byte 2 */ 202 u8 alloc_resp_len; /* byte 2 */
205 u8 req_len; /* byte 3 */ 203 u8 req_len; /* byte 3 */
206 204 u8 req_data[0];
207 union { /* bytes 4-N */
208 u32 smp_req_gen;
209 struct smp_req_phy_id phy_id;
210 struct smp_req_phycntl phy_cntl;
211 struct smp_req_conf_rtinfo conf_rt_info;
212 u8 vendor[SMP_REQ_VENDOR_SPECIFIC_MAX_LEN];
213 };
214} __packed; 205} __packed;
215 206
216#define SMP_RESP_HDR_SZ 4 207#define SMP_RESP_HDR_SZ 4