Pass associated log page data to async event consumers, if requested.
Sponsored by: Intel Reviewed by: carl
This commit is contained in:
parent
894007a2dc
commit
18a3a60fb4
@ -331,7 +331,9 @@ nvme_notify_consumer(struct nvme_consumer *cons)
|
|||||||
|
|
||||||
void
|
void
|
||||||
nvme_notify_async_consumers(struct nvme_controller *ctrlr,
|
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;
|
struct nvme_consumer *cons;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
@ -339,7 +341,8 @@ nvme_notify_async_consumers(struct nvme_controller *ctrlr,
|
|||||||
for (i = 0; i < NVME_MAX_CONSUMERS; i++) {
|
for (i = 0; i < NVME_MAX_CONSUMERS; i++) {
|
||||||
cons = &nvme_consumer[i];
|
cons = &nvme_consumer[i];
|
||||||
if (cons->id != INVALID_CONSUMER_ID && cons->async_fn != NULL)
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -731,7 +731,8 @@ typedef void (*nvme_cb_fn_t)(void *, const struct nvme_completion *);
|
|||||||
|
|
||||||
typedef void *(*nvme_cons_ns_fn_t)(struct nvme_namespace *, void *);
|
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_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 {
|
enum nvme_namespace_flags {
|
||||||
NVME_NS_DEALLOCATE_SUPPORTED = 0x1,
|
NVME_NS_DEALLOCATE_SUPPORTED = 0x1,
|
||||||
|
@ -602,7 +602,21 @@ nvme_ctrlr_async_event_log_page_cb(void *arg, const struct nvme_completion *cpl)
|
|||||||
{
|
{
|
||||||
struct nvme_async_event_request *aer = arg;
|
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
|
* 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)
|
nvme_ctrlr_async_event_cb(void *arg, const struct nvme_completion *cpl)
|
||||||
{
|
{
|
||||||
struct nvme_async_event_request *aer = arg;
|
struct nvme_async_event_request *aer = arg;
|
||||||
uint8_t log_page_id;
|
|
||||||
|
|
||||||
if (cpl->status.sc == NVME_SC_ABORTED_SQ_DELETION) {
|
if (cpl->status.sc == NVME_SC_ABORTED_SQ_DELETION) {
|
||||||
/*
|
/*
|
||||||
@ -630,19 +643,20 @@ nvme_ctrlr_async_event_cb(void *arg, const struct nvme_completion *cpl)
|
|||||||
printf("Asynchronous event occurred.\n");
|
printf("Asynchronous event occurred.\n");
|
||||||
|
|
||||||
/* Associated log page is in bits 23:16 of completion entry dw0. */
|
/* 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,
|
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));
|
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,
|
NVME_GLOBAL_NAMESPACE_TAG, aer->log_page_buffer,
|
||||||
aer->log_page_size, nvme_ctrlr_async_event_log_page_cb,
|
aer->log_page_size, nvme_ctrlr_async_event_log_page_cb,
|
||||||
aer);
|
aer);
|
||||||
/* Wait to notify consumers until after log page is fetched. */
|
/* Wait to notify consumers until after log page is fetched. */
|
||||||
} else {
|
} 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
|
* Repost another asynchronous event request to replace the one
|
||||||
|
@ -130,6 +130,7 @@ struct nvme_async_event_request {
|
|||||||
struct nvme_controller *ctrlr;
|
struct nvme_controller *ctrlr;
|
||||||
struct nvme_request *req;
|
struct nvme_request *req;
|
||||||
struct nvme_completion cpl;
|
struct nvme_completion cpl;
|
||||||
|
uint32_t log_page_id;
|
||||||
uint32_t log_page_size;
|
uint32_t log_page_size;
|
||||||
uint8_t log_page_buffer[NVME_MAX_AER_LOG_SIZE];
|
uint8_t log_page_buffer[NVME_MAX_AER_LOG_SIZE];
|
||||||
};
|
};
|
||||||
@ -475,6 +476,8 @@ nvme_allocate_request_uio(struct uio *uio, nvme_cb_fn_t cb_fn, void *cb_arg)
|
|||||||
#define nvme_free_request(req) uma_zfree(nvme_request_zone, req)
|
#define nvme_free_request(req) uma_zfree(nvme_request_zone, req)
|
||||||
|
|
||||||
void nvme_notify_async_consumers(struct nvme_controller *ctrlr,
|
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__ */
|
#endif /* __NVME_PRIVATE_H__ */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user