From: Kuan-Wei Chiu <visitorckw@gmail.com>
To: trini@konsulko.com, tuomas.tynkkynen@iki.fi, bmeng.cn@gmail.com,
sjg@chromium.org, jerome.forissier@arm.com
Cc: jserv@ccns.ncku.edu.tw, eleanor15x@gmail.com,
marscheng@google.com, u-boot@lists.u-boot-project.org,
Kuan-Wei Chiu <visitorckw@gmail.com>
Subject: [PATCH v2 1/6] net: 9p: Add 9P2000.L protocol support
Date: Sat, 29 Aug 2026 19:21:14 +0000 [thread overview]
Message-ID: <20260829192119.2658328-2-visitorckw@gmail.com> (raw)
In-Reply-To: <20260829192119.2658328-1-visitorckw@gmail.com>
Introduce the core 9P network protocol client implementation.
9P is a network filesystem protocol originally developed for the
Plan 9 operating system. Add the baseline 9P2000.L protocol handling,
including message serialization, DM UCLASS_9P transport management,
and basic transport operations.
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
---
Changes in v2:
- Consistently use 9P2000.L instead of 9P2000 in subject and Kconfig.
- Add kerneldoc comments in include/9p.h.
- Move filesystem declarations to include/9pfs.h.
- Add LOG_CATEGORY and drop #include <config.h>.
- Return -ecode from P9_RLERROR in p9_check_error().
- Check memalign() return for NULL and return -ENOMEM.
- Parse server msize and version string in Rversion.
- Check return value of strlcpy() in p9_client_walk().
- Check nwqid == nwname in Rwalk reply.
- Validate count <= read_len before memcpy in read/readdir.
- Implement DM UCLASS_9P.
---
include/9p.h | 203 ++++++++++++++++++++
include/dm/uclass-id.h | 1 +
net/9p/Kconfig | 5 +
net/9p/Makefile | 5 +
net/9p/client.c | 408 +++++++++++++++++++++++++++++++++++++++++
net/Kconfig | 2 +
net/Makefile | 1 +
7 files changed, 625 insertions(+)
create mode 100644 include/9p.h
create mode 100644 net/9p/Kconfig
create mode 100644 net/9p/Makefile
create mode 100644 net/9p/client.c
diff --git a/include/9p.h b/include/9p.h
new file mode 100644
index 00000000000..e755c78be0f
--- /dev/null
+++ b/include/9p.h
@@ -0,0 +1,203 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2026, Kuan-Wei Chiu <visitorckw@gmail.com>
+ */
+
+#ifndef __9P_H__
+#define __9P_H__
+
+#include <linux/types.h>
+
+#define P9_MSIZE 65536
+#define P9_NOFID (~0U)
+#define P9_NOTAG 0xFFFF
+#define P9_REQ_TAG 1
+
+#define P9_RLERROR 7
+#define P9_TLOPEN 12
+#define P9_RLOPEN 13
+#define P9_TGETATTR 24
+#define P9_RGETATTR 25
+#define P9_TREADDIR 40
+#define P9_RREADDIR 41
+#define P9_TVERSION 100
+#define P9_RVERSION 101
+#define P9_TATTACH 104
+#define P9_RATTACH 105
+#define P9_TWALK 110
+#define P9_RWALK 111
+#define P9_TREAD 116
+#define P9_RREAD 117
+#define P9_TCLUNK 120
+#define P9_RCLUNK 121
+
+#define P9_O_RDONLY 00000000
+#define P9_GETATTR_SIZE 0x00000010ULL
+#define P9_GETATTR_SIZE_OFFSET 41
+#define P9_DT_DIR 4
+
+/**
+ * struct p9_dirent_hdr - 9P2000.L directory entry wire header
+ * @qid: File QID (13 bytes)
+ * @offset: Offset cookie for next readdir (8 bytes)
+ * @type: Directory entry type (1 byte)
+ * @name_len: Length of filename (2 bytes)
+ */
+struct p9_dirent_hdr {
+ u8 qid[13];
+ u64 offset;
+ u8 type;
+ u16 name_len;
+} __packed;
+
+/**
+ * struct p9_header - 9P message header
+ * @size: Total message size in bytes, including this header
+ * @id: Message type / opcode (e.g. P9_TVERSION)
+ * @tag: Message tag to match request and reply
+ */
+struct p9_header {
+ u32 size;
+ u8 id;
+ u16 tag;
+} __packed;
+
+struct udevice;
+
+/**
+ * struct dm_p9_ops - Driver model operations for 9P transports
+ * @request: Execute a transmit/receive transaction
+ * @get_mount_tag: (optional) Retrieve the mount tag string
+ */
+struct dm_p9_ops {
+ int (*request)(struct udevice *dev, void *tx, int tx_len, void *rx, int rx_len);
+ const char *(*get_mount_tag)(struct udevice *dev);
+};
+
+/**
+ * struct p9_client - 9P client state
+ * @dev: Underlying transport udevice
+ * @tx: Transmit buffer
+ * @rx: Receive buffer
+ * @next_fid: Next FID to allocate
+ * @msize: Negotiated maximum message size
+ */
+struct p9_client {
+ struct udevice *dev;
+ u8 *tx;
+ u8 *rx;
+ u32 next_fid;
+ u32 msize;
+};
+
+/**
+ * p9_get_device() - Find a 9P transport device by mount tag or default
+ * @tag: Mount tag to match, or NULL/"-" for default/first device
+ * @devp: Output pointer to the found udevice
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int p9_get_device(const char *tag, struct udevice **devp);
+
+/**
+ * p9_get_client() - Get 9P client state from a transport udevice
+ * @dev: 9P transport udevice
+ *
+ * Return: Pointer to struct p9_client
+ */
+struct p9_client *p9_get_client(struct udevice *dev);
+
+/**
+ * p9_client_alloc_fid() - Allocate a unique FID
+ * @c: Pointer to 9P client
+ *
+ * Return: Newly allocated FID
+ */
+u32 p9_client_alloc_fid(struct p9_client *c);
+
+/**
+ * p9_client_version() - Negotiate 9P2000.L protocol version and msize
+ * @c: Pointer to 9P client
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int p9_client_version(struct p9_client *c);
+
+/**
+ * p9_client_attach() - Attach to the root directory
+ * @c: Pointer to 9P client
+ * @fid: FID to assign to root
+ * @uname: User name
+ * @aname: File tree / mount point name
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int p9_client_attach(struct p9_client *c, u32 fid, const char *uname, const char *aname);
+
+/**
+ * p9_client_walk() - Walk a path and associate with a new FID
+ * @c: Pointer to 9P client
+ * @base_fid: Starting directory FID
+ * @new_fid: New FID to associate with target path
+ * @path: Relative path to walk
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int p9_client_walk(struct p9_client *c, u32 base_fid, u32 new_fid, const char *path);
+
+/**
+ * p9_client_lopen() - Open a file (9P2000.L)
+ * @c: Pointer to 9P client
+ * @fid: FID of file to open
+ * @flags: Open flags (e.g. P9_O_RDONLY)
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int p9_client_lopen(struct p9_client *c, u32 fid, u32 flags);
+
+/**
+ * p9_client_clunk() - Forget / close a FID
+ * @c: Pointer to 9P client
+ * @fid: FID to clunk
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int p9_client_clunk(struct p9_client *c, u32 fid);
+
+/**
+ * p9_client_stat() - Get file size attribute via Tgetattr
+ * @c: Pointer to 9P client
+ * @fid: FID of file
+ * @size: Output pointer for file size
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int p9_client_stat(struct p9_client *c, u32 fid, loff_t *size);
+
+/**
+ * p9_client_read() - Read data from a file
+ * @c: Pointer to 9P client
+ * @fid: FID of file
+ * @offset: Byte offset in file to read from
+ * @count: Maximum number of bytes to read
+ * @buf: Destination buffer
+ * @actread: Output pointer for actual bytes read
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int p9_client_read(struct p9_client *c, u32 fid, u64 offset, u32 count, void *buf, u32 *actread);
+
+/**
+ * p9_client_readdir() - Read directory entries
+ * @c: Pointer to 9P client
+ * @fid: FID of directory
+ * @offset: Directory offset / cookie
+ * @count: Maximum bytes of dirents to read
+ * @buf: Destination buffer
+ * @actread: Output pointer for actual bytes returned
+ *
+ * Return: 0 on success, negative error code on failure
+ */
+int p9_client_readdir(struct p9_client *c, u32 fid, u64 offset, u32 count, void *buf, u32 *actread);
+
+#endif /* __9P_H__ */
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index fe0aae2720c..10680dc860c 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -108,6 +108,7 @@ enum uclass_id {
UCLASS_PANEL, /* Display panel, such as an LCD */
UCLASS_PANEL_BACKLIGHT, /* Backlight controller for panel */
UCLASS_PARTITION, /* Logical disk partition device */
+ UCLASS_9P, /* 9P protocol transport */
UCLASS_PCH, /* x86 platform controller hub */
UCLASS_PCI, /* PCI bus */
UCLASS_PCI_EP, /* PCI endpoint device */
diff --git a/net/9p/Kconfig b/net/9p/Kconfig
new file mode 100644
index 00000000000..5fda98cb23d
--- /dev/null
+++ b/net/9p/Kconfig
@@ -0,0 +1,5 @@
+config NET_9P
+ bool "9P2000.L protocol support"
+ help
+ This enables support for the 9P network protocol (9P2000.L).
+ It implements the core 9P2000.L client and protocol handling.
diff --git a/net/9p/Makefile b/net/9p/Makefile
new file mode 100644
index 00000000000..e9220b0826e
--- /dev/null
+++ b/net/9p/Makefile
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (C) 2026, Kuan-Wei Chiu <visitorckw@gmail.com>
+
+obj-y += client.o
diff --git a/net/9p/client.c b/net/9p/client.c
new file mode 100644
index 00000000000..970cf4d6e8f
--- /dev/null
+++ b/net/9p/client.c
@@ -0,0 +1,408 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2026, Kuan-Wei Chiu <visitorckw@gmail.com>
+ */
+
+#define LOG_CATEGORY LOGC_NET
+
+#include <9p.h>
+#include <dm.h>
+#include <dm/device.h>
+#include <dm/device-internal.h>
+#include <dm/uclass.h>
+#include <log.h>
+#include <malloc.h>
+#include <asm/cache.h>
+#include <asm/unaligned.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+static int p9_post_probe(struct udevice *dev)
+{
+ struct p9_client *c = dev_get_uclass_priv(dev);
+
+ c->dev = dev;
+ return 0;
+}
+
+UCLASS_DRIVER(p9) = {
+ .name = "p9",
+ .id = UCLASS_9P,
+ .per_device_auto = sizeof(struct p9_client),
+ .post_probe = p9_post_probe,
+};
+
+struct p9_client *p9_get_client(struct udevice *dev)
+{
+ return dev_get_uclass_priv(dev);
+}
+
+int p9_get_device(const char *tag, struct udevice **devp)
+{
+ struct udevice *dev;
+ char *endp;
+ ulong num;
+ int ret;
+
+ if (!tag || !tag[0] || !strcmp(tag, "-"))
+ return uclass_first_device_err(UCLASS_9P, devp);
+
+ num = simple_strtoul(tag, &endp, 10);
+ if (*endp == '\0') {
+ ret = uclass_get_device(UCLASS_9P, num, devp);
+ if (!ret)
+ return 0;
+ }
+
+ uclass_foreach_dev_probe(UCLASS_9P, dev) {
+ const struct dm_p9_ops *ops = device_get_ops(dev);
+
+ if (ops && ops->get_mount_tag) {
+ const char *mtag = ops->get_mount_tag(dev);
+
+ if (mtag && !strcmp(mtag, tag)) {
+ *devp = dev;
+ return 0;
+ }
+ }
+
+ if (!strcmp(dev->name, tag)) {
+ *devp = dev;
+ return 0;
+ }
+ }
+
+ return -ENODEV;
+}
+
+u32 p9_client_alloc_fid(struct p9_client *c)
+{
+ if (c->next_fid >= 0xFFFF0000 || c->next_fid == 0)
+ c->next_fid = 2; /* fid 1 is reserved for root */
+ return c->next_fid++;
+}
+
+static void p9_put_u16(u8 **p, u16 v)
+{
+ put_unaligned_le16(v, *p);
+ *p += 2;
+}
+
+static void p9_put_u32(u8 **p, u32 v)
+{
+ put_unaligned_le32(v, *p);
+ *p += 4;
+}
+
+static void p9_put_u64(u8 **p, u64 v)
+{
+ put_unaligned_le64(v, *p);
+ *p += 8;
+}
+
+static void p9_put_str(u8 **p, const char *s)
+{
+ u16 len = strlen(s);
+
+ put_unaligned_le16(len, *p);
+ *p += 2;
+ memcpy(*p, s, len);
+ *p += len;
+}
+
+static int p9_request(struct p9_client *c, void *tx, int tx_len, void *rx, int rx_len)
+{
+ const struct dm_p9_ops *ops = device_get_ops(c->dev);
+
+ if (!ops || !ops->request)
+ return -ENOSYS;
+
+ return ops->request(c->dev, tx, tx_len, rx, rx_len);
+}
+
+static int p9_check_error(struct p9_client *c, int expected_id, const char *step)
+{
+ struct p9_header *rx_hdr = (struct p9_header *)c->rx;
+ u32 ecode;
+
+ if (rx_hdr->id == P9_RLERROR) {
+ ecode = get_unaligned_le32(c->rx + sizeof(struct p9_header));
+ log_err("9P Error: %s failed (ecode=%u)\n", step, ecode);
+ return -ecode;
+ } else if (rx_hdr->id != expected_id) {
+ log_err("9P Error: %s got id %d (expected %d)\n", step, rx_hdr->id, expected_id);
+ return -EIO;
+ }
+ return 0;
+}
+
+int p9_client_version(struct p9_client *c)
+{
+ struct p9_header *hdr;
+ u8 *ptr;
+ u32 server_msize;
+ u16 vlen;
+ int ret;
+
+ if (!c->tx) {
+ c->tx = memalign(ARCH_DMA_MINALIGN, P9_MSIZE);
+ if (!c->tx)
+ return -ENOMEM;
+ }
+ if (!c->rx) {
+ c->rx = memalign(ARCH_DMA_MINALIGN, P9_MSIZE);
+ if (!c->rx) {
+ free(c->tx);
+ c->tx = NULL;
+ return -ENOMEM;
+ }
+ }
+
+ hdr = (struct p9_header *)c->tx;
+ ptr = c->tx + sizeof(*hdr);
+ p9_put_u32(&ptr, P9_MSIZE);
+ p9_put_str(&ptr, "9P2000.L");
+
+ hdr->size = ptr - c->tx;
+ hdr->id = P9_TVERSION;
+ hdr->tag = P9_NOTAG;
+
+ ret = p9_request(c, c->tx, hdr->size, c->rx, P9_MSIZE);
+ if (ret < 0)
+ return ret;
+
+ ret = p9_check_error(c, P9_RVERSION, "Tversion");
+ if (ret < 0)
+ return ret;
+
+ ptr = c->rx + sizeof(*hdr);
+ server_msize = get_unaligned_le32(ptr);
+ ptr += 4;
+ vlen = get_unaligned_le16(ptr);
+ ptr += 2;
+
+ if (vlen != strlen("9P2000.L") || memcmp(ptr, "9P2000.L", vlen) != 0) {
+ log_err("9P: Unsupported server version: %.*s\n", vlen, ptr);
+ return -EPROTONOSUPPORT;
+ }
+
+ c->msize = min((u32)P9_MSIZE, server_msize);
+ return 0;
+}
+
+int p9_client_attach(struct p9_client *c, u32 fid, const char *uname, const char *aname)
+{
+ struct p9_header *hdr = (struct p9_header *)c->tx;
+ u8 *ptr = c->tx + sizeof(*hdr);
+ int ret;
+
+ p9_put_u32(&ptr, fid);
+ p9_put_u32(&ptr, P9_NOFID);
+ p9_put_str(&ptr, uname);
+ p9_put_str(&ptr, aname);
+ p9_put_u32(&ptr, 0);
+
+ hdr->size = ptr - c->tx;
+ hdr->id = P9_TATTACH;
+ hdr->tag = P9_REQ_TAG;
+
+ ret = p9_request(c, c->tx, hdr->size, c->rx, c->msize ? c->msize : P9_MSIZE);
+ if (ret < 0)
+ return ret;
+
+ return p9_check_error(c, P9_RATTACH, "Tattach");
+}
+
+int p9_client_walk(struct p9_client *c, u32 base_fid, u32 new_fid, const char *path)
+{
+ struct p9_header *hdr = (struct p9_header *)c->tx;
+ u8 *ptr = c->tx + sizeof(*hdr);
+ char path_buf[128];
+ char *wnames[16];
+ char *token, *p = path_buf;
+ int nwname = 0, i, ret;
+ u16 nwqid;
+
+ if (strlcpy(path_buf, path, sizeof(path_buf)) >= sizeof(path_buf)) {
+ log_err("9P: Path too long\n");
+ return -ENAMETOOLONG;
+ }
+
+ while ((token = strsep(&p, "/")) != NULL) {
+ if (*token == '\0' || strcmp(token, ".") == 0)
+ continue;
+ if (nwname >= 16) {
+ log_err("9P: Path too deep (max 16 levels)\n");
+ return -EINVAL;
+ }
+ wnames[nwname++] = token;
+ }
+
+ p9_put_u32(&ptr, base_fid);
+ p9_put_u32(&ptr, new_fid);
+ p9_put_u16(&ptr, nwname);
+ for (i = 0; i < nwname; i++)
+ p9_put_str(&ptr, wnames[i]);
+
+ hdr->size = ptr - c->tx;
+ hdr->id = P9_TWALK;
+ hdr->tag = P9_REQ_TAG;
+
+ ret = p9_request(c, c->tx, hdr->size, c->rx, c->msize ? c->msize : P9_MSIZE);
+ if (ret < 0)
+ return ret;
+
+ ret = p9_check_error(c, P9_RWALK, "Twalk");
+ if (ret < 0)
+ return ret;
+
+ ptr = c->rx + sizeof(*hdr);
+ nwqid = get_unaligned_le16(ptr);
+ if (nwqid != nwname)
+ return -ENOENT;
+
+ return 0;
+}
+
+int p9_client_lopen(struct p9_client *c, u32 fid, u32 flags)
+{
+ struct p9_header *hdr = (struct p9_header *)c->tx;
+ u8 *ptr = c->tx + sizeof(*hdr);
+ int ret;
+
+ p9_put_u32(&ptr, fid);
+ p9_put_u32(&ptr, flags);
+
+ hdr->size = ptr - c->tx;
+ hdr->id = P9_TLOPEN;
+ hdr->tag = P9_REQ_TAG;
+
+ ret = p9_request(c, c->tx, hdr->size, c->rx, c->msize ? c->msize : P9_MSIZE);
+ if (ret < 0)
+ return ret;
+
+ return p9_check_error(c, P9_RLOPEN, "Tlopen");
+}
+
+int p9_client_clunk(struct p9_client *c, u32 fid)
+{
+ struct p9_header *hdr = (struct p9_header *)c->tx;
+ u8 *ptr = c->tx + sizeof(*hdr);
+
+ p9_put_u32(&ptr, fid);
+ hdr->size = ptr - c->tx;
+ hdr->id = P9_TCLUNK;
+ hdr->tag = P9_REQ_TAG;
+
+ return p9_request(c, c->tx, hdr->size, c->rx, c->msize ? c->msize : P9_MSIZE);
+}
+
+int p9_client_stat(struct p9_client *c, u32 fid, loff_t *size)
+{
+ struct p9_header *hdr = (struct p9_header *)c->tx;
+ u8 *ptr = c->tx + sizeof(*hdr);
+ u64 valid;
+ int ret;
+
+ p9_put_u32(&ptr, fid);
+ p9_put_u64(&ptr, P9_GETATTR_SIZE);
+
+ hdr->size = ptr - c->tx;
+ hdr->id = P9_TGETATTR;
+ hdr->tag = P9_REQ_TAG;
+
+ ret = p9_request(c, c->tx, hdr->size, c->rx, c->msize ? c->msize : P9_MSIZE);
+ if (ret < 0)
+ return ret;
+
+ ret = p9_check_error(c, P9_RGETATTR, "Tgetattr");
+ if (ret == 0) {
+ ptr = c->rx + sizeof(*hdr);
+ valid = get_unaligned_le64(ptr);
+ ptr += sizeof(valid);
+ ptr += P9_GETATTR_SIZE_OFFSET;
+ if (valid & P9_GETATTR_SIZE) {
+ *size = get_unaligned_le64(ptr);
+ return 0;
+ }
+ }
+ return ret ? ret : -EIO;
+}
+
+int p9_client_read(struct p9_client *c, u32 fid, u64 offset, u32 count, void *buf, u32 *actread)
+{
+ struct p9_header *hdr = (struct p9_header *)c->tx;
+ u8 *ptr = c->tx + sizeof(*hdr);
+ u32 max_read = (c->msize ? c->msize : P9_MSIZE) - 24;
+ u32 read_len = (count == 0 || count > max_read) ? max_read : count;
+ u32 count_rx;
+ int ret;
+
+ p9_put_u32(&ptr, fid);
+ p9_put_u64(&ptr, offset);
+ p9_put_u32(&ptr, read_len);
+
+ hdr->size = ptr - c->tx;
+ hdr->id = P9_TREAD;
+ hdr->tag = P9_REQ_TAG;
+
+ ret = p9_request(c, c->tx, hdr->size, c->rx, c->msize ? c->msize : P9_MSIZE);
+ if (ret < 0)
+ return ret;
+
+ ret = p9_check_error(c, P9_RREAD, "Tread");
+ if (ret < 0)
+ return ret;
+
+ ptr = c->rx + sizeof(*hdr);
+ count_rx = get_unaligned_le32(ptr);
+ ptr += 4;
+ if (count_rx > read_len) {
+ log_err("9P: Tread returned count %u > requested %u\n", count_rx, read_len);
+ return -EIO;
+ }
+
+ *actread = count_rx;
+ memcpy(buf, ptr, count_rx);
+ return 0;
+}
+
+int p9_client_readdir(struct p9_client *c, u32 fid, u64 offset, u32 count, void *buf, u32 *actread)
+{
+ struct p9_header *hdr = (struct p9_header *)c->tx;
+ u8 *ptr = c->tx + sizeof(*hdr);
+ u32 max_read = (c->msize ? c->msize : P9_MSIZE) - 24;
+ u32 read_len = (count == 0 || count > max_read) ? max_read : count;
+ u32 count_rx;
+ int ret;
+
+ p9_put_u32(&ptr, fid);
+ p9_put_u64(&ptr, offset);
+ p9_put_u32(&ptr, read_len);
+
+ hdr->size = ptr - c->tx;
+ hdr->id = P9_TREADDIR;
+ hdr->tag = P9_REQ_TAG;
+
+ ret = p9_request(c, c->tx, hdr->size, c->rx, c->msize ? c->msize : P9_MSIZE);
+ if (ret < 0)
+ return ret;
+
+ ret = p9_check_error(c, P9_RREADDIR, "Treaddir");
+ if (ret < 0)
+ return ret;
+
+ ptr = c->rx + sizeof(*hdr);
+ count_rx = get_unaligned_le32(ptr);
+ ptr += 4;
+ if (count_rx > read_len) {
+ log_err("9P: Treaddir returned count %u > requested %u\n", count_rx, read_len);
+ return -EIO;
+ }
+
+ *actread = count_rx;
+ memcpy(buf, ptr, count_rx);
+ return 0;
+}
diff --git a/net/Kconfig b/net/Kconfig
index 386376ce884..00448ab4cc6 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -236,6 +236,8 @@ endif # if NET_LEGACY
source "net/lwip/Kconfig"
+source "net/9p/Kconfig"
+
config BOOTDEV_ETH
bool "Enable bootdev for ethernet"
depends on BOOTSTD
diff --git a/net/Makefile b/net/Makefile
index ceac6de6377..7745607248b 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -49,3 +49,4 @@ obj-y += net-common.o
endif
obj-$(CONFIG_NET_LWIP) += lwip/
+obj-$(CONFIG_NET_9P) += 9p/
--
2.55.0.897.gb25b4bd76c-goog
next prev parent reply other threads:[~2026-08-29 19:21 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-29 19:21 [PATCH v2 0/6] fs: Add 9P filesystem support over virtio Kuan-Wei Chiu
2026-08-29 19:21 ` Kuan-Wei Chiu [this message]
2026-09-11 11:43 ` [PATCH v2 1/6] net: 9p: Add 9P2000.L protocol support Simon Glass
2026-08-29 19:21 ` [PATCH v2 2/6] fs: 9p: Add 9P filesystem support Kuan-Wei Chiu
2026-09-11 11:43 ` Simon Glass
2026-08-29 19:21 ` [PATCH v2 3/6] virtio: 9p: Add 9P transport driver Kuan-Wei Chiu
2026-09-11 11:43 ` Simon Glass
2026-08-29 19:21 ` [PATCH v2 4/6] doc: 9p: Add 9P filesystem documentation Kuan-Wei Chiu
2026-09-11 11:43 ` Simon Glass
2026-08-29 19:21 ` [PATCH v2 5/6] test: 9p: Add test for 9P filesystem Kuan-Wei Chiu
2026-09-11 11:44 ` Simon Glass
2026-08-29 19:21 ` [PATCH v2 6/6] MAINTAINERS: Add entry for 9PFS Kuan-Wei Chiu
2026-08-30 10:41 ` [PATCH v2 0/6] fs: Add 9P filesystem support over virtio Peter Robinson
2026-09-02 1:51 ` Kuan-Wei Chiu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260829192119.2658328-2-visitorckw@gmail.com \
--to=visitorckw@gmail.com \
--cc=bmeng.cn@gmail.com \
--cc=eleanor15x@gmail.com \
--cc=jerome.forissier@arm.com \
--cc=jserv@ccns.ncku.edu.tw \
--cc=marscheng@google.com \
--cc=sjg@chromium.org \
--cc=trini@konsulko.com \
--cc=tuomas.tynkkynen@iki.fi \
--cc=u-boot@lists.u-boot-project.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.