Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 534ef056 authored by Hannes Reinecke's avatar Hannes Reinecke Committed by James Bottomley
Browse files

[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: default avatarHannes Reinecke <hare@suse.de>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 51375ee8
Loading
Loading
Loading
Loading
+31 −22
Original line number Original line Diff line number Diff line
@@ -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
					 * Remove any SCBs in the waiting
				 * queue that may also be for this target so
					 * for selection queue that may
				 * that command ordering is preserved.
					 * also be for this target so that
					 * command ordering is preserved.
					 */
					 */
					ahd_freeze_devq(ahd, scb);
					ahd_freeze_devq(ahd, scb);
					ahd_qinfifo_requeue_tail(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
				 * Remove any SCBs in the waiting for
			 * queue that may also be for this target so that
				 * selection queue that may also be for
			 * command ordering is preserved.
				 * this target so that command ordering
				 * is preserved.
				 */
				 */
				ahd_freeze_devq(ahd, scb);
				ahd_freeze_devq(ahd, scb);
				ahd_qinfifo_requeue_tail(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
				 * Remove any SCBs in the waiting for
			 * queue that may also be for this target so that
				 * selection queue that may also be for
			 * command ordering is preserved.
				 * this target so that command ordering
				 * is preserved.
				 */
				 */
				ahd_freeze_devq(ahd, scb);
				ahd_freeze_devq(ahd, scb);
				ahd_qinfifo_requeue_tail(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)) {