39 #elif __linux__ || __APPLE__
41 #include <linux/types.h>
43 #include <sys/ioctl.h>
51 #define ROUND_TO_ULONG(x) ni_round_up(x,sizeof(uint32_t))
63 uint32_t hw_id, uint32_t *p_instance_id)
73 "Hardware %u %s experiencing insufficient resource (instance %u opcode %x)!\n",
74 hw_id, type_str, *p_instance_id, opcode);
78 "Hardware %u %s failed to open session due to invalid "
80 "parameter values given (instance %u opcode %x)!\n",
81 hw_id, type_str, *p_instance_id, opcode);
85 "Hardware %u %s got stream error (instance %u opcode %x)!\n",
86 hw_id, type_str, *p_instance_id, opcode);
90 "Error: Hardware %u %s doesn't support Interlaced video (instance %u opcode %x)!\n",
91 hw_id, type_str, *p_instance_id, opcode);
98 type_str, hw_id, *p_instance_id);
102 "Error rc = 0x%x, op = %02x, %s %u.%u terminating?\n", rc,
103 opcode, type_str, hw_id,
120 ni_nvme_send_admin_pass_through_command(ni_device_handle_t handle,
121 ni_nvme_passthrough_cmd_t *p_cmd)
143 return ioctl(handle, NVME_IOCTL_ADMIN_CMD, p_cmd);
153 int32_t ni_nvme_send_io_pass_through_command(ni_device_handle_t handle,
154 ni_nvme_passthrough_cmd_t *p_cmd)
176 return ioctl(handle, NVME_IOCTL_IO_CMD, p_cmd);
179 #endif //__linux__ defined
183 #define ROUND_TO_DWORD_PTR(x) ni_round_up(x,sizeof(PDWORD))
185 static ni_retcode_t ni_nvme_get_identity(HANDLE handle, HANDLE event_handle,
201 LPTSTR p_scsi_path =
"\\\\.\\PHYSICALDRIVE";
202 LPCTSTR p_format =
"%s%d";
203 PUCHAR p_buffer = NULL;
205 CHAR firmware_revision[8] = {0};
206 int device_count = 0;
210 CHAR serial_num[20] = {0};
211 CHAR model_name[40] = {0};
224 memset(p_buffer, 0, data_len);
225 ni_event_handle_t event_handle = NULL;
227 for (scsi_port = 0; scsi_port < max_handles; scsi_port++)
229 wsprintf(port_name_buffer, p_format, p_scsi_path, scsi_port);
231 CreateFile(port_name_buffer, GENERIC_READ | GENERIC_WRITE,
232 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
233 FILE_ATTRIBUTE_NORMAL, NULL);
234 if (INVALID_HANDLE_VALUE == handle)
241 DISK_GEOMETRY_EX disk_geometry = { 0 };
242 DWORD bytes_returned;
245 IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
249 sizeof(disk_geometry),
253 LONGLONG disk_size = disk_geometry.DiskSize.QuadPart;
256 ZeroMemory(p_buffer, data_len);
257 rc = ni_nvme_get_identity(handle, event_handle, p_buffer);
262 port_name_buffer, (
double)disk_size);
274 "Identity information retrieved from the device "
278 " VID: 0x%x \n SSVID: 0x%x \n",
286 memset(firmware_revision, 0,
sizeof(firmware_revision));
287 memcpy(firmware_revision, p_ni_id_data->
ai8Fr,
288 sizeof(firmware_revision));
289 firmware_revision[
sizeof(firmware_revision) - 1] = 0;
291 memset(model_name, 0,
sizeof(model_name));
292 memcpy(model_name, p_ni_id_data->
ai8Mn,
sizeof(model_name));
293 model_name[
sizeof(model_name) - 1] = 0;
295 memset(serial_num, 0,
sizeof(serial_num));
296 memcpy(serial_num, p_ni_id_data->
ai8Sn,
sizeof(serial_num));
297 serial_num[
sizeof(serial_num) - 1] = 0;
305 "NETINT %s NVMe video transcoder identified "
307 model_name, port_name_buffer);
308 strncpy(ni_devices[device_count++], port_name_buffer,
313 "Device at port %s %d is not a NETINT NVMe device\n",
322 "Device at port %s is not a NETINT NVMe device,ret=%d\n\n",
323 port_name_buffer, retval);
335 "Total Number of NETINT NVMe Transcoders identified: %d \n\n",
340 #endif //_WIN32 defined
342 #ifndef XCODER_IO_RW_ENABLED
351 ni_device_handle_t handle,
353 uint32_t data_len,
void *p_data,
362 rc = ni_nvme_get_identity(handle, NI_INVALID_EVENT_HANDLE, p_data);
367 ni_nvme_passthrough_cmd_t nvme_cmd = {0};
369 nvme_cmd.opcode = opcode;
370 nvme_cmd.cdw10 = (__u32)ni_htonl(p_ni_nvme_cmd->
cdw10);
371 nvme_cmd.cdw11 = (__u32)ni_htonl(p_ni_nvme_cmd->
cdw11);
372 nvme_cmd.cdw12 = (__u32)ni_htonl(p_ni_nvme_cmd->
cdw12);
373 nvme_cmd.cdw13 = (__u32)ni_htonl(p_ni_nvme_cmd->
cdw13);
374 nvme_cmd.cdw14 = (__u32)ni_htonl(p_ni_nvme_cmd->
cdw14);
375 nvme_cmd.cdw15 = (__u32)ni_htonl(p_ni_nvme_cmd->
cdw15);
376 nvme_cmd.addr = (__u64)ni_htonll((uintptr_t)p_data);
377 nvme_cmd.data_len = ni_htonl(data_len);
379 rc = ni_nvme_send_admin_pass_through_command(handle, &nvme_cmd);
381 *p_result = ni_htonl(nvme_cmd.result);
385 __func__, (int64_t)handle, (uint32_t)(*p_result), rc);
399 void *p_data, uint32_t *p_result)
405 ni_nvme_passthrough_cmd_t nvme_cmd;
408 memset(&nvme_cmd, 0,
sizeof(nvme_cmd));
409 nvme_cmd.opcode = opcode;
410 nvme_cmd.nsid = ni_htonl(1);
411 nvme_cmd.addr = (__u64)ni_htonll((uintptr_t)p_data);
412 nvme_cmd.data_len = ni_htonl(data_len);
413 nvme_cmd.cdw2 = (__u32)ni_htonl(p_ni_nvme_cmd->
cdw2);
414 nvme_cmd.cdw3 = (__u32)ni_htonl(p_ni_nvme_cmd->
cdw3);
415 nvme_cmd.cdw10 = (__u32)ni_htonl(p_ni_nvme_cmd->
cdw10);
416 nvme_cmd.cdw11 = (__u32)ni_htonl(p_ni_nvme_cmd->
cdw11);
417 nvme_cmd.cdw12 = (__u32)ni_htonl(p_ni_nvme_cmd->
cdw12);
418 nvme_cmd.cdw13 = (__u32)ni_htonl(p_ni_nvme_cmd->
cdw13);
419 nvme_cmd.cdw14 = (__u32)ni_htonl(p_ni_nvme_cmd->
cdw14);
420 nvme_cmd.cdw15 = (__u32)ni_htonl(p_ni_nvme_cmd->
cdw15);
422 rc = ni_nvme_send_io_pass_through_command(handle, &nvme_cmd);
426 *p_result = ni_htonl(nvme_cmd.result);
430 __func__, (int64_t)handle, (uint32_t)(*p_result), rc);
446 ni_device_handle_t handle,
448 uint32_t data_len,
void *p_data,
452 ni_nvme_passthrough_cmd_t nvme_cmd = {0};
454 nvme_cmd.opcode = opcode;
455 nvme_cmd.nsid = ni_htonl(1);
456 nvme_cmd.addr = (__u64)ni_htonll((uintptr_t)p_data);
457 nvme_cmd.data_len = ni_htonl(data_len);
458 nvme_cmd.cdw10 = (__u32)ni_htonl(p_ni_nvme_cmd->
cdw10);
459 nvme_cmd.cdw11 = (__u32)ni_htonl(p_ni_nvme_cmd->
cdw11);
460 nvme_cmd.cdw12 = (__u32)ni_htonl(p_ni_nvme_cmd->
cdw12);
461 nvme_cmd.cdw13 = (__u32)ni_htonl(p_ni_nvme_cmd->
cdw13);
462 nvme_cmd.cdw14 = (__u32)ni_htonl(p_ni_nvme_cmd->
cdw14);
463 nvme_cmd.cdw15 = (__u32)ni_htonl(p_ni_nvme_cmd->
cdw15);
465 rc = ni_nvme_send_admin_pass_through_command(handle, &nvme_cmd);
469 *p_result = ni_htonl(nvme_cmd.result);
472 handle, *p_result, rc);
476 #endif //__linux__ defined
490 uint64_t lba_low = (lba & 0x3FFFF);
492 uint16_t session_id = (uint16_t)(
497 "encoder lba:0x%" PRIx64
"(4K-aligned), 0x%" PRIx64
498 "(512B-aligned), session ID:%u\n",
499 lba, ((uint64_t)lba << 3), session_id);
509 "encoder ctrl command failed: op-0x%x, "
510 "subtype-0x%x, option-0x%x\n",
515 (uint32_t)(lba_low & 0xF));
521 "decoder lba:0x%" PRIx64
"(4K-aligned), 0x%" PRIx64
522 "(512B-aligned), session ID:%u\n",
523 lba, ((uint64_t)lba << 3), session_id);
533 "decoder ctrl command failed: op-0x%x, "
534 "subtype-0x%x, option-0x%x\n",
539 (uint32_t)(lba_low & 0xF));
555 ni_event_handle_t event_handle,
void *p_data,
556 uint32_t data_len, uint32_t lba)
568 uint32_t offset_l = (uint32_t)(offset & 0xFFFFFFFF);
569 DWORD offset_h = (DWORD)(offset >> 32);
572 "%s: handle=%" PRIx64
", lba=0x%lx, len=%d,offset:0x%x,0x%x\n",
573 __func__, (int64_t)handle, ((uint64_t)lba << 3), data_len, offset_l, offset_h);
574 memset(&overlap, 0,
sizeof(overlap));
575 overlap.Offset = offset_l;
576 overlap.OffsetHigh = offset_h;
579 rc = ReadFile(handle, p_data, data_len, &data_len_, &overlap);
585 "%s() ReadFile handle=%" PRIx64
", event_handle="
586 "%" PRIx64
", lba=0x%lx, len=%d, rc=%d\n",
587 __func__, (int64_t)handle, (int64_t)event_handle, ((uint64_t)lba << 3),
596 if (!handle || handle == NI_INVALID_DEVICE_HANDLE)
600 ni_log(
NI_LOG_ERROR,
"%s: ERROR: invalid parameters: handle=%" PRId32
"\n", __func__, handle);
607 "%s: Buffer not %d aligned = %p! Reading to aligned memory "
614 "ERROR %d: %s() alloc data buffer failed\n",
NI_ERRNO,
620 rc = pread(handle, p_buf, data_len, offset);
623 memcpy(p_data, p_buf, data_len);
629 rc = pread(handle, p_data, data_len, offset);
632 "%s: handle=%" PRIx64
633 ", offset 0x%lx, lba=0x%lx, len=%d, rc=%d\n",
634 __func__, (int64_t)handle, offset, ((uint64_t)lba << 3), data_len, rc);
635 if (rc < 0 || rc != data_len)
638 "ERROR %d: %s failed, lba=0x%lx, len=%u, rc=%d, error=%d\n",
661 ni_event_handle_t event_handle,
void *p_data,
662 uint32_t data_len, uint32_t lba)
674 uint32_t offset_l = (uint32_t)(offset & 0xFFFFFFFF);
675 DWORD offset_h = (DWORD)(offset >> 32);
680 "%s: handle=%" PRIx64
", lba=0x%lx, len=%d,offset:0x%x,0x%x\n",
681 __func__, (int64_t)handle, ((uint64_t)lba << 3), data_len, offset_l, offset_h);
683 memset(&overlap, 0,
sizeof(overlap));
684 overlap.Offset = offset_l;
685 overlap.OffsetHigh = offset_h;
687 rc = WriteFile(handle, p_data, data_len, &data_len_, &overlap);
693 "%s() WriteFile handle=%" PRIx64
", event_handle="
694 "%" PRIx64
", lba=0x%lx, len=%d, rc=%d\n",
695 __func__, (int64_t)handle, (int64_t)event_handle, ((uint64_t)lba << 3),
704 if (!handle || handle == NI_INVALID_DEVICE_HANDLE)
708 ni_log(
NI_LOG_ERROR,
"%s: ERROR: invalid parameters: handle=%" PRId32
"\n", __func__, handle);
715 "%s: Buffer not %d aligned = %p! Copying to aligned memory "
722 "ERROR %d: %s() alloc data buffer failed\n",
NI_ERRNO,
728 memcpy(p_buf, p_data, data_len);
729 rc = pwrite(handle, p_buf, data_len, offset);
735 rc = pwrite(handle, p_data, data_len, offset);
738 "%s: handle=%" PRIx64
", lba=0x%lx, len=%d, rc=%d\n", __func__,
739 (int64_t)handle, ((uint64_t)lba << 3), data_len, rc);
740 if ((rc < 0) || (rc != data_len))
743 "ERROR %d: %s failed, lba=0x%lx, len=%u, rc=%d, error=%d\n",
757 void ni_nvme_setup_aio_iocb(ni_device_handle_t handle, ni_iocb_t *iocb,
758 void *p_data, uint32_t data_len, uint32_t lba,
761 memset(iocb, 0,
sizeof(ni_iocb_t));
762 iocb->aio_fildes = handle;
763 iocb->aio_lio_opcode = write ? IOCB_CMD_PWRITE : IOCB_CMD_PREAD;
764 iocb->aio_reqprio = 0;
765 iocb->aio_buf = (uint64_t)p_data;
766 iocb->aio_nbytes = data_len;
770 int32_t ni_nvme_batch_cmd_aio(ni_aio_context_t ctx, ni_iocb_t **iocbs,
771 ni_io_event_t *events,
int iocb_num)
776 for (i = 0; i < iocb_num; i++) {
777 ni_iocb_t *iocb = iocbs[i];
779 " nbytes %llu, offset 0x%llx\n", i, iocb->aio_fildes, iocb->aio_lio_opcode,
780 iocb->aio_buf, iocb->aio_nbytes, iocb->aio_offset);
783 rc = ni_aio_submit(ctx, iocb_num, iocbs);
784 if (rc != iocb_num) {
785 ni_log(
NI_LOG_ERROR,
"%s: ERROR: failed to submit enough aio iocb, rc=%d\n", __func__,
790 rc = ni_aio_getevents(ctx, iocb_num, iocb_num, events, NULL);
791 if (rc != iocb_num) {
795 for (i = 0; i < iocb_num; i++) {
796 ni_io_event_t *evt = &events[i];
797 ni_iocb_t *iocb = (ni_iocb_t *)evt->obj;
798 if (iocb->aio_nbytes != evt->res) {
800 __func__, iocb->aio_nbytes, evt->res);