+/////////////////////////////////////////////////////////////////////////////
+// scsi_device
+
+bool scsi_device::scsi_pass_through_and_check(scsi_cmnd_io * iop,
+ const char * msg)
+{
+ // Provide sense buffer
+ unsigned char sense[32] = {0, };
+ iop->sensep = sense;
+ iop->max_sense_len = sizeof(sense);
+ iop->timeout = SCSI_TIMEOUT_DEFAULT;
+
+ // Run cmd
+ if (!scsi_pass_through(iop)) {
+ if (scsi_debugmode > 0)
+ pout("%sscsi_pass_through() failed, errno=%d [%s]\n",
+ msg, get_errno(), get_errmsg());
+ return false;
+ }
+
+ // Check sense
+ scsi_sense_disect sinfo;
+ scsi_do_sense_disect(iop, &sinfo);
+ int err = scsiSimpleSenseFilter(&sinfo);
+ if (err) {
+ if (scsi_debugmode > 0)
+ pout("%sscsi error: %s\n", msg, scsiErrString(err));
+ return set_err(EIO, "scsi error %s", scsiErrString(err));
+ }
+
+ return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// nvme_device
+
+bool nvme_device::set_nvme_err(nvme_cmd_out & out, unsigned status, const char * msg /* = 0 */)
+{
+ if (!status)
+ throw std::logic_error("nvme_device: set_nvme_err() called with status=0");
+
+ out.status = status;
+ out.status_valid = true;
+ return set_err(EIO, "%sNVMe Status 0x%02x", (msg ? msg : ""), status);
+}
+