39 const char * req_type,
unsigned nsid);
47 const char * req_type,
unsigned nsid)
48:
smart_device(intf, scsidev->get_dev_name(),
"sntasmedia", req_type),
61 unsigned cdw10_hi = in.
cdw10 >> 16;
64 if (in.
cdw10 == 0x0000001)
66 if (in.
cdw10 == 0x0000000) {
69 return set_err(ENOSYS,
"NVMe Identify Namespace 0x%x not supported", in.
nsid);
71 return set_err(ENOSYS,
"NVMe Identify with CDW10=0x%08x not supported", in.
cdw10);
74 return set_err(ENOSYS,
"NVMe Get Log Page with NSID=0x%x not supported", in.
nsid);
77 return set_err(ENOSYS,
"NVMe admin command 0x%02x not supported", in.
opcode);
81 return set_err(ENOSYS,
"Nonzero NVMe command dwords 11, 14, or 15 not supported");
83 uint8_t
cdb[16] = {0, };
89 cdb[6] = (uint8_t)(cdw10_hi >> 8);
90 cdb[7] = (uint8_t)cdw10_hi;
102 io_hdr.cmnd_len =
sizeof(
cdb);
104 io_hdr.dxferp = (uint8_t *)in.buffer;
105 io_hdr.dxfer_len =
size;
106 memset(in.buffer, 0, in.size);
110 return set_err(scsidev->
get_err());
119#define SNT_JMICRON_NVME_SIGNATURE 0x454d564eu
120#define SNT_JMICRON_CDB_LEN 12
121#define SNT_JMICRON_NVM_CMD_LEN 512
131 const char * req_type,
unsigned nsid);
135 virtual bool open()
override;
147 const char * req_type,
unsigned nsid)
148:
smart_device(intf, scsidev->get_dev_name(),
"sntjmicron", req_type),
189 constexpr bool admin =
true;
197 unsigned int lid = in.
cdw10 & 0xFF;
198 if (lid == 0x6 && in.
size > 0x218) {
199 unsigned size = 0x218;
201 pout(
"Warning: self-test output truncated to 19 items to workaround controller bug\n");
213 nvm_cmd[3] = in.
nsid;
218 nvm_cmd[13] = in.
cdw11;
219 nvm_cmd[14] = in.
cdw12;
220 nvm_cmd[15] = in.
cdw13;
221 nvm_cmd[16] = in.
cdw14;
222 nvm_cmd[17] = in.
cdw15;
234 io_nvm.
dxferp = (uint8_t *)nvm_cmd;
239 "sntjmicron_device::nvme_pass_through:NVM: "))
279 "sntjmicron_device::nvme_pass_through:Data: "))
297 io_reply.
dxferp = (uint8_t *)nvm_reply;
302 "sntjmicron_device::nvme_pass_through:Reply: "))
307 swapx(&nvm_reply[i]);
310 return set_err(EIO,
"Out of spec JMicron NVMe reply");
312 int status = nvm_reply[5] >> 17;
317 out.
result = nvm_reply[2];
334 const char * req_type,
unsigned nsid);
342 const char * req_type,
unsigned nsid)
343:
smart_device(intf, scsidev->get_dev_name(),
"sntrealtek", req_type),
358 if (in.
cdw10 == 0x0000001)
360 if (in.
cdw10 == 0x0000000) {
363 return set_err(ENOSYS,
"NVMe Identify Namespace 0x%x not supported", in.
nsid);
365 return set_err(ENOSYS,
"NVMe Identify with CDW10=0x%08x not supported", in.
cdw10);
368 return set_err(ENOSYS,
"NVMe Get Log Page with NSID=0x%x not supported", in.
nsid);
372 pout(
"Warning: NVMe Get Log truncated to 0x%03x bytes, 0x%03x bytes zero filled\n",
size, in.
size -
size);
376 return set_err(ENOSYS,
"NVMe admin command 0x%02x not supported", in.
opcode);
380 return set_err(ENOSYS,
"Nonzero NVMe command dwords 11-15 not supported");
382 uint8_t
cdb[16] = {0, };
390 io_hdr.cmnd_len =
sizeof(
cdb);
392 io_hdr.dxferp = (uint8_t *)in.buffer;
393 io_hdr.dxfer_len =
size;
394 memset(in.buffer, 0, in.size);
398 return set_err(scsidev->
get_err());
412 throw std::logic_error(
"smart_interface: get_snt_device() called with scsidev=0");
419 if (!strcmp(type,
"sntjmicron#please_try")) {
420 set_err(EINVAL,
"USB to NVMe bridge [please try '-d sntjmicron' and report result to: "
421 PACKAGE_BUGREPORT
"]");
425 if (!strcmp(type,
"sntasmedia")) {
430 else if (!strncmp(type,
"sntjmicron", 10)) {
431 int n1 = -1, n2 = -1, len = strlen(type);
433 sscanf(type,
"sntjmicron%n,0x%x%n", &n1, &
nsid, &n2);
434 if (!(n1 == len || n2 == len)) {
435 set_err(EINVAL,
"Invalid NVMe namespace id in '%s'", type);
441 else if (!strcmp(type,
"sntrealtek")) {
447 set_err(EINVAL,
"Unknown SNT device type '%s'", type);
Smart pointer class for device pointers.
device_type * release()
Return the pointer and release ownership.
unsigned get_nsid() const
Get namespace id.
bool set_nvme_err(nvme_cmd_out &out, unsigned status, const char *msg=0)
Set last error number and message if pass-through returns NVMe error status.
void set_nsid(unsigned nsid)
Set namespace id.
bool scsi_pass_through_and_check(scsi_cmnd_io *iop, const char *msg="")
Base class for all devices.
const error_info & get_err() const
Get last error info struct.
bool set_err(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
const char * get_info_name() const
Get informal name.
device_info & set_info()
R/W access to device info struct.
The platform interface abstraction.
virtual nvme_device * get_snt_device(const char *type, scsi_device *scsidev)
Return NVMe->SCSI filter for a SNT or USB 'type'.
virtual bool nvme_pass_through(const nvme_cmd_in &in, nvme_cmd_out &out) override
NVMe pass through.
virtual ~sntjmicron_device()
virtual bool open() override
Open device, return false on error.
sntjmicron_device(smart_interface *intf, scsi_device *scsidev, const char *req_type, unsigned nsid)
virtual ~sntrealtek_device()
virtual bool nvme_pass_through(const nvme_cmd_in &in, nvme_cmd_out &out) override
NVMe pass through.
sntrealtek_device(smart_interface *intf, scsi_device *scsidev, const char *req_type, unsigned nsid)
Implement a device by tunneling through another device.
tunnel_device_type * get_tunnel_dev()
constexpr uint32_t nvme_broadcast_nsid
#define SAT_ATA_PASSTHROUGH_12
#define DXFER_FROM_DEVICE
#define SNT_JMICRON_CDB_LEN
#define SNT_JMICRON_NVM_CMD_LEN
const char * scsinvme_cpp_svnid
#define SNT_JMICRON_NVME_SIGNATURE
static void sg_put_unaligned_be24(uint32_t val, void *p)
static void sg_put_unaligned_le16(uint16_t val, void *p)
void pout(const char *fmt,...)
NVMe pass through input parameters.
unsigned char direction() const
Get I/O direction from opcode.
unsigned char opcode
Opcode (CDW0 07:00)
unsigned size
Size of buffer.
unsigned cdw15
Cmd specific.
unsigned nsid
Namespace ID.
void * buffer
Pointer to data buffer.
NVMe pass through output parameters.
unsigned result
Command specific result (DW0)
std::string info_name
Informal name.
std::string strprintf(const char *fmt,...)
void swapx(unsigned short *p)