Skip to content

Commit

Permalink
[SCSI] mpt2sas: Target Reset will be issued from Interrupt context.
Browse files Browse the repository at this point in the history
(1) Added three new functions to handle sending target resest and OP_REMOVE
from interrupt time, they are _scsih_tm_tr_send, _scsih_tm_tr_complete, and
_scsih_sas_control_complete.  This code will create a link list of pending
target resets if there is no more available request in the hipriority
request queue.  The list is stored in ioc->delayed_tr_list.

(2) All callback handler return type is changed from void to u8.
Now _base_interrupt will check for return type of callback handlers to
take decision of message frame is already freed or not.
In genral,
Return 1 meaning mf should be freed from _base_interrupt
       0 means the mf is freed from function.

Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
  • Loading branch information
Kashyap, Desai authored and James Bottomley committed Oct 2, 2009
1 parent 595bb0b commit 77e63ed
Show file tree
Hide file tree
Showing 6 changed files with 372 additions and 54 deletions.
35 changes: 25 additions & 10 deletions drivers/scsi/mpt2sas/mpt2sas_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -575,20 +575,21 @@ _base_display_reply_info(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
* @msix_index: MSIX table index supplied by the OS
* @reply: reply message frame(lower 32bit addr)
*
* Return nothing.
* Return 1 meaning mf should be freed from _base_interrupt
* 0 means the mf is freed from this function.
*/
void
u8
mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
u32 reply)
{
MPI2DefaultReply_t *mpi_reply;

mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
if (mpi_reply && mpi_reply->Function == MPI2_FUNCTION_EVENT_ACK)
return;
return 1;

if (ioc->base_cmds.status == MPT2_CMD_NOT_USED)
return;
return 1;

ioc->base_cmds.status |= MPT2_CMD_COMPLETE;
if (mpi_reply) {
Expand All @@ -597,6 +598,7 @@ mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
}
ioc->base_cmds.status &= ~MPT2_CMD_PENDING;
complete(&ioc->base_cmds.done);
return 1;
}

/**
Expand All @@ -605,9 +607,10 @@ mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
* @msix_index: MSIX table index supplied by the OS
* @reply: reply message frame(lower 32bit addr)
*
* Return nothing.
* Return 1 meaning mf should be freed from _base_interrupt
* 0 means the mf is freed from this function.
*/
static void
static u8
_base_async_event(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, u32 reply)
{
Mpi2EventNotificationReply_t *mpi_reply;
Expand All @@ -616,9 +619,9 @@ _base_async_event(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, u32 reply)

mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
if (!mpi_reply)
return;
return 1;
if (mpi_reply->Function != MPI2_FUNCTION_EVENT_NOTIFICATION)
return;
return 1;
#ifdef CONFIG_SCSI_MPT2SAS_LOGGING
_base_display_event_data(ioc, mpi_reply);
#endif
Expand Down Expand Up @@ -647,6 +650,8 @@ _base_async_event(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, u32 reply)

/* ctl callback handler */
mpt2sas_ctl_event_callback(ioc, msix_index, reply);

return 1;
}

/**
Expand Down Expand Up @@ -745,6 +750,7 @@ _base_interrupt(int irq, void *bus_id)
u8 msix_index;
struct MPT2SAS_ADAPTER *ioc = bus_id;
Mpi2ReplyDescriptorsUnion_t *rpf;
u8 rc;

if (ioc->mask_interrupts)
return IRQ_NONE;
Expand Down Expand Up @@ -777,12 +783,13 @@ _base_interrupt(int irq, void *bus_id)
if (smid)
cb_idx = _base_get_cb_idx(ioc, smid);
if (smid && cb_idx != 0xFF) {
mpt_callbacks[cb_idx](ioc, smid, msix_index,
rc = mpt_callbacks[cb_idx](ioc, smid, msix_index,
reply);
if (reply)
_base_display_reply_info(ioc, smid, msix_index,
reply);
mpt2sas_base_free_smid(ioc, smid);
if (rc)
mpt2sas_base_free_smid(ioc, smid);
}
if (!smid)
_base_async_event(ioc, msix_index, reply);
Expand Down Expand Up @@ -3323,10 +3330,18 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
unsigned long flags;
u32 reply_address;
u16 smid;
struct _tr_list *delayed_tr, *delayed_tr_next;

dinitprintk(ioc, printk(MPT2SAS_DEBUG_FMT "%s\n", ioc->name,
__func__));

/* clean the delayed target reset list */
list_for_each_entry_safe(delayed_tr, delayed_tr_next,
&ioc->delayed_tr_list, list) {
list_del(&delayed_tr->list);
kfree(delayed_tr);
}

/* initialize the scsi lookup free list */
spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
INIT_LIST_HEAD(&ioc->free_list);
Expand Down
41 changes: 30 additions & 11 deletions drivers/scsi/mpt2sas/mpt2sas_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ struct _sas_device {
u16 slot;
u8 hidden_raid_component;
u8 responding;
u16 state;
};

/**
Expand Down Expand Up @@ -443,6 +444,17 @@ struct request_tracker {
struct list_head tracker_list;
};

/**
* struct _tr_list - target reset list
* @handle: device handle
* @state: state machine
*/
struct _tr_list {
struct list_head list;
u16 handle;
u16 state;
};

typedef void (*MPT_ADD_SGE)(void *paddr, u32 flags_length, dma_addr_t dma_addr);

/**
Expand Down Expand Up @@ -617,6 +629,8 @@ struct MPT2SAS_ADAPTER {
u8 ctl_cb_idx;
u8 base_cb_idx;
u8 config_cb_idx;
u8 tm_tr_cb_idx;
u8 tm_sas_control_cb_idx;
struct _internal_cmd base_cmds;
struct _internal_cmd transport_cmds;
struct _internal_cmd tm_cmds;
Expand Down Expand Up @@ -727,6 +741,8 @@ struct MPT2SAS_ADAPTER {
struct dma_pool *reply_post_free_dma_pool;
u32 reply_post_host_index;

struct list_head delayed_tr_list;

/* diag buffer support */
u8 *diag_buffer[MPI2_DIAG_BUF_TYPE_COUNT];
u32 diag_buffer_sz[MPI2_DIAG_BUF_TYPE_COUNT];
Expand All @@ -738,8 +754,8 @@ struct MPT2SAS_ADAPTER {
u32 diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT];
};

typedef void (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid,
u8 msix_index, u32 reply);
typedef u8 (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
u32 reply);


/* base shared API */
Expand All @@ -757,7 +773,8 @@ int mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
void *mpt2sas_base_get_msg_frame(struct MPT2SAS_ADAPTER *ioc, u16 smid);
void *mpt2sas_base_get_sense_buffer(struct MPT2SAS_ADAPTER *ioc, u16 smid);
void mpt2sas_base_build_zero_len_sge(struct MPT2SAS_ADAPTER *ioc, void *paddr);
dma_addr_t mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc, u16 smid);
dma_addr_t mpt2sas_base_get_sense_buffer_dma(struct MPT2SAS_ADAPTER *ioc,
u16 smid);

/* hi-priority queue */
u16 mpt2sas_base_get_smid_hpr(struct MPT2SAS_ADAPTER *ioc, u8 cb_idx);
Expand All @@ -776,7 +793,7 @@ void mpt2sas_base_initialize_callback_handler(void);
u8 mpt2sas_base_register_callback_handler(MPT_CALLBACK cb_func);
void mpt2sas_base_release_callback_handler(u8 cb_idx);

void mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
u8 mpt2sas_base_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
u32 reply);
void *mpt2sas_base_get_reply_virt_addr(struct MPT2SAS_ADAPTER *ioc, u32 phys_addr);

Expand All @@ -791,6 +808,8 @@ int mpt2sas_base_scsi_enclosure_processor(struct MPT2SAS_ADAPTER *ioc,
void mpt2sas_base_validate_event_type(struct MPT2SAS_ADAPTER *ioc, u32 *event_type);

/* scsih shared API */
u8 mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
u32 reply);
void mpt2sas_scsih_issue_tm(struct MPT2SAS_ADAPTER *ioc, u16 handle, uint lun,
u8 type, u16 smid_task, ulong timeout);
void mpt2sas_scsih_set_tm_flag(struct MPT2SAS_ADAPTER *ioc, u16 handle);
Expand All @@ -802,12 +821,10 @@ struct _sas_node *mpt2sas_scsih_expander_find_by_sas_address(struct MPT2SAS_ADAP
struct _sas_device *mpt2sas_scsih_sas_device_find_by_sas_address(
struct MPT2SAS_ADAPTER *ioc, u64 sas_address);

void mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
u32 reply);
void mpt2sas_scsih_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase);

/* config shared API */
void mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
u8 mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
u32 reply);
int mpt2sas_config_get_number_hba_phys(struct MPT2SAS_ADAPTER *ioc, u8 *num_phys);
int mpt2sas_config_get_manufacturing_pg0(struct MPT2SAS_ADAPTER *ioc,
Expand Down Expand Up @@ -861,17 +878,17 @@ extern struct device_attribute *mpt2sas_host_attrs[];
extern struct device_attribute *mpt2sas_dev_attrs[];
void mpt2sas_ctl_init(void);
void mpt2sas_ctl_exit(void);
void mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
u8 mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
u32 reply);
void mpt2sas_ctl_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase);
void mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
u8 mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
u32 reply);
void mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc,
Mpi2EventNotificationReply_t *mpi_reply);

/* transport shared API */
void mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid,
u8 msix_index, u32 reply);
u8 mpt2sas_transport_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
u32 reply);
struct _sas_port *mpt2sas_transport_port_add(struct MPT2SAS_ADAPTER *ioc,
u16 handle, u16 parent_handle);
void mpt2sas_transport_port_remove(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
Expand All @@ -885,6 +902,8 @@ void mpt2sas_transport_update_links(struct MPT2SAS_ADAPTER *ioc, u16 handle,
extern struct sas_function_template mpt2sas_transport_functions;
extern struct scsi_transport_template *mpt2sas_transport_template;
extern int scsi_internal_device_block(struct scsi_device *sdev);
extern u8 mpt2sas_stm_zero_smid_handler(struct MPT2SAS_ADAPTER *ioc,
u8 msix_index, u32 reply);
extern int scsi_internal_device_unblock(struct scsi_device *sdev);

#endif /* MPT2SAS_BASE_H_INCLUDED */
10 changes: 6 additions & 4 deletions drivers/scsi/mpt2sas/mpt2sas_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,18 +233,19 @@ _config_free_config_dma_memory(struct MPT2SAS_ADAPTER *ioc,
*
* The callback handler when using _config_request.
*
* Return nothing.
* Return 1 meaning mf should be freed from _base_interrupt
* 0 means the mf is freed from this function.
*/
void
u8
mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
u32 reply)
{
MPI2DefaultReply_t *mpi_reply;

if (ioc->config_cmds.status == MPT2_CMD_NOT_USED)
return;
return 1;
if (ioc->config_cmds.smid != smid)
return;
return 1;
ioc->config_cmds.status |= MPT2_CMD_COMPLETE;
mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
if (mpi_reply) {
Expand All @@ -258,6 +259,7 @@ mpt2sas_config_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
#endif
ioc->config_cmds.smid = USHORT_MAX;
complete(&ioc->config_cmds.done);
return 1;
}

/**
Expand Down
16 changes: 10 additions & 6 deletions drivers/scsi/mpt2sas/mpt2sas_ctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,18 +225,19 @@ _ctl_display_some_debug(struct MPT2SAS_ADAPTER *ioc, u16 smid,
*
* The callback handler when using ioc->ctl_cb_idx.
*
* Return nothing.
* Return 1 meaning mf should be freed from _base_interrupt
* 0 means the mf is freed from this function.
*/
void
u8
mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
u32 reply)
{
MPI2DefaultReply_t *mpi_reply;

if (ioc->ctl_cmds.status == MPT2_CMD_NOT_USED)
return;
return 1;
if (ioc->ctl_cmds.smid != smid)
return;
return 1;
ioc->ctl_cmds.status |= MPT2_CMD_COMPLETE;
mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
if (mpi_reply) {
Expand All @@ -248,6 +249,7 @@ mpt2sas_ctl_done(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
#endif
ioc->ctl_cmds.status &= ~MPT2_CMD_PENDING;
complete(&ioc->ctl_cmds.done);
return 1;
}

/**
Expand Down Expand Up @@ -336,16 +338,18 @@ mpt2sas_ctl_add_to_event_log(struct MPT2SAS_ADAPTER *ioc,
* This function merely adds a new work task into ioc->firmware_event_thread.
* The tasks are worked from _firmware_event_work in user context.
*
* Return nothing.
* Return 1 meaning mf should be freed from _base_interrupt
* 0 means the mf is freed from this function.
*/
void
u8
mpt2sas_ctl_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
u32 reply)
{
Mpi2EventNotificationReply_t *mpi_reply;

mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
mpt2sas_ctl_add_to_event_log(ioc, mpi_reply);
return 1;
}

/**
Expand Down
Loading

0 comments on commit 77e63ed

Please sign in to comment.