aic79xx: check for non-NULL scb in ahd_handle_nonpkt_busfree
Subsystems (2)
PATCH 1/1 aic79xx: check for non-NULL scb in ahd_handle_nonpkt_busfree
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 <[email protected]>
drivers/scsi/aic7xxx/aic79xx_core.c +31 -22
@@ -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 )) {