"Fossies" - the Fresh Open Source Software Archive

Member "xorriso-1.5.4/libburn/sbc.c" (30 Jan 2021, 4745 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 "sbc.c" see the Fossies "Dox" file reference documentation.

    1 /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
    2 
    3 /* scsi block commands */
    4 
    5 /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
    6    Copyright (c) 2006 - 2010 Thomas Schmitt <scdbackup@gmx.net>
    7    Provided under GPL version 2 or later.
    8 */
    9 
   10 #ifdef HAVE_CONFIG_H
   11 #include "../config.h"
   12 #endif
   13 
   14 #include <string.h>
   15 #include <unistd.h>
   16 
   17 #include "transport.h"
   18 #include "sbc.h"
   19 #include "spc.h"
   20 #include "options.h"
   21 
   22 
   23 /* ts A70910
   24    debug: for tracing calls which might use open drive fds
   25           or for catching SCSI usage of emulated drives. */
   26 int mmc_function_spy(struct burn_drive *d, char * text);
   27 
   28 
   29 /* START STOP UNIT as of SBC-1 and SBC-2
   30    0:  Opcode 0x1B
   31    1:  bit0= Immed
   32        bit1-7= reserved 
   33    2:  reserved
   34    3:  reserved
   35    4:  bit0= Start (else Stop unit)
   36        bit1= Load/Eject (according to Start resp. Stop)
   37        bit2-3= reserved
   38        bit4-7= Power Condition
   39                0= Start Valid: process Start and Load/Eject bits
   40                1= assume Active state
   41                2= assume Idle state
   42                3= assume Stanby state
   43               (5= SBC-1 only: assume Sleep state)
   44                7= transfer control of power conditions to logical unit
   45               10= force idle condition timer to 0
   46               11= force standby condition timer to 0
   47               All others are reserved.
   48    5:  Control (set to 0)
   49 */
   50 static unsigned char SBC_LOAD[] = { 0x1b, 0, 0, 0, 3, 0 };
   51 static unsigned char SBC_UNLOAD[] = { 0x1b, 0, 0, 0, 2, 0 };
   52 static unsigned char SBC_START_UNIT[] = { 0x1b, 0, 0, 0, 1, 0 };
   53 static unsigned char SBC_STOP_UNIT[] = { 0x1b, 0, 0, 0, 0, 0 };
   54 
   55 void sbc_load(struct burn_drive *d)
   56 {
   57     struct command *c;
   58 
   59     c = &(d->casual_command);
   60     if (mmc_function_spy(d, "load") <= 0)
   61         return;
   62 
   63     scsi_init_command(c, SBC_LOAD, sizeof(SBC_LOAD));
   64     c->retry = 1;
   65 
   66     /* ts A70921 : Had to revoke Immed because of LG GSA-4082B */
   67     /* c->opcode[1] |= 1; / * ts A70918 : Immed */
   68 
   69     c->dir = NO_TRANSFER;
   70     c->timeout = Libburn_mmc_load_timeouT;
   71     d->issue_command(d, c);
   72     if (c->error)
   73         return;
   74     /* ts A70923 : Needed regardless of Immed bit. Was once 1 minute, now
   75            5 minutes for loading. If this does not suffice then other commands
   76        shall fail righteously. */
   77     spc_wait_unit_attention(d, 300, "waiting after START UNIT (+ LOAD)",0);
   78 }
   79 
   80 void sbc_eject(struct burn_drive *d)
   81 {
   82     struct command *c;
   83 
   84     c = &(d->casual_command);
   85     if (mmc_function_spy(d, "eject") <= 0)
   86         return;
   87 
   88     scsi_init_command(c, SBC_UNLOAD, sizeof(SBC_UNLOAD));
   89     /* c->opcode[1] |= 1; / * ts A70918 : Immed , ts B00109 : revoked */
   90     c->page = NULL;
   91     c->dir = NO_TRANSFER;
   92     d->issue_command(d, c);
   93     /* ts A70918 : Wait long. A late eject could surprise or hurt user.
   94        ts B00109 : Asynchronous eject revoked, as one cannot reliably
   95                    distinguish out from unready.
   96     if (c->error)
   97         return;
   98     spc_wait_unit_attention(d, 1800, "STOP UNIT (+ EJECT)", 0);
   99     */
  100 }
  101 
  102 
  103 /* ts A91112 : Now with flag */
  104 /* @param flag bit0= asynchronous waiting
  105 */
  106 int sbc_start_unit_flag(struct burn_drive *d, int flag)
  107 {
  108     struct command *c;
  109     int ret;
  110 
  111     c = &(d->casual_command);
  112     if (mmc_function_spy(d, "start_unit") <= 0)
  113         return 0;
  114 
  115     scsi_init_command(c, SBC_START_UNIT, sizeof(SBC_START_UNIT));
  116     c->retry = 1;
  117     if (d->do_no_immed && (flag & 1))
  118         c->timeout = 1800 * 1000;
  119     else
  120         c->opcode[1] |= (flag & 1); /* ts A70918 : Immed */
  121     c->dir = NO_TRANSFER;
  122     d->issue_command(d, c);
  123     if (c->error)
  124         return 0;
  125     if (d->do_no_immed || !(flag & 1))
  126         return 1;
  127     /* ts A70918 : asynchronous */
  128     ret = spc_wait_unit_attention(d, 1800, "START UNIT", 0);
  129     return ret;
  130 }
  131 
  132 
  133 int sbc_start_unit(struct burn_drive *d)
  134 {
  135     int ret;
  136 
  137     d->is_stopped = 0; /* no endless starting attempts */
  138 
  139     /* Asynchronous, not to block controller by waiting */
  140     ret = sbc_start_unit_flag(d, 1);
  141     if (ret <= 0)
  142         return ret;
  143     /* Synchronous to catch Pioneer DVR-216D which is ready too early.
  144        A pending START UNIT can prevent ejecting of the tray.
  145     */
  146     ret = sbc_start_unit_flag(d, 0);
  147     return ret;
  148 }
  149 
  150 
  151 /* ts A90824 : Trying to reduce drive noise */
  152 int sbc_stop_unit(struct burn_drive *d)
  153 {
  154     struct command *c;
  155     int ret;
  156 
  157     c = &(d->casual_command);
  158     if (mmc_function_spy(d, "stop_unit") <= 0)
  159         return 0;
  160 
  161     scsi_init_command(c, SBC_STOP_UNIT, sizeof(SBC_STOP_UNIT));
  162     c->retry = 0;
  163     c->opcode[1] |= 1; /* Immed */
  164     c->dir = NO_TRANSFER;
  165     d->issue_command(d, c);
  166     if (c->error)
  167         return 0;
  168     ret = spc_wait_unit_attention(d, 1800, "STOP UNIT", 0);
  169     d->is_stopped = 1;
  170     return ret;
  171 }
  172 
  173 
  174 
  175 /* ts A61021 : the sbc specific part of sg.c:enumerate_common()
  176 */
  177 int sbc_setup_drive(struct burn_drive *d)
  178 {
  179     d->eject = sbc_eject;
  180     d->load = sbc_load;
  181     d->start_unit = sbc_start_unit;
  182     d->stop_unit = sbc_stop_unit;
  183     d->is_stopped = 0;
  184     return 1;
  185 }
  186