diff options
author | James Bottomley <JBottomley@Parallels.com> | 2013-05-07 18:38:18 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-06-04 14:15:59 -0400 |
commit | e73823f7a2c921dcf068d34ea03bd682498d9e42 (patch) | |
tree | 8b5b2262352572b3069a671f7578ea6d5ef07162 | |
parent | 9edf7d75ee5f21663a0183d21f702682d0ef132f (diff) |
[SCSI] libsas: implement > 16 byte CDB support
Remove the arbitrary expectation in libsas that all SCSI commands are 16 bytes
or less. Instead do all copies via cmd->cmd_len (and use a pointer to this in
the libsas task instead of a copy). Note that this still doesn't enable > 16
byte CDB support in the underlying drivers because their internal format has
to be fixed and the wire format of > 16 byte CDBs according to the SAS spec is
different. the libsas drivers (isci, aic94xx, mvsas and pm8xxx are all
updated for this change.
Cc: Lukasz Dorau <lukasz.dorau@intel.com>
Cc: Maciej Patelczyk <maciej.patelczyk@intel.com>
Cc: Dave Jiang <dave.jiang@intel.com>
Cc: Jack Wang <xjtuwjp@gmail.com>
Cc: Lindar Liu <lindar_liu@usish.com>
Cc: Xiangliang Yu <yuxiangl@marvell.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r-- | drivers/scsi/aic94xx/aic94xx_task.c | 3 | ||||
-rw-r--r-- | drivers/scsi/isci/request.c | 4 | ||||
-rw-r--r-- | drivers/scsi/libsas/sas_scsi_host.c | 2 | ||||
-rw-r--r-- | drivers/scsi/mvsas/mv_sas.c | 3 | ||||
-rw-r--r-- | drivers/scsi/pm8001/pm8001_hwi.c | 3 | ||||
-rw-r--r-- | drivers/scsi/pm8001/pm80xx_hwi.c | 21 | ||||
-rw-r--r-- | include/scsi/libsas.h | 2 |
7 files changed, 21 insertions, 17 deletions
diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c index 393e7ce8e95a..59b86e260ce9 100644 --- a/drivers/scsi/aic94xx/aic94xx_task.c +++ b/drivers/scsi/aic94xx/aic94xx_task.c | |||
@@ -505,7 +505,8 @@ static int asd_build_ssp_ascb(struct asd_ascb *ascb, struct sas_task *task, | |||
505 | scb->ssp_task.ssp_cmd.efb_prio_attr |= EFB_MASK; | 505 | scb->ssp_task.ssp_cmd.efb_prio_attr |= EFB_MASK; |
506 | scb->ssp_task.ssp_cmd.efb_prio_attr |= (task->ssp_task.task_prio << 3); | 506 | scb->ssp_task.ssp_cmd.efb_prio_attr |= (task->ssp_task.task_prio << 3); |
507 | scb->ssp_task.ssp_cmd.efb_prio_attr |= (task->ssp_task.task_attr & 7); | 507 | scb->ssp_task.ssp_cmd.efb_prio_attr |= (task->ssp_task.task_attr & 7); |
508 | memcpy(scb->ssp_task.ssp_cmd.cdb, task->ssp_task.cdb, 16); | 508 | memcpy(scb->ssp_task.ssp_cmd.cdb, task->ssp_task.cmd->cmnd, |
509 | task->ssp_task.cmd->cmd_len); | ||
509 | 510 | ||
510 | scb->ssp_task.sister_scb = cpu_to_le16(0xFFFF); | 511 | scb->ssp_task.sister_scb = cpu_to_le16(0xFFFF); |
511 | scb->ssp_task.conn_handle = cpu_to_le16( | 512 | scb->ssp_task.conn_handle = cpu_to_le16( |
diff --git a/drivers/scsi/isci/request.c b/drivers/scsi/isci/request.c index e3e3bcbd5a9f..7b082157eb79 100644 --- a/drivers/scsi/isci/request.c +++ b/drivers/scsi/isci/request.c | |||
@@ -184,8 +184,8 @@ static void sci_io_request_build_ssp_command_iu(struct isci_request *ireq) | |||
184 | cmd_iu->task_attr = task->ssp_task.task_attr; | 184 | cmd_iu->task_attr = task->ssp_task.task_attr; |
185 | cmd_iu->_r_c = 0; | 185 | cmd_iu->_r_c = 0; |
186 | 186 | ||
187 | sci_swab32_cpy(&cmd_iu->cdb, task->ssp_task.cdb, | 187 | sci_swab32_cpy(&cmd_iu->cdb, task->ssp_task.cmd->cmnd, |
188 | sizeof(task->ssp_task.cdb) / sizeof(u32)); | 188 | task->ssp_task.cmd->cmd_len / sizeof(u32)); |
189 | } | 189 | } |
190 | 190 | ||
191 | static void sci_task_request_build_ssp_task_iu(struct isci_request *ireq) | 191 | static void sci_task_request_build_ssp_task_iu(struct isci_request *ireq) |
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 6e795a174a12..da3aee17faa5 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c | |||
@@ -167,7 +167,7 @@ static struct sas_task *sas_create_task(struct scsi_cmnd *cmd, | |||
167 | int_to_scsilun(cmd->device->lun, &lun); | 167 | int_to_scsilun(cmd->device->lun, &lun); |
168 | memcpy(task->ssp_task.LUN, &lun.scsi_lun, 8); | 168 | memcpy(task->ssp_task.LUN, &lun.scsi_lun, 8); |
169 | task->ssp_task.task_attr = TASK_ATTR_SIMPLE; | 169 | task->ssp_task.task_attr = TASK_ATTR_SIMPLE; |
170 | memcpy(task->ssp_task.cdb, cmd->cmnd, 16); | 170 | task->ssp_task.cmd = cmd; |
171 | 171 | ||
172 | task->scatter = scsi_sglist(cmd); | 172 | task->scatter = scsi_sglist(cmd); |
173 | task->num_scatter = scsi_sg_count(cmd); | 173 | task->num_scatter = scsi_sg_count(cmd); |
diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c index c9e244984e30..f14665a6293d 100644 --- a/drivers/scsi/mvsas/mv_sas.c +++ b/drivers/scsi/mvsas/mv_sas.c | |||
@@ -686,7 +686,8 @@ static int mvs_task_prep_ssp(struct mvs_info *mvi, | |||
686 | if (ssp_hdr->frame_type != SSP_TASK) { | 686 | if (ssp_hdr->frame_type != SSP_TASK) { |
687 | buf_cmd[9] = fburst | task->ssp_task.task_attr | | 687 | buf_cmd[9] = fburst | task->ssp_task.task_attr | |
688 | (task->ssp_task.task_prio << 3); | 688 | (task->ssp_task.task_prio << 3); |
689 | memcpy(buf_cmd + 12, &task->ssp_task.cdb, 16); | 689 | memcpy(buf_cmd + 12, task->ssp_task.cmd->cmnd, |
690 | task->ssp_task.cmd->cmd_len); | ||
690 | } else{ | 691 | } else{ |
691 | buf_cmd[10] = tmf->tmf; | 692 | buf_cmd[10] = tmf->tmf; |
692 | switch (tmf->tmf) { | 693 | switch (tmf->tmf) { |
diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 69dd49c05f1e..a58546f73f0d 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c | |||
@@ -4291,7 +4291,8 @@ static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, | |||
4291 | ssp_cmd.ssp_iu.efb_prio_attr |= 0x80; | 4291 | ssp_cmd.ssp_iu.efb_prio_attr |= 0x80; |
4292 | ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_prio << 3); | 4292 | ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_prio << 3); |
4293 | ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7); | 4293 | ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7); |
4294 | memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cdb, 16); | 4294 | memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cmd->cmnd, |
4295 | task->ssp_task.cmd->cmd_len); | ||
4295 | circularQ = &pm8001_ha->inbnd_q_tbl[0]; | 4296 | circularQ = &pm8001_ha->inbnd_q_tbl[0]; |
4296 | 4297 | ||
4297 | /* fill in PRD (scatter/gather) table, if any */ | 4298 | /* fill in PRD (scatter/gather) table, if any */ |
diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index 302514d8157b..f6c65eeafb5d 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c | |||
@@ -3559,9 +3559,9 @@ err_out: | |||
3559 | 3559 | ||
3560 | static int check_enc_sas_cmd(struct sas_task *task) | 3560 | static int check_enc_sas_cmd(struct sas_task *task) |
3561 | { | 3561 | { |
3562 | if ((task->ssp_task.cdb[0] == READ_10) | 3562 | u8 cmd = task->ssp_task.cmd->cmnd[0]; |
3563 | || (task->ssp_task.cdb[0] == WRITE_10) | 3563 | |
3564 | || (task->ssp_task.cdb[0] == WRITE_VERIFY)) | 3564 | if (cmd == READ_10 || cmd == WRITE_10 || cmd == WRITE_VERIFY) |
3565 | return 1; | 3565 | return 1; |
3566 | else | 3566 | else |
3567 | return 0; | 3567 | return 0; |
@@ -3624,7 +3624,8 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, | |||
3624 | ssp_cmd.ssp_iu.efb_prio_attr |= 0x80; | 3624 | ssp_cmd.ssp_iu.efb_prio_attr |= 0x80; |
3625 | ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_prio << 3); | 3625 | ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_prio << 3); |
3626 | ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7); | 3626 | ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7); |
3627 | memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cdb, 16); | 3627 | memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cmd->cmnd, |
3628 | task->ssp_task.cmd->cmd_len); | ||
3628 | circularQ = &pm8001_ha->inbnd_q_tbl[0]; | 3629 | circularQ = &pm8001_ha->inbnd_q_tbl[0]; |
3629 | 3630 | ||
3630 | /* Check if encryption is set */ | 3631 | /* Check if encryption is set */ |
@@ -3632,7 +3633,7 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, | |||
3632 | !(pm8001_ha->encrypt_info.status) && check_enc_sas_cmd(task)) { | 3633 | !(pm8001_ha->encrypt_info.status) && check_enc_sas_cmd(task)) { |
3633 | PM8001_IO_DBG(pm8001_ha, pm8001_printk( | 3634 | PM8001_IO_DBG(pm8001_ha, pm8001_printk( |
3634 | "Encryption enabled.Sending Encrypt SAS command 0x%x\n", | 3635 | "Encryption enabled.Sending Encrypt SAS command 0x%x\n", |
3635 | task->ssp_task.cdb[0])); | 3636 | task->ssp_task.cmd->cmnd[0])); |
3636 | opc = OPC_INB_SSP_INI_DIF_ENC_IO; | 3637 | opc = OPC_INB_SSP_INI_DIF_ENC_IO; |
3637 | /* enable encryption. 0 for SAS 1.1 and SAS 2.0 compatible TLR*/ | 3638 | /* enable encryption. 0 for SAS 1.1 and SAS 2.0 compatible TLR*/ |
3638 | ssp_cmd.dad_dir_m_tlr = cpu_to_le32 | 3639 | ssp_cmd.dad_dir_m_tlr = cpu_to_le32 |
@@ -3666,14 +3667,14 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, | |||
3666 | /* XTS mode. All other fields are 0 */ | 3667 | /* XTS mode. All other fields are 0 */ |
3667 | ssp_cmd.key_cmode = 0x6 << 4; | 3668 | ssp_cmd.key_cmode = 0x6 << 4; |
3668 | /* set tweak values. Should be the start lba */ | 3669 | /* set tweak values. Should be the start lba */ |
3669 | ssp_cmd.twk_val0 = cpu_to_le32((task->ssp_task.cdb[2] << 24) | | 3670 | ssp_cmd.twk_val0 = cpu_to_le32((task->ssp_task.cmd->cmnd[2] << 24) | |
3670 | (task->ssp_task.cdb[3] << 16) | | 3671 | (task->ssp_task.cmd->cmnd[3] << 16) | |
3671 | (task->ssp_task.cdb[4] << 8) | | 3672 | (task->ssp_task.cmd->cmnd[4] << 8) | |
3672 | (task->ssp_task.cdb[5])); | 3673 | (task->ssp_task.cmd->cmnd[5])); |
3673 | } else { | 3674 | } else { |
3674 | PM8001_IO_DBG(pm8001_ha, pm8001_printk( | 3675 | PM8001_IO_DBG(pm8001_ha, pm8001_printk( |
3675 | "Sending Normal SAS command 0x%x inb q %x\n", | 3676 | "Sending Normal SAS command 0x%x inb q %x\n", |
3676 | task->ssp_task.cdb[0], inb)); | 3677 | task->ssp_task.cmd->cmnd[0], inb)); |
3677 | /* fill in PRD (scatter/gather) table, if any */ | 3678 | /* fill in PRD (scatter/gather) table, if any */ |
3678 | if (task->num_scatter > 1) { | 3679 | if (task->num_scatter > 1) { |
3679 | pm8001_chip_make_sg(task->scatter, ccb->n_elem, | 3680 | pm8001_chip_make_sg(task->scatter, ccb->n_elem, |
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h index e2c1e66d58ae..f843dd8722a9 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h | |||
@@ -608,7 +608,7 @@ struct sas_ssp_task { | |||
608 | u8 enable_first_burst:1; | 608 | u8 enable_first_burst:1; |
609 | enum task_attribute task_attr; | 609 | enum task_attribute task_attr; |
610 | u8 task_prio; | 610 | u8 task_prio; |
611 | u8 cdb[16]; | 611 | struct scsi_cmnd *cmd; |
612 | }; | 612 | }; |
613 | 613 | ||
614 | struct sas_task { | 614 | struct sas_task { |