scsi: mpi3mr: Add Event acknowledgment logic
Add Event acknowledgment logic. Link: https://lore.kernel.org/r/20211220141159.16117-19-sreekanth.reddy@broadcom.com Signed-off-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
c5758fc72b
commit
c1af985d27
|
@ -96,7 +96,11 @@ extern int prot_mask;
|
||||||
#define MPI3MR_HOSTTAG_DEVRMCMD_MAX (MPI3MR_HOSTTAG_DEVRMCMD_MIN + \
|
#define MPI3MR_HOSTTAG_DEVRMCMD_MAX (MPI3MR_HOSTTAG_DEVRMCMD_MIN + \
|
||||||
MPI3MR_NUM_DEVRMCMD - 1)
|
MPI3MR_NUM_DEVRMCMD - 1)
|
||||||
|
|
||||||
#define MPI3MR_INTERNAL_CMDS_RESVD MPI3MR_HOSTTAG_DEVRMCMD_MAX
|
#define MPI3MR_INTERNAL_CMDS_RESVD MPI3MR_HOSTTAG_DEVRMCMD_MAX
|
||||||
|
#define MPI3MR_NUM_EVTACKCMD 4
|
||||||
|
#define MPI3MR_HOSTTAG_EVTACKCMD_MIN (MPI3MR_HOSTTAG_DEVRMCMD_MAX + 1)
|
||||||
|
#define MPI3MR_HOSTTAG_EVTACKCMD_MAX (MPI3MR_HOSTTAG_EVTACKCMD_MIN + \
|
||||||
|
MPI3MR_NUM_EVTACKCMD - 1)
|
||||||
|
|
||||||
/* Reduced resource count definition for crash kernel */
|
/* Reduced resource count definition for crash kernel */
|
||||||
#define MPI3MR_HOST_IOS_KDUMP 128
|
#define MPI3MR_HOST_IOS_KDUMP 128
|
||||||
|
@ -674,11 +678,15 @@ struct scmd_priv {
|
||||||
* @chain_buf_lock: Chain buffer list lock
|
* @chain_buf_lock: Chain buffer list lock
|
||||||
* @host_tm_cmds: Command tracker for task management commands
|
* @host_tm_cmds: Command tracker for task management commands
|
||||||
* @dev_rmhs_cmds: Command tracker for device removal commands
|
* @dev_rmhs_cmds: Command tracker for device removal commands
|
||||||
|
* @evtack_cmds: Command tracker for event ack commands
|
||||||
* @devrem_bitmap_sz: Device removal bitmap size
|
* @devrem_bitmap_sz: Device removal bitmap size
|
||||||
* @devrem_bitmap: Device removal bitmap
|
* @devrem_bitmap: Device removal bitmap
|
||||||
* @dev_handle_bitmap_sz: Device handle bitmap size
|
* @dev_handle_bitmap_sz: Device handle bitmap size
|
||||||
* @removepend_bitmap: Remove pending bitmap
|
* @removepend_bitmap: Remove pending bitmap
|
||||||
* @delayed_rmhs_list: Delayed device removal list
|
* @delayed_rmhs_list: Delayed device removal list
|
||||||
|
* @evtack_cmds_bitmap_sz: Event Ack bitmap size
|
||||||
|
* @evtack_cmds_bitmap: Event Ack bitmap
|
||||||
|
* @delayed_evtack_cmds_list: Delayed event acknowledgment list
|
||||||
* @ts_update_counter: Timestamp update counter
|
* @ts_update_counter: Timestamp update counter
|
||||||
* @reset_in_progress: Reset in progress flag
|
* @reset_in_progress: Reset in progress flag
|
||||||
* @unrecoverable: Controller unrecoverable flag
|
* @unrecoverable: Controller unrecoverable flag
|
||||||
|
@ -800,11 +808,15 @@ struct mpi3mr_ioc {
|
||||||
|
|
||||||
struct mpi3mr_drv_cmd host_tm_cmds;
|
struct mpi3mr_drv_cmd host_tm_cmds;
|
||||||
struct mpi3mr_drv_cmd dev_rmhs_cmds[MPI3MR_NUM_DEVRMCMD];
|
struct mpi3mr_drv_cmd dev_rmhs_cmds[MPI3MR_NUM_DEVRMCMD];
|
||||||
|
struct mpi3mr_drv_cmd evtack_cmds[MPI3MR_NUM_EVTACKCMD];
|
||||||
u16 devrem_bitmap_sz;
|
u16 devrem_bitmap_sz;
|
||||||
void *devrem_bitmap;
|
void *devrem_bitmap;
|
||||||
u16 dev_handle_bitmap_sz;
|
u16 dev_handle_bitmap_sz;
|
||||||
void *removepend_bitmap;
|
void *removepend_bitmap;
|
||||||
struct list_head delayed_rmhs_list;
|
struct list_head delayed_rmhs_list;
|
||||||
|
u16 evtack_cmds_bitmap_sz;
|
||||||
|
void *evtack_cmds_bitmap;
|
||||||
|
struct list_head delayed_evtack_cmds_list;
|
||||||
|
|
||||||
u32 ts_update_counter;
|
u32 ts_update_counter;
|
||||||
u8 reset_in_progress;
|
u8 reset_in_progress;
|
||||||
|
@ -862,6 +874,18 @@ struct delayed_dev_rmhs_node {
|
||||||
u8 iou_rc;
|
u8 iou_rc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct delayed_evt_ack_node - Delayed event ack node
|
||||||
|
* @list: list head
|
||||||
|
* @event: MPI3 event ID
|
||||||
|
* @event_ctx: event context
|
||||||
|
*/
|
||||||
|
struct delayed_evt_ack_node {
|
||||||
|
struct list_head list;
|
||||||
|
u8 event;
|
||||||
|
u32 event_ctx;
|
||||||
|
};
|
||||||
|
|
||||||
int mpi3mr_setup_resources(struct mpi3mr_ioc *mrioc);
|
int mpi3mr_setup_resources(struct mpi3mr_ioc *mrioc);
|
||||||
void mpi3mr_cleanup_resources(struct mpi3mr_ioc *mrioc);
|
void mpi3mr_cleanup_resources(struct mpi3mr_ioc *mrioc);
|
||||||
int mpi3mr_init_ioc(struct mpi3mr_ioc *mrioc);
|
int mpi3mr_init_ioc(struct mpi3mr_ioc *mrioc);
|
||||||
|
@ -898,7 +922,7 @@ void mpi3mr_ioc_disable_intr(struct mpi3mr_ioc *mrioc);
|
||||||
void mpi3mr_ioc_enable_intr(struct mpi3mr_ioc *mrioc);
|
void mpi3mr_ioc_enable_intr(struct mpi3mr_ioc *mrioc);
|
||||||
|
|
||||||
enum mpi3mr_iocstate mpi3mr_get_iocstate(struct mpi3mr_ioc *mrioc);
|
enum mpi3mr_iocstate mpi3mr_get_iocstate(struct mpi3mr_ioc *mrioc);
|
||||||
int mpi3mr_send_event_ack(struct mpi3mr_ioc *mrioc, u8 event,
|
int mpi3mr_process_event_ack(struct mpi3mr_ioc *mrioc, u8 event,
|
||||||
u32 event_ctx);
|
u32 event_ctx);
|
||||||
|
|
||||||
void mpi3mr_wait_for_host_io(struct mpi3mr_ioc *mrioc, u32 timeout);
|
void mpi3mr_wait_for_host_io(struct mpi3mr_ioc *mrioc, u32 timeout);
|
||||||
|
@ -906,7 +930,7 @@ void mpi3mr_cleanup_fwevt_list(struct mpi3mr_ioc *mrioc);
|
||||||
void mpi3mr_flush_host_io(struct mpi3mr_ioc *mrioc);
|
void mpi3mr_flush_host_io(struct mpi3mr_ioc *mrioc);
|
||||||
void mpi3mr_invalidate_devhandles(struct mpi3mr_ioc *mrioc);
|
void mpi3mr_invalidate_devhandles(struct mpi3mr_ioc *mrioc);
|
||||||
void mpi3mr_rfresh_tgtdevs(struct mpi3mr_ioc *mrioc);
|
void mpi3mr_rfresh_tgtdevs(struct mpi3mr_ioc *mrioc);
|
||||||
void mpi3mr_flush_delayed_rmhs_list(struct mpi3mr_ioc *mrioc);
|
void mpi3mr_flush_delayed_cmd_lists(struct mpi3mr_ioc *mrioc);
|
||||||
void mpi3mr_check_rh_fault_ioc(struct mpi3mr_ioc *mrioc, u32 reason_code);
|
void mpi3mr_check_rh_fault_ioc(struct mpi3mr_ioc *mrioc, u32 reason_code);
|
||||||
void mpi3mr_print_fault_info(struct mpi3mr_ioc *mrioc);
|
void mpi3mr_print_fault_info(struct mpi3mr_ioc *mrioc);
|
||||||
void mpi3mr_check_rh_fault_ioc(struct mpi3mr_ioc *mrioc, u32 reason_code);
|
void mpi3mr_check_rh_fault_ioc(struct mpi3mr_ioc *mrioc, u32 reason_code);
|
||||||
|
|
|
@ -312,6 +312,12 @@ mpi3mr_get_drv_cmd(struct mpi3mr_ioc *mrioc, u16 host_tag,
|
||||||
return &mrioc->dev_rmhs_cmds[idx];
|
return &mrioc->dev_rmhs_cmds[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (host_tag >= MPI3MR_HOSTTAG_EVTACKCMD_MIN &&
|
||||||
|
host_tag <= MPI3MR_HOSTTAG_EVTACKCMD_MAX) {
|
||||||
|
idx = host_tag - MPI3MR_HOSTTAG_EVTACKCMD_MIN;
|
||||||
|
return &mrioc->evtack_cmds[idx];
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2691,6 +2697,13 @@ static int mpi3mr_alloc_reply_sense_bufs(struct mpi3mr_ioc *mrioc)
|
||||||
goto out_failed;
|
goto out_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < MPI3MR_NUM_EVTACKCMD; i++) {
|
||||||
|
mrioc->evtack_cmds[i].reply = kzalloc(mrioc->reply_sz,
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!mrioc->evtack_cmds[i].reply)
|
||||||
|
goto out_failed;
|
||||||
|
}
|
||||||
|
|
||||||
mrioc->host_tm_cmds.reply = kzalloc(mrioc->reply_sz, GFP_KERNEL);
|
mrioc->host_tm_cmds.reply = kzalloc(mrioc->reply_sz, GFP_KERNEL);
|
||||||
if (!mrioc->host_tm_cmds.reply)
|
if (!mrioc->host_tm_cmds.reply)
|
||||||
goto out_failed;
|
goto out_failed;
|
||||||
|
@ -2711,6 +2724,14 @@ static int mpi3mr_alloc_reply_sense_bufs(struct mpi3mr_ioc *mrioc)
|
||||||
if (!mrioc->devrem_bitmap)
|
if (!mrioc->devrem_bitmap)
|
||||||
goto out_failed;
|
goto out_failed;
|
||||||
|
|
||||||
|
mrioc->evtack_cmds_bitmap_sz = MPI3MR_NUM_EVTACKCMD / 8;
|
||||||
|
if (MPI3MR_NUM_EVTACKCMD % 8)
|
||||||
|
mrioc->evtack_cmds_bitmap_sz++;
|
||||||
|
mrioc->evtack_cmds_bitmap = kzalloc(mrioc->evtack_cmds_bitmap_sz,
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!mrioc->evtack_cmds_bitmap)
|
||||||
|
goto out_failed;
|
||||||
|
|
||||||
mrioc->num_reply_bufs = mrioc->facts.max_reqs + MPI3MR_NUM_EVT_REPLIES;
|
mrioc->num_reply_bufs = mrioc->facts.max_reqs + MPI3MR_NUM_EVT_REPLIES;
|
||||||
mrioc->reply_free_qsz = mrioc->num_reply_bufs + 1;
|
mrioc->reply_free_qsz = mrioc->num_reply_bufs + 1;
|
||||||
mrioc->num_sense_bufs = mrioc->facts.max_reqs / MPI3MR_SENSEBUF_FACTOR;
|
mrioc->num_sense_bufs = mrioc->facts.max_reqs / MPI3MR_SENSEBUF_FACTOR;
|
||||||
|
@ -3030,17 +3051,17 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mpi3mr_send_event_ack - Send event acknowledgment
|
* mpi3mr_process_event_ack - Process event acknowledgment
|
||||||
* @mrioc: Adapter instance reference
|
* @mrioc: Adapter instance reference
|
||||||
* @event: MPI3 event ID
|
* @event: MPI3 event ID
|
||||||
* @event_ctx: Event context
|
* @event_ctx: event context
|
||||||
*
|
*
|
||||||
* Send event acknowledgment through admin queue and wait for
|
* Send event acknowledgment through admin queue and wait for
|
||||||
* it to complete.
|
* it to complete.
|
||||||
*
|
*
|
||||||
* Return: 0 on success, non-zero on failures.
|
* Return: 0 on success, non-zero on failures.
|
||||||
*/
|
*/
|
||||||
int mpi3mr_send_event_ack(struct mpi3mr_ioc *mrioc, u8 event,
|
int mpi3mr_process_event_ack(struct mpi3mr_ioc *mrioc, u8 event,
|
||||||
u32 event_ctx)
|
u32 event_ctx)
|
||||||
{
|
{
|
||||||
struct mpi3_event_ack_request evtack_req;
|
struct mpi3_event_ack_request evtack_req;
|
||||||
|
@ -3803,8 +3824,13 @@ void mpi3mr_memset_buffers(struct mpi3mr_ioc *mrioc)
|
||||||
for (i = 0; i < MPI3MR_NUM_DEVRMCMD; i++)
|
for (i = 0; i < MPI3MR_NUM_DEVRMCMD; i++)
|
||||||
memset(mrioc->dev_rmhs_cmds[i].reply, 0,
|
memset(mrioc->dev_rmhs_cmds[i].reply, 0,
|
||||||
sizeof(*mrioc->dev_rmhs_cmds[i].reply));
|
sizeof(*mrioc->dev_rmhs_cmds[i].reply));
|
||||||
|
for (i = 0; i < MPI3MR_NUM_EVTACKCMD; i++)
|
||||||
|
memset(mrioc->evtack_cmds[i].reply, 0,
|
||||||
|
sizeof(*mrioc->evtack_cmds[i].reply));
|
||||||
memset(mrioc->removepend_bitmap, 0, mrioc->dev_handle_bitmap_sz);
|
memset(mrioc->removepend_bitmap, 0, mrioc->dev_handle_bitmap_sz);
|
||||||
memset(mrioc->devrem_bitmap, 0, mrioc->devrem_bitmap_sz);
|
memset(mrioc->devrem_bitmap, 0, mrioc->devrem_bitmap_sz);
|
||||||
|
memset(mrioc->evtack_cmds_bitmap, 0,
|
||||||
|
mrioc->evtack_cmds_bitmap_sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < mrioc->num_queues; i++) {
|
for (i = 0; i < mrioc->num_queues; i++) {
|
||||||
|
@ -3898,12 +3924,20 @@ void mpi3mr_free_mem(struct mpi3mr_ioc *mrioc)
|
||||||
kfree(mrioc->host_tm_cmds.reply);
|
kfree(mrioc->host_tm_cmds.reply);
|
||||||
mrioc->host_tm_cmds.reply = NULL;
|
mrioc->host_tm_cmds.reply = NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < MPI3MR_NUM_EVTACKCMD; i++) {
|
||||||
|
kfree(mrioc->evtack_cmds[i].reply);
|
||||||
|
mrioc->evtack_cmds[i].reply = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
kfree(mrioc->removepend_bitmap);
|
kfree(mrioc->removepend_bitmap);
|
||||||
mrioc->removepend_bitmap = NULL;
|
mrioc->removepend_bitmap = NULL;
|
||||||
|
|
||||||
kfree(mrioc->devrem_bitmap);
|
kfree(mrioc->devrem_bitmap);
|
||||||
mrioc->devrem_bitmap = NULL;
|
mrioc->devrem_bitmap = NULL;
|
||||||
|
|
||||||
|
kfree(mrioc->evtack_cmds_bitmap);
|
||||||
|
mrioc->evtack_cmds_bitmap = NULL;
|
||||||
|
|
||||||
kfree(mrioc->chain_bitmap);
|
kfree(mrioc->chain_bitmap);
|
||||||
mrioc->chain_bitmap = NULL;
|
mrioc->chain_bitmap = NULL;
|
||||||
|
|
||||||
|
@ -4079,6 +4113,11 @@ static void mpi3mr_flush_drv_cmds(struct mpi3mr_ioc *mrioc)
|
||||||
cmdptr = &mrioc->dev_rmhs_cmds[i];
|
cmdptr = &mrioc->dev_rmhs_cmds[i];
|
||||||
mpi3mr_drv_cmd_comp_reset(mrioc, cmdptr);
|
mpi3mr_drv_cmd_comp_reset(mrioc, cmdptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < MPI3MR_NUM_EVTACKCMD; i++) {
|
||||||
|
cmdptr = &mrioc->evtack_cmds[i];
|
||||||
|
mpi3mr_drv_cmd_comp_reset(mrioc, cmdptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4176,10 +4215,11 @@ int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
mpi3mr_flush_delayed_rmhs_list(mrioc);
|
mpi3mr_flush_delayed_cmd_lists(mrioc);
|
||||||
mpi3mr_flush_drv_cmds(mrioc);
|
mpi3mr_flush_drv_cmds(mrioc);
|
||||||
memset(mrioc->devrem_bitmap, 0, mrioc->devrem_bitmap_sz);
|
memset(mrioc->devrem_bitmap, 0, mrioc->devrem_bitmap_sz);
|
||||||
memset(mrioc->removepend_bitmap, 0, mrioc->dev_handle_bitmap_sz);
|
memset(mrioc->removepend_bitmap, 0, mrioc->dev_handle_bitmap_sz);
|
||||||
|
memset(mrioc->evtack_cmds_bitmap, 0, mrioc->evtack_cmds_bitmap_sz);
|
||||||
mpi3mr_cleanup_fwevt_list(mrioc);
|
mpi3mr_cleanup_fwevt_list(mrioc);
|
||||||
mpi3mr_flush_host_io(mrioc);
|
mpi3mr_flush_host_io(mrioc);
|
||||||
mpi3mr_invalidate_devhandles(mrioc);
|
mpi3mr_invalidate_devhandles(mrioc);
|
||||||
|
|
|
@ -34,6 +34,9 @@ MODULE_PARM_DESC(logging_level,
|
||||||
" bits for enabling additional logging info (default=0)");
|
" bits for enabling additional logging info (default=0)");
|
||||||
|
|
||||||
/* Forward declarations*/
|
/* Forward declarations*/
|
||||||
|
static void mpi3mr_send_event_ack(struct mpi3mr_ioc *mrioc, u8 event,
|
||||||
|
struct mpi3mr_drv_cmd *cmdparam, u32 event_ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mpi3mr_host_tag_for_scmd - Get host tag for a scmd
|
* mpi3mr_host_tag_for_scmd - Get host tag for a scmd
|
||||||
* @mrioc: Adapter instance reference
|
* @mrioc: Adapter instance reference
|
||||||
|
@ -1336,7 +1339,7 @@ static void mpi3mr_fwevt_bh(struct mpi3mr_ioc *mrioc,
|
||||||
|
|
||||||
evt_ack:
|
evt_ack:
|
||||||
if (fwevt->send_ack)
|
if (fwevt->send_ack)
|
||||||
mpi3mr_send_event_ack(mrioc, fwevt->event_id,
|
mpi3mr_process_event_ack(mrioc, fwevt->event_id,
|
||||||
fwevt->evt_ctx);
|
fwevt->evt_ctx);
|
||||||
out:
|
out:
|
||||||
/* Put fwevt reference count to neutralize kref_init increment */
|
/* Put fwevt reference count to neutralize kref_init increment */
|
||||||
|
@ -1400,24 +1403,33 @@ static int mpi3mr_create_tgtdev(struct mpi3mr_ioc *mrioc,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mpi3mr_flush_delayed_rmhs_list - Flush pending commands
|
* mpi3mr_flush_delayed_cmd_lists - Flush pending commands
|
||||||
* @mrioc: Adapter instance reference
|
* @mrioc: Adapter instance reference
|
||||||
*
|
*
|
||||||
* Flush pending commands in the delayed removal handshake list
|
* Flush pending commands in the delayed lists due to a
|
||||||
* due to a controller reset or driver removal as a cleanup.
|
* controller reset or driver removal as a cleanup.
|
||||||
*
|
*
|
||||||
* Return: Nothing
|
* Return: Nothing
|
||||||
*/
|
*/
|
||||||
void mpi3mr_flush_delayed_rmhs_list(struct mpi3mr_ioc *mrioc)
|
void mpi3mr_flush_delayed_cmd_lists(struct mpi3mr_ioc *mrioc)
|
||||||
{
|
{
|
||||||
struct delayed_dev_rmhs_node *_rmhs_node;
|
struct delayed_dev_rmhs_node *_rmhs_node;
|
||||||
|
struct delayed_evt_ack_node *_evtack_node;
|
||||||
|
|
||||||
|
dprint_reset(mrioc, "flushing delayed dev_remove_hs commands\n");
|
||||||
while (!list_empty(&mrioc->delayed_rmhs_list)) {
|
while (!list_empty(&mrioc->delayed_rmhs_list)) {
|
||||||
_rmhs_node = list_entry(mrioc->delayed_rmhs_list.next,
|
_rmhs_node = list_entry(mrioc->delayed_rmhs_list.next,
|
||||||
struct delayed_dev_rmhs_node, list);
|
struct delayed_dev_rmhs_node, list);
|
||||||
list_del(&_rmhs_node->list);
|
list_del(&_rmhs_node->list);
|
||||||
kfree(_rmhs_node);
|
kfree(_rmhs_node);
|
||||||
}
|
}
|
||||||
|
dprint_reset(mrioc, "flushing delayed event ack commands\n");
|
||||||
|
while (!list_empty(&mrioc->delayed_evtack_cmds_list)) {
|
||||||
|
_evtack_node = list_entry(mrioc->delayed_evtack_cmds_list.next,
|
||||||
|
struct delayed_evt_ack_node, list);
|
||||||
|
list_del(&_evtack_node->list);
|
||||||
|
kfree(_evtack_node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1633,6 +1645,141 @@ out_failed:
|
||||||
clear_bit(cmd_idx, mrioc->devrem_bitmap);
|
clear_bit(cmd_idx, mrioc->devrem_bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mpi3mr_complete_evt_ack - event ack request completion
|
||||||
|
* @mrioc: Adapter instance reference
|
||||||
|
* @drv_cmd: Internal command tracker
|
||||||
|
*
|
||||||
|
* This is the completion handler for non blocking event
|
||||||
|
* acknowledgment sent to the firmware and this will issue any
|
||||||
|
* pending event acknowledgment request.
|
||||||
|
*
|
||||||
|
* Return: Nothing
|
||||||
|
*/
|
||||||
|
static void mpi3mr_complete_evt_ack(struct mpi3mr_ioc *mrioc,
|
||||||
|
struct mpi3mr_drv_cmd *drv_cmd)
|
||||||
|
{
|
||||||
|
u16 cmd_idx = drv_cmd->host_tag - MPI3MR_HOSTTAG_EVTACKCMD_MIN;
|
||||||
|
struct delayed_evt_ack_node *delayed_evtack = NULL;
|
||||||
|
|
||||||
|
if (drv_cmd->ioc_status != MPI3_IOCSTATUS_SUCCESS) {
|
||||||
|
dprint_event_th(mrioc,
|
||||||
|
"immediate event ack failed with ioc_status(0x%04x) log_info(0x%08x)\n",
|
||||||
|
(drv_cmd->ioc_status & MPI3_IOCSTATUS_STATUS_MASK),
|
||||||
|
drv_cmd->ioc_loginfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!list_empty(&mrioc->delayed_evtack_cmds_list)) {
|
||||||
|
delayed_evtack =
|
||||||
|
list_entry(mrioc->delayed_evtack_cmds_list.next,
|
||||||
|
struct delayed_evt_ack_node, list);
|
||||||
|
mpi3mr_send_event_ack(mrioc, delayed_evtack->event, drv_cmd,
|
||||||
|
delayed_evtack->event_ctx);
|
||||||
|
list_del(&delayed_evtack->list);
|
||||||
|
kfree(delayed_evtack);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
drv_cmd->state = MPI3MR_CMD_NOTUSED;
|
||||||
|
drv_cmd->callback = NULL;
|
||||||
|
clear_bit(cmd_idx, mrioc->evtack_cmds_bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mpi3mr_send_event_ack - Issue event acknwoledgment request
|
||||||
|
* @mrioc: Adapter instance reference
|
||||||
|
* @event: MPI3 event id
|
||||||
|
* @cmdparam: Internal command tracker
|
||||||
|
* @event_ctx: event context
|
||||||
|
*
|
||||||
|
* Issues event acknowledgment request to the firmware if there
|
||||||
|
* is a free command to send the event ack else it to a pend
|
||||||
|
* list so that it will be processed on a completion of a prior
|
||||||
|
* event acknowledgment .
|
||||||
|
*
|
||||||
|
* Return: Nothing
|
||||||
|
*/
|
||||||
|
static void mpi3mr_send_event_ack(struct mpi3mr_ioc *mrioc, u8 event,
|
||||||
|
struct mpi3mr_drv_cmd *cmdparam, u32 event_ctx)
|
||||||
|
{
|
||||||
|
struct mpi3_event_ack_request evtack_req;
|
||||||
|
int retval = 0;
|
||||||
|
u8 retrycount = 5;
|
||||||
|
u16 cmd_idx = MPI3MR_NUM_EVTACKCMD;
|
||||||
|
struct mpi3mr_drv_cmd *drv_cmd = cmdparam;
|
||||||
|
struct delayed_evt_ack_node *delayed_evtack = NULL;
|
||||||
|
|
||||||
|
if (drv_cmd) {
|
||||||
|
dprint_event_th(mrioc,
|
||||||
|
"sending delayed event ack in the top half for event(0x%02x), event_ctx(0x%08x)\n",
|
||||||
|
event, event_ctx);
|
||||||
|
goto issue_cmd;
|
||||||
|
}
|
||||||
|
dprint_event_th(mrioc,
|
||||||
|
"sending event ack in the top half for event(0x%02x), event_ctx(0x%08x)\n",
|
||||||
|
event, event_ctx);
|
||||||
|
do {
|
||||||
|
cmd_idx = find_first_zero_bit(mrioc->evtack_cmds_bitmap,
|
||||||
|
MPI3MR_NUM_EVTACKCMD);
|
||||||
|
if (cmd_idx < MPI3MR_NUM_EVTACKCMD) {
|
||||||
|
if (!test_and_set_bit(cmd_idx,
|
||||||
|
mrioc->evtack_cmds_bitmap))
|
||||||
|
break;
|
||||||
|
cmd_idx = MPI3MR_NUM_EVTACKCMD;
|
||||||
|
}
|
||||||
|
} while (retrycount--);
|
||||||
|
|
||||||
|
if (cmd_idx >= MPI3MR_NUM_EVTACKCMD) {
|
||||||
|
delayed_evtack = kzalloc(sizeof(*delayed_evtack),
|
||||||
|
GFP_ATOMIC);
|
||||||
|
if (!delayed_evtack)
|
||||||
|
return;
|
||||||
|
INIT_LIST_HEAD(&delayed_evtack->list);
|
||||||
|
delayed_evtack->event = event;
|
||||||
|
delayed_evtack->event_ctx = event_ctx;
|
||||||
|
list_add_tail(&delayed_evtack->list,
|
||||||
|
&mrioc->delayed_evtack_cmds_list);
|
||||||
|
dprint_event_th(mrioc,
|
||||||
|
"event ack in the top half for event(0x%02x), event_ctx(0x%08x) is postponed\n",
|
||||||
|
event, event_ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
drv_cmd = &mrioc->evtack_cmds[cmd_idx];
|
||||||
|
|
||||||
|
issue_cmd:
|
||||||
|
cmd_idx = drv_cmd->host_tag - MPI3MR_HOSTTAG_EVTACKCMD_MIN;
|
||||||
|
|
||||||
|
memset(&evtack_req, 0, sizeof(evtack_req));
|
||||||
|
if (drv_cmd->state & MPI3MR_CMD_PENDING) {
|
||||||
|
dprint_event_th(mrioc,
|
||||||
|
"sending event ack failed due to command in use\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
drv_cmd->state = MPI3MR_CMD_PENDING;
|
||||||
|
drv_cmd->is_waiting = 0;
|
||||||
|
drv_cmd->callback = mpi3mr_complete_evt_ack;
|
||||||
|
evtack_req.host_tag = cpu_to_le16(drv_cmd->host_tag);
|
||||||
|
evtack_req.function = MPI3_FUNCTION_EVENT_ACK;
|
||||||
|
evtack_req.event = event;
|
||||||
|
evtack_req.event_context = cpu_to_le32(event_ctx);
|
||||||
|
retval = mpi3mr_admin_request_post(mrioc, &evtack_req,
|
||||||
|
sizeof(evtack_req), 1);
|
||||||
|
if (retval) {
|
||||||
|
dprint_event_th(mrioc,
|
||||||
|
"posting event ack request is failed\n");
|
||||||
|
goto out_failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
dprint_event_th(mrioc,
|
||||||
|
"event ack in the top half for event(0x%02x), event_ctx(0x%08x) is posted\n",
|
||||||
|
event, event_ctx);
|
||||||
|
out:
|
||||||
|
return;
|
||||||
|
out_failed:
|
||||||
|
drv_cmd->state = MPI3MR_CMD_NOTUSED;
|
||||||
|
drv_cmd->callback = NULL;
|
||||||
|
clear_bit(cmd_idx, mrioc->evtack_cmds_bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mpi3mr_pcietopochg_evt_th - PCIETopologyChange evt tophalf
|
* mpi3mr_pcietopochg_evt_th - PCIETopologyChange evt tophalf
|
||||||
* @mrioc: Adapter instance reference
|
* @mrioc: Adapter instance reference
|
||||||
|
@ -3773,6 +3920,7 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||||
INIT_LIST_HEAD(&mrioc->fwevt_list);
|
INIT_LIST_HEAD(&mrioc->fwevt_list);
|
||||||
INIT_LIST_HEAD(&mrioc->tgtdev_list);
|
INIT_LIST_HEAD(&mrioc->tgtdev_list);
|
||||||
INIT_LIST_HEAD(&mrioc->delayed_rmhs_list);
|
INIT_LIST_HEAD(&mrioc->delayed_rmhs_list);
|
||||||
|
INIT_LIST_HEAD(&mrioc->delayed_evtack_cmds_list);
|
||||||
|
|
||||||
mutex_init(&mrioc->reset_mutex);
|
mutex_init(&mrioc->reset_mutex);
|
||||||
mpi3mr_init_drv_cmd(&mrioc->init_cmds, MPI3MR_HOSTTAG_INITCMDS);
|
mpi3mr_init_drv_cmd(&mrioc->init_cmds, MPI3MR_HOSTTAG_INITCMDS);
|
||||||
|
|
Loading…
Reference in New Issue