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__ */
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to