Page MenuHomeFreeBSD

D33032.id98634.diff
No OneTemporary

D33032.id98634.diff

Index: sys/cam/nvme/nvme_da.c
===================================================================
--- sys/cam/nvme/nvme_da.c
+++ sys/cam/nvme/nvme_da.c
@@ -642,17 +642,51 @@
cam_periph_lock(periph);
}
+static void
+ndasetgeom(struct nda_softc *softc, struct cam_periph *periph)
+{
+ struct disk *disk = softc->disk;
+ struct ccb_pathinq cpi;
+ const struct nvme_namespace_data *nsd;
+ const struct nvme_controller_data *cd;
+ uint8_t flbas_fmt, lbads, vwc_present;
+
+ nsd = nvme_get_identify_ns(periph);
+ cd = nvme_get_identify_cntrl(periph);
+
+ flbas_fmt = (nsd->flbas >> NVME_NS_DATA_FLBAS_FORMAT_SHIFT) &
+ NVME_NS_DATA_FLBAS_FORMAT_MASK;
+ lbads = (nsd->lbaf[flbas_fmt] >> NVME_NS_DATA_LBAF_LBADS_SHIFT) &
+ NVME_NS_DATA_LBAF_LBADS_MASK;
+ disk->d_sectorsize = 1 << lbads;
+ disk->d_mediasize = (off_t)(disk->d_sectorsize * nsd->nsze);
+ disk->d_delmaxsize = disk->d_mediasize;
+ disk->d_flags = DISKFLAG_DIRECT_COMPLETION;
+ if (nvme_ctrlr_has_dataset_mgmt(cd))
+ disk->d_flags |= DISKFLAG_CANDELETE;
+ vwc_present = (cd->vwc >> NVME_CTRLR_DATA_VWC_PRESENT_SHIFT) &
+ NVME_CTRLR_DATA_VWC_PRESENT_MASK;
+ if (vwc_present)
+ disk->d_flags |= DISKFLAG_CANFLUSHCACHE;
+ if ((cpi.hba_misc & PIM_UNMAPPED) != 0) {
+ disk->d_flags |= DISKFLAG_UNMAPPED_BIO;
+ softc->unmappedio = 1;
+ }
+}
+
static void
ndaasync(void *callback_arg, u_int32_t code,
struct cam_path *path, void *arg)
{
struct cam_periph *periph;
+ struct nda_softc *softc;
+ struct ccb_getdev *cgd;
+ int error;
periph = (struct cam_periph *)callback_arg;
switch (code) {
case AC_FOUND_DEVICE:
{
- struct ccb_getdev *cgd;
cam_status status;
cgd = (struct ccb_getdev *)arg;
@@ -679,15 +713,42 @@
"due to status 0x%x\n", status);
break;
}
+ case AC_GETDEV_CHANGED:
+ {
+ struct disk *disk;
+ char announce_buf[80];
+
+ softc = (struct nda_softc *)periph->softc;
+ cgd = (struct ccb_getdev *)arg;
+ disk = softc->disk;
+
+ /*
+ * Update our information based on the new Identify data.
+ */
+ ndasetgeom(softc, periph);
+ error = disk_resize(disk, M_NOWAIT);
+ if (error != 0) {
+ xpt_print(periph->path, "disk_resize(9) failed, error = %d\n", error);
+ break;
+ }
+
+ snprintf(announce_buf, sizeof(announce_buf),
+ "%juMB (%ju %u byte sectors)",
+ (uintmax_t)((uintmax_t)disk->d_mediasize / (1024*1024)),
+ (uintmax_t)disk->d_mediasize / disk->d_sectorsize,
+ disk->d_sectorsize);
+ xpt_announce_periph(periph, announce_buf);
+
+ cam_periph_async(periph, code, path, arg);
+ break;
+ }
case AC_ADVINFO_CHANGED:
{
uintptr_t buftype;
buftype = (uintptr_t)arg;
if (buftype == CDAI_TYPE_PHYS_PATH) {
- struct nda_softc *softc;
-
- softc = periph->softc;
+ softc = (struct nda_softc *)periph->softc;
disk_attr_changed(softc->disk, "GEOM::physpath",
M_NOWAIT);
}
@@ -845,7 +906,6 @@
const struct nvme_namespace_data *nsd;
const struct nvme_controller_data *cd;
char announce_buf[80];
- uint8_t flbas_fmt, lbads, vwc_present;
u_int maxio;
int quirks;
@@ -892,6 +952,7 @@
softc->quirks = quirks;
cam_iosched_set_sort_queue(softc->cam_iosched, 0);
softc->disk = disk = disk_alloc();
+ ndasetgeom(softc, periph);
disk->d_rotation_rate = DISK_RR_NON_ROTATING;
disk->d_open = ndaopen;
disk->d_close = ndaclose;
@@ -910,24 +971,6 @@
else if (maxio > maxphys)
maxio = maxphys; /* for safety */
disk->d_maxsize = maxio;
- flbas_fmt = (nsd->flbas >> NVME_NS_DATA_FLBAS_FORMAT_SHIFT) &
- NVME_NS_DATA_FLBAS_FORMAT_MASK;
- lbads = (nsd->lbaf[flbas_fmt] >> NVME_NS_DATA_LBAF_LBADS_SHIFT) &
- NVME_NS_DATA_LBAF_LBADS_MASK;
- disk->d_sectorsize = 1 << lbads;
- disk->d_mediasize = (off_t)(disk->d_sectorsize * nsd->nsze);
- disk->d_delmaxsize = disk->d_mediasize;
- disk->d_flags = DISKFLAG_DIRECT_COMPLETION;
- if (nvme_ctrlr_has_dataset_mgmt(cd))
- disk->d_flags |= DISKFLAG_CANDELETE;
- vwc_present = (cd->vwc >> NVME_CTRLR_DATA_VWC_PRESENT_SHIFT) &
- NVME_CTRLR_DATA_VWC_PRESENT_MASK;
- if (vwc_present)
- disk->d_flags |= DISKFLAG_CANFLUSHCACHE;
- if ((cpi.hba_misc & PIM_UNMAPPED) != 0) {
- disk->d_flags |= DISKFLAG_UNMAPPED_BIO;
- softc->unmappedio = 1;
- }
/*
* d_ident and d_descr are both far bigger than the length of either
* the serial or model number strings.
@@ -993,7 +1036,7 @@
* Register for device going away and info about the drive
* changing (though with NVMe, it can't)
*/
- xpt_register_async(AC_LOST_DEVICE | AC_ADVINFO_CHANGED,
+ xpt_register_async(AC_LOST_DEVICE | AC_ADVINFO_CHANGED | AC_GETDEV_CHANGED,
ndaasync, periph, periph->path);
softc->state = NDA_STATE_NORMAL;
Index: sys/dev/nvd/nvd.c
===================================================================
--- sys/dev/nvd/nvd.c
+++ sys/dev/nvd/nvd.c
@@ -65,6 +65,9 @@
static void *nvd_new_disk(struct nvme_namespace *ns, void *ctrlr);
static void *nvd_new_controller(struct nvme_controller *ctrlr);
+static void nvd_controller_async(void *ctrlr_arg,
+ const struct nvme_completion *async_cpl,
+ uint32_t log_page_id, void *log_page_buffer, uint32_t log_page_size);
static void nvd_controller_fail(void *ctrlr);
static int nvd_load(void);
@@ -157,7 +160,7 @@
TAILQ_INIT(&disk_head);
consumer_handle = nvme_register_consumer(nvd_new_disk,
- nvd_new_controller, NULL, nvd_controller_fail);
+ nvd_new_controller, nvd_controller_async, nvd_controller_fail);
return (consumer_handle != NULL ? 0 : -1);
}
@@ -264,6 +267,28 @@
mtx_unlock(&ndisk->bioqlock);
}
+static void
+nvd_resize(struct nvd_disk *ndisk)
+{
+ struct disk *disk = ndisk->disk;
+ struct nvme_namespace *ns = ndisk->ns;
+
+ disk->d_sectorsize = nvme_ns_get_sector_size(ns);
+ disk->d_mediasize = (off_t)nvme_ns_get_size(ns);
+ disk->d_maxsize = nvme_ns_get_max_io_xfer_size(ns);
+ disk->d_delmaxsize = (off_t)nvme_ns_get_size(ns);
+ if (disk->d_delmaxsize > nvd_delete_max)
+ disk->d_delmaxsize = nvd_delete_max;
+
+ disk_resize(disk, M_NOWAIT);
+
+ printf(NVD_STR"%u: NVMe namespace resized\n", ndisk->unit);
+ printf(NVD_STR"%u: %juMB (%ju %u byte sectors)\n", disk->d_unit,
+ (uintmax_t)disk->d_mediasize / (1024*1024),
+ (uintmax_t)disk->d_mediasize / disk->d_sectorsize,
+ disk->d_sectorsize);
+}
+
static void
nvd_gonecb(struct disk *dp)
{
@@ -502,6 +527,18 @@
return (ndisk);
}
+static void
+nvd_controller_async(void *ctrlr_arg, const struct nvme_completion *async_cpl,
+ uint32_t log_page_id, void *log_page_buffer, uint32_t log_page_size)
+{
+ struct nvd_controller *ctrlr = ctrlr_arg;
+ struct nvd_disk *ndisk;
+
+ mtx_lock(&nvd_lock);
+ TAILQ_FOREACH(ndisk, &ctrlr->disk_head, ctrlr_tailq)
+ nvd_resize(ndisk);
+ mtx_unlock(&nvd_lock);
+}
static void
nvd_controller_fail(void *ctrlr_arg)
Index: sys/dev/nvme/nvme.c
===================================================================
--- sys/dev/nvme/nvme.c
+++ sys/dev/nvme/nvme.c
@@ -278,30 +278,6 @@
}
}
-void
-nvme_notify_ns(struct nvme_controller *ctrlr, int nsid)
-{
- struct nvme_consumer *cons;
- struct nvme_namespace *ns;
- void *ctrlr_cookie;
- uint32_t i;
-
- KASSERT(nsid <= NVME_MAX_NAMESPACES,
- ("%s: Namespace notification to nsid %d exceeds range\n",
- device_get_nameunit(ctrlr->dev), nsid));
-
- if (!ctrlr->is_initialized)
- return;
-
- ns = &ctrlr->ns[nsid - 1];
- for (i = 0; i < NVME_MAX_CONSUMERS; i++) {
- cons = &nvme_consumer[i];
- if (cons->id != INVALID_CONSUMER_ID && cons->ns_fn != NULL &&
- (ctrlr_cookie = ctrlr->cons_cookie[i]) != NULL)
- ns->cons_cookie[i] = (*cons->ns_fn)(ns, ctrlr_cookie);
- }
-}
-
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,
Index: sys/dev/nvme/nvme_ctrlr.c
===================================================================
--- sys/dev/nvme/nvme_ctrlr.c
+++ sys/dev/nvme/nvme_ctrlr.c
@@ -682,7 +682,6 @@
{
struct nvme_async_event_request *aer = arg;
struct nvme_health_information_page *health_info;
- struct nvme_ns_list *nsl;
struct nvme_error_information_entry *err;
int i;
@@ -750,14 +749,6 @@
~health_info->critical_warning;
nvme_ctrlr_cmd_set_async_event_config(aer->ctrlr,
aer->ctrlr->async_event_config, NULL, NULL);
- } else if (aer->log_page_id == NVME_LOG_CHANGED_NAMESPACE &&
- !nvme_use_nvd) {
- nsl = (struct nvme_ns_list *)aer->log_page_buffer;
- for (i = 0; i < nitems(nsl->ns) && nsl->ns[i] != 0; i++) {
- if (nsl->ns[i] > NVME_MAX_NAMESPACES)
- break;
- nvme_notify_ns(aer->ctrlr, nsl->ns[i]);
- }
}
/*
Index: sys/dev/nvme/nvme_private.h
===================================================================
--- sys/dev/nvme/nvme_private.h
+++ sys/dev/nvme/nvme_private.h
@@ -569,7 +569,6 @@
uint32_t log_page_size);
void nvme_notify_fail_consumers(struct nvme_controller *ctrlr);
void nvme_notify_new_controller(struct nvme_controller *ctrlr);
-void nvme_notify_ns(struct nvme_controller *ctrlr, int nsid);
void nvme_ctrlr_shared_handler(void *arg);
void nvme_ctrlr_poll(struct nvme_controller *ctrlr);
Index: sys/dev/nvme/nvme_sim.c
===================================================================
--- sys/dev/nvme/nvme_sim.c
+++ sys/dev/nvme/nvme_sim.c
@@ -323,7 +323,7 @@
}
static void *
-nvme_sim_ns_change(struct nvme_namespace *ns, void *sc_arg)
+nvme_sim_new_ns(struct nvme_namespace *ns, void *sc_arg)
{
struct nvme_sim_softc *sc = sc_arg;
union ccb *ccb;
@@ -350,6 +350,21 @@
return (sc_arg);
}
+static void
+nvme_sim_controller_async(void *ctrlr_arg, const struct nvme_completion *async_cpl,
+ uint32_t log_page_id, void *log_page_buffer, uint32_t log_page_size)
+{
+ struct nvme_sim_softc *sc = ctrlr_arg;
+
+ switch (log_page_id) {
+ case NVME_LOG_CHANGED_NAMESPACE:
+ xpt_async(AC_GETDEV_CHANGED, sc->s_path, NULL);
+ break;
+ default:
+ break;
+ }
+}
+
static void
nvme_sim_controller_fail(void *ctrlr_arg)
{
@@ -370,8 +385,8 @@
if (nvme_use_nvd)
return;
- consumer_cookie = nvme_register_consumer(nvme_sim_ns_change,
- nvme_sim_new_controller, NULL, nvme_sim_controller_fail);
+ consumer_cookie = nvme_register_consumer(nvme_sim_new_ns,
+ nvme_sim_new_controller, nvme_sim_controller_async, nvme_sim_controller_fail);
}
SYSINIT(nvme_sim_register, SI_SUB_DRIVERS, SI_ORDER_ANY,

File Metadata

Mime Type
text/plain
Expires
Sat, Apr 18, 7:01 PM (1 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31729978
Default Alt Text
D33032.id98634.diff (10 KB)

Event Timeline