btrfs: [] on the end of a struct field is a variable length array.
[haiku.git] / src / add-ons / kernel / generic / scsi_periph / error_handling.cpp
blobf576158c1ca1ce9fe97d122ebcdc88c3b2a9abbe
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 */
8 //! Error handling
11 #include "scsi_periph_int.h"
14 /*! Decode sense data and generate error code. */
15 static
16 err_res check_sense(scsi_periph_device_info *device, scsi_ccb *request)
18 scsi_sense *sense = (scsi_sense *)request->sense;
20 if ((request->subsys_status & SCSI_AUTOSNS_VALID) == 0) {
21 SHOW_ERROR0(2, "No auto-sense (but there should be)");
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);
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);
32 // that's a bit too short
33 return MK_ERROR(err_act_fail, B_ERROR);
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);
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");
49 // we need something like "busy"
50 return MK_ERROR(err_act_fail, B_DEV_NOT_READY);
52 case SCSIS_ASC_LUN_NEED_INIT:
53 SHOW_INFO0(2, "LUN needs init");
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);
59 case SCSIS_ASC_LUN_NEED_MANUAL_HELP:
60 SHOW_ERROR0(2, "LUN needs manual help");
62 return MK_ERROR(err_act_fail, B_DEV_NOT_READY);
64 case SCSIS_ASC_LUN_FORMATTING:
65 SHOW_INFO0(2, "LUN is formatting");
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);
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);
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);
80 case SCSIS_ASC_ID_RECOV:
81 SHOW_ERROR0(2, "Recovered ID with ECC");
82 return MK_ERROR(err_act_ok, B_OK);
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);
90 return MK_ERROR(err_act_retry, B_DEV_MEDIA_CHANGE_REQUESTED);
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);
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);
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);
114 case SCSIS_ASC_WRITE_PROTECTED >> 8:
115 SHOW_ERROR0( 2, "Write protected" );
117 // isn't there any proper "write protected" error code?
118 return MK_ERROR(err_act_fail, B_READ_ONLY_DEVICE);
120 case SCSIS_ASC_NO_MEDIUM >> 8:
121 SHOW_FLOW0(2, "No medium");
122 return MK_ERROR(err_act_fail, B_DEV_NO_MEDIA);
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);
129 switch (sense->sense_key) {
130 case SCSIS_KEY_NO_SENSE:
131 SHOW_ERROR0(2, "No sense");
133 // we thought there was an error, huh?
134 return MK_ERROR(err_act_ok, B_OK);
136 case SCSIS_KEY_RECOVERED_ERROR:
137 SHOW_ERROR0(2, "Recovered error");
139 // we should probably tell about that; perhaps tomorrow
140 return MK_ERROR(err_act_ok, B_OK);
142 case SCSIS_KEY_NOT_READY:
143 return MK_ERROR(err_act_retry, B_DEV_NOT_READY);
145 case SCSIS_KEY_MEDIUM_ERROR:
146 SHOW_ERROR0(2, "Medium error");
147 return MK_ERROR( err_act_retry, B_DEV_RECALIBRATE_ERROR);
149 case SCSIS_KEY_HARDWARE_ERROR:
150 SHOW_ERROR0(2, "Hardware error");
151 return MK_ERROR(err_act_retry, B_DEV_SEEK_ERROR);
153 case SCSIS_KEY_ILLEGAL_REQUEST:
154 SHOW_ERROR0(2, "Illegal request");
155 return MK_ERROR(err_act_invalid_req, B_ERROR);
157 case SCSIS_KEY_UNIT_ATTENTION:
158 SHOW_ERROR0(2, "Unit attention");
159 return MK_ERROR( err_act_retry, B_DEV_NOT_READY);
161 case SCSIS_KEY_DATA_PROTECT:
162 SHOW_ERROR0(2, "Data protect");
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);
168 case SCSIS_KEY_BLANK_CHECK:
169 SHOW_ERROR0(2, "Is blank");
171 return MK_ERROR(err_act_fail, B_DEV_UNREADABLE);
173 case SCSIS_KEY_VENDOR_SPECIFIC:
174 return MK_ERROR(err_act_fail, B_ERROR);
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);
180 case SCSIS_KEY_ABORTED_COMMAND:
181 // proper error code?
182 return MK_ERROR(err_act_retry, B_ERROR);
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);
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);
194 case SCSIS_KEY_RESERVED:
195 default:
196 return MK_ERROR(err_act_fail, B_ERROR);
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);
207 /*! Check scsi status, using sense if available. */
208 static err_res
209 check_scsi_status(scsi_periph_device_info *device, scsi_ccb *request)
211 SHOW_FLOW(3, "%d", request->device_status & SCSI_STATUS_MASK);
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);
218 case SCSI_STATUS_CHECK_CONDITION:
219 return check_sense(device, request);
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);
228 case SCSI_STATUS_COMMAND_TERMINATED:
229 return MK_ERROR(err_act_retry, B_INTERRUPTED);
231 default:
232 return MK_ERROR(err_act_retry, B_ERROR);
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
242 err_res
243 periph_check_error(scsi_periph_device_info *device, scsi_ccb *request)
245 SHOW_FLOW(4, "%d", request->subsys_status & SCSI_SUBSYS_STATUS_MASK);
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);
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);
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);
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);
281 // request broken
282 case SCSI_REQ_INVALID:
283 SHOW_ERROR0(2, "Invalid request");
284 return MK_ERROR(err_act_fail, B_ERROR);
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);
301 // device error
302 case SCSI_REQ_CMP_ERR:
303 return check_scsi_status(device, request);
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);
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);