1
/***************************************************************************
4
* Fri Oct 20 12:24:41 2006
5
* Copyright 2006 Rouquier Philippe
6
* <Rouquier Philippe@localhost.localdomain>
7
****************************************************************************/
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License as published by
12
* the Free Software Foundation; either version 2 of the License, or
13
* (at your option) any later version.
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU Library General Public License for more details.
20
* You should have received a copy of the GNU General Public License
21
* along with this program; if not, write to the Free Software
22
* Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA
32
#include "scsi-error.h"
33
#include "scsi-utils.h"
34
#include "scsi-base.h"
35
#include "scsi-sense-data.h"
38
* defines to interpret sense data (returned after SENSE REQUEST)
39
* (defined in SCSI Primary command 3 / SPC specs)
42
#define SENSE_DATA_KEY(sense) ((sense) ? (sense) [2] & 0x0F : 0x00) /* Sense code itself */
43
#define SENSE_DATA_ASC(sense) ((sense) ? (sense) [12] : 0x00) /* Additional Sense Code */
44
#define SENSE_DATA_ASCQ(sense) ((sense) ? (sense) [13] : 0x00) /* Additional Sense Code Qualifier */
45
#define SENSE_DATA_ASC_ASCQ(sense) ((sense) ? (sense) [12] << 8 | (sense) [13] : 0x00) /* ASC and ASCQ combined */
47
#define SENSE_CODE_NOT_READY 0x02
48
#define SENSE_CODE_ILLEGAL_REQUEST 0x05
49
#define SENSE_CODE_UNIT_ATTENTION 0x06
51
#define ASC_CODE_NOT_READY 0x04
52
#define ASC_CODE_PARAMETER 0x26
53
#define ASC_CODE_PROTECTION_KEY 0x6F
55
#define ASC_ASCQ_CODE_INVALID_COMMAND 0x2000
56
#define ASC_ASCQ_CODE_OUTRANGE_ADDRESS 0x2100
57
#define ASC_ASCQ_CODE_INVALID_ADDRESS 0x2101
58
#define ASC_ASCQ_CODE_INVALID_FIELD_IN_PARAM 0x2600
59
#define ASC_ASCQ_CODE_INVALID_FIELD_IN_CDB 0x2400
60
#define ASC_ASCQ_CODE_INSUFFICIENT_TIME_FOR_OPERATION 0x2E00
61
#define ASC_ASCQ_CODE_KEY_NOT_ESTABLISHED 0x6F02
62
#define ASC_ASCQ_CODE_SCRAMBLED_SECTOR 0x6F03
63
#define ASC_ASCQ_CODE_INVALID_TRACK_MODE 0x6400
70
brasero_sense_data_print (uchar *sense_data)
77
printf("Sense key: 0x%02x ", sense_data [0]);
78
for (i = 1; i < BRASERO_SENSE_DATA_SIZE; i ++)
79
printf("0x%02x ", sense_data [i]);
84
static BraseroScsiResult
85
brasero_sense_data_unknown (uchar *sense_data, BraseroScsiErrCode *err)
87
BRASERO_SCSI_SET_ERRCODE (err, BRASERO_SCSI_ERR_UNKNOWN);
88
brasero_sense_data_print (sense_data);
90
return BRASERO_SCSI_FAILURE;
93
static BraseroScsiResult
94
brasero_sense_data_not_ready (uchar *sense_data, BraseroScsiErrCode *err)
96
BraseroScsiResult res = BRASERO_SCSI_FAILURE;
98
switch (SENSE_DATA_ASCQ (sense_data)) {
99
case ASC_CODE_NOT_READY:
100
BRASERO_SCSI_SET_ERRCODE (err, BRASERO_SCSI_NOT_READY);
104
res = brasero_sense_data_unknown (sense_data, err);
111
static BraseroScsiResult
112
brasero_sense_data_illegal_request (uchar *sense_data, BraseroScsiErrCode *err)
114
BraseroScsiResult res = BRASERO_SCSI_FAILURE;
116
switch (SENSE_DATA_ASC_ASCQ (sense_data)) {
117
case ASC_ASCQ_CODE_INVALID_COMMAND:
118
BRASERO_SCSI_SET_ERRCODE (err, BRASERO_SCSI_INVALID_COMMAND);
121
case ASC_ASCQ_CODE_OUTRANGE_ADDRESS:
122
BRASERO_SCSI_SET_ERRCODE (err, BRASERO_SCSI_OUTRANGE_ADDRESS);
125
case ASC_ASCQ_CODE_INVALID_ADDRESS:
126
BRASERO_SCSI_SET_ERRCODE (err, BRASERO_SCSI_INVALID_ADDRESS);
129
case ASC_ASCQ_CODE_INVALID_FIELD_IN_PARAM:
130
BRASERO_SCSI_SET_ERRCODE (err, BRASERO_SCSI_INVALID_PARAMETER);
133
case ASC_ASCQ_CODE_INVALID_FIELD_IN_CDB:
134
BRASERO_SCSI_SET_ERRCODE (err, BRASERO_SCSI_INVALID_FIELD);
137
case ASC_ASCQ_CODE_KEY_NOT_ESTABLISHED:
138
case ASC_ASCQ_CODE_SCRAMBLED_SECTOR:
139
BRASERO_SCSI_SET_ERRCODE (err, BRASERO_SCSI_KEY_NOT_ESTABLISHED);
142
case ASC_ASCQ_CODE_INVALID_TRACK_MODE:
143
BRASERO_SCSI_SET_ERRCODE (err, BRASERO_SCSI_INVALID_TRACK_MODE);
147
res = brasero_sense_data_unknown (sense_data, err);
154
static BraseroScsiResult
155
brasero_sense_data_unit_attention (uchar *sense_data,
156
BraseroScsiErrCode *err)
158
BraseroScsiResult res = BRASERO_SCSI_FAILURE;
160
switch (SENSE_DATA_ASC_ASCQ (sense_data)) {
161
case ASC_ASCQ_CODE_INSUFFICIENT_TIME_FOR_OPERATION:
162
BRASERO_SCSI_SET_ERRCODE (err, BRASERO_SCSI_TIMEOUT);
166
res = brasero_sense_data_unknown (sense_data, err);
174
brasero_sense_data_process (uchar *sense_data,
175
BraseroScsiErrCode *err)
177
BraseroScsiResult res = BRASERO_SCSI_FAILURE;
181
/* see if something was written to the sense buffer and if we
182
* can interpret more precisely what went wrong */
183
switch (SENSE_DATA_KEY (sense_data)) {
184
case SENSE_CODE_NOT_READY:
185
res = brasero_sense_data_not_ready (sense_data, err);
188
case SENSE_CODE_ILLEGAL_REQUEST:
189
res = brasero_sense_data_illegal_request (sense_data, err);
192
case SENSE_CODE_UNIT_ATTENTION:
193
res = brasero_sense_data_unit_attention (sense_data, err);
197
res = brasero_sense_data_unknown (sense_data, err);