diff options
author | Hannes Reinecke <hare@suse.de> | 2010-01-15 07:07:34 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-01-17 13:48:12 -0500 |
commit | 534ef056db8a8fb6b9d50188d88ed5d1fbc66673 (patch) | |
tree | 0c2c497e5781ef870eed9d09d39792895f43073b /drivers/scsi | |
parent | 51375ee8374dd7fa574e1a14ebac406c6d28543b (diff) |
[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>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/aic7xxx/aic79xx_core.c | 53 |
1 files changed, 31 insertions, 22 deletions
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c index 4d419c155ce9..78971db5b60e 100644 --- a/drivers/scsi/aic7xxx/aic79xx_core.c +++ b/drivers/scsi/aic7xxx/aic79xx_core.c | |||
@@ -3171,13 +3171,16 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) | |||
3171 | tinfo->curr.transport_version = 2; | 3171 | tinfo->curr.transport_version = 2; |
3172 | tinfo->goal.transport_version = 2; | 3172 | tinfo->goal.transport_version = 2; |
3173 | tinfo->goal.ppr_options = 0; | 3173 | tinfo->goal.ppr_options = 0; |
3174 | /* | 3174 | if (scb != NULL) { |
3175 | * Remove any SCBs in the waiting for selection | 3175 | /* |
3176 | * queue that may also be for this target so | 3176 | * Remove any SCBs in the waiting |
3177 | * that command ordering is preserved. | 3177 | * for selection queue that may |
3178 | */ | 3178 | * also be for this target so that |
3179 | ahd_freeze_devq(ahd, scb); | 3179 | * command ordering is preserved. |
3180 | ahd_qinfifo_requeue_tail(ahd, scb); | 3180 | */ |
3181 | ahd_freeze_devq(ahd, scb); | ||
3182 | ahd_qinfifo_requeue_tail(ahd, scb); | ||
3183 | } | ||
3181 | printerror = 0; | 3184 | printerror = 0; |
3182 | } | 3185 | } |
3183 | } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE) | 3186 | } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE) |
@@ -3194,13 +3197,16 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) | |||
3194 | MSG_EXT_WDTR_BUS_8_BIT, | 3197 | MSG_EXT_WDTR_BUS_8_BIT, |
3195 | AHD_TRANS_CUR|AHD_TRANS_GOAL, | 3198 | AHD_TRANS_CUR|AHD_TRANS_GOAL, |
3196 | /*paused*/TRUE); | 3199 | /*paused*/TRUE); |
3197 | /* | 3200 | if (scb != NULL) { |
3198 | * Remove any SCBs in the waiting for selection | 3201 | /* |
3199 | * queue that may also be for this target so that | 3202 | * Remove any SCBs in the waiting for |
3200 | * command ordering is preserved. | 3203 | * selection queue that may also be for |
3201 | */ | 3204 | * this target so that command ordering |
3202 | ahd_freeze_devq(ahd, scb); | 3205 | * is preserved. |
3203 | ahd_qinfifo_requeue_tail(ahd, scb); | 3206 | */ |
3207 | ahd_freeze_devq(ahd, scb); | ||
3208 | ahd_qinfifo_requeue_tail(ahd, scb); | ||
3209 | } | ||
3204 | printerror = 0; | 3210 | printerror = 0; |
3205 | } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE) | 3211 | } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE) |
3206 | && ppr_busfree == 0) { | 3212 | && ppr_busfree == 0) { |
@@ -3217,13 +3223,16 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) | |||
3217 | /*ppr_options*/0, | 3223 | /*ppr_options*/0, |
3218 | AHD_TRANS_CUR|AHD_TRANS_GOAL, | 3224 | AHD_TRANS_CUR|AHD_TRANS_GOAL, |
3219 | /*paused*/TRUE); | 3225 | /*paused*/TRUE); |
3220 | /* | 3226 | if (scb != NULL) { |
3221 | * Remove any SCBs in the waiting for selection | 3227 | /* |
3222 | * queue that may also be for this target so that | 3228 | * Remove any SCBs in the waiting for |
3223 | * command ordering is preserved. | 3229 | * selection queue that may also be for |
3224 | */ | 3230 | * this target so that command ordering |
3225 | ahd_freeze_devq(ahd, scb); | 3231 | * is preserved. |
3226 | ahd_qinfifo_requeue_tail(ahd, scb); | 3232 | */ |
3233 | ahd_freeze_devq(ahd, scb); | ||
3234 | ahd_qinfifo_requeue_tail(ahd, scb); | ||
3235 | } | ||
3227 | printerror = 0; | 3236 | printerror = 0; |
3228 | } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0 | 3237 | } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0 |
3229 | && ahd_sent_msg(ahd, AHDMSG_1B, | 3238 | && ahd_sent_msg(ahd, AHDMSG_1B, |
@@ -3251,7 +3260,7 @@ ahd_handle_nonpkt_busfree(struct ahd_softc *ahd) | |||
3251 | * the message phases. We check it last in case we | 3260 | * the message phases. We check it last in case we |
3252 | * had to send some other message that caused a busfree. | 3261 | * had to send some other message that caused a busfree. |
3253 | */ | 3262 | */ |
3254 | if (printerror != 0 | 3263 | if (scb != NULL && printerror != 0 |
3255 | && (lastphase == P_MESGIN || lastphase == P_MESGOUT) | 3264 | && (lastphase == P_MESGIN || lastphase == P_MESGOUT) |
3256 | && ((ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0)) { | 3265 | && ((ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0)) { |
3257 | 3266 | ||