mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-29 12:03:03 +00:00
Add an interface for nvme shim drivers (i.e. nvd) to register for
notifications when new nvme controllers are added to the system. Sponsored by: Intel
This commit is contained in:
parent
0a0b08cc30
commit
038a5ee403
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=248738
@ -45,7 +45,7 @@ struct nvd_disk;
|
||||
static disk_ioctl_t nvd_ioctl;
|
||||
static disk_strategy_t nvd_strategy;
|
||||
|
||||
static void create_geom_disk(void *, struct nvme_namespace *ns);
|
||||
static void *create_geom_disk(struct nvme_namespace *ns, void *ctrlr);
|
||||
static void destroy_geom_disk(struct nvd_disk *ndisk);
|
||||
|
||||
static int nvd_load(void);
|
||||
@ -105,7 +105,7 @@ nvd_load()
|
||||
{
|
||||
|
||||
TAILQ_INIT(&nvd_head);
|
||||
consumer_handle = nvme_register_consumer(create_geom_disk, NULL);
|
||||
consumer_handle = nvme_register_consumer(create_geom_disk, NULL, NULL);
|
||||
|
||||
return (consumer_handle != NULL ? 0 : -1);
|
||||
}
|
||||
@ -233,8 +233,8 @@ nvd_bioq_process(void *arg, int pending)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
create_geom_disk(void *arg, struct nvme_namespace *ns)
|
||||
static void *
|
||||
create_geom_disk(struct nvme_namespace *ns, void *ctrlr)
|
||||
{
|
||||
struct nvd_disk *ndisk;
|
||||
struct disk *disk;
|
||||
@ -287,6 +287,8 @@ create_geom_disk(void *arg, struct nvme_namespace *ns)
|
||||
taskqueue_start_threads(&ndisk->tq, 1, PI_DISK, "nvd taskq");
|
||||
|
||||
TAILQ_INSERT_HEAD(&nvd_head, ndisk, tailq);
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -40,11 +40,14 @@ __FBSDID("$FreeBSD$");
|
||||
#include "nvme_private.h"
|
||||
|
||||
struct nvme_consumer {
|
||||
nvme_consumer_cb_fn_t cb_fn;
|
||||
void *cb_arg;
|
||||
uint32_t id;
|
||||
nvme_cons_ns_fn_t ns_fn;
|
||||
nvme_cons_ctrlr_fn_t ctrlr_fn;
|
||||
nvme_cons_async_fn_t async_fn;
|
||||
};
|
||||
|
||||
struct nvme_consumer nvme_consumer[NVME_MAX_CONSUMERS];
|
||||
#define INVALID_CONSUMER_ID 0xFFFF
|
||||
|
||||
uma_zone_t nvme_request_zone;
|
||||
|
||||
@ -118,8 +121,13 @@ nvme_probe (device_t device)
|
||||
static void
|
||||
nvme_init(void)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
nvme_request_zone = uma_zcreate("nvme_request",
|
||||
sizeof(struct nvme_request), NULL, NULL, NULL, NULL, 0, 0);
|
||||
|
||||
for (i = 0; i < NVME_MAX_CONSUMERS; i++)
|
||||
nvme_consumer[i].id = INVALID_CONSUMER_ID;
|
||||
}
|
||||
|
||||
SYSINIT(nvme_register, SI_SUB_DRIVERS, SI_ORDER_SECOND, nvme_init, NULL);
|
||||
@ -292,26 +300,52 @@ nvme_detach (device_t dev)
|
||||
}
|
||||
|
||||
static void
|
||||
nvme_notify_consumer(struct nvme_consumer *consumer)
|
||||
nvme_notify_consumer(struct nvme_consumer *cons)
|
||||
{
|
||||
device_t *devlist;
|
||||
struct nvme_controller *ctrlr;
|
||||
int dev, ns, devcount;
|
||||
struct nvme_namespace *ns;
|
||||
void *ctrlr_cookie;
|
||||
int dev_idx, ns_idx, devcount;
|
||||
|
||||
if (devclass_get_devices(nvme_devclass, &devlist, &devcount))
|
||||
return;
|
||||
|
||||
for (dev = 0; dev < devcount; dev++) {
|
||||
ctrlr = DEVICE2SOFTC(devlist[dev]);
|
||||
for (ns = 0; ns < ctrlr->cdata.nn; ns++)
|
||||
(*consumer->cb_fn)(consumer->cb_arg, &ctrlr->ns[ns]);
|
||||
for (dev_idx = 0; dev_idx < devcount; dev_idx++) {
|
||||
ctrlr = DEVICE2SOFTC(devlist[dev_idx]);
|
||||
if (cons->ctrlr_fn != NULL)
|
||||
ctrlr_cookie = (*cons->ctrlr_fn)(ctrlr);
|
||||
else
|
||||
ctrlr_cookie = NULL;
|
||||
ctrlr->cons_cookie[cons->id] = ctrlr_cookie;
|
||||
for (ns_idx = 0; ns_idx < ctrlr->cdata.nn; ns_idx++) {
|
||||
ns = &ctrlr->ns[ns_idx];
|
||||
if (cons->ns_fn != NULL)
|
||||
ns->cons_cookie[cons->id] =
|
||||
(*cons->ns_fn)(ns, ctrlr_cookie);
|
||||
}
|
||||
}
|
||||
|
||||
free(devlist, M_TEMP);
|
||||
}
|
||||
|
||||
void
|
||||
nvme_notify_async_consumers(struct nvme_controller *ctrlr,
|
||||
const struct nvme_completion *async_cpl)
|
||||
{
|
||||
struct nvme_consumer *cons;
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < NVME_MAX_CONSUMERS; i++) {
|
||||
cons = &nvme_consumer[i];
|
||||
if (cons->id != INVALID_CONSUMER_ID && cons->async_fn != NULL)
|
||||
(*cons->async_fn)(ctrlr->cons_cookie[i], async_cpl);
|
||||
}
|
||||
}
|
||||
|
||||
struct nvme_consumer *
|
||||
nvme_register_consumer(nvme_consumer_cb_fn_t cb_fn, void *cb_arg)
|
||||
nvme_register_consumer(nvme_cons_ns_fn_t ns_fn, nvme_cons_ctrlr_fn_t ctrlr_fn,
|
||||
nvme_cons_async_fn_t async_fn)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -320,9 +354,11 @@ nvme_register_consumer(nvme_consumer_cb_fn_t cb_fn, void *cb_arg)
|
||||
* right now since we only have one nvme consumer - nvd(4).
|
||||
*/
|
||||
for (i = 0; i < NVME_MAX_CONSUMERS; i++)
|
||||
if (nvme_consumer[i].cb_fn == NULL) {
|
||||
nvme_consumer[i].cb_fn = cb_fn;
|
||||
nvme_consumer[i].cb_arg = cb_arg;
|
||||
if (nvme_consumer[i].id == INVALID_CONSUMER_ID) {
|
||||
nvme_consumer[i].id = i;
|
||||
nvme_consumer[i].ns_fn = ns_fn;
|
||||
nvme_consumer[i].ctrlr_fn = ctrlr_fn;
|
||||
nvme_consumer[i].async_fn = async_fn;
|
||||
|
||||
nvme_notify_consumer(&nvme_consumer[i]);
|
||||
return (&nvme_consumer[i]);
|
||||
@ -336,7 +372,6 @@ void
|
||||
nvme_unregister_consumer(struct nvme_consumer *consumer)
|
||||
{
|
||||
|
||||
consumer->cb_fn = NULL;
|
||||
consumer->cb_arg = NULL;
|
||||
consumer->id = INVALID_CONSUMER_ID;
|
||||
}
|
||||
|
||||
|
@ -690,10 +690,14 @@ enum nvme_io_test_flags {
|
||||
struct bio;
|
||||
|
||||
struct nvme_namespace;
|
||||
struct nvme_controller;
|
||||
struct nvme_consumer;
|
||||
|
||||
typedef void (*nvme_cb_fn_t)(void *, const struct nvme_completion *);
|
||||
typedef void (*nvme_consumer_cb_fn_t)(void *, struct nvme_namespace *);
|
||||
|
||||
typedef void *(*nvme_cons_ns_fn_t)(struct nvme_namespace *, void *);
|
||||
typedef void *(*nvme_cons_ctrlr_fn_t)(struct nvme_controller *);
|
||||
typedef void (*nvme_cons_async_fn_t)(void *, const struct nvme_completion *);
|
||||
|
||||
enum nvme_namespace_flags {
|
||||
NVME_NS_DEALLOCATE_SUPPORTED = 0x1,
|
||||
@ -714,10 +718,14 @@ int nvme_ns_cmd_flush(struct nvme_namespace *ns, nvme_cb_fn_t cb_fn,
|
||||
void *cb_arg);
|
||||
|
||||
/* Registration functions */
|
||||
struct nvme_consumer * nvme_register_consumer(nvme_consumer_cb_fn_t cb_fn,
|
||||
void *cb_arg);
|
||||
struct nvme_consumer * nvme_register_consumer(nvme_cons_ns_fn_t ns_fn,
|
||||
nvme_cons_ctrlr_fn_t ctrlr_fn,
|
||||
nvme_cons_async_fn_t async_fn);
|
||||
void nvme_unregister_consumer(struct nvme_consumer *consumer);
|
||||
|
||||
/* Controller helper functions */
|
||||
device_t nvme_ctrlr_get_device(struct nvme_controller *ctrlr);
|
||||
|
||||
/* Namespace helper functions */
|
||||
uint32_t nvme_ns_get_max_io_xfer_size(struct nvme_namespace *ns);
|
||||
uint32_t nvme_ns_get_sector_size(struct nvme_namespace *ns);
|
||||
|
@ -551,6 +551,8 @@ nvme_ctrlr_async_event_cb(void *arg, const struct nvme_completion *cpl)
|
||||
return;
|
||||
}
|
||||
|
||||
nvme_notify_async_consumers(aer->ctrlr, cpl);
|
||||
|
||||
/* TODO: decode async event type based on status */
|
||||
|
||||
/*
|
||||
@ -909,3 +911,10 @@ nvme_ctrlr_submit_io_request(struct nvme_controller *ctrlr,
|
||||
|
||||
nvme_qpair_submit_request(qpair, req);
|
||||
}
|
||||
|
||||
device_t
|
||||
nvme_ctrlr_get_device(struct nvme_controller *ctrlr)
|
||||
{
|
||||
|
||||
return (ctrlr->dev);
|
||||
}
|
||||
|
@ -190,6 +190,7 @@ struct nvme_namespace {
|
||||
uint16_t id;
|
||||
uint16_t flags;
|
||||
struct cdev *cdev;
|
||||
void *cons_cookie[NVME_MAX_CONSUMERS];
|
||||
};
|
||||
|
||||
/*
|
||||
@ -264,6 +265,8 @@ struct nvme_controller {
|
||||
uint32_t num_aers;
|
||||
struct nvme_async_event_request aer[NVME_MAX_ASYNC_EVENTS];
|
||||
|
||||
void *cons_cookie[NVME_MAX_CONSUMERS];
|
||||
|
||||
#ifdef CHATHAM2
|
||||
uint64_t chatham_size;
|
||||
uint64_t chatham_lbas;
|
||||
@ -446,4 +449,7 @@ nvme_allocate_request_uio(struct uio *uio, nvme_cb_fn_t cb_fn, void *cb_arg)
|
||||
|
||||
#define nvme_free_request(req) uma_zfree(nvme_request_zone, req)
|
||||
|
||||
void nvme_notify_async_consumers(struct nvme_controller *ctrlr,
|
||||
const struct nvme_completion *async_cpl);
|
||||
|
||||
#endif /* __NVME_PRIVATE_H__ */
|
||||
|
Loading…
Reference in New Issue
Block a user