Changeset View
Changeset View
Standalone View
Standalone View
sys/cam/ctl/ctl.c
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 7,430 Lines • ▼ Show 20 Lines | ctl_report_supported_opcodes(struct ctl_scsiio *ctsio) | ||||
retval = CTL_RETVAL_COMPLETE; | retval = CTL_RETVAL_COMPLETE; | ||||
opcode = cdb->requested_opcode; | opcode = cdb->requested_opcode; | ||||
service_action = scsi_2btoul(cdb->requested_service_action); | service_action = scsi_2btoul(cdb->requested_service_action); | ||||
switch (cdb->options & RSO_OPTIONS_MASK) { | switch (cdb->options & RSO_OPTIONS_MASK) { | ||||
case RSO_OPTIONS_ALL: | case RSO_OPTIONS_ALL: | ||||
num = 0; | num = 0; | ||||
for (i = 0; i < 256; i++) { | for (i = 0; i < 256; i++) { | ||||
entry = &ctl_cmd_table[i]; | entry = &ctl_cmd_table[i]; | ||||
asomers: Should "field" be 4 for REQUESTED SERVICE ACTION instead of 1 for SERVICE ACTION? | |||||
Done Inline ActionsSigh, yes, and actually, it needs to be ignored for RSO_OPTIONS_ALL and RSO_OPTIONS_OC so I need to revisit this a bit. jhb: Sigh, yes, and actually, it needs to be ignored for RSO_OPTIONS_ALL and RSO_OPTIONS_OC so I… | |||||
Done Inline ActionsThis should now be fixed. jhb: This should now be fixed. | |||||
if (entry->flags & CTL_CMD_FLAG_SA5) { | if (entry->flags & CTL_CMD_FLAG_SA5) { | ||||
for (j = 0; j < 32; j++) { | for (j = 0; j < 32; j++) { | ||||
sentry = &((const struct ctl_cmd_entry *) | sentry = &((const struct ctl_cmd_entry *) | ||||
entry->execute)[j]; | entry->execute)[j]; | ||||
if (ctl_cmd_applicable( | if (ctl_cmd_applicable( | ||||
lun->be_lun->lun_type, sentry)) | lun->be_lun->lun_type, sentry)) | ||||
num++; | num++; | ||||
} | } | ||||
} else { | } else { | ||||
if (ctl_cmd_applicable(lun->be_lun->lun_type, | if (ctl_cmd_applicable(lun->be_lun->lun_type, | ||||
entry)) | entry)) | ||||
num++; | num++; | ||||
} | } | ||||
} | } | ||||
total_len = sizeof(struct scsi_report_supported_opcodes_all) + | total_len = sizeof(struct scsi_report_supported_opcodes_all) + | ||||
num * sizeof(struct scsi_report_supported_opcodes_descr); | num * sizeof(struct scsi_report_supported_opcodes_descr); | ||||
break; | break; | ||||
case RSO_OPTIONS_OC: | case RSO_OPTIONS_OC: | ||||
if (ctl_cmd_table[opcode].flags & CTL_CMD_FLAG_SA5) { | if (ctl_cmd_table[opcode].flags & CTL_CMD_FLAG_SA5) { | ||||
goto invalid_options; | goto invalid_options; | ||||
} | } | ||||
total_len = sizeof(struct scsi_report_supported_opcodes_one) + 32; | total_len = sizeof(struct scsi_report_supported_opcodes_one) + 32; | ||||
break; | break; | ||||
case RSO_OPTIONS_OC_SA: | case RSO_OPTIONS_OC_SA: | ||||
if ((ctl_cmd_table[opcode].flags & CTL_CMD_FLAG_SA5) == 0 || | if ((ctl_cmd_table[opcode].flags & CTL_CMD_FLAG_SA5) == 0) { | ||||
service_action >= 32) { | |||||
goto invalid_options; | goto invalid_options; | ||||
} | } | ||||
total_len = sizeof(struct scsi_report_supported_opcodes_one) + 32; | /* FALLTHROUGH */ | ||||
break; | |||||
case RSO_OPTIONS_OC_ASA: | case RSO_OPTIONS_OC_ASA: | ||||
if ((ctl_cmd_table[opcode].flags & CTL_CMD_FLAG_SA5) != 0 && | if (service_action >= 32) { | ||||
service_action >= 32) { | ctl_set_invalid_field(/*ctsio*/ ctsio, | ||||
goto invalid_options; | /*sks_valid*/ 1, | ||||
/*command*/ 1, | |||||
/*field*/ 4, | |||||
/*bit_valid*/ 0, | |||||
/*bit*/ 0); | |||||
ctl_done((union ctl_io *)ctsio); | |||||
return (CTL_RETVAL_COMPLETE); | |||||
Done Inline ActionsRemoving the SA5 check here is on purpose, for the ASA case both with and without SA5 is fine and is handled below. jhb: Removing the SA5 check here is on purpose, for the ASA case both with and without SA5 is fine… | |||||
} | } | ||||
total_len = sizeof(struct scsi_report_supported_opcodes_one) + 32; | total_len = sizeof(struct scsi_report_supported_opcodes_one) + 32; | ||||
break; | break; | ||||
default: | default: | ||||
invalid_options: | invalid_options: | ||||
Done Inline ActionsNote that this is not a generic "there's an invalid field in the command", but is specifically saying that the RSO_OPTIONS field in the cdb->options byte is invalid. jhb: Note that this is not a generic "there's an invalid field in the command", but is specifically… | |||||
ctl_set_invalid_field(/*ctsio*/ ctsio, | ctl_set_invalid_field(/*ctsio*/ ctsio, | ||||
/*sks_valid*/ 1, | /*sks_valid*/ 1, | ||||
/*command*/ 1, | /*command*/ 1, | ||||
/*field*/ 2, | /*field*/ 2, | ||||
/*bit_valid*/ 1, | /*bit_valid*/ 1, | ||||
/*bit*/ 2); | /*bit*/ 2); | ||||
ctl_done((union ctl_io *)ctsio); | ctl_done((union ctl_io *)ctsio); | ||||
return (CTL_RETVAL_COMPLETE); | return (CTL_RETVAL_COMPLETE); | ||||
▲ Show 20 Lines • Show All 7,062 Lines • Show Last 20 Lines |
Should "field" be 4 for REQUESTED SERVICE ACTION instead of 1 for SERVICE ACTION?