"Fossies" - the Fresh Open Source Software Archive 
Member "xorriso-1.5.4/libburn/spc.c" (30 Jan 2021, 58029 Bytes) of package /linux/misc/xorriso-1.5.4.pl02.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "spc.c" see the
Fossies "Dox" file reference documentation and the last
Fossies "Diffs" side-by-side code changes report:
1.5.2_vs_1.5.4.
1 /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
2
3 /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
4 Copyright (c) 2006 - 2019 Thomas Schmitt <scdbackup@gmx.net>
5 Provided under GPL version 2 or later.
6 */
7
8 /* scsi primary commands */
9
10 #ifdef HAVE_CONFIG_H
11 #include "../config.h"
12 #endif
13
14 #include <unistd.h>
15 #include <stdio.h>
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <fcntl.h>
19 #include <sys/ioctl.h>
20 #include <string.h>
21
22 /* ts A61008 */
23 /* #include <a ssert.h> */
24
25 #include <stdlib.h>
26
27 #include "libburn.h"
28 #include "transport.h"
29 #include "spc.h"
30 #include "mmc.h"
31 #include "sbc.h"
32 #include "drive.h"
33 #include "debug.h"
34 #include "options.h"
35 #include "init.h"
36 #include "util.h"
37
38 #include "libdax_msgs.h"
39 extern struct libdax_msgs *libdax_messenger;
40
41 /* ts A91111 :
42 whether to log SCSI commands:
43 bit0= log in /tmp/libburn_sg_command_log
44 bit1= log to stderr
45 bit2= flush every line
46 */
47 extern int burn_sg_log_scsi;
48
49
50 /* spc command set */
51 /* ts A70519 : allocation length byte 3+4 was 0,255 */
52 static unsigned char SPC_INQUIRY[] = { 0x12, 0, 0, 0, 36, 0 };
53
54 /*static char SPC_TEST[]={0,0,0,0,0,0};*/
55 static unsigned char SPC_PREVENT[] = { 0x1e, 0, 0, 0, 1, 0 };
56 static unsigned char SPC_ALLOW[] = { 0x1e, 0, 0, 0, 0, 0 };
57 static unsigned char SPC_MODE_SENSE[] = { 0x5a, 0, 0, 0, 0, 0, 0, 16, 0, 0 };
58 static unsigned char SPC_MODE_SELECT[] = { 0x55, 16, 0, 0, 0, 0, 0, 0, 0, 0 };
59 static unsigned char SPC_REQUEST_SENSE[] = { 0x03, 0, 0, 0, 18, 0 };
60 static unsigned char SPC_TEST_UNIT_READY[] = { 0x00, 0, 0, 0, 0, 0 };
61
62 #ifdef Libburn_enable_scsi_cmd_ABh
63 static unsigned char SPC_READ_MEDIA_SERIAL_NUMBER[] =
64 { 0xAB, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
65 #endif
66
67 /* ts A70519 : An initializer for the abstract SCSI command structure */
68 int scsi_init_command(struct command *c, unsigned char *opcode, int oplen)
69 {
70 if (oplen > 16)
71 return 0;
72 memset(c, 0, sizeof(struct command));
73 memcpy(c->opcode, opcode, oplen);
74 c->oplen = oplen;
75 c->dir = NO_TRANSFER;
76 c->dxfer_len = -1;
77 memset(c->sense, 0, sizeof(c->sense));
78 c->sense_len = 0;
79 c->error = 0;
80 c->retry = 0;
81 c->page = NULL;
82 c->timeout = Libburn_scsi_default_timeouT;
83 c->start_time = c->end_time = 0.0;
84 c->retry_count = 0;
85 c->last_retry_key = 0;
86 c->last_retry_asc = 0;
87 c->last_retry_ascq = 0;
88 return 1;
89 }
90
91
92 /* ts B00728 */
93 int spc_decode_sense(unsigned char *sense, int senselen,
94 int *key, int *asc, int *ascq)
95 {
96 *key = *asc = *ascq = 0;
97 if ((sense[0] & 0x7f) == 0x72 || (sense[0] & 0x7f) == 0x73) {
98 if (senselen <= 0 || senselen > 1)
99 *key = sense[1] & 0x0f;
100 if (senselen <= 0 || senselen > 2)
101 *asc = sense[2];
102 if (senselen <= 0 || senselen > 3)
103 *ascq = sense[3];
104 return 1;
105 }
106 if (senselen <= 0 || senselen > 2)
107 *key = sense[2] & 0x0f;
108 if (senselen <= 0 || senselen > 12)
109 *asc = sense[12];
110 if (senselen <= 0 || senselen > 13)
111 *ascq = sense[13];
112 return 1;
113 }
114
115
116 int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq,
117 int *progress)
118 {
119 struct command *c;
120
121 c = &(d->casual_command);
122 if (mmc_function_spy(d, "test_unit_ready") <= 0)
123 return 0;
124
125 scsi_init_command(c, SPC_TEST_UNIT_READY,sizeof(SPC_TEST_UNIT_READY));
126 c->retry = 0;
127 c->dir = NO_TRANSFER;
128 d->issue_command(d, c);
129 *key = *asc = *ascq = 0;
130 *progress = -1;
131 if (c->error) {
132 spc_decode_sense(c->sense, 0, key, asc, ascq);
133 if (c->sense[0] == 0x70 &&
134 ((c->sense[2] & 0x0f) == 0 || (c->sense[2] & 0x0f) == 2) &&
135 (c->sense[15] & 0x80))
136 *progress = (c->sense[16] << 8) + c->sense[17];
137 return (*key == 0);
138 }
139 return 1;
140 }
141
142
143 int spc_test_unit_ready(struct burn_drive *d)
144 {
145 int key, asc, ascq, progress;
146
147 return spc_test_unit_ready_r(d, &key, &asc, &ascq, &progress);
148 }
149
150
151 /* ts A70315 */
152 /** @param flag bit0=do not wait 0.1 seconds before first test unit ready
153 bit1=do not issue success message
154 */
155 /** Wait until the drive state becomes clear or until max_usec elapsed */
156 int spc_wait_unit_attention(struct burn_drive *d, int max_sec, char *cmd_text,
157 int flag)
158 {
159 int i, ret = 1, key = 0, asc = 0, ascq = 0, clueless_start = 0;
160 static double tests_per_second = 2.0;
161 int sleep_usecs, loop_limit, clueless_timeout, progress;
162 char *msg = NULL, *cmd_name = NULL, *cmd_cpt;
163 unsigned char sense[14];
164
165 BURN_ALLOC_MEM(msg, char, 320);
166 BURN_ALLOC_MEM(cmd_name, char, 320);
167 clueless_timeout = 5 * tests_per_second + 1;
168 loop_limit = max_sec * tests_per_second + 1;
169 sleep_usecs = 1000000 / tests_per_second;
170
171 strcpy(cmd_name, cmd_text);
172 cmd_cpt = strchr(cmd_name, ':');
173 if (cmd_cpt != NULL)
174 *cmd_cpt = 0;
175
176 if (!(flag & 1))
177 usleep(sleep_usecs);
178
179 for(i = !(flag & 1); i < loop_limit; i++) {
180 ret = spc_test_unit_ready_r(d, &key, &asc, &ascq, &progress);
181 if (ret > 0) /* ready */
182 break;
183 if (key!=0x2 || asc!=0x4) {
184 if (key == 0x2 && asc == 0x3A) {
185 ret = 1; /* medium not present = ok */
186 /* <<<
187 ts A70912 :
188 My LG GSA-4082B on asynchronous load:
189 first it reports no media 2,3A,00,
190 then it reports not ready 2,04,00,
191 further media inquiry retrieves wrong data
192
193 if(i<=100)
194 goto slumber;
195 */
196 break;
197 }
198 if (key == 0x6 && asc == 0x28)
199 /* medium change notice or alike = try again */
200 goto slumber;
201
202 handle_error:;
203 /* ts A90213 */
204 sprintf(msg,
205 "Asynchronous SCSI error on %s: ", cmd_name);
206 sense[0] = 0x70; /* Fixed format sense data */
207 sense[2] = key;
208 sense[12] = asc;
209 sense[13] = ascq;
210 scsi_error_msg(d, sense, 14, msg + strlen(msg),
211 &key, &asc, &ascq);
212 libdax_msgs_submit(libdax_messenger, d->global_index,
213 0x0002014d,
214 LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
215 msg, 0, 0);
216 if (cmd_cpt != NULL) {
217 sprintf(msg, "Attempted SCSI CDB: %s",
218 cmd_cpt + 1);
219 libdax_msgs_submit(libdax_messenger,
220 d->global_index, 0x0002014d,
221 LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
222 msg, 0, 0);
223 }
224 d->cancel = 1;
225 break;
226 } else if (ascq == 0x00) { /* CAUSE NOT REPORTABLE */
227 /* Might be a clueless system adapter */
228 if (clueless_start == 0)
229 clueless_start = i;
230 if (i - clueless_start > clueless_timeout) {
231 libdax_msgs_submit(libdax_messenger,
232 d->global_index,
233 0x00000002,
234 LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH,
235 "Ended clueless NOT READY cycle",
236 0, 0);
237 if (cmd_cpt != NULL) {
238 sprintf(msg, "Attempted SCSI CDB: %s",
239 cmd_cpt + 1);
240 libdax_msgs_submit(libdax_messenger,
241 d->global_index,
242 0x00000002,
243 LIBDAX_MSGS_SEV_DEBUG,
244 LIBDAX_MSGS_PRIO_HIGH,
245 msg, 0, 0);
246 }
247 ret = 1; /* medium not present = ok */
248 break;
249 }
250 } else if (ascq == 0x02 || ascq == 0x03)
251 goto handle_error;
252
253 slumber:;
254 usleep(sleep_usecs);
255 }
256 if (ret <= 0 || !(flag & 2)) {
257 sprintf(msg, "Async %s %s after %d.%d seconds",
258 cmd_name, (ret > 0 ? "succeeded" : "failed"),
259 i / 10, i % 10);
260 libdax_msgs_submit(libdax_messenger, d->global_index,
261 0x00020150, LIBDAX_MSGS_SEV_DEBUG,
262 LIBDAX_MSGS_PRIO_LOW, msg, 0, 0);
263 }
264
265 if (i < max_sec * 10)
266 {ret = (ret > 0); goto ex;}
267
268 sprintf(msg, "Timeout (%d s) with asynchronous SCSI command %s\n",
269 max_sec, cmd_name);
270 libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002014f,
271 LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
272 if (cmd_cpt != NULL) {
273 sprintf(msg, "Attempted SCSI CDB: %s", cmd_cpt + 1);
274 libdax_msgs_submit(libdax_messenger, d->global_index,
275 0x0002014f, LIBDAX_MSGS_SEV_SORRY,
276 LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
277 }
278 ret = 0;
279 ex:;
280 BURN_FREE_MEM(msg);
281 BURN_FREE_MEM(cmd_name);
282 return ret;
283 }
284
285
286 void spc_request_sense(struct burn_drive *d, struct buffer *buf)
287 {
288 struct command *c;
289
290 c = &(d->casual_command);
291 if (mmc_function_spy(d, "request_sense") <= 0)
292 return;
293
294 scsi_init_command(c, SPC_REQUEST_SENSE, sizeof(SPC_REQUEST_SENSE));
295 c->retry = 0;
296 c->dxfer_len= c->opcode[4];
297 c->retry = 0;
298 c->page = buf;
299 c->page->sectors = 0;
300 c->page->bytes = 0;
301 c->dir = FROM_DRIVE;
302 d->issue_command(d, c);
303 }
304
305 static int spc_report_async_error(struct burn_drive *d,
306 int key, int asc, int ascq, int flag)
307 {
308 char *msg = NULL;
309 unsigned char sense[14];
310 int ret;
311
312 BURN_ALLOC_MEM(msg, char, BURN_DRIVE_ADR_LEN + 160);
313
314 sprintf(msg, "Asynchronous SCSI error : ");
315 sense[0] = 0x70; /* Fixed format sense data */
316 sense[2] = key;
317 sense[12] = asc;
318 sense[13] = ascq;
319 scsi_error_msg(d, sense, 14, msg + strlen(msg), &key, &asc, &ascq);
320 libdax_msgs_submit(libdax_messenger, d->global_index,
321 0x000201a5,
322 LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
323 msg, 0, 0);
324 ret = 1;
325 ex:;
326 BURN_FREE_MEM(msg);
327 return ret;
328 }
329
330 /* @return -3 = other error reported
331 -2 = drive is ready ,
332 -1 = not ready, but no progress reported ,
333 >= 0 progress indication between 0 and 65535
334 */
335 int spc_get_erase_progress(struct burn_drive *d)
336 {
337 struct buffer *b = NULL;
338 int ret, key, asc, ascq, progress;
339
340 if (mmc_function_spy(d, "get_erase_progress") <= 0)
341 {ret = 0; goto ex;}
342
343 /* ts B20104 :
344 TEST UNIT READY seems to be more reliable than REQUEST SENSE.
345 Nevertheless growisofs still uses the latter as fallback.
346 */
347 ret = spc_test_unit_ready_r(d, &key, &asc, &ascq, &progress);
348 if (ret > 0)
349 {ret = -2; goto ex;}
350
351 /* Check key, asc, ascq for errors other than "not yet ready" */
352 if (key != 0 &&
353 (key != 0x2 || asc != 0x04 || ascq == 0x02 || ascq ==0x03)) {
354 spc_report_async_error(d, key, asc, ascq, 0);
355 ret= -3; goto ex;
356 }
357
358 if (progress >= 0)
359 {ret = progress; goto ex;}
360
361 /* Fallback to request sense */
362 BURN_ALLOC_MEM(b, struct buffer, 1);
363 spc_request_sense(d, b);
364
365 /* Checking the preconditions as of SPC-3 4.5.2.4.4 and 4.5.3 */
366 ret = -1;
367 if (b->data[0] == 0x70 &&
368 ((b->data[2] & 0x0f) == 0 || (b->data[2] & 0x0f) == 2) &&
369 (b->data[15] & 0x80))
370 ret = (b->data[16] << 8) | b->data[17];
371 ex:;
372 BURN_FREE_MEM(b);
373 return ret;
374 }
375
376 void spc_inquiry(struct burn_drive *d)
377 {
378 struct buffer *buf = NULL;
379 struct burn_scsi_inquiry_data *id;
380 struct command *c = NULL;
381
382 if (mmc_function_spy(d, "inquiry") <= 0)
383 return;
384
385 BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
386 BURN_ALLOC_MEM_VOID(c, struct command, 1);
387 scsi_init_command(c, SPC_INQUIRY, sizeof(SPC_INQUIRY));
388 c->dxfer_len = (c->opcode[3] << 8) | c->opcode[4];
389 c->retry = 1;
390 c->page = buf;
391 c->page->bytes = 0;
392 c->page->sectors = 0;
393 c->dir = FROM_DRIVE;
394 d->issue_command(d, c);
395 id = (struct burn_scsi_inquiry_data *)d->idata;
396 id->peripheral = 0x7f; /* SPC-3: incabable undefined peripheral type */
397 id->version = 0; /* SPC-3: no claim for conformance */
398 memset(id->vendor, 0, 9);
399 memset(id->product, 0, 17);
400 memset(id->revision, 0, 5);
401 if (c->error) {
402 id->valid = -1;
403 goto ex;
404 }
405 id->peripheral = ((char *) c->page->data)[0];
406 id->version = ((char *) c->page->data)[2];
407 memcpy(id->vendor, c->page->data + 8, 8);
408 memcpy(id->product, c->page->data + 16, 16);
409 memcpy(id->revision, c->page->data + 32, 4);
410 id->valid = 1;
411 ex:;
412 BURN_FREE_MEM(buf);
413 BURN_FREE_MEM(c);
414 return;
415 }
416
417 void spc_prevent(struct burn_drive *d)
418 {
419 struct command *c;
420
421 c = &(d->casual_command);
422 if (mmc_function_spy(d, "prevent") <= 0)
423 return;
424
425 scsi_init_command(c, SPC_PREVENT, sizeof(SPC_PREVENT));
426 c->retry = 1;
427 c->dir = NO_TRANSFER;
428 d->issue_command(d, c);
429
430 #ifdef Libburn_pioneer_dvr_216d_get_evenT
431 mmc_get_event(d);
432 #endif
433
434 }
435
436 void spc_allow(struct burn_drive *d)
437 {
438 struct command *c;
439
440 c = &(d->casual_command);
441 if (mmc_function_spy(d, "allow") <= 0)
442 return;
443
444 scsi_init_command(c, SPC_ALLOW, sizeof(SPC_ALLOW));
445 c->retry = 1;
446 c->dir = NO_TRANSFER;
447 d->issue_command(d, c);
448 }
449
450
451 /* ts B40216 : Outsourced from spc_sense_caps_al().
452 To be called by spc_sense_caps() after spc_sense_caps_al()
453 */
454 static int spc_try_get_performance(struct burn_drive *d, int flag)
455 {
456 int ret;
457 struct burn_feature_descr *feature_descr;
458
459 /* ts B40107 : Feature 0x107 announces availability of GET PERFORMANCE
460 Its WSPD bit announces Type 3.
461 Try this even if the feature is not current.
462 */
463 ret = burn_drive_has_feature(d, 0x107, &feature_descr, 0);
464 if (ret <= 0)
465 return ret;
466 if (feature_descr->data_lenght <= 0)
467 return 1;
468 if (feature_descr->data[0] & 2) /* WSPD */
469 ret = mmc_get_write_performance(d);
470 /* Get read performance */
471 mmc_get_performance(d, 0x00, 0);
472 return 1;
473 }
474
475
476 /*
477 ts A70518 - A90603 : Do not call with *alloc_len < 10
478 */
479 /** @param flag bit0= do only inquire alloc_len
480 @return 1=ok , <=0 error ,
481 2=Block Descriptor Length > 0, retry with flag bit1
482 */
483 static int spc_sense_caps_al(struct burn_drive *d, int *alloc_len, int flag)
484 {
485 struct buffer *buf = NULL;
486 struct scsi_mode_data *m;
487 int page_length, num_write_speeds = 0, i, speed, ret;
488 int old_alloc_len, was_error = 0, block_descr_len;
489 unsigned char *page;
490 struct command *c = NULL;
491 struct burn_speed_descriptor *sd;
492 char *msg = NULL;
493
494 /* ts A61225 : 1 = report about post-MMC-1 speed descriptors */
495 static int speed_debug = 0;
496
497 if (*alloc_len < 10)
498 {ret = 0; goto ex;}
499
500 BURN_ALLOC_MEM(msg, char, BURN_DRIVE_ADR_LEN + 160);
501 BURN_ALLOC_MEM(buf, struct buffer, 1);
502 BURN_ALLOC_MEM(c, struct command, 1);
503
504 /* ts A90602 : Clearing mdata before command execution */
505 m = d->mdata;
506 m->p2a_valid = 0;
507 burn_mdata_free_subs(m);
508
509 memset(buf, 0, sizeof(struct buffer));
510 scsi_init_command(c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
511 c->dxfer_len = *alloc_len;
512 c->opcode[7] = (c->dxfer_len >> 8) & 0xff;
513 c->opcode[8] = c->dxfer_len & 0xff;
514 c->retry = 1;
515 c->opcode[2] = 0x2A;
516 c->page = buf;
517 c->page->bytes = 0;
518 c->page->sectors = 0;
519 c->dir = FROM_DRIVE;
520 d->issue_command(d, c);
521 if (c->error) {
522 memset(buf, 0, sizeof(struct buffer));
523 m->p2a_valid = -1;
524 was_error = 1;
525 }
526
527 /* ts B11103 : qemu SCSI CD-ROM has Block Descriptor Length > 0.
528 The descriptors come between header and page.
529 */
530 block_descr_len = c->page->data[6] * 256 + c->page->data[7];
531
532 if (block_descr_len + 8 + 2 > *alloc_len) {
533 if (block_descr_len + 8 + 2 > BUFFER_SIZE || !(flag & 1)) {
534 m->p2a_valid = -1;
535 sprintf(msg,
536 "MODE SENSE page 2A with oversized Block Descriptors: %s : %d",
537 d->devname, block_descr_len);
538 libdax_msgs_submit(libdax_messenger, d->global_index,
539 0x0002016e, LIBDAX_MSGS_SEV_DEBUG,
540 LIBDAX_MSGS_PRIO_LOW, msg, 0, 0);
541 {ret = 0; goto ex;}
542
543 }
544 *alloc_len = block_descr_len + 10;
545 {ret = 2; goto ex;}
546 }
547
548 /* Skip over Mode Data Header and block descriptors */
549 page = c->page->data + 8 + block_descr_len;
550
551 /* ts A61225 :
552 Although MODE SENSE indeed belongs to SPC, the returned code page
553 2Ah is part of MMC-1 to MMC-3. In MMC-1 5.2.3.4. it has 22 bytes,
554 in MMC-3 6.3.11 there are at least 28 bytes plus a variable length
555 set of speed descriptors. In MMC-5 E.11 it is declared "legacy".
556 ts B11031 :
557 qemu emulates an ATAPI DVD-ROM, which delivers only a page length
558 of 18. This is now tolerated.
559 */
560 /* ts A90603 :
561 SPC-1 8.3.3 enumerates mode page format bytes from 0 to n and
562 defines Page Length as (n-1).
563 */
564 page_length = page[1];
565 old_alloc_len = *alloc_len;
566 *alloc_len = page_length + 10 + block_descr_len;
567 if (flag & 1)
568 {ret = !was_error; goto ex;}
569 if (page_length + 10 > old_alloc_len)
570 page_length = old_alloc_len - 10;
571
572 /* ts A90602 : page_length N asserts page[N+1]. (see SPC-1 8.3.3) */
573 /* ts B11031 : qemu drive has a page_length of 18 */
574 if (page_length < 18) {
575 m->p2a_valid = -1;
576 sprintf(msg, "MODE SENSE page 2A too short: %s : %d",
577 d->devname, page_length);
578 libdax_msgs_submit(libdax_messenger, d->global_index,
579 0x0002016e, LIBDAX_MSGS_SEV_DEBUG,
580 LIBDAX_MSGS_PRIO_LOW, msg, 0, 0);
581 {ret = 0; goto ex;}
582 }
583
584 m->buffer_size = page[12] * 256 + page[13];
585 m->dvdram_read = page[2] & 32;
586 m->dvdram_write = page[3] & 32;
587 m->dvdr_read = page[2] & 16;
588 m->dvdr_write = page[3] & 16;
589 m->dvdrom_read = page[2] & 8;
590 m->simulate = page[3] & 4;
591 m->cdrw_read = page[2] & 2;
592 m->cdrw_write = page[3] & 2;
593 m->cdr_read = page[2] & 1;
594 m->cdr_write = page[3] & 1;
595
596 m->c2_pointers = page[5] & 16;
597 m->underrun_proof = page[4] & 128;
598
599 /* ts A61021 : these fields are marked obsolete in MMC 3 */
600 m->max_read_speed = page[8] * 256 + page[9];
601 m->cur_read_speed = page[14] * 256 + page[15];
602
603 m->max_write_speed = m->cur_write_speed = 0;
604 if (page_length >= 18) /* note: page length is page size - 2 */
605 m->max_write_speed = page[18] * 256 + page[19];
606 if (page_length >= 20)
607 m->cur_write_speed = page[20] * 256 + page[21];
608
609 /* ts A61021 : New field to be set by atip (or following MMC-3 info) */
610 m->min_write_speed = m->max_write_speed;
611
612 /* ts A61225 : for ACh GET PERFORMANCE, Type 03h */
613 m->min_end_lba = 0x7fffffff;
614 m->max_end_lba = 0;
615
616 if (!was_error)
617 m->p2a_valid = 1;
618
619 /* ts A61225 : end of MMC-1 , begin of MMC-3 */
620 if (page_length < 30) /* no write speed descriptors ? */
621 goto no_speed_descriptors;
622
623 m->cur_write_speed = page[28] * 256 + page[29];
624
625 if (speed_debug)
626 fprintf(stderr, "LIBBURN_DEBUG: cur_write_speed = %d\n",
627 m->cur_write_speed);
628
629 num_write_speeds = page[30] * 256 + page[31];
630 m->max_write_speed = m->min_write_speed = m->cur_write_speed;
631
632 if (32 + 4 * num_write_speeds > page_length + 2) {
633 sprintf(msg, "Malformed capabilities page 2Ah received (len=%d, #speeds=%d)", page_length, num_write_speeds);
634 libdax_msgs_submit(libdax_messenger, d->global_index,
635 0x0002013c,
636 LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
637 msg, 0, 0);
638 {ret = 0; goto ex;}
639 }
640
641 for (i = 0; i < num_write_speeds; i++) {
642 speed = page[32 + 4 * i + 2] * 256 + page[32 + 4 * i + 3];
643
644 if (speed_debug)
645 fprintf(stderr,
646 "LIBBURN_DEBUG: write speed #%d = %d kB/s (rc %d)\n",
647 i, speed, page[32 + 4 * i + 1] & 7);
648
649 /* ts A61226 */
650 ret = burn_speed_descriptor_new(&(d->mdata->speed_descriptors),
651 NULL, d->mdata->speed_descriptors, 0);
652 if (ret > 0) {
653 sd = d->mdata->speed_descriptors;
654 sd->source = 1;
655 if (d->current_profile > 0) {
656 sd->profile_loaded = d->current_profile;
657 strcpy(sd->profile_name,
658 d->current_profile_text);
659 }
660 sd->wrc = (( page[32 + 4 * i + 1] & 7 ) == 1 );
661 sd->write_speed = speed;
662 }
663
664 if (speed > m->max_write_speed)
665 m->max_write_speed = speed;
666 if (speed < m->min_write_speed)
667 m->min_write_speed = speed;
668 }
669
670 if (speed_debug)
671 fprintf(stderr,
672 "LIBBURN_DEBUG: 5Ah,2Ah min_write_speed = %d , max_write_speed = %d\n",
673 m->min_write_speed, m->max_write_speed);
674
675 no_speed_descriptors:;
676
677 ret = !was_error;
678 ex:
679 BURN_FREE_MEM(msg);
680 BURN_FREE_MEM(buf);
681 BURN_FREE_MEM(c);
682 return ret;
683 }
684
685
686 void spc_sense_caps(struct burn_drive *d)
687 {
688 int alloc_len, start_len = 30, minimum_len = 28, ret;
689
690 mmc_start_if_needed(d, 1);
691 if (mmc_function_spy(d, "sense_caps") <= 0)
692 return;
693
694 mmc_get_configuration(d);
695
696 /* first command execution to learn Allocation Length */
697 alloc_len = start_len;
698 ret = spc_sense_caps_al(d, &alloc_len, 1);
699 if (ret == 2) {
700 /* ts B40205: Unexpectedly found Block Descriptors.
701 Repeat with new alloc_len.
702 */
703 ret = spc_sense_caps_al(d, &alloc_len, 1);
704 if (ret == 2)
705 goto try_get_performance;
706 }
707 /* ts B11103:
708 qemu ATAPI DVD-ROM delivers only 28.
709 SanDisk Cruzer U3 memory stick throws error on alloc_len < 30.
710 MMC-1 prescribes that 30 are available. qemu tolerates 30.
711 */
712 if (alloc_len >= minimum_len && ret > 0)
713 /* second execution with announced length */
714 spc_sense_caps_al(d, &alloc_len, 0);
715
716 try_get_performance:;
717 spc_try_get_performance(d, 0);
718 }
719
720
721 void spc_sense_error_params(struct burn_drive *d)
722 {
723 struct buffer *buf = NULL;
724 struct scsi_mode_data *m;
725 int alloc_len = 12 ;
726 unsigned char *page;
727 struct command *c = NULL;
728
729 mmc_start_if_needed(d, 1);
730 if (mmc_function_spy(d, "sense_error_params") <= 0)
731 goto ex;
732
733 BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
734 BURN_ALLOC_MEM_VOID(c, struct command, 1);
735
736 scsi_init_command(c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
737 c->dxfer_len = alloc_len;
738 c->opcode[7] = (c->dxfer_len >> 8) & 0xff;
739 c->opcode[8] = c->dxfer_len & 0xff;
740 c->retry = 1;
741 c->opcode[2] = 0x01;
742 c->page = buf;
743 c->page->bytes = 0;
744 c->page->sectors = 0;
745 c->dir = FROM_DRIVE;
746 d->issue_command(d, c);
747 m = d->mdata;
748 page = c->page->data + 8;
749 d->params.retries = page[3];
750 m->retry_page_length = page[1];
751 m->retry_page_valid = 1;
752 ex:;
753 BURN_FREE_MEM(buf);
754 BURN_FREE_MEM(c);
755 }
756
757 void spc_select_error_params(struct burn_drive *d,
758 const struct burn_read_opts *o)
759 {
760 struct buffer *buf = NULL;
761 struct command *c = NULL;
762
763 mmc_start_if_needed(d, 1);
764 if (mmc_function_spy(d, "select_error_params") <= 0)
765 goto ex;
766
767 BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
768 BURN_ALLOC_MEM_VOID(c, struct command, 1);
769
770 scsi_init_command(c, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
771 c->retry = 1;
772 if (d->mdata->retry_page_valid <= 0)
773 d->mdata->retry_page_length = 0;
774 c->opcode[8] = 8 + 2 + d->mdata->retry_page_length;
775 c->page = buf;
776 c->page->bytes = 0;
777 c->page->sectors = 0;
778
779 memset(c->page->data, 0, 8 + 2 + d->mdata->retry_page_length);
780 c->page->bytes = 8 + 2 + d->mdata->retry_page_length;
781 c->page->data[8] = 1;
782 c->page->data[9] = d->mdata->retry_page_length;
783 if (o->transfer_damaged_blocks)
784 c->page->data[10] |= 32;
785 if (o->report_recovered_errors)
786 c->page->data[10] |= 4;
787 if (!o->hardware_error_recovery)
788 c->page->data[10] |= 1;
789 c->page->data[11] = d->params.retries;
790 c->dir = TO_DRIVE;
791 d->issue_command(d, c);
792 ex:;
793 BURN_FREE_MEM(buf);
794 BURN_FREE_MEM(c);
795 }
796
797 void spc_sense_write_params(struct burn_drive *d)
798 {
799 struct buffer *buf = NULL;
800 struct scsi_mode_data *m;
801 int dummy1, dummy2, alloc_len = 10;
802 unsigned char *page;
803 struct command *c = NULL;
804
805 mmc_start_if_needed(d, 1);
806 if (mmc_function_spy(d, "sense_write_params") <= 0)
807 goto ex;
808
809 BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
810 BURN_ALLOC_MEM_VOID(c, struct command, 1);
811
812 /* ts A61007 : Done in soft at only caller burn_drive_grab() */
813 /* a ssert(d->mdata->cdr_write || d->mdata->cdrw_write ||
814 d->mdata->dvdr_write || d->mdata->dvdram_write); */
815
816 scsi_init_command(c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
817 c->dxfer_len = alloc_len;
818 c->opcode[7] = (c->dxfer_len >> 8) & 0xff;
819 c->opcode[8] = c->dxfer_len & 0xff;
820 c->retry = 1;
821 c->opcode[2] = 0x05;
822 c->page = buf;
823 c->page->bytes = 0;
824 c->page->sectors = 0;
825 c->dir = FROM_DRIVE;
826 d->issue_command(d, c);
827
828 /* ts A71128 : do not interpret reply if error */
829 m = d->mdata;
830 if (!c->error) {
831 page = c->page->data + 8;
832 m->write_page_length = page[1];
833 if (m->write_page_length > 0)
834 m->write_page_valid = 1;
835 else
836 m->write_page_length = 0x32;
837 }
838 mmc_read_disc_info(d);
839
840 /* ts A70212 : try to setup d->media_capacity_remaining */
841 if (d->current_profile == 0x1a || d->current_profile == 0x13 ||
842 d->current_profile == 0x12 || d->current_profile == 0x43)
843 d->read_format_capacities(d, -1);
844 else if (d->status == BURN_DISC_BLANK ||
845 (d->current_is_cd_profile && d->status == BURN_DISC_APPENDABLE)) {
846 burn_drive_send_default_page_05(d, 0);
847 d->get_nwa(d, -1, &dummy1, &dummy2);
848 }
849 /* others are hopefully up to date from mmc_read_disc_info() */
850
851 /*
852 fprintf(stderr, "LIBBURN_DEBUG: media_capacity_remaining = %.f\n",
853 (double) d->media_capacity_remaining);
854 */
855
856 ex:;
857 BURN_FREE_MEM(buf);
858 BURN_FREE_MEM(c);
859 }
860
861
862 /* remark ts A61104 :
863 Although command MODE SELECT is SPC, the content of the
864 Write Parameters Mode Page (05h) is MMC (Table 108 in MMC-1).
865 Thus the filling of the mode page is done by mmc_compose_mode_page_5().
866 */
867 void spc_select_write_params(struct burn_drive *d, struct burn_session *s,
868 int tnum, const struct burn_write_opts *o)
869 {
870 struct buffer *buf = NULL;
871 struct command *c = NULL;
872 int alloc_len;
873
874 mmc_start_if_needed(d, 1);
875 if (mmc_function_spy(d, "select_write_params") <= 0)
876 goto ex;
877
878 BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
879 BURN_ALLOC_MEM_VOID(c, struct command, 1);
880
881 /* ts A61007 : All current callers are safe. */
882 /* a ssert(o->drive == d); */
883
884 /* <<< A61030
885 fprintf(stderr,"libburn_debug: write_type=%d multi=%d control=%d\n",
886 o->write_type,o->multi,o->control);
887 fprintf(stderr,"libburn_debug: block_type=%d spc_block_type=%d\n",
888 o->block_type,spc_block_type(o->block_type));
889 */
890
891 alloc_len = 8 + 2 + d->mdata->write_page_length;
892 memset(&(buf->data), 0, alloc_len);
893
894 #ifdef Libburn_pioneer_dvr_216d_load_mode5
895
896 scsi_init_command(c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE));
897 c->dxfer_len = alloc_len;
898 c->opcode[7] = (alloc_len >> 8) & 0xff;
899 c->opcode[8] = alloc_len & 0xff;
900 c->retry = 1;
901 c->opcode[2] = 0x05;
902 c->page = buf;
903 c->page->bytes = 0;
904 c->page->sectors = 0;
905 c->dir = FROM_DRIVE;
906 d->issue_command(d, c);
907
908 if (c->error)
909 memset(&(buf->data), 0,
910 8 + 2 + d->mdata->write_page_length);
911
912 #endif /* Libburn_pioneer_dvr_216d_load_mode5 */
913
914 scsi_init_command(c, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT));
915 c->retry = 1;
916 c->opcode[7] = (alloc_len >> 8) & 0xff;
917 c->opcode[8] = alloc_len & 0xff;
918 c->page = buf;
919 c->page->bytes = 0;
920 c->page->sectors = 0;
921
922 c->page->bytes = alloc_len;
923
924 /* ts A61229 */
925 if (mmc_compose_mode_page_5(d, s, tnum, o, c->page->data + 8) <= 0)
926 goto ex;
927
928 c->dir = TO_DRIVE;
929 d->issue_command(d, c);
930 ex:;
931 BURN_FREE_MEM(buf);
932 BURN_FREE_MEM(c);
933 }
934
935
936 #ifdef Libburn_enable_scsi_cmd_ABh
937
938 /* At least on Linux kernel 3.16 the command ABh causes EFAULT if not sent
939 from the superuser.
940 For a test it may be replaced by a dummy 28h READ12 on block 0.
941 This causes no EFAULT although it sets the wrong dxfer_len 4 rather
942 than 2048. So it is indeed a permission problem and not bad alignment.
943 */
944
945 /* ts B51016 */
946 int spc_read_media_serial_number_al(struct burn_drive *d, int *alloc_len)
947 {
948 struct buffer *buf = NULL;
949 struct command *c = NULL;
950 unsigned char *data;
951 int ret;
952
953 if (*alloc_len < 4)
954 {ret = 0; goto ex;}
955
956 BURN_ALLOC_MEM(buf, struct buffer, 1);
957 BURN_ALLOC_MEM(c, struct command, 1);
958 if (mmc_function_spy(d, "spc_read_media_serial_number") <= 0)
959 {ret = 0; goto ex;}
960 /*
961 #de fine Spc_read_media_serial_number_dummY yes
962 */
963 #ifdef Spc_read_media_serial_number_dummY
964
965 {
966 static unsigned char MMC_READ_12[] =
967 { 0x28, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 };
968
969 scsi_init_command(c, MMC_READ_12, sizeof(MMC_READ_12));
970 c->dxfer_len = *alloc_len;
971 }
972
973 #else
974
975 scsi_init_command(c, SPC_READ_MEDIA_SERIAL_NUMBER,
976 sizeof(SPC_READ_MEDIA_SERIAL_NUMBER));
977 c->dxfer_len = *alloc_len;
978 /* (Will not accept more than 32 KB anyway) */
979 c->opcode[8] = (c->dxfer_len >> 8) & 0xff;
980 c->opcode[9] = c->dxfer_len & 0xff;
981
982 #endif /* ! Spc_read_media_serial_number_dummY */
983
984 c->retry = 1;
985 c->page = buf;
986 memset(c->page->data, 0, *alloc_len);
987 c->page->bytes = 0;
988 c->page->sectors = 0;
989
990 c->dir = FROM_DRIVE;
991 d->issue_command(d, c);
992
993 if (c->error)
994 {ret = 0; goto ex;}
995
996 data = c->page->data;
997
998 #ifdef Spc_read_media_serial_number_dummY
999 d->media_serial_number_len = 0;
1000 #else
1001 d->media_serial_number_len =
1002 (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[7];
1003 #endif
1004
1005 if (*alloc_len >= d->media_serial_number_len + 4) {
1006 if (d->media_serial_number != NULL)
1007 BURN_FREE_MEM(d->media_serial_number);
1008 BURN_ALLOC_MEM(d->media_serial_number, char,
1009 d->media_serial_number_len + 1);
1010 if (d->media_serial_number_len > 0)
1011 memcpy(d->media_serial_number, data + 4,
1012 d->media_serial_number_len);
1013 d->media_serial_number[d->media_serial_number_len] = 0;
1014 }
1015
1016 *alloc_len = d->media_serial_number_len + 4;
1017 ret = 1;
1018 ex:;
1019 BURN_FREE_MEM(c);
1020 BURN_FREE_MEM(buf);
1021 return ret;
1022 }
1023
1024
1025 int spc_read_media_serial_number(struct burn_drive *d)
1026 {
1027 int alloc_len = 4, ret;
1028
1029 ret = spc_read_media_serial_number_al(d, &alloc_len);
1030 if (alloc_len > 4 && alloc_len <= 0x8000 && ret > 0)
1031 ret = spc_read_media_serial_number_al(d, &alloc_len);
1032 return ret;
1033 }
1034
1035 #endif /* Libburn_enable_scsi_cmd_ABh */
1036
1037
1038 void spc_getcaps(struct burn_drive *d)
1039 {
1040 if (mmc_function_spy(d, "getcaps") <= 0)
1041 return;
1042
1043 burn_speed_descriptor_destroy(&(d->mdata->speed_descriptors), 1);
1044 spc_inquiry(d);
1045 spc_sense_caps(d);
1046 spc_sense_error_params(d);
1047 }
1048
1049 /*
1050 don't check totally stupid modes (raw/raw0)
1051 some drives say they're ok, and they're not.
1052 */
1053
1054 void spc_probe_write_modes(struct burn_drive *d)
1055 {
1056 struct buffer *buf = NULL;
1057 int try_write_type = 1;
1058 int try_block_type = 0;
1059 int key, asc, ascq, usable_write_type = -1, usable_block_type = -1;
1060 int last_try = 0;
1061 struct command *c = NULL;
1062
1063 mmc_start_if_needed(d, 1);
1064 if (mmc_function_spy(d, "spc_probe_write_modes") <= 0)
1065 goto ex;
1066
1067 BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
1068 BURN_ALLOC_MEM_VOID(c, struct command, 1);
1069
1070 /* ts A70213 : added pseudo try_write_type 4 to set a suitable mode */
1071 while (try_write_type != 5) {
1072 /* ts A70213 */
1073 if (try_write_type == 4) {
1074 /* Pseudo write type NONE . Set a usable write mode */
1075 if (usable_write_type == -1)
1076 break;
1077 try_write_type = usable_write_type;
1078 try_block_type = usable_block_type;
1079 last_try= 1;
1080 }
1081
1082 scsi_init_command(c, SPC_MODE_SELECT,sizeof(SPC_MODE_SELECT));
1083 c->retry = 1;
1084 c->opcode[8] = 8 + 2 + 0x32;
1085 c->page = buf;
1086
1087 memset(c->page->data, 0, 8 + 2 + 0x32);
1088 c->page->bytes = 8 + 2 + 0x32;
1089
1090 c->page->data[8] = 5;
1091 c->page->data[9] = 0x32;
1092 c->page->data[10] = try_write_type;
1093 if (try_block_type > 4)
1094 c->page->data[11] = 4;
1095 else
1096 c->page->data[11] = 0;
1097 c->page->data[12] = try_block_type;
1098 c->page->data[23] = 150;
1099 c->dir = TO_DRIVE;
1100
1101 d->silent_on_scsi_error = 1;
1102 d->issue_command(d, c);
1103 d->silent_on_scsi_error = 0;
1104
1105 if (last_try)
1106 break;
1107
1108 spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
1109 if (key)
1110 /* try_block_type not supported */;
1111 else {
1112 /* try_write_type, try_block_type is supported mode */
1113 if (try_write_type == 2) /* sao */
1114 d->block_types[try_write_type] =
1115 BURN_BLOCK_SAO;
1116 else
1117 d->block_types[try_write_type] |=
1118 1 << try_block_type;
1119
1120 /* ts A70213 */
1121 if ((usable_write_type < 0 && try_write_type > 0) ||
1122 (try_write_type == 1 && try_block_type == 8)) {
1123 /* Packet is not supported yet.
1124 Prefer TAO MODE_1. */
1125 usable_write_type = try_write_type;
1126 usable_block_type = try_block_type;
1127 }
1128 }
1129 switch (try_block_type) {
1130 case 0:
1131 case 1:
1132 case 2:
1133 try_block_type++;
1134 break;
1135 case 3:
1136 try_block_type = 8;
1137 break;
1138 case 8:
1139 case 9:
1140 case 10:
1141 case 11:
1142 case 12:
1143 try_block_type++;
1144 break;
1145 case 13:
1146 try_block_type = 0;
1147 try_write_type++;
1148 break;
1149 default:
1150 goto ex;
1151 }
1152 }
1153 ex:;
1154 BURN_FREE_MEM(buf);
1155 BURN_FREE_MEM(c);
1156 }
1157
1158 /* ( ts A61229 : shouldn't this go to mmc.c too ?) */
1159
1160 /** @return -1 = error */
1161 int spc_block_type(enum burn_block_types b)
1162 {
1163 switch (b) {
1164 case BURN_BLOCK_SAO:
1165 return 0; /* ignored bitz */
1166 case BURN_BLOCK_RAW0:
1167 return 0;
1168 case BURN_BLOCK_RAW16:
1169 return 1;
1170 case BURN_BLOCK_RAW96P:
1171 return 2;
1172 case BURN_BLOCK_RAW96R:
1173 return 3;
1174 case BURN_BLOCK_MODE1:
1175 return 8;
1176 case BURN_BLOCK_MODE2R:
1177 return 9;
1178 case BURN_BLOCK_MODE2_PATHETIC:
1179 return 10;
1180 case BURN_BLOCK_MODE2_LAME:
1181 return 11;
1182 case BURN_BLOCK_MODE2_OBSCURE:
1183 return 12;
1184 case BURN_BLOCK_MODE2_OK:
1185 return 13;
1186 default:
1187 return -1;
1188 }
1189 /* ts A61007 : already prevented in burn_write_opts_set_write_type() */
1190 /* a ssert(0); */;
1191 }
1192
1193 /* ts A61021 : the spc specific part of sg.c:enumerate_common()
1194 */
1195 int spc_setup_drive(struct burn_drive *d)
1196 {
1197 d->getcaps = spc_getcaps;
1198 d->lock = spc_prevent;
1199 d->unlock = spc_allow;
1200 d->read_disc_info = spc_sense_write_params;
1201 d->get_erase_progress = spc_get_erase_progress;
1202 d->test_unit_ready = spc_test_unit_ready;
1203 d->probe_write_modes = spc_probe_write_modes;
1204 d->send_parameters = spc_select_error_params;
1205 d->send_write_parameters = spc_select_write_params;
1206 return 1;
1207 }
1208
1209 /* ts A61021 : the general SCSI specific part of sg.c:enumerate_common()
1210 @param flag Bitfiled for control purposes
1211 bit0= do not setup spc/sbc/mmc
1212 */
1213 int burn_scsi_setup_drive(struct burn_drive *d, int bus_no, int host_no,
1214 int channel_no, int target_no, int lun_no, int flag)
1215 {
1216 int ret;
1217
1218 /* ts A60923 */
1219 d->bus_no = bus_no;
1220 d->host = host_no;
1221 d->id = target_no;
1222 d->channel = channel_no;
1223 d->lun = lun_no;
1224
1225 /* ts A61106 */
1226 d->silent_on_scsi_error = 0;
1227
1228 /* ts B21023 */
1229 d->had_particular_error = 0;
1230
1231
1232 d->idata = calloc(1, sizeof(struct burn_scsi_inquiry_data));
1233 d->mdata = calloc(1, sizeof(struct scsi_mode_data));
1234
1235 /* ts A61007 : obsolete Assert in drive_getcaps() */
1236 if (d->idata == NULL || d->mdata == NULL) {
1237 libdax_msgs_submit(libdax_messenger, -1, 0x00020108,
1238 LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
1239 "Could not allocate new drive object", 0, 0);
1240 return -1;
1241 }
1242 d->idata->valid = 0;
1243 d->mdata->p2a_valid = 0;
1244 d->mdata->max_read_speed = 0;
1245 d->mdata->cur_read_speed = 0;
1246 d->mdata->max_write_speed = 0;
1247 d->mdata->cur_write_speed = 0;
1248 d->mdata->speed_descriptors = NULL;
1249 d->mdata->write_page_length = 0x32;
1250 d->mdata->write_page_valid = 0;
1251 if (!(flag & 1)) {
1252 ret = spc_setup_drive(d);
1253 if (ret<=0)
1254 return ret;
1255 ret = sbc_setup_drive(d);
1256 if (ret<=0)
1257 return ret;
1258 ret = mmc_setup_drive(d);
1259 if (ret<=0)
1260 return ret;
1261 }
1262 return 1;
1263 }
1264
1265
1266 /* ts A61122 - A80829 */
1267 enum response scsi_error_msg(struct burn_drive *d, unsigned char *sense,
1268 int senselen, char msg_data[161],
1269 int *key, int *asc, int *ascq)
1270 {
1271 int ret;
1272 char *msg;
1273 static char key_def[16][40] = {
1274 "(no specific error)",
1275 "Recovered error",
1276 "Drive not ready",
1277 "Medium error",
1278 "Drive error",
1279 "Illegal request",
1280 "Drive event",
1281 "Data protected",
1282 "Blank/Nonblank",
1283 "Vendor specific code",
1284 "Copy aborted",
1285 "Command aborted",
1286 "(obsolete error code)",
1287 "Volume overflow",
1288 "Miscompare",
1289 "(reserved error code)",
1290 };
1291
1292 msg= msg_data;
1293 *key= *asc= *ascq= -1;
1294
1295 ret = spc_decode_sense(sense, senselen, key, asc, ascq);
1296 if (ret <= 0)
1297 *key= *asc= *ascq= -1;
1298
1299 sprintf(msg, "[%X %2.2X %2.2X] ", *key, *asc, *ascq);
1300 msg= msg + strlen(msg);
1301
1302 if (key_def[*key & 0xf][0] != '(') {
1303 sprintf(msg, "%s. ", key_def[*key & 0xf]);
1304 msg= msg + strlen(msg);
1305 }
1306
1307 switch (*asc) {
1308 case 0x00:
1309 if (*key > 0 || *ascq > 0)
1310 break; /* Fall through to unknown error */
1311 sprintf(msg, "(No error reported by SCSI transaction)");
1312 return GO_ON;
1313
1314 case 0x02:
1315 sprintf(msg, "Not ready");
1316 goto return_retry;
1317 case 0x04:
1318 if (*ascq == 1)
1319 sprintf(msg,
1320 "Logical unit is in the process of becoming ready");
1321 else
1322 sprintf(msg, "Logical unit is not ready");
1323 goto return_retry;
1324 case 0x06:
1325 if (*ascq == 0)
1326 sprintf(msg, "No reference position found");
1327 else
1328 break;
1329 goto return_fail;
1330 case 0x08:
1331 if (*ascq == 0)
1332 sprintf(msg, "Logical unit communication failure");
1333 else if (*ascq == 1)
1334 sprintf(msg, "Logical unit communication timeout");
1335 else if (*ascq == 2)
1336 sprintf(msg, "Logical unit communication parity error");
1337 else if (*ascq == 3)
1338 sprintf(msg, "Logical unit communication crc error");
1339 else
1340 break;
1341 goto return_retry;
1342 case 0x09:
1343 if (*ascq == 0)
1344 sprintf(msg, "Track following error");
1345 else if (*ascq == 1)
1346 sprintf(msg, "Tracking servo failure");
1347 else if (*ascq == 2)
1348 sprintf(msg, "Focus servo failure");
1349 else if (*ascq == 3)
1350 sprintf(msg, "Spindle servo failure");
1351 else if (*ascq == 4)
1352 sprintf(msg, "Head select fault");
1353 else
1354 break;
1355 goto return_fail;
1356 case 0x0C:
1357 if (*ascq == 0)
1358 sprintf(msg, "Write error");
1359 else if (*ascq == 1)
1360 sprintf(msg,
1361 "Write error, recovered with auto-allocation");
1362 else if (*ascq == 2)
1363 sprintf(msg, "Write error, auto reallocation failed");
1364 else if (*ascq == 7)
1365 sprintf(msg, "Write error, recovery needed");
1366 else if (*ascq == 8)
1367 sprintf(msg, "Write error, recovery failed");
1368 else if (*ascq == 9)
1369 sprintf(msg, "Write error, loss of streaming");
1370 else if (*ascq == 0x0f)
1371 sprintf(msg, "Defects in error window");
1372 else
1373 break;
1374 goto return_fail;
1375 case 0x11:
1376 if (*ascq == 0)
1377 sprintf(msg, "Unrecovered read error");
1378 else if (*ascq == 1)
1379 sprintf(msg, "Read retries exhausted");
1380 else if (*ascq == 2)
1381 sprintf(msg, "Error too long to correct");
1382 else if (*ascq == 5)
1383 sprintf(msg, "L-EC uncorrectable error");
1384 else if (*ascq == 6)
1385 sprintf(msg, "CIRC uncorrectable error");
1386 else
1387 break;
1388 goto return_fail;
1389 case 0x15:
1390 if (*ascq == 0)
1391 sprintf(msg, "Random positioning error");
1392 else if (*ascq == 1)
1393 sprintf(msg, "Mechanical positioning error");
1394 else
1395 break;
1396 goto return_fail;
1397 case 0x1a:
1398 if (*ascq == 0)
1399 sprintf(msg, "Parameter list length error");
1400 else
1401 break;
1402 goto return_fail;
1403 case 0x1b:
1404 if (*ascq == 0)
1405 sprintf(msg, "Synchronous data transfer error");
1406 else
1407 break;
1408 goto return_fail;
1409 case 0x20:
1410 if (*ascq == 0)
1411 sprintf(msg, "Invalid command operation code");
1412 else
1413 break;
1414 goto return_fail;
1415 case 0x21:
1416 if (*ascq == 0)
1417 sprintf(msg, "Lba out of range");
1418 else if (*ascq == 1)
1419 sprintf(msg, "Invalid element address");
1420 else if (*ascq == 2)
1421 sprintf(msg, "Invalid address for write");
1422 else if (*ascq == 3)
1423 sprintf(msg, "Invalid write crossing layer jump");
1424 else
1425 break;
1426 goto return_fail;
1427 case 0x24:
1428 if (*ascq == 0)
1429 sprintf(msg, "Invalid field in cdb");
1430 else
1431 break;
1432 goto return_fail;
1433 case 0x26:
1434 if (*ascq == 0)
1435 sprintf(msg, "Invalid field in parameter list");
1436 else if (*ascq == 1)
1437 sprintf(msg, "Parameter not supported");
1438 else if (*ascq == 2)
1439 sprintf(msg, "Parameter value invalid");
1440 else
1441 break;
1442 goto return_fail;
1443 case 0x27:
1444 sprintf(msg, "Write protected");
1445 goto return_fail;
1446 case 0x28:
1447 if (*ascq == 0)
1448 sprintf(msg, "Medium may have changed");
1449 else if (*ascq == 1)
1450 sprintf(msg, "Import or export element accessed");
1451 else if (*ascq == 2)
1452 sprintf(msg, "Format layer may have changed");
1453 else if (*ascq == 3)
1454 sprintf(msg,
1455 "Import/export element accessed, medium changed");
1456 else if (*key == 6)
1457 sprintf(msg, "Unknown ASCQ with drive event ASC 28");
1458 else
1459 break;
1460 goto return_retry;
1461 case 0x29:
1462 if (*ascq == 0)
1463 sprintf(msg,
1464 "Power on, reset, or bus device reset occurred");
1465 else if (*ascq == 1)
1466 sprintf(msg, "Power on occurred");
1467 else if (*ascq == 2)
1468 sprintf(msg, "Bus reset occurred");
1469 else if (*ascq == 3)
1470 sprintf(msg, "Bus device reset function occurred");
1471 else if (*ascq == 4)
1472 sprintf(msg, "Device internal reset");
1473 else
1474 break;
1475 goto return_retry;
1476 case 0x2c:
1477 if (*ascq == 0)
1478 sprintf(msg, "Command sequence error");
1479 else
1480 break;
1481 goto return_fail;
1482 case 0x2e:
1483 if (*ascq == 0)
1484 sprintf(msg, "Insufficient time for operation");
1485 else
1486 break;
1487 goto return_fail;
1488 case 0x30:
1489 if (*ascq == 0)
1490 sprintf(msg, "Incompatible medium installed");
1491 else if (*ascq == 1)
1492 sprintf(msg, "Cannot read medium, unknown format");
1493 else if (*ascq == 2)
1494 sprintf(msg,
1495 "Cannot read medium, incompatible format");
1496 else if (*ascq == 4)
1497 sprintf(msg, "Cannot write medium, unknown format");
1498 else if (*ascq == 5)
1499 sprintf(msg,
1500 "Cannot write medium, incompatible format");
1501 else if (*ascq == 6)
1502 sprintf(msg,
1503 "Cannot format medium, incompatible medium");
1504 else if (*ascq == 7)
1505 sprintf(msg, "Cleaning failure");
1506 else if (*ascq == 8)
1507 sprintf(msg,
1508 "Cannot write, application code mismatch");
1509 else if (*ascq == 9)
1510 sprintf(msg, "Current session not fixated for append");
1511 else if (*ascq == 10)
1512 sprintf(msg, "Medium not formatted");
1513 else if (*ascq == 11)
1514 sprintf(msg,
1515 "Cannot write medium, unsupported medium version");
1516 else
1517 break;
1518 goto return_fail;
1519 case 0x31:
1520 if (*ascq == 0)
1521 sprintf(msg, "Medium unformatted or format corrupted");
1522 else if (*ascq == 1)
1523 sprintf(msg, "Format command failed");
1524 else
1525 break;
1526 goto return_fail;
1527 case 0x32:
1528 if (*ascq == 0)
1529 sprintf(msg, "No defect spare location available");
1530 else
1531 break;
1532 goto return_fail;
1533 case 0x3A:
1534 if (*ascq == 0)
1535 sprintf(msg, "Medium not present");
1536 else if (*ascq == 1)
1537 sprintf(msg, "Medium not present, tray closed");
1538 else if (*ascq == 2)
1539 sprintf(msg, "Medium not present, tray open");
1540 else if (*ascq == 3)
1541 sprintf(msg, "Medium not present, loadable");
1542 else
1543 break;
1544 d->status = BURN_DISC_EMPTY;
1545 goto return_fail;
1546 case 0x3E:
1547 if (*ascq == 1)
1548 sprintf(msg, "Logical unit failure");
1549 else if (*ascq == 2)
1550 sprintf(msg, "Timeout on logical unit");
1551 else
1552 break;
1553 goto return_fail;
1554 case 0x44:
1555 if (*ascq == 0)
1556 sprintf(msg, "Internal target failure");
1557 else
1558 break;
1559 goto return_fail;
1560 case 0x51:
1561 if (*ascq == 0)
1562 sprintf(msg, "Erase failure");
1563 else if (*ascq == 1)
1564 sprintf(msg, "Erase failure. Incomplete erase operation");
1565 else
1566 break;
1567 goto return_fail;
1568 case 0x57:
1569 if (*ascq == 0)
1570 sprintf(msg, "Unable to recover Table-of-Content");
1571 else
1572 break;
1573 goto return_fail;
1574 case 0x63:
1575 if (*ascq == 0)
1576 sprintf(msg,
1577 "End of user area encountered on this track");
1578 else if (*ascq == 1)
1579 sprintf(msg, "Packet does not fit in available space");
1580 else
1581 break;
1582 goto return_fail;
1583 case 0x64:
1584 if (*ascq == 0)
1585 sprintf(msg, "Illegal mode for this track");
1586 else if (*ascq == 1)
1587 sprintf(msg, "Invalid packet size");
1588 else
1589 break;
1590 goto return_fail;
1591 case 0x6F:
1592 if (*ascq == 0)
1593 sprintf(msg, "Copy protection key exchange failure – Authentication failure");
1594 else if (*ascq == 1)
1595 sprintf(msg, "Copy protection key exchange failure – Key not present");
1596 else if (*ascq == 2)
1597 sprintf(msg, "Copy protection key exchange failure – Key not established");
1598 else if (*ascq == 3)
1599 sprintf(msg, "Read of scrambled sector without authentication");
1600 else if (*ascq == 4)
1601 sprintf(msg, "Media region code is mismatched to logical unit region");
1602 else if (*ascq == 5)
1603 sprintf(msg, "Logical unit region must be permanent / Region reset count error");
1604 else if (*ascq == 6)
1605 sprintf(msg, "Insufficient block count for binding nonce recording");
1606 else if (*ascq == 7)
1607 sprintf(msg, "Conflict in binding nonce recording");
1608 else if (*ascq == 8)
1609 sprintf(msg, "Insufficient permission");
1610 else
1611 break;
1612 goto return_fail;
1613 case 0x72:
1614 if (*ascq == 0)
1615 sprintf(msg, "Session fixation error");
1616 else if (*ascq == 1)
1617 sprintf(msg, "Session fixation error writing lead-in");
1618 else if (*ascq == 2)
1619 sprintf(msg,
1620 "Session fixation error writing lead-out");
1621 else if (*ascq == 3)
1622 sprintf(msg,
1623 "Session fixation error, incomplete track in session");
1624 else if (*ascq == 4)
1625 sprintf(msg,
1626 "Empty or partially written reserved track");
1627 else if (*ascq == 5)
1628 sprintf(msg, "No more track reservations allowed");
1629 else
1630 break;
1631 goto return_fail;
1632 case 0x73:
1633 if (*ascq == 0)
1634 sprintf(msg, "CD control error");
1635 else if (*ascq == 1)
1636 sprintf(msg, "Power calibration area almost full");
1637 else if (*ascq == 2)
1638 sprintf(msg, "Power calibration area is full");
1639 else if (*ascq == 3)
1640 sprintf(msg, "Power calibration area error");
1641 else if (*ascq == 4)
1642 sprintf(msg, "Program memory area update failure");
1643 else if (*ascq == 5)
1644 sprintf(msg, "Program memory area is full");
1645 else
1646 break;
1647 goto return_fail;
1648 }
1649 sprintf(msg_data,
1650 "See MMC specs: Sense Key %X \"%s\", ASC %2.2X ASCQ %2.2X",
1651 *key & 0xf, key_def[(*key) & 0xf], *asc, *ascq);
1652 goto return_fail;
1653
1654 return_fail:
1655 strcat(msg, ".");
1656 if (*key == 1)
1657 return GO_ON;
1658 return FAIL;
1659
1660 return_retry:;
1661 strcat(msg, ".");
1662 if (*key == 1)
1663 return GO_ON;
1664 return RETRY;
1665 }
1666
1667
1668 /* ts A61115 moved from sg-*.c */
1669 /* ts A61122 made it frontend to scsi_error_msg() */
1670 enum response scsi_error(struct burn_drive *d, unsigned char *sense,
1671 int senselen)
1672 {
1673 int key, asc, ascq, ret = 0;
1674 char *msg = NULL;
1675 enum response resp;
1676
1677 BURN_ALLOC_MEM(msg, char, 160);
1678 resp = scsi_error_msg(d, sense, senselen, msg, &key, &asc, &ascq);
1679 ex:;
1680 if (ret == -1)
1681 resp = FAIL;
1682 BURN_FREE_MEM(msg);
1683 return resp;
1684 }
1685
1686
1687 static char *scsi_command_name(unsigned int c, int flag)
1688 {
1689 switch (c) {
1690 case 0x00:
1691 return "TEST UNIT READY";
1692 case 0x03:
1693 return "REQUEST SENSE";
1694 case 0x04:
1695 return "FORMAT UNIT";
1696 case 0x1b:
1697 return "START/STOP UNIT";
1698 case 0x12:
1699 return "INQUIRY";
1700 case 0x1e:
1701 return "PREVENT/ALLOW MEDIA REMOVAL";
1702 case 0x23:
1703 return "READ FORMAT CAPACITIES";
1704 case 0x25:
1705 return "READ CAPACITY";
1706 case 0x28:
1707 return "READ(10)";
1708 case 0x2a:
1709 return "WRITE(10)";
1710 case 0x35:
1711 return "SYNCHRONIZE CACHE";
1712 case 0x43:
1713 return "READ TOC/PMA/ATIP";
1714 case 0x46:
1715 return "GET CONFIGURATION";
1716 case 0x4a:
1717 return "GET EVENT STATUS NOTIFICATION";
1718 case 0x51:
1719 return "READ DISC INFORMATION";
1720 case 0x52:
1721 return "READ TRACK INFORMATION";
1722 case 0x53:
1723 return "RESERVE TRACK";
1724 case 0x54:
1725 return "SEND OPC INFORMATION";
1726 case 0x55:
1727 return "MODE SELECT";
1728 case 0x5a:
1729 return "MODE SENSE";
1730 case 0x5b:
1731 return "CLOSE TRACK/SESSION";
1732 case 0x5c:
1733 return "READ BUFFER CAPACITY";
1734 case 0x5d:
1735 return "SEND CUE SHEET";
1736 case 0xa1:
1737 return "BLANK";
1738 case 0xaa:
1739 return "WRITE(12)";
1740 case 0xab:
1741 return "READ MEDIA SERIAL NUMBER";
1742 case 0xac:
1743 return "GET PERFORMANCE";
1744 case 0xad:
1745 return "READ DISC STRUCTURE";
1746 case 0xb6:
1747 return "SET STREAMING";
1748 case 0xb9:
1749 return "READ CD MSF";
1750 case 0xbb:
1751 return "SET CD SPEED";
1752 case 0xbe:
1753 return "READ CD";
1754
1755 #ifdef Libburn_develop_quality_scaN
1756
1757 case 0xf3:
1758 return "NEC/OPTIARC REPORT ERROR RATE";
1759
1760 #endif /* Libburn_develop_quality_scaN */
1761
1762 }
1763 return "(NOT IN LIBBURN COMMAND LIST)";
1764 }
1765
1766
1767 /* ts B90206: Avoid publishing more inner API functions which begin by scsi_ */
1768 char *spc_command_name(unsigned int c, int flag)
1769 {
1770 return(scsi_command_name(c, flag));
1771 }
1772
1773
1774 /* ts B90616 */
1775 void spc_register_retry(struct command *c)
1776 {
1777 c->retry_count++;
1778 spc_decode_sense(c->sense, c->sense_len, &c->last_retry_key,
1779 &c->last_retry_asc, &c->last_retry_ascq);
1780 }
1781
1782
1783 /* ts B90511 */
1784 /* @param flag bit0= do not prepend command name
1785 bit1= do not append dxfer_len
1786 */
1787 int spc_human_readable_cmd(struct command *c, char *msg, int msg_max, int flag)
1788 {
1789 int j, l, lname;
1790
1791 if ((flag & 1) && c->retry_count <= 0) {
1792 msg[0] = 0;
1793 } else {
1794 if (msg_max < 60)
1795 return -1;
1796 strcpy(msg, spc_command_name( (unsigned int) c->opcode[0], 0));
1797 if (c->retry_count > 0) {
1798 sprintf(msg + strlen(msg), " #%d", c->retry_count + 1);
1799 if (c->last_retry_key > 0)
1800 sprintf(msg + strlen(msg), ",[%X %2.2X %2.2X]",
1801 c->last_retry_key, c->last_retry_asc,
1802 c->last_retry_ascq);
1803 }
1804 strcat(msg, " : ");
1805 }
1806 lname = l = strlen(msg);
1807 for (j = 0; j < 16 && j < c->oplen; j++) {
1808 if (l > msg_max - 3) {
1809 if (msg_max - 4 >= lname) {
1810 l = msg_max - 4;
1811 sprintf(msg + strlen(msg), "... ");
1812 }
1813 return 0;
1814 }
1815 sprintf(msg + l, "%2.2x ", c->opcode[j]);
1816 l += 3;
1817 }
1818 if (c->dir != NO_TRANSFER && c->page != NULL && !(flag & 2)) {
1819 if (l > msg_max - 24)
1820 return 0;
1821 sprintf(msg + l, " : dxfer_len= %d", c->dxfer_len);
1822 l = strlen(msg);
1823 }
1824 return 1;
1825 }
1826
1827
1828 /* ts A61030 - A61115 */
1829 /* @param flag bit0= do report conditions which are considered not an error
1830 bit1= report with severity FAILURE rather than DEBUG
1831 */
1832 int scsi_notify_error(struct burn_drive *d, struct command *c,
1833 unsigned char *sense, int senselen, int flag)
1834 {
1835 int key= -1, asc= -1, ascq= -1, ret;
1836 char *msg = NULL, *scsi_msg = NULL;
1837
1838 if (d->silent_on_scsi_error == 1 || d->silent_on_scsi_error == 2)
1839 {ret = 1; goto ex;}
1840
1841 BURN_ALLOC_MEM(msg, char, 320);
1842 BURN_ALLOC_MEM(scsi_msg, char, 160);
1843 scsi_error_msg(d, sense, senselen, scsi_msg, &key, &asc, &ascq);
1844
1845 if (!(flag & 1)) {
1846 /* SPC : TEST UNIT READY command */
1847 if (c->opcode[0] == 0)
1848 {ret = 1; goto ex;}
1849 /* MMC : READ DISC INFORMATION command */
1850 if (c->opcode[0] == 0x51)
1851 if (key == 0x2 && asc == 0x3A &&
1852 ascq>=0 && ascq <= 0x02) /* MEDIUM NOT PRESENT */
1853 {ret = 1; goto ex;}
1854 if (key == 0 && asc == 0 && ascq == 0)
1855 {ret = 1; goto ex;}
1856 }
1857
1858 sprintf(msg, "SCSI error condition on command %2.2Xh %s: ",
1859 c->opcode[0],
1860 scsi_command_name((unsigned int) c->opcode[0], 0));
1861 strcat(msg, scsi_msg);
1862 ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f,
1863 (flag & 2) && d->silent_on_scsi_error != 3 ?
1864 LIBDAX_MSGS_SEV_FAILURE : LIBDAX_MSGS_SEV_DEBUG,
1865 LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
1866 strcpy(msg, "CDB= ");
1867 if (spc_human_readable_cmd(c, msg + strlen(msg), 320 - strlen(msg), 1)
1868 > 0) {
1869 libdax_msgs_submit(libdax_messenger, d->global_index,
1870 0x0002010f,
1871 (flag & 2) && d->silent_on_scsi_error != 3 ?
1872 LIBDAX_MSGS_SEV_FAILURE : LIBDAX_MSGS_SEV_DEBUG,
1873 LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
1874 }
1875 ex:;
1876 BURN_FREE_MEM(msg);
1877 BURN_FREE_MEM(scsi_msg);
1878 return ret;
1879 }
1880
1881
1882 /* ts B11110 */
1883 /* @param flag bit0= do not show eventual data payload sent to the drive
1884 (never with WRITE commands)
1885 */
1886 int scsi_show_command(unsigned char *opcode, int oplen, int dir,
1887 unsigned char *data, int bytes,
1888 void *fp_in, int flag)
1889 {
1890 int i;
1891 FILE *fp = fp_in;
1892
1893 fprintf(fp, "\n%s\n",
1894 scsi_command_name((unsigned int) opcode[0], 0));
1895 for(i = 0; i < 16 && i < oplen; i++)
1896 fprintf(fp, "%2.2x ", opcode[i]);
1897 if (i > 0)
1898 fprintf(fp, "\n");
1899 if (flag & 1)
1900 return 1;
1901 if (opcode[0] == 0x2A) { /* WRITE 10 */
1902 if ((flag & 2) && oplen > 8)
1903 fprintf(fp, "%d -> %d\n",
1904 (opcode[7] << 8) | opcode[8],
1905 mmc_four_char_to_int(opcode + 2));
1906 } else if (opcode[0] == 0xAA) { /* WRITE 12 */
1907 if ((flag & 2) && oplen > 9)
1908 fprintf(fp, "%d -> %d\n",
1909 mmc_four_char_to_int(opcode + 6),
1910 mmc_four_char_to_int(opcode + 2));
1911 } else if (dir == TO_DRIVE && !(flag & 1)) {
1912 fprintf(fp, "To drive: %db\n", bytes);
1913 for (i = 0; i < bytes; i++)
1914 fprintf(fp, "%2.2x%c", data[i],
1915 ((i % 20) == 19 ? '\n' : ' '));
1916 if (i % 20)
1917 fprintf(fp, "\n");
1918 }
1919 return 1;
1920 }
1921
1922
1923
1924 /* ts A91106 */
1925 /* @param flag bit0= do not show eventual data payload sent to the drive
1926 (never with WRITE commands)
1927 */
1928 int scsi_show_cmd_text(struct command *c, void *fp_in, int flag)
1929 {
1930 return scsi_show_command(c->opcode, c->oplen, c->dir, c->page->data,
1931 c->page->bytes, fp_in, flag);
1932 }
1933
1934
1935 /* ts A91106 */ /* ts B11110 */
1936 int scsi_show_command_reply(unsigned char *opcode, int data_dir,
1937 unsigned char *data, int dxfer_len,
1938 void *fp_in, int flag)
1939 {
1940 int i;
1941 FILE *fp = fp_in;
1942
1943 if (data_dir != FROM_DRIVE)
1944 return 2;
1945 if (opcode[0] == 0x28 || opcode[0] == 0x3C ||
1946 opcode[0] == 0xA8 || opcode[0] == 0xB9 || opcode[0] == 0xBE) {
1947 /* READ commands */
1948 /* >>> report amount of data */;
1949
1950 return 2;
1951 }
1952 fprintf(fp, "From drive: %db\n", dxfer_len);
1953 for (i = 0; i < dxfer_len; i++)
1954 fprintf(fp, "%2.2x%c", data[i],
1955 ((i % 20) == 19 ? '\n' : ' '));
1956 if (i % 20)
1957 fprintf(fp, "\n");
1958 return 1;
1959 }
1960
1961
1962 /* ts B11110 */
1963 /** Logs command (before execution) */
1964 int scsi_log_command(unsigned char *opcode, int oplen, int data_dir,
1965 unsigned char *data, int bytes,
1966 void *fp_in, int flag)
1967 {
1968 FILE *fp = fp_in;
1969
1970 if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) {
1971 scsi_show_command(opcode, oplen, data_dir, data, bytes, fp, 0);
1972 if (burn_sg_log_scsi & 4)
1973 fflush(fp);
1974 }
1975 if (fp == stderr || !(burn_sg_log_scsi & 2))
1976 return 1;
1977 scsi_log_command(opcode, oplen, data_dir, data, bytes, stderr, 0);
1978 return 1;
1979 }
1980
1981
1982 /* ts B40731 */
1983 /* Arbitrary SCSI log message */
1984 int scsi_log_text(char *text, void *fp_in, int flag)
1985 {
1986 FILE *fp = fp_in;
1987
1988 if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) {
1989 fprintf(fp, "%s\n", text);
1990 if (burn_sg_log_scsi & 4)
1991 fflush(fp);
1992 }
1993 if (fp == stderr || !(burn_sg_log_scsi & 2))
1994 return 1;
1995 fprintf(stderr, "%s\n", text);
1996 return 1;
1997 }
1998
1999
2000 /* ts A91218 (former sg_log_cmd ts A70518) */
2001 /** Logs command (before execution) */
2002 int scsi_log_cmd(struct command *c, void *fp_in, int flag)
2003 {
2004 int ret, bytes = 0;
2005 unsigned char *data = NULL;
2006
2007 if (c->page != NULL) {
2008 data = c->page->data;
2009 bytes = c->page->bytes;
2010 }
2011 ret = scsi_log_command(c->opcode, c->oplen, c->dir, data, bytes,
2012 fp_in, flag);
2013 return ret;
2014 }
2015
2016
2017 /* ts B11110 */
2018 /** Logs outcome of a sg command.
2019 @param flag bit0 causes an error message
2020 bit1 do not print duration
2021 */
2022 int scsi_log_reply(unsigned char *opcode, int data_dir, unsigned char *data,
2023 int dxfer_len, void *fp_in, unsigned char sense[18],
2024 int sense_len, double duration, int flag)
2025 {
2026 FILE *fp = fp_in;
2027 int key, asc, ascq, i, l;
2028
2029 if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) {
2030 if (flag & 1) {
2031 l = 18;
2032 if ((sense[0] & 0x7f) == 0x72 ||
2033 (sense[0] & 0x7f) == 0x73)
2034 l = sense[7] + 7 + 1; /* SPC-3 4.5.2. */
2035 if (l > sense_len)
2036 l = sense_len;
2037 fprintf(fp, "+++ sense data =");
2038 for (i = 0 ; i < l; i++)
2039 fprintf(fp, " %2.2X", sense[i]);
2040 fprintf(fp, "\n");
2041 spc_decode_sense(sense, 0, &key, &asc, &ascq);
2042 fprintf(fp, "+++ key=%X asc=%2.2Xh ascq=%2.2Xh\n",
2043 (unsigned int) key, (unsigned int) asc,
2044 (unsigned int) ascq);
2045 } else {
2046 scsi_show_command_reply(opcode, data_dir, data,
2047 dxfer_len, fp, 0);
2048 }
2049 if (!(flag & 2))
2050 fprintf(fp, " %8.f us [ %.f ]\n",
2051 duration * 1.0e6,
2052 (burn_get_time(0) - lib_start_time) * 1.0e6);
2053 if (burn_sg_log_scsi & 4)
2054 fflush(fp);
2055 }
2056 if (fp == stderr || !(burn_sg_log_scsi & 2))
2057 return 1;
2058 scsi_log_reply(opcode, data_dir, data, dxfer_len,
2059 stderr, sense, sense_len, duration, flag);
2060
2061 return 1;
2062 }
2063
2064
2065 /* ts A91221 (former sg_log_err ts A91108) */
2066 /** Legacy frontend to scsi_log_reply().
2067 @param flag bit0 causes an error message
2068 bit1 do not print duration
2069 */
2070 int scsi_log_err(struct burn_drive *d, struct command *c,
2071 void *fp_in, unsigned char sense[18],
2072 int sense_len, int flag)
2073 {
2074 int ret;
2075 unsigned char *data = NULL;
2076
2077 if (c->page != NULL)
2078 data = c->page->data;
2079
2080 ret= scsi_log_reply(c->opcode, c->dir, data, c->dxfer_len ,
2081 fp_in, sense, sense_len,
2082 c->end_time - c->start_time, flag);
2083 return ret;
2084 }
2085
2086 /* ts B31112 */
2087 int scsi_log_message(struct burn_drive *d, void *fp_in, char * msg, int flag)
2088 {
2089 int ret;
2090 FILE *fp = fp_in;
2091
2092 if (fp != NULL && (fp == stderr || (burn_sg_log_scsi & 1))) {
2093 fprintf(fp, "%s\n", msg);
2094 if (burn_sg_log_scsi & 4)
2095 fflush(fp);
2096 }
2097 if (fp == stderr || !(burn_sg_log_scsi & 2))
2098 return 1;
2099 ret = scsi_log_message(d, stderr, msg, flag);
2100 return ret;
2101 }
2102
2103 /* ts B00808 */
2104 /*
2105 @param flag bit0 = do not retry
2106 bit1 = do not print duration
2107 @return 0 = not yet done , 1 = done , -1 = error
2108 */
2109 int scsi_eval_cmd_outcome(struct burn_drive *d, struct command *c, void *fp,
2110 unsigned char *sense, int sense_len,
2111 time_t start_time, int timeout_ms,
2112 int loop_count, int flag)
2113 {
2114 enum response outcome;
2115 int done = -1, usleep_time;
2116 char *msg = NULL;
2117
2118 if (burn_sg_log_scsi & 3)
2119 scsi_log_err(d, c, fp, sense, sense_len,
2120 (sense_len > 0) | (flag & 2));
2121 if (sense == c->sense)
2122 c->sense_len = sense_len;
2123 if (sense_len <= 0)
2124 {done = 1; goto ex;}
2125
2126 outcome = scsi_error(d, sense, sense_len);
2127 if (outcome == RETRY && c->retry && !(flag & 1)) {
2128 /* Calming down retries and breaking up endless cycle
2129 */
2130 if (c->opcode[0] == 0x2A || c->opcode[0] == 0xAA) {
2131 /* WRITE(10) , WRITE(12) */
2132 usleep_time = Libburn_scsi_write_retry_usleeP +
2133 loop_count * Libburn_scsi_write_retry_incR;
2134 if (usleep_time > Libburn_scsi_write_retry_umaX)
2135 usleep_time = Libburn_scsi_write_retry_umaX;
2136 } else {
2137 usleep_time = Libburn_scsi_retry_usleeP +
2138 loop_count * Libburn_scsi_retry_incR;
2139 if (usleep_time > Libburn_scsi_retry_umaX)
2140 usleep_time = Libburn_scsi_retry_umaX;
2141 }
2142 if (time(NULL) + usleep_time / 1000000 - start_time >
2143 timeout_ms / 1000 + 1) {
2144 done = -1; /* In case of alloc failure */
2145 BURN_ALLOC_MEM_VOID(msg, char, 320);
2146 done = 1;
2147 sprintf(msg,
2148 "Timeout exceed (%d ms). Retry canceled.\n",
2149 timeout_ms);
2150 libdax_msgs_submit(libdax_messenger, d->global_index,
2151 0x0002018a,
2152 LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH,
2153 msg, 0, 0);
2154 strcpy(msg, "Command: ");
2155 if (spc_human_readable_cmd(c, msg + strlen(msg),
2156 320 - strlen(msg), 0) > 0)
2157 libdax_msgs_submit(libdax_messenger,
2158 d->global_index, 0x0002018a,
2159 LIBDAX_MSGS_SEV_SORRY,
2160 LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
2161 goto err_ex;
2162 }
2163 if (d->cancel)
2164 {done = 1; goto ex;}
2165 if (usleep_time > 0)
2166 usleep(usleep_time);
2167 if (d->cancel)
2168 {done = 1; goto ex;}
2169 if (burn_sg_log_scsi & 3)
2170 scsi_log_cmd(c, fp, 0);
2171 {done = 0; goto ex;}
2172 } else if (outcome == RETRY) {
2173 done = 1;
2174 } else if (outcome == GO_ON) {
2175 {done = 1; goto ex;}
2176 } else if (outcome == FAIL) {
2177 done = 1;
2178 }
2179 err_ex:;
2180 c->error = 1;
2181 scsi_notify_error(d, c, sense, sense_len, 0);
2182 ex:;
2183 BURN_FREE_MEM(msg);
2184 return done;
2185 }
2186
2187
2188 int spc_confirm_cd_drive(struct burn_drive *d, int flag)
2189 {
2190 char *msg = NULL;
2191 int ret;
2192
2193 BURN_ALLOC_MEM(msg, char, strlen(d->devname) + 1024);
2194
2195 spc_inquiry(d);
2196 if (d->idata->valid < 0) {
2197 sprintf(msg, "INQUIRY failed with drive '%s'", d->devname);
2198 libdax_msgs_submit(libdax_messenger, -1, 0x0002000a,
2199 LIBDAX_MSGS_SEV_FAILURE,
2200 LIBDAX_MSGS_PRIO_HIGH, msg, 0,0);
2201 ret = 0; goto ex;
2202 }
2203 if (d->idata->peripheral != 0x5) {
2204 sprintf(msg, "Does not identify itself as CD-ROM drive '%s'",
2205 d->devname);
2206 libdax_msgs_submit(libdax_messenger, -1, 0x0002000a,
2207 LIBDAX_MSGS_SEV_FAILURE,
2208 LIBDAX_MSGS_PRIO_HIGH, msg, 0,0);
2209 ret = 0; goto ex;
2210 }
2211 ret = 1;
2212 ex:;
2213 BURN_FREE_MEM(msg);
2214 return ret;
2215 }
2216