[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

View File

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