brasero r629 - in branches/brasero_0_7: . src src/scsi



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)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]