Author: philippr Date: Mon Feb 4 21:24:15 2008 New Revision: 629 URL: http://svn.gnome.org/viewvc/brasero?rev=629&view=rev
Log: better fix for #513742 fix for a small problem where key sense data wasn\'t correct in some cases fix for #502703 – Data Integrity Check Always Fails AND Burning Speed Slow (except dvd which ignored setting). instead of reading volume declared size we correct the size when we detect a track written in SAO mode (and a multisession disc) this means READ CD scsi function was implemented * src/Makefile.am: * src/brasero-data-disc.c: (brasero_data_disc_get_selected_uri): * src/brasero-project.c: (brasero_project_get_selected_uri): * src/burn-medium.c: (brasero_medium_track_written_SAO), (brasero_medium_track_get_info), (brasero_medium_set_track_type), (brasero_medium_get_sessions_info): * src/scsi/scsi-error.c: * src/scsi/scsi-error.h: * src/scsi/scsi-mmc1.h: * src/scsi/scsi-opcodes.h: * src/scsi/scsi-read-toc-pma-atip.h: * src/scsi/scsi-sense-data.c: (brasero_sense_data_print), (brasero_sense_data_illegal_request): * src/scsi/scsi-utils.h: Modified: branches/brasero_0_7/ChangeLog branches/brasero_0_7/src/Makefile.am branches/brasero_0_7/src/brasero-data-disc.c branches/brasero_0_7/src/brasero-project.c branches/brasero_0_7/src/burn-medium.c branches/brasero_0_7/src/scsi/scsi-error.c branches/brasero_0_7/src/scsi/scsi-error.h branches/brasero_0_7/src/scsi/scsi-mmc1.h branches/brasero_0_7/src/scsi/scsi-opcodes.h branches/brasero_0_7/src/scsi/scsi-read-toc-pma-atip.h branches/brasero_0_7/src/scsi/scsi-sense-data.c branches/brasero_0_7/src/scsi/scsi-utils.h Modified: branches/brasero_0_7/src/Makefile.am ============================================================================== --- branches/brasero_0_7/src/Makefile.am (original) +++ branches/brasero_0_7/src/Makefile.am Mon Feb 4 21:24:15 2008 @@ -174,6 +174,8 @@ scsi/scsi-dvd-structures.h \ scsi/scsi-read-format-capacities.c \ scsi/scsi-read-format-capacities.h \ + scsi/scsi-read-cd.h \ + scsi/scsi-read-cd.c \ burn-debug.c \ burn-debug.h \ burn-track.h \ @@ -217,7 +219,7 @@ brasero-preview.h \ brasero-preview.c \ burn-image-format.c \ - burn-image-format.h + burn-image-format.h brasero_LDADD = $(BRASERO_LIBS) Modified: branches/brasero_0_7/src/brasero-data-disc.c ============================================================================== --- branches/brasero_0_7/src/brasero-data-disc.c (original) +++ branches/brasero_0_7/src/brasero-data-disc.c Mon Feb 4 21:24:15 2008 @@ -11659,7 +11659,7 @@ brasero_data_disc_get_selected_uri (BraseroDisc *disc, gchar **uri) { - gchar *path; + gchar *path= NULL; GtkTreePath *realpath; BraseroDataDisc *data; @@ -11676,6 +11676,11 @@ brasero_data_disc_tree_path_to_disc_path (data, realpath, &path); gtk_tree_path_free (realpath); + if (!path) { + *uri = NULL; + return TRUE; + } + *uri = brasero_data_disc_path_to_uri (data, path); if (*uri == BRASERO_IMPORTED_FILE) { *uri = NULL; Modified: branches/brasero_0_7/src/brasero-project.c ============================================================================== --- branches/brasero_0_7/src/brasero-project.c (original) +++ branches/brasero_0_7/src/brasero-project.c Mon Feb 4 21:24:15 2008 @@ -646,7 +646,7 @@ if (project->priv->is_burning) return NULL; - if (brasero_disc_get_selected_uri (project->priv->current, uri)) + if (brasero_disc_get_selected_uri (project->priv->current, &uri)) return uri; return NULL; Modified: branches/brasero_0_7/src/burn-medium.c ============================================================================== --- branches/brasero_0_7/src/burn-medium.c (original) +++ branches/brasero_0_7/src/burn-medium.c Mon Feb 4 21:24:15 2008 @@ -1110,37 +1110,6 @@ * Functions to get information about disc contents */ -static void -brasero_medium_set_track_type (BraseroMedium *self, - BraseroMediumTrack *track, - guchar control) -{ - BraseroMediumPrivate *priv; - - priv = BRASERO_MEDIUM_PRIVATE (self); - - if (control & BRASERO_SCSI_TRACK_COPY) - track->type |= BRASERO_MEDIUM_TRACK_COPY; - - if (!(control & BRASERO_SCSI_TRACK_DATA)) { - track->type |= BRASERO_MEDIUM_TRACK_AUDIO; - priv->info |= BRASERO_MEDIUM_HAS_AUDIO; - - if (control & BRASERO_SCSI_TRACK_PREEMP) - track->type |= BRASERO_MEDIUM_TRACK_PREEMP; - - if (control & BRASERO_SCSI_TRACK_4_CHANNELS) - track->type |= BRASERO_MEDIUM_TRACK_4_CHANNELS; - } - else { - track->type |= BRASERO_MEDIUM_TRACK_DATA; - priv->info |= BRASERO_MEDIUM_HAS_DATA; - - if (control & BRASERO_SCSI_TRACK_DATA_INCREMENTAL) - track->type |= BRASERO_MEDIUM_TRACK_INCREMENTAL; - } -} - static BraseroBurnResult brasero_medium_track_volume_size (BraseroMedium *self, BraseroMediumTrack *track, @@ -1183,6 +1152,61 @@ return BRASERO_BURN_OK; } +static gboolean +brasero_medium_track_written_SAO (int fd, + int track_num, + int track_start) +{ + unsigned char buffer [2048]; + BraseroScsiResult result; + + BRASERO_BURN_LOG ("Checking for TDBs in track pregap."); + + /* The two following sectors are readable */ + result = brasero_mmc1_read_block (fd, + TRUE, + BRASERO_SCSI_BLOCK_TYPE_ANY, + BRASERO_SCSI_BLOCK_HEADER_NONE, + BRASERO_SCSI_BLOCK_NO_SUBCHANNEL, + track_start - 1, + 1, + buffer, + sizeof (buffer), + NULL); + + if (result == BRASERO_SCSI_OK) { + int i; + + if (buffer [0] != 'T' || buffer [1] != 'D' || buffer [2] != 'I') { + BRASERO_BURN_LOG ("Track was probably recorded in SAO mode - no TDB."); + return TRUE; + } + + /* Find the TDU (16 bytes) for the track (there can be for other tracks). + * i must be < 128 = ((2048 - 8 (size TDB)) / 16 (size TDU). */ + for (i = 0; i < 128; i ++) { + if (BRASERO_GET_BCD (buffer [8 + i * 16]) != track_num) + break; + } + + if (i >= 128) { + BRASERO_BURN_LOG ("No appropriate TDU for track"); + return TRUE; + } + + if (buffer [8 + i * 16] == 0x80 || buffer [8 + i * 16] == 0x00) { + BRASERO_BURN_LOG ("Track was recorded in TAO mode."); + return FALSE; + } + + BRASERO_BURN_LOG ("Track was recorded in Packet mode."); + return FALSE; + } + + BRASERO_BURN_LOG ("No pregap. That track must have been recorded in SAO mode."); + return TRUE; +} + static BraseroBurnResult brasero_medium_track_get_info (BraseroMedium *self, gboolean multisession, @@ -1224,6 +1248,19 @@ track->blocks_num = BRASERO_GET_32 (track_info.track_size); track->session = BRASERO_SCSI_SESSION_NUM (track_info); + if (track->blocks_num <= 300) { + /* Now here is a potential bug: we can write tracks (data or + * not) shorter than 300 Kio /2 sec but they will be padded to + * reach this floor value. It means that blocks_num is always + * 300 blocks even if the data length on the track is actually + * shorter. + * So we read the volume descriptor. If it works, good otherwise + * use the old value. + * That's important for checksuming to have a perfect account of + * the data size. */ + BRASERO_BURN_LOG ("300 sectors size. Checking for real size"); + brasero_medium_track_volume_size (self, track, fd); + } /* NOTE: for multisession CDs only * if the session was incremental (TAO/packet/...) by opposition to DAO * and SAO, then 2 blocks (run-out) have been added at the end of user @@ -1231,42 +1268,60 @@ * track has been recorded in TAO mode * See MMC5 * 6.44.3.2 CD-R Fixed Packet, Variable Packet, Track-At-Once - * 6.44.3.2 CD-R Fixed Packet, Variable Packet, Track-At-Once * Now, strangely track_get_info always removes two blocks, whereas read * raw toc adds them (always) and this, whatever the mode, the position. * It means that when we detect a SAO session we have to add 2 blocks to * all tracks in it. * See # for any information: * if first track is recorded in SAO/DAO then the length will be two sec - * shorter. If not that's fine. + * shorter. If not, if it was recorded in TAO, that's fine. * The other way would be to use read raw toc but then that's the * opposite that happens and that latter will return two more bytes for * TAO recorded session. * So there are 2 workarounds: - * - read the volume size + * - read the volume size (can be unreliable) * - read the 2 last blocks and see if they are run-outs - * here we do solution 1 but only for CDRW, not blank, and for first - * session only since that's the only one that can be recorded in DAO - */ - if (track->session == 1 - && multisession == TRUE - && (priv->info & BRASERO_MEDIUM_CD) - && !(priv->info & BRASERO_MEDIUM_ROM)) { - BRASERO_BURN_LOG ("Track belongs to first session of multisession CD. Checking for real size"); - brasero_medium_track_volume_size (self, track, fd); - } - else if (track->blocks_num <= 300) { - /* Now here is a potential bug: we can write tracks (data or - * not) shorter than 300 Kio /2 sec but they will be padded to - * reach this floor value. That means that is blocks_num is 300 - * blocks that may mean that the data length on the track is - * actually shorter. - * So we read the volume descriptor. If it works, good otherwise - * use the old value. - * That's important for checksuming to have a perfect account of - * the data size. */ - BRASERO_BURN_LOG ("300 sectors size. Checking for real size"); - brasero_medium_track_volume_size (self, track, fd); + * here we do solution 2 but only for CDRW, not blank, and for first + * session only since that's the only one that can be recorded in DAO. */ + else if (track->session == 1 + && (track->type & BRASERO_MEDIUM_TRACK_DATA) + && multisession + && (priv->info & BRASERO_MEDIUM_CD) + && !(priv->info & BRASERO_MEDIUM_ROM)) { + BRASERO_BURN_LOG ("Data track belongs to first session of multisession CD. " + "Checking for real size (%i sectors currently).", + track->blocks_num); + + /* we test the pregaps blocks for TDB: these are special blocks + * filling the pregap of a track when it was recorded as TAO or + * as Packet. + * NOTE: in this case we need to skip 7 sectors before since if + * it was recorded incrementally then there is also 4 runins, + * 1 link sector and 2 runouts (at end of pregap). + * we also make sure that the two blocks we're adding are + * actually readable. */ + /* Test the last block, the before last and the one before before last */ + result = brasero_mmc1_read_block (fd, + FALSE, + BRASERO_SCSI_BLOCK_TYPE_ANY, + BRASERO_SCSI_BLOCK_HEADER_NONE, + BRASERO_SCSI_BLOCK_NO_SUBCHANNEL, + track->blocks_num + track->start, + 2, + NULL, + 0, + NULL); + + if (result == BRASERO_SCSI_OK) { + BRASERO_BURN_LOG ("Following two sectors are readable."); + + if (brasero_medium_track_written_SAO (fd, track_num, track->start)) { + track->blocks_num += 2; + BRASERO_BURN_LOG ("Correcting track size (now %i)", track->blocks_num); + } + } + else + BRASERO_BURN_LOG ("Detected runouts"); } if (track_info.next_wrt_address_valid) @@ -1284,6 +1339,37 @@ #if 0 +static void +brasero_medium_set_track_type (BraseroMedium *self, + BraseroMediumTrack *track, + guchar control) +{ + BraseroMediumPrivate *priv; + + priv = BRASERO_MEDIUM_PRIVATE (self); + + if (control & BRASERO_SCSI_TRACK_COPY) + track->type |= BRASERO_MEDIUM_TRACK_COPY; + + if (!(control & BRASERO_SCSI_TRACK_DATA)) { + track->type |= BRASERO_MEDIUM_TRACK_AUDIO; + priv->info |= BRASERO_MEDIUM_HAS_AUDIO; + + if (control & BRASERO_SCSI_TRACK_PREEMP) + track->type |= BRASERO_MEDIUM_TRACK_PREEMP; + + if (control & BRASERO_SCSI_TRACK_4_CHANNELS) + track->type |= BRASERO_MEDIUM_TRACK_4_CHANNELS; + } + else { + track->type |= BRASERO_MEDIUM_TRACK_DATA; + priv->info |= BRASERO_MEDIUM_HAS_DATA; + + if (control & BRASERO_SCSI_TRACK_DATA_INCREMENTAL) + track->type |= BRASERO_MEDIUM_TRACK_INCREMENTAL; + } +} + /** * return : * 0 when it's not possible to determine (fallback to formatted toc) @@ -1704,12 +1790,6 @@ track->start = BRASERO_GET_32 (desc->track_start); /* we shouldn't request info on a track if the disc is closed */ - brasero_medium_track_get_info (self, - multisession, - track, - g_slist_length (priv->tracks), - fd, - code); if (desc->control & BRASERO_SCSI_TRACK_COPY) track->type |= BRASERO_MEDIUM_TRACK_COPY; @@ -1724,8 +1804,26 @@ if (desc->control & BRASERO_SCSI_TRACK_4_CHANNELS) track->type |= BRASERO_MEDIUM_TRACK_4_CHANNELS; } - else if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS) - || BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_RESTRICTED)) { + else { + track->type |= BRASERO_MEDIUM_TRACK_DATA; + priv->info |= BRASERO_MEDIUM_HAS_DATA; + + if (desc->control & BRASERO_SCSI_TRACK_DATA_INCREMENTAL) + track->type |= BRASERO_MEDIUM_TRACK_INCREMENTAL; + } + + brasero_medium_track_get_info (self, + multisession, + track, + g_slist_length (priv->tracks), + fd, + code); + + if (desc->control & BRASERO_SCSI_TRACK_COPY) + track->type |= BRASERO_MEDIUM_TRACK_COPY; + + if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS) + || BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_RESTRICTED)) { BraseroBurnResult result; /* a special case for these two kinds of media (DVD+RW) @@ -1733,29 +1831,15 @@ result = brasero_medium_track_volume_size (self, track, fd); - if (result == BRASERO_BURN_OK) { - track->type |= BRASERO_MEDIUM_TRACK_DATA; - priv->info |= BRASERO_MEDIUM_HAS_DATA; - - priv->next_wr_add = 0; - - if (desc->control & BRASERO_SCSI_TRACK_DATA_INCREMENTAL) - track->type |= BRASERO_MEDIUM_TRACK_INCREMENTAL; - } - else { + if (result != BRASERO_BURN_OK) { priv->tracks = g_slist_remove (priv->tracks, track); g_free (track); priv->info |= BRASERO_MEDIUM_BLANK; priv->info &= ~BRASERO_MEDIUM_CLOSED; } - } - else { - track->type |= BRASERO_MEDIUM_TRACK_DATA; - priv->info |= BRASERO_MEDIUM_HAS_DATA; - - if (desc->control & BRASERO_SCSI_TRACK_DATA_INCREMENTAL) - track->type |= BRASERO_MEDIUM_TRACK_INCREMENTAL; + else + priv->next_wr_add = 0; } } Modified: branches/brasero_0_7/src/scsi/scsi-error.c ============================================================================== --- branches/brasero_0_7/src/scsi/scsi-error.c (original) +++ branches/brasero_0_7/src/scsi/scsi-error.c Mon Feb 4 21:24:15 2008 @@ -38,6 +38,8 @@ N_("invalid field in command"), N_("the device timed out"), N_("key not established"), + /* FIXME: set for translation */ + "invalid track mode", NULL }; /* errno */ const gchar * Modified: branches/brasero_0_7/src/scsi/scsi-error.h ============================================================================== --- branches/brasero_0_7/src/scsi/scsi-error.h (original) +++ branches/brasero_0_7/src/scsi/scsi-error.h Mon Feb 4 21:24:15 2008 @@ -51,6 +51,7 @@ BRASERO_SCSI_INVALID_FIELD, BRASERO_SCSI_TIMEOUT, BRASERO_SCSI_KEY_NOT_ESTABLISHED, + BRASERO_SCSI_INVALID_TRACK_MODE, BRASERO_SCSI_ERRNO, BRASERO_SCSI_ERROR_LAST } BraseroScsiErrCode; Modified: branches/brasero_0_7/src/scsi/scsi-mmc1.h ============================================================================== --- branches/brasero_0_7/src/scsi/scsi-mmc1.h (original) +++ branches/brasero_0_7/src/scsi/scsi-mmc1.h Mon Feb 4 21:24:15 2008 @@ -23,6 +23,7 @@ */ #include "scsi-error.h" +#include "scsi-read-cd.h" #include "scsi-read-disc-info.h" #include "scsi-read-toc-pma-atip.h" #include "scsi-read-track-information.h" @@ -63,6 +64,17 @@ BraseroScsiTrackInfo *track_info, int *size, BraseroScsiErrCode *error); +BraseroScsiResult +brasero_mmc1_read_block (int fd, + gboolean user_data, + BraseroScsiBlockType type, + BraseroScsiBlockHeader header, + BraseroScsiBlockSubChannel channel, + int start, + int size, + unsigned char *block, + int buffer_len, + BraseroScsiErrCode *error); G_END_DECLS Modified: branches/brasero_0_7/src/scsi/scsi-opcodes.h ============================================================================== --- branches/brasero_0_7/src/scsi/scsi-opcodes.h (original) +++ branches/brasero_0_7/src/scsi/scsi-opcodes.h Mon Feb 4 21:24:15 2008 @@ -52,6 +52,8 @@ #define BRASERO_READ_SUB_CHANNEL_OPCODE 0x42 #define BRASERO_READ_MASTER_CUE_OPCODE 0x59 +#define BRASERO_READ_CD_OPCODE 0xBE + /** * MMC2 */ Modified: branches/brasero_0_7/src/scsi/scsi-read-toc-pma-atip.h ============================================================================== --- branches/brasero_0_7/src/scsi/scsi-read-toc-pma-atip.h (original) +++ branches/brasero_0_7/src/scsi/scsi-read-toc-pma-atip.h Mon Feb 4 21:24:15 2008 @@ -29,10 +29,7 @@ #ifndef _SCSI_READ_TOC_PMA_ATIP_H #define _SCSI_READ_TOC_PMA_ATIP_H -#ifdef __cplusplus -extern "C" -{ -#endif +G_BEGIN_DECLS #if G_BYTE_ORDER == G_LITTLE_ENDIAN @@ -328,8 +325,6 @@ #define BRASERO_SCSI_TRACK_LEADOUT_START 0xAA -#ifdef __cplusplus -} -#endif +G_END_DECLS #endif /* _SCSI_READ_TOC_PMA_ATIP_H */ Modified: branches/brasero_0_7/src/scsi/scsi-sense-data.c ============================================================================== --- branches/brasero_0_7/src/scsi/scsi-sense-data.c (original) +++ branches/brasero_0_7/src/scsi/scsi-sense-data.c Mon Feb 4 21:24:15 2008 @@ -39,7 +39,7 @@ * (defined in SCSI Primary command 3 / SPC specs) **/ -#define SENSE_DATA_KEY(sense) ((sense) ? (sense) [2] & 0xFF : 0x00) /* Sense code itself */ +#define SENSE_DATA_KEY(sense) ((sense) ? (sense) [2] & 0x0F : 0x00) /* Sense code itself */ #define SENSE_DATA_ASC(sense) ((sense) ? (sense) [12] : 0x00) /* Additional Sense Code */ #define SENSE_DATA_ASCQ(sense) ((sense) ? (sense) [13] : 0x00) /* Additional Sense Code Qualifier */ #define SENSE_DATA_ASC_ASCQ(sense) ((sense) ? (sense) [12] << 8 | (sense) [13] : 0x00) /* ASC and ASCQ combined */ @@ -60,6 +60,7 @@ #define ASC_ASCQ_CODE_INSUFFICIENT_TIME_FOR_OPERATION 0x2E00 #define ASC_ASCQ_CODE_KEY_NOT_ESTABLISHED 0x6F02 #define ASC_ASCQ_CODE_SCRAMBLED_SECTOR 0x6F03 +#define ASC_ASCQ_CODE_INVALID_TRACK_MODE 0x6400 /** * error processing @@ -73,7 +74,7 @@ if (!sense_data) return; - printf("Sense key: 0x%02x ", sense_data [0]); + printf("Sense buffer: 0x%02x ", sense_data [0]); for (i = 1; i < BRASERO_SENSE_DATA_SIZE; i ++) printf("0x%02x ", sense_data [i]); @@ -138,6 +139,10 @@ BRASERO_SCSI_SET_ERRCODE (err, BRASERO_SCSI_KEY_NOT_ESTABLISHED); break; + case ASC_ASCQ_CODE_INVALID_TRACK_MODE: + BRASERO_SCSI_SET_ERRCODE (err, BRASERO_SCSI_INVALID_TRACK_MODE); + break; + default: res = brasero_sense_data_unknown (sense_data, err); break; Modified: branches/brasero_0_7/src/scsi/scsi-utils.h ============================================================================== --- branches/brasero_0_7/src/scsi/scsi-utils.h (original) +++ branches/brasero_0_7/src/scsi/scsi-utils.h Mon Feb 4 21:24:15 2008 @@ -40,6 +40,7 @@ #define BRASERO_SET_BCD(data, num) (uchar)(data)=((((num)/10)<<4)&0xF0)|((num)-(((num)/10)*10)) #define BRASERO_SET_16(data, num) (data)[0]=(((num)>>8)&0xFF);(data)[1]=(uchar)((num)&0xFF) +#define BRASERO_SET_24(data, num) (data)[0]=(uchar)(((num)>>16)&0xFF);(data)[1]=(uchar)(((num)>>8)&0xFF);(data)[2]=(uchar)((num)&0xFF); #define BRASERO_SET_32(data, num) (data)[0]=(uchar)(((num)>>24)&0xFF);(data)[1]=(uchar)(((num)>>16)&0xFF);(data)[2]=(uchar)(((num)>>8)&0xFF);(data)[3]=(uchar)((num)&0xFF) #define BRASERO_MSF_TO_LBA(minute, second, frame) (((minute)*60+(second))*75+frame) _______________________________________________ SVN-commits-list mailing list (read only) http://mail.gnome.org/mailman/listinfo/svn-commits-list Want to limit the commits to a few modules? Go to above URL, log in to edit your options and select the modules ('topics') you want. Module maintainer? It is possible to set the reply-to to your development mailing list. Email [EMAIL PROTECTED] if interested.