svn commit: r263273 - stable/9/sys/dev/nvme

Jim Harris jimharris at FreeBSD.org
Mon Mar 17 21:42:32 UTC 2014


Author: jimharris
Date: Mon Mar 17 21:42:31 2014
New Revision: 263273
URL: http://svnweb.freebsd.org/changeset/base/263273

Log:
  MFC r254302:
  
    Send a shutdown notification in the driver unload path, to ensure
    notification gets sent in cases where system shuts down with driver
    unloaded.
  
  Sponsored by:	Intel

Modified:
  stable/9/sys/dev/nvme/nvme.c
  stable/9/sys/dev/nvme/nvme.h
  stable/9/sys/dev/nvme/nvme_ctrlr.c
  stable/9/sys/dev/nvme/nvme_private.h
Directory Properties:
  stable/9/sys/   (props changed)
  stable/9/sys/dev/   (props changed)

Modified: stable/9/sys/dev/nvme/nvme.c
==============================================================================
--- stable/9/sys/dev/nvme/nvme.c	Mon Mar 17 20:42:45 2014	(r263272)
+++ stable/9/sys/dev/nvme/nvme.c	Mon Mar 17 21:42:31 2014	(r263273)
@@ -157,30 +157,14 @@ nvme_shutdown(void)
 {
 	device_t		*devlist;
 	struct nvme_controller	*ctrlr;
-	union cc_register	cc;
-	union csts_register	csts;
 	int			dev, devcount;
 
 	if (devclass_get_devices(nvme_devclass, &devlist, &devcount))
 		return;
 
 	for (dev = 0; dev < devcount; dev++) {
-		/*
-		 * Only notify controller of shutdown when a real shutdown is
-		 *  in process, not when a module unload occurs.  It seems at
-		 *  least some controllers (Chatham at least) don't let you
-		 *  re-enable the controller after shutdown notification has
-		 *  been received.
-		 */
 		ctrlr = DEVICE2SOFTC(devlist[dev]);
-		cc.raw = nvme_mmio_read_4(ctrlr, cc);
-		cc.bits.shn = NVME_SHN_NORMAL;
-		nvme_mmio_write_4(ctrlr, cc, cc.raw);
-		csts.raw = nvme_mmio_read_4(ctrlr, csts);
-		while (csts.bits.shst != NVME_SHST_COMPLETE) {
-			DELAY(5);
-			csts.raw = nvme_mmio_read_4(ctrlr, csts);
-		}
+		nvme_ctrlr_shutdown(ctrlr);
 	}
 
 	free(devlist, M_TEMP);

Modified: stable/9/sys/dev/nvme/nvme.h
==============================================================================
--- stable/9/sys/dev/nvme/nvme.h	Mon Mar 17 20:42:45 2014	(r263272)
+++ stable/9/sys/dev/nvme/nvme.h	Mon Mar 17 21:42:31 2014	(r263273)
@@ -170,27 +170,30 @@ struct nvme_registers
 	union cap_lo_register	cap_lo;
 	union cap_hi_register	cap_hi;
 
-	uint32_t	vs;		/* version */
-	uint32_t	intms;		/* interrupt mask set */
-	uint32_t	intmc;		/* interrupt mask clear */
+	uint32_t		vs;	/* version */
+	uint32_t		intms;	/* interrupt mask set */
+	uint32_t		intmc;	/* interrupt mask clear */
 
 	/** controller configuration */
 	union cc_register	cc;
 
-	uint32_t	reserved1;
-	uint32_t	csts;		/* controller status */
-	uint32_t	reserved2;
+	uint32_t		reserved1;
+
+	/** controller status */
+	union csts_register	csts;
+
+	uint32_t		reserved2;
 
 	/** admin queue attributes */
 	union aqa_register	aqa;
 
-	uint64_t	asq;		/* admin submission queue base addr */
-	uint64_t	acq;		/* admin completion queue base addr */
-	uint32_t	reserved3[0x3f2];
+	uint64_t		asq;	/* admin submission queue base addr */
+	uint64_t		acq;	/* admin completion queue base addr */
+	uint32_t		reserved3[0x3f2];
 
 	struct {
-	    uint32_t	sq_tdbl;	/* submission queue tail doorbell */
-	    uint32_t	cq_hdbl;	/* completion queue head doorbell */
+	    uint32_t		sq_tdbl; /* submission queue tail doorbell */
+	    uint32_t		cq_hdbl; /* completion queue head doorbell */
 	} doorbell[1] __packed;
 } __packed;
 

Modified: stable/9/sys/dev/nvme/nvme_ctrlr.c
==============================================================================
--- stable/9/sys/dev/nvme/nvme_ctrlr.c	Mon Mar 17 20:42:45 2014	(r263272)
+++ stable/9/sys/dev/nvme/nvme_ctrlr.c	Mon Mar 17 21:42:31 2014	(r263273)
@@ -1177,6 +1177,21 @@ nvme_ctrlr_destruct(struct nvme_controll
 {
 	int				i;
 
+	/*
+	 *  Notify the controller of a shutdown, even though this is due to
+	 *   a driver unload, not a system shutdown (this path is not invoked
+	 *   during shutdown).  This ensures the controller receives a
+	 *   shutdown notification in case the system is shutdown before
+	 *   reloading the driver.
+	 *
+	 *  Chatham does not let you re-enable the controller after shutdown
+	 *   notification has been received, so do not send it in this case.
+	 *   This is OK because Chatham does not depend on the shutdown
+	 *   notification anyways.
+	 */
+	if (pci_get_devid(ctrlr->dev) != CHATHAM_PCI_ID)
+		nvme_ctrlr_shutdown(ctrlr);
+
 	nvme_ctrlr_disable(ctrlr);
 	taskqueue_free(ctrlr->taskqueue);
 
@@ -1223,6 +1238,26 @@ nvme_ctrlr_destruct(struct nvme_controll
 }
 
 void
+nvme_ctrlr_shutdown(struct nvme_controller *ctrlr)
+{
+	union cc_register	cc;
+	union csts_register	csts;
+	int			ticks = 0;
+
+	cc.raw = nvme_mmio_read_4(ctrlr, cc);
+	cc.bits.shn = NVME_SHN_NORMAL;
+	nvme_mmio_write_4(ctrlr, cc, cc.raw);
+	csts.raw = nvme_mmio_read_4(ctrlr, csts);
+	while ((csts.bits.shst != NVME_SHST_COMPLETE) && (ticks++ < 5*hz)) {
+		pause("nvme shn", 1);
+		csts.raw = nvme_mmio_read_4(ctrlr, csts);
+	}
+	if (csts.bits.shst != NVME_SHST_COMPLETE)
+		nvme_printf(ctrlr, "did not complete shutdown within 5 seconds "
+		    "of notification\n");
+}
+
+void
 nvme_ctrlr_submit_admin_request(struct nvme_controller *ctrlr,
     struct nvme_request *req)
 {

Modified: stable/9/sys/dev/nvme/nvme_private.h
==============================================================================
--- stable/9/sys/dev/nvme/nvme_private.h	Mon Mar 17 20:42:45 2014	(r263272)
+++ stable/9/sys/dev/nvme/nvme_private.h	Mon Mar 17 21:42:31 2014	(r263273)
@@ -437,6 +437,7 @@ void	nvme_completion_poll_cb(void *arg, 
 
 int	nvme_ctrlr_construct(struct nvme_controller *ctrlr, device_t dev);
 void	nvme_ctrlr_destruct(struct nvme_controller *ctrlr, device_t dev);
+void	nvme_ctrlr_shutdown(struct nvme_controller *ctrlr);
 int	nvme_ctrlr_hw_reset(struct nvme_controller *ctrlr);
 void	nvme_ctrlr_reset(struct nvme_controller *ctrlr);
 /* ctrlr defined as void * to allow use with config_intrhook. */


More information about the svn-src-stable-9 mailing list