124593e2cSAxel Dörfler /*
2*a1e8da41SAxel Dörfler * Copyright 2011, Haiku, Inc. All RightsReserved.
3*a1e8da41SAxel Dörfler * Copyright 2002-03, Thomas Kurschel. All rights reserved.
424593e2cSAxel Dörfler * Distributed under the terms of the MIT License.
524593e2cSAxel Dörfler */
624593e2cSAxel Dörfler
724593e2cSAxel Dörfler
8*a1e8da41SAxel Dörfler //! Error handling
924593e2cSAxel Dörfler
1024593e2cSAxel Dörfler
1124593e2cSAxel Dörfler #include "scsi_periph_int.h"
1224593e2cSAxel Dörfler
1324593e2cSAxel Dörfler
14*a1e8da41SAxel Dörfler /*! Decode sense data and generate error code. */
1524593e2cSAxel Dörfler static
check_sense(scsi_periph_device_info * device,scsi_ccb * request)1624593e2cSAxel Dörfler err_res check_sense(scsi_periph_device_info *device, scsi_ccb *request)
1724593e2cSAxel Dörfler {
1824593e2cSAxel Dörfler scsi_sense *sense = (scsi_sense *)request->sense;
1924593e2cSAxel Dörfler
2024593e2cSAxel Dörfler if ((request->subsys_status & SCSI_AUTOSNS_VALID) == 0) {
2124593e2cSAxel Dörfler SHOW_ERROR0(2, "No auto-sense (but there should be)");
2224593e2cSAxel Dörfler
2324593e2cSAxel Dörfler // shouldn't happen (cam_status should be CAM_AUTOSENSE_FAIL
2424593e2cSAxel Dörfler // as we asked for autosense)
2524593e2cSAxel Dörfler return MK_ERROR(err_act_fail, B_ERROR);
2624593e2cSAxel Dörfler }
2724593e2cSAxel Dörfler
2824593e2cSAxel Dörfler if (SCSI_MAX_SENSE_SIZE - request->sense_resid
2924593e2cSAxel Dörfler < (int)offsetof(scsi_sense, add_sense_length) + 1) {
3024593e2cSAxel Dörfler SHOW_ERROR(2, "sense too short (%d bytes)", SCSI_MAX_SENSE_SIZE - request->sense_resid);
3124593e2cSAxel Dörfler
3224593e2cSAxel Dörfler // that's a bit too short
3324593e2cSAxel Dörfler return MK_ERROR(err_act_fail, B_ERROR);
3424593e2cSAxel Dörfler }
3524593e2cSAxel Dörfler
3624593e2cSAxel Dörfler switch (sense->error_code) {
3724593e2cSAxel Dörfler case SCSIS_DEFERRED_ERROR:
3824593e2cSAxel Dörfler // we are doomed - some previous request turned out to have failed
3924593e2cSAxel Dörfler // we neither know which one nor can we resubmit it
4024593e2cSAxel Dörfler SHOW_ERROR0(2, "encountered DEFERRED ERROR - bye, bye");
4124593e2cSAxel Dörfler return MK_ERROR(err_act_ok, B_OK);
4224593e2cSAxel Dörfler
4324593e2cSAxel Dörfler case SCSIS_CURR_ERROR:
4424593e2cSAxel Dörfler // we start with very specific and finish very general error infos
4524593e2cSAxel Dörfler switch ((sense->asc << 8) | sense->ascq) {
4624593e2cSAxel Dörfler case SCSIS_ASC_AUDIO_PLAYING:
4724593e2cSAxel Dörfler SHOW_INFO0(2, "busy because playing audio");
4824593e2cSAxel Dörfler
4924593e2cSAxel Dörfler // we need something like "busy"
5024593e2cSAxel Dörfler return MK_ERROR(err_act_fail, B_DEV_NOT_READY);
5124593e2cSAxel Dörfler
5224593e2cSAxel Dörfler case SCSIS_ASC_LUN_NEED_INIT:
5324593e2cSAxel Dörfler SHOW_INFO0(2, "LUN needs init");
5424593e2cSAxel Dörfler
5524593e2cSAxel Dörfler // reported by some devices that are idle and spun down
5624593e2cSAxel Dörfler // sending START UNIT should awake them
5724593e2cSAxel Dörfler return MK_ERROR(err_act_start, B_NO_INIT);
5824593e2cSAxel Dörfler
5924593e2cSAxel Dörfler case SCSIS_ASC_LUN_NEED_MANUAL_HELP:
6024593e2cSAxel Dörfler SHOW_ERROR0(2, "LUN needs manual help");
6124593e2cSAxel Dörfler
6224593e2cSAxel Dörfler return MK_ERROR(err_act_fail, B_DEV_NOT_READY);
6324593e2cSAxel Dörfler
6424593e2cSAxel Dörfler case SCSIS_ASC_LUN_FORMATTING:
6524593e2cSAxel Dörfler SHOW_INFO0(2, "LUN is formatting");
6624593e2cSAxel Dörfler
6724593e2cSAxel Dörfler // we could wait, but as formatting normally takes quite long,
6824593e2cSAxel Dörfler // we give up without any further retries
6924593e2cSAxel Dörfler return MK_ERROR(err_act_fail, B_DEV_NOT_READY);
7024593e2cSAxel Dörfler
7124593e2cSAxel Dörfler case SCSIS_ASC_MEDIUM_CHANGED:
7224593e2cSAxel Dörfler SHOW_FLOW0(3, "Medium changed");
7324593e2cSAxel Dörfler periph_media_changed(device, request);
7424593e2cSAxel Dörfler return MK_ERROR(err_act_fail, B_DEV_MEDIA_CHANGED);
7524593e2cSAxel Dörfler
7624593e2cSAxel Dörfler case SCSIS_ASC_WRITE_ERR_AUTOREALLOC:
7724593e2cSAxel Dörfler SHOW_ERROR0(2, "Recovered write error - block got reallocated automatically");
7824593e2cSAxel Dörfler return MK_ERROR(err_act_ok, B_OK);
7924593e2cSAxel Dörfler
8024593e2cSAxel Dörfler case SCSIS_ASC_ID_RECOV:
8124593e2cSAxel Dörfler SHOW_ERROR0(2, "Recovered ID with ECC");
8224593e2cSAxel Dörfler return MK_ERROR(err_act_ok, B_OK);
8324593e2cSAxel Dörfler
8424593e2cSAxel Dörfler case SCSIS_ASC_REMOVAL_REQUESTED:
8524593e2cSAxel Dörfler SHOW_INFO0(2, "Removal requested");
86*a1e8da41SAxel Dörfler mutex_lock(&device->mutex);
8724593e2cSAxel Dörfler device->removal_requested = true;
88*a1e8da41SAxel Dörfler mutex_unlock(&device->mutex);
8924593e2cSAxel Dörfler
9024593e2cSAxel Dörfler return MK_ERROR(err_act_retry, B_DEV_MEDIA_CHANGE_REQUESTED);
9124593e2cSAxel Dörfler
9224593e2cSAxel Dörfler case SCSIS_ASC_LUN_BECOMING_READY:
9324593e2cSAxel Dörfler SHOW_INFO0(2, "Becoming ready");
9424593e2cSAxel Dörfler // wait a bit - the device needs some time
9524593e2cSAxel Dörfler snooze(100000);
9624593e2cSAxel Dörfler return MK_ERROR(err_act_many_retries, B_DEV_NOT_READY);
9724593e2cSAxel Dörfler
9824593e2cSAxel Dörfler case SCSIS_ASC_WAS_RESET:
9924593e2cSAxel Dörfler SHOW_INFO0(2, "Unit was reset");
10024593e2cSAxel Dörfler // TBD: need a better error code here
10124593e2cSAxel Dörfler // as some earlier command led to the reset, we are innocent
10224593e2cSAxel Dörfler return MK_ERROR(err_act_retry, B_DEV_NOT_READY);
10324593e2cSAxel Dörfler }
10424593e2cSAxel Dörfler
10524593e2cSAxel Dörfler switch (sense->asc) {
10624593e2cSAxel Dörfler case SCSIS_ASC_DATA_RECOV_NO_ERR_CORR >> 8:
10724593e2cSAxel Dörfler case SCSIS_ASC_DATA_RECOV_WITH_CORR >> 8:
10824593e2cSAxel Dörfler // these are the groups of recovered data with or without correction
10924593e2cSAxel Dörfler // we should print at least a warning here
11024593e2cSAxel Dörfler SHOW_ERROR(0, "Recovered data, asc=0x%2x, ascq=0x%2x",
11124593e2cSAxel Dörfler sense->asc, sense->ascq);
11224593e2cSAxel Dörfler return MK_ERROR(err_act_ok, B_OK);
11324593e2cSAxel Dörfler
11424593e2cSAxel Dörfler case SCSIS_ASC_WRITE_PROTECTED >> 8:
11524593e2cSAxel Dörfler SHOW_ERROR0( 2, "Write protected" );
11624593e2cSAxel Dörfler
11724593e2cSAxel Dörfler // isn't there any proper "write protected" error code?
11824593e2cSAxel Dörfler return MK_ERROR(err_act_fail, B_READ_ONLY_DEVICE);
11924593e2cSAxel Dörfler
12024593e2cSAxel Dörfler case SCSIS_ASC_NO_MEDIUM >> 8:
12124593e2cSAxel Dörfler SHOW_FLOW0(2, "No medium");
12224593e2cSAxel Dörfler return MK_ERROR(err_act_fail, B_DEV_NO_MEDIA);
12324593e2cSAxel Dörfler }
12424593e2cSAxel Dörfler
12524593e2cSAxel Dörfler // we issue this info very late, so we don't clutter syslog with
12624593e2cSAxel Dörfler // messages about changed or missing media
12724593e2cSAxel Dörfler SHOW_ERROR(3, "0x%04x", (sense->asc << 8) | sense->ascq);
12824593e2cSAxel Dörfler
12924593e2cSAxel Dörfler switch (sense->sense_key) {
13024593e2cSAxel Dörfler case SCSIS_KEY_NO_SENSE:
13124593e2cSAxel Dörfler SHOW_ERROR0(2, "No sense");
13224593e2cSAxel Dörfler
13324593e2cSAxel Dörfler // we thought there was an error, huh?
13424593e2cSAxel Dörfler return MK_ERROR(err_act_ok, B_OK);
13524593e2cSAxel Dörfler
13624593e2cSAxel Dörfler case SCSIS_KEY_RECOVERED_ERROR:
13724593e2cSAxel Dörfler SHOW_ERROR0(2, "Recovered error");
13824593e2cSAxel Dörfler
13924593e2cSAxel Dörfler // we should probably tell about that; perhaps tomorrow
14024593e2cSAxel Dörfler return MK_ERROR(err_act_ok, B_OK);
14124593e2cSAxel Dörfler
14224593e2cSAxel Dörfler case SCSIS_KEY_NOT_READY:
14324593e2cSAxel Dörfler return MK_ERROR(err_act_retry, B_DEV_NOT_READY);
14424593e2cSAxel Dörfler
14524593e2cSAxel Dörfler case SCSIS_KEY_MEDIUM_ERROR:
14624593e2cSAxel Dörfler SHOW_ERROR0(2, "Medium error");
14724593e2cSAxel Dörfler return MK_ERROR( err_act_retry, B_DEV_RECALIBRATE_ERROR);
14824593e2cSAxel Dörfler
14924593e2cSAxel Dörfler case SCSIS_KEY_HARDWARE_ERROR:
15024593e2cSAxel Dörfler SHOW_ERROR0(2, "Hardware error");
15124593e2cSAxel Dörfler return MK_ERROR(err_act_retry, B_DEV_SEEK_ERROR);
15224593e2cSAxel Dörfler
15324593e2cSAxel Dörfler case SCSIS_KEY_ILLEGAL_REQUEST:
15424593e2cSAxel Dörfler SHOW_ERROR0(2, "Illegal request");
15524593e2cSAxel Dörfler return MK_ERROR(err_act_invalid_req, B_ERROR);
15624593e2cSAxel Dörfler
15724593e2cSAxel Dörfler case SCSIS_KEY_UNIT_ATTENTION:
15824593e2cSAxel Dörfler SHOW_ERROR0(2, "Unit attention");
15924593e2cSAxel Dörfler return MK_ERROR( err_act_retry, B_DEV_NOT_READY);
16024593e2cSAxel Dörfler
16124593e2cSAxel Dörfler case SCSIS_KEY_DATA_PROTECT:
16224593e2cSAxel Dörfler SHOW_ERROR0(2, "Data protect");
16324593e2cSAxel Dörfler
16424593e2cSAxel Dörfler // we could set "permission denied", but that's probably
16524593e2cSAxel Dörfler // irritating to the user
16624593e2cSAxel Dörfler return MK_ERROR(err_act_fail, B_NOT_ALLOWED);
16724593e2cSAxel Dörfler
16824593e2cSAxel Dörfler case SCSIS_KEY_BLANK_CHECK:
16924593e2cSAxel Dörfler SHOW_ERROR0(2, "Is blank");
17024593e2cSAxel Dörfler
17124593e2cSAxel Dörfler return MK_ERROR(err_act_fail, B_DEV_UNREADABLE);
17224593e2cSAxel Dörfler
17324593e2cSAxel Dörfler case SCSIS_KEY_VENDOR_SPECIFIC:
17424593e2cSAxel Dörfler return MK_ERROR(err_act_fail, B_ERROR);
17524593e2cSAxel Dörfler
17624593e2cSAxel Dörfler case SCSIS_KEY_COPY_ABORTED:
17724593e2cSAxel Dörfler // we don't use copy, so this is really wrong
17824593e2cSAxel Dörfler return MK_ERROR(err_act_fail, B_ERROR);
17924593e2cSAxel Dörfler
18024593e2cSAxel Dörfler case SCSIS_KEY_ABORTED_COMMAND:
18124593e2cSAxel Dörfler // proper error code?
18224593e2cSAxel Dörfler return MK_ERROR(err_act_retry, B_ERROR);
18324593e2cSAxel Dörfler
18424593e2cSAxel Dörfler case SCSIS_KEY_EQUAL:
18524593e2cSAxel Dörfler case SCSIS_KEY_MISCOMPARE:
18624593e2cSAxel Dörfler // we don't search, so this is really wrong
18724593e2cSAxel Dörfler return MK_ERROR(err_act_fail, B_ERROR);
18824593e2cSAxel Dörfler
18924593e2cSAxel Dörfler case SCSIS_KEY_VOLUME_OVERFLOW:
19024593e2cSAxel Dörfler // not the best return code, but this error doesn't apply
19124593e2cSAxel Dörfler // to devices we currently support
19224593e2cSAxel Dörfler return MK_ERROR(err_act_fail, B_DEV_SEEK_ERROR);
19324593e2cSAxel Dörfler
19424593e2cSAxel Dörfler case SCSIS_KEY_RESERVED:
19524593e2cSAxel Dörfler default:
19624593e2cSAxel Dörfler return MK_ERROR(err_act_fail, B_ERROR);
19724593e2cSAxel Dörfler }
19824593e2cSAxel Dörfler
19924593e2cSAxel Dörfler default:
20024593e2cSAxel Dörfler // shouldn't happen - there are only 2 error codes defined
20124593e2cSAxel Dörfler SHOW_ERROR(2, "Invalid sense type (0x%x)", sense->error_code);
20224593e2cSAxel Dörfler return MK_ERROR(err_act_fail, B_ERROR);
20324593e2cSAxel Dörfler }
20424593e2cSAxel Dörfler }
20524593e2cSAxel Dörfler
20624593e2cSAxel Dörfler
207*a1e8da41SAxel Dörfler /*! Check scsi status, using sense if available. */
20824593e2cSAxel Dörfler static err_res
check_scsi_status(scsi_periph_device_info * device,scsi_ccb * request)20924593e2cSAxel Dörfler check_scsi_status(scsi_periph_device_info *device, scsi_ccb *request)
21024593e2cSAxel Dörfler {
21124593e2cSAxel Dörfler SHOW_FLOW(3, "%d", request->device_status & SCSI_STATUS_MASK);
21224593e2cSAxel Dörfler
21324593e2cSAxel Dörfler switch (request->device_status & SCSI_STATUS_MASK) {
21424593e2cSAxel Dörfler case SCSI_STATUS_GOOD:
21524593e2cSAxel Dörfler // shouldn't happen (cam_status should be CAM_REQ_CMP)
21624593e2cSAxel Dörfler return MK_ERROR(err_act_ok, B_OK);
21724593e2cSAxel Dörfler
21824593e2cSAxel Dörfler case SCSI_STATUS_CHECK_CONDITION:
21924593e2cSAxel Dörfler return check_sense(device, request);
22024593e2cSAxel Dörfler
22124593e2cSAxel Dörfler case SCSI_STATUS_QUEUE_FULL:
22224593e2cSAxel Dörfler // SIM should have automatically requeued request, fall through
22324593e2cSAxel Dörfler case SCSI_STATUS_BUSY:
22424593e2cSAxel Dörfler // take deep breath and try again
22524593e2cSAxel Dörfler snooze(1000000);
22624593e2cSAxel Dörfler return MK_ERROR(err_act_retry, B_DEV_TIMEOUT);
22724593e2cSAxel Dörfler
22824593e2cSAxel Dörfler case SCSI_STATUS_COMMAND_TERMINATED:
22924593e2cSAxel Dörfler return MK_ERROR(err_act_retry, B_INTERRUPTED);
23024593e2cSAxel Dörfler
23124593e2cSAxel Dörfler default:
23224593e2cSAxel Dörfler return MK_ERROR(err_act_retry, B_ERROR);
23324593e2cSAxel Dörfler }
23424593e2cSAxel Dörfler }
23524593e2cSAxel Dörfler
23624593e2cSAxel Dörfler
237*a1e8da41SAxel Dörfler /*! Check result of request
23824593e2cSAxel Dörfler * 1. check SCSI subsystem problems
23924593e2cSAxel Dörfler * 2. if request hit device, check SCSI status
24024593e2cSAxel Dörfler * 3. if request got executed, check sense
24124593e2cSAxel Dörfler */
24224593e2cSAxel Dörfler err_res
periph_check_error(scsi_periph_device_info * device,scsi_ccb * request)24324593e2cSAxel Dörfler periph_check_error(scsi_periph_device_info *device, scsi_ccb *request)
24424593e2cSAxel Dörfler {
24524593e2cSAxel Dörfler SHOW_FLOW(4, "%d", request->subsys_status & SCSI_SUBSYS_STATUS_MASK);
24624593e2cSAxel Dörfler
24724593e2cSAxel Dörfler switch (request->subsys_status & SCSI_SUBSYS_STATUS_MASK) {
24824593e2cSAxel Dörfler // everything is ok
24924593e2cSAxel Dörfler case SCSI_REQ_CMP:
25024593e2cSAxel Dörfler return MK_ERROR(err_act_ok, B_OK);
25124593e2cSAxel Dörfler
25224593e2cSAxel Dörfler // no device
25324593e2cSAxel Dörfler case SCSI_LUN_INVALID:
25424593e2cSAxel Dörfler case SCSI_TID_INVALID:
25524593e2cSAxel Dörfler case SCSI_PATH_INVALID:
25624593e2cSAxel Dörfler case SCSI_DEV_NOT_THERE:
25724593e2cSAxel Dörfler case SCSI_NO_HBA:
25824593e2cSAxel Dörfler SHOW_ERROR0(2, "No device");
25924593e2cSAxel Dörfler return MK_ERROR(err_act_fail, B_DEV_BAD_DRIVE_NUM);
26024593e2cSAxel Dörfler
26124593e2cSAxel Dörfler // device temporary unavailable
26224593e2cSAxel Dörfler case SCSI_SEL_TIMEOUT:
26324593e2cSAxel Dörfler case SCSI_BUSY:
26424593e2cSAxel Dörfler case SCSI_SCSI_BUSY:
26524593e2cSAxel Dörfler case SCSI_HBA_ERR:
26624593e2cSAxel Dörfler case SCSI_MSG_REJECT_REC:
26724593e2cSAxel Dörfler case SCSI_NO_NEXUS:
26824593e2cSAxel Dörfler case SCSI_FUNC_NOTAVAIL:
26924593e2cSAxel Dörfler case SCSI_RESRC_UNAVAIL:
27024593e2cSAxel Dörfler // take a deep breath and hope device becomes ready
27124593e2cSAxel Dörfler snooze(1000000);
27224593e2cSAxel Dörfler return MK_ERROR(err_act_retry, B_DEV_TIMEOUT);
27324593e2cSAxel Dörfler
27424593e2cSAxel Dörfler // data transmission went wrong
27524593e2cSAxel Dörfler case SCSI_DATA_RUN_ERR:
27624593e2cSAxel Dörfler case SCSI_UNCOR_PARITY:
27724593e2cSAxel Dörfler SHOW_ERROR0(2, "Data transmission failed");
27824593e2cSAxel Dörfler // retry immediately
27924593e2cSAxel Dörfler return MK_ERROR(err_act_retry, B_DEV_READ_ERROR);
28024593e2cSAxel Dörfler
28124593e2cSAxel Dörfler // request broken
28224593e2cSAxel Dörfler case SCSI_REQ_INVALID:
28324593e2cSAxel Dörfler SHOW_ERROR0(2, "Invalid request");
28424593e2cSAxel Dörfler return MK_ERROR(err_act_fail, B_ERROR);
28524593e2cSAxel Dörfler
28624593e2cSAxel Dörfler // request aborted
28724593e2cSAxel Dörfler case SCSI_REQ_ABORTED:
28824593e2cSAxel Dörfler case SCSI_SCSI_BUS_RESET:
28924593e2cSAxel Dörfler case SCSI_REQ_TERMIO:
29024593e2cSAxel Dörfler case SCSI_UNEXP_BUSFREE:
29124593e2cSAxel Dörfler case SCSI_BDR_SENT:
29224593e2cSAxel Dörfler case SCSI_CMD_TIMEOUT:
29324593e2cSAxel Dörfler case SCSI_IID_INVALID:
29424593e2cSAxel Dörfler case SCSI_UNACKED_EVENT:
29524593e2cSAxel Dörfler case SCSI_IDE:
29624593e2cSAxel Dörfler case SCSI_SEQUENCE_FAIL:
29724593e2cSAxel Dörfler // take a small breath and retry
29824593e2cSAxel Dörfler snooze(100000);
29924593e2cSAxel Dörfler return MK_ERROR(err_act_retry, B_DEV_TIMEOUT);
30024593e2cSAxel Dörfler
30124593e2cSAxel Dörfler // device error
30224593e2cSAxel Dörfler case SCSI_REQ_CMP_ERR:
30324593e2cSAxel Dörfler return check_scsi_status(device, request);
30424593e2cSAxel Dörfler
30524593e2cSAxel Dörfler // device error, but we don't know what happened
30624593e2cSAxel Dörfler case SCSI_AUTOSENSE_FAIL:
30724593e2cSAxel Dörfler SHOW_ERROR0(2, "Auto-sense failed, don't know what really happened");
30824593e2cSAxel Dörfler return MK_ERROR(err_act_fail, B_ERROR);
30924593e2cSAxel Dörfler
31024593e2cSAxel Dörfler // should not happen, give up
31124593e2cSAxel Dörfler case SCSI_BUS_RESET_DENIED:
31224593e2cSAxel Dörfler case SCSI_PROVIDE_FAIL:
31324593e2cSAxel Dörfler case SCSI_UA_TERMIO:
31424593e2cSAxel Dörfler case SCSI_CDB_RECVD:
31524593e2cSAxel Dörfler case SCSI_LUN_ALLREADY_ENAB:
31624593e2cSAxel Dörfler // supposed to fall through
31724593e2cSAxel Dörfler default:
31824593e2cSAxel Dörfler return MK_ERROR(err_act_fail, B_ERROR);
31924593e2cSAxel Dörfler }
32024593e2cSAxel Dörfler }
321