"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