38
38
#define HP_SW_PATH_PASSIVE 1
39
39
40
40
struct hp_sw_dh_data {
41
- unsigned char sense [SCSI_SENSE_BUFFERSIZE ];
42
41
int path_state ;
43
42
int retries ;
44
43
int retry_cnt ;
45
44
struct scsi_device * sdev ;
46
- activate_complete callback_fn ;
47
- void * callback_data ;
48
45
};
49
46
50
47
static int hp_sw_start_stop (struct hp_sw_dh_data * );
@@ -56,43 +53,34 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *);
56
53
*
57
54
* Returns SCSI_DH_DEV_OFFLINED if the sdev is on the passive path
58
55
*/
59
- static int tur_done (struct scsi_device * sdev , unsigned char * sense )
56
+ static int tur_done (struct scsi_device * sdev , struct hp_sw_dh_data * h ,
57
+ struct scsi_sense_hdr * sshdr )
60
58
{
61
- struct scsi_sense_hdr sshdr ;
62
- int ret ;
59
+ int ret = SCSI_DH_IO ;
63
60
64
- ret = scsi_normalize_sense (sense , SCSI_SENSE_BUFFERSIZE , & sshdr );
65
- if (!ret ) {
66
- sdev_printk (KERN_WARNING , sdev ,
67
- "%s: sending tur failed, no sense available\n" ,
68
- HP_SW_NAME );
69
- ret = SCSI_DH_IO ;
70
- goto done ;
71
- }
72
- switch (sshdr .sense_key ) {
61
+ switch (sshdr -> sense_key ) {
73
62
case UNIT_ATTENTION :
74
63
ret = SCSI_DH_IMM_RETRY ;
75
64
break ;
76
65
case NOT_READY :
77
- if (( sshdr . asc == 0x04 ) && ( sshdr . ascq == 2 ) ) {
66
+ if (sshdr -> asc == 0x04 && sshdr -> ascq == 2 ) {
78
67
/*
79
68
* LUN not ready - Initialization command required
80
69
*
81
70
* This is the passive path
82
71
*/
83
- ret = SCSI_DH_DEV_OFFLINED ;
72
+ h -> path_state = HP_SW_PATH_PASSIVE ;
73
+ ret = SCSI_DH_OK ;
84
74
break ;
85
75
}
86
76
/* Fallthrough */
87
77
default :
88
78
sdev_printk (KERN_WARNING , sdev ,
89
79
"%s: sending tur failed, sense %x/%x/%x\n" ,
90
- HP_SW_NAME , sshdr . sense_key , sshdr . asc ,
91
- sshdr . ascq );
80
+ HP_SW_NAME , sshdr -> sense_key , sshdr -> asc ,
81
+ sshdr -> ascq );
92
82
break ;
93
83
}
94
-
95
- done :
96
84
return ret ;
97
85
}
98
86
@@ -105,130 +93,35 @@ static int tur_done(struct scsi_device *sdev, unsigned char *sense)
105
93
*/
106
94
static int hp_sw_tur (struct scsi_device * sdev , struct hp_sw_dh_data * h )
107
95
{
108
- struct request * req ;
109
- int ret ;
96
+ unsigned char cmd [6 ] = { TEST_UNIT_READY };
97
+ struct scsi_sense_hdr sshdr ;
98
+ int ret = SCSI_DH_OK , res ;
99
+ u64 req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
100
+ REQ_FAILFAST_DRIVER ;
110
101
111
102
retry :
112
- req = blk_get_request (sdev -> request_queue , WRITE , GFP_NOIO );
113
- if (IS_ERR (req ))
114
- return SCSI_DH_RES_TEMP_UNAVAIL ;
115
-
116
- blk_rq_set_block_pc (req );
117
- req -> cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
118
- REQ_FAILFAST_DRIVER ;
119
- req -> cmd_len = COMMAND_SIZE (TEST_UNIT_READY );
120
- req -> cmd [0 ] = TEST_UNIT_READY ;
121
- req -> timeout = HP_SW_TIMEOUT ;
122
- req -> sense = h -> sense ;
123
- memset (req -> sense , 0 , SCSI_SENSE_BUFFERSIZE );
124
- req -> sense_len = 0 ;
125
-
126
- ret = blk_execute_rq (req -> q , NULL , req , 1 );
127
- if (ret == - EIO ) {
128
- if (req -> sense_len > 0 ) {
129
- ret = tur_done (sdev , h -> sense );
130
- } else {
103
+ res = scsi_execute_req_flags (sdev , cmd , DMA_NONE , NULL , 0 , & sshdr ,
104
+ HP_SW_TIMEOUT , HP_SW_RETRIES ,
105
+ NULL , req_flags , 0 );
106
+ if (res ) {
107
+ if (scsi_sense_valid (& sshdr ))
108
+ ret = tur_done (sdev , h , & sshdr );
109
+ else {
131
110
sdev_printk (KERN_WARNING , sdev ,
132
111
"%s: sending tur failed with %x\n" ,
133
- HP_SW_NAME , req -> errors );
112
+ HP_SW_NAME , res );
134
113
ret = SCSI_DH_IO ;
135
114
}
136
115
} else {
137
116
h -> path_state = HP_SW_PATH_ACTIVE ;
138
117
ret = SCSI_DH_OK ;
139
118
}
140
- if (ret == SCSI_DH_IMM_RETRY ) {
141
- blk_put_request (req );
119
+ if (ret == SCSI_DH_IMM_RETRY )
142
120
goto retry ;
143
- }
144
- if (ret == SCSI_DH_DEV_OFFLINED ) {
145
- h -> path_state = HP_SW_PATH_PASSIVE ;
146
- ret = SCSI_DH_OK ;
147
- }
148
-
149
- blk_put_request (req );
150
121
151
122
return ret ;
152
123
}
153
124
154
- /*
155
- * start_done - Handle START STOP UNIT return status
156
- * @sdev: sdev the command has been sent to
157
- * @errors: blk error code
158
- */
159
- static int start_done (struct scsi_device * sdev , unsigned char * sense )
160
- {
161
- struct scsi_sense_hdr sshdr ;
162
- int rc ;
163
-
164
- rc = scsi_normalize_sense (sense , SCSI_SENSE_BUFFERSIZE , & sshdr );
165
- if (!rc ) {
166
- sdev_printk (KERN_WARNING , sdev ,
167
- "%s: sending start_stop_unit failed, "
168
- "no sense available\n" ,
169
- HP_SW_NAME );
170
- return SCSI_DH_IO ;
171
- }
172
- switch (sshdr .sense_key ) {
173
- case NOT_READY :
174
- if ((sshdr .asc == 0x04 ) && (sshdr .ascq == 3 )) {
175
- /*
176
- * LUN not ready - manual intervention required
177
- *
178
- * Switch-over in progress, retry.
179
- */
180
- rc = SCSI_DH_RETRY ;
181
- break ;
182
- }
183
- /* fall through */
184
- default :
185
- sdev_printk (KERN_WARNING , sdev ,
186
- "%s: sending start_stop_unit failed, sense %x/%x/%x\n" ,
187
- HP_SW_NAME , sshdr .sense_key , sshdr .asc ,
188
- sshdr .ascq );
189
- rc = SCSI_DH_IO ;
190
- }
191
-
192
- return rc ;
193
- }
194
-
195
- static void start_stop_endio (struct request * req , int error )
196
- {
197
- struct hp_sw_dh_data * h = req -> end_io_data ;
198
- unsigned err = SCSI_DH_OK ;
199
-
200
- if (error || host_byte (req -> errors ) != DID_OK ||
201
- msg_byte (req -> errors ) != COMMAND_COMPLETE ) {
202
- sdev_printk (KERN_WARNING , h -> sdev ,
203
- "%s: sending start_stop_unit failed with %x\n" ,
204
- HP_SW_NAME , req -> errors );
205
- err = SCSI_DH_IO ;
206
- goto done ;
207
- }
208
-
209
- if (req -> sense_len > 0 ) {
210
- err = start_done (h -> sdev , h -> sense );
211
- if (err == SCSI_DH_RETRY ) {
212
- err = SCSI_DH_IO ;
213
- if (-- h -> retry_cnt ) {
214
- blk_put_request (req );
215
- err = hp_sw_start_stop (h );
216
- if (err == SCSI_DH_OK )
217
- return ;
218
- }
219
- }
220
- }
221
- done :
222
- req -> end_io_data = NULL ;
223
- __blk_put_request (req -> q , req );
224
- if (h -> callback_fn ) {
225
- h -> callback_fn (h -> callback_data , err );
226
- h -> callback_fn = h -> callback_data = NULL ;
227
- }
228
- return ;
229
-
230
- }
231
-
232
125
/*
233
126
* hp_sw_start_stop - Send START STOP UNIT command
234
127
* @sdev: sdev command should be sent to
@@ -237,26 +130,48 @@ static void start_stop_endio(struct request *req, int error)
237
130
*/
238
131
static int hp_sw_start_stop (struct hp_sw_dh_data * h )
239
132
{
240
- struct request * req ;
241
-
242
- req = blk_get_request (h -> sdev -> request_queue , WRITE , GFP_ATOMIC );
243
- if (IS_ERR (req ))
244
- return SCSI_DH_RES_TEMP_UNAVAIL ;
245
-
246
- blk_rq_set_block_pc (req );
247
- req -> cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
248
- REQ_FAILFAST_DRIVER ;
249
- req -> cmd_len = COMMAND_SIZE (START_STOP );
250
- req -> cmd [0 ] = START_STOP ;
251
- req -> cmd [4 ] = 1 ; /* Start spin cycle */
252
- req -> timeout = HP_SW_TIMEOUT ;
253
- req -> sense = h -> sense ;
254
- memset (req -> sense , 0 , SCSI_SENSE_BUFFERSIZE );
255
- req -> sense_len = 0 ;
256
- req -> end_io_data = h ;
133
+ unsigned char cmd [6 ] = { START_STOP , 0 , 0 , 0 , 1 , 0 };
134
+ struct scsi_sense_hdr sshdr ;
135
+ struct scsi_device * sdev = h -> sdev ;
136
+ int res , rc = SCSI_DH_OK ;
137
+ int retry_cnt = HP_SW_RETRIES ;
138
+ u64 req_flags = REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
139
+ REQ_FAILFAST_DRIVER ;
257
140
258
- blk_execute_rq_nowait (req -> q , NULL , req , 1 , start_stop_endio );
259
- return SCSI_DH_OK ;
141
+ retry :
142
+ res = scsi_execute_req_flags (sdev , cmd , DMA_NONE , NULL , 0 , & sshdr ,
143
+ HP_SW_TIMEOUT , HP_SW_RETRIES ,
144
+ NULL , req_flags , 0 );
145
+ if (res ) {
146
+ if (!scsi_sense_valid (& sshdr )) {
147
+ sdev_printk (KERN_WARNING , sdev ,
148
+ "%s: sending start_stop_unit failed, "
149
+ "no sense available\n" , HP_SW_NAME );
150
+ return SCSI_DH_IO ;
151
+ }
152
+ switch (sshdr .sense_key ) {
153
+ case NOT_READY :
154
+ if (sshdr .asc == 0x04 && sshdr .ascq == 3 ) {
155
+ /*
156
+ * LUN not ready - manual intervention required
157
+ *
158
+ * Switch-over in progress, retry.
159
+ */
160
+ if (-- retry_cnt )
161
+ goto retry ;
162
+ rc = SCSI_DH_RETRY ;
163
+ break ;
164
+ }
165
+ /* fall through */
166
+ default :
167
+ sdev_printk (KERN_WARNING , sdev ,
168
+ "%s: sending start_stop_unit failed, "
169
+ "sense %x/%x/%x\n" , HP_SW_NAME ,
170
+ sshdr .sense_key , sshdr .asc , sshdr .ascq );
171
+ rc = SCSI_DH_IO ;
172
+ }
173
+ }
174
+ return rc ;
260
175
}
261
176
262
177
static int hp_sw_prep_fn (struct scsi_device * sdev , struct request * req )
@@ -290,15 +205,8 @@ static int hp_sw_activate(struct scsi_device *sdev,
290
205
291
206
ret = hp_sw_tur (sdev , h );
292
207
293
- if (ret == SCSI_DH_OK && h -> path_state == HP_SW_PATH_PASSIVE ) {
294
- h -> retry_cnt = h -> retries ;
295
- h -> callback_fn = fn ;
296
- h -> callback_data = data ;
208
+ if (ret == SCSI_DH_OK && h -> path_state == HP_SW_PATH_PASSIVE )
297
209
ret = hp_sw_start_stop (h );
298
- if (ret == SCSI_DH_OK )
299
- return 0 ;
300
- h -> callback_fn = h -> callback_data = NULL ;
301
- }
302
210
303
211
if (fn )
304
212
fn (data , ret );
0 commit comments