1/*
2 * Copyright 2011, Haiku, Inc. All RightsReserved.
3 * Copyright 2002-03, Thomas Kurschel. All rights reserved.
4 * Distributed under the terms of the MIT License.
5 */
6
7
8//!	Error handling
9
10
11#include "scsi_periph_int.h"
12
13
14/*! Decode sense data and generate error code. */
15static
16err_res check_sense(scsi_periph_device_info *device, scsi_ccb *request)
17{
18	scsi_sense *sense = (scsi_sense *)request->sense;
19
20	if ((request->subsys_status & SCSI_AUTOSNS_VALID) == 0) {
21		SHOW_ERROR0(2, "No auto-sense (but there should be)");
22
23		// shouldn't happen (cam_status should be CAM_AUTOSENSE_FAIL
24		// as we asked for autosense)
25		return MK_ERROR(err_act_fail, B_ERROR);
26	}
27
28	if (SCSI_MAX_SENSE_SIZE - request->sense_resid
29			< (int)offsetof(scsi_sense, add_sense_length) + 1) {
30		SHOW_ERROR(2, "sense too short (%d bytes)", SCSI_MAX_SENSE_SIZE - request->sense_resid);
31
32		// that's a bit too short
33		return MK_ERROR(err_act_fail, B_ERROR);
34	}
35
36	switch (sense->error_code) {
37		case SCSIS_DEFERRED_ERROR:
38			// we are doomed - some previous request turned out to have failed
39			// we neither know which one nor can we resubmit it
40			SHOW_ERROR0(2, "encountered DEFERRED ERROR - bye, bye");
41			return MK_ERROR(err_act_ok, B_OK);
42
43		case SCSIS_CURR_ERROR:
44			// we start with very specific and finish very general error infos
45			switch ((sense->asc << 8) | sense->ascq) {
46				case SCSIS_ASC_AUDIO_PLAYING:
47					SHOW_INFO0(2, "busy because playing audio");
48
49					// we need something like "busy"
50					return MK_ERROR(err_act_fail, B_DEV_NOT_READY);
51
52				case SCSIS_ASC_LUN_NEED_INIT:
53					SHOW_INFO0(2, "LUN needs init");
54
55					// reported by some devices that are idle and spun down
56					// sending START UNIT should awake them
57					return MK_ERROR(err_act_start, B_NO_INIT);
58
59				case SCSIS_ASC_LUN_NEED_MANUAL_HELP:
60					SHOW_ERROR0(2, "LUN needs manual help");
61
62					return MK_ERROR(err_act_fail, B_DEV_NOT_READY);
63
64				case SCSIS_ASC_LUN_FORMATTING:
65					SHOW_INFO0(2, "LUN is formatting");
66
67					// we could wait, but as formatting normally takes quite long,
68					// we give up without any further retries
69					return MK_ERROR(err_act_fail, B_DEV_NOT_READY);
70
71				case SCSIS_ASC_MEDIUM_CHANGED:
72					SHOW_FLOW0(3, "Medium changed");
73					periph_media_changed(device, request);
74					return MK_ERROR(err_act_fail, B_DEV_MEDIA_CHANGED);
75
76				case SCSIS_ASC_WRITE_ERR_AUTOREALLOC:
77					SHOW_ERROR0(2, "Recovered write error - block got reallocated automatically");
78					return MK_ERROR(err_act_ok, B_OK);
79
80				case SCSIS_ASC_ID_RECOV:
81					SHOW_ERROR0(2, "Recovered ID with ECC");
82					return MK_ERROR(err_act_ok, B_OK);
83
84				case SCSIS_ASC_REMOVAL_REQUESTED:
85					SHOW_INFO0(2, "Removal requested");
86					mutex_lock(&device->mutex);
87					device->removal_requested = true;
88					mutex_unlock(&device->mutex);
89
90					return MK_ERROR(err_act_retry, B_DEV_MEDIA_CHANGE_REQUESTED);
91
92				case SCSIS_ASC_LUN_BECOMING_READY:
93					SHOW_INFO0(2, "Becoming ready");
94					// wait a bit - the device needs some time
95					snooze(100000);
96					return MK_ERROR(err_act_many_retries, B_DEV_NOT_READY);
97
98				case SCSIS_ASC_WAS_RESET:
99					SHOW_INFO0(2, "Unit was reset");
100					// TBD: need a better error code here
101					// as some earlier command led to the reset, we are innocent
102					return MK_ERROR(err_act_retry, B_DEV_NOT_READY);
103			}
104
105			switch (sense->asc) {
106				case SCSIS_ASC_DATA_RECOV_NO_ERR_CORR >> 8:
107				case SCSIS_ASC_DATA_RECOV_WITH_CORR >> 8:
108					// these are the groups of recovered data with or without correction
109					// we should print at least a warning here
110					SHOW_ERROR(0, "Recovered data, asc=0x%2x, ascq=0x%2x",
111						sense->asc, sense->ascq);
112					return MK_ERROR(err_act_ok, B_OK);
113
114				case SCSIS_ASC_WRITE_PROTECTED >> 8:
115					SHOW_ERROR0( 2, "Write protected" );
116
117					// isn't there any proper "write protected" error code?
118					return MK_ERROR(err_act_fail, B_READ_ONLY_DEVICE);
119
120				case SCSIS_ASC_NO_MEDIUM >> 8:
121					SHOW_FLOW0(2, "No medium");
122					return MK_ERROR(err_act_fail, B_DEV_NO_MEDIA);
123			}
124
125			// we issue this info very late, so we don't clutter syslog with
126			// messages about changed or missing media
127			SHOW_ERROR(3, "0x%04x", (sense->asc << 8) | sense->ascq);
128
129			switch (sense->sense_key) {
130				case SCSIS_KEY_NO_SENSE:
131					SHOW_ERROR0(2, "No sense");
132
133					// we thought there was an error, huh?
134					return MK_ERROR(err_act_ok, B_OK);
135
136				case SCSIS_KEY_RECOVERED_ERROR:
137					SHOW_ERROR0(2, "Recovered error");
138
139					// we should probably tell about that; perhaps tomorrow
140					return MK_ERROR(err_act_ok, B_OK);
141
142				case SCSIS_KEY_NOT_READY:
143					return MK_ERROR(err_act_retry, B_DEV_NOT_READY);
144
145				case SCSIS_KEY_MEDIUM_ERROR:
146					SHOW_ERROR0(2, "Medium error");
147					return MK_ERROR( err_act_retry, B_DEV_RECALIBRATE_ERROR);
148
149				case SCSIS_KEY_HARDWARE_ERROR:
150					SHOW_ERROR0(2, "Hardware error");
151					return MK_ERROR(err_act_retry, B_DEV_SEEK_ERROR);
152
153				case SCSIS_KEY_ILLEGAL_REQUEST:
154					SHOW_ERROR0(2, "Illegal request");
155					return MK_ERROR(err_act_invalid_req, B_ERROR);
156
157				case SCSIS_KEY_UNIT_ATTENTION:
158					SHOW_ERROR0(2, "Unit attention");
159					return MK_ERROR( err_act_retry, B_DEV_NOT_READY);
160
161				case SCSIS_KEY_DATA_PROTECT:
162					SHOW_ERROR0(2, "Data protect");
163
164					// we could set "permission denied", but that's probably
165					// irritating to the user
166					return MK_ERROR(err_act_fail, B_NOT_ALLOWED);
167
168				case SCSIS_KEY_BLANK_CHECK:
169					SHOW_ERROR0(2, "Is blank");
170
171					return MK_ERROR(err_act_fail, B_DEV_UNREADABLE);
172
173				case SCSIS_KEY_VENDOR_SPECIFIC:
174					return MK_ERROR(err_act_fail, B_ERROR);
175
176				case SCSIS_KEY_COPY_ABORTED:
177					// we don't use copy, so this is really wrong
178					return MK_ERROR(err_act_fail, B_ERROR);
179
180				case SCSIS_KEY_ABORTED_COMMAND:
181					// proper error code?
182					return MK_ERROR(err_act_retry, B_ERROR);
183
184				case SCSIS_KEY_EQUAL:
185				case SCSIS_KEY_MISCOMPARE:
186					// we don't search, so this is really wrong
187					return MK_ERROR(err_act_fail, B_ERROR);
188
189				case SCSIS_KEY_VOLUME_OVERFLOW:
190					// not the best return code, but this error doesn't apply
191					// to devices we currently support
192					return MK_ERROR(err_act_fail, B_DEV_SEEK_ERROR);
193
194				case SCSIS_KEY_RESERVED:
195				default:
196					return MK_ERROR(err_act_fail, B_ERROR);
197			}
198
199		default:
200			// shouldn't happen - there are only 2 error codes defined
201			SHOW_ERROR(2, "Invalid sense type (0x%x)", sense->error_code);
202			return MK_ERROR(err_act_fail, B_ERROR);
203	}
204}
205
206
207/*!	Check scsi status, using sense if available. */
208static err_res
209check_scsi_status(scsi_periph_device_info *device, scsi_ccb *request)
210{
211	SHOW_FLOW(3, "%d", request->device_status & SCSI_STATUS_MASK);
212
213	switch (request->device_status & SCSI_STATUS_MASK) {
214		case SCSI_STATUS_GOOD:
215			// shouldn't happen (cam_status should be CAM_REQ_CMP)
216			return MK_ERROR(err_act_ok, B_OK);
217
218		case SCSI_STATUS_CHECK_CONDITION:
219			return check_sense(device, request);
220
221		case SCSI_STATUS_QUEUE_FULL:
222			// SIM should have automatically requeued request, fall through
223		case SCSI_STATUS_BUSY:
224			// take deep breath and try again
225			snooze(1000000);
226			return MK_ERROR(err_act_retry, B_DEV_TIMEOUT);
227
228		case SCSI_STATUS_COMMAND_TERMINATED:
229			return MK_ERROR(err_act_retry, B_INTERRUPTED);
230
231		default:
232			return MK_ERROR(err_act_retry, B_ERROR);
233	}
234}
235
236
237/*!	Check result of request
238 *	1. check SCSI subsystem problems
239 *	2. if request hit device, check SCSI status
240 *	3. if request got executed, check sense
241 */
242err_res
243periph_check_error(scsi_periph_device_info *device, scsi_ccb *request)
244{
245	SHOW_FLOW(4, "%d", request->subsys_status & SCSI_SUBSYS_STATUS_MASK);
246
247	switch (request->subsys_status & SCSI_SUBSYS_STATUS_MASK) {
248		// everything is ok
249		case SCSI_REQ_CMP:
250			return MK_ERROR(err_act_ok, B_OK);
251
252		// no device
253		case SCSI_LUN_INVALID:
254		case SCSI_TID_INVALID:
255		case SCSI_PATH_INVALID:
256		case SCSI_DEV_NOT_THERE:
257		case SCSI_NO_HBA:
258			SHOW_ERROR0(2, "No device");
259			return MK_ERROR(err_act_fail, B_DEV_BAD_DRIVE_NUM);
260
261		// device temporary unavailable
262		case SCSI_SEL_TIMEOUT:
263		case SCSI_BUSY:
264		case SCSI_SCSI_BUSY:
265		case SCSI_HBA_ERR:
266		case SCSI_MSG_REJECT_REC:
267		case SCSI_NO_NEXUS:
268		case SCSI_FUNC_NOTAVAIL:
269		case SCSI_RESRC_UNAVAIL:
270			// take a deep breath and hope device becomes ready
271			snooze(1000000);
272			return MK_ERROR(err_act_retry, B_DEV_TIMEOUT);
273
274		// data transmission went wrong
275		case SCSI_DATA_RUN_ERR:
276		case SCSI_UNCOR_PARITY:
277			SHOW_ERROR0(2, "Data transmission failed");
278			// retry immediately
279			return MK_ERROR(err_act_retry, B_DEV_READ_ERROR);
280
281		// request broken
282		case SCSI_REQ_INVALID:
283			SHOW_ERROR0(2, "Invalid request");
284			return MK_ERROR(err_act_fail, B_ERROR);
285
286		// request aborted
287		case SCSI_REQ_ABORTED:
288		case SCSI_SCSI_BUS_RESET:
289		case SCSI_REQ_TERMIO:
290		case SCSI_UNEXP_BUSFREE:
291		case SCSI_BDR_SENT:
292		case SCSI_CMD_TIMEOUT:
293		case SCSI_IID_INVALID:
294		case SCSI_UNACKED_EVENT:
295		case SCSI_IDE:
296		case SCSI_SEQUENCE_FAIL:
297			// take a small breath and retry
298			snooze(100000);
299			return MK_ERROR(err_act_retry, B_DEV_TIMEOUT);
300
301		// device error
302		case SCSI_REQ_CMP_ERR:
303			return check_scsi_status(device, request);
304
305		// device error, but we don't know what happened
306		case SCSI_AUTOSENSE_FAIL:
307			SHOW_ERROR0(2, "Auto-sense failed, don't know what really happened");
308			return MK_ERROR(err_act_fail, B_ERROR);
309
310		// should not happen, give up
311		case SCSI_BUS_RESET_DENIED:
312		case SCSI_PROVIDE_FAIL:
313		case SCSI_UA_TERMIO:
314		case SCSI_CDB_RECVD:
315		case SCSI_LUN_ALLREADY_ENAB:
316			// supposed to fall through
317		default:
318			return MK_ERROR(err_act_fail, B_ERROR);
319	}
320}
321