libxcoder  3.5.1
ni_nvme_logan.c
Go to the documentation of this file.
1 /*******************************************************************************
2  *
3  * Copyright (C) 2022 NETINT Technologies
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to deal
7  * in the Software without restriction, including without limitation the rights
8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9  * copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
18  * SOFTWARE.
19  *
20  ******************************************************************************/
21 
22 /*!*****************************************************************************
23 * \file ni_nvme_logan.c
24 *
25 * \brief Private routines related to working with NI T-408 over NVME interface
26 *
27 *******************************************************************************/
28 
29 
30 #ifdef _WIN32
31  #include <windows.h>
32  #include <ntddstor.h>
33  #include <winioctl.h>
34  #include <Ntddscsi.h>
35 #elif defined(__linux__) || defined(__APPLE__)
36  #include <sys/ioctl.h>
37  #include <sys/stat.h>
38  #include <unistd.h>
39 #endif
40 
41 #include "ni_nvme_logan.h"
42 #include "ni_util_logan.h"
43 
44 #define ROUND_TO_ULONG(x) ni_logan_round_up(x,sizeof(uint32_t))
45 
46 /*!******************************************************************************
47  * \brief Check f/w error return code, and if it's a fatal one, terminate
48  * application's decoding/encoding processing by sending
49  * self a SIGTERM signal. Application shall handle this gracefully.
50  *
51  * \param
52  *
53  * \return 1 (or non-zero) if need to terminate, 0 otherwise
54  ******************************************************************************/
57  uint32_t xcoder_type,
58  uint32_t hw_id,
59  int32_t *p_instance_id)
60 {
61  switch (rc)
62  {
72  {
74  {
75  ni_log(NI_LOG_ERROR, "VPU recovery happened, op = %02x %s %d.%d terminating?\n",
76  opcode,
77  xcoder_type == NI_LOGAN_DEVICE_TYPE_DECODER ? "decoder" : "encoder",
78  hw_id, *p_instance_id);
79  }
80  else
81  {
82  ni_log(NI_LOG_ERROR, "Error rc = 0x%x, op = %02x %s %d.%d terminating?\n",
83  rc, opcode,
84  xcoder_type == NI_LOGAN_DEVICE_TYPE_DECODER ? "decoder" : "encoder",
85  hw_id, *p_instance_id);
86  }
87 
92  {
94  }
95  break;
96  }
97  default:
98  {
99  break; // nothing
100  }
101  }
103 }
104 
105 #ifdef __linux__
106 
107 /*!******************************************************************************
108  * \brief Submit a nvme admin passthrough command to the driver
109  *
110  * \param
111  *
112  * \return
113  *******************************************************************************/
114 int32_t ni_logan_nvme_send_admin_pass_through_command(ni_device_handle_t handle,
115  ni_logan_nvme_passthrough_cmd_t *p_cmd)
116 {
117  ni_log(NI_LOG_TRACE, "%s: handle=%d\n", __FUNCTION__, handle);
118  ni_log(NI_LOG_TRACE, "opcode: %02x\n", p_cmd->opcode);
119  ni_log(NI_LOG_TRACE, "flags: %02x\n", p_cmd->flags);
120  ni_log(NI_LOG_TRACE, "rsvd1: %04x\n", p_cmd->rsvd1);
121  ni_log(NI_LOG_TRACE, "nsid: %08x\n", p_cmd->nsid);
122  ni_log(NI_LOG_TRACE, "cdw2: %08x\n", p_cmd->cdw2);
123  ni_log(NI_LOG_TRACE, "cdw3: %08x\n", p_cmd->cdw3);
124  //ni_log(NI_LOG_TRACE, "metadata: %"PRIx64"\n", p_cmd->metadata);
125  //ni_log(NI_LOG_TRACE, "addr: %"PRIx64"\n", p_cmd->addr);
126  ni_log(NI_LOG_TRACE, "metadata_len: %08x\n", p_cmd->metadata_len);
127  ni_log(NI_LOG_TRACE, "data_len: %08x\n", p_cmd->data_len);
128  ni_log(NI_LOG_TRACE, "cdw10: %08x\n", p_cmd->cdw10);
129  ni_log(NI_LOG_TRACE, "cdw11: %08x\n", p_cmd->cdw11);
130  ni_log(NI_LOG_TRACE, "cdw12: %08x\n", p_cmd->cdw12);
131  ni_log(NI_LOG_TRACE, "cdw13: %08x\n", p_cmd->cdw13);
132  ni_log(NI_LOG_TRACE, "cdw14: %08x\n", p_cmd->cdw14);
133  ni_log(NI_LOG_TRACE, "cdw15: %08x\n", p_cmd->cdw15);
134  ni_log(NI_LOG_TRACE, "timeout_ms: %08x\n", p_cmd->timeout_ms);
135  ni_log(NI_LOG_TRACE, "result: %08x\n", p_cmd->result);
136 
137 #ifndef XCODER_SIM_ENABLED
138  return ioctl(handle, NVME_IOCTL_ADMIN_CMD, p_cmd);
139 #else
140  return 0;
141 #endif
142 }
143 
144 /*!******************************************************************************
145  * \brief Submit a nvme io passthrough command to the driver
146  *
147  * \param
148  *
149  * \return
150  *******************************************************************************/
151 int32_t ni_logan_nvme_send_io_pass_through_command(ni_device_handle_t handle,
152  ni_logan_nvme_passthrough_cmd_t * p_cmd)
153 {
154  ni_log(NI_LOG_TRACE, "%s: handle=%d\n", __FUNCTION__, handle);
155  ni_log(NI_LOG_TRACE, "opcode: %02x\n", p_cmd->opcode);
156  ni_log(NI_LOG_TRACE, "addr: %p\n", (void *)p_cmd->addr);
157  ni_log(NI_LOG_TRACE, "flags: %02x\n", p_cmd->flags);
158  ni_log(NI_LOG_TRACE, "rsvd1: %04x\n", p_cmd->rsvd1);
159  ni_log(NI_LOG_TRACE, "nsid: %08x\n", p_cmd->nsid);
160  ni_log(NI_LOG_TRACE, "cdw2: %08x\n", p_cmd->cdw2);
161  ni_log(NI_LOG_TRACE, "cdw3: %08x\n", p_cmd->cdw3);
162  //ni_log(NI_LOG_TRACE, "metadata: %"PRIx64"\n", p_cmd->metadata);
163  //ni_log(NI_LOG_TRACE, "addr: %"PRIx64"\n", p_cmd->addr);
164  ni_log(NI_LOG_TRACE, "metadata_len: %08x\n", p_cmd->metadata_len);
165  ni_log(NI_LOG_TRACE, "data_len: %08x\n", p_cmd->data_len);
166  ni_log(NI_LOG_TRACE, "cdw10: %08x\n", p_cmd->cdw10);
167  ni_log(NI_LOG_TRACE, "cdw11: %08x\n", p_cmd->cdw11);
168  ni_log(NI_LOG_TRACE, "cdw12: %08x\n", p_cmd->cdw12);
169  ni_log(NI_LOG_TRACE, "cdw13: %08x\n", p_cmd->cdw13);
170  ni_log(NI_LOG_TRACE, "cdw14: %08x\n", p_cmd->cdw14);
171  ni_log(NI_LOG_TRACE, "cdw15: %08x\n", p_cmd->cdw15);
172  ni_log(NI_LOG_TRACE, "timeout_ms: %08x\n", p_cmd->timeout_ms);
173  ni_log(NI_LOG_TRACE, "result: %08x\n", p_cmd->result);
174 
175 #ifndef XCODER_SIM_ENABLED
176  return ioctl(handle, NVME_IOCTL_IO_CMD, p_cmd);
177 #else
178  return 0;
179 #endif
180 }
181 
182 #endif //defined(__linux__) defined
183 
184 #ifdef _WIN32
185 
186 #define ROUND_TO_DWORD_PTR(x) ni_logan_round_up(x,sizeof(PDWORD))
187 
188 static ni_logan_retcode_t ni_logan_nvme_get_identity(HANDLE handle,
189  HANDLE event_handle,
190  PVOID p_identity)
191 {
192  uint32_t lba = IDENTIFY_DEVICE_R;
193  DWORD data_len = NI_LOGAN_NVME_IDENTITY_CMD_DATA_SZ;
195 
196  rc = ni_logan_nvme_send_read_cmd(handle, event_handle, p_identity, data_len, lba);
197 
198  return rc;
199 }
200 
202  int max_handles)
203 {
204  TCHAR port_name_buffer[NI_LOGAN_MAX_DEVICE_NAME_LEN] = { 0 };
205  LPTSTR p_scsi_path = "\\\\.\\PHYSICALDRIVE";
206  LPCTSTR p_format = "%s%d";
207  PUCHAR p_buffer = NULL;
209  CHAR firmware_revision[9] = { 0 };
210  int device_count = 0;
211  int scsi_port = 0;
212  DWORD retval = 0;
213  DWORD data_len = NI_LOGAN_NVME_IDENTITY_CMD_DATA_SZ;
214  CHAR serial_num[21] = { 0 };
215  CHAR model_name[41] = { 0 };
216  ni_logan_nvme_identity_t* p_ni_logan_identity = NULL;
217 
218  ni_log(NI_LOG_INFO, "Searching for NETINT NVMe devices ...\n\n");
219 
220  if (ni_logan_posix_memalign((void **)(&p_buffer), sysconf(_SC_PAGESIZE), data_len))
221  {
222  ni_log(NI_LOG_ERROR, "ERROR %d: %s() alloc buffer failed\n",
223  NI_ERRNO, __FUNCTION__);
225  }
226 
227  memset(p_buffer, 0, data_len);
228  ni_event_handle_t event_handle = ni_logan_create_event();
229  if (NI_INVALID_EVENT_HANDLE == event_handle)
230  {
231  ni_log(NI_LOG_ERROR, "ERROR %s(): create event failed\n", __FUNCTION__);
233  }
234 
235  for (scsi_port = 0; scsi_port < max_handles; scsi_port++)
236  {
237  wsprintf(port_name_buffer, p_format, p_scsi_path, scsi_port);
238  HANDLE handle = CreateFile(port_name_buffer, GENERIC_READ | GENERIC_WRITE,
239  FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
240  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
241  if (INVALID_HANDLE_VALUE == handle)
242  {
243  retval = NI_ERRNO;
244  }
245  else
246  {
247  ZeroMemory(p_buffer, data_len);
248  rc = ni_logan_nvme_get_identity(handle, event_handle, p_buffer);
249  if (NI_LOGAN_RETCODE_SUCCESS == rc)
250  {
251  ni_logan_nvme_identity_t* p_ni_logan_id_data = (ni_logan_nvme_identity_t*) p_buffer;
252  ni_log(NI_LOG_INFO, "Identity information retrieved from the device at port %s\n",
253  port_name_buffer);
254  ni_log(NI_LOG_INFO, " VID: 0x%x \n SSVID: 0x%x \n",
255  p_ni_logan_id_data->ui16Vid, p_ni_logan_id_data->ui16Ssvid);
256 
257  if ((NETINT_PCI_VENDOR_ID == p_ni_logan_id_data->ui16Vid) &&
258  (NETINT_PCI_VENDOR_ID == p_ni_logan_id_data->ui16Ssvid) &&
259  (p_ni_logan_id_data->device_is_xcoder))
260  {
261  /* make the fw revision/model name/serial num to string*/
262  memset(firmware_revision, 0, sizeof(firmware_revision));
263  memcpy(firmware_revision, p_ni_logan_id_data->ai8Fr, sizeof(p_ni_logan_id_data->ai8Fr));
264  firmware_revision[sizeof(p_ni_logan_id_data->ai8Fr)] = 0;
265 
266  memset(model_name, 0, sizeof(model_name));
267  memcpy(model_name, p_ni_logan_id_data->ai8Mn, sizeof(p_ni_logan_id_data->ai8Mn));
268  model_name[sizeof(p_ni_logan_id_data->ai8Mn)] = 0;
269 
270  memset(serial_num, 0, sizeof(serial_num));
271  memcpy(serial_num, p_ni_logan_id_data->ai8Sn, sizeof(p_ni_logan_id_data->ai8Sn));
272  serial_num[sizeof(p_ni_logan_id_data->ai8Sn)] = 0;
273  ni_log(NI_LOG_INFO, " Device Model: %s \n", model_name);
274  ni_log(NI_LOG_INFO, " Firmware Rev: %s \n", firmware_revision);
275  ni_log(NI_LOG_INFO, " Serial Number: %s \n", serial_num);
276 
277  ni_log(NI_LOG_INFO, "NETINT %s NVMe video transcoder identified at "
278  "port %s\n\n", model_name, port_name_buffer);
279  strncpy(ni_logan_devices[device_count++], port_name_buffer, NI_LOGAN_MAX_DEVICE_NAME_LEN);
280  }
281  else
282  {
283  ni_log(NI_LOG_INFO, "Device at port %s is not a NETINT NVMe device\n",
284  port_name_buffer);
285  }
286 
287  CloseHandle(handle);
288  }
289  else
290  {
291  retval = NI_ERRNO;
292  ni_log(NI_LOG_INFO, "Device at port %s is not a NETINT NVMe device, "
293  "ret=%d\n\n", port_name_buffer ,retval);
294  CloseHandle(handle);
295  }
296  }
297  } // end for loop
298 
299  if (p_buffer)
300  {
301  free(p_buffer);
302  }
303  ni_logan_close_event(event_handle);
304 
305  ni_log(NI_LOG_INFO, "Total Number of NETINT NVMe Transcoders indentified: "
306  "%d \n\n", device_count);
307  return device_count;
308 }
309 #endif //_WIN32 defined
310 
311 
312 /*!******************************************************************************
313  * \brief parse the lba opcode, subtype, option
314  * It's called only if a I/O read/write fails,
315  * so just use the print level "NI_LOG_ERROR" now.
316  *
317  * \param lba is 4k aligned
318  *
319  * \return
320  *******************************************************************************/
321 void ni_logan_parse_lba(uint64_t lba)
322 {
323  uint64_t lba_high = (lba >> NI_LOGAN_INSTANCE_TYPE_OFFSET);
324  uint64_t lba_low = (lba & 0x3FFFF);
325  uint8_t device_type = (lba_high & NI_LOGAN_DEVICE_TYPE_ENCODER);
326  uint16_t session_id = (uint16_t)(lba_high >> (NI_LOGAN_SESSION_ID_OFFSET - NI_LOGAN_INSTANCE_TYPE_OFFSET));
327 
328  if (device_type == NI_LOGAN_DEVICE_TYPE_ENCODER)
329  {
330  ni_log(NI_LOG_ERROR, "encoder lba:0x%" PRIx64 "(4K-aligned), 0x%" PRIx64 " "
331  "(512B-aligned), session ID:%u\n", lba, (lba<<3), session_id);
332  if (lba_low >= WR_OFFSET_IN_4K)
333  {
334  ni_log(NI_LOG_ERROR, "encoder send frame failed\n");
335  }
336  else if(lba_low >= RD_OFFSET_IN_4K)
337  {
338  ni_log(NI_LOG_ERROR, "encoder receive packet failed\n");
339  }
340  else
341  {
342  ni_log(NI_LOG_ERROR, "encoder ctrl command failed: op-0x%x, subtype-0x%x,"
343  "option-0x%x\n",
344  (uint32_t)(((lba_low - START_OFFSET_IN_4K)>>NI_LOGAN_OP_BIT_OFFSET)+0xD0),
345  (uint32_t)((lba_low>>NI_LOGAN_SUB_BIT_OFFSET) & 0xF),
346  (uint32_t)(lba_low & 0xF));
347  }
348  }
349  else
350  {
351  ni_log(NI_LOG_ERROR, "decoder lba:0x%" PRIx64 "(4K-aligned), 0x%" PRIx64 " "
352  "(512B-aligned), session ID:%u\n", lba, (lba<<3), session_id);
353  if (lba_low >= WR_OFFSET_IN_4K)
354  {
355  ni_log(NI_LOG_ERROR, "decoder send packet failed\n");
356  }
357  else if(lba_low >= RD_OFFSET_IN_4K)
358  {
359  ni_log(NI_LOG_ERROR, "decoder receive frame failed\n");
360  }
361  else
362  {
363  ni_log(NI_LOG_ERROR, "decoder ctrl command failed: op-0x%x, subtype-0x%x,"
364  "option-0x%x\n",
365  (uint32_t)(((lba_low - START_OFFSET_IN_4K)>>NI_LOGAN_OP_BIT_OFFSET)+0xD0),
366  (uint32_t)((lba_low>>NI_LOGAN_SUB_BIT_OFFSET) & 0xF),
367  (uint32_t)(lba_low & 0xF));
368  }
369  }
370 }
371 
372 /*!******************************************************************************
373  * \brief Compose a io read command
374  *
375  * \param
376  *
377  * \return value < 0, failed, return failure code.
378  * value >= 0, success,
379  * windows return success code,
380  * linux return actural size
381  *******************************************************************************/
382 int32_t ni_logan_nvme_send_read_cmd(ni_device_handle_t handle,
383  ni_event_handle_t event_handle,
384  void *p_data,
385  uint32_t data_len,
386  uint32_t lba)
387 {
388  int32_t rc;
389  uint64_t offset = (uint64_t)lba << LBA_BIT_OFFSET;
390 #ifdef _WIN32
391  uint32_t offset_l = (uint32_t)(offset & 0xFFFFFFFF);
392  DWORD offset_h = (DWORD)(offset >> 32);
393  OVERLAPPED overlap;
394  DWORD data_len_; //data real count
395 
396  ni_log(NI_LOG_TRACE, "%s: handle=%" PRIx64 ", lba=0x%x, len=%d, "
397  "offset:0x%x,0x%x\n", __FUNCTION__, (int64_t) handle, (lba<<3),
398  data_len, offset_l, offset_h);
399  memset(&overlap, 0, sizeof(overlap));
400  overlap.Offset = offset_l;
401  overlap.OffsetHigh = offset_h;
402 
403  rc = ReadFile(handle, p_data, data_len, &data_len_, &overlap);
404 
405  ni_log(NI_LOG_TRACE, "rc=%d, actlen=%d\n", rc, data_len_);
406  if (rc == FALSE)
407  {
408  rc = NI_ERRNO;
409  ni_log(NI_LOG_TRACE, "%s() ReadFile handle=%" PRIx64 ", "
410  "event_handle=%" PRIx64 ", lba=0x%x, len=%d, rc=%d\n",
411  __FUNCTION__, (int64_t)handle, (int64_t)event_handle,
412  (lba<<3), data_len, rc);
413  ni_logan_parse_lba(lba);
415  }
416  else
417  {
418  ni_log(NI_LOG_TRACE, "%s() ReadFile success handle=%" PRIx64 ", "
419  "event_handle=%" PRIx64 ", lba=0x%x, len=%d, rc=%d\n",
420  __FUNCTION__, (int64_t) handle, (int64_t)event_handle,
421  (lba<<3), data_len, rc);
423  }
424 #else
425  rc = pread(handle, p_data, data_len, offset);
426  ni_log(NI_LOG_TRACE, "%s: handle=%" PRIx64 ", lba=0x%x, len=%d, rc=%d\n",
427  __FUNCTION__, (int64_t)handle, (lba<<3), data_len, rc);
428  if ((rc < 0) || (rc != data_len))
429  {
430  ni_log(NI_LOG_ERROR, "ERROR %d: %s failed, lba=0x%x, len=%d, rc=%d, "
431  "error=%d\n", NI_ERRNO, __FUNCTION__,
432  (lba<<3), data_len, rc, NI_ERRNO);
433  ni_logan_parse_lba(lba);
435  }
436  else
437  {
439  }
440 #endif
441  return rc;
442 }
443 
444 /*!******************************************************************************
445  * \brief Compose a io write command
446  *
447  * \param
448  *
449  * \return value < 0, failed, return failure code.
450  * value >= 0, success,
451  * windows return success code,
452  * linux return actural size
453  *******************************************************************************/
454 int32_t ni_logan_nvme_send_write_cmd(ni_device_handle_t handle,
455  ni_event_handle_t event_handle,
456  void *p_data,
457  uint32_t data_len,
458  uint32_t lba)
459 {
460  int32_t rc;
461  uint64_t offset = (uint64_t)lba << LBA_BIT_OFFSET;
462 #ifdef _WIN32
463  uint32_t offset_l = (uint32_t)(offset & 0xFFFFFFFF);
464  DWORD offset_h = (DWORD)(offset >> 32);
465  OVERLAPPED overlap;
466  DWORD data_len_; //data real count
467 
468  ni_log(NI_LOG_TRACE, "%s: handle=%" PRIx64 ", lba=0x%x, len=%d "
469  "offset:0x%x,0x%x\n", __FUNCTION__, (int64_t)handle, (lba<<3),
470  data_len,offset_l,offset_h);
471 
472  memset(&overlap, 0, sizeof(overlap));
473  overlap.Offset = offset_l;
474  overlap.OffsetHigh = offset_h;
475 
476  rc = WriteFile(handle, p_data, data_len, &data_len_, &overlap);
477 
478  ni_log(NI_LOG_TRACE, "rc=%d, actlen=%d\n", rc, data_len_);
479  if (rc == FALSE)
480  {
481  rc = NI_ERRNO;
482  ni_log(NI_LOG_TRACE, "%s() WriteFile handle=%" PRIx64 ", "
483  "event_handle=%" PRIx64 ", lba=0x%x, len=%d, rc=%d\n", __FUNCTION__,
484  (int64_t)handle, (int64_t)event_handle, (lba<<3), data_len, rc);
485  ni_logan_parse_lba(lba);
487  }
488  else
489  {
490  ni_log(NI_LOG_TRACE, "%s() ReadFile success handle=%" PRIx64 ", "
491  "event_handle=%" PRIx64 ", lba=0x%x, len=%d, rc=%d\n",
492  __FUNCTION__, (int64_t)handle, (int64_t)event_handle, (lba<<3),
493  data_len, rc);
495  }
496 #else
497  rc = pwrite(handle, p_data, data_len, offset);
498  ni_log(NI_LOG_TRACE, "%s: handle=%" PRIx64 ", lba=0x%x, len=%d, rc=%d\n",
499  __FUNCTION__, (int64_t) handle, (lba<<3), data_len, rc);
500  if ((rc < 0) || (rc != data_len))
501  {
502  ni_log(NI_LOG_ERROR, "ERROR %d: %s failed, lba=0x%x, len=%d, rc=%d, "
503  "error=%d\n", NI_ERRNO, __FUNCTION__,
504  (lba<<3), data_len, rc, NI_ERRNO);
505  ni_logan_parse_lba(lba);
507  }
508  else
509  {
511  }
512 #endif
513  return rc;
514 }
ni_logan_retcode_t
@ NI_LOGAN_RETCODE_ERROR_INVALID_HANDLE
@ NI_LOGAN_RETCODE_NVME_SC_VPU_GENERAL_ERROR
@ NI_LOGAN_RETCODE_NVME_SC_RESOURCE_IS_EMPTY
@ NI_LOGAN_RETCODE_NVME_SC_REQUEST_IN_PROGRESS
@ NI_LOGAN_RETCODE_ERROR_NVME_CMD_FAILED
@ NI_LOGAN_RETCODE_ERROR_MEM_ALOC
@ NI_LOGAN_RETCODE_SUCCESS
@ NI_LOGAN_RETCODE_FAILURE
@ NI_LOGAN_RETCODE_NVME_SC_VPU_RECOVERY
@ NI_LOGAN_RETCODE_NVME_SC_RESOURCE_UNAVAILABLE
@ NI_LOGAN_RETCODE_NVME_SC_VPU_RSRC_INSUFFICIENT
@ NI_LOGAN_RETCODE_NVME_SC_INVALID_PARAMETER
@ NI_LOGAN_RETCODE_NVME_SC_REQUEST_NOT_COMPLETED
@ NI_LOGAN_RETCODE_NVME_SC_RESOURCE_NOT_FOUND
#define NI_ERRNO
#define NETINT_PCI_VENDOR_ID
Definition: ni_defs_logan.h:80
#define NI_LOGAN_MAX_DEVICE_NAME_LEN
@ NI_LOGAN_DEVICE_TYPE_ENCODER
@ NI_LOGAN_DEVICE_TYPE_DECODER
void ni_logan_close_event(ni_event_handle_t event_handle)
Closes event and releases resources.
ni_event_handle_t ni_logan_create_event(void)
Create event and returnes event handle if successful.
void ni_log(ni_log_level_t level, const char *fmt,...)
print log message using ni_log_callback
Definition: ni_log_logan.c:120
@ NI_LOG_TRACE
Definition: ni_log_logan.h:67
@ NI_LOG_ERROR
Definition: ni_log_logan.h:64
@ NI_LOG_INFO
Definition: ni_log_logan.h:65
void ni_logan_parse_lba(uint64_t lba)
parse the lba opcode, subtype, option It's called only if a I/O read/write fails, so just use the pri...
ni_logan_retcode_t ni_logan_nvme_check_error_code(int rc, ni_logan_nvme_admin_opcode_t opcode, uint32_t xcoder_type, uint32_t hw_id, int32_t *p_instance_id)
Check f/w error return code, and if it's a fatal one, terminate application's decoding/encoding proce...
Definition: ni_nvme_logan.c:55
int32_t ni_logan_nvme_send_write_cmd(ni_device_handle_t handle, ni_event_handle_t event_handle, void *p_data, uint32_t data_len, uint32_t lba)
Compose a io write command.
int32_t ni_logan_nvme_send_read_cmd(ni_device_handle_t handle, ni_event_handle_t event_handle, void *p_data, uint32_t data_len, uint32_t lba)
Compose a io read command.
Definitions related to working with NI T-408 over NVME interface.
#define NI_LOGAN_SUB_BIT_OFFSET
#define LBA_BIT_OFFSET
int ni_logan_nvme_enumerate_devices(char ni_logan_devices[][NI_LOGAN_MAX_DEVICE_NAME_LEN], int max_handles)
prints a report on detected nvme devices
#define NI_LOGAN_NVME_IDENTITY_CMD_DATA_SZ
Definition: ni_nvme_logan.h:42
#define NI_LOGAN_SESSION_ID_OFFSET
#define WR_OFFSET_IN_4K
#define IDENTIFY_DEVICE_R
enum _ni_logan_nvme_admin_opcode ni_logan_nvme_admin_opcode_t
#define NI_LOGAN_INSTANCE_TYPE_OFFSET
#define START_OFFSET_IN_4K
#define NI_LOGAN_OP_BIT_OFFSET
#define RD_OFFSET_IN_4K
int32_t ni_logan_posix_memalign(void **pp_memptr, size_t alignment, size_t size)
Exported utility routines definition.