New API call burn_drive_set_immed()

This commit is contained in:
Thomas Schmitt 2016-07-30 14:03:10 +00:00
parent 2e8dec42e5
commit 740e726ffe
8 changed files with 114 additions and 15 deletions

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2016.07.23.104100"
#define Cdrskin_timestamP "2016.07.30.140328"

View File

@ -58,6 +58,9 @@
/* A90815 : for mmc_obtain_profile_name() */
#include "mmc.h"
/* B60730 : for Libburn_do_no_immed_defaulT */
#include "os.h"
#include "libdax_msgs.h"
extern struct libdax_msgs *libdax_messenger;
@ -88,6 +91,13 @@ int burn_setup_drive(struct burn_drive *d, char *fname)
d->do_stream_recording = 0;
d->stream_recording_start= 0;
d->role_5_nwa = 0;
#ifdef Libburn_do_no_immed_defaulT
d->do_no_immed = Libburn_do_no_immed_defaulT;
#else
d->do_no_immed = 0;
#endif
d->features = NULL;
d->drive_serial_number = NULL;
d->drive_serial_number_len = -1;
@ -888,6 +898,12 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
#else /* Libburn_old_progress_looP */
while (1) {
/* >>> ??? ts B60730 : abort if user interrupts ?
if (d->cancel)
break;
*/
ret = d->get_erase_progress(d);
if (ret == -2 || ret > 0)
break;
@ -896,6 +912,12 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
sleep(1);
}
while (1) {
/* >>> ??? ts B60730 : abort if user interrupts ?
if (d->cancel)
break;
*/
ret = d->get_erase_progress(d);
if(ret == -2)
break;
@ -912,7 +934,7 @@ void burn_disc_erase_sync(struct burn_drive *d, int fast)
/* ts A61125 : update media state records */
burn_drive_mark_unready(d, 0);
if (d->drive_role == 1)
if (d->drive_role == 1 && !d->cancel)
burn_drive_inquire_media(d);
d->busy = BURN_DRIVE_IDLE;
if (was_error)
@ -3577,3 +3599,17 @@ ex:
return ret;
}
int burn_drive_set_immed(struct burn_drive *drive, int enable)
{
drive->do_no_immed = !enable;
return 1;
}
int burn_drive_get_immed(struct burn_drive *drive)
{
return !drive->do_no_immed;
}

View File

@ -1858,6 +1858,33 @@ void burn_disc_write(struct burn_write_opts *o, struct burn_disc *disc);
int burn_drive_set_stream_recording(struct burn_drive *drive, int recmode,
int start, int flag);
/* ts B60730 */
/** Enable or disable use of the Immed bit with long running SCSI commands.
If the Immed bit is used, then those SCSI commands end early and leave
the drive in not-ready state. libburn then tries periodically whether
the drive became ready again. Only then it assumes the command to be
completely done.
The default setting may depend on the operating system on which libburn
was compiled.
@param drive The drive which will be affected.
@param enable 1= use Immed bit.
0= use no Immed bit. Affected commands can last very long.
@return 1=success , <=0 failure
@since 1.4.6
*/
int burn_drive_set_immed(struct burn_drive *drive, int enable);
/* ts B60730 */
/** Inquire the current setting of usage of the Immed bit. Either the still set
system dependent default or the value set by call burn_drive_set_immed().
@return The current value.
@since 1.4.6
*/
int burn_drive_get_immed(struct burn_drive *drive);
/** Cancel an operation on a drive.
This will only work when the drive's busy state is BURN_DRIVE_READING or
BURN_DRIVE_WRITING.

View File

@ -613,7 +613,8 @@ void mmc_close(struct burn_drive *d, int session, int track)
scsi_init_command(c, MMC_CLOSE, sizeof(MMC_CLOSE));
c->retry = 1;
c->opcode[1] |= 1; /* ts A70918 : Immed */
if (!d->do_no_immed)
c->opcode[1] |= 1; /* ts A70918 : Immed */
/* (ts A61030 : shifted !!session rather than or-ing plain session ) */
c->opcode[2] = ((session & 3) << 1) | !!track;
@ -621,7 +622,10 @@ void mmc_close(struct burn_drive *d, int session, int track)
c->opcode[5] = track & 0xFF;
c->page = NULL;
c->dir = NO_TRANSFER;
c->timeout = Libburn_mmc_close_timeouT;
if (d->do_no_immed)
c->timeout = Libburn_mmc_close_noim_timeouT;
else
c->timeout = Libburn_mmc_close_timeouT;
d->issue_command(d, c);
/* ts A70918 : Immed : wait for drive to complete command */
@ -2717,12 +2721,16 @@ void mmc_erase(struct burn_drive *d, int fast)
return;
scsi_init_command(c, MMC_BLANK, sizeof(MMC_BLANK));
c->opcode[1] = 16; /* IMMED set to 1 */
if (!d->do_no_immed)
c->opcode[1] = 16; /* IMMED set to 1 */
c->opcode[1] |= !!fast;
c->retry = 1;
c->page = NULL;
c->dir = NO_TRANSFER;
c->timeout = Libburn_mmc_blank_timeouT;
if (d->do_no_immed)
c->timeout = Libburn_mmc_blank_noim_timeouT;
else
c->timeout = Libburn_mmc_blank_timeouT;
d->issue_command(d, c);
if (c->error) {
d->cancel = 1;
@ -3522,10 +3530,14 @@ void mmc_sync_cache(struct burn_drive *d)
scsi_init_command(c, MMC_SYNC_CACHE, sizeof(MMC_SYNC_CACHE));
c->retry = 1;
c->opcode[1] |= 2; /* ts A70918 : Immed */
if (!d->do_no_immed)
c->opcode[1] |= 2; /* ts A70918 : Immed */
c->page = NULL;
c->dir = NO_TRANSFER;
c->timeout = Libburn_mmc_sync_timeouT;
if (d->do_no_immed)
c->timeout = Libburn_mmc_sync_noim_timeouT;
else
c->timeout = Libburn_mmc_sync_timeouT;
libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO,
@ -3674,11 +3686,15 @@ int mmc_format_unit(struct burn_drive *d, off_t size, int flag)
c->page->bytes = 12;
c->page->sectors = 0;
c->dir = TO_DRIVE;
c->timeout = Libburn_mmc_blank_timeouT;
if (d->do_no_immed)
c->timeout = Libburn_mmc_blank_noim_timeouT;
else
c->timeout = Libburn_mmc_blank_timeouT;
memset(c->page->data, 0, c->page->bytes);
descr[0] = 0;
c->page->data[1] = 0x02; /* Immed */
if (!d->do_no_immed)
c->page->data[1] = 0x02; /* Immed */
c->page->data[3] = 8; /* Format descriptor length */
num_of_blocks = size / 2048;
mmc_int_to_four_char(c->page->data + 4, num_of_blocks);

View File

@ -44,6 +44,14 @@
/* The number of above list items */
#define BURN_OS_NON_SIGNAL_COUNT 11
/* ts B60730 */
/* Either OpenBSD or SASANO Takayoshi's LG BH14NS48 throw 2,0,0
on Immed bit with BLANK and SYNCHRONIZE CACHE.
Until it is clear that the drive is to blame, the OpenBSD default is
not to use Immed.
*/
#define Libburn_do_no_immed_defaulT 1
#else /* __OpenBSD__ */
/** To list all signals which shall surely not be caught */

View File

@ -114,12 +114,15 @@ int sbc_start_unit_flag(struct burn_drive *d, int flag)
scsi_init_command(c, SBC_START_UNIT, sizeof(SBC_START_UNIT));
c->retry = 1;
c->opcode[1] |= (flag & 1); /* ts A70918 : Immed */
if (d->do_no_immed && (flag & 1))
c->timeout = 1800 * 1000;
else
c->opcode[1] |= (flag & 1); /* ts A70918 : Immed */
c->dir = NO_TRANSFER;
d->issue_command(d, c);
if (c->error)
return 0;
if (!(flag & 1))
if (d->do_no_immed || !(flag & 1))
return 1;
/* ts A70918 : asynchronous */
ret = spc_wait_unit_attention(d, 1800, "START UNIT", 0);

View File

@ -156,17 +156,23 @@ int spc_confirm_cd_drive(struct burn_drive *d, int flag);
/* RESERVE TRACK */
#define Libburn_mmc_reserve_timeouT 200000
/* CLOSE TRACK/SESSION (with Immed bit) */
/* CLOSE TRACK/SESSION with Immed bit */
#define Libburn_mmc_close_timeouT 200000
/* CLOSE TRACK/SESSION without Immed bit */
#define Libburn_mmc_close_noim_timeouT 3600000
/* BLANK , FORMAT UNIT (with Immed bit) */
/* BLANK , FORMAT UNIT with Immed bit */
#define Libburn_mmc_blank_timeouT 200000
/* BLANK , FORMAT UNIT without Immed bit */
#define Libburn_mmc_blank_noim_timeouT 18000000
/* SEND OPC INFORMATION */
#define Libburn_mmc_opc_timeouT 200000
/* MMC_SYNC_CACHE */
/* MMC_SYNC_CACHE with Immed bit */
#define Libburn_mmc_sync_timeouT 200000
/* MMC_SYNC_CACHE without Immed bit */
#define Libburn_mmc_sync_noim_timeouT 3600000
/* START STOP UNIT with Start bit and Load bit set */
#define Libburn_mmc_load_timeouT 300000

View File

@ -378,6 +378,9 @@ struct burn_drive
/* ts B10314 : Next Writeable Address for drive_role == 5 */
int role_5_nwa;
/* ts B60730 */
int do_no_immed;
int toc_temp;
struct burn_disc *disc; /* disc structure */
int block_types[4];