Skip to content

Commit

Permalink
[SCSI] sym53c8xx: fixes two bugs related to chip reset
Browse files Browse the repository at this point in the history
This patch fixes two bugs pointed by James Bottomley:

 1. the if (!sym_data->io_reset).  That variable is only ever filled
    by a stack based completion.  If we find it non empty it means
    this code has been entered twice and we have a severe problem,
    so that should just become a BUG_ON(sym_data->io_reset).
 2. sym_data->io_reset should be set to NULL before the routine is
    exited otherwise the PCI recovery code could end up completing
    what will be a bogus pointer into the stack.

Big thanks to James Bottomley for help with the patch.

Signed-off-by: Krzysztof Helt <krzysztof.h1@w.pl>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
  • Loading branch information
Krzysztof Helt authored and James Bottomley committed Jan 23, 2008
1 parent 3a0086a commit d9aa3af
Showing 1 changed file with 7 additions and 6 deletions.
13 changes: 7 additions & 6 deletions drivers/scsi/sym53c8xx_2/sym_glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -609,22 +609,24 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
*/
#define WAIT_FOR_PCI_RECOVERY 35
if (pci_channel_offline(pdev)) {
struct completion *io_reset;
int finished_reset = 0;
init_completion(&eh_done);
spin_lock_irq(shost->host_lock);
/* Make sure we didn't race */
if (pci_channel_offline(pdev)) {
if (!sym_data->io_reset)
sym_data->io_reset = &eh_done;
io_reset = sym_data->io_reset;
BUG_ON(sym_data->io_reset);
sym_data->io_reset = &eh_done;
} else {
finished_reset = 1;
}
spin_unlock_irq(shost->host_lock);
if (!finished_reset)
finished_reset = wait_for_completion_timeout(io_reset,
finished_reset = wait_for_completion_timeout
(sym_data->io_reset,
WAIT_FOR_PCI_RECOVERY*HZ);
spin_lock_irq(shost->host_lock);
sym_data->io_reset = NULL;
spin_unlock_irq(shost->host_lock);
if (!finished_reset)
return SCSI_FAILED;
}
Expand Down Expand Up @@ -1879,7 +1881,6 @@ static void sym2_io_resume(struct pci_dev *pdev)
spin_lock_irq(shost->host_lock);
if (sym_data->io_reset)
complete_all(sym_data->io_reset);
sym_data->io_reset = NULL;
spin_unlock_irq(shost->host_lock);
}

Expand Down

0 comments on commit d9aa3af

Please sign in to comment.