diff --git a/cdrskin/cdrskin.c b/cdrskin/cdrskin.c index a9b4313..87d87fd 100644 --- a/cdrskin/cdrskin.c +++ b/cdrskin/cdrskin.c @@ -169,6 +169,7 @@ or #define Cdrskin_libburn_has_convert_scsi_adR 1 #define Cdrskin_libburn_has_burn_msgS 1 #define Cdrskin_libburn_has_burn_aborT 1 +#define Cdrskin_libburn_has_cleanup_handleR 1 #define Cdrskin_libburn_has_audioxtR 1 #define Cdrskin_libburn_has_get_start_end_lbA 1 #define Cdrskin_libburn_has_burn_disc_unsuitablE 1 @@ -192,7 +193,7 @@ or #ifdef Cdrskin_new_api_tesT /* put macros under test caveat here */ -#define Cdrskin_libburn_has_cleanup_handleR 1 +#define Cdrskin_allow_libburn_taO 1 #endif @@ -4728,7 +4729,11 @@ set_padsize:; printf("cdrskin: write type : RAW/RAW96R\n"); } else if(strcmp(argv[i],"-sao")==0 || strcmp(argv[i],"-dao")==0) { + +#ifndef Cdrskin_allow_libburn_taO set_sao:; +#endif + strcpy(skin->write_mode_name,"SAO"); skin->write_type= BURN_WRITE_SAO; skin->block_type= BURN_BLOCK_SAO; @@ -4765,6 +4770,17 @@ set_speed:; skin->swap_audio_bytes= 0; } else if(strcmp(argv[i],"-tao")==0) { + +#ifdef Cdrskin_allow_libburn_taO + + strcpy(skin->write_mode_name,"TAO"); + skin->write_type= BURN_WRITE_TAO; + skin->block_type= BURN_BLOCK_MODE1; + if(skin->verbosity>=Cdrskin_verbose_cmD) + printf("cdrskin: write type : TAO\n"); + +#else /* Cdrskin_allow_libburn_taO */ + if(skin->tao_to_sao_tsize<=0.0) { fprintf(stderr,"cdrskin: FATAL : libburn does not support -tao yet.\n"); fprintf(stderr,"cdrskin: HINT : Try option tao_to_sao_tsize=650m\n"); @@ -4773,6 +4789,8 @@ set_speed:; printf("cdrskin: NOTE : substituting mode -tao by mode -sao\n"); goto set_sao; +#endif /* Cdrskin_allow_libburn_taO */ + } else if(strncmp(argv[i],"tao_to_sao_tsize=",17)==0) { skin->tao_to_sao_tsize= Scanf_io_size(argv[i]+17,0); if(skin->tao_to_sao_tsize>Cdrskin_tracksize_maX) diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index 5322bac..9610b87 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2006.10.28.151521" +#define Cdrskin_timestamP "2006.10.31.115606" diff --git a/libburn/libdax_msgs.h b/libburn/libdax_msgs.h index 1578ef5..7d1afd7 100644 --- a/libburn/libdax_msgs.h +++ b/libburn/libdax_msgs.h @@ -303,7 +303,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff 0x00020006 (FATAL,HIGH) = Too many scsi siblings 0x00020007 (NOTE,HIGH) = Closed O_EXCL scsi siblings - From the hunt on Assert: + General library operations: 0x00020101 (WARNING,HIGH) = Cannot find given worker item 0x00020102 (SORRY,HIGH) = A drive operation is still going on @@ -320,7 +320,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff 0x0002010c (FATAL,HIGH) = Failed to transfer command to drive 0x0002010d (DEBUG,HIGH) = Could not inquire TOC 0x0002010e (FATAL,HIGH) = Attempt to read ATIP from ungrabbed drive - 0x0002010f + 0x0002010f (DEBUG,HIGH) = SCSI error condition on command 0x00020110 (FATAL,HIGH) = Persistent drive address too long 0x00020111 (FATAL,HIGH) = Could not allocate new auxiliary object 0x00020112 (SORRY,HIGH) = Bad combination of write_type and block_type @@ -329,6 +329,8 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff 0x00020115 (SORRY,HIGH) = Attempt to set track mode to unusable value 0x00020116 (FATAL,HIGH) = Track mode has unusable value 0x00020117 (FATAL,HIGH) = toc_entry of drive is already in use + 0x00020118 (DEBUG,HIGH) = Closing track + 0x00020119 (DEBUG,HIGH) = Closing session libdax_audioxtr: 0x00020200 (SORRY,HIGH) = Cannot open audio source file diff --git a/libburn/mmc.c b/libburn/mmc.c index f36cdc9..eec4f70 100644 --- a/libburn/mmc.c +++ b/libburn/mmc.c @@ -20,6 +20,15 @@ #include "structure.h" #include "options.h" + +#ifdef Libburn_log_in_and_out_streaM +/* <<< ts A61031 */ +#include +#include +#include +#endif /* Libburn_log_in_and_out_streaM */ + + /* ts A61005 */ #include "libdax_msgs.h" extern struct libdax_msgs *libdax_messenger; @@ -158,14 +167,13 @@ void mmc_close(struct burn_drive *d, int session, int track) mmc_function_spy("mmc_close"); - libdax_msgs_submit(libdax_messenger, -1, 0x00000002, - LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, - "HOW THAT ? mmc_close() was called", 0, 0); - c.retry = 1; c.oplen = sizeof(MMC_CLOSE); memcpy(c.opcode, MMC_CLOSE, sizeof(MMC_CLOSE)); - c.opcode[2] = session | !!track; + + /* ts A61030 : shifted !!session rather than or-ing plain session */ + c.opcode[2] = ((!!session)<<1) | !!track; + c.opcode[4] = track >> 8; c.opcode[5] = track & 0xFF; c.page = NULL; @@ -230,6 +238,14 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf) struct command c; int len; +#ifdef Libburn_log_in_and_out_streaM + /* <<< ts A61031 */ + static int tee_fd= -1; + if(tee_fd==-1) + tee_fd= open("/tmp/libburn_sg_written", + 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; @@ -261,7 +277,12 @@ int mmc_write(struct burn_drive *d, int start, struct buffer *buf) burn_print(12, "%d, %d, %d, %d\n", c->opcode[6], c->opcode[7], c->opcode[8], c->opcode[9]); */ -/* write(fileno(stderr), c.page->data, c.page->bytes);*/ +#ifdef Libburn_log_in_and_out_streaM + /* <<< ts A61031 */ + if(tee_fd!=-1) { + write(tee_fd,c.page->data,len*2048); + } +#endif /* Libburn_log_in_and_out_streaM */ d->issue_command(d, &c); return 0; diff --git a/libburn/sector.c b/libburn/sector.c index 43d2415..d9fd239 100644 --- a/libburn/sector.c +++ b/libburn/sector.c @@ -19,6 +19,15 @@ #include "toc.h" #include "write.h" + +#ifdef Libburn_log_in_and_out_streaM +/* <<< ts A61031 */ +#include +#include +#include +#endif /* Libburn_log_in_and_out_streaM */ + + /*static unsigned char isrc[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";*/ #define sector_common(X) d->alba++; d->rlba X; @@ -81,6 +90,15 @@ static void get_bytes(struct burn_track *track, int count, unsigned char *data) { int valid, shortage, curr, i, tr; +#ifdef Libburn_log_in_and_out_streaM + /* <<< ts A61031 */ + static int tee_fd= -1; + if(tee_fd==-1) + tee_fd= open("/tmp/libburn_sg_readin", + O_WRONLY|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR); +#endif /* Libburn_log_in_and_out_streaM */ + + /* no track pointer means we're just generating 0s */ if (!track) { memset(data, 0, count); @@ -112,6 +130,13 @@ static void get_bytes(struct burn_track *track, int count, unsigned char *data) valid = 0; } +#ifdef Libburn_log_in_and_out_streaM + /* <<< ts A61031 */ + if(tee_fd!=-1 && valid>0) { + write(tee_fd, data + curr, valid); + } +#endif /* Libburn_log_in_and_out_streaM */ + curr += valid; shortage = count - curr; @@ -622,6 +647,11 @@ int sector_headers_is_ok(struct burn_write_opts *o, int mode) return 1; if (o->write_type == BURN_WRITE_SAO) return 1; + + /* ts A61031 */ + if (o->write_type == BURN_WRITE_TAO) + return 1; + if (mode & BURN_MODE1) return 2; return 0; @@ -650,6 +680,11 @@ void sector_headers(struct burn_write_opts *o, unsigned char *out, return; if (o->write_type == BURN_WRITE_SAO) return; + + /* ts A61031 */ + if (o->write_type == BURN_WRITE_TAO) + return 1; + if (mode & BURN_MODE1) modebyte = 1; diff --git a/libburn/sg-linux.c b/libburn/sg-linux.c index a5a760c..a49eb3e 100644 --- a/libburn/sg-linux.c +++ b/libburn/sg-linux.c @@ -585,19 +585,40 @@ int sg_release(struct burn_drive *d) return 0; } + int sg_issue_command(struct burn_drive *d, struct command *c) { int done = 0, no_c_page = 0; int err; sg_io_hdr_t s; -/* ts A60821 - <<< debug: for tracing calls which might use open drive fds */ +#ifdef Libburn_log_sg_commandS + /* <<< ts A61030 */ + static FILE *fp= NULL; + static int fpcount= 0; + int i; +#endif /* Libburn_log_sg_commandS */ + + /* <<< ts A60821 + debug: for tracing calls which might use open drive fds */ char buf[161]; sprintf(buf,"sg_issue_command d->fd= %d d->released= %d\n", d->fd,d->released); mmc_function_spy(buf); +#ifdef Libburn_log_sg_commandS + /* <<< ts A61030 */ + if(fp==NULL) { + fp= fopen("/tmp/libburn_sg_command_log","a"); + fprintf(fp,"\n-----------------------------------------\n"); + } + for(i=0;i<10;i++) + fprintf(fp,"%2.2x ", c->opcode[i]); + fprintf(fp,"\n"); + fpcount++; +#endif /* Libburn_log_sg_commandS */ + + /* ts A61010 : with no fd there is no chance to send an ioctl */ if (d->fd < 0) { c->error = 1; @@ -670,6 +691,11 @@ int sg_issue_command(struct burn_drive *d, struct command *c) if (s.sb_len_wr) { if (!c->retry) { c->error = 1; + + /* ts A61030 */ + /* >>> to become d->notify_error() */ + scsi_notify_error(d, c, s.sbp, s.sb_len_wr, 0); + return 1; } switch (scsi_error(d, s.sbp, s.sb_len_wr)) { @@ -688,6 +714,31 @@ int sg_issue_command(struct burn_drive *d, struct command *c) return 1; } + +/* ts A61030 */ +/* @param flag bit0=do also report TEST UNIT READY failures */ +int scsi_notify_error(struct burn_drive *d, struct command *c, + unsigned char *sense, int senselen, int flag) +{ + int key, asc, ascq, ret; + char msg[160]; + + if (c->opcode[0] == 0) /* SPC : TEST UNIT READY command */ + if(!(flag & 1)) + return 1; + + key = sense[2]; + asc = sense[12]; + ascq = sense[13]; + + sprintf(msg,"SCSI error condition on command %2.2Xh : ", c->opcode[0]); + sprintf(msg+strlen(msg), "key= %x asc= %x ascq= %x\n", key,asc,ascq); + ret = libdax_msgs_submit(libdax_messenger, d->global_index, 0x0002010f, + LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg,0,0); + return ret; +} + + enum response scsi_error(struct burn_drive *d, unsigned char *sense, int senselen) { diff --git a/libburn/sg.h b/libburn/sg.h index 7563a34..1501d65 100644 --- a/libburn/sg.h +++ b/libburn/sg.h @@ -64,5 +64,9 @@ int sg_release(struct burn_drive *); int sg_issue_command(struct burn_drive *, struct command *); enum response scsi_error(struct burn_drive *, unsigned char *, int); +/* ts A61030 */ +/* @param flag bit0=do also report TEST UNIT READY failures */ +int scsi_notify_error(struct burn_drive *, struct command *c, + unsigned char *sense, int senselen, int flag); #endif /* __SG */ diff --git a/libburn/spc.c b/libburn/spc.c index 5142bac..4cf1226 100644 --- a/libburn/spc.c +++ b/libburn/spc.c @@ -284,6 +284,13 @@ void spc_select_write_params(struct burn_drive *d, /* ts A61007 : All current callers are safe. */ /* a ssert(o->drive == d); */ + /* <<< A61030 + fprintf(stderr,"libburn_debug: write_type=%d multi=%d control=%d\n", + o->write_type,o->multi,o->control); + fprintf(stderr,"libburn_debug: block_type=%d spc_block_type=%d\n", + o->block_type,spc_block_type(o->block_type)); + */ + memcpy(c.opcode, SPC_MODE_SELECT, sizeof(SPC_MODE_SELECT)); c.retry = 1; c.oplen = sizeof(SPC_MODE_SELECT); diff --git a/libburn/transport.h b/libburn/transport.h index 5ef987e..7b9cb87 100644 --- a/libburn/transport.h +++ b/libburn/transport.h @@ -190,7 +190,7 @@ struct burn_drive void (*close_session) ( struct burn_write_opts * o); /* ts A61029 */ - void (*close_track_session) ( struct burn_write_opts * o, + void (*close_track_session) ( struct burn_drive *d, int session, int track); int (*test_unit_ready) (struct burn_drive * d); diff --git a/libburn/write.c b/libburn/write.c index 6793721..705ea1e 100644 --- a/libburn/write.c +++ b/libburn/write.c @@ -115,6 +115,35 @@ int burn_write_flush(struct burn_write_opts *o) } +/* ts A61030 */ +int burn_write_close_track(struct burn_write_opts *o, int tnum) +{ + char msg[81]; + + sprintf(msg, "Closing track %2.2d\n", tnum+1); + libdax_msgs_submit(libdax_messenger, o->drive->global_index,0x00020119, + LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, msg,0,0); + + /* MMC-1 mentions track number 0xFF for "the incomplete track", + MMC-3 does not. I tried both. 0xFF was in effect when other + bugs finally gave up and made way for readable tracks. */ + o->drive->close_track_session(o->drive, 0, 0xff); /* tnum+1); */ + return 1; +} + + +/* ts A61030 */ +int burn_write_close_session(struct burn_write_opts *o) +{ + libdax_msgs_submit(libdax_messenger, o->drive->global_index,0x00020119, + LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_HIGH, + "Closing session", 0, 0); + + o->drive->close_track_session(o->drive, 1, 0); + return 1; +} + + /* ts A60819: This is unused since about Feb 2006, icculus.org/burn CVS. The compiler complains. We shall please our compiler. @@ -488,6 +517,7 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s, burn_print(12, "track %d is %d sectors long\n", tnum, sectors); + /* ts A61030 : this cannot happen. tnum is alsways < s-tracks */ if (tnum == s->tracks) tmp = sectors > 150 ? 150 : sectors; @@ -505,6 +535,11 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s, d->progress.sector++; } for (; i < sectors; i++) { + + /* ts A61030: program execution never gets to this point */ + fprintf(stderr,"LIBBURN_DEBUG: TNUM=%d TRACKS=%d TMP=%d\n", + tnum, s->tracks, tmp); + burn_print(1, "last track, leadout prep\n"); /* ts A61023 */ @@ -535,9 +570,14 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s, d->buffer->sectors = 0; } } - if (o->write_type == BURN_WRITE_TAO) + if (o->write_type == BURN_WRITE_TAO) { if (!burn_write_flush(o)) return 0; + + /* ts A61030 */ + if (burn_write_close_track(o, tnum) <= 0) + return 0; + } return 1; } @@ -570,6 +610,7 @@ void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc) struct burn_track *lt; int first = 1, i; int res; + char msg[80]; /* ts A60924 : libburn/message.c gets obsoleted burn_message_clear_queue(); @@ -587,7 +628,15 @@ void burn_disc_write_sync(struct burn_write_opts *o, struct burn_disc *disc) return crap. so we send the command, then ignore the result. */ res = d->get_nwa(d); -/* printf("ignored nwa: %d\n", res);*/ + + /* >>> ts A61031 : one should not ignore the "crap" but find out + when and why it occurs. Multi-session will hardly + work on base of flat guessing. + */ + sprintf(msg, "Ignored nwa: %d\n", res); + libdax_msgs_submit(libdax_messenger, d->global_index, 0x00000002, + LIBDAX_MSGS_SEV_DEBUG, LIBDAX_MSGS_PRIO_ZERO, + msg, 0, 0); d->alba = d->start_lba; d->nwa = d->alba; @@ -636,8 +685,17 @@ return crap. so we send the command, then ignore the result. goto fail; } else { if (first) { - d->nwa = -150; - d->alba = -150; + + /* ts A61030 : this made the burner take data */ + if(o->write_type == BURN_WRITE_TAO) + d->nwa= d->alba= 0; + else { + + d->nwa = -150; + d->alba = -150; + + } + } else { d->nwa += 4500; d->alba += 4500; @@ -652,8 +710,16 @@ return crap. so we send the command, then ignore the result. lt->mode)) goto fail; } else { - if (!burn_write_flush(o)) - goto fail; + + /* ts A61030 */ + if (o->write_type == BURN_WRITE_TAO) { + if (burn_write_close_session(o) <= 0) + goto fail; + } else + + if (!burn_write_flush(o)) + goto fail; + d->nwa += first ? 6750 : 2250; d->alba += first ? 6750 : 2250; } @@ -665,15 +731,18 @@ return crap. so we send the command, then ignore the result. d->progress.start_sector = 0; d->progress.sectors = 0; } - if (o->write_type != BURN_WRITE_SAO) + + /* ts A61030: extended skipping of flush to TAO: session is closed */ + if (o->write_type != BURN_WRITE_SAO && o->write_type != BURN_WRITE_TAO) if (!burn_write_flush(o)) goto fail; + sleep(1); burn_print(1, "done\n"); d->busy = BURN_DRIVE_IDLE; - /* ts A61012 : This return was traditionally missing, a suspect this + /* ts A61012 : This return was traditionally missing. I suspect this to have caused Cdrskin_eject() failures */ return; diff --git a/libburn/write.h b/libburn/write.h index 737ffb8..27ba00f 100644 --- a/libburn/write.h +++ b/libburn/write.h @@ -26,4 +26,8 @@ int burn_write_track(struct burn_write_opts *o, struct burn_session *s, int tnum); int burn_write_flush(struct burn_write_opts *o); +/* ts A61030 : necessary for TAO */ +int burn_write_close_track(struct burn_write_opts *o, int tnum); +int burn_write_close_session(struct burn_write_opts *o); + #endif /* BURN__WRITE_H */