Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 254560
b: refs/heads/master
c: e9bf709
h: refs/heads/master
v: v3
  • Loading branch information
Dan Williams committed Jul 3, 2011
1 parent d0c8659 commit 60f510b
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 86 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ddcc7e347a891937be65358b43f40b7f81185f8f
refs/heads/master: e9bf709564e90abea25ca7aeae8c3de5cc6468d7
138 changes: 64 additions & 74 deletions trunk/drivers/scsi/isci/request.c
Original file line number Diff line number Diff line change
Expand Up @@ -2943,6 +2943,20 @@ static void isci_request_io_request_complete(struct isci_host *isci_host,
dma_unmap_sg(&isci_host->pdev->dev, task->scatter,
request->num_sg_entries, task->data_dir);
break;
case SAS_PROTOCOL_SMP: {
struct scatterlist *sg = &task->smp_task.smp_req;
struct smp_req *smp_req;
void *kaddr;

dma_unmap_sg(&isci_host->pdev->dev, sg, 1, DMA_TO_DEVICE);

/* need to swab it back in case the command buffer is re-used */
kaddr = kmap_atomic(sg_page(sg), KM_IRQ0);
smp_req = kaddr + sg->offset;
sci_swab32_cpy(smp_req, smp_req, sg->length / sizeof(u32));
kunmap_atomic(kaddr, KM_IRQ0);
break;
}
default:
break;
}
Expand Down Expand Up @@ -3160,7 +3174,7 @@ scic_io_request_construct(struct scic_sds_controller *scic,
else if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP))
memset(&sci_req->stp.cmd, 0, sizeof(sci_req->stp.cmd));
else if (dev_is_expander(dev))
memset(&sci_req->smp.cmd, 0, sizeof(sci_req->smp.cmd));
/* pass */;
else
return SCI_FAILURE_UNSUPPORTED_PROTOCOL;

Expand Down Expand Up @@ -3236,30 +3250,54 @@ static enum sci_status isci_request_stp_request_construct(
return status;
}

/*
* This function will fill in the SCU Task Context for a SMP request. The
* following important settings are utilized: -# task_type ==
* SCU_TASK_TYPE_SMP. This simply indicates that a normal request type
* (i.e. non-raw frame) is being utilized to perform task management. -#
* control_frame == 1. This ensures that the proper endianess is set so
* that the bytes are transmitted in the right order for a smp request frame.
* @sci_req: This parameter specifies the smp request object being
* constructed.
*
*/
static void
scu_smp_request_construct_task_context(struct scic_sds_request *sci_req,
ssize_t req_len)
static enum sci_status
scic_io_request_construct_smp(struct device *dev,
struct scic_sds_request *sci_req,
struct sas_task *task)
{
dma_addr_t dma_addr;
struct scatterlist *sg = &task->smp_task.smp_req;
struct scic_sds_remote_device *sci_dev;
struct scic_sds_port *sci_port;
struct scu_task_context *task_context;
ssize_t word_cnt = sizeof(struct smp_req) / sizeof(u32);
struct scic_sds_port *sci_port;
struct smp_req *smp_req;
void *kaddr;
u8 req_len;
u32 cmd;

kaddr = kmap_atomic(sg_page(sg), KM_IRQ0);
smp_req = kaddr + sg->offset;
/*
* Look at the SMP requests' header fields; for certain SAS 1.x SMP
* functions under SAS 2.0, a zero request length really indicates
* a non-zero default length.
*/
if (smp_req->req_len == 0) {
switch (smp_req->func) {
case SMP_DISCOVER:
case SMP_REPORT_PHY_ERR_LOG:
case SMP_REPORT_PHY_SATA:
case SMP_REPORT_ROUTE_INFO:
smp_req->req_len = 2;
break;
case SMP_CONF_ROUTE_INFO:
case SMP_PHY_CONTROL:
case SMP_PHY_TEST_FUNCTION:
smp_req->req_len = 9;
break;
/* Default - zero is a valid default for 2.0. */
}
}
req_len = smp_req->req_len;
sci_swab32_cpy(smp_req, smp_req, sg->length / sizeof(u32));
cmd = *(u32 *) smp_req;
kunmap_atomic(kaddr, KM_IRQ0);

if (!dma_map_sg(dev, sg, 1, DMA_TO_DEVICE))
return SCI_FAILURE;

sci_req->protocol = SCIC_SMP_PROTOCOL;

/* byte swap the smp request. */
sci_swab32_cpy(&sci_req->smp.cmd, &sci_req->smp.cmd,
word_cnt);

task_context = scic_sds_request_get_task_context(sci_req);

Expand Down Expand Up @@ -3307,7 +3345,7 @@ scu_smp_request_construct_task_context(struct scic_sds_request *sci_req,
* 18h ~ 30h, protocol specific
* since commandIU has been build by framework at this point, we just
* copy the frist DWord from command IU to this location. */
memcpy(&task_context->type.smp, &sci_req->smp.cmd, sizeof(u32));
memcpy(&task_context->type.smp, &cmd, sizeof(u32));

/*
* 40h
Expand Down Expand Up @@ -3347,48 +3385,12 @@ scu_smp_request_construct_task_context(struct scic_sds_request *sci_req,
* Copy the physical address for the command buffer to the SCU Task
* Context command buffer should not contain command header.
*/
dma_addr = scic_io_request_get_dma_addr(sci_req,
((char *) &sci_req->smp.cmd) +
sizeof(u32));

task_context->command_iu_upper = upper_32_bits(dma_addr);
task_context->command_iu_lower = lower_32_bits(dma_addr);
task_context->command_iu_upper = upper_32_bits(sg_dma_address(sg));
task_context->command_iu_lower = lower_32_bits(sg_dma_address(sg) + sizeof(u32));

/* SMP response comes as UF, so no need to set response IU address. */
task_context->response_iu_upper = 0;
task_context->response_iu_lower = 0;
}

static enum sci_status
scic_io_request_construct_smp(struct scic_sds_request *sci_req)
{
struct smp_req *smp_req = &sci_req->smp.cmd;

sci_req->protocol = SCIC_SMP_PROTOCOL;

/*
* Look at the SMP requests' header fields; for certain SAS 1.x SMP
* functions under SAS 2.0, a zero request length really indicates
* a non-zero default length.
*/
if (smp_req->req_len == 0) {
switch (smp_req->func) {
case SMP_DISCOVER:
case SMP_REPORT_PHY_ERR_LOG:
case SMP_REPORT_PHY_SATA:
case SMP_REPORT_ROUTE_INFO:
smp_req->req_len = 2;
break;
case SMP_CONF_ROUTE_INFO:
case SMP_PHY_CONTROL:
case SMP_PHY_TEST_FUNCTION:
smp_req->req_len = 9;
break;
/* Default - zero is a valid default for 2.0. */
}
}

scu_smp_request_construct_task_context(sci_req, smp_req->req_len);

sci_change_state(&sci_req->sm, SCI_REQ_CONSTRUCTED);

Expand All @@ -3404,24 +3406,12 @@ scic_io_request_construct_smp(struct scic_sds_request *sci_req)
*/
static enum sci_status isci_smp_request_build(struct isci_request *ireq)
{
enum sci_status status = SCI_FAILURE;
struct sas_task *task = isci_request_access_task(ireq);
struct device *dev = &ireq->isci_host->pdev->dev;
struct scic_sds_request *sci_req = &ireq->sci;
enum sci_status status = SCI_FAILURE;

dev_dbg(&ireq->isci_host->pdev->dev,
"%s: request = %p\n", __func__, ireq);

dev_dbg(&ireq->isci_host->pdev->dev,
"%s: smp_req len = %d\n",
__func__,
task->smp_task.smp_req.length);

/* copy the smp_command to the address; */
sg_copy_to_buffer(&task->smp_task.smp_req, 1,
&sci_req->smp.cmd,
sizeof(struct smp_req));

status = scic_io_request_construct_smp(sci_req);
status = scic_io_request_construct_smp(dev, sci_req, task);
if (status != SCI_SUCCESS)
dev_warn(&ireq->isci_host->pdev->dev,
"%s: failed with status = %d\n",
Expand Down
1 change: 0 additions & 1 deletion trunk/drivers/scsi/isci/request.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,6 @@ struct scic_sds_request {
} ssp;

struct {
struct smp_req cmd;
struct smp_resp rsp;
} smp;

Expand Down
11 changes: 1 addition & 10 deletions trunk/drivers/scsi/isci/sas.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,6 @@ struct smp_req_phycntl {
u8 _r_h[3]; /* bytes 37-39 */
} __packed;

#define SMP_REQ_VENDOR_SPECIFIC_MAX_LEN 1016

/*
* struct smp_req - This structure simply unionizes the existing request
* structures into a common request type.
Expand All @@ -203,14 +201,7 @@ struct smp_req {
u8 func; /* byte 1 */
u8 alloc_resp_len; /* byte 2 */
u8 req_len; /* byte 3 */

union { /* bytes 4-N */
u32 smp_req_gen;
struct smp_req_phy_id phy_id;
struct smp_req_phycntl phy_cntl;
struct smp_req_conf_rtinfo conf_rt_info;
u8 vendor[SMP_REQ_VENDOR_SPECIFIC_MAX_LEN];
};
u8 req_data[0];
} __packed;

#define SMP_RESP_HDR_SZ 4
Expand Down

0 comments on commit 60f510b

Please sign in to comment.