35#include <sys/utsname.h>
46#define TS_DEBOUNCE_MS 2000ULL
48static uint64_t s_last_ts_ms = 0;
50static uint64_t get_epoch_ms(
void)
53 if (clock_gettime(CLOCK_REALTIME, &ts) != 0)
55 return (uint64_t)ts.tv_sec * 1000ULL + (uint64_t)ts.tv_nsec / 1000000ULL;
67static int sysfs_to_blk_dev(
const char *sysfs_path,
char *blk_dev,
70 char nvme_dir[PATH_MAX];
71 int n = snprintf(nvme_dir,
sizeof(nvme_dir),
"%s/nvme", sysfs_path);
72 if (n < 0 || n >= (
int)
sizeof(nvme_dir))
75 DIR *d = opendir(nvme_dir);
79 char ctrl_name[64] = {0};
81 while ((entry = readdir(d)))
83 if (entry->d_name[0] ==
'.')
85 if (strncmp(entry->d_name,
"nvme", 4) == 0)
87 int m = snprintf(ctrl_name,
sizeof(ctrl_name),
"%s", entry->d_name);
88 if (m >= 0 && m < (
int)
sizeof(ctrl_name))
94 if (ctrl_name[0] ==
'\0')
97 char ns_dir[PATH_MAX];
98 n = snprintf(ns_dir,
sizeof(ns_dir),
"%s/nvme/%s", sysfs_path, ctrl_name);
99 if (n < 0 || n >= (
int)
sizeof(ns_dir))
107 while ((entry = readdir(d)))
109 if (entry->d_name[0] ==
'.')
111 if (strncmp(entry->d_name, ctrl_name, strlen(ctrl_name)) == 0 &&
112 entry->d_name[strlen(ctrl_name)] ==
'n')
114 int k = snprintf(blk_dev, blk_dev_sz,
"/dev/%s", entry->d_name);
115 if (k >= 0 && k < (
int)blk_dev_sz)
121 return found ? 0 : -1;
130static void send_set_features_timestamp(
const char *blk_dev, uint64_t epoch_ms)
133 if (fd == NI_INVALID_DEVICE_HANDLE)
137 memset(&cap, 0,
sizeof(cap));
141 "%s: skipping host timestamp on %s: capability query failed\n",
152 "%s: skipping host timestamp on %s: FW API version needs to be >= 6tB\n",
162 "%s: failed to allocate aligned buffer for %s\n",
168 memcpy(buf, &epoch_ms,
sizeof(epoch_ms));
177static int get_kernel_version(
void)
180 if (uname(&uts) != 0)
183 int major = 0, minor = 0, patch = 0;
184 if (sscanf(uts.release,
"%d.%d.%d", &major, &minor, &patch) != 3)
187 return major * 10000 + minor * 100 + patch;
190void ni_host_ts_set(
void)
192 uint64_t epoch_ms = get_epoch_ms();
196 if (s_last_ts_ms != 0 && (epoch_ms - s_last_ts_ms) < TS_DEBOUNCE_MS)
199 s_last_ts_ms = epoch_ms;
201 time_t now = (time_t)(epoch_ms / 1000);
205 int kernel_ver = get_kernel_version();
207 if (kernel_ver >= 41400)
210 if (localtime_r(&now, &tm_buf) &&
211 strftime(datebuf,
sizeof(datebuf),
"%c", &tm_buf) > 0)
214 QuadraDevice *devs = NULL;
215 int ndev = quadra_device_find(&devs);
222 for (
int i = 0; i < ndev; i++)
224 char blk_dev[PATH_MAX];
225 if (sysfs_to_blk_dev(devs[i].sysfs_path, blk_dev,
sizeof(blk_dev)) != 0)
229 send_set_features_timestamp(blk_dev, epoch_ms);
Common NETINT definitions used by all modules.
#define NI_XCODER_REVISION_API_MAJOR_VER_IDX
ni_retcode_t ni_device_capability_query2(ni_device_handle_t device_handle, ni_device_capability_t *p_cap, bool device_in_ctxt)
Query device and return device capability structure This function had replaced ni_device_capability_q...
void ni_device_close(ni_device_handle_t device_handle)
Close device and release resources.
ni_device_handle_t ni_device_open2(const char *p_dev, ni_device_mode_t mode)
Open device and return device device_handle if successful.
Public definitions for operating NETINT video processing devices for video processing.
Set host timestamp on Quadra NVMe controllers.
void ni_log(ni_log_level_t level, const char *fmt,...)
print log message using ni_log_callback
int32_t ni_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.
Private definitions for interfacing with NETINT video processing devices over NVMe.
#define CONFIG_SESSION_SetHostTime_W(sid)
#define NI_DATA_BUFFER_LEN
int ni_posix_memalign(void **memptr, size_t alignment, size_t size)
Allocate aligned memory.
int ni_cmp_fw_api_ver(const char ver1[], const char ver2[])
Compare two 3 character strings containing a FW API version. Handle comparision when FW API version f...
#define ni_aligned_free(p_memptr)