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;
202 nvm_cmd[3] = in.
nsid;
206 nvm_cmd[12] = in.
cdw10;
207 nvm_cmd[13] = in.
cdw11;
208 nvm_cmd[14] = in.
cdw12;
209 nvm_cmd[15] = in.
cdw13;
210 nvm_cmd[16] = in.
cdw14;
211 nvm_cmd[17] = in.
cdw15;
223 io_nvm.
dxferp = (uint8_t *)nvm_cmd;
228 "sntjmicron_device::nvme_pass_through:NVM: "))
268 "sntjmicron_device::nvme_pass_through:Data: "))
286 io_reply.
dxferp = (uint8_t *)nvm_reply;
291 "sntjmicron_device::nvme_pass_through:Reply: "))
296 swapx(&nvm_reply[i]);
299 return set_err(EIO,
"Out of spec JMicron NVMe reply");
301 int status = nvm_reply[5] >> 17;
306 out.
result = nvm_reply[2];
323 const char * req_type,
unsigned nsid);
331 const char * req_type,
unsigned nsid)
332:
smart_device(intf, scsidev->get_dev_name(),
"sntrealtek", req_type),
347 if (in.
cdw10 == 0x0000001)
349 if (in.
cdw10 == 0x0000000) {
352 return set_err(ENOSYS,
"NVMe Identify Namespace 0x%x not supported", in.
nsid);
354 return set_err(ENOSYS,
"NVMe Identify with CDW10=0x%08x not supported", in.
cdw10);
357 return set_err(ENOSYS,
"NVMe Get Log Page with NSID=0x%x not supported", in.
nsid);
361 pout(
"Warning: NVMe Get Log truncated to 0x%03x bytes, 0x%03x bytes zero filled\n",
size, in.
size -
size);
365 return set_err(ENOSYS,
"NVMe admin command 0x%02x not supported", in.
opcode);
369 return set_err(ENOSYS,
"Nonzero NVMe command dwords 11-15 not supported");
371 uint8_t
cdb[16] = {0, };
379 io_hdr.cmnd_len =
sizeof(
cdb);
381 io_hdr.dxferp = (uint8_t *)in.buffer;
382 io_hdr.dxfer_len =
size;
383 memset(in.buffer, 0, in.size);
387 return set_err(scsidev->
get_err());
401 throw std::logic_error(
"smart_interface: get_snt_device() called with scsidev=0");
408 if (!strcmp(type,
"sntjmicron#please_try")) {
409 set_err(EINVAL,
"USB to NVMe bridge [please try '-d sntjmicron' and report result to: "
410 PACKAGE_BUGREPORT
"]");
414 if (!strcmp(type,
"sntasmedia")) {
419 else if (!strncmp(type,
"sntjmicron", 10)) {
420 int n1 = -1, n2 = -1, len = strlen(type);
422 sscanf(type,
"sntjmicron%n,0x%x%n", &n1, &
nsid, &n2);
423 if (!(n1 == len || n2 == len)) {
424 set_err(EINVAL,
"Invalid NVMe namespace id in '%s'", type);
430 else if (!strcmp(type,
"sntrealtek")) {
436 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)