brasero r969 - in trunk: . src
- From: philippr svn gnome org
- To: svn-commits-list gnome org
- Subject: brasero r969 - in trunk: . src
- Date: Thu, 10 Jul 2008 11:40:27 +0000 (UTC)
Author: philippr
Date: Thu Jul 10 11:40:27 2008
New Revision: 969
URL: http://svn.gnome.org/viewvc/brasero?rev=969&view=rev
Log:
Fix for #535835 â TEAC R55S - can\'t burn CD-R
Now that the medium is identified, try to get its contents.
* src/burn-medium.c (brasero_medium_get_page_2A_max_speed),
(brasero_medium_track_get_info),
(brasero_medium_add_DVD_plus_RW_leadout),
(brasero_medium_get_sessions_info), (brasero_medium_get_contents),
(brasero_medium_check_BCD_use),
(brasero_medium_old_drive_get_disc_info),
(brasero_medium_check_old_drive), (brasero_medium_get_medium_type),
(brasero_medium_get_css_feature):
* src/scsi-sg.c (brasero_scsi_command_issue_sync):
Modified:
trunk/ChangeLog
trunk/src/burn-medium.c
trunk/src/scsi-sg.c
Modified: trunk/src/burn-medium.c
==============================================================================
--- trunk/src/burn-medium.c (original)
+++ trunk/src/burn-medium.c Thu Jul 10 11:40:27 2008
@@ -873,374 +873,6 @@
g_free (data);
return BRASERO_BURN_OK;
}
-
-static BraseroBurnResult
-brasero_medium_old_drive_get_disc_info (BraseroMedium *self,
- BraseroDeviceHandle *handle,
- BraseroScsiErrCode *code)
-{
- int size;
- BraseroScsiResult result;
- BraseroMediumPrivate *priv;
- BraseroScsiDiscInfoStd *info = NULL;
-
- BRASERO_BURN_LOG ("Retrieving media status for old drive");
-
- priv = BRASERO_MEDIUM_PRIVATE (self);
-
- result = brasero_mmc1_read_disc_information_std (handle,
- &info,
- &size,
- code);
- if (result != BRASERO_SCSI_OK) {
- g_free (info);
-
- BRASERO_BURN_LOG ("READ DISC INFORMATION failed for old drive");
- return BRASERO_BURN_ERR;
- }
-
- /* Try to identify the type: can only be CDROM CDR CDRW.
- * NOTE: since there is no way to distinguish a CDROM and a closed CDR
- * if the disc is closed we set it as CDROM (except if it's RW). */
- if (info->erasable)
- priv->info = BRASERO_MEDIUM_CDRW;
- else if (info->status == BRASERO_SCSI_DISC_FINALIZED)
- priv->info = BRASERO_MEDIUM_CDROM;
- else
- priv->info = BRASERO_MEDIUM_CDR;
-
- if (info->status == BRASERO_SCSI_DISC_EMPTY) {
- priv->info |= BRASERO_MEDIUM_BLANK;
- priv->block_size = 2048;
- priv->next_wr_add = 0;
- BRASERO_BURN_LOG ("Empty media (old drive)");
- }
- else if (info->status == BRASERO_SCSI_DISC_INCOMPLETE) {
- priv->info |= BRASERO_MEDIUM_APPENDABLE;
- priv->block_size = 2048;
- priv->next_wr_add = 0;
- BRASERO_BURN_LOG ("Appendable media (old drive)");
- }
- else if (info->status == BRASERO_SCSI_DISC_FINALIZED) {
- priv->info |= BRASERO_MEDIUM_CLOSED;
- BRASERO_BURN_LOG ("Closed media (old drive)");
- }
-
- return BRASERO_BURN_OK;
-}
-
-static BraseroBurnResult
-brasero_medium_check_old_drive (BraseroMedium *self,
- BraseroDeviceHandle *handle,
- BraseroScsiErrCode *code)
-{
- gchar *model;
- BraseroMediumPrivate *priv;
-
- priv = BRASERO_MEDIUM_PRIVATE (self);
-
- model = brasero_drive_get_display_name (priv->drive);
- if (!model)
- return BRASERO_BURN_ERR;
-
- if (!strcmp (model, "CD-R55S")) {
- g_free (model);
- priv->max_rd = BRASERO_SPEED_TO_RATE_CD (12);
- priv->max_wrt = BRASERO_SPEED_TO_RATE_CD (4);
- return brasero_medium_old_drive_get_disc_info (self,
- handle,
- code);
- }
-
- BRASERO_BURN_LOG ("Not an old drive model");
-
- return BRASERO_BURN_ERR;
-}
-
-static BraseroBurnResult
-brasero_medium_get_medium_type (BraseroMedium *self,
- BraseroDeviceHandle *handle,
- BraseroScsiErrCode *code)
-{
- BraseroScsiGetConfigHdr *hdr = NULL;
- BraseroMediumPrivate *priv;
- BraseroScsiResult result;
- int size;
-
- BRASERO_BURN_LOG ("Retrieving media profile");
-
- priv = BRASERO_MEDIUM_PRIVATE (self);
- result = brasero_mmc2_get_configuration_feature (handle,
- BRASERO_SCSI_FEAT_REAL_TIME_STREAM,
- &hdr,
- &size,
- code);
- if (result != BRASERO_SCSI_OK) {
- BraseroScsiAtipData *data = NULL;
- int size = 0;
-
- BRASERO_BURN_LOG ("GET CONFIGURATION failed");
-
- /* This could be a MMC1 drive since this command was
- * introduced in MMC2 and is supported onward. So it
- * has to be a CD (R/RW). The rest of the information
- * will be provided by read_disc_information. */
-
- /* retrieve the speed */
- result = brasero_medium_get_page_2A_max_speed (self,
- handle,
- code);
-
- /* If this fails it means that this drive is probably older than
- * MMC1 spec or does not conform to it. Try our last chance. */
- if (result != BRASERO_BURN_OK)
- return brasero_medium_check_old_drive (self,
- handle,
- code);
-
- /* The only thing here left to determine is if that's a WRITABLE
- * or a REWRITABLE. To determine that information, we need to
- * read TocPmaAtip. It if fails that's a ROM, if it succeeds.
- * No need to set error code since we consider that it's a ROM
- * if a failure happens. */
- result = brasero_mmc1_read_atip (handle,
- &data,
- &size,
- NULL);
- if (result != BRASERO_SCSI_OK) {
- /* CDROM */
- priv->info = BRASERO_MEDIUM_CDROM;
- priv->type = types [1];
- priv->icon = icons [1];
- }
- else {
- /* check the size of the structure: it must be at least 8 bytes long */
- if (size < 8) {
- if (size)
- g_free (data);
-
- BRASERO_BURN_LOG ("READ ATIP failed (wrong size)");
- return BRASERO_BURN_ERR;
- }
-
- if (data->desc->erasable) {
- /* CDRW */
- priv->info = BRASERO_MEDIUM_CDRW;
- priv->type = types [3];
- priv->icon = icons [3];
- }
- else {
- /* CDR */
- priv->info = BRASERO_MEDIUM_CDR;
- priv->type = types [2];
- priv->icon = icons [2];
- }
-
- g_free (data);
- }
-
- return result;
- }
-
- switch (BRASERO_GET_16 (hdr->current_profile)) {
- case BRASERO_SCSI_PROF_CDROM:
- priv->info = BRASERO_MEDIUM_CDROM;
- priv->type = types [1];
- priv->icon = icons [1];
- break;
-
- case BRASERO_SCSI_PROF_CDR:
- priv->info = BRASERO_MEDIUM_CDR;
- priv->type = types [2];
- priv->icon = icons [2];
- break;
-
- case BRASERO_SCSI_PROF_CDRW:
- priv->info = BRASERO_MEDIUM_CDRW;
- priv->type = types [3];
- priv->icon = icons [3];
- break;
-
- case BRASERO_SCSI_PROF_DVD_ROM:
- priv->info = BRASERO_MEDIUM_DVD_ROM;
- priv->type = types [4];
- priv->icon = icons [4];
- break;
-
- case BRASERO_SCSI_PROF_DVD_R:
- priv->info = BRASERO_MEDIUM_DVDR;
- priv->type = types [5];
- priv->icon = icons [5];
- break;
-
- case BRASERO_SCSI_PROF_DVD_RW_RESTRICTED:
- priv->info = BRASERO_MEDIUM_DVDRW_RESTRICTED;
- priv->type = types [6];
- priv->icon = icons [6];
- break;
-
- case BRASERO_SCSI_PROF_DVD_RW_SEQUENTIAL:
- priv->info = BRASERO_MEDIUM_DVDRW;
- priv->type = types [6];
- priv->icon = icons [6];
- break;
-
- case BRASERO_SCSI_PROF_DVD_R_PLUS:
- priv->info = BRASERO_MEDIUM_DVDR_PLUS;
- priv->type = types [7];
- priv->icon = icons [7];
- break;
-
- case BRASERO_SCSI_PROF_DVD_RW_PLUS:
- priv->info = BRASERO_MEDIUM_DVDRW_PLUS;
- priv->type = types [8];
- priv->icon = icons [7];
- break;
-
- case BRASERO_SCSI_PROF_DVD_R_PLUS_DL:
- priv->info = BRASERO_MEDIUM_DVDR_PLUS_DL;
- priv->type = types [9];
- priv->icon = icons [7];
- break;
-
- case BRASERO_SCSI_PROF_DVD_RW_PLUS_DL:
- priv->info = BRASERO_MEDIUM_DVDRW_PLUS_DL;
- priv->type = types [10];
- priv->icon = icons [7];
- break;
-
- case BRASERO_SCSI_PROF_DVD_R_DL_SEQUENTIAL:
- priv->info = BRASERO_MEDIUM_DVDR_DL;
- priv->type = types [11];
- priv->icon = icons [5];
- break;
-
- case BRASERO_SCSI_PROF_DVD_R_DL_JUMP:
- priv->info = BRASERO_MEDIUM_DVDR_JUMP_DL;
- priv->type = types [11];
- priv->icon = icons [5];
- break;
-
- /* WARNING: these types are recognized, no more */
- case BRASERO_SCSI_PROF_BD_ROM:
- priv->info = BRASERO_MEDIUM_BD_ROM;
- priv->type = types [13];
- priv->icon = icons [4];
- break;
-
- case BRASERO_SCSI_PROF_BR_R_SEQUENTIAL:
- priv->info = BRASERO_MEDIUM_BDR_SRM;
- priv->type = types [14];
- priv->icon = icons [5];
- break;
-
- case BRASERO_SCSI_PROF_BR_R_RANDOM:
- priv->info = BRASERO_MEDIUM_BDR_RANDOM;
- priv->type = types [14];
- priv->icon = icons [5];
- break;
-
- case BRASERO_SCSI_PROF_BD_RW:
- priv->info = BRASERO_MEDIUM_BDRW;
- priv->type = types [15];
- priv->icon = icons [6];
- break;
-
- case BRASERO_SCSI_PROF_DVD_RAM:
- priv->info = BRASERO_MEDIUM_DVD_RAM;
- priv->type = types [12];
- priv->icon = icons [8];
- break;
-
- case BRASERO_SCSI_PROF_NON_REMOVABLE:
- case BRASERO_SCSI_PROF_REMOVABLE:
- case BRASERO_SCSI_PROF_MO_ERASABLE:
- case BRASERO_SCSI_PROF_MO_WRITE_ONCE:
- case BRASERO_SCSI_PROF_MO_ADVANCED_STORAGE:
- case BRASERO_SCSI_PROF_DDCD_ROM:
- case BRASERO_SCSI_PROF_DDCD_R:
- case BRASERO_SCSI_PROF_DDCD_RW:
- case BRASERO_SCSI_PROF_HD_DVD_ROM:
- case BRASERO_SCSI_PROF_HD_DVD_R:
- case BRASERO_SCSI_PROF_HD_DVD_RAM:
- priv->info = BRASERO_MEDIUM_UNSUPPORTED;
- priv->icon = icons [0];
- g_free (hdr);
- return BRASERO_BURN_NOT_SUPPORTED;
- }
-
- /* try all SCSI functions to get write/read speeds in order */
- if (hdr->desc->add_len >= sizeof (BraseroScsiRTStreamDesc)) {
- BraseroScsiRTStreamDesc *stream;
-
- /* means it's at least an MMC3 drive */
- stream = (BraseroScsiRTStreamDesc *) hdr->desc->data;
- if (stream->wrt_spd) {
- result = brasero_medium_get_speed_mmc3 (self, handle, code);
- if (result == BRASERO_BURN_OK)
- goto end;
- }
-
- if (stream->mp2a) {
- result = brasero_medium_get_page_2A_write_speed_desc (self, handle, code);
- if (result == BRASERO_BURN_OK)
- goto end;
- }
- }
-
- /* fallback for speeds */
- result = brasero_medium_get_page_2A_max_speed (self, handle, code);
-
-end:
-
- g_free (hdr);
-
- if (result != BRASERO_BURN_OK)
- return result;
-
- return BRASERO_BURN_OK;
-}
-
-static BraseroBurnResult
-brasero_medium_get_css_feature (BraseroMedium *self,
- BraseroDeviceHandle *handle,
- BraseroScsiErrCode *code)
-{
- BraseroScsiGetConfigHdr *hdr = NULL;
- BraseroMediumPrivate *priv;
- BraseroScsiResult result;
- int size;
-
- priv = BRASERO_MEDIUM_PRIVATE (self);
-
- BRASERO_BURN_LOG ("Testing for Css encrypted media");
- result = brasero_mmc2_get_configuration_feature (handle,
- BRASERO_SCSI_FEAT_DVD_CSS,
- &hdr,
- &size,
- code);
- if (result != BRASERO_SCSI_OK) {
- g_free (hdr);
-
- BRASERO_BURN_LOG ("GET CONFIGURATION failed");
- return BRASERO_BURN_ERR;
- }
-
- if (hdr->desc->add_len < sizeof (BraseroScsiDVDCssDesc)) {
- g_free (hdr);
- return BRASERO_BURN_OK;
- }
-
- /* here we just need to see if this feature is current or not */
- if (hdr->desc->current) {
- priv->info |= BRASERO_MEDIUM_PROTECTED;
- BRASERO_BURN_LOG ("media is Css protected");
- }
-
- g_free (hdr);
- return BRASERO_BURN_OK;
-}
-
/**
* Functions to get information about disc contents
*/
@@ -1470,21 +1102,278 @@
}
- if (track_info.next_wrt_address_valid)
- priv->next_wr_add = BRASERO_GET_32 (track_info.next_wrt_address);
-
- BRASERO_BURN_LOG ("Track %i (session %i): type = %i start = %llu size = %llu",
- track_num,
- track->session,
- track->type,
- track->start,
- track->blocks_num);
+ if (track_info.next_wrt_address_valid)
+ priv->next_wr_add = BRASERO_GET_32 (track_info.next_wrt_address);
+
+ BRASERO_BURN_LOG ("Track %i (session %i): type = %i start = %llu size = %llu",
+ track_num,
+ track->session,
+ track->type,
+ track->start,
+ track->blocks_num);
+
+ return BRASERO_BURN_OK;
+}
+
+/**
+ * NOTE: for DVD-R multisession we lose 28688 blocks for each session
+ * so the capacity is the addition of all session sizes + 28688 for each
+ * For all multisession DVD-/+R and CDR-RW the remaining size is given
+ * in the leadout. One exception though with DVD+/-RW.
+ */
+
+static void
+brasero_medium_add_DVD_plus_RW_leadout (BraseroMedium *self,
+ gint32 start)
+{
+ BraseroMediumTrack *leadout;
+ BraseroMediumPrivate *priv;
+
+ priv = BRASERO_MEDIUM_PRIVATE (self);
+
+ leadout = g_new0 (BraseroMediumTrack, 1);
+ priv->tracks = g_slist_append (priv->tracks, leadout);
+
+ leadout->start = start;
+ leadout->type = BRASERO_MEDIUM_TRACK_LEADOUT;
+
+ /* we fabricate the leadout here. We don't really need one in
+ * fact since it is always at the last sector whatever the
+ * amount of data written. So we need in fact to read the file
+ * system and get the last sector from it. Hopefully it won't be
+ * buggy */
+ priv->next_wr_add = 0;
+
+ leadout->blocks_num = priv->block_num;
+ if (g_slist_length (priv->tracks) > 1) {
+ BraseroMediumTrack *track;
+
+ track = priv->tracks->data;
+ leadout->blocks_num -= ((track->blocks_num > 300) ? track->blocks_num : 300);
+ }
+ BRASERO_BURN_LOG ("Adding fabricated leadout start = %llu length = %llu",
+ leadout->start,
+ leadout->blocks_num);
+}
+
+static BraseroBurnResult
+brasero_medium_get_sessions_info (BraseroMedium *self,
+ BraseroDeviceHandle *handle,
+ BraseroScsiErrCode *code)
+{
+ int num, i, size;
+ gboolean multisession;
+ BraseroScsiResult result;
+ BraseroScsiTocDesc *desc;
+ BraseroMediumPrivate *priv;
+ BraseroScsiFormattedTocData *toc = NULL;
+
+ BRASERO_BURN_LOG ("Reading Toc");
+
+ priv = BRASERO_MEDIUM_PRIVATE (self);
+ result = brasero_mmc1_read_toc_formatted (handle,
+ 0,
+ &toc,
+ &size,
+ code);
+ if (result != BRASERO_SCSI_OK) {
+ g_free (toc);
+
+ BRASERO_BURN_LOG ("READ TOC failed");
+ return BRASERO_BURN_ERR;
+ }
+
+ num = (size - sizeof (BraseroScsiFormattedTocData)) /
+ sizeof (BraseroScsiTocDesc);
+
+ /* remove 1 for leadout */
+ multisession = (priv->info & BRASERO_MEDIUM_APPENDABLE) || (num -1) != 1;
+
+ BRASERO_BURN_LOG ("%i track(s) found", num);
+
+ desc = toc->desc;
+ for (i = 0; i < num; i ++, desc ++) {
+ BraseroMediumTrack *track;
+
+ if (desc->track_num == BRASERO_SCSI_TRACK_LEADOUT_START)
+ break;
+
+ track = g_new0 (BraseroMediumTrack, 1);
+ priv->tracks = g_slist_prepend (priv->tracks, track);
+ track->start = BRASERO_GET_32 (desc->track_start);
+
+ /* we shouldn't request info on a track if the disc is closed */
+ if (desc->control & BRASERO_SCSI_TRACK_COPY)
+ track->type |= BRASERO_MEDIUM_TRACK_COPY;
+
+ if (!(desc->control & BRASERO_SCSI_TRACK_DATA)) {
+ track->type |= BRASERO_MEDIUM_TRACK_AUDIO;
+ priv->info |= BRASERO_MEDIUM_HAS_AUDIO;
+
+ if (desc->control & BRASERO_SCSI_TRACK_PREEMP)
+ track->type |= BRASERO_MEDIUM_TRACK_PREEMP;
+
+ if (desc->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 (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),
+ handle,
+ 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)
+ * which have only one track: the first. */
+ result = brasero_medium_track_volume_size (self,
+ track,
+ handle);
+ 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|
+ BRASERO_MEDIUM_HAS_DATA);
+
+ BRASERO_BURN_LOG ("Empty first session.");
+ }
+ else
+ priv->next_wr_add = 0;
+ }
+ }
+
+ /* put the tracks in the right order */
+ priv->tracks = g_slist_reverse (priv->tracks);
+
+ if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS)
+ || BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_RESTRICTED)) {
+ gint32 start;
+
+ /* It starts where the other one finishes */
+ if (priv->tracks)
+ start = BRASERO_GET_32 (desc->track_start);
+ else
+ start = 0;
+
+ brasero_medium_add_DVD_plus_RW_leadout (self, start);
+ }
+ else if (!(priv->info & BRASERO_MEDIUM_CLOSED)) {
+ BraseroMediumTrack *track;
+
+ /* we shouldn't request info on leadout if the disc is closed
+ * (except for DVD+/- (restricted) RW (see above) */
+ track = g_new0 (BraseroMediumTrack, 1);
+ priv->tracks = g_slist_append (priv->tracks, track);
+ track->start = BRASERO_GET_32 (desc->track_start);
+ track->type = BRASERO_MEDIUM_TRACK_LEADOUT;
+
+ brasero_medium_track_get_info (self,
+ FALSE,
+ track,
+ g_slist_length (priv->tracks),
+ handle,
+ code);
+ }
+
+ g_free (toc);
+
+ return BRASERO_BURN_OK;
+}
+
+static BraseroBurnResult
+brasero_medium_get_contents (BraseroMedium *self,
+ BraseroDeviceHandle *handle,
+ BraseroScsiErrCode *code)
+{
+ int size;
+ BraseroScsiResult result;
+ BraseroMediumPrivate *priv;
+ BraseroScsiDiscInfoStd *info = NULL;
+
+ BRASERO_BURN_LOG ("Retrieving media status");
+
+ priv = BRASERO_MEDIUM_PRIVATE (self);
+
+ result = brasero_mmc1_read_disc_information_std (handle,
+ &info,
+ &size,
+ code);
+ if (result != BRASERO_SCSI_OK) {
+ g_free (info);
+
+ BRASERO_BURN_LOG ("READ DISC INFORMATION failed");
+ return BRASERO_BURN_ERR;
+ }
+
+ if (info->erasable)
+ priv->info |= BRASERO_MEDIUM_REWRITABLE;
+
+ if (info->status == BRASERO_SCSI_DISC_EMPTY) {
+ BraseroMediumTrack *track;
+
+ BRASERO_BURN_LOG ("Empty media");
+
+ priv->info |= BRASERO_MEDIUM_BLANK;
+ priv->block_size = 2048;
+
+ if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS)
+ || BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_RESTRICTED))
+ brasero_medium_add_DVD_plus_RW_leadout (self, 0);
+ else {
+ track = g_new0 (BraseroMediumTrack, 1);
+ track->start = 0;
+ track->type = BRASERO_MEDIUM_TRACK_LEADOUT;
+ priv->tracks = g_slist_prepend (priv->tracks, track);
+
+ brasero_medium_track_get_info (self,
+ FALSE,
+ track,
+ 1,
+ handle,
+ code);
+ }
+ goto end;
+ }
+
+ if (info->status == BRASERO_SCSI_DISC_INCOMPLETE) {
+ priv->info |= BRASERO_MEDIUM_APPENDABLE;
+ BRASERO_BURN_LOG ("Appendable media");
+ }
+ else if (info->status == BRASERO_SCSI_DISC_FINALIZED) {
+ priv->info |= BRASERO_MEDIUM_CLOSED;
+ BRASERO_BURN_LOG ("Closed media");
+ }
+
+ result = brasero_medium_get_sessions_info (self, handle, code);
+
+end:
- return BRASERO_BURN_OK;
+ g_free (info);
+ return result;
}
#if 0
+/**
+ * These are special routines for old CD-R(W) drives that don't conform to MMC
+ */
+
static void
brasero_medium_set_track_type (BraseroMedium *self,
BraseroMediumTrack *track,
@@ -1615,6 +1504,7 @@
start_LBA -= 150;
start_BCD -= 150;
+/*
result = brasero_mmc1_read_track_info (handle,
track_num,
&track_info,
@@ -1623,10 +1513,10 @@
if (result != BRASERO_SCSI_OK) {
BRASERO_BURN_LOG ("READ TRACK INFO failed");
- /* Fallback to formatted toc */
- return 0;
+*/ /* Fallback to formatted toc */
+/* return 0;
}
-
+*/
track_start = BRASERO_GET_32 (track_info.start_lba);
BRASERO_BURN_LOG ("comparing DCB %i and LBA %i to real start address %i",
start_BCD, start_LBA, track_start);
@@ -1848,257 +1738,377 @@
#endif
-/**
- * NOTE: for DVD-R multisession we lose 28688 blocks for each session
- * so the capacity is the addition of all session sizes + 28688 for each
- * For all multisession DVD-/+R and CDR-RW the remaining size is given
- * in the leadout. One exception though with DVD+/-RW.
- */
-
-static void
-brasero_medium_add_DVD_plus_RW_leadout (BraseroMedium *self,
- gint32 start)
+static BraseroBurnResult
+brasero_medium_old_drive_get_disc_info (BraseroMedium *self,
+ BraseroDeviceHandle *handle,
+ BraseroScsiErrCode *code)
{
- BraseroMediumTrack *leadout;
+ int size;
+ BraseroScsiResult result;
BraseroMediumPrivate *priv;
+ BraseroScsiDiscInfoStd *info = NULL;
+
+ BRASERO_BURN_LOG ("Retrieving media status for old drive");
priv = BRASERO_MEDIUM_PRIVATE (self);
- leadout = g_new0 (BraseroMediumTrack, 1);
- priv->tracks = g_slist_append (priv->tracks, leadout);
+ result = brasero_mmc1_read_disc_information_std (handle,
+ &info,
+ &size,
+ code);
+ if (result != BRASERO_SCSI_OK) {
+ g_free (info);
+
+ BRASERO_BURN_LOG ("READ DISC INFORMATION failed for old drive");
+ return BRASERO_BURN_ERR;
+ }
- leadout->start = start;
- leadout->type = BRASERO_MEDIUM_TRACK_LEADOUT;
+ /* Try to identify the type: can only be CDROM CDR CDRW.
+ * NOTE: since there is no way to distinguish a CDROM and a closed CDR
+ * if the disc is closed we set it as CDROM (except if it's RW). */
+ if (info->erasable)
+ priv->info = BRASERO_MEDIUM_CDRW;
+ else if (info->status == BRASERO_SCSI_DISC_FINALIZED)
+ priv->info = BRASERO_MEDIUM_CDROM;
+ else
+ priv->info = BRASERO_MEDIUM_CDR;
- /* we fabricate the leadout here. We don't really need one in
- * fact since it is always at the last sector whatever the
- * amount of data written. So we need in fact to read the file
- * system and get the last sector from it. Hopefully it won't be
- * buggy */
- priv->next_wr_add = 0;
+ if (info->status == BRASERO_SCSI_DISC_EMPTY) {
+ priv->info |= BRASERO_MEDIUM_BLANK;
+ priv->block_size = 2048;
+ priv->next_wr_add = 0;
+ BRASERO_BURN_LOG ("Empty media (old drive)");
+ }
+ else if (info->status == BRASERO_SCSI_DISC_INCOMPLETE) {
+ priv->info |= BRASERO_MEDIUM_APPENDABLE;
+ priv->block_size = 2048;
+ priv->next_wr_add = 0;
+ BRASERO_BURN_LOG ("Appendable media (old drive)");
+ }
+ else if (info->status == BRASERO_SCSI_DISC_FINALIZED) {
+ priv->info |= BRASERO_MEDIUM_CLOSED;
+ BRASERO_BURN_LOG ("Closed media (old drive)");
+ }
- leadout->blocks_num = priv->block_num;
- if (g_slist_length (priv->tracks) > 1) {
- BraseroMediumTrack *track;
+ /* get the contents */
+ result = brasero_medium_get_sessions_info (self, handle, code);
+ return result;
+}
- track = priv->tracks->data;
- leadout->blocks_num -= ((track->blocks_num > 300) ? track->blocks_num : 300);
+static BraseroBurnResult
+brasero_medium_check_old_drive (BraseroMedium *self,
+ BraseroDeviceHandle *handle,
+ BraseroScsiErrCode *code)
+{
+ gchar *model;
+ BraseroMediumPrivate *priv;
+
+ priv = BRASERO_MEDIUM_PRIVATE (self);
+
+ model = brasero_drive_get_display_name (priv->drive);
+ if (!model)
+ return BRASERO_BURN_ERR;
+
+ if (!strcmp (model, "CD-R55S")) {
+ g_free (model);
+ priv->max_rd = BRASERO_SPEED_TO_RATE_CD (12);
+ priv->max_wrt = BRASERO_SPEED_TO_RATE_CD (4);
+ return brasero_medium_old_drive_get_disc_info (self,
+ handle,
+ code);
}
- BRASERO_BURN_LOG ("Adding fabricated leadout start = %llu length = %llu",
- leadout->start,
- leadout->blocks_num);
+
+ BRASERO_BURN_LOG ("Not an old drive model");
+
+ return BRASERO_BURN_ERR;
}
+/**
+ * Some identification functions
+ */
+
static BraseroBurnResult
-brasero_medium_get_sessions_info (BraseroMedium *self,
- BraseroDeviceHandle *handle,
- BraseroScsiErrCode *code)
+brasero_medium_get_medium_type (BraseroMedium *self,
+ BraseroDeviceHandle *handle,
+ BraseroScsiErrCode *code)
{
- int num, i, size;
- gboolean multisession;
- BraseroScsiResult result;
- BraseroScsiTocDesc *desc;
+ BraseroScsiGetConfigHdr *hdr = NULL;
BraseroMediumPrivate *priv;
- BraseroScsiFormattedTocData *toc = NULL;
+ BraseroScsiResult result;
+ int size;
- BRASERO_BURN_LOG ("Reading Toc");
+ BRASERO_BURN_LOG ("Retrieving media profile");
priv = BRASERO_MEDIUM_PRIVATE (self);
- result = brasero_mmc1_read_toc_formatted (handle,
- 0,
- &toc,
- &size,
- code);
+ result = brasero_mmc2_get_configuration_feature (handle,
+ BRASERO_SCSI_FEAT_REAL_TIME_STREAM,
+ &hdr,
+ &size,
+ code);
if (result != BRASERO_SCSI_OK) {
- g_free (toc);
+ BraseroScsiAtipData *data = NULL;
+ int size = 0;
- BRASERO_BURN_LOG ("READ TOC failed");
- return BRASERO_BURN_ERR;
+ BRASERO_BURN_LOG ("GET CONFIGURATION failed");
+
+ /* This could be a MMC1 drive since this command was
+ * introduced in MMC2 and is supported onward. So it
+ * has to be a CD (R/RW). The rest of the information
+ * will be provided by read_disc_information. */
+
+ /* retrieve the speed */
+ result = brasero_medium_get_page_2A_max_speed (self,
+ handle,
+ code);
+
+ /* If this fails it means that this drive is probably older than
+ * MMC1 spec or does not conform to it. Try our last chance. */
+ if (result != BRASERO_BURN_OK)
+ return brasero_medium_check_old_drive (self,
+ handle,
+ code);
+
+ /* The only thing here left to determine is if that's a WRITABLE
+ * or a REWRITABLE. To determine that information, we need to
+ * read TocPmaAtip. It if fails that's a ROM, if it succeeds.
+ * No need to set error code since we consider that it's a ROM
+ * if a failure happens. */
+ result = brasero_mmc1_read_atip (handle,
+ &data,
+ &size,
+ NULL);
+ if (result != BRASERO_SCSI_OK) {
+ /* CDROM */
+ priv->info = BRASERO_MEDIUM_CDROM;
+ priv->type = types [1];
+ priv->icon = icons [1];
+ }
+ else {
+ /* check the size of the structure: it must be at least 8 bytes long */
+ if (size < 8) {
+ if (size)
+ g_free (data);
+
+ BRASERO_BURN_LOG ("READ ATIP failed (wrong size)");
+ return BRASERO_BURN_ERR;
+ }
+
+ if (data->desc->erasable) {
+ /* CDRW */
+ priv->info = BRASERO_MEDIUM_CDRW;
+ priv->type = types [3];
+ priv->icon = icons [3];
+ }
+ else {
+ /* CDR */
+ priv->info = BRASERO_MEDIUM_CDR;
+ priv->type = types [2];
+ priv->icon = icons [2];
+ }
+
+ g_free (data);
+ }
+
+ return result;
}
- num = (size - sizeof (BraseroScsiFormattedTocData)) /
- sizeof (BraseroScsiTocDesc);
+ switch (BRASERO_GET_16 (hdr->current_profile)) {
+ case BRASERO_SCSI_PROF_CDROM:
+ priv->info = BRASERO_MEDIUM_CDROM;
+ priv->type = types [1];
+ priv->icon = icons [1];
+ break;
- /* remove 1 for leadout */
- multisession = (priv->info & BRASERO_MEDIUM_APPENDABLE) || (num -1) != 1;
+ case BRASERO_SCSI_PROF_CDR:
+ priv->info = BRASERO_MEDIUM_CDR;
+ priv->type = types [2];
+ priv->icon = icons [2];
+ break;
- BRASERO_BURN_LOG ("%i track(s) found", num);
+ case BRASERO_SCSI_PROF_CDRW:
+ priv->info = BRASERO_MEDIUM_CDRW;
+ priv->type = types [3];
+ priv->icon = icons [3];
+ break;
- desc = toc->desc;
- for (i = 0; i < num; i ++, desc ++) {
- BraseroMediumTrack *track;
+ case BRASERO_SCSI_PROF_DVD_ROM:
+ priv->info = BRASERO_MEDIUM_DVD_ROM;
+ priv->type = types [4];
+ priv->icon = icons [4];
+ break;
- if (desc->track_num == BRASERO_SCSI_TRACK_LEADOUT_START)
- break;
+ case BRASERO_SCSI_PROF_DVD_R:
+ priv->info = BRASERO_MEDIUM_DVDR;
+ priv->type = types [5];
+ priv->icon = icons [5];
+ break;
- track = g_new0 (BraseroMediumTrack, 1);
- priv->tracks = g_slist_prepend (priv->tracks, track);
- track->start = BRASERO_GET_32 (desc->track_start);
+ case BRASERO_SCSI_PROF_DVD_RW_RESTRICTED:
+ priv->info = BRASERO_MEDIUM_DVDRW_RESTRICTED;
+ priv->type = types [6];
+ priv->icon = icons [6];
+ break;
- /* we shouldn't request info on a track if the disc is closed */
- if (desc->control & BRASERO_SCSI_TRACK_COPY)
- track->type |= BRASERO_MEDIUM_TRACK_COPY;
+ case BRASERO_SCSI_PROF_DVD_RW_SEQUENTIAL:
+ priv->info = BRASERO_MEDIUM_DVDRW;
+ priv->type = types [6];
+ priv->icon = icons [6];
+ break;
- if (!(desc->control & BRASERO_SCSI_TRACK_DATA)) {
- track->type |= BRASERO_MEDIUM_TRACK_AUDIO;
- priv->info |= BRASERO_MEDIUM_HAS_AUDIO;
+ case BRASERO_SCSI_PROF_DVD_R_PLUS:
+ priv->info = BRASERO_MEDIUM_DVDR_PLUS;
+ priv->type = types [7];
+ priv->icon = icons [7];
+ break;
- if (desc->control & BRASERO_SCSI_TRACK_PREEMP)
- track->type |= BRASERO_MEDIUM_TRACK_PREEMP;
+ case BRASERO_SCSI_PROF_DVD_RW_PLUS:
+ priv->info = BRASERO_MEDIUM_DVDRW_PLUS;
+ priv->type = types [8];
+ priv->icon = icons [7];
+ break;
- if (desc->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;
+ case BRASERO_SCSI_PROF_DVD_R_PLUS_DL:
+ priv->info = BRASERO_MEDIUM_DVDR_PLUS_DL;
+ priv->type = types [9];
+ priv->icon = icons [7];
+ break;
- if (desc->control & BRASERO_SCSI_TRACK_DATA_INCREMENTAL)
- track->type |= BRASERO_MEDIUM_TRACK_INCREMENTAL;
- }
+ case BRASERO_SCSI_PROF_DVD_RW_PLUS_DL:
+ priv->info = BRASERO_MEDIUM_DVDRW_PLUS_DL;
+ priv->type = types [10];
+ priv->icon = icons [7];
+ break;
- brasero_medium_track_get_info (self,
- multisession,
- track,
- g_slist_length (priv->tracks),
- handle,
- code);
+ case BRASERO_SCSI_PROF_DVD_R_DL_SEQUENTIAL:
+ priv->info = BRASERO_MEDIUM_DVDR_DL;
+ priv->type = types [11];
+ priv->icon = icons [5];
+ break;
- if (desc->control & BRASERO_SCSI_TRACK_COPY)
- track->type |= BRASERO_MEDIUM_TRACK_COPY;
+ case BRASERO_SCSI_PROF_DVD_R_DL_JUMP:
+ priv->info = BRASERO_MEDIUM_DVDR_JUMP_DL;
+ priv->type = types [11];
+ priv->icon = icons [5];
+ break;
- if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS)
- || BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_RESTRICTED)) {
- BraseroBurnResult result;
+ /* WARNING: these types are recognized, no more */
+ case BRASERO_SCSI_PROF_BD_ROM:
+ priv->info = BRASERO_MEDIUM_BD_ROM;
+ priv->type = types [13];
+ priv->icon = icons [4];
+ break;
- /* a special case for these two kinds of media (DVD+RW)
- * which have only one track: the first. */
- result = brasero_medium_track_volume_size (self,
- track,
- handle);
- if (result != BRASERO_BURN_OK) {
- priv->tracks = g_slist_remove (priv->tracks, track);
- g_free (track);
+ case BRASERO_SCSI_PROF_BR_R_SEQUENTIAL:
+ priv->info = BRASERO_MEDIUM_BDR_SRM;
+ priv->type = types [14];
+ priv->icon = icons [5];
+ break;
- priv->info |= BRASERO_MEDIUM_BLANK;
- priv->info &= ~(BRASERO_MEDIUM_CLOSED|
- BRASERO_MEDIUM_HAS_DATA);
+ case BRASERO_SCSI_PROF_BR_R_RANDOM:
+ priv->info = BRASERO_MEDIUM_BDR_RANDOM;
+ priv->type = types [14];
+ priv->icon = icons [5];
+ break;
- BRASERO_BURN_LOG ("Empty first session.");
- }
- else
- priv->next_wr_add = 0;
- }
- }
+ case BRASERO_SCSI_PROF_BD_RW:
+ priv->info = BRASERO_MEDIUM_BDRW;
+ priv->type = types [15];
+ priv->icon = icons [6];
+ break;
- /* put the tracks in the right order */
- priv->tracks = g_slist_reverse (priv->tracks);
+ case BRASERO_SCSI_PROF_DVD_RAM:
+ priv->info = BRASERO_MEDIUM_DVD_RAM;
+ priv->type = types [12];
+ priv->icon = icons [8];
+ break;
+
+ case BRASERO_SCSI_PROF_NON_REMOVABLE:
+ case BRASERO_SCSI_PROF_REMOVABLE:
+ case BRASERO_SCSI_PROF_MO_ERASABLE:
+ case BRASERO_SCSI_PROF_MO_WRITE_ONCE:
+ case BRASERO_SCSI_PROF_MO_ADVANCED_STORAGE:
+ case BRASERO_SCSI_PROF_DDCD_ROM:
+ case BRASERO_SCSI_PROF_DDCD_R:
+ case BRASERO_SCSI_PROF_DDCD_RW:
+ case BRASERO_SCSI_PROF_HD_DVD_ROM:
+ case BRASERO_SCSI_PROF_HD_DVD_R:
+ case BRASERO_SCSI_PROF_HD_DVD_RAM:
+ priv->info = BRASERO_MEDIUM_UNSUPPORTED;
+ priv->icon = icons [0];
+ g_free (hdr);
+ return BRASERO_BURN_NOT_SUPPORTED;
+ }
- if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS)
- || BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_RESTRICTED)) {
- gint32 start;
+ /* try all SCSI functions to get write/read speeds in order */
+ if (hdr->desc->add_len >= sizeof (BraseroScsiRTStreamDesc)) {
+ BraseroScsiRTStreamDesc *stream;
- /* It starts where the other one finishes */
- if (priv->tracks)
- start = BRASERO_GET_32 (desc->track_start);
- else
- start = 0;
+ /* means it's at least an MMC3 drive */
+ stream = (BraseroScsiRTStreamDesc *) hdr->desc->data;
+ if (stream->wrt_spd) {
+ result = brasero_medium_get_speed_mmc3 (self, handle, code);
+ if (result == BRASERO_BURN_OK)
+ goto end;
+ }
- brasero_medium_add_DVD_plus_RW_leadout (self, start);
+ if (stream->mp2a) {
+ result = brasero_medium_get_page_2A_write_speed_desc (self, handle, code);
+ if (result == BRASERO_BURN_OK)
+ goto end;
+ }
}
- else if (!(priv->info & BRASERO_MEDIUM_CLOSED)) {
- BraseroMediumTrack *track;
- /* we shouldn't request info on leadout if the disc is closed
- * (except for DVD+/- (restricted) RW (see above) */
- track = g_new0 (BraseroMediumTrack, 1);
- priv->tracks = g_slist_append (priv->tracks, track);
- track->start = BRASERO_GET_32 (desc->track_start);
- track->type = BRASERO_MEDIUM_TRACK_LEADOUT;
+ /* fallback for speeds */
+ result = brasero_medium_get_page_2A_max_speed (self, handle, code);
- brasero_medium_track_get_info (self,
- FALSE,
- track,
- g_slist_length (priv->tracks),
- handle,
- code);
- }
+end:
- g_free (toc);
+ g_free (hdr);
+
+ if (result != BRASERO_BURN_OK)
+ return result;
return BRASERO_BURN_OK;
}
static BraseroBurnResult
-brasero_medium_get_contents (BraseroMedium *self,
- BraseroDeviceHandle *handle,
- BraseroScsiErrCode *code)
+brasero_medium_get_css_feature (BraseroMedium *self,
+ BraseroDeviceHandle *handle,
+ BraseroScsiErrCode *code)
{
- int size;
- BraseroScsiResult result;
+ BraseroScsiGetConfigHdr *hdr = NULL;
BraseroMediumPrivate *priv;
- BraseroScsiDiscInfoStd *info = NULL;
-
- BRASERO_BURN_LOG ("Retrieving media status");
+ BraseroScsiResult result;
+ int size;
priv = BRASERO_MEDIUM_PRIVATE (self);
- result = brasero_mmc1_read_disc_information_std (handle,
- &info,
+ BRASERO_BURN_LOG ("Testing for Css encrypted media");
+ result = brasero_mmc2_get_configuration_feature (handle,
+ BRASERO_SCSI_FEAT_DVD_CSS,
+ &hdr,
&size,
code);
if (result != BRASERO_SCSI_OK) {
- g_free (info);
-
- BRASERO_BURN_LOG ("READ DISC INFORMATION failed");
+ g_free (hdr);
+
+ BRASERO_BURN_LOG ("GET CONFIGURATION failed");
return BRASERO_BURN_ERR;
}
- if (info->erasable)
- priv->info |= BRASERO_MEDIUM_REWRITABLE;
-
- if (info->status == BRASERO_SCSI_DISC_EMPTY) {
- BraseroMediumTrack *track;
-
- BRASERO_BURN_LOG ("Empty media");
-
- priv->info |= BRASERO_MEDIUM_BLANK;
- priv->block_size = 2048;
-
- if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_PLUS)
- || BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DVDRW_RESTRICTED))
- brasero_medium_add_DVD_plus_RW_leadout (self, 0);
- else {
- track = g_new0 (BraseroMediumTrack, 1);
- track->start = 0;
- track->type = BRASERO_MEDIUM_TRACK_LEADOUT;
- priv->tracks = g_slist_prepend (priv->tracks, track);
-
- brasero_medium_track_get_info (self,
- FALSE,
- track,
- 1,
- handle,
- code);
- }
- goto end;
+ if (hdr->desc->add_len < sizeof (BraseroScsiDVDCssDesc)) {
+ g_free (hdr);
+ return BRASERO_BURN_OK;
}
- if (info->status == BRASERO_SCSI_DISC_INCOMPLETE) {
- priv->info |= BRASERO_MEDIUM_APPENDABLE;
- BRASERO_BURN_LOG ("Appendable media");
- }
- else if (info->status == BRASERO_SCSI_DISC_FINALIZED) {
- priv->info |= BRASERO_MEDIUM_CLOSED;
- BRASERO_BURN_LOG ("Closed media");
+ /* here we just need to see if this feature is current or not */
+ if (hdr->desc->current) {
+ priv->info |= BRASERO_MEDIUM_PROTECTED;
+ BRASERO_BURN_LOG ("media is Css protected");
}
- result = brasero_medium_get_sessions_info (self, handle, code);
-
-end:
-
- g_free (info);
- return result;
+ g_free (hdr);
+ return BRASERO_BURN_OK;
}
static void
Modified: trunk/src/scsi-sg.c
==============================================================================
--- trunk/src/scsi-sg.c (original)
+++ trunk/src/scsi-sg.c Thu Jul 10 11:40:27 2008
@@ -110,8 +110,6 @@
buffer,
size);
- /* for the time being only sg driver is supported */
-
/* NOTE on SG_IO: only for TEST UNIT READY, REQUEST/MODE SENSE, INQUIRY,
* READ CAPACITY, READ BUFFER, READ and LOG SENSE are allowed with it */
res = ioctl (cmd->handle->fd, SG_IO, &transport);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]