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) ...@@ -448,6 +448,7 @@ static void ipr_init_ipr_cmnd(struct ipr_cmnd *ipr_cmd)
{ {
ipr_reinit_ipr_cmnd(ipr_cmd); ipr_reinit_ipr_cmnd(ipr_cmd);
ipr_cmd->u.scratch = 0; ipr_cmd->u.scratch = 0;
ipr_cmd->sibling = NULL;
init_timer(&ipr_cmd->timer); init_timer(&ipr_cmd->timer);
} }
...@@ -676,8 +677,8 @@ static void ipr_do_req(struct ipr_cmnd *ipr_cmd, ...@@ -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) static void ipr_internal_cmd_done(struct ipr_cmnd *ipr_cmd)
{ {
if (ipr_cmd->u.sibling) if (ipr_cmd->sibling)
ipr_cmd->u.sibling = NULL; ipr_cmd->sibling = NULL;
else else
complete(&ipr_cmd->completion); complete(&ipr_cmd->completion);
} }
...@@ -3015,10 +3016,10 @@ static void ipr_bus_reset_done(struct ipr_cmnd *ipr_cmd) ...@@ -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 * If abort has not completed, indicate the reset has, else call the
* abort's done function to wake the sleeping eh thread * abort's done function to wake the sleeping eh thread
*/ */
if (ipr_cmd->u.sibling->u.sibling) if (ipr_cmd->sibling->sibling)
ipr_cmd->u.sibling->u.sibling = NULL; ipr_cmd->sibling->sibling = NULL;
else 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); list_add_tail(&ipr_cmd->queue, &ioa_cfg->free_q);
LEAVE; LEAVE;
...@@ -3051,8 +3052,8 @@ static void ipr_abort_timeout(struct ipr_cmnd *ipr_cmd) ...@@ -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"); ipr_sdev_err(ipr_cmd->u.sdev, "Abort timed out. Resetting bus\n");
reset_cmd = ipr_get_free_ipr_cmnd(ioa_cfg); reset_cmd = ipr_get_free_ipr_cmnd(ioa_cfg);
ipr_cmd->u.sibling = reset_cmd; ipr_cmd->sibling = reset_cmd;
reset_cmd->u.sibling = ipr_cmd; reset_cmd->sibling = ipr_cmd;
reset_cmd->ioarcb.res_handle = ipr_cmd->ioarcb.res_handle; reset_cmd->ioarcb.res_handle = ipr_cmd->ioarcb.res_handle;
cmd_pkt = &reset_cmd->ioarcb.cmd_pkt; cmd_pkt = &reset_cmd->ioarcb.cmd_pkt;
cmd_pkt->request_type = IPR_RQTYPE_IOACMD; cmd_pkt->request_type = IPR_RQTYPE_IOACMD;
......
...@@ -932,13 +932,13 @@ struct ipr_cmnd { ...@@ -932,13 +932,13 @@ struct ipr_cmnd {
dma_addr_t sense_buffer_dma; dma_addr_t sense_buffer_dma;
unsigned short dma_use_sg; unsigned short dma_use_sg;
dma_addr_t dma_handle; dma_addr_t dma_handle;
struct ipr_cmnd *sibling;
union { union {
enum ipr_shutdown_type shutdown_type; enum ipr_shutdown_type shutdown_type;
struct ipr_hostrcb *hostrcb; struct ipr_hostrcb *hostrcb;
unsigned long time_left; unsigned long time_left;
unsigned long scratch; unsigned long scratch;
struct ipr_resource_entry *res; struct ipr_resource_entry *res;
struct ipr_cmnd *sibling;
struct scsi_device *sdev; struct scsi_device *sdev;
} u; } 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