svn commit: r328680 - in stable/11/sys: cam cam/scsi dev/nvme kern

Alexander Motin mav at FreeBSD.org
Thu Feb 1 16:35:41 UTC 2018


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);


More information about the svn-src-all mailing list