Author: cperciva
Date: Mon Sep 28 00:53:45 2020
New Revision: 366213
URL: https://svnweb.freebsd.org/changeset/base/366213

Log:
  MFS r366179: Make nvmecontrol work with nda like it does with nvd, and
  associated bits.
  
  Approved by:  re (delphij)
  Sponsored by: https://www.patreon.com/cperciva

Modified:
  releng/12.2/sys/cam/cam_ccb.h
  releng/12.2/sys/cam/nvme/nvme_da.c
  releng/12.2/sys/dev/nvme/nvme_sim.c
Directory Properties:
  releng/12.2/   (props changed)

Modified: releng/12.2/sys/cam/cam_ccb.h
==============================================================================
--- releng/12.2/sys/cam/cam_ccb.h       Mon Sep 28 00:52:16 2020        
(r366212)
+++ releng/12.2/sys/cam/cam_ccb.h       Mon Sep 28 00:53:45 2020        
(r366213)
@@ -630,6 +630,7 @@ struct ccb_pathinq_settings_sas {
        u_int32_t bitrate;      /* Mbps */
 };
 
+#define NVME_DEV_NAME_LEN      52
 struct ccb_pathinq_settings_nvme {
        uint32_t nsid;          /* Namespace ID for this path */
        uint32_t domain;
@@ -637,7 +638,10 @@ struct ccb_pathinq_settings_nvme {
        uint8_t  slot;
        uint8_t  function;
        uint8_t  extra;
+       char     dev_name[NVME_DEV_NAME_LEN]; /* nvme controller dev name for 
this device */
 };
+_Static_assert(sizeof(struct ccb_pathinq_settings_nvme) == 64,
+    "ccb_pathinq_settings_nvme too big");
 
 #define        PATHINQ_SETTINGS_SIZE   128
 
@@ -1030,6 +1034,7 @@ struct ccb_trans_settings_nvme 
        uint8_t         speed;          /* PCIe generation for each lane */
        uint8_t         max_lanes;      /* Number of PCIe lanes */
        uint8_t         max_speed;      /* PCIe generation for each lane */
+
 };
 
 #include <cam/mmc/mmc_bus.h>

Modified: releng/12.2/sys/cam/nvme/nvme_da.c
==============================================================================
--- releng/12.2/sys/cam/nvme/nvme_da.c  Mon Sep 28 00:52:16 2020        
(r366212)
+++ releng/12.2/sys/cam/nvme/nvme_da.c  Mon Sep 28 00:53:45 2020        
(r366213)
@@ -88,6 +88,7 @@ typedef enum {
        NDA_CCB_BUFFER_IO       = 0x01,
        NDA_CCB_DUMP            = 0x02,
        NDA_CCB_TRIM            = 0x03,
+       NDA_CCB_PASS            = 0x04,
        NDA_CCB_TYPE_MASK       = 0x0F,
 } nda_ccb_state;
 
@@ -136,6 +137,7 @@ struct nda_trim_request {
 
 /* Need quirk table */
 
+static disk_ioctl_t    ndaioctl;
 static disk_strategy_t ndastrategy;
 static dumper_t        ndadump;
 static periph_init_t   ndainit;
@@ -354,6 +356,91 @@ ndaschedule(struct cam_periph *periph)
        cam_iosched_schedule(softc->cam_iosched, periph);
 }
 
+static int
+ndaioctl(struct disk *dp, u_long cmd, void *data, int fflag,
+    struct thread *td)
+{
+       struct cam_periph *periph;
+       struct nda_softc *softc;
+
+       periph = (struct cam_periph *)dp->d_drv1;
+       softc = (struct nda_softc *)periph->softc;
+
+       switch (cmd) {
+       case NVME_IO_TEST:
+       case NVME_BIO_TEST:
+               /*
+                * These don't map well to the underlying CCBs, so
+                * they are usupported via CAM.
+                */
+               return (ENOTTY);
+       case NVME_GET_NSID:
+       {
+               struct nvme_get_nsid *gnsid = (struct nvme_get_nsid *)data;
+               struct ccb_pathinq cpi;
+
+               xpt_path_inq(&cpi, periph->path);
+               strncpy(gnsid->cdev, cpi.xport_specific.nvme.dev_name,
+                   sizeof(gnsid->cdev));
+               gnsid->nsid = cpi.xport_specific.nvme.nsid;
+               return (0);
+       }
+       case NVME_PASSTHROUGH_CMD:
+       {
+               struct nvme_pt_command *pt;
+               union ccb *ccb;
+               struct cam_periph_map_info mapinfo;
+               u_int maxmap = MAXPHYS; /* XXX is this right */
+               int error;
+
+               /*
+                * Create a NVME_IO CCB to do the passthrough command.
+                */
+               pt = (struct nvme_pt_command *)data;
+               ccb = xpt_alloc_ccb();
+               xpt_setup_ccb(&ccb->ccb_h, periph->path, CAM_PRIORITY_NORMAL);
+               ccb->ccb_state = NDA_CCB_PASS;
+               cam_fill_nvmeio(&ccb->nvmeio,
+                   0,                  /* Retries */
+                   ndadone,
+                   (pt->is_read ? CAM_DIR_IN : CAM_DIR_OUT) | CAM_DATA_VADDR,
+                   pt->buf,
+                   pt->len,
+                   nda_default_timeout * 1000);
+               memcpy(&ccb->nvmeio.cmd, &pt->cmd, sizeof(pt->cmd));
+
+               /*
+                * Wire the user memory in this request for the I/O
+                */
+               memset(&mapinfo, 0, sizeof(mapinfo));
+               error = cam_periph_mapmem(ccb, &mapinfo, maxmap);
+               if (error)
+                       return (error);
+
+               /*
+                * Lock the periph and run the command. XXX do we need
+                * to lock the periph?
+                */
+               cam_periph_lock(periph);
+               cam_periph_runccb(ccb, NULL, CAM_RETRY_SELTO, SF_RETRY_UA | 
SF_NO_PRINT,
+                   NULL);
+               cam_periph_unlock(periph);
+
+               /*
+                * Tear down mapping and return status.
+                */
+               cam_periph_unmapmem(ccb, &mapinfo);
+               cam_periph_lock(periph);
+               error = (ccb->ccb_h.status == CAM_REQ_CMP) ? 0 : EIO;
+               xpt_release_ccb(ccb);
+               return (error);
+       }
+       default:
+               break;
+       }
+       return (ENOTTY);
+}
+
 /*
  * Actually translate the requested transfer into one the physical driver
  * can understand.  The transfer is described by a buf and will include
@@ -735,11 +822,8 @@ ndaregister(struct cam_periph *periph, void *arg)
        /* ident_data parsing */
 
        periph->softc = softc;
-
        softc->quirks = NDA_Q_NONE;
-
        xpt_path_inq(&cpi, periph->path);
-
        TASK_INIT(&softc->sysctl_task, 0, ndasysctlinit, periph);
 
        /*
@@ -763,6 +847,7 @@ ndaregister(struct cam_periph *periph, void *arg)
        disk->d_open = ndaopen;
        disk->d_close = ndaclose;
        disk->d_strategy = ndastrategy;
+       disk->d_ioctl = ndaioctl;
        disk->d_getattr = ndagetattr;
        disk->d_dump = ndadump;
        disk->d_gone = ndadiskgonecb;
@@ -1108,6 +1193,8 @@ ndadone(struct cam_periph *periph, union ccb *done_ccb
        }
        case NDA_CCB_DUMP:
                /* No-op.  We're polling */
+               return;
+       case NDA_CCB_PASS:
                return;
        default:
                break;

Modified: releng/12.2/sys/dev/nvme/nvme_sim.c
==============================================================================
--- releng/12.2/sys/dev/nvme/nvme_sim.c Mon Sep 28 00:52:16 2020        
(r366212)
+++ releng/12.2/sys/dev/nvme/nvme_sim.c Mon Sep 28 00:53:45 2020        
(r366213)
@@ -197,6 +197,8 @@ nvme_sim_action(struct cam_sim *sim, union ccb *ccb)
                cpi->xport_specific.nvme.slot = pci_get_slot(dev);
                cpi->xport_specific.nvme.function = pci_get_function(dev);
                cpi->xport_specific.nvme.extra = 0;
+               strncpy(cpi->xport_specific.nvme.dev_name, 
device_get_nameunit(ctrlr->dev),
+                   sizeof(cpi->xport_specific.nvme.dev_name));
                cpi->ccb_h.status = CAM_REQ_CMP;
                break;
        }
_______________________________________________
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