diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index f5c8340..a3f0b63 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2020.08.22.132046" +#define Cdrskin_timestamP "2020.08.24.132739" diff --git a/libburn/drive.c b/libburn/drive.c index 1300a7f..21d86b0 100644 --- a/libburn/drive.c +++ b/libburn/drive.c @@ -557,6 +557,8 @@ struct burn_drive *burn_drive_register(struct burn_drive *d) d->thread_pid_valid = 0; memset(&(d->thread_tid), 0, sizeof(d->thread_tid)); d->medium_state_changed = 0; + d->set_streaming_exact_bit = 0; + d->set_streaming_err = 0; d->toc_entries = 0; d->toc_entry = NULL; d->disc = NULL; @@ -1599,6 +1601,22 @@ void burn_drive_set_speed(struct burn_drive *d, int r, int w) d->set_speed(d, r, w); } +int burn_drive_set_speed_exact(struct burn_drive *d, int r, int w) +{ + int sose; + + d->nominal_write_speed = w; + if(d->drive_role != 1) + return 0; + sose = d->silent_on_scsi_error; + d->silent_on_scsi_error = 3; + d->set_streaming_err = 0; + d->set_streaming_exact_bit = 1; + d->set_speed(d, r, w); + d->silent_on_scsi_error = sose; + d->set_streaming_exact_bit = 0; + return !d->set_streaming_err; +} /* ts A70711 API function */ int burn_drive_set_buffer_waiting(struct burn_drive *d, int enable, diff --git a/libburn/libburn.h b/libburn/libburn.h index 906806b..e8e3f0d 100644 --- a/libburn/libburn.h +++ b/libburn/libburn.h @@ -2996,7 +2996,7 @@ int burn_track_get_counters(struct burn_track *t, off_t *read_bytes, off_t *written_bytes); -/** Sets drive read and write speed +/** Sets drive read and write speed. Note: "k" is 1000, not 1024. 1xCD = 176.4 k/s, 1xDVD = 1385 k/s, 1xBD = 4496 k/s. Fractional speeds should be rounded up. Like 4xCD = 706. @@ -3007,6 +3007,22 @@ int burn_track_get_counters(struct burn_track *t, void burn_drive_set_speed(struct burn_drive *d, int read, int write); +/* ts C00822 */ +/** Sets drive read and write speed using the "Exact" bit of SCSI command + SET STREAMING. This command will be used even if a CD medium is present. + MMC specifies that with the Exact bit the desired speed settings shall + either be obeyed by the drive exactly, or that the drive shall indicate + failure and not accept the settings. + The call parameters have the same meaning as with burn_drive_set_speed(). + @param d The drive to set speed for. It must be a role 1 drive. + @param read Read speed in k/s (0 is max, -1 is min). + @param write Write speed in k/s (0 is max, -1 is min). + @return 1=success , 0=failure + @since 1.5.4 +*/ +int burn_drive_set_speed_exact(struct burn_drive *d, int read, int write); + + /* ts A70711 */ /** Controls the behavior with writing when the drive buffer is suspected to be full. To check and wait for enough free buffer space before writing diff --git a/libburn/libburn.ver b/libburn/libburn.ver index 9dd51c8..71a6e51 100644 --- a/libburn/libburn.ver +++ b/libburn/libburn.ver @@ -80,6 +80,7 @@ burn_drive_scan_and_grab; burn_drive_set_buffer_waiting; burn_drive_set_immed; burn_drive_set_speed; +burn_drive_set_speed_exact; burn_drive_set_stream_recording; burn_drive_snooze; burn_drive_was_feat21_failure; diff --git a/libburn/mmc.c b/libburn/mmc.c index e4df746..874d483 100644 --- a/libburn/mmc.c +++ b/libburn/mmc.c @@ -2832,6 +2832,8 @@ int mmc_set_streaming(struct burn_drive *d, pd = c->page->data; pd[0] = 0; /* WRC=0 (Default Rotation Control), RDD=Exact=RA=0 */ + if (d->set_streaming_exact_bit) + pd[0] |= 2; /* Exact= 1 */ if (w_speed == 0) w_speed = 0x10000000; /* ~ 2 TB/s */ @@ -2849,8 +2851,9 @@ int mmc_set_streaming(struct burn_drive *d, } else eff_end_lba = end_lba; - sprintf(msg, "mmc_set_streaming: end_lba=%d , r=%d , w=%d", - eff_end_lba, r_speed, w_speed); + sprintf(msg, + "mmc_set_streaming: end_lba=%d , r=%d , w=%d , exact=%d", + eff_end_lba, r_speed, w_speed, !!(pd[0] & 2)); libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, msg, 0, 0); @@ -2886,6 +2889,8 @@ int mmc_set_streaming(struct burn_drive *d, LIBDAX_MSGS_SEV_DEBUG : LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); } + if (key != 0) + d->set_streaming_err = 1; {ret = 0; goto ex;} } ret = 1; @@ -2963,8 +2968,8 @@ void mmc_set_speed(struct burn_drive *d, int r, int w) /* ts A61221 : try to set DVD speed via command B6h */ if (strstr(d->current_profile_text, "DVD") == d->current_profile_text - || - strstr(d->current_profile_text, "BD") == d->current_profile_text) { + || strstr(d->current_profile_text, "BD") == d->current_profile_text + || d->set_streaming_exact_bit) { ret = mmc_set_streaming(d, r, w, end_lba); if (ret != 0) return; /* success or really fatal failure */ diff --git a/libburn/transport.h b/libburn/transport.h index 86ec7d9..0b60d98 100644 --- a/libburn/transport.h +++ b/libburn/transport.h @@ -442,6 +442,13 @@ struct burn_drive /* 0=no change, 1=change, -1=already urged OS to revalidate medium */ int medium_state_changed; + /* ts C00822 */ + /* If set, use Exact bit with SET STREAMING and use SET STREAMING + even if the medium is a CD. + */ + int set_streaming_exact_bit; + int set_streaming_err; + /* transport functions */ int (*grab) (struct burn_drive *); int (*release) (struct burn_drive *);