Commit e73823f7 authored by James Bottomley's avatar James Bottomley

[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: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 9edf7d75
...@@ -505,7 +505,8 @@ static int asd_build_ssp_ascb(struct asd_ascb *ascb, struct sas_task *task, ...@@ -505,7 +505,8 @@ static int asd_build_ssp_ascb(struct asd_ascb *ascb, struct sas_task *task,
scb->ssp_task.ssp_cmd.efb_prio_attr |= EFB_MASK; scb->ssp_task.ssp_cmd.efb_prio_attr |= EFB_MASK;
scb->ssp_task.ssp_cmd.efb_prio_attr |= (task->ssp_task.task_prio << 3); scb->ssp_task.ssp_cmd.efb_prio_attr |= (task->ssp_task.task_prio << 3);
scb->ssp_task.ssp_cmd.efb_prio_attr |= (task->ssp_task.task_attr & 7); scb->ssp_task.ssp_cmd.efb_prio_attr |= (task->ssp_task.task_attr & 7);
memcpy(scb->ssp_task.ssp_cmd.cdb, task->ssp_task.cdb, 16); memcpy(scb->ssp_task.ssp_cmd.cdb, task->ssp_task.cmd->cmnd,
task->ssp_task.cmd->cmd_len);
scb->ssp_task.sister_scb = cpu_to_le16(0xFFFF); scb->ssp_task.sister_scb = cpu_to_le16(0xFFFF);
scb->ssp_task.conn_handle = cpu_to_le16( scb->ssp_task.conn_handle = cpu_to_le16(
......
...@@ -184,8 +184,8 @@ static void sci_io_request_build_ssp_command_iu(struct isci_request *ireq) ...@@ -184,8 +184,8 @@ static void sci_io_request_build_ssp_command_iu(struct isci_request *ireq)
cmd_iu->task_attr = task->ssp_task.task_attr; cmd_iu->task_attr = task->ssp_task.task_attr;
cmd_iu->_r_c = 0; cmd_iu->_r_c = 0;
sci_swab32_cpy(&cmd_iu->cdb, task->ssp_task.cdb, sci_swab32_cpy(&cmd_iu->cdb, task->ssp_task.cmd->cmnd,
sizeof(task->ssp_task.cdb) / sizeof(u32)); task->ssp_task.cmd->cmd_len / sizeof(u32));
} }
static void sci_task_request_build_ssp_task_iu(struct isci_request *ireq) static void sci_task_request_build_ssp_task_iu(struct isci_request *ireq)
......
...@@ -167,7 +167,7 @@ static struct sas_task *sas_create_task(struct scsi_cmnd *cmd, ...@@ -167,7 +167,7 @@ static struct sas_task *sas_create_task(struct scsi_cmnd *cmd,
int_to_scsilun(cmd->device->lun, &lun); int_to_scsilun(cmd->device->lun, &lun);
memcpy(task->ssp_task.LUN, &lun.scsi_lun, 8); memcpy(task->ssp_task.LUN, &lun.scsi_lun, 8);
task->ssp_task.task_attr = TASK_ATTR_SIMPLE; task->ssp_task.task_attr = TASK_ATTR_SIMPLE;
memcpy(task->ssp_task.cdb, cmd->cmnd, 16); task->ssp_task.cmd = cmd;
task->scatter = scsi_sglist(cmd); task->scatter = scsi_sglist(cmd);
task->num_scatter = scsi_sg_count(cmd); task->num_scatter = scsi_sg_count(cmd);
......
...@@ -686,7 +686,8 @@ static int mvs_task_prep_ssp(struct mvs_info *mvi, ...@@ -686,7 +686,8 @@ static int mvs_task_prep_ssp(struct mvs_info *mvi,
if (ssp_hdr->frame_type != SSP_TASK) { if (ssp_hdr->frame_type != SSP_TASK) {
buf_cmd[9] = fburst | task->ssp_task.task_attr | buf_cmd[9] = fburst | task->ssp_task.task_attr |
(task->ssp_task.task_prio << 3); (task->ssp_task.task_prio << 3);
memcpy(buf_cmd + 12, &task->ssp_task.cdb, 16); memcpy(buf_cmd + 12, task->ssp_task.cmd->cmnd,
task->ssp_task.cmd->cmd_len);
} else{ } else{
buf_cmd[10] = tmf->tmf; buf_cmd[10] = tmf->tmf;
switch (tmf->tmf) { switch (tmf->tmf) {
......
...@@ -4291,7 +4291,8 @@ static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, ...@@ -4291,7 +4291,8 @@ static int pm8001_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
ssp_cmd.ssp_iu.efb_prio_attr |= 0x80; ssp_cmd.ssp_iu.efb_prio_attr |= 0x80;
ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_prio << 3); ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_prio << 3);
ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7); ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7);
memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cdb, 16); memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cmd->cmnd,
task->ssp_task.cmd->cmd_len);
circularQ = &pm8001_ha->inbnd_q_tbl[0]; circularQ = &pm8001_ha->inbnd_q_tbl[0];
/* fill in PRD (scatter/gather) table, if any */ /* fill in PRD (scatter/gather) table, if any */
......
...@@ -3559,9 +3559,9 @@ static int pm80xx_chip_smp_req(struct pm8001_hba_info *pm8001_ha, ...@@ -3559,9 +3559,9 @@ static int pm80xx_chip_smp_req(struct pm8001_hba_info *pm8001_ha,
static int check_enc_sas_cmd(struct sas_task *task) static int check_enc_sas_cmd(struct sas_task *task)
{ {
if ((task->ssp_task.cdb[0] == READ_10) u8 cmd = task->ssp_task.cmd->cmnd[0];
|| (task->ssp_task.cdb[0] == WRITE_10)
|| (task->ssp_task.cdb[0] == WRITE_VERIFY)) if (cmd == READ_10 || cmd == WRITE_10 || cmd == WRITE_VERIFY)
return 1; return 1;
else else
return 0; return 0;
...@@ -3624,7 +3624,8 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, ...@@ -3624,7 +3624,8 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
ssp_cmd.ssp_iu.efb_prio_attr |= 0x80; ssp_cmd.ssp_iu.efb_prio_attr |= 0x80;
ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_prio << 3); ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_prio << 3);
ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7); ssp_cmd.ssp_iu.efb_prio_attr |= (task->ssp_task.task_attr & 7);
memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cdb, 16); memcpy(ssp_cmd.ssp_iu.cdb, task->ssp_task.cmd->cmnd,
task->ssp_task.cmd->cmd_len);
circularQ = &pm8001_ha->inbnd_q_tbl[0]; circularQ = &pm8001_ha->inbnd_q_tbl[0];
/* Check if encryption is set */ /* Check if encryption is set */
...@@ -3632,7 +3633,7 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha, ...@@ -3632,7 +3633,7 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
!(pm8001_ha->encrypt_info.status) && check_enc_sas_cmd(task)) { !(pm8001_ha->encrypt_info.status) && check_enc_sas_cmd(task)) {
PM8001_IO_DBG(pm8001_ha, pm8001_printk( PM8001_IO_DBG(pm8001_ha, pm8001_printk(
"Encryption enabled.Sending Encrypt SAS command 0x%x\n", "Encryption enabled.Sending Encrypt SAS command 0x%x\n",
task->ssp_task.cdb[0])); task->ssp_task.cmd->cmnd[0]));
opc = OPC_INB_SSP_INI_DIF_ENC_IO; opc = OPC_INB_SSP_INI_DIF_ENC_IO;
/* enable encryption. 0 for SAS 1.1 and SAS 2.0 compatible TLR*/ /* enable encryption. 0 for SAS 1.1 and SAS 2.0 compatible TLR*/
ssp_cmd.dad_dir_m_tlr = cpu_to_le32 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,14 +3667,14 @@ static int pm80xx_chip_ssp_io_req(struct pm8001_hba_info *pm8001_ha,
/* XTS mode. All other fields are 0 */ /* XTS mode. All other fields are 0 */
ssp_cmd.key_cmode = 0x6 << 4; ssp_cmd.key_cmode = 0x6 << 4;
/* set tweak values. Should be the start lba */ /* set tweak values. Should be the start lba */
ssp_cmd.twk_val0 = cpu_to_le32((task->ssp_task.cdb[2] << 24) | ssp_cmd.twk_val0 = cpu_to_le32((task->ssp_task.cmd->cmnd[2] << 24) |
(task->ssp_task.cdb[3] << 16) | (task->ssp_task.cmd->cmnd[3] << 16) |
(task->ssp_task.cdb[4] << 8) | (task->ssp_task.cmd->cmnd[4] << 8) |
(task->ssp_task.cdb[5])); (task->ssp_task.cmd->cmnd[5]));
} else { } else {
PM8001_IO_DBG(pm8001_ha, pm8001_printk( PM8001_IO_DBG(pm8001_ha, pm8001_printk(
"Sending Normal SAS command 0x%x inb q %x\n", "Sending Normal SAS command 0x%x inb q %x\n",
task->ssp_task.cdb[0], inb)); task->ssp_task.cmd->cmnd[0], inb));
/* fill in PRD (scatter/gather) table, if any */ /* fill in PRD (scatter/gather) table, if any */
if (task->num_scatter > 1) { if (task->num_scatter > 1) {
pm8001_chip_make_sg(task->scatter, ccb->n_elem, pm8001_chip_make_sg(task->scatter, ccb->n_elem,
......
...@@ -608,7 +608,7 @@ struct sas_ssp_task { ...@@ -608,7 +608,7 @@ struct sas_ssp_task {
u8 enable_first_burst:1; u8 enable_first_burst:1;
enum task_attribute task_attr; enum task_attribute task_attr;
u8 task_prio; u8 task_prio;
u8 cdb[16]; struct scsi_cmnd *cmd;
}; };
struct sas_task { struct sas_task {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment