diff options
Diffstat (limited to 'drivers/scsi/constants.c')
-rw-r--r-- | drivers/scsi/constants.c | 274 |
1 files changed, 151 insertions, 123 deletions
diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index 61f6024b61ba..2a458d66b6ff 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c | |||
@@ -202,31 +202,29 @@ static const char * get_sa_name(const struct value_name_pair * arr, | |||
202 | } | 202 | } |
203 | 203 | ||
204 | /* attempt to guess cdb length if cdb_len==0 . No trailing linefeed. */ | 204 | /* attempt to guess cdb length if cdb_len==0 . No trailing linefeed. */ |
205 | static void print_opcode_name(unsigned char * cdbp, int cdb_len, | 205 | static void print_opcode_name(unsigned char * cdbp, int cdb_len) |
206 | int start_of_line) | ||
207 | { | 206 | { |
208 | int sa, len, cdb0; | 207 | int sa, len, cdb0; |
209 | const char * name; | 208 | const char * name; |
210 | const char * leadin = start_of_line ? KERN_INFO : ""; | ||
211 | 209 | ||
212 | cdb0 = cdbp[0]; | 210 | cdb0 = cdbp[0]; |
213 | switch(cdb0) { | 211 | switch(cdb0) { |
214 | case VARIABLE_LENGTH_CMD: | 212 | case VARIABLE_LENGTH_CMD: |
215 | len = cdbp[7] + 8; | 213 | len = cdbp[7] + 8; |
216 | if (len < 10) { | 214 | if (len < 10) { |
217 | printk("%sshort variable length command, " | 215 | printk("short variable length command, " |
218 | "len=%d ext_len=%d", leadin, len, cdb_len); | 216 | "len=%d ext_len=%d", len, cdb_len); |
219 | break; | 217 | break; |
220 | } | 218 | } |
221 | sa = (cdbp[8] << 8) + cdbp[9]; | 219 | sa = (cdbp[8] << 8) + cdbp[9]; |
222 | name = get_sa_name(maint_in_arr, MAINT_IN_SZ, sa); | 220 | name = get_sa_name(maint_in_arr, MAINT_IN_SZ, sa); |
223 | if (name) { | 221 | if (name) { |
224 | printk("%s%s", leadin, name); | 222 | printk("%s", name); |
225 | if ((cdb_len > 0) && (len != cdb_len)) | 223 | if ((cdb_len > 0) && (len != cdb_len)) |
226 | printk(", in_cdb_len=%d, ext_len=%d", | 224 | printk(", in_cdb_len=%d, ext_len=%d", |
227 | len, cdb_len); | 225 | len, cdb_len); |
228 | } else { | 226 | } else { |
229 | printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); | 227 | printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); |
230 | if ((cdb_len > 0) && (len != cdb_len)) | 228 | if ((cdb_len > 0) && (len != cdb_len)) |
231 | printk(", in_cdb_len=%d, ext_len=%d", | 229 | printk(", in_cdb_len=%d, ext_len=%d", |
232 | len, cdb_len); | 230 | len, cdb_len); |
@@ -236,83 +234,80 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len, | |||
236 | sa = cdbp[1] & 0x1f; | 234 | sa = cdbp[1] & 0x1f; |
237 | name = get_sa_name(maint_in_arr, MAINT_IN_SZ, sa); | 235 | name = get_sa_name(maint_in_arr, MAINT_IN_SZ, sa); |
238 | if (name) | 236 | if (name) |
239 | printk("%s%s", leadin, name); | 237 | printk("%s", name); |
240 | else | 238 | else |
241 | printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); | 239 | printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); |
242 | break; | 240 | break; |
243 | case MAINTENANCE_OUT: | 241 | case MAINTENANCE_OUT: |
244 | sa = cdbp[1] & 0x1f; | 242 | sa = cdbp[1] & 0x1f; |
245 | name = get_sa_name(maint_out_arr, MAINT_OUT_SZ, sa); | 243 | name = get_sa_name(maint_out_arr, MAINT_OUT_SZ, sa); |
246 | if (name) | 244 | if (name) |
247 | printk("%s%s", leadin, name); | 245 | printk("%s", name); |
248 | else | 246 | else |
249 | printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); | 247 | printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); |
250 | break; | 248 | break; |
251 | case SERVICE_ACTION_IN_12: | 249 | case SERVICE_ACTION_IN_12: |
252 | sa = cdbp[1] & 0x1f; | 250 | sa = cdbp[1] & 0x1f; |
253 | name = get_sa_name(serv_in12_arr, SERV_IN12_SZ, sa); | 251 | name = get_sa_name(serv_in12_arr, SERV_IN12_SZ, sa); |
254 | if (name) | 252 | if (name) |
255 | printk("%s%s", leadin, name); | 253 | printk("%s", name); |
256 | else | 254 | else |
257 | printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); | 255 | printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); |
258 | break; | 256 | break; |
259 | case SERVICE_ACTION_OUT_12: | 257 | case SERVICE_ACTION_OUT_12: |
260 | sa = cdbp[1] & 0x1f; | 258 | sa = cdbp[1] & 0x1f; |
261 | name = get_sa_name(serv_out12_arr, SERV_OUT12_SZ, sa); | 259 | name = get_sa_name(serv_out12_arr, SERV_OUT12_SZ, sa); |
262 | if (name) | 260 | if (name) |
263 | printk("%s%s", leadin, name); | 261 | printk("%s", name); |
264 | else | 262 | else |
265 | printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); | 263 | printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); |
266 | break; | 264 | break; |
267 | case SERVICE_ACTION_IN_16: | 265 | case SERVICE_ACTION_IN_16: |
268 | sa = cdbp[1] & 0x1f; | 266 | sa = cdbp[1] & 0x1f; |
269 | name = get_sa_name(serv_in16_arr, SERV_IN16_SZ, sa); | 267 | name = get_sa_name(serv_in16_arr, SERV_IN16_SZ, sa); |
270 | if (name) | 268 | if (name) |
271 | printk("%s%s", leadin, name); | 269 | printk("%s", name); |
272 | else | 270 | else |
273 | printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); | 271 | printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); |
274 | break; | 272 | break; |
275 | case SERVICE_ACTION_OUT_16: | 273 | case SERVICE_ACTION_OUT_16: |
276 | sa = cdbp[1] & 0x1f; | 274 | sa = cdbp[1] & 0x1f; |
277 | name = get_sa_name(serv_out16_arr, SERV_OUT16_SZ, sa); | 275 | name = get_sa_name(serv_out16_arr, SERV_OUT16_SZ, sa); |
278 | if (name) | 276 | if (name) |
279 | printk("%s%s", leadin, name); | 277 | printk("%s", name); |
280 | else | 278 | else |
281 | printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); | 279 | printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); |
282 | break; | 280 | break; |
283 | default: | 281 | default: |
284 | if (cdb0 < 0xc0) { | 282 | if (cdb0 < 0xc0) { |
285 | name = cdb_byte0_names[cdb0]; | 283 | name = cdb_byte0_names[cdb0]; |
286 | if (name) | 284 | if (name) |
287 | printk("%s%s", leadin, name); | 285 | printk("%s", name); |
288 | else | 286 | else |
289 | printk("%scdb[0]=0x%x (reserved)", | 287 | printk("cdb[0]=0x%x (reserved)", cdb0); |
290 | leadin, cdb0); | ||
291 | } else | 288 | } else |
292 | printk("%scdb[0]=0x%x (vendor)", leadin, cdb0); | 289 | printk("cdb[0]=0x%x (vendor)", cdb0); |
293 | break; | 290 | break; |
294 | } | 291 | } |
295 | } | 292 | } |
296 | 293 | ||
297 | #else /* ifndef CONFIG_SCSI_CONSTANTS */ | 294 | #else /* ifndef CONFIG_SCSI_CONSTANTS */ |
298 | 295 | ||
299 | static void print_opcode_name(unsigned char * cdbp, int cdb_len, | 296 | static void print_opcode_name(unsigned char * cdbp, int cdb_len) |
300 | int start_of_line) | ||
301 | { | 297 | { |
302 | int sa, len, cdb0; | 298 | int sa, len, cdb0; |
303 | const char * leadin = start_of_line ? KERN_INFO : ""; | ||
304 | 299 | ||
305 | cdb0 = cdbp[0]; | 300 | cdb0 = cdbp[0]; |
306 | switch(cdb0) { | 301 | switch(cdb0) { |
307 | case VARIABLE_LENGTH_CMD: | 302 | case VARIABLE_LENGTH_CMD: |
308 | len = cdbp[7] + 8; | 303 | len = cdbp[7] + 8; |
309 | if (len < 10) { | 304 | if (len < 10) { |
310 | printk("%sshort opcode=0x%x command, len=%d " | 305 | printk("short opcode=0x%x command, len=%d " |
311 | "ext_len=%d", leadin, cdb0, len, cdb_len); | 306 | "ext_len=%d", cdb0, len, cdb_len); |
312 | break; | 307 | break; |
313 | } | 308 | } |
314 | sa = (cdbp[8] << 8) + cdbp[9]; | 309 | sa = (cdbp[8] << 8) + cdbp[9]; |
315 | printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); | 310 | printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); |
316 | if (len != cdb_len) | 311 | if (len != cdb_len) |
317 | printk(", in_cdb_len=%d, ext_len=%d", len, cdb_len); | 312 | printk(", in_cdb_len=%d, ext_len=%d", len, cdb_len); |
318 | break; | 313 | break; |
@@ -323,49 +318,48 @@ static void print_opcode_name(unsigned char * cdbp, int cdb_len, | |||
323 | case SERVICE_ACTION_IN_16: | 318 | case SERVICE_ACTION_IN_16: |
324 | case SERVICE_ACTION_OUT_16: | 319 | case SERVICE_ACTION_OUT_16: |
325 | sa = cdbp[1] & 0x1f; | 320 | sa = cdbp[1] & 0x1f; |
326 | printk("%scdb[0]=0x%x, sa=0x%x", leadin, cdb0, sa); | 321 | printk("cdb[0]=0x%x, sa=0x%x", cdb0, sa); |
327 | break; | 322 | break; |
328 | default: | 323 | default: |
329 | if (cdb0 < 0xc0) | 324 | if (cdb0 < 0xc0) |
330 | printk("%scdb[0]=0x%x", leadin, cdb0); | 325 | printk("cdb[0]=0x%x", cdb0); |
331 | else | 326 | else |
332 | printk("%scdb[0]=0x%x (vendor)", leadin, cdb0); | 327 | printk("cdb[0]=0x%x (vendor)", cdb0); |
333 | break; | 328 | break; |
334 | } | 329 | } |
335 | } | 330 | } |
336 | #endif | 331 | #endif |
337 | 332 | ||
338 | void __scsi_print_command(unsigned char *command) | 333 | void __scsi_print_command(unsigned char *cdb) |
339 | { | 334 | { |
340 | int k, len; | 335 | int k, len; |
341 | 336 | ||
342 | print_opcode_name(command, 0, 1); | 337 | print_opcode_name(cdb, 0); |
343 | if (VARIABLE_LENGTH_CMD == command[0]) | 338 | if (VARIABLE_LENGTH_CMD == cdb[0]) |
344 | len = command[7] + 8; | 339 | len = cdb[7] + 8; |
345 | else | 340 | else |
346 | len = COMMAND_SIZE(command[0]); | 341 | len = COMMAND_SIZE(cdb[0]); |
347 | /* print out all bytes in cdb */ | 342 | /* print out all bytes in cdb */ |
348 | for (k = 0; k < len; ++k) | 343 | for (k = 0; k < len; ++k) |
349 | printk(" %02x", command[k]); | 344 | printk(" %02x", cdb[k]); |
350 | printk("\n"); | 345 | printk("\n"); |
351 | } | 346 | } |
352 | EXPORT_SYMBOL(__scsi_print_command); | 347 | EXPORT_SYMBOL(__scsi_print_command); |
353 | 348 | ||
354 | /* This function (perhaps with the addition of peripheral device type) | 349 | void scsi_print_command(struct scsi_cmnd *cmd) |
355 | * is more approriate than __scsi_print_command(). Perhaps that static | ||
356 | * can be dropped later if it replaces the __scsi_print_command version. | ||
357 | */ | ||
358 | static void scsi_print_cdb(unsigned char *cdb, int cdb_len, int start_of_line) | ||
359 | { | 350 | { |
360 | int k; | 351 | int k; |
361 | 352 | ||
362 | print_opcode_name(cdb, cdb_len, start_of_line); | 353 | scmd_printk(KERN_INFO, cmd, "CDB: "); |
354 | print_opcode_name(cmd->cmnd, cmd->cmd_len); | ||
355 | |||
363 | /* print out all bytes in cdb */ | 356 | /* print out all bytes in cdb */ |
364 | printk(":"); | 357 | printk(":"); |
365 | for (k = 0; k < cdb_len; ++k) | 358 | for (k = 0; k < cmd->cmd_len; ++k) |
366 | printk(" %02x", cdb[k]); | 359 | printk(" %02x", cmd->cmnd[k]); |
367 | printk("\n"); | 360 | printk("\n"); |
368 | } | 361 | } |
362 | EXPORT_SYMBOL(scsi_print_command); | ||
369 | 363 | ||
370 | /** | 364 | /** |
371 | * | 365 | * |
@@ -410,7 +404,11 @@ struct error_info { | |||
410 | const char * text; | 404 | const char * text; |
411 | }; | 405 | }; |
412 | 406 | ||
413 | static struct error_info additional[] = | 407 | /* |
408 | * The canonical list of T10 Additional Sense Codes is available at: | ||
409 | * http://www.t10.org/lists/asc-num.txt | ||
410 | */ | ||
411 | static const struct error_info additional[] = | ||
414 | { | 412 | { |
415 | {0x0000, "No additional sense information"}, | 413 | {0x0000, "No additional sense information"}, |
416 | {0x0001, "Filemark detected"}, | 414 | {0x0001, "Filemark detected"}, |
@@ -714,6 +712,7 @@ static struct error_info additional[] = | |||
714 | 712 | ||
715 | {0x2F00, "Commands cleared by another initiator"}, | 713 | {0x2F00, "Commands cleared by another initiator"}, |
716 | {0x2F01, "Commands cleared by power loss notification"}, | 714 | {0x2F01, "Commands cleared by power loss notification"}, |
715 | {0x2F02, "Commands cleared by device server"}, | ||
717 | 716 | ||
718 | {0x3000, "Incompatible medium installed"}, | 717 | {0x3000, "Incompatible medium installed"}, |
719 | {0x3001, "Cannot read medium - unknown format"}, | 718 | {0x3001, "Cannot read medium - unknown format"}, |
@@ -1176,67 +1175,77 @@ scsi_extd_sense_format(unsigned char asc, unsigned char ascq) { | |||
1176 | } | 1175 | } |
1177 | EXPORT_SYMBOL(scsi_extd_sense_format); | 1176 | EXPORT_SYMBOL(scsi_extd_sense_format); |
1178 | 1177 | ||
1179 | /* Print extended sense information; no leadin, no linefeed */ | 1178 | void |
1180 | static void | ||
1181 | scsi_show_extd_sense(unsigned char asc, unsigned char ascq) | 1179 | scsi_show_extd_sense(unsigned char asc, unsigned char ascq) |
1182 | { | 1180 | { |
1183 | const char *extd_sense_fmt = scsi_extd_sense_format(asc, ascq); | 1181 | const char *extd_sense_fmt = scsi_extd_sense_format(asc, ascq); |
1184 | 1182 | ||
1185 | if (extd_sense_fmt) { | 1183 | if (extd_sense_fmt) { |
1186 | if (strstr(extd_sense_fmt, "%x")) { | 1184 | if (strstr(extd_sense_fmt, "%x")) { |
1187 | printk("Additional sense: "); | 1185 | printk("Add. Sense: "); |
1188 | printk(extd_sense_fmt, ascq); | 1186 | printk(extd_sense_fmt, ascq); |
1189 | } else | 1187 | } else |
1190 | printk("Additional sense: %s", extd_sense_fmt); | 1188 | printk("Add. Sense: %s", extd_sense_fmt); |
1191 | } else { | 1189 | } else { |
1192 | if (asc >= 0x80) | 1190 | if (asc >= 0x80) |
1193 | printk("<<vendor>> ASC=0x%x ASCQ=0x%x", asc, ascq); | 1191 | printk("<<vendor>> ASC=0x%x ASCQ=0x%x", asc, |
1192 | ascq); | ||
1194 | if (ascq >= 0x80) | 1193 | if (ascq >= 0x80) |
1195 | printk("ASC=0x%x <<vendor>> ASCQ=0x%x", asc, ascq); | 1194 | printk("ASC=0x%x <<vendor>> ASCQ=0x%x", asc, |
1195 | ascq); | ||
1196 | else | 1196 | else |
1197 | printk("ASC=0x%x ASCQ=0x%x", asc, ascq); | 1197 | printk("ASC=0x%x ASCQ=0x%x", asc, ascq); |
1198 | } | 1198 | } |
1199 | |||
1200 | printk("\n"); | ||
1199 | } | 1201 | } |
1202 | EXPORT_SYMBOL(scsi_show_extd_sense); | ||
1200 | 1203 | ||
1201 | void | 1204 | void |
1202 | scsi_print_sense_hdr(const char *name, struct scsi_sense_hdr *sshdr) | 1205 | scsi_show_sense_hdr(struct scsi_sense_hdr *sshdr) |
1203 | { | 1206 | { |
1204 | const char *sense_txt; | 1207 | const char *sense_txt; |
1205 | /* An example of deferred is when an earlier write to disk cache | ||
1206 | * succeeded, but now the disk discovers that it cannot write the | ||
1207 | * data to the magnetic media. | ||
1208 | */ | ||
1209 | const char *error = scsi_sense_is_deferred(sshdr) ? | ||
1210 | "<<DEFERRED>>" : "Current"; | ||
1211 | printk(KERN_INFO "%s: %s", name, error); | ||
1212 | if (sshdr->response_code >= 0x72) | ||
1213 | printk(" [descriptor]"); | ||
1214 | 1208 | ||
1215 | sense_txt = scsi_sense_key_string(sshdr->sense_key); | 1209 | sense_txt = scsi_sense_key_string(sshdr->sense_key); |
1216 | if (sense_txt) | 1210 | if (sense_txt) |
1217 | printk(": sense key: %s\n", sense_txt); | 1211 | printk("Sense Key : %s ", sense_txt); |
1218 | else | 1212 | else |
1219 | printk(": sense key=0x%x\n", sshdr->sense_key); | 1213 | printk("Sense Key : 0x%x ", sshdr->sense_key); |
1220 | printk(KERN_INFO " "); | 1214 | |
1221 | scsi_show_extd_sense(sshdr->asc, sshdr->ascq); | 1215 | printk("%s", scsi_sense_is_deferred(sshdr) ? "[deferred] " : |
1216 | "[current] "); | ||
1217 | |||
1218 | if (sshdr->response_code >= 0x72) | ||
1219 | printk("[descriptor]"); | ||
1220 | |||
1222 | printk("\n"); | 1221 | printk("\n"); |
1223 | } | 1222 | } |
1223 | EXPORT_SYMBOL(scsi_show_sense_hdr); | ||
1224 | |||
1225 | /* | ||
1226 | * Print normalized SCSI sense header with a prefix. | ||
1227 | */ | ||
1228 | void | ||
1229 | scsi_print_sense_hdr(const char *name, struct scsi_sense_hdr *sshdr) | ||
1230 | { | ||
1231 | printk(KERN_INFO "%s: ", name); | ||
1232 | scsi_show_sense_hdr(sshdr); | ||
1233 | printk(KERN_INFO "%s: ", name); | ||
1234 | scsi_show_extd_sense(sshdr->asc, sshdr->ascq); | ||
1235 | } | ||
1224 | EXPORT_SYMBOL(scsi_print_sense_hdr); | 1236 | EXPORT_SYMBOL(scsi_print_sense_hdr); |
1225 | 1237 | ||
1226 | /* Print sense information */ | ||
1227 | void | 1238 | void |
1228 | __scsi_print_sense(const char *name, const unsigned char *sense_buffer, | 1239 | scsi_decode_sense_buffer(const unsigned char *sense_buffer, int sense_len, |
1229 | int sense_len) | 1240 | struct scsi_sense_hdr *sshdr) |
1230 | { | 1241 | { |
1231 | int k, num, res; | 1242 | int k, num, res; |
1232 | unsigned int info; | ||
1233 | struct scsi_sense_hdr ssh; | ||
1234 | 1243 | ||
1235 | res = scsi_normalize_sense(sense_buffer, sense_len, &ssh); | 1244 | res = scsi_normalize_sense(sense_buffer, sense_len, sshdr); |
1236 | if (0 == res) { | 1245 | if (0 == res) { |
1237 | /* this may be SCSI-1 sense data */ | 1246 | /* this may be SCSI-1 sense data */ |
1238 | num = (sense_len < 32) ? sense_len : 32; | 1247 | num = (sense_len < 32) ? sense_len : 32; |
1239 | printk(KERN_INFO "Unrecognized sense data (in hex):"); | 1248 | printk("Unrecognized sense data (in hex):"); |
1240 | for (k = 0; k < num; ++k) { | 1249 | for (k = 0; k < num; ++k) { |
1241 | if (0 == (k % 16)) { | 1250 | if (0 == (k % 16)) { |
1242 | printk("\n"); | 1251 | printk("\n"); |
@@ -1247,11 +1256,20 @@ __scsi_print_sense(const char *name, const unsigned char *sense_buffer, | |||
1247 | printk("\n"); | 1256 | printk("\n"); |
1248 | return; | 1257 | return; |
1249 | } | 1258 | } |
1250 | scsi_print_sense_hdr(name, &ssh); | 1259 | } |
1251 | if (ssh.response_code < 0x72) { | 1260 | |
1261 | void | ||
1262 | scsi_decode_sense_extras(const unsigned char *sense_buffer, int sense_len, | ||
1263 | struct scsi_sense_hdr *sshdr) | ||
1264 | { | ||
1265 | int k, num, res; | ||
1266 | |||
1267 | if (sshdr->response_code < 0x72) | ||
1268 | { | ||
1252 | /* only decode extras for "fixed" format now */ | 1269 | /* only decode extras for "fixed" format now */ |
1253 | char buff[80]; | 1270 | char buff[80]; |
1254 | int blen, fixed_valid; | 1271 | int blen, fixed_valid; |
1272 | unsigned int info; | ||
1255 | 1273 | ||
1256 | fixed_valid = sense_buffer[0] & 0x80; | 1274 | fixed_valid = sense_buffer[0] & 0x80; |
1257 | info = ((sense_buffer[3] << 24) | (sense_buffer[4] << 16) | | 1275 | info = ((sense_buffer[3] << 24) | (sense_buffer[4] << 16) | |
@@ -1281,13 +1299,13 @@ __scsi_print_sense(const char *name, const unsigned char *sense_buffer, | |||
1281 | res += snprintf(buff + res, blen - res, "ILI"); | 1299 | res += snprintf(buff + res, blen - res, "ILI"); |
1282 | } | 1300 | } |
1283 | if (res > 0) | 1301 | if (res > 0) |
1284 | printk(KERN_INFO "%s\n", buff); | 1302 | printk("%s\n", buff); |
1285 | } else if (ssh.additional_length > 0) { | 1303 | } else if (sshdr->additional_length > 0) { |
1286 | /* descriptor format with sense descriptors */ | 1304 | /* descriptor format with sense descriptors */ |
1287 | num = 8 + ssh.additional_length; | 1305 | num = 8 + sshdr->additional_length; |
1288 | num = (sense_len < num) ? sense_len : num; | 1306 | num = (sense_len < num) ? sense_len : num; |
1289 | printk(KERN_INFO "Descriptor sense data with sense " | 1307 | printk("Descriptor sense data with sense descriptors " |
1290 | "descriptors (in hex):"); | 1308 | "(in hex):"); |
1291 | for (k = 0; k < num; ++k) { | 1309 | for (k = 0; k < num; ++k) { |
1292 | if (0 == (k % 16)) { | 1310 | if (0 == (k % 16)) { |
1293 | printk("\n"); | 1311 | printk("\n"); |
@@ -1295,29 +1313,42 @@ __scsi_print_sense(const char *name, const unsigned char *sense_buffer, | |||
1295 | } | 1313 | } |
1296 | printk("%02x ", sense_buffer[k]); | 1314 | printk("%02x ", sense_buffer[k]); |
1297 | } | 1315 | } |
1316 | |||
1298 | printk("\n"); | 1317 | printk("\n"); |
1299 | } | 1318 | } |
1319 | |||
1300 | } | 1320 | } |
1301 | EXPORT_SYMBOL(__scsi_print_sense); | ||
1302 | 1321 | ||
1303 | void scsi_print_sense(const char *devclass, struct scsi_cmnd *cmd) | 1322 | /* Normalize and print sense buffer with name prefix */ |
1323 | void __scsi_print_sense(const char *name, const unsigned char *sense_buffer, | ||
1324 | int sense_len) | ||
1304 | { | 1325 | { |
1305 | const char *name = devclass; | 1326 | struct scsi_sense_hdr sshdr; |
1306 | 1327 | ||
1307 | if (cmd->request->rq_disk) | 1328 | printk(KERN_INFO "%s: ", name); |
1308 | name = cmd->request->rq_disk->disk_name; | 1329 | scsi_decode_sense_buffer(sense_buffer, sense_len, &sshdr); |
1309 | __scsi_print_sense(name, cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); | 1330 | scsi_show_sense_hdr(&sshdr); |
1331 | scsi_decode_sense_extras(sense_buffer, sense_len, &sshdr); | ||
1332 | printk(KERN_INFO "%s: ", name); | ||
1333 | scsi_show_extd_sense(sshdr.asc, sshdr.ascq); | ||
1310 | } | 1334 | } |
1311 | EXPORT_SYMBOL(scsi_print_sense); | 1335 | EXPORT_SYMBOL(__scsi_print_sense); |
1312 | 1336 | ||
1313 | void scsi_print_command(struct scsi_cmnd *cmd) | 1337 | /* Normalize and print sense buffer in SCSI command */ |
1338 | void scsi_print_sense(char *name, struct scsi_cmnd *cmd) | ||
1314 | { | 1339 | { |
1315 | /* Assume appended output (i.e. not at start of line) */ | 1340 | struct scsi_sense_hdr sshdr; |
1316 | sdev_printk("", cmd->device, "\n"); | 1341 | |
1317 | printk(KERN_INFO " command: "); | 1342 | scmd_printk(KERN_INFO, cmd, ""); |
1318 | scsi_print_cdb(cmd->cmnd, cmd->cmd_len, 0); | 1343 | scsi_decode_sense_buffer(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE, |
1344 | &sshdr); | ||
1345 | scsi_show_sense_hdr(&sshdr); | ||
1346 | scsi_decode_sense_extras(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE, | ||
1347 | &sshdr); | ||
1348 | scmd_printk(KERN_INFO, cmd, ""); | ||
1349 | scsi_show_extd_sense(sshdr.asc, sshdr.ascq); | ||
1319 | } | 1350 | } |
1320 | EXPORT_SYMBOL(scsi_print_command); | 1351 | EXPORT_SYMBOL(scsi_print_sense); |
1321 | 1352 | ||
1322 | #ifdef CONFIG_SCSI_CONSTANTS | 1353 | #ifdef CONFIG_SCSI_CONSTANTS |
1323 | 1354 | ||
@@ -1327,25 +1358,6 @@ static const char * const hostbyte_table[]={ | |||
1327 | "DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY"}; | 1358 | "DID_PASSTHROUGH", "DID_SOFT_ERROR", "DID_IMM_RETRY"}; |
1328 | #define NUM_HOSTBYTE_STRS ARRAY_SIZE(hostbyte_table) | 1359 | #define NUM_HOSTBYTE_STRS ARRAY_SIZE(hostbyte_table) |
1329 | 1360 | ||
1330 | void scsi_print_hostbyte(int scsiresult) | ||
1331 | { | ||
1332 | int hb = host_byte(scsiresult); | ||
1333 | |||
1334 | printk("Hostbyte=0x%02x", hb); | ||
1335 | if (hb < NUM_HOSTBYTE_STRS) | ||
1336 | printk("(%s) ", hostbyte_table[hb]); | ||
1337 | else | ||
1338 | printk("is invalid "); | ||
1339 | } | ||
1340 | #else | ||
1341 | void scsi_print_hostbyte(int scsiresult) | ||
1342 | { | ||
1343 | printk("Hostbyte=0x%02x ", host_byte(scsiresult)); | ||
1344 | } | ||
1345 | #endif | ||
1346 | |||
1347 | #ifdef CONFIG_SCSI_CONSTANTS | ||
1348 | |||
1349 | static const char * const driverbyte_table[]={ | 1361 | static const char * const driverbyte_table[]={ |
1350 | "DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR", | 1362 | "DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR", |
1351 | "DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE"}; | 1363 | "DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE"}; |
@@ -1356,19 +1368,35 @@ static const char * const driversuggest_table[]={"SUGGEST_OK", | |||
1356 | "SUGGEST_5", "SUGGEST_6", "SUGGEST_7", "SUGGEST_SENSE"}; | 1368 | "SUGGEST_5", "SUGGEST_6", "SUGGEST_7", "SUGGEST_SENSE"}; |
1357 | #define NUM_SUGGEST_STRS ARRAY_SIZE(driversuggest_table) | 1369 | #define NUM_SUGGEST_STRS ARRAY_SIZE(driversuggest_table) |
1358 | 1370 | ||
1359 | void scsi_print_driverbyte(int scsiresult) | 1371 | void scsi_show_result(int result) |
1360 | { | 1372 | { |
1361 | int dr = (driver_byte(scsiresult) & DRIVER_MASK); | 1373 | int hb = host_byte(result); |
1362 | int su = ((driver_byte(scsiresult) & SUGGEST_MASK) >> 4); | 1374 | int db = (driver_byte(result) & DRIVER_MASK); |
1375 | int su = ((driver_byte(result) & SUGGEST_MASK) >> 4); | ||
1363 | 1376 | ||
1364 | printk("Driverbyte=0x%02x ", driver_byte(scsiresult)); | 1377 | printk("Result: hostbyte=%s driverbyte=%s,%s\n", |
1365 | printk("(%s,%s) ", | 1378 | (hb < NUM_HOSTBYTE_STRS ? hostbyte_table[hb] : "invalid"), |
1366 | (dr < NUM_DRIVERBYTE_STRS ? driverbyte_table[dr] : "invalid"), | 1379 | (db < NUM_DRIVERBYTE_STRS ? driverbyte_table[db] : "invalid"), |
1367 | (su < NUM_SUGGEST_STRS ? driversuggest_table[su] : "invalid")); | 1380 | (su < NUM_SUGGEST_STRS ? driversuggest_table[su] : "invalid")); |
1368 | } | 1381 | } |
1382 | |||
1369 | #else | 1383 | #else |
1370 | void scsi_print_driverbyte(int scsiresult) | 1384 | |
1385 | void scsi_show_result(int result) | ||
1371 | { | 1386 | { |
1372 | printk("Driverbyte=0x%02x ", driver_byte(scsiresult)); | 1387 | printk("Result: hostbyte=0x%02x driverbyte=0x%02x\n", |
1388 | host_byte(result), driver_byte(result)); | ||
1373 | } | 1389 | } |
1390 | |||
1374 | #endif | 1391 | #endif |
1392 | EXPORT_SYMBOL(scsi_show_result); | ||
1393 | |||
1394 | |||
1395 | void scsi_print_result(struct scsi_cmnd *cmd) | ||
1396 | { | ||
1397 | scmd_printk(KERN_INFO, cmd, ""); | ||
1398 | scsi_show_result(cmd->result); | ||
1399 | } | ||
1400 | EXPORT_SYMBOL(scsi_print_result); | ||
1401 | |||
1402 | |||