[SCSI] aic79xx: check for non-NULL scb in ahd_handle_nonpkt_busfree

When removing several devices aic79xx will occasionally Oops
in ahd_handle_nonpkt_busfree during rescan. Looking at the
code I found that we're indeed not checking if the scb in
question is NULL. So check for it before accessing it.

Signed-off-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
This commit is contained in:
Hannes Reinecke 2010-01-15 13:07:34 +01:00 committed by James Bottomley
parent 51375ee837
commit 534ef056db
1 changed files with 31 additions and 22 deletions

View File

@ -3171,13 +3171,16 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
tinfo->curr.transport_version = 2;
tinfo->goal.transport_version = 2;
tinfo->goal.ppr_options = 0;
/*
* Remove any SCBs in the waiting for selection
* queue that may also be for this target so
* that command ordering is preserved.
*/
ahd_freeze_devq(ahd, scb);
ahd_qinfifo_requeue_tail(ahd, scb);
if (scb != NULL) {
/*
* Remove any SCBs in the waiting
* for selection queue that may
* also be for this target so that
* command ordering is preserved.
*/
ahd_freeze_devq(ahd, scb);
ahd_qinfifo_requeue_tail(ahd, scb);
}
printerror = 0;
}
} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE)
@ -3194,13 +3197,16 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
MSG_EXT_WDTR_BUS_8_BIT,
AHD_TRANS_CUR|AHD_TRANS_GOAL,
/*paused*/TRUE);
/*
* Remove any SCBs in the waiting for selection
* queue that may also be for this target so that
* command ordering is preserved.
*/
ahd_freeze_devq(ahd, scb);
ahd_qinfifo_requeue_tail(ahd, scb);
if (scb != NULL) {
/*
* Remove any SCBs in the waiting for
* selection queue that may also be for
* this target so that command ordering
* is preserved.
*/
ahd_freeze_devq(ahd, scb);
ahd_qinfifo_requeue_tail(ahd, scb);
}
printerror = 0;
} else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE)
&& ppr_busfree == 0) {
@ -3217,13 +3223,16 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
/*ppr_options*/0,
AHD_TRANS_CUR|AHD_TRANS_GOAL,
/*paused*/TRUE);
/*
* Remove any SCBs in the waiting for selection
* queue that may also be for this target so that
* command ordering is preserved.
*/
ahd_freeze_devq(ahd, scb);
ahd_qinfifo_requeue_tail(ahd, scb);
if (scb != NULL) {
/*
* Remove any SCBs in the waiting for
* selection queue that may also be for
* this target so that command ordering
* is preserved.
*/
ahd_freeze_devq(ahd, scb);
ahd_qinfifo_requeue_tail(ahd, scb);
}
printerror = 0;
} else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0
&& ahd_sent_msg(ahd, AHDMSG_1B,
@ -3251,7 +3260,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd)
* the message phases. We check it last in case we
* had to send some other message that caused a busfree.
*/
if (printerror != 0
if (scb != NULL && printerror != 0
&& (lastphase == P_MESGIN || lastphase == P_MESGOUT)
&& ((ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0)) {