svn commit: r248760 - head/sys/dev/nvme

Jim Harris jimharris at FreeBSD.org
Tue Mar 26 21:08:33 UTC 2013


Author: jimharris
Date: Tue Mar 26 21:08:32 2013
New Revision: 248760
URL: http://svnweb.freebsd.org/changeset/base/248760

Log:
  Pass associated log page data to async event consumers, if requested.
  
  Sponsored by:	Intel
  Reviewed by:	carl

Modified:
  head/sys/dev/nvme/nvme.c
  head/sys/dev/nvme/nvme.h
  head/sys/dev/nvme/nvme_ctrlr.c
  head/sys/dev/nvme/nvme_private.h

Modified: head/sys/dev/nvme/nvme.c
==============================================================================
--- head/sys/dev/nvme/nvme.c	Tue Mar 26 21:05:15 2013	(r248759)
+++ head/sys/dev/nvme/nvme.c	Tue Mar 26 21:08:32 2013	(r248760)
@@ -331,7 +331,9 @@ nvme_notify_consumer(struct nvme_consume
 
 void
 nvme_notify_async_consumers(struct nvme_controller *ctrlr,
-			    const struct nvme_completion *async_cpl)
+			    const struct nvme_completion *async_cpl,
+			    uint32_t log_page_id, void *log_page_buffer,
+			    uint32_t log_page_size)
 {
 	struct nvme_consumer	*cons;
 	uint32_t		i;
@@ -339,7 +341,8 @@ nvme_notify_async_consumers(struct nvme_
 	for (i = 0; i < NVME_MAX_CONSUMERS; i++) {
 		cons = &nvme_consumer[i];
 		if (cons->id != INVALID_CONSUMER_ID && cons->async_fn != NULL)
-			(*cons->async_fn)(ctrlr->cons_cookie[i], async_cpl);
+			(*cons->async_fn)(ctrlr->cons_cookie[i], async_cpl,
+			    log_page_id, log_page_buffer, log_page_size);
 	}
 }
 

Modified: head/sys/dev/nvme/nvme.h
==============================================================================
--- head/sys/dev/nvme/nvme.h	Tue Mar 26 21:05:15 2013	(r248759)
+++ head/sys/dev/nvme/nvme.h	Tue Mar 26 21:08:32 2013	(r248760)
@@ -731,7 +731,8 @@ typedef void (*nvme_cb_fn_t)(void *, con
 
 typedef void *(*nvme_cons_ns_fn_t)(struct nvme_namespace *, void *);
 typedef void *(*nvme_cons_ctrlr_fn_t)(struct nvme_controller *);
-typedef void (*nvme_cons_async_fn_t)(void *, const struct nvme_completion *);
+typedef void (*nvme_cons_async_fn_t)(void *, const struct nvme_completion *,
+				     uint32_t, void *, uint32_t);
 
 enum nvme_namespace_flags {
 	NVME_NS_DEALLOCATE_SUPPORTED	= 0x1,

Modified: head/sys/dev/nvme/nvme_ctrlr.c
==============================================================================
--- head/sys/dev/nvme/nvme_ctrlr.c	Tue Mar 26 21:05:15 2013	(r248759)
+++ head/sys/dev/nvme/nvme_ctrlr.c	Tue Mar 26 21:08:32 2013	(r248760)
@@ -602,7 +602,21 @@ nvme_ctrlr_async_event_log_page_cb(void 
 {
 	struct nvme_async_event_request	*aer = arg;
 
-	nvme_notify_async_consumers(aer->ctrlr, &aer->cpl);
+	/*
+	 * If the log page fetch for some reason completed with an error,
+	 *  don't pass log page data to the consumers.  In practice, this case
+	 *  should never happen.
+	 */
+	if (nvme_completion_is_error(cpl))
+		nvme_notify_async_consumers(aer->ctrlr, &aer->cpl,
+		    aer->log_page_id, NULL, 0);
+	else
+		/*
+		 * Pass the cpl data from the original async event completion,
+		 *  not the log page fetch.
+		 */
+		nvme_notify_async_consumers(aer->ctrlr, &aer->cpl,
+		    aer->log_page_id, aer->log_page_buffer, aer->log_page_size);
 
 	/*
 	 * Repost another asynchronous event request to replace the one
@@ -615,7 +629,6 @@ static void
 nvme_ctrlr_async_event_cb(void *arg, const struct nvme_completion *cpl)
 {
 	struct nvme_async_event_request	*aer = arg;
-	uint8_t				log_page_id;
 
 	if (cpl->status.sc == NVME_SC_ABORTED_SQ_DELETION) {
 		/*
@@ -630,19 +643,20 @@ nvme_ctrlr_async_event_cb(void *arg, con
 	printf("Asynchronous event occurred.\n");
 
 	/* Associated log page is in bits 23:16 of completion entry dw0. */
-	log_page_id = (cpl->cdw0 & 0xFF0000) >> 16;
+	aer->log_page_id = (cpl->cdw0 & 0xFF0000) >> 16;
 
-	if (is_log_page_id_valid(log_page_id)) {
+	if (is_log_page_id_valid(aer->log_page_id)) {
 		aer->log_page_size = nvme_ctrlr_get_log_page_size(aer->ctrlr,
-		    log_page_id);
+		    aer->log_page_id);
 		memcpy(&aer->cpl, cpl, sizeof(*cpl));
-		nvme_ctrlr_cmd_get_log_page(aer->ctrlr, log_page_id,
+		nvme_ctrlr_cmd_get_log_page(aer->ctrlr, aer->log_page_id,
 		    NVME_GLOBAL_NAMESPACE_TAG, aer->log_page_buffer,
 		    aer->log_page_size, nvme_ctrlr_async_event_log_page_cb,
 		    aer);
 		/* Wait to notify consumers until after log page is fetched. */
 	} else {
-		nvme_notify_async_consumers(aer->ctrlr, cpl);
+		nvme_notify_async_consumers(aer->ctrlr, cpl, aer->log_page_id,
+		    NULL, 0);
 
 		/*
 		 * Repost another asynchronous event request to replace the one

Modified: head/sys/dev/nvme/nvme_private.h
==============================================================================
--- head/sys/dev/nvme/nvme_private.h	Tue Mar 26 21:05:15 2013	(r248759)
+++ head/sys/dev/nvme/nvme_private.h	Tue Mar 26 21:08:32 2013	(r248760)
@@ -130,6 +130,7 @@ struct nvme_async_event_request {
 	struct nvme_controller		*ctrlr;
 	struct nvme_request		*req;
 	struct nvme_completion		cpl;
+	uint32_t			log_page_id;
 	uint32_t			log_page_size;
 	uint8_t				log_page_buffer[NVME_MAX_AER_LOG_SIZE];
 };
@@ -475,6 +476,8 @@ nvme_allocate_request_uio(struct uio *ui
 #define nvme_free_request(req)	uma_zfree(nvme_request_zone, req)
 
 void	nvme_notify_async_consumers(struct nvme_controller *ctrlr,
-				    const struct nvme_completion *async_cpl);
+				    const struct nvme_completion *async_cpl,
+				    uint32_t log_page_id, void *log_page_buffer,
+				    uint32_t log_page_size);
 
 #endif /* __NVME_PRIVATE_H__ */


More information about the svn-src-all mailing list