mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-10-28 11:25:21 +01:00
ufshci: add a control device node
The driver only exposed a CAM SIM. Userland had no way to reach the device for anything that is not a SCSI command, so reading a descriptor or an attribute was impossible. Add /dev/ufshci%d as a root only node and the ioctl ABI header for it. The node answers no ioctl yet. The header pulls in ufshci.h, which declares bool only under _KERNEL, so include stdbool.h for userland the way nvme.h already does. Reviewed by: imp (mentor) Sponsored by: Samsung Electronics Differential Revision: https://reviews.freebsd.org/D59558
This commit is contained in:
1 parent
d3e5082ce4
commit
28fefc441e
6 files changed
+137
No files matched your search
@@ -9,6 +9,9 @@
|
||||
#define __UFSHCI_H__
|
||||
|
||||
#include <sys/param.h>
|
||||
#ifndef _KERNEL
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
#include <sys/endian.h>
|
||||
|
||||
/*
|
||||
|
||||
@@ -459,12 +459,18 @@ ufshci_ctrlr_construct(struct ufshci_controller *ctrlr, device_t dev)
|
||||
|
||||
TASK_INIT(&ctrlr->reset_task, 0, ufshci_ctrlr_reset_task, ctrlr);
|
||||
|
||||
error = ufshci_ioctl_construct(ctrlr, dev);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
ufshci_ctrlr_destruct(struct ufshci_controller *ctrlr, device_t dev)
|
||||
{
|
||||
ufshci_ioctl_destruct(ctrlr);
|
||||
|
||||
if (ctrlr->resource == NULL)
|
||||
goto nores;
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*-
|
||||
* Copyright (c) 2026, Samsung Electronics Co., Ltd.
|
||||
* Written by Jaeyoon Choi
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/ioccom.h>
|
||||
|
||||
#include "ufshci_private.h"
|
||||
#include "ufshci_ioctl.h"
|
||||
|
||||
static d_ioctl_t ufshci_ioctl;
|
||||
|
||||
static struct cdevsw ufshci_cdevsw = {
|
||||
.d_version = D_VERSION,
|
||||
.d_ioctl = ufshci_ioctl,
|
||||
.d_name = "ufshci",
|
||||
};
|
||||
|
||||
static int
|
||||
ufshci_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int flag,
|
||||
struct thread *td)
|
||||
{
|
||||
switch (cmd) {
|
||||
default:
|
||||
return (ENOTTY);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ufshci_ioctl_construct(struct ufshci_controller *ctrlr, device_t dev)
|
||||
{
|
||||
struct make_dev_args md_args;
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Set si_drv1 as the node is created. A separate assignment after
|
||||
* make_dev leaves a window where an open that races the attach finds
|
||||
* it unset.
|
||||
*/
|
||||
make_dev_args_init(&md_args);
|
||||
md_args.mda_devsw = &ufshci_cdevsw;
|
||||
md_args.mda_uid = UID_ROOT;
|
||||
md_args.mda_gid = GID_WHEEL;
|
||||
md_args.mda_mode = 0600;
|
||||
md_args.mda_unit = device_get_unit(dev);
|
||||
md_args.mda_si_drv1 = ctrlr;
|
||||
|
||||
error = make_dev_s(&md_args, &ctrlr->cdev, "ufshci%d",
|
||||
device_get_unit(dev));
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
ufshci_ioctl_destruct(struct ufshci_controller *ctrlr)
|
||||
{
|
||||
if (ctrlr->cdev != NULL) {
|
||||
destroy_dev(ctrlr->cdev);
|
||||
ctrlr->cdev = NULL;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*-
|
||||
* Copyright (c) 2026, Samsung Electronics Co., Ltd.
|
||||
* Written by Jaeyoon Choi
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#ifndef __UFSHCI_IOCTL_H__
|
||||
#define __UFSHCI_IOCTL_H__
|
||||
|
||||
#include <sys/ioccom.h>
|
||||
|
||||
#include <dev/ufshci/ufshci.h>
|
||||
|
||||
#define UFSHCI_PT_FLAG_DATA_IN 0x01 /* device -> host */
|
||||
#define UFSHCI_PT_FLAG_DATA_OUT 0x02 /* host -> device */
|
||||
|
||||
/*
|
||||
* Largest data buffer a single passthrough request may carry. A transfer
|
||||
* this long covers 256 pages of 4096 bytes, and one more when the buffer
|
||||
* does not start on a page boundary, which is what the PRDT holds.
|
||||
*/
|
||||
#define UFSHCI_PT_MAX_XFER (1024 * 1024)
|
||||
|
||||
/*
|
||||
* req_upiu and resp_upiu carry the UPIU whole, including its EHS and its
|
||||
* data segment. A query request keeps its descriptor bytes in that data
|
||||
* segment, so such a request leaves buf NULL and len zero.
|
||||
*
|
||||
* buf is the separate buffer a command UPIU moves through the PRDT. Only
|
||||
* a command UPIU uses it.
|
||||
*/
|
||||
struct ufshci_pt_command {
|
||||
struct ufshci_upiu req_upiu; /* [in] */
|
||||
struct ufshci_upiu resp_upiu; /* [out] */
|
||||
void *buf; /* [in] PRDT payload, may be NULL */
|
||||
uint32_t len; /* [in] length of buf */
|
||||
uint32_t flags; /* [in] UFSHCI_PT_FLAG_* */
|
||||
uint32_t timeout_ms; /* [in] 0 means the driver default */
|
||||
uint32_t xfer_len; /* [out] bytes actually moved */
|
||||
uint8_t ocs; /* [out] overall command status */
|
||||
uint8_t reserved[7];
|
||||
};
|
||||
|
||||
struct ufshci_pt_uic_command {
|
||||
struct ufshci_uic_cmd cmd; /* [in/out] opcode and argument1..3 */
|
||||
uint32_t timeout_ms; /* [in] */
|
||||
uint32_t result; /* [out] UICCMDARG2 result code */
|
||||
};
|
||||
|
||||
#define UFSHCI_PASSTHROUGH_CMD _IOWR('u', 0, struct ufshci_pt_command)
|
||||
#define UFSHCI_PASSTHROUGH_UIC _IOWR('u', 1, struct ufshci_pt_uic_command)
|
||||
|
||||
#endif /* __UFSHCI_IOCTL_H__ */
|
||||
@@ -302,6 +302,7 @@ struct ufshci_device {
|
||||
*/
|
||||
struct ufshci_controller {
|
||||
device_t dev;
|
||||
struct cdev *cdev;
|
||||
|
||||
uint32_t quirks;
|
||||
#define UFSHCI_QUIRK_IGNORE_UIC_POWER_MODE \
|
||||
@@ -457,6 +458,11 @@ void ufshci_ctrlr_poll(struct ufshci_controller *ctrlr);
|
||||
|
||||
int ufshci_ctrlr_submit_task_mgmt_request(struct ufshci_controller *ctrlr,
|
||||
struct ufshci_request *req);
|
||||
/* ioctl */
|
||||
int ufshci_ioctl_construct(struct ufshci_controller *ctrlr,
|
||||
device_t dev);
|
||||
void ufshci_ioctl_destruct(struct ufshci_controller *ctrlr);
|
||||
|
||||
int ufshci_ctrlr_submit_transfer_request(struct ufshci_controller *ctrlr,
|
||||
struct ufshci_request *req);
|
||||
int ufshci_ctrlr_send_nop(struct ufshci_controller *ctrlr);
|
||||
|
||||
@@ -12,6 +12,7 @@ SRCS = ufshci.c \
|
||||
ufshci_req_queue.c \
|
||||
ufshci_req_sdb.c \
|
||||
ufshci_sim.c \
|
||||
ufshci_ioctl.c \
|
||||
ufshci_sysctl.c \
|
||||
acpi_if.h \
|
||||
bus_if.h \
|
||||
|
||||
Reference in new issue
Block a user