From 740e726ffe909dc5564b3901d6634bce5d0d5cfd Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Sat, 30 Jul 2016 14:03:10 +0000 Subject: [PATCH] New API call burn_drive_set_immed() --- cdrskin/cdrskin_timestamp.h | 2 +- libburn/drive.c | 38 ++++++++++++++++++++++++++++++++++++- libburn/libburn.h | 27 ++++++++++++++++++++++++++ libburn/mmc.c | 32 +++++++++++++++++++++++-------- libburn/os-netbsd.h | 8 ++++++++ libburn/sbc.c | 7 +++++-- libburn/spc.h | 12 +++++++++--- libburn/transport.h | 3 +++ 8 files changed, 114 insertions(+), 15 deletions(-) diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index 020dd4a..cb214db 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2016.07.23.104100" +#define Cdrskin_timestamP "2016.07.30.140328" diff --git a/libburn/drive.c b/libburn/drive.c index 521e4a6..3e17d55 100644 --- a/libburn/drive.c +++ b/libburn/drive.c @@ -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; +} + + diff --git a/libburn/libburn.h b/libburn/libburn.h index c2f8237..31c7cdd 100644 --- a/libburn/libburn.h +++ b/libburn/libburn.h @@ -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. diff --git a/libburn/mmc.c b/libburn/mmc.c index 904b45d..953f863 100644 --- a/libburn/mmc.c +++ b/libburn/mmc.c @@ -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); diff --git a/libburn/os-netbsd.h b/libburn/os-netbsd.h index 7b10e6a..9303c7a 100644 --- a/libburn/os-netbsd.h +++ b/libburn/os-netbsd.h @@ -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 */ diff --git a/libburn/sbc.c b/libburn/sbc.c index d29f167..5ddb01f 100644 --- a/libburn/sbc.c +++ b/libburn/sbc.c @@ -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); diff --git a/libburn/spc.h b/libburn/spc.h index 7b7512e..799ffae 100644 --- a/libburn/spc.h +++ b/libburn/spc.h @@ -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 diff --git a/libburn/transport.h b/libburn/transport.h index 8f73753..55114ba 100644 --- a/libburn/transport.h +++ b/libburn/transport.h @@ -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];