diff options
Diffstat (limited to 'drivers/scsi/scsi_error.c')
-rw-r--r-- | drivers/scsi/scsi_error.c | 85 |
1 files changed, 14 insertions, 71 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index afd34a608fe7..66a96cd98b97 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -33,9 +33,11 @@ | |||
33 | #include <scsi/scsi_device.h> | 33 | #include <scsi/scsi_device.h> |
34 | #include <scsi/scsi_driver.h> | 34 | #include <scsi/scsi_driver.h> |
35 | #include <scsi/scsi_eh.h> | 35 | #include <scsi/scsi_eh.h> |
36 | #include <scsi/scsi_common.h> | ||
36 | #include <scsi/scsi_transport.h> | 37 | #include <scsi/scsi_transport.h> |
37 | #include <scsi/scsi_host.h> | 38 | #include <scsi/scsi_host.h> |
38 | #include <scsi/scsi_ioctl.h> | 39 | #include <scsi/scsi_ioctl.h> |
40 | #include <scsi/scsi_dh.h> | ||
39 | #include <scsi/sg.h> | 41 | #include <scsi/sg.h> |
40 | 42 | ||
41 | #include "scsi_priv.h" | 43 | #include "scsi_priv.h" |
@@ -463,11 +465,10 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) | |||
463 | if (scsi_sense_is_deferred(&sshdr)) | 465 | if (scsi_sense_is_deferred(&sshdr)) |
464 | return NEEDS_RETRY; | 466 | return NEEDS_RETRY; |
465 | 467 | ||
466 | if (sdev->scsi_dh_data && sdev->scsi_dh_data->scsi_dh && | 468 | if (sdev->handler && sdev->handler->check_sense) { |
467 | sdev->scsi_dh_data->scsi_dh->check_sense) { | ||
468 | int rc; | 469 | int rc; |
469 | 470 | ||
470 | rc = sdev->scsi_dh_data->scsi_dh->check_sense(sdev, &sshdr); | 471 | rc = sdev->handler->check_sense(sdev, &sshdr); |
471 | if (rc != SCSI_RETURN_NOT_HANDLED) | 472 | if (rc != SCSI_RETURN_NOT_HANDLED) |
472 | return rc; | 473 | return rc; |
473 | /* handler does not care. Drop down to default handling */ | 474 | /* handler does not care. Drop down to default handling */ |
@@ -2178,8 +2179,17 @@ int scsi_error_handler(void *data) | |||
2178 | * We never actually get interrupted because kthread_run | 2179 | * We never actually get interrupted because kthread_run |
2179 | * disables signal delivery for the created thread. | 2180 | * disables signal delivery for the created thread. |
2180 | */ | 2181 | */ |
2181 | while (!kthread_should_stop()) { | 2182 | while (true) { |
2183 | /* | ||
2184 | * The sequence in kthread_stop() sets the stop flag first | ||
2185 | * then wakes the process. To avoid missed wakeups, the task | ||
2186 | * should always be in a non running state before the stop | ||
2187 | * flag is checked | ||
2188 | */ | ||
2182 | set_current_state(TASK_INTERRUPTIBLE); | 2189 | set_current_state(TASK_INTERRUPTIBLE); |
2190 | if (kthread_should_stop()) | ||
2191 | break; | ||
2192 | |||
2183 | if ((shost->host_failed == 0 && shost->host_eh_scheduled == 0) || | 2193 | if ((shost->host_failed == 0 && shost->host_eh_scheduled == 0) || |
2184 | shost->host_failed != atomic_read(&shost->host_busy)) { | 2194 | shost->host_failed != atomic_read(&shost->host_busy)) { |
2185 | SCSI_LOG_ERROR_RECOVERY(1, | 2195 | SCSI_LOG_ERROR_RECOVERY(1, |
@@ -2416,45 +2426,6 @@ bool scsi_command_normalize_sense(const struct scsi_cmnd *cmd, | |||
2416 | EXPORT_SYMBOL(scsi_command_normalize_sense); | 2426 | EXPORT_SYMBOL(scsi_command_normalize_sense); |
2417 | 2427 | ||
2418 | /** | 2428 | /** |
2419 | * scsi_sense_desc_find - search for a given descriptor type in descriptor sense data format. | ||
2420 | * @sense_buffer: byte array of descriptor format sense data | ||
2421 | * @sb_len: number of valid bytes in sense_buffer | ||
2422 | * @desc_type: value of descriptor type to find | ||
2423 | * (e.g. 0 -> information) | ||
2424 | * | ||
2425 | * Notes: | ||
2426 | * only valid when sense data is in descriptor format | ||
2427 | * | ||
2428 | * Return value: | ||
2429 | * pointer to start of (first) descriptor if found else NULL | ||
2430 | */ | ||
2431 | const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len, | ||
2432 | int desc_type) | ||
2433 | { | ||
2434 | int add_sen_len, add_len, desc_len, k; | ||
2435 | const u8 * descp; | ||
2436 | |||
2437 | if ((sb_len < 8) || (0 == (add_sen_len = sense_buffer[7]))) | ||
2438 | return NULL; | ||
2439 | if ((sense_buffer[0] < 0x72) || (sense_buffer[0] > 0x73)) | ||
2440 | return NULL; | ||
2441 | add_sen_len = (add_sen_len < (sb_len - 8)) ? | ||
2442 | add_sen_len : (sb_len - 8); | ||
2443 | descp = &sense_buffer[8]; | ||
2444 | for (desc_len = 0, k = 0; k < add_sen_len; k += desc_len) { | ||
2445 | descp += desc_len; | ||
2446 | add_len = (k < (add_sen_len - 1)) ? descp[1]: -1; | ||
2447 | desc_len = add_len + 2; | ||
2448 | if (descp[0] == desc_type) | ||
2449 | return descp; | ||
2450 | if (add_len < 0) // short descriptor ?? | ||
2451 | break; | ||
2452 | } | ||
2453 | return NULL; | ||
2454 | } | ||
2455 | EXPORT_SYMBOL(scsi_sense_desc_find); | ||
2456 | |||
2457 | /** | ||
2458 | * scsi_get_sense_info_fld - get information field from sense data (either fixed or descriptor format) | 2429 | * scsi_get_sense_info_fld - get information field from sense data (either fixed or descriptor format) |
2459 | * @sense_buffer: byte array of sense data | 2430 | * @sense_buffer: byte array of sense data |
2460 | * @sb_len: number of valid bytes in sense_buffer | 2431 | * @sb_len: number of valid bytes in sense_buffer |
@@ -2503,31 +2474,3 @@ int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len, | |||
2503 | } | 2474 | } |
2504 | } | 2475 | } |
2505 | EXPORT_SYMBOL(scsi_get_sense_info_fld); | 2476 | EXPORT_SYMBOL(scsi_get_sense_info_fld); |
2506 | |||
2507 | /** | ||
2508 | * scsi_build_sense_buffer - build sense data in a buffer | ||
2509 | * @desc: Sense format (non zero == descriptor format, | ||
2510 | * 0 == fixed format) | ||
2511 | * @buf: Where to build sense data | ||
2512 | * @key: Sense key | ||
2513 | * @asc: Additional sense code | ||
2514 | * @ascq: Additional sense code qualifier | ||
2515 | * | ||
2516 | **/ | ||
2517 | void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq) | ||
2518 | { | ||
2519 | if (desc) { | ||
2520 | buf[0] = 0x72; /* descriptor, current */ | ||
2521 | buf[1] = key; | ||
2522 | buf[2] = asc; | ||
2523 | buf[3] = ascq; | ||
2524 | buf[7] = 0; | ||
2525 | } else { | ||
2526 | buf[0] = 0x70; /* fixed, current */ | ||
2527 | buf[2] = key; | ||
2528 | buf[7] = 0xa; | ||
2529 | buf[12] = asc; | ||
2530 | buf[13] = ascq; | ||
2531 | } | ||
2532 | } | ||
2533 | EXPORT_SYMBOL(scsi_build_sense_buffer); | ||