]>
Commit | Line | Data |
---|---|---|
8de80845 GKH |
1 | From 534ef056db8a8fb6b9d50188d88ed5d1fbc66673 Mon Sep 17 00:00:00 2001 |
2 | From: Hannes Reinecke <hare@suse.de> | |
3 | Date: Fri, 15 Jan 2010 13:07:34 +0100 | |
4 | Subject: [SCSI] aic79xx: check for non-NULL scb in ahd_handle_nonpkt_busfree | |
5 | ||
6 | From: Hannes Reinecke <hare@suse.de> | |
7 | ||
8 | commit 534ef056db8a8fb6b9d50188d88ed5d1fbc66673 upstream. | |
9 | ||
10 | When removing several devices aic79xx will occasionally Oops | |
11 | in ahd_handle_nonpkt_busfree during rescan. Looking at the | |
12 | code I found that we're indeed not checking if the scb in | |
13 | question is NULL. So check for it before accessing it. | |
14 | ||
15 | Signed-off-by: Hannes Reinecke <hare@suse.de> | |
16 | Signed-off-by: James Bottomley <James.Bottomley@suse.de> | |
17 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
18 | ||
19 | --- | |
20 | drivers/scsi/aic7xxx/aic79xx_core.c | 53 +++++++++++++++++++++--------------- | |
21 | 1 file changed, 31 insertions(+), 22 deletions(-) | |
22 | ||
23 | --- a/drivers/scsi/aic7xxx/aic79xx_core.c | |
24 | +++ b/drivers/scsi/aic7xxx/aic79xx_core.c | |
25 | @@ -3171,13 +3171,16 @@ ahd_handle_nonpkt_busfree(struct ahd_sof | |
26 | tinfo->curr.transport_version = 2; | |
27 | tinfo->goal.transport_version = 2; | |
28 | tinfo->goal.ppr_options = 0; | |
29 | - /* | |
30 | - * Remove any SCBs in the waiting for selection | |
31 | - * queue that may also be for this target so | |
32 | - * that command ordering is preserved. | |
33 | - */ | |
34 | - ahd_freeze_devq(ahd, scb); | |
35 | - ahd_qinfifo_requeue_tail(ahd, scb); | |
36 | + if (scb != NULL) { | |
37 | + /* | |
38 | + * Remove any SCBs in the waiting | |
39 | + * for selection queue that may | |
40 | + * also be for this target so that | |
41 | + * command ordering is preserved. | |
42 | + */ | |
43 | + ahd_freeze_devq(ahd, scb); | |
44 | + ahd_qinfifo_requeue_tail(ahd, scb); | |
45 | + } | |
46 | printerror = 0; | |
47 | } | |
48 | } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_WDTR, FALSE) | |
49 | @@ -3194,13 +3197,16 @@ ahd_handle_nonpkt_busfree(struct ahd_sof | |
50 | MSG_EXT_WDTR_BUS_8_BIT, | |
51 | AHD_TRANS_CUR|AHD_TRANS_GOAL, | |
52 | /*paused*/TRUE); | |
53 | - /* | |
54 | - * Remove any SCBs in the waiting for selection | |
55 | - * queue that may also be for this target so that | |
56 | - * command ordering is preserved. | |
57 | - */ | |
58 | - ahd_freeze_devq(ahd, scb); | |
59 | - ahd_qinfifo_requeue_tail(ahd, scb); | |
60 | + if (scb != NULL) { | |
61 | + /* | |
62 | + * Remove any SCBs in the waiting for | |
63 | + * selection queue that may also be for | |
64 | + * this target so that command ordering | |
65 | + * is preserved. | |
66 | + */ | |
67 | + ahd_freeze_devq(ahd, scb); | |
68 | + ahd_qinfifo_requeue_tail(ahd, scb); | |
69 | + } | |
70 | printerror = 0; | |
71 | } else if (ahd_sent_msg(ahd, AHDMSG_EXT, MSG_EXT_SDTR, FALSE) | |
72 | && ppr_busfree == 0) { | |
73 | @@ -3217,13 +3223,16 @@ ahd_handle_nonpkt_busfree(struct ahd_sof | |
74 | /*ppr_options*/0, | |
75 | AHD_TRANS_CUR|AHD_TRANS_GOAL, | |
76 | /*paused*/TRUE); | |
77 | - /* | |
78 | - * Remove any SCBs in the waiting for selection | |
79 | - * queue that may also be for this target so that | |
80 | - * command ordering is preserved. | |
81 | - */ | |
82 | - ahd_freeze_devq(ahd, scb); | |
83 | - ahd_qinfifo_requeue_tail(ahd, scb); | |
84 | + if (scb != NULL) { | |
85 | + /* | |
86 | + * Remove any SCBs in the waiting for | |
87 | + * selection queue that may also be for | |
88 | + * this target so that command ordering | |
89 | + * is preserved. | |
90 | + */ | |
91 | + ahd_freeze_devq(ahd, scb); | |
92 | + ahd_qinfifo_requeue_tail(ahd, scb); | |
93 | + } | |
94 | printerror = 0; | |
95 | } else if ((ahd->msg_flags & MSG_FLAG_EXPECT_IDE_BUSFREE) != 0 | |
96 | && ahd_sent_msg(ahd, AHDMSG_1B, | |
97 | @@ -3251,7 +3260,7 @@ ahd_handle_nonpkt_busfree(struct ahd_sof | |
98 | * the message phases. We check it last in case we | |
99 | * had to send some other message that caused a busfree. | |
100 | */ | |
101 | - if (printerror != 0 | |
102 | + if (scb != NULL && printerror != 0 | |
103 | && (lastphase == P_MESGIN || lastphase == P_MESGOUT) | |
104 | && ((ahd->msg_flags & MSG_FLAG_EXPECT_PPR_BUSFREE) != 0)) { | |
105 |