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 <ch...@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);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to