Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions libnvme/src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ elif host_system == 'windows'
'nvme/scan-win.c',
'nvme/tree-win.c',
]
elif host_system == 'freebsd'
sources += [
'nvme/ctrl-sysfs-custom-freebsd.c',
'nvme/ioctl-freebsd.c',
'nvme/lib-freebsd.c',
'nvme/mem-freebsd.c',
'nvme/scan-freebsd.c',
'nvme/tree-freebsd.c',
]
endif
headers = [
'nvme/accessors.h',
Expand Down
51 changes: 51 additions & 0 deletions libnvme/src/nvme/ctrl-sysfs-custom-freebsd.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* This file is part of libnvme.
* Copyright (c) 2026 SUSE Software Solutions
*
* Authors: Daniel Wagner <dwagner@suse.de>
*/

#include <errno.h>
#include <stdio.h>

#include <ccan/endian/endian.h>

#include <compiler-attributes.h>

#include "lib.h"

#include "ctrl-sysfs.c"

#ifdef CONFIG_FABRICS
# include "ctrl-sysfs-custom-fabrics.c"
#else
# include "ctrl-sysfs-custom-no-fabrics.c"
#endif

int libnvme_ctrl_load_identity(struct libnvme_ctrl *c)
{
struct nvme_id_ctrl id_ctrl;
int ret;

ret = libnvme_ctrl_identify(c, &id_ctrl);
if (ret != 0)
return ret;

if (asprintf(&c->sysfs->cntrltype, "%u", id_ctrl.cntrltype) < 0)
return -ENOMEM;

if (asprintf(&c->sysfs->cntlid, "%u", le16_to_cpu(id_ctrl.cntlid)) < 0)
return -ENOMEM;

if (asprintf(&c->sysfs->dctype, "%u", id_ctrl.dctype) < 0)
return -ENOMEM;

return 0;
}

int libnvme_ctrl_load_phy_slot(__shr_unused struct libnvme_ctrl *c)
{
/* FreeBSD has no PCIe physical slot sysfs equivalent. */
return 0;
}
61 changes: 61 additions & 0 deletions libnvme/src/nvme/ioctl-freebsd.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* This file is part of libnvme.
* Copyright (c) 2026 SUSE Software Solutions
*
* Authors: Daniel Wagner <dwagner@suse.de>
*/

#include <errno.h>

#include <compiler-attributes.h>

#include <libnvme.h>

#include "private.h"

__shr_public int libnvme_reset_subsystem(
__shr_unused struct libnvme_transport_handle *hdl)
{
return -ENOTSUP;
}

__shr_public int libnvme_reset_ctrl(
__shr_unused struct libnvme_transport_handle *hdl)
{
return -ENOTSUP;
}

__shr_public int libnvme_rescan_ns(
__shr_unused struct libnvme_transport_handle *hdl)
{
return -ENOTSUP;
}

__shr_public int libnvme_get_nsid(
__shr_unused struct libnvme_transport_handle *hdl,
__shr_unused __u32 *nsid)
{
return -ENOTSUP;
}

__shr_public int libnvme_update_block_size(
__shr_unused struct libnvme_transport_handle *hdl,
__shr_unused int block_size)
{
return -ENOTSUP;
}

__shr_public int libnvme_exec_admin_passthru(
__shr_unused struct libnvme_transport_handle *hdl,
__shr_unused struct libnvme_passthru_cmd *cmd)
{
return -ENOTSUP;
}

__shr_public int libnvme_exec_io_passthru(
__shr_unused struct libnvme_transport_handle *hdl,
__shr_unused struct libnvme_passthru_cmd *cmd)
{
return -ENOTSUP;
}
122 changes: 122 additions & 0 deletions libnvme/src/nvme/lib-freebsd.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* This file is part of libnvme.
* Copyright (c) 2026 SUSE Software Solutions
*
* Authors: Daniel Wagner <dwagner@suse.de>
*/

#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#include <libnvme.h>

#include <compiler-attributes.h>

#include "private.h"

/*
* FreeBSD: opening a device node is plain POSIX and portable, so this
* mirrors lib-linux.c's approach without assuming Linux's "nvme%dn%d"
* naming scheme. Actual command submission is stubbed out in
* ioctl-freebsd.c.
*/

static int __libnvme_transport_handle_open_direct(
struct libnvme_transport_handle *hdl, const char *devname)
{
int ret;

hdl->type = LIBNVME_TRANSPORT_HANDLE_TYPE_DIRECT;

hdl->fd = open(devname, O_RDONLY);
if (hdl->fd < 0)
return -errno;

ret = fstat(hdl->fd, &hdl->stat);
if (ret < 0) {
close(hdl->fd);
return -errno;
}

if (!S_ISCHR(hdl->stat.st_mode) && !S_ISBLK(hdl->stat.st_mode)) {
close(hdl->fd);
return -EINVAL;
}

return 0;
}

void __libnvme_transport_handle_close_direct(
struct libnvme_transport_handle *hdl)
{
libnvme_close_uring(hdl);
close(hdl->fd);
free(hdl);
}

__shr_public int libnvme_open(
struct libnvme_global_ctx *ctx, const char *name,
struct libnvme_transport_handle **hdlp)
{
struct libnvme_transport_handle *hdl;
int ret;

hdl = __libnvme_create_transport_handle(ctx);
if (!hdl)
return -ENOMEM;

hdl->name = strdup(name);
if (!hdl->name) {
free(hdl);
return -ENOMEM;
}

if (!strncmp(name, "NVME_TEST_FD", 12)) {
hdl->type = LIBNVME_TRANSPORT_HANDLE_TYPE_DIRECT;
hdl->fd = LIBNVME_TEST_FD;

if (!strcmp(name, "NVME_TEST_FD64"))
hdl->ioctl_admin_state = IOCTL_STATE_IOCTL64;

*hdlp = hdl;
return 0;
}

if (!strncmp(name, "mctp:", strlen("mctp:"))) {
libnvme_close(hdl);
return -ENOTSUP;
}

ret = __libnvme_transport_handle_open_direct(hdl, name);
if (ret) {
libnvme_close(hdl);
return ret;
}

*hdlp = hdl;

return 0;
}

__shr_public void libnvme_close(struct libnvme_transport_handle *hdl)
{
if (!hdl)
return;

free(hdl->name);

switch (hdl->type) {
case LIBNVME_TRANSPORT_HANDLE_TYPE_DIRECT:
__libnvme_transport_handle_close_direct(hdl);
break;
case LIBNVME_TRANSPORT_HANDLE_TYPE_MI:
case LIBNVME_TRANSPORT_HANDLE_TYPE_UNKNOWN:
free(hdl);
break;
}
}
84 changes: 84 additions & 0 deletions libnvme/src/nvme/mem-freebsd.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* This file is part of libnvme.
* Copyright (c) 2026 SUSE Software Solutions
*
* Authors: Daniel Wagner <dwagner@suse.de>
*/

#include <malloc_np.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <ccan/minmax/minmax.h>

#include <compiler-attributes.h>

#include "mem.h"
#include "private.h"

/*
* FreeBSD: plain page-aligned allocations. Linux's transparent-hugepage
* mmap/madvise flags (MAP_HUGETLB, MADV_HUGEPAGE) have no FreeBSD
* equivalent, so libnvme_alloc_huge() always takes the small-allocation
* posix_memalign() path regardless of size -- correct, just without the
* performance benefit of real huge pages.
*/

__shr_public void *libnvme_alloc(size_t len)
{
size_t _len = round_up(len, 0x1000);
void *p;

if (posix_memalign((void *)&p, getpagesize(), _len))
return NULL;

memset(p, 0, _len);
return p;
}

__shr_public void *libnvme_realloc(void *p, size_t len)
{
size_t old_len = malloc_usable_size(p);
void *result = libnvme_alloc(len);

if (p && result) {
memcpy(result, p, min_t(size_t, old_len, len));
free(p);
}

return result;
}

__shr_public void libnvme_free(void *p)
{
free(p);
}

__shr_public void *libnvme_alloc_huge(size_t len,
struct libnvme_mem_huge *mh)
{
memset(mh, 0, sizeof(*mh));

len = round_up(len, 0x1000);

mh->p = libnvme_alloc(len);
if (!mh->p)
return NULL;

mh->libnvme_alloc = true;
mh->len = len;
return mh->p;
}

__shr_public void libnvme_free_huge(struct libnvme_mem_huge *mh)
{
if (!mh || mh->len == 0)
return;

free(mh->p);

mh->len = 0;
mh->p = NULL;
}
57 changes: 57 additions & 0 deletions libnvme/src/nvme/scan-freebsd.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/*
* This file is part of libnvme.
* Copyright (c) 2026 SUSE Software Solutions
*
* Authors: Daniel Wagner <dwagner@suse.de>
*/

#include <dirent.h>

#include <compiler-attributes.h>

#include <libnvme.h>

#include "private.h"

__shr_public int libnvme_scan_subsystems(
__shr_unused struct libnvme_global_ctx *ctx,
__shr_unused struct dirent ***subsys)
{
return 0;
}

__shr_public int libnvme_scan_subsystem_namespaces(
__shr_unused libnvme_subsystem_t s,
__shr_unused struct dirent ***ns)
{
return 0;
}

__shr_public int libnvme_scan_ctrls(
__shr_unused struct libnvme_global_ctx *ctx,
__shr_unused struct dirent ***ctrls)
{
return 0;
}

__shr_public int libnvme_scan_ctrl_namespace_paths(
__shr_unused libnvme_ctrl_t c,
__shr_unused struct dirent ***paths)
{
return 0;
}

__shr_public int libnvme_scan_ctrl_namespaces(
__shr_unused libnvme_ctrl_t c,
__shr_unused struct dirent ***ns)
{
return 0;
}

__shr_public int libnvme_scan_ns_head_paths(
__shr_unused libnvme_ns_head_t head,
__shr_unused struct dirent ***paths)
{
return 0;
}
Loading
Loading