Date: Thu, 1 Feb 2018 16:35:40 +0000 (UTC) From: Alexander Motin <mav@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r328680 - in stable/11/sys: cam cam/scsi dev/nvme kern Message-ID: <201802011635.w11GZeo0020898@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mav Date: Thu Feb 1 16:35:40 2018 New Revision: 328680 URL: https://svnweb.freebsd.org/changeset/base/328680 Log: MFC r320984 (by imp): 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. Modified: stable/11/sys/cam/cam_ccb.h stable/11/sys/cam/cam_periph.c stable/11/sys/cam/cam_xpt.c stable/11/sys/cam/scsi/scsi_pass.c stable/11/sys/dev/nvme/nvme_sim.c stable/11/sys/kern/subr_bus_dma.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/cam/cam_ccb.h ============================================================================== --- stable/11/sys/cam/cam_ccb.h Thu Feb 1 16:33:15 2018 (r328679) +++ stable/11/sys/cam/cam_ccb.h Thu Feb 1 16:35:40 2018 (r328680) @@ -206,7 +206,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_MMCSD_IO = 0x1d | XPT_FC_DEV_QUEUED, /* Placeholder for MMC / SD / SDIO I/O stuff */ @@ -215,6 +215,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 */ @@ -801,7 +804,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; @@ -1429,6 +1432,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: stable/11/sys/cam/cam_periph.c ============================================================================== --- stable/11/sys/cam/cam_periph.c Thu Feb 1 16:33:15 2018 (r328679) +++ stable/11/sys/cam/cam_periph.c Thu Feb 1 16:35:40 2018 (r328680) @@ -829,6 +829,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); @@ -994,6 +1005,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: stable/11/sys/cam/cam_xpt.c ============================================================================== --- stable/11/sys/cam/cam_xpt.c Thu Feb 1 16:33:15 2018 (r328679) +++ stable/11/sys/cam/cam_xpt.c Thu Feb 1 16:35:40 2018 (r328680) @@ -2545,9 +2545,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_RESET_DEV: case XPT_ENG_EXEC: case XPT_SMP_IO: @@ -5412,6 +5412,7 @@ static struct kv map[] = { { XPT_MMCSD_IO, "XPT_MMCSD_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: stable/11/sys/cam/scsi/scsi_pass.c ============================================================================== --- stable/11/sys/cam/scsi/scsi_pass.c Thu Feb 1 16:33:15 2018 (r328679) +++ stable/11/sys/cam/scsi/scsi_pass.c Thu Feb 1 16:35:40 2018 (r328680) @@ -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 */ @@ -1943,7 +1967,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) { uma_zfree(softc->pass_zone, io_req); Modified: stable/11/sys/dev/nvme/nvme_sim.c ============================================================================== --- stable/11/sys/dev/nvme/nvme_sim.c Thu Feb 1 16:33:15 2018 (r328679) +++ stable/11/sys/dev/nvme/nvme_sim.c Thu Feb 1 16:35:40 2018 (r328680) @@ -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; } @@ -233,6 +236,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: stable/11/sys/kern/subr_bus_dma.c ============================================================================== --- stable/11/sys/kern/subr_bus_dma.c Thu Feb 1 16:33:15 2018 (r328679) +++ stable/11/sys/kern/subr_bus_dma.c Thu Feb 1 16:35:40 2018 (r328680) @@ -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?201802011635.w11GZeo0020898>