aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_error.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_error.c')
-rw-r--r--drivers/scsi/scsi_error.c85
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,
2416EXPORT_SYMBOL(scsi_command_normalize_sense); 2426EXPORT_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 */
2431const 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}
2455EXPORT_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}
2505EXPORT_SYMBOL(scsi_get_sense_info_fld); 2476EXPORT_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 **/
2517void 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}
2533EXPORT_SYMBOL(scsi_build_sense_buffer);