Date: Fri, 14 Jul 2017 14:52:20 +0000 (UTC) From: Warner Losh <imp@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r320984 - in head/sys: cam cam/scsi dev/nvme kern Message-ID: <201707141452.v6EEqKQE017932@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: imp Date: Fri Jul 14 14:52:20 2017 New Revision: 320984 URL: https://svnweb.freebsd.org/changeset/base/320984 Log: This adds CAM pass(4) support for NVMe IO's. Applications indicate the IO type (Admin or NVM) using XPT op-codes XPT_NVME_ADMIN or XPT_NVME_IO. Submitted by: Chuck Tuffli <chuck@tuffli.net> Differential Revision: https://reviews.freebsd.org/D10247 Modified: head/sys/cam/cam_ccb.h head/sys/cam/cam_periph.c head/sys/cam/cam_xpt.c head/sys/cam/scsi/scsi_pass.c head/sys/dev/nvme/nvme_sim.c head/sys/kern/subr_bus_dma.c Modified: head/sys/cam/cam_ccb.h ============================================================================== --- head/sys/cam/cam_ccb.h Fri Jul 14 14:51:28 2017 (r320983) +++ head/sys/cam/cam_ccb.h Fri Jul 14 14:52:20 2017 (r320984) @@ -207,7 +207,7 @@ typedef enum { /* Serial Management Protocol */ XPT_NVME_IO = 0x1c | XPT_FC_DEV_QUEUED, - /* Execiute the requestred NVMe I/O operation */ + /* Execute the requested NVMe I/O operation */ XPT_MMC_IO = 0x1d | XPT_FC_DEV_QUEUED, /* Placeholder for MMC / SD / SDIO I/O stuff */ @@ -216,6 +216,9 @@ typedef enum { | XPT_FC_XPT_ONLY, /* Scan Target */ + XPT_NVME_ADMIN = 0x1f | XPT_FC_DEV_QUEUED, + /* Execute the requested NVMe Admin operation */ + /* HBA engine commands 0x20->0x2F */ XPT_ENG_INQ = 0x20 | XPT_FC_XPT_ONLY, /* HBA engine feature inquiry */ @@ -819,7 +822,7 @@ struct ccb_relsim { }; /* - * NVMe I/O Request CCB used for the XPT_NVME_IO function code. + * NVMe I/O Request CCB used for the XPT_NVME_IO and XPT_NVME_ADMIN function codes. */ struct ccb_nvmeio { struct ccb_hdr ccb_h; @@ -1508,6 +1511,21 @@ cam_fill_nvmeio(struct ccb_nvmeio *nvmeio, u_int32_t r u_int32_t timeout) { nvmeio->ccb_h.func_code = XPT_NVME_IO; + nvmeio->ccb_h.flags = flags; + nvmeio->ccb_h.retry_count = retries; + nvmeio->ccb_h.cbfcnp = cbfcnp; + nvmeio->ccb_h.timeout = timeout; + nvmeio->data_ptr = data_ptr; + nvmeio->dxfer_len = dxfer_len; +} + +static __inline void +cam_fill_nvmeadmin(struct ccb_nvmeio *nvmeio, u_int32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), + u_int32_t flags, u_int8_t *data_ptr, u_int32_t dxfer_len, + u_int32_t timeout) +{ + nvmeio->ccb_h.func_code = XPT_NVME_ADMIN; nvmeio->ccb_h.flags = flags; nvmeio->ccb_h.retry_count = retries; nvmeio->ccb_h.cbfcnp = cbfcnp; Modified: head/sys/cam/cam_periph.c ============================================================================== --- head/sys/cam/cam_periph.c Fri Jul 14 14:51:28 2017 (r320983) +++ head/sys/cam/cam_periph.c Fri Jul 14 14:52:20 2017 (r320984) @@ -848,6 +848,17 @@ cam_periph_mapmem(union ccb *ccb, struct cam_periph_ma dirs[1] = CAM_DIR_IN; numbufs = 2; break; + case XPT_NVME_IO: + case XPT_NVME_ADMIN: + if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE) + return (0); + if ((ccb->ccb_h.flags & CAM_DATA_MASK) != CAM_DATA_VADDR) + return (EINVAL); + data_ptrs[0] = &ccb->nvmeio.data_ptr; + lengths[0] = ccb->nvmeio.dxfer_len; + dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK; + numbufs = 1; + break; case XPT_DEV_ADVINFO: if (ccb->cdai.bufsiz == 0) return (0); @@ -1013,6 +1024,11 @@ cam_periph_unmapmem(union ccb *ccb, struct cam_periph_ case XPT_DEV_ADVINFO: numbufs = min(mapinfo->num_bufs_used, 1); data_ptrs[0] = (uint8_t **)&ccb->cdai.buf; + break; + case XPT_NVME_IO: + case XPT_NVME_ADMIN: + data_ptrs[0] = &ccb->nvmeio.data_ptr; + numbufs = min(mapinfo->num_bufs_used, 1); break; default: /* allow ourselves to be swapped once again */ Modified: head/sys/cam/cam_xpt.c ============================================================================== --- head/sys/cam/cam_xpt.c Fri Jul 14 14:51:28 2017 (r320983) +++ head/sys/cam/cam_xpt.c Fri Jul 14 14:52:20 2017 (r320984) @@ -2689,9 +2689,9 @@ xpt_action_default(union ccb *start_ccb) start_ccb->ataio.resid = 0; /* FALLTHROUGH */ case XPT_NVME_IO: - if (start_ccb->ccb_h.func_code == XPT_NVME_IO) - start_ccb->nvmeio.resid = 0; /* FALLTHROUGH */ + case XPT_NVME_ADMIN: + /* FALLTHROUGH */ case XPT_MMC_IO: /* XXX just like nmve_io? */ case XPT_RESET_DEV: @@ -5548,6 +5548,7 @@ static struct kv map[] = { { XPT_MMC_IO, "XPT_MMC_IO" }, { XPT_SMP_IO, "XPT_SMP_IO" }, { XPT_SCAN_TGT, "XPT_SCAN_TGT" }, + { XPT_NVME_ADMIN, "XPT_NVME_ADMIN" }, { XPT_ENG_INQ, "XPT_ENG_INQ" }, { XPT_ENG_EXEC, "XPT_ENG_EXEC" }, { XPT_EN_LUN, "XPT_EN_LUN" }, Modified: head/sys/cam/scsi/scsi_pass.c ============================================================================== --- head/sys/cam/scsi/scsi_pass.c Fri Jul 14 14:51:28 2017 (r320983) +++ head/sys/cam/scsi/scsi_pass.c Fri Jul 14 14:52:20 2017 (r320984) @@ -1146,6 +1146,11 @@ passiocleanup(struct pass_softc *softc, struct pass_io numbufs = min(io_req->num_bufs, 1); data_ptrs[0] = (uint8_t **)&ccb->cdai.buf; break; + case XPT_NVME_IO: + case XPT_NVME_ADMIN: + data_ptrs[0] = &ccb->nvmeio.data_ptr; + numbufs = min(io_req->num_bufs, 1); + break; default: /* allow ourselves to be swapped once again */ return; @@ -1384,6 +1389,25 @@ passmemsetup(struct cam_periph *periph, struct pass_io dirs[0] = CAM_DIR_IN; numbufs = 1; break; + case XPT_NVME_ADMIN: + case XPT_NVME_IO: + if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_NONE) + return (0); + + io_req->data_flags = ccb->ccb_h.flags & CAM_DATA_MASK; + + /* + * We only support a single virtual address for NVMe + */ + if ((ccb->ccb_h.flags & CAM_DATA_MASK) != CAM_DATA_VADDR) + return (EINVAL); + + data_ptrs[0] = &ccb->nvmeio.data_ptr; + lengths[0] = ccb->nvmeio.dxfer_len; + dirs[0] = ccb->ccb_h.flags & CAM_DIR_MASK; + numbufs = 1; + maxmap = softc->maxio; + break; default: return(EINVAL); break; /* NOTREACHED */ @@ -1957,7 +1981,8 @@ passdoioctl(struct cdev *dev, u_long cmd, caddr_t addr */ if ((fc == XPT_SCSI_IO) || (fc == XPT_ATA_IO) || (fc == XPT_SMP_IO) || (fc == XPT_DEV_MATCH) - || (fc == XPT_DEV_ADVINFO)) { + || (fc == XPT_DEV_ADVINFO) + || (fc == XPT_NVME_ADMIN) || (fc == XPT_NVME_IO)) { error = passmemsetup(periph, io_req); if (error != 0) goto camioqueue_error; Modified: head/sys/dev/nvme/nvme_sim.c ============================================================================== --- head/sys/dev/nvme/nvme_sim.c Fri Jul 14 14:51:28 2017 (r320983) +++ head/sys/dev/nvme/nvme_sim.c Fri Jul 14 14:52:20 2017 (r320984) @@ -110,7 +110,10 @@ nvme_sim_nvmeio(struct cam_sim *sim, union ccb *ccb) memcpy(&req->cmd, &ccb->nvmeio.cmd, sizeof(ccb->nvmeio.cmd)); - nvme_ctrlr_submit_io_request(ctrlr, req); + if (ccb->ccb_h.func_code == XPT_NVME_IO) + nvme_ctrlr_submit_io_request(ctrlr, req); + else + nvme_ctrlr_submit_admin_request(ctrlr, req); ccb->ccb_h.status |= CAM_SIM_QUEUED; } @@ -225,6 +228,7 @@ nvme_sim_action(struct cam_sim *sim, union ccb *ccb) ccb->ccb_h.status = CAM_REQ_CMP; break; case XPT_NVME_IO: /* Execute the requested I/O operation */ + case XPT_NVME_ADMIN: /* or Admin operation */ nvme_sim_nvmeio(sim, ccb); return; /* no done */ default: Modified: head/sys/kern/subr_bus_dma.c ============================================================================== --- head/sys/kern/subr_bus_dma.c Fri Jul 14 14:51:28 2017 (r320983) +++ head/sys/kern/subr_bus_dma.c Fri Jul 14 14:52:20 2017 (r320984) @@ -218,6 +218,16 @@ _bus_dmamap_load_ccb(bus_dma_tag_t dmat, bus_dmamap_t sglist_cnt = 0; break; } + case XPT_NVME_IO: + case XPT_NVME_ADMIN: { + struct ccb_nvmeio *nvmeio; + + nvmeio = &ccb->nvmeio; + data_ptr = nvmeio->data_ptr; + dxfer_len = nvmeio->dxfer_len; + sglist_cnt = 0; + break; + } default: panic("_bus_dmamap_load_ccb: Unsupported func code %d", ccb_h->func_code);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201707141452.v6EEqKQE017932>