[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:
parent
51375ee837
commit
534ef056db
1 changed files with 31 additions and 22 deletions
|
@ -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)) {
|
||||
|
||||
|
|
Loading…
Reference in a new issue