summaryrefslogtreecommitdiffstats
path: root/sys/dev/firewire/sbp_targ.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/firewire/sbp_targ.c')
-rw-r--r--sys/dev/firewire/sbp_targ.c91
1 files changed, 69 insertions, 22 deletions
diff --git a/sys/dev/firewire/sbp_targ.c b/sys/dev/firewire/sbp_targ.c
index c5b9d23..f04b968 100644
--- a/sys/dev/firewire/sbp_targ.c
+++ b/sys/dev/firewire/sbp_targ.c
@@ -41,6 +41,7 @@
#include <sys/types.h>
#include <sys/conf.h>
#include <sys/malloc.h>
+#include <sys/endian.h>
#if __FreeBSD_version < 500000
#include <sys/devicestat.h>
#endif
@@ -632,6 +633,12 @@ sbp_targ_send_status(struct orb_info *orbi, union ccb *ccb)
{
struct sbp_cmd_status *sbp_cmd_status;
struct scsi_sense_data *sense;
+ int error_code, sense_key, asc, ascq;
+ uint8_t stream_bits;
+ uint8_t sks[3];
+ uint64_t info;
+ int64_t sinfo;
+ int sense_len;
if (debug)
printf("%s: STATUS %d\n", __func__,
@@ -659,35 +666,75 @@ sbp_targ_send_status(struct orb_info *orbi, union ccb *ccb)
#endif
#endif
- if ((sense->error_code & SSD_ERRCODE) == SSD_CURRENT_ERROR)
+ sense_len = ccb->csio.sense_len - ccb->csio.sense_resid;
+ scsi_extract_sense_len(sense, sense_len, &error_code,
+ &sense_key, &asc, &ascq, /*show_errors*/ 0);
+
+ switch (error_code) {
+ case SSD_CURRENT_ERROR:
+ case SSD_DESC_CURRENT_ERROR:
sbp_cmd_status->sfmt = SBP_SFMT_CURR;
- else
+ break;
+ default:
sbp_cmd_status->sfmt = SBP_SFMT_DEFER;
+ break;
+ }
- sbp_cmd_status->valid = (sense->error_code & SSD_ERRCODE_VALID)
- ? 1 : 0;
- sbp_cmd_status->s_key = sense->flags & SSD_KEY;
- sbp_cmd_status->mark = (sense->flags & SSD_FILEMARK)? 1 : 0;
- sbp_cmd_status->eom = (sense->flags & SSD_EOM) ? 1 : 0;
- sbp_cmd_status->ill_len = (sense->flags & SSD_ILI) ? 1 : 0;
+ if (scsi_get_sense_info(sense, sense_len, SSD_DESC_INFO, &info,
+ &sinfo) == 0) {
+ uint32_t info_trunc;
+ sbp_cmd_status->valid = 1;
+ info_trunc = info;
- bcopy(&sense->info[0], &sbp_cmd_status->info, 4);
+ sbp_cmd_status->info = htobe32(info_trunc);
+ } else {
+ sbp_cmd_status->valid = 0;
+ }
- if (sense->extra_len <= 6)
- /* add_sense_code(_qual), info, cmd_spec_info */
- sbp_status->len = 4;
- else
- /* fru, sense_key_spec */
- sbp_status->len = 5;
-
- bcopy(&sense->cmd_spec_info[0], &sbp_cmd_status->cdb, 4);
+ sbp_cmd_status->s_key = sense_key;
+
+ if (scsi_get_stream_info(sense, sense_len, NULL,
+ &stream_bits) == 0) {
+ sbp_cmd_status->mark =
+ (stream_bits & SSD_FILEMARK) ? 1 : 0;
+ sbp_cmd_status->eom =
+ (stream_bits & SSD_EOM) ? 1 : 0;
+ sbp_cmd_status->ill_len =
+ (stream_bits & SSD_ILI) ? 1 : 0;
+ } else {
+ sbp_cmd_status->mark = 0;
+ sbp_cmd_status->eom = 0;
+ sbp_cmd_status->ill_len = 0;
+ }
+
+
+ /* add_sense_code(_qual), info, cmd_spec_info */
+ sbp_status->len = 4;
+
+ if (scsi_get_sense_info(sense, sense_len, SSD_DESC_COMMAND,
+ &info, &sinfo) == 0) {
+ uint32_t cmdspec_trunc;
+
+ cmdspec_trunc = info;
+
+ sbp_cmd_status->cdb = htobe32(cmdspec_trunc);
+ }
- sbp_cmd_status->s_code = sense->add_sense_code;
- sbp_cmd_status->s_qlfr = sense->add_sense_code_qual;
- sbp_cmd_status->fru = sense->fru;
+ sbp_cmd_status->s_code = asc;
+ sbp_cmd_status->s_qlfr = ascq;
- bcopy(&sense->sense_key_spec[0],
- &sbp_cmd_status->s_keydep[0], 3);
+ if (scsi_get_sense_info(sense, sense_len, SSD_DESC_FRU, &info,
+ &sinfo) == 0) {
+ sbp_cmd_status->fru = (uint8_t)info;
+ sbp_status->len = 5;
+ } else {
+ sbp_cmd_status->fru = 0;
+ }
+
+ if (scsi_get_sks(sense, sense_len, sks) == 0) {
+ bcopy(sks, &sbp_cmd_status->s_keydep[0], sizeof(sks));
+ sbp_status->len = 5;
+ }
break;
}
OpenPOWER on IntegriCloud