diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index 76fc5ba..b3fd1be 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2007.09.10.110050" +#define Cdrskin_timestamP "2007.09.12.104626" diff --git a/libburn/drive.c b/libburn/drive.c index a2649bd..812bcb6 100644 --- a/libburn/drive.c +++ b/libburn/drive.c @@ -55,6 +55,7 @@ int burn_setup_drive(struct burn_drive *d, char *fname) d->mdata = NULL; d->toc_entry = NULL; d->released = 1; + d->stdio_fd = -1; d->status = BURN_DISC_UNREADY; return 1; } @@ -65,13 +66,21 @@ void burn_drive_free_subs(struct burn_drive *d) { if (d->idata != NULL) free((void *) d->idata); + d->idata = NULL; if (d->mdata != NULL) { burn_mdata_free_subs(d->mdata); free((void *) d->mdata); } + d->mdata = NULL; if(d->toc_entry != NULL) free((void *) d->toc_entry); - free(d->devname); + d->toc_entry = NULL; + if (d->devname != NULL) + free(d->devname); + d->devname = NULL; + if (d->stdio_fd >= 0) + close (d->stdio_fd); + d->stdio_fd = -1; } @@ -359,14 +368,14 @@ struct burn_drive *burn_drive_finish_enum(struct burn_drive *d) struct burn_drive *t; /* ts A60821 <<< debug: for tracing calls which might use open drive fds */ - int mmc_function_spy(char * text); + int mmc_function_spy(struct burn_drive *d, char * text); d->drive_role = 1; /* MMC drive */ t = burn_drive_register(d); /* ts A60821 */ - mmc_function_spy("enumerate_common : -------- doing grab"); + mmc_function_spy(NULL, "enumerate_common : -------- doing grab"); /* try to get the drive info */ if (t->grab(t)) { @@ -381,7 +390,7 @@ struct burn_drive *burn_drive_finish_enum(struct burn_drive *d) } /* ts A60821 */ - mmc_function_spy("enumerate_common : ----- would release "); + mmc_function_spy(NULL, "enumerate_common : ----- would release "); return t; } @@ -1128,8 +1137,8 @@ int burn_drive_grab_dummy(struct burn_drive_info *drive_infos[], char *fname) d= (struct burn_drive *) calloc(1, sizeof(struct burn_drive)); if (d == NULL) return 0; - d->status = BURN_DISC_EMPTY; burn_setup_drive(d, fname); + d->status = BURN_DISC_EMPTY; if (fname[0] != 0) d->drive_role = 2; diff --git a/libburn/libdax_msgs.h b/libburn/libdax_msgs.h index 380a142..0f100f1 100644 --- a/libburn/libdax_msgs.h +++ b/libburn/libdax_msgs.h @@ -385,6 +385,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff 0x00020149 (SORRY,HIGH) = Unsuitable filetype for pseudo-drive 0x0002014a (SORRY,HIGH) = Cannot read desired amount of data 0x0002014b (SORRY,HIGH) = Drive is already registered resp. scanned + 0x0002014c (FATAL,HIGH) = Emulated drive caught in SCSI function libdax_audioxtr: diff --git a/libburn/mmc.c b/libburn/mmc.c index 095d6c2..9cd730d 100644 --- a/libburn/mmc.c +++ b/libburn/mmc.c @@ -172,12 +172,25 @@ static unsigned char MMC_READ_10[] = static int mmc_function_spy_do_tell = 0; -int mmc_function_spy(char * text) +int mmc_function_spy(struct burn_drive *d, char * text) { - if (mmc_function_spy_do_tell) fprintf(stderr,"libburn: experimental: mmc_function_spy: %s\n", text); + if (d == NULL) + return 1; + if (d->drive_role != 1) { + char msg[4096]; + + sprintf(msg, "Emulated drive caught in SCSI adapter \"%s\"", + text); + libdax_msgs_submit(libdax_messenger, d->global_index, + 0x0002014c, + LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, + msg, 0, 0); + d->cancel = 1; + return 0; + } return 1; } @@ -212,7 +225,8 @@ void mmc_send_cue_sheet(struct burn_drive *d, struct cue_sheet *s) struct command c; - mmc_function_spy("mmc_send_cue_sheet"); + if (mmc_function_spy(d, "mmc_send_cue_sheet") <= 0) + return; scsi_init_command(&c, MMC_SEND_CUE_SHEET, sizeof(MMC_SEND_CUE_SHEET)); /* @@ -242,7 +256,9 @@ int mmc_reserve_track(struct burn_drive *d, off_t size) int lba; char msg[80]; - mmc_function_spy("mmc_reserve_track"); + if (mmc_function_spy(d, "mmc_reserve_track") <= 0) + return 0; + scsi_init_command(&c, MMC_RESERVE_TRACK, sizeof(MMC_RESERVE_TRACK)); /* c.oplen = sizeof(MMC_RESERVE_TRACK); @@ -274,7 +290,8 @@ int mmc_read_track_info(struct burn_drive *d, int trackno, struct buffer *buf, { struct command c; - mmc_function_spy("mmc_read_track_info"); + if (mmc_function_spy(d, "mmc_read_track_info") <= 0) + return 0; scsi_init_command(&c, MMC_TRACK_INFO, sizeof(MMC_TRACK_INFO)); /* @@ -320,7 +337,8 @@ int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa) int ret, num, alloc_len = 20; unsigned char *data; - mmc_function_spy("mmc_get_nwa"); + if (mmc_function_spy(d, "mmc_get_nwa") <= 0) + return -1; ret = mmc_read_track_info(d, trackno, &buf, alloc_len); if (ret <= 0) @@ -360,7 +378,8 @@ void mmc_close_disc(struct burn_write_opts *o) { struct burn_drive *d; - mmc_function_spy("mmc_close_disc"); + if (mmc_function_spy(d, "mmc_close_disc") <= 0) + return; libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, @@ -381,7 +400,8 @@ void mmc_close_session(struct burn_write_opts *o) { struct burn_drive *d; - mmc_function_spy("mmc_close_session"); + if (mmc_function_spy(d, "mmc_close_session") <= 0) + return; libdax_msgs_submit(libdax_messenger, -1, 0x00000002, LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, @@ -405,7 +425,8 @@ void mmc_close(struct burn_drive *d, int session, int track) { struct command c; - mmc_function_spy("mmc_close"); + if (mmc_function_spy(d, "mmc_close") <= 0) + return; scsi_init_command(&c, MMC_CLOSE, sizeof(MMC_CLOSE)); /* @@ -429,7 +450,8 @@ void mmc_get_event(struct burn_drive *d) struct command c; int alloc_len= 8; - mmc_function_spy("mmc_get_event"); + if (mmc_function_spy(d, "mmc_get_event") <= 0) + return; scsi_init_command(&c, MMC_GET_EVENT, sizeof(MMC_GET_EVENT)); /* @@ -594,7 +616,9 @@ void mmc_write_12(struct burn_drive *d, int start, struct buffer *buf) struct command c; int len; - mmc_function_spy("mmc_write_12"); + if (mmc_function_spy(d, "mmc_write_12") <= 0) + return; + len = buf->sectors; /* ts A61009 */ @@ -634,11 +658,10 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf) O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR); #endif /* Libburn_log_in_and_out_streaM */ - mmc_function_spy("mmc_write"); - pthread_mutex_lock(&d->access_lock); - cancelled = d->cancel; - pthread_mutex_unlock(&d->access_lock); + if (mmc_function_spy(d, "mmc_write") <= 0) + return BE_CANCELLED; + cancelled = d->cancel; if (cancelled) return BE_CANCELLED; @@ -713,9 +736,7 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf) LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0); } - pthread_mutex_lock(&d->access_lock); d->cancel = 1; - pthread_mutex_unlock(&d->access_lock); return BE_CANCELLED; } @@ -780,6 +801,9 @@ int mmc_fake_toc(struct burn_drive *d) unsigned char *tdata, size_data[4], start_data[4]; char msg[160]; + if (mmc_function_spy(d, "mmc_fake_toc") <= 0) + return -1; + if (d->last_track_no <= 0 || d->complete_sessions <= 0 || d->status == BURN_DISC_BLANK) return 2; @@ -905,8 +929,6 @@ static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len) int i, bpl= 12, old_alloc_len; unsigned char *tdata; - mmc_function_spy("mmc_read_toc"); - if (*alloc_len < 4) return 0; @@ -1073,6 +1095,9 @@ void mmc_read_toc(struct burn_drive *d) { int alloc_len = 4, ret; + if (mmc_function_spy(d, "mmc_read_toc") <= 0) + return; + ret = mmc_read_toc_al(d, &alloc_len); /* fprintf(stderr, @@ -1100,7 +1125,8 @@ int mmc_read_multi_session_c1(struct burn_drive *d, int *trackno, int *start) struct burn_track **tracks; struct burn_toc_entry toc_entry; - mmc_function_spy("mmc_read_multi_session_c1"); + if (mmc_function_spy(d, "mmc_read_multi_session_c1") <= 0) + return 0; /* First try to evaluate the eventually loaded TOC before issueing a MMC command. This search obtains the first track of the last @@ -1187,9 +1213,9 @@ static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len) mmc_get_configuration(d); +/* ts A70910 : found this as condition for mmc_function_spy() which went up if (*alloc_len < 2) - - mmc_function_spy("mmc_read_disc_info"); +*/ scsi_init_command(&c, MMC_GET_DISC_INFO, sizeof(MMC_GET_DISC_INFO)); /* @@ -1320,6 +1346,9 @@ void mmc_read_disc_info(struct burn_drive *d) { int alloc_len = 34, ret; + if (mmc_function_spy(d, "mmc_read_disc_info") <= 0) + return; + ret = mmc_read_disc_info_al(d, &alloc_len); /* fprintf(stderr,"LIBBURN_DEBUG: 51h alloc_len = %d , ret = %d\n", @@ -1348,7 +1377,8 @@ void mmc_read_atip(struct burn_drive *d) 4234, 5646, 7056, 8468, -12, -13, -14, -15}; /* 24, 32, 40, 48, -, -, -, - */ - mmc_function_spy("mmc_read_atip"); + if (mmc_function_spy(d, "mmc_read_atip") <= 0) + return; scsi_init_command(&c, MMC_GET_ATIP, sizeof(MMC_GET_ATIP)); /* @@ -1504,7 +1534,8 @@ void mmc_read_sectors(struct burn_drive *d, int errorblock, req; struct command c; - mmc_function_spy("mmc_read_sectors"); + if (mmc_function_spy(d, "mmc_read_sectors") <= 0) + return; /* ts A61009 : to be ensured by callers */ /* a ssert(len >= 0); */ @@ -1573,7 +1604,8 @@ void mmc_erase(struct burn_drive *d, int fast) { struct command c; - mmc_function_spy("mmc_erase"); + if (mmc_function_spy(d, "mmc_erase") <= 0) + return; scsi_init_command(&c, MMC_BLANK, sizeof(MMC_BLANK)); /* @@ -1593,7 +1625,9 @@ void mmc_read_lead_in(struct burn_drive *d, struct buffer *buf) int len; struct command c; - mmc_function_spy("mmc_read_lead_in"); + if (mmc_function_spy(d, "mmc_read_lead_in") <= 0) + return; + len = buf->sectors; scsi_init_command(&c, MMC_READ_CD, sizeof(MMC_READ_CD)); /* @@ -1619,7 +1653,8 @@ void mmc_perform_opc(struct burn_drive *d) { struct command c; - mmc_function_spy("mmc_perform_opc"); + if (mmc_function_spy(d, "mmc_perform_opc") <= 0) + return; scsi_init_command(&c, MMC_SEND_OPC, sizeof(MMC_SEND_OPC)); /* @@ -1649,7 +1684,8 @@ int mmc_set_streaming(struct burn_drive *d, char msg[160]; unsigned char *pd; - mmc_function_spy("mmc_set_streaming"); + if (mmc_function_spy(d, "mmc_set_streaming") <= 0) + return 0; scsi_init_command(&c, MMC_SET_STREAMING, sizeof(MMC_SET_STREAMING)); /* @@ -1731,7 +1767,8 @@ void mmc_set_speed(struct burn_drive *d, int r, int w) int ret, end_lba = 0; struct burn_speed_descriptor *best_sd = NULL; - mmc_function_spy("mmc_set_speed"); + if (mmc_function_spy(d, "mmc_set_speed") <= 0) + return; if (r <= 0 || w <= 0) { /* ts A70712 : now searching for best speed descriptor */ @@ -1851,8 +1888,6 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len) d->current_feat21h_link_size = -1; d->current_feat2fh_byte4 = -1; - mmc_function_spy("mmc_get_configuration"); - scsi_init_command(&c, MMC_GET_CONFIGURATION, sizeof(MMC_GET_CONFIGURATION)); /* @@ -2039,6 +2074,9 @@ void mmc_get_configuration(struct burn_drive *d) { int alloc_len = 8, ret; + if (mmc_function_spy(d, "mmc_get_configuration") <= 0) + return; + /* first command execution to learn Allocation Length */ ret = mmc_get_configuration_al(d, &alloc_len); /* @@ -2066,8 +2104,6 @@ static int mmc_read_format_capacities_al(struct burn_drive *d, char msg[160]; */ - mmc_function_spy("mmc_read_format_capacities"); - if (*alloc_len < 4) return 0; @@ -2204,6 +2240,9 @@ int mmc_read_format_capacities(struct burn_drive *d, int top_wanted) { int alloc_len = 4, ret; + if (mmc_function_spy(d, "mmc_read_format_capacities") <= 0) + return 0; + ret = mmc_read_format_capacities_al(d, &alloc_len, top_wanted); /* fprintf(stderr,"LIBBURN_DEBUG: 23h alloc_len = %d , ret = %d\n", @@ -2220,7 +2259,8 @@ void mmc_sync_cache(struct burn_drive *d) { struct command c; - mmc_function_spy("mmc_sync_cache"); + if (mmc_function_spy(d, "mmc_sync_cache") <= 0) + return; scsi_init_command(&c, MMC_SYNC_CACHE, sizeof(MMC_SYNC_CACHE)); /* @@ -2262,7 +2302,8 @@ int mmc_read_buffer_capacity(struct burn_drive *d) unsigned char *data; int alloc_len = 12; - mmc_function_spy("mmc_read_buffer_capacity"); + if (mmc_function_spy(d, "mmc_read_buffer_capacity") <= 0) + return 0; scsi_init_command(&c, MMC_READ_BUFFER_CAPACITY, sizeof(MMC_READ_BUFFER_CAPACITY)); @@ -2328,7 +2369,8 @@ int mmc_format_unit(struct burn_drive *d, off_t size, int flag) char msg[160],descr[80]; int full_format_type = 0x00; /* Full Format (or 0x10 for DVD-RW ?) */ - mmc_function_spy("mmc_format_unit"); + if (mmc_function_spy(d, "mmc_format_unit") <= 0) + return 0; scsi_init_command(&c, MMC_FORMAT_UNIT, sizeof(MMC_FORMAT_UNIT)); /* @@ -2561,8 +2603,6 @@ static int mmc_get_write_performance_al(struct burn_drive *d, /* A61225 : 1 = report about speed descriptors */ static int speed_debug = 0; - mmc_function_spy("mmc_get_write_performance"); - if (d->current_profile <= 0) mmc_get_configuration(d); @@ -2680,6 +2720,9 @@ int mmc_get_write_performance(struct burn_drive *d) { int alloc_len = 8, max_descr = 0, ret; + if (mmc_function_spy(d, "mmc_get_write_performance") <= 0) + return 0; + /* first command execution to learn number of descriptors and dxfer_len */ ret = mmc_get_write_performance_al(d, &alloc_len, &max_descr); @@ -2807,7 +2850,9 @@ int mmc_read_10(struct burn_drive *d, int start,int amount, struct buffer *buf) { struct command c; - mmc_function_spy("mmc_read_10"); + if (mmc_function_spy(d, "mmc_read_10") <= 0) + return -1; +; if (amount > BUFFER_SIZE / 2048) return -1; diff --git a/libburn/sbc.c b/libburn/sbc.c index 230179f..3424bc1 100644 --- a/libburn/sbc.c +++ b/libburn/sbc.c @@ -10,6 +10,13 @@ #include "spc.h" #include "options.h" + +/* ts A70910 + debug: for tracing calls which might use open drive fds + or for catching SCSI usage of emulated drives. */ +int mmc_function_spy(struct burn_drive *d, char * text); + + /* spc command set */ static unsigned char SBC_LOAD[] = { 0x1b, 0, 0, 0, 3, 0 }; static unsigned char SBC_UNLOAD[] = { 0x1b, 0, 0, 0, 2, 0 }; @@ -19,6 +26,9 @@ void sbc_load(struct burn_drive *d) { struct command c; + if (mmc_function_spy(d, "load") <= 0) + return; + scsi_init_command(&c, SBC_LOAD, sizeof(SBC_LOAD)); /* memcpy(c.opcode, SBC_LOAD, sizeof(SBC_LOAD)); @@ -35,6 +45,9 @@ void sbc_eject(struct burn_drive *d) { struct command c; + if (mmc_function_spy(d, "eject") <= 0) + return; + scsi_init_command(&c, SBC_UNLOAD, sizeof(SBC_UNLOAD)); /* memcpy(c.opcode, SBC_UNLOAD, sizeof(SBC_UNLOAD)); @@ -51,6 +64,9 @@ int sbc_start_unit(struct burn_drive *d) { struct command c; + if (mmc_function_spy(d, "start_unit") <= 0) + return 0; + scsi_init_command(&c, SBC_START_UNIT, sizeof(SBC_START_UNIT)); /* memcpy(c.opcode, SBC_START_UNIT, sizeof(SBC_START_UNIT)); diff --git a/libburn/sg-freebsd.c b/libburn/sg-freebsd.c index 6be71fe..67e2993 100644 --- a/libburn/sg-freebsd.c +++ b/libburn/sg-freebsd.c @@ -50,8 +50,9 @@ int burn_drive_is_banned(char *device_address); /* ts A60821 - <<< debug: for tracing calls which might use open drive fds */ -int mmc_function_spy(char * text); + debug: for tracing calls which might use open drive fds + or for catching SCSI usage of emulated drives. */ +int mmc_function_spy(struct burn_drive *d, char * text); /* ts A61021 : Moved most code from scsi_enumerate_drives under @@ -390,7 +391,7 @@ static void enumerate_common(char *fname, int bus_no, int host_no, /* ts A60821 <<< debug: for tracing calls which might use open drive fds */ - mmc_function_spy("enumerate_common : -------- doing grab"); + mmc_function_spy(NULL, "enumerate_common : -------- doing grab"); /* try to get the drive info */ if (t->grab(t)) { @@ -404,7 +405,7 @@ static void enumerate_common(char *fname, int bus_no, int host_no, /* ts A60821 <<< debug: for tracing calls which might use open drive fds */ - mmc_function_spy("enumerate_common : ----- would release "); + mmc_function_spy(NULL, "enumerate_common : ----- would release "); } @@ -452,7 +453,8 @@ int sg_grab(struct burn_drive *d) int count; struct cam_device *cam; - mmc_function_spy("sg_grab"); + if (mmc_function_spy(d, "sg_grab") <= 0) + return 0; if (burn_drive_is_open(d)) { d->released = 0; @@ -487,14 +489,15 @@ int sg_grab(struct burn_drive *d) int sg_release(struct burn_drive *d) { - mmc_function_spy("sg_release"); + if (mmc_function_spy(d, "sg_release") <= 0) + return 0; if (d->cam == NULL) { burn_print(1, "release an ungrabbed drive. die\n"); return 0; } - mmc_function_spy("sg_release ----------- closing."); + mmc_function_spy(NULL, "sg_release ----------- closing."); sg_close_drive(d); d->released = 1; @@ -510,7 +513,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c) char buf[161]; snprintf(buf, sizeof (buf), "sg_issue_command d->cam=%p d->released=%d", (void*)d->cam, d->released); - mmc_function_spy(buf); + mmc_function_spy(NULL, buf); if (d->cam == NULL) { c->error = 0; diff --git a/libburn/sg-linux.c b/libburn/sg-linux.c index d19d06a..b0a2c72 100644 --- a/libburn/sg-linux.c +++ b/libburn/sg-linux.c @@ -201,8 +201,9 @@ extern int burn_sg_open_abort_busy; /* ts A60821 - <<< debug: for tracing calls which might use open drive fds */ -int mmc_function_spy(char * text); + debug: for tracing calls which might use open drive fds + or for catching SCSI usage of emulated drives. */ +int mmc_function_spy(struct burn_drive *d, char * text); /* ------------------------------------------------------------------------ */ @@ -939,7 +940,8 @@ int sg_grab(struct burn_drive *d) /* ts A60821 <<< debug: for tracing calls which might use open drive fds */ - mmc_function_spy("sg_grab"); + if (mmc_function_spy(d, "sg_grab") <= 0) + return 0; /* ts A60813 - A60927 @@ -967,7 +969,7 @@ int sg_grab(struct burn_drive *d) /* ts A60821 <<< debug: for tracing calls which might use open drive fds */ - mmc_function_spy("sg_grab ----------- opening"); + mmc_function_spy(NULL, "sg_grab ----------- opening"); /* ts A70409 : DDLP-B */ /* >>> obtain single lock on d->devname */ @@ -1025,7 +1027,8 @@ int sg_release(struct burn_drive *d) { /* ts A60821 <<< debug: for tracing calls which might use open drive fds */ - mmc_function_spy("sg_release"); + if (mmc_function_spy(d, "sg_release") <= 0) + return 0; if (d->fd < 1) { burn_print(1, "release an ungrabbed drive. die\n"); @@ -1034,7 +1037,7 @@ int sg_release(struct burn_drive *d) /* ts A60821 <<< debug: for tracing calls which might use open drive fds */ - mmc_function_spy("sg_release ----------- closing"); + mmc_function_spy(NULL, "sg_release ----------- closing"); sg_close_drive(d); return 0; @@ -1131,7 +1134,7 @@ int sg_issue_command(struct burn_drive *d, struct command *c) char buf[161]; sprintf(buf,"sg_issue_command d->fd= %d d->released= %d\n", d->fd,d->released); - mmc_function_spy(buf); + mmc_function_spy(NULL, buf); #ifdef Libburn_log_sg_commandS /* ts A61030 */ diff --git a/libburn/spc.c b/libburn/spc.c index 7fa1569..564676e 100644 --- a/libburn/spc.c +++ b/libburn/spc.c @@ -27,6 +27,11 @@ #include "libdax_msgs.h" extern struct libdax_msgs *libdax_messenger; +/* ts A70910 + debug: for tracing calls which might use open drive fds + or for catching SCSI usage of emulated drives. */ +int mmc_function_spy(struct burn_drive *d, char * text); + /* spc command set */ /* ts A70519 : allocation length byte 3+4 was 0,255 */ @@ -63,6 +68,9 @@ int spc_test_unit_ready_r(struct burn_drive *d, int *key, int *asc, int *ascq) { struct command c; + if (mmc_function_spy(d, "test_unit_ready") <= 0) + return 0; + scsi_init_command(&c, SPC_TEST_UNIT_READY,sizeof(SPC_TEST_UNIT_READY)); /* c.oplen = sizeof(SPC_TEST_UNIT_READY); @@ -111,6 +119,9 @@ void spc_request_sense(struct burn_drive *d, struct buffer *buf) { struct command c; + if (mmc_function_spy(d, "request_sense") <= 0) + return; + scsi_init_command(&c, SPC_REQUEST_SENSE, sizeof(SPC_REQUEST_SENSE)); c.retry = 0; /* @@ -130,6 +141,9 @@ int spc_get_erase_progress(struct burn_drive *d) { struct buffer b; + if (mmc_function_spy(d, "get_erase_progress") <= 0) + return; + spc_request_sense(d, &b); return (b.data[16] << 8) | b.data[17]; } @@ -140,6 +154,9 @@ void spc_inquiry(struct burn_drive *d) struct burn_scsi_inquiry_data *id; struct command c; + if (mmc_function_spy(d, "inquiry") <= 0) + return; + scsi_init_command(&c, SPC_INQUIRY, sizeof(SPC_INQUIRY)); /* memcpy(c.opcode, SPC_INQUIRY, sizeof(SPC_INQUIRY)); @@ -171,6 +188,9 @@ void spc_prevent(struct burn_drive *d) { struct command c; + if (mmc_function_spy(d, "prevent") <= 0) + return; + scsi_init_command(&c, SPC_PREVENT, sizeof(SPC_PREVENT)); /* memcpy(c.opcode, SPC_PREVENT, sizeof(SPC_PREVENT)); @@ -186,6 +206,9 @@ void spc_allow(struct burn_drive *d) { struct command c; + if (mmc_function_spy(d, "allow") <= 0) + return; + scsi_init_command(&c, SPC_ALLOW, sizeof(SPC_ALLOW)); /* memcpy(c.opcode, SPC_ALLOW, sizeof(SPC_ALLOW)); @@ -368,6 +391,9 @@ void spc_sense_caps(struct burn_drive *d) { int alloc_len, start_len = 22, ret; + if (mmc_function_spy(d, "sense_caps") <= 0) + return; + /* first command execution to learn Allocation Length */ alloc_len = start_len; ret = spc_sense_caps_al(d, &alloc_len, 1); @@ -389,6 +415,9 @@ void spc_sense_error_params(struct burn_drive *d) unsigned char *page; struct command c; + if (mmc_function_spy(d, "sense_error_params") <= 0) + return; + scsi_init_command(&c, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE)); /* memcpy(c.opcode, SPC_MODE_SENSE, sizeof(SPC_MODE_SENSE)); @@ -419,6 +448,9 @@ void spc_select_error_params(struct burn_drive *d, struct buffer buf; struct command c; + if (mmc_function_spy(d, "select_error_params") <= 0) + return; + scsi_init_command(&c, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT)); /* memcpy(c.opcode, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT)); @@ -457,6 +489,9 @@ void spc_sense_write_params(struct burn_drive *d) unsigned char *page; struct command c; + if (mmc_function_spy(d, "sense_write_params") <= 0) + return; + /* ts A61007 : Done in soft at only caller burn_drive_grab() */ /* a ssert(d->mdata->cdr_write || d->mdata->cdrw_write || d->mdata->dvdr_write || d->mdata->dvdram_write); */ @@ -514,6 +549,9 @@ void spc_select_write_params(struct burn_drive *d, struct buffer buf; struct command c; + if (mmc_function_spy(d, "select_write_params") <= 0) + return; + /* ts A61007 : All current callers are safe. */ /* a ssert(o->drive == d); */ @@ -554,6 +592,9 @@ void spc_select_write_params(struct burn_drive *d, void spc_getcaps(struct burn_drive *d) { + if (mmc_function_spy(d, "getcaps") <= 0) + return; + spc_inquiry(d); spc_sense_caps(d); spc_sense_error_params(d); @@ -573,6 +614,9 @@ void spc_probe_write_modes(struct burn_drive *d) int last_try = 0; struct command c; + if (mmc_function_spy(d, "spc_probe_write_modes") <= 0) + return; + /* ts A70213 : added pseudo try_write_type 4 to set a suitable mode */ while (try_write_type != 5) { burn_print(9, "trying %d, %d\n", try_write_type, diff --git a/libburn/transport.h b/libburn/transport.h index 7600160..25b79fb 100644 --- a/libburn/transport.h +++ b/libburn/transport.h @@ -199,6 +199,8 @@ struct burn_drive /* ts A61106 */ int silent_on_scsi_error; + int stdio_fd; + int nwa; /* next writeable address */ int alba; /* absolute lba */ int rlba; /* relative lba in section */ diff --git a/libburn/write.c b/libburn/write.c index 4fffdcb..819cfb4 100644 --- a/libburn/write.c +++ b/libburn/write.c @@ -1190,7 +1190,7 @@ int burn_dvd_write_track(struct burn_write_opts *o, } - /* >>> ts A70215 : what about offset padding ? */ + /* (offset padding is done within sector_data()) */ burn_disc_init_track_status(o, s, tnum, sectors); for (i = 0; open_ended || i < sectors; i++) { @@ -1213,7 +1213,7 @@ int burn_dvd_write_track(struct burn_write_opts *o, d->progress.sector++; } - /* >>> ts A70215 : what about tail padding ? */ + /* (tail padding is done in sector_data()) */ /* Pad up buffer to next full o->obs (usually 32 kB) */ if (o->obs_pad && out->bytes > 0 && out->bytes < o->obs) { @@ -1607,7 +1607,8 @@ early_failure:; /* ts A70904 */ -int burn_stdio_open_write(struct burn_drive *d, off_t start_byte, int flag) +int burn_stdio_open_write(struct burn_drive *d, off_t start_byte, + int sector_size, int flag) { /* <<< We need _LARGEFILE64_SOURCE defined by the build system. @@ -1642,7 +1643,7 @@ int burn_stdio_open_write(struct burn_drive *d, off_t start_byte, int flag) close(fd); fd = -1; } - d->nwa = start_byte / 2048; + d->nwa = start_byte / sector_size; return fd; } @@ -1672,31 +1673,179 @@ int burn_stdio_write(int fd, char *buf, int count, struct burn_drive *d, 0x00020148, LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, "Cannot write desired amount of data", errno, 0); + d->cancel = 1; return 0; } return count; } +/* ts A70911 + If defined this makes stdio run on top of sector_data() rather than + own stdio read and write functions. The MMC function pointers d->write() + and d->sync_cache() get replaced by stdio substitutes. +*/ +#define Libburn_stdio_track_by_sector_datA 1 + + +#ifdef Libburn_stdio_track_by_sector_datA + +/* ts A70910 : to be used as burn_drive.write(), emulating mmc_write() */ +int burn_stdio_mmc_write(struct burn_drive *d, int start, struct buffer *buf) +{ + int ret; + off_t start_byte; + + if (d->cancel) + return BE_CANCELLED; + if (d->stdio_fd < 0) { + + /* >>> program error */; + + d->cancel = 1; + return BE_CANCELLED; + } + if (start != d->nwa) { + char msg[80]; + + start_byte = ((off_t) start) * + (off_t) (buf->bytes / buf->sectors); + if (lseek(d->stdio_fd, start_byte, SEEK_SET)==-1) { + sprintf(msg, "Cannot address start byte %.f", + (double) start_byte); + libdax_msgs_submit(libdax_messenger, d->global_index, + 0x00020147, + LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, + msg, errno, 0); + d->cancel = 1; + return BE_CANCELLED; + } + d->nwa = start; + } + ret = burn_stdio_write(d->stdio_fd,(char *)buf->data, buf->bytes, d,0); + if (ret <= 0) + return BE_CANCELLED; + d->nwa += buf->sectors; + return 0; +} + + +/* ts A70910 : to be used as burn_drive.write(), + emulating mmc_write() with simulated writing. */ +int burn_stdio_mmc_dummy_write(struct burn_drive *d, int start, + struct buffer *buf) +{ + if (d->cancel) + return BE_CANCELLED; + d->nwa = start + buf->sectors; + return 0; +} + + +/* ts A70911 */ +/* Flush stdio system buffer to physical device. + @param flag bit0= do not report debug message (intermediate sync) +*/ +int burn_stdio_sync_cache(struct burn_drive *d, int flag) +{ + if (d->stdio_fd < 0) { + + /* >>> program error */; + + d->cancel = 1; + return 0; + } + if (!(flag & 1)) + libdax_msgs_submit(libdax_messenger, -1, 0x00000002, + LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, + "syncing cache (stdio fsync)", 0, 0); + if (fsync(d->stdio_fd) != 0) { + libdax_msgs_submit(libdax_messenger, d->global_index, + 0x00020148, + LIBDAX_MSGS_SEV_SORRY, LIBDAX_MSGS_PRIO_HIGH, + "Cannot write desired amount of data", errno, 0); + d->cancel = 1; + return 0; + } + return 1; +} + + +/* ts A70911 : to be used as burn_drive.sync_cache(), + emulating mmc_sync_cache() */ +void burn_stdio_mmc_sync_cache(struct burn_drive *d) +{ + burn_stdio_sync_cache(d, 0); +} + + +#endif /* Libburn_stdio_track_by_sector_datA */ + + /* ts A70904 */ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s, - int tnum, int fd, int flag) + int tnum, int flag) { - int open_ended, bufsize, ret, eof_seen = 0, sectors; + int open_ended, bufsize, ret, sectors, fd; struct burn_track *t = s->track[tnum]; struct burn_drive *d = o->drive; - off_t t_size, w_count; char buf[16*2048]; +#ifdef Libburn_stdio_track_by_sector_datA + int i, prev_sync_sector = 0; + struct buffer *out = d->buffer; +#else + int eof_seen = 0; + off_t t_size, w_count; +#endif bufsize = sizeof(buf); + fd = d->stdio_fd; sectors = burn_track_get_sectors(t); burn_disc_init_track_status(o, s, tnum, sectors); + open_ended = burn_track_is_open_ended(t); + +#ifdef Libburn_stdio_track_by_sector_datA + + /* attach stdio emulators for mmc_*() functions */ + if (o->simulate) + d->write = burn_stdio_mmc_dummy_write; + else + d->write = burn_stdio_mmc_write; + d->sync_cache = burn_stdio_mmc_sync_cache; + + for (i = 0; open_ended || i < sectors; i++) { + /* transact a (CD sized) sector */ + if (!sector_data(o, t, 0)) + return 0; + if (open_ended) { + d->progress.sectors = sectors = d->progress.sector; + if (burn_track_is_data_done(t)) + break; + } + d->progress.sector++; + /* Flush to disk after each full MB */ + if (d->progress.sector - prev_sync_sector >= 512) { + prev_sync_sector = d->progress.sector; + if (!o->simulate) + burn_stdio_sync_cache(d, 1); + } + } + + /* Pad up buffer to next full o->obs (usually 32 kB) */ + if (o->obs_pad && out->bytes > 0 && out->bytes < o->obs) { + memset(out->data + out->bytes, 0, o->obs - out->bytes); + out->sectors += (o->obs - out->bytes) / 2048; + out->bytes = o->obs; + } + ret = burn_write_flush(o, t); + +#else /* Libburn_stdio_track_by_sector_datA */ + + t_size = t->source->get_size(t->source); /* >>> write t->offset zeros */; - open_ended = burn_track_is_open_ended(t); - t_size = t->source->get_size(t->source); for(w_count = 0; w_count < t_size || open_ended; w_count += ret) { @@ -1730,10 +1879,19 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s, d->progress.sectors = d->progress.sector; t->writecount += ret; t->written_sectors = t->writecount / 2048; + + /* Flush to physical device after each full MB */ + if (d->progress.sector - prev_sync_sector >= 512) { + prev_sync_sector = d->progress.sector; + if (!o->simulate) + burn_stdio_sync_cache(d, 1); + } } /* >>> write t->tail zeros */; +#endif + return 1; } @@ -1742,7 +1900,7 @@ int burn_stdio_write_track(struct burn_write_opts *o, struct burn_session *s, int burn_stdio_write_sync(struct burn_write_opts *o, struct burn_disc *disc) { - int ret, fd = -1; + int ret; struct burn_drive *d = o->drive; d->needs_close_session = 0; @@ -1758,12 +1916,15 @@ int burn_stdio_write_sync(struct burn_write_opts *o, d->progress.session = 0; d->progress.tracks = 1; + /* >>> adjust sector size (2048) to eventual audio or even raw */ /* open target file */ - fd = burn_stdio_open_write(d, o->start_byte, 0); - if (fd == -1) + if (d->stdio_fd >= 0) + close(d->stdio_fd); + d->stdio_fd = burn_stdio_open_write(d, o->start_byte, 2048, 0); + if (d->stdio_fd == -1) {ret = 0; goto ex;} - ret = burn_stdio_write_track(o, disc->session[0], 0, fd, 0); + ret = burn_stdio_write_track(o, disc->session[0], 0, 0); if (ret <= 0) goto ex; @@ -1773,8 +1934,10 @@ int burn_stdio_write_sync(struct burn_write_opts *o, d->progress.sectors = 0; ret = 1; ex:; - if (fd != -1) - close (fd); + if (d->stdio_fd != -1) { + close (d->stdio_fd); + d->stdio_fd = -1; + } /* update media state records */ burn_drive_mark_unready(d); @@ -2051,7 +2214,7 @@ int burn_random_access_write(struct burn_drive *d, off_t byte_address, return 0; } if(d->drive_role != 1) { - fd = burn_stdio_open_write(d, byte_address, 0); + fd = burn_stdio_open_write(d, byte_address, 2048, 0); if (fd == -1) return 0; }