nvme_sim.c revision 335138
1303126Simp/*- 2303126Simp * Copyright (c) 2016 Netflix, Inc 3303126Simp * All rights reserved. 4303126Simp * 5303126Simp * Redistribution and use in source and binary forms, with or without 6303126Simp * modification, are permitted provided that the following conditions 7303126Simp * are met: 8303126Simp * 1. Redistributions of source code must retain the above copyright 9303126Simp * notice, this list of conditions and the following disclaimer, 10303126Simp * without modification, immediately at the beginning of the file. 11303126Simp * 2. Redistributions in binary form must reproduce the above copyright 12303126Simp * notice, this list of conditions and the following disclaimer in the 13303126Simp * documentation and/or other materials provided with the distribution. 14303126Simp * 15303126Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16303126Simp * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17303126Simp * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18303126Simp * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19303126Simp * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20303126Simp * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21303126Simp * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22303126Simp * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23303126Simp * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24303126Simp * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25303126Simp */ 26303126Simp 27303126Simp#include <sys/cdefs.h> 28303126Simp__FBSDID("$FreeBSD: stable/11/sys/dev/nvme/nvme_sim.c 335138 2018-06-14 14:46:20Z mav $"); 29303126Simp 30303126Simp#include <sys/param.h> 31303126Simp#include <sys/systm.h> 32303126Simp#include <sys/buf.h> 33303126Simp#include <sys/bus.h> 34303126Simp#include <sys/conf.h> 35303126Simp#include <sys/ioccom.h> 36303126Simp#include <sys/malloc.h> 37303126Simp#include <sys/proc.h> 38303126Simp#include <sys/smp.h> 39303126Simp 40303126Simp#include <cam/cam.h> 41303126Simp#include <cam/cam_ccb.h> 42303126Simp#include <cam/cam_sim.h> 43303126Simp#include <cam/cam_xpt_sim.h> 44303126Simp#include <cam/cam_xpt_internal.h> // Yes, this is wrong. 45303126Simp#include <cam/cam_debug.h> 46303126Simp 47328751Smav#include <dev/pci/pcivar.h> 48328751Smav#include <dev/pci/pcireg.h> 49328751Smav 50303126Simp#include "nvme_private.h" 51303126Simp 52303126Simp#define ccb_accb_ptr spriv_ptr0 53303126Simp#define ccb_ctrlr_ptr spriv_ptr1 54303126Simpstatic void nvme_sim_action(struct cam_sim *sim, union ccb *ccb); 55303126Simpstatic void nvme_sim_poll(struct cam_sim *sim); 56303126Simp 57303126Simp#define sim2softc(sim) ((struct nvme_sim_softc *)cam_sim_softc(sim)) 58303126Simp#define sim2ns(sim) (sim2softc(sim)->s_ns) 59303126Simp#define sim2ctrlr(sim) (sim2softc(sim)->s_ctrlr) 60303126Simp 61303126Simpstruct nvme_sim_softc 62303126Simp{ 63303126Simp struct nvme_controller *s_ctrlr; 64303126Simp struct nvme_namespace *s_ns; 65303126Simp struct cam_sim *s_sim; 66303126Simp struct cam_path *s_path; 67303126Simp}; 68303126Simp 69303126Simpstatic void 70303126Simpnvme_sim_nvmeio_done(void *ccb_arg, const struct nvme_completion *cpl) 71303126Simp{ 72303126Simp union ccb *ccb = (union ccb *)ccb_arg; 73303126Simp 74303126Simp /* 75303126Simp * Let the periph know the completion, and let it sort out what 76303126Simp * it means. Make our best guess, though for the status code. 77303126Simp */ 78303126Simp memcpy(&ccb->nvmeio.cpl, cpl, sizeof(*cpl)); 79328699Smav if (nvme_completion_is_error(cpl)) { 80303126Simp ccb->ccb_h.status = CAM_REQ_CMP_ERR; 81328699Smav xpt_done(ccb); 82328699Smav } else { 83303126Simp ccb->ccb_h.status = CAM_REQ_CMP; 84328699Smav xpt_done_direct(ccb); 85328699Smav } 86303126Simp} 87303126Simp 88303126Simpstatic void 89303126Simpnvme_sim_nvmeio(struct cam_sim *sim, union ccb *ccb) 90303126Simp{ 91303126Simp struct ccb_nvmeio *nvmeio = &ccb->nvmeio; 92303126Simp struct nvme_request *req; 93303126Simp void *payload; 94303126Simp uint32_t size; 95303126Simp struct nvme_controller *ctrlr; 96303126Simp 97303126Simp ctrlr = sim2ctrlr(sim); 98303126Simp payload = nvmeio->data_ptr; 99303126Simp size = nvmeio->dxfer_len; 100303126Simp /* SG LIST ??? */ 101303126Simp if ((nvmeio->ccb_h.flags & CAM_DATA_MASK) == CAM_DATA_BIO) 102303126Simp req = nvme_allocate_request_bio((struct bio *)payload, 103303126Simp nvme_sim_nvmeio_done, ccb); 104328696Smav else if ((nvmeio->ccb_h.flags & CAM_DATA_SG) == CAM_DATA_SG) 105328696Smav req = nvme_allocate_request_ccb(ccb, nvme_sim_nvmeio_done, ccb); 106303126Simp else if (payload == NULL) 107303126Simp req = nvme_allocate_request_null(nvme_sim_nvmeio_done, ccb); 108303126Simp else 109303126Simp req = nvme_allocate_request_vaddr(payload, size, 110303126Simp nvme_sim_nvmeio_done, ccb); 111303126Simp 112303126Simp if (req == NULL) { 113303126Simp nvmeio->ccb_h.status = CAM_RESRC_UNAVAIL; 114303126Simp xpt_done(ccb); 115303126Simp return; 116303126Simp } 117303126Simp 118303126Simp memcpy(&req->cmd, &ccb->nvmeio.cmd, sizeof(ccb->nvmeio.cmd)); 119303126Simp 120328680Smav if (ccb->ccb_h.func_code == XPT_NVME_IO) 121328680Smav nvme_ctrlr_submit_io_request(ctrlr, req); 122328680Smav else 123328680Smav nvme_ctrlr_submit_admin_request(ctrlr, req); 124303126Simp 125303126Simp ccb->ccb_h.status |= CAM_SIM_QUEUED; 126303126Simp} 127303126Simp 128303126Simpstatic void 129303126Simpnvme_sim_action(struct cam_sim *sim, union ccb *ccb) 130303126Simp{ 131303126Simp struct nvme_controller *ctrlr; 132303126Simp struct nvme_namespace *ns; 133303126Simp 134303126Simp CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, 135303126Simp ("nvme_sim_action: func= %#x\n", 136303126Simp ccb->ccb_h.func_code)); 137303126Simp 138303126Simp /* 139303126Simp * XXX when we support multiple namespaces in the base driver we'll need 140303126Simp * to revisit how all this gets stored and saved in the periph driver's 141303126Simp * reserved areas. Right now we store all three in the softc of the sim. 142303126Simp */ 143303126Simp ns = sim2ns(sim); 144303126Simp ctrlr = sim2ctrlr(sim); 145303126Simp 146303126Simp mtx_assert(&ctrlr->lock, MA_OWNED); 147303126Simp 148303126Simp switch (ccb->ccb_h.func_code) { 149303126Simp case XPT_CALC_GEOMETRY: /* Calculate Geometry Totally nuts ? XXX */ 150303126Simp /* 151303126Simp * Only meaningful for old-school SCSI disks since only the SCSI 152303126Simp * da driver generates them. Reject all these that slip through. 153303126Simp */ 154303126Simp /*FALLTHROUGH*/ 155303126Simp case XPT_ABORT: /* Abort the specified CCB */ 156303126Simp case XPT_EN_LUN: /* Enable LUN as a target */ 157303126Simp case XPT_TARGET_IO: /* Execute target I/O request */ 158303126Simp case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */ 159303126Simp case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/ 160303126Simp /* 161303126Simp * Only target mode generates these, and only for SCSI. They are 162303126Simp * all invalid/unsupported for NVMe. 163303126Simp */ 164303126Simp ccb->ccb_h.status = CAM_REQ_INVALID; 165303126Simp break; 166303126Simp case XPT_SET_TRAN_SETTINGS: 167303126Simp /* 168303126Simp * NVMe doesn't really have different transfer settings, but 169303126Simp * other parts of CAM think failure here is a big deal. 170303126Simp */ 171303126Simp ccb->ccb_h.status = CAM_REQ_CMP; 172303126Simp break; 173303126Simp case XPT_PATH_INQ: /* Path routing inquiry */ 174303126Simp { 175328750Smav struct ccb_pathinq *cpi = &ccb->cpi; 176328750Smav device_t dev = ctrlr->dev; 177303126Simp 178303126Simp /* 179303126Simp * NVMe may have multiple LUNs on the same path. Current generation 180303126Simp * of NVMe devives support only a single name space. Multiple name 181303126Simp * space drives are coming, but it's unclear how we should report 182303126Simp * them up the stack. 183303126Simp */ 184303126Simp cpi->version_num = 1; 185303126Simp cpi->hba_inquiry = 0; 186303126Simp cpi->target_sprt = 0; 187303126Simp cpi->hba_misc = PIM_UNMAPPED /* | PIM_NOSCAN */; 188303126Simp cpi->hba_eng_cnt = 0; 189303126Simp cpi->max_target = 0; 190303126Simp cpi->max_lun = ctrlr->cdata.nn; 191303126Simp cpi->maxio = nvme_ns_get_max_io_xfer_size(ns); 192303126Simp cpi->initiator_id = 0; 193303126Simp cpi->bus_id = cam_sim_bus(sim); 194303126Simp cpi->base_transfer_speed = 4000000; /* 4 GB/s 4 lanes pcie 3 */ 195303126Simp strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 196303126Simp strncpy(cpi->hba_vid, "NVMe", HBA_IDLEN); 197303126Simp strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 198303126Simp cpi->unit_number = cam_sim_unit(sim); 199335138Smav cpi->transport = XPORT_NVME; /* XXX XPORT_PCIE ? */ 200335138Smav cpi->transport_version = 1; /* XXX Get PCIe spec ? */ 201335138Smav cpi->protocol = PROTO_NVME; 202335138Smav cpi->protocol_version = NVME_REV_1; /* Groks all 1.x NVMe cards */ 203303126Simp cpi->xport_specific.nvme.nsid = ns->id; 204328750Smav cpi->xport_specific.nvme.domain = pci_get_domain(dev); 205328750Smav cpi->xport_specific.nvme.bus = pci_get_bus(dev); 206328750Smav cpi->xport_specific.nvme.slot = pci_get_slot(dev); 207328750Smav cpi->xport_specific.nvme.function = pci_get_function(dev); 208328750Smav cpi->xport_specific.nvme.extra = 0; 209303126Simp cpi->ccb_h.status = CAM_REQ_CMP; 210303126Simp break; 211303126Simp } 212303126Simp case XPT_GET_TRAN_SETTINGS: /* Get transport settings */ 213303126Simp { 214303126Simp struct ccb_trans_settings *cts; 215303126Simp struct ccb_trans_settings_nvme *nvmep; 216303126Simp struct ccb_trans_settings_nvme *nvmex; 217303126Simp 218303126Simp cts = &ccb->cts; 219303126Simp nvmex = &cts->xport_specific.nvme; 220303126Simp nvmep = &cts->proto_specific.nvme; 221303126Simp 222303126Simp nvmex->valid = CTS_NVME_VALID_SPEC; 223303126Simp nvmex->spec_major = 1; /* XXX read from card */ 224303126Simp nvmex->spec_minor = 2; 225303126Simp nvmex->spec_tiny = 0; 226303126Simp 227303126Simp nvmep->valid = CTS_NVME_VALID_SPEC; 228303126Simp nvmep->spec_major = 1; /* XXX read from card */ 229303126Simp nvmep->spec_minor = 2; 230303126Simp nvmep->spec_tiny = 0; 231303126Simp cts->transport = XPORT_NVME; 232303126Simp cts->protocol = PROTO_NVME; 233303126Simp cts->ccb_h.status = CAM_REQ_CMP; 234303126Simp break; 235303126Simp } 236303126Simp case XPT_TERM_IO: /* Terminate the I/O process */ 237303126Simp /* 238303126Simp * every driver handles this, but nothing generates it. Assume 239303126Simp * it's OK to just say 'that worked'. 240303126Simp */ 241303126Simp /*FALLTHROUGH*/ 242303126Simp case XPT_RESET_DEV: /* Bus Device Reset the specified device */ 243303126Simp case XPT_RESET_BUS: /* Reset the specified bus */ 244303126Simp /* 245303126Simp * NVMe doesn't really support physically resetting the bus. It's part 246303126Simp * of the bus scanning dance, so return sucess to tell the process to 247303126Simp * proceed. 248303126Simp */ 249303126Simp ccb->ccb_h.status = CAM_REQ_CMP; 250303126Simp break; 251303126Simp case XPT_NVME_IO: /* Execute the requested I/O operation */ 252328680Smav case XPT_NVME_ADMIN: /* or Admin operation */ 253303126Simp nvme_sim_nvmeio(sim, ccb); 254303126Simp return; /* no done */ 255303126Simp default: 256303126Simp ccb->ccb_h.status = CAM_REQ_INVALID; 257303126Simp break; 258303126Simp } 259303126Simp xpt_done(ccb); 260303126Simp} 261303126Simp 262303126Simpstatic void 263303126Simpnvme_sim_poll(struct cam_sim *sim) 264303126Simp{ 265303126Simp 266328702Smav nvme_ctrlr_poll(sim2ctrlr(sim)); 267303126Simp} 268303126Simp 269303126Simpstatic void * 270303126Simpnvme_sim_new_controller(struct nvme_controller *ctrlr) 271303126Simp{ 272303126Simp struct cam_devq *devq; 273303126Simp int max_trans; 274303126Simp int unit; 275303126Simp struct nvme_sim_softc *sc = NULL; 276303126Simp 277328691Smav max_trans = ctrlr->max_hw_pend_io; 278303126Simp unit = device_get_unit(ctrlr->dev); 279303126Simp devq = cam_simq_alloc(max_trans); 280303126Simp if (devq == NULL) 281303126Simp return NULL; 282303126Simp 283303126Simp sc = malloc(sizeof(*sc), M_NVME, M_ZERO | M_WAITOK); 284303126Simp 285303126Simp sc->s_ctrlr = ctrlr; 286303126Simp 287303126Simp sc->s_sim = cam_sim_alloc(nvme_sim_action, nvme_sim_poll, 288303126Simp "nvme", sc, unit, &ctrlr->lock, max_trans, max_trans, devq); 289303126Simp if (sc->s_sim == NULL) { 290303126Simp printf("Failed to allocate a sim\n"); 291303126Simp cam_simq_free(devq); 292303126Simp free(sc, M_NVME); 293303126Simp return NULL; 294303126Simp } 295303126Simp 296303126Simp return sc; 297303126Simp} 298303126Simp 299303126Simpstatic void 300303126Simpnvme_sim_rescan_target(struct nvme_controller *ctrlr, struct cam_path *path) 301303126Simp{ 302303126Simp union ccb *ccb; 303303126Simp 304303126Simp ccb = xpt_alloc_ccb_nowait(); 305303126Simp if (ccb == NULL) { 306303126Simp printf("unable to alloc CCB for rescan\n"); 307303126Simp return; 308303126Simp } 309303126Simp 310303126Simp if (xpt_clone_path(&ccb->ccb_h.path, path) != CAM_REQ_CMP) { 311303126Simp printf("unable to copy path for rescan\n"); 312303126Simp xpt_free_ccb(ccb); 313303126Simp return; 314303126Simp } 315303126Simp 316303126Simp xpt_rescan(ccb); 317303126Simp} 318303126Simp 319303126Simpstatic void * 320303126Simpnvme_sim_new_ns(struct nvme_namespace *ns, void *sc_arg) 321303126Simp{ 322303126Simp struct nvme_sim_softc *sc = sc_arg; 323303126Simp struct nvme_controller *ctrlr = sc->s_ctrlr; 324303126Simp int i; 325303126Simp 326303126Simp sc->s_ns = ns; 327303126Simp 328303126Simp /* 329303126Simp * XXX this is creating one bus per ns, but it should be one 330303126Simp * XXX target per controller, and one LUN per namespace. 331303126Simp * XXX Current drives only support one NS, so there's time 332303126Simp * XXX to fix it later when new drives arrive. 333303126Simp * 334303126Simp * XXX I'm pretty sure the xpt_bus_register() call below is 335303126Simp * XXX like super lame and it really belongs in the sim_new_ctrlr 336303126Simp * XXX callback. Then the create_path below would be pretty close 337303126Simp * XXX to being right. Except we should be per-ns not per-ctrlr 338303126Simp * XXX data. 339303126Simp */ 340303126Simp 341303126Simp mtx_lock(&ctrlr->lock); 342303126Simp/* Create bus */ 343303126Simp 344303126Simp /* 345303126Simp * XXX do I need to lock ctrlr->lock ? 346303126Simp * XXX do I need to lock the path? 347303126Simp * ata and scsi seem to in their code, but their discovery is 348303126Simp * somewhat more asynchronous. We're only every called one at a 349303126Simp * time, and nothing is in parallel. 350303126Simp */ 351303126Simp 352303126Simp i = 0; 353303126Simp if (xpt_bus_register(sc->s_sim, ctrlr->dev, 0) != CAM_SUCCESS) 354303126Simp goto error; 355303126Simp i++; 356303126Simp if (xpt_create_path(&sc->s_path, /*periph*/NULL, cam_sim_path(sc->s_sim), 357303126Simp 1, ns->id) != CAM_REQ_CMP) 358303126Simp goto error; 359303126Simp i++; 360303126Simp 361303126Simp sc->s_path->device->nvme_data = nvme_ns_get_data(ns); 362303126Simp sc->s_path->device->nvme_cdata = nvme_ctrlr_get_data(ns->ctrlr); 363303126Simp 364303126Simp/* Scan bus */ 365303126Simp nvme_sim_rescan_target(ctrlr, sc->s_path); 366303126Simp 367303126Simp mtx_unlock(&ctrlr->lock); 368303126Simp 369303126Simp return ns; 370303126Simp 371303126Simperror: 372303126Simp switch (i) { 373303126Simp case 2: 374303126Simp xpt_free_path(sc->s_path); 375303126Simp case 1: 376303126Simp xpt_bus_deregister(cam_sim_path(sc->s_sim)); 377303126Simp case 0: 378303126Simp cam_sim_free(sc->s_sim, /*free_devq*/TRUE); 379303126Simp } 380303126Simp mtx_unlock(&ctrlr->lock); 381303126Simp return NULL; 382303126Simp} 383303126Simp 384303126Simpstatic void 385303126Simpnvme_sim_controller_fail(void *ctrlr_arg) 386303126Simp{ 387303126Simp /* XXX cleanup XXX */ 388303126Simp} 389303126Simp 390303126Simpstruct nvme_consumer *consumer_cookie; 391303126Simp 392303126Simpstatic void 393303126Simpnvme_sim_init(void) 394303126Simp{ 395328681Smav if (nvme_use_nvd) 396328681Smav return; 397303126Simp 398303126Simp consumer_cookie = nvme_register_consumer(nvme_sim_new_ns, 399303126Simp nvme_sim_new_controller, NULL, nvme_sim_controller_fail); 400303126Simp} 401303126Simp 402303126SimpSYSINIT(nvme_sim_register, SI_SUB_DRIVERS, SI_ORDER_ANY, 403303126Simp nvme_sim_init, NULL); 404303126Simp 405303126Simpstatic void 406303126Simpnvme_sim_uninit(void) 407303126Simp{ 408328681Smav if (nvme_use_nvd) 409328681Smav return; 410303126Simp /* XXX Cleanup */ 411303126Simp 412303126Simp nvme_unregister_consumer(consumer_cookie); 413303126Simp} 414303126Simp 415303126SimpSYSUNINIT(nvme_sim_unregister, SI_SUB_DRIVERS, SI_ORDER_ANY, 416303126Simp nvme_sim_uninit, NULL); 417