Commit d7f2d29d authored by Brian King's avatar Brian King Committed by James Bottomley

[PATCH] ipr abort hang fix

The following patch fixes a hang that occurs when an abort
is issued by the midlayer. The hang is the result of overriding
a field in the union of the ipr_cmd struct. It is fixed by moving
this pointer outside of the union, since it is not mutually exclusive
with the other fields in the union.
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 311a8896
......@@ -448,6 +448,7 @@ static void ipr_init_ipr_cmnd(struct ipr_cmnd *ipr_cmd)
{
ipr_reinit_ipr_cmnd(ipr_cmd);
ipr_cmd->u.scratch = 0;
ipr_cmd->sibling = NULL;
init_timer(&ipr_cmd->timer);
}
......@@ -676,8 +677,8 @@ static void ipr_do_req(struct ipr_cmnd *ipr_cmd,
**/
static void ipr_internal_cmd_done(struct ipr_cmnd *ipr_cmd)
{
if (ipr_cmd->u.sibling)
ipr_cmd->u.sibling = NULL;
if (ipr_cmd->sibling)
ipr_cmd->sibling = NULL;
else
complete(&ipr_cmd->completion);
}
......@@ -3015,10 +3016,10 @@ static void ipr_bus_reset_done(struct ipr_cmnd *ipr_cmd)
* If abort has not completed, indicate the reset has, else call the
* abort's done function to wake the sleeping eh thread
*/
if (ipr_cmd->u.sibling->u.sibling)
ipr_cmd->u.sibling->u.sibling = NULL;
if (ipr_cmd->sibling->sibling)
ipr_cmd->sibling->sibling = NULL;
else
ipr_cmd->u.sibling->done(ipr_cmd->u.sibling);
ipr_cmd->sibling->done(ipr_cmd->sibling);
list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
LEAVE;
......@@ -3051,8 +3052,8 @@ static void ipr_abort_timeout(struct ipr_cmnd *ipr_cmd)
ipr_sdev_err(ipr_cmd->u.sdev, "Abort timed out. Resetting bus\n");
reset_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
ipr_cmd->u.sibling = reset_cmd;
reset_cmd->u.sibling = ipr_cmd;
ipr_cmd->sibling = reset_cmd;
reset_cmd->sibling = ipr_cmd;
reset_cmd->ioarcb.res_handle = ipr_cmd->ioarcb.res_handle;
cmd_pkt = &reset_cmd->ioarcb.cmd_pkt;
cmd_pkt->request_type = IPR_RQTYPE_IOACMD;
......
......@@ -932,13 +932,13 @@ struct ipr_cmnd {
dma_addr_t sense_buffer_dma;
unsigned short dma_use_sg;
dma_addr_t dma_handle;
struct ipr_cmnd *sibling;
union {
enum ipr_shutdown_type shutdown_type;
struct ipr_hostrcb *hostrcb;
unsigned long time_left;
unsigned long scratch;
struct ipr_resource_entry *res;
struct ipr_cmnd *sibling;
struct scsi_device *sdev;
} u;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment