Index: ChangeLog =================================================================== --- a/ChangeLog (revision 311) +++ b/ChangeLog (working copy) @@ -1,3 +1,30 @@ +2007-09-30 Luis Medinas + + * src/burn-medium.c: (brasero_medium_init_real): + + Revert broken merge. + +2007-09-28 Rouquier Philippe + + Increased debugging output for SCSI + +2007-09-25 Rouquier Philippe + + Backported changes from trunk as an attempt to fix some recurring scsi + errors + +2007-09-25 Rouquier Philippe + + fix stupid mistake in scsi error handling + +2007-09-24 Rouquier Philippe + + fix 475442 + +2007-09-24 Rouquier Philippe + + fix 465203 + 2007-08-25 Rouquier Philippe fixes for libisofs 0.2.5 and 0.2.8 Index: src/burn.c =================================================================== --- a/src/burn.c (revision 311) +++ b/src/burn.c (working copy) @@ -943,7 +943,8 @@ GError **error) { gchar *failure; - gint64 media_size; + gint64 img_sectors; + gint64 media_sectors; BraseroBurnError berror; BraseroMediumInfo media; BraseroBurnResult result; @@ -1045,7 +1046,7 @@ * one exception if we don't have enough space left on * the disc. * NOTE: if MERGE or APPEND flag is on then don't check - */ + * NOTE: it's safe to compare size in bytes here */ NCB_MEDIA_GET_FREE_SPACE (drive, &size, NULL); if (!(flags & (BRASERO_BURN_FLAG_MERGE|BRASERO_BURN_FLAG_APPEND)) && size > burn->priv->image_size @@ -1106,17 +1107,36 @@ } } - /* we check that the image will fit on the media */ + /* we check that the image will fit on the media + * NOTE: we must use the sectors for comparison */ if (flags & (BRASERO_BURN_FLAG_MERGE|BRASERO_BURN_FLAG_APPEND)) - NCB_MEDIA_GET_FREE_SPACE (drive, &media_size, NULL); + NCB_MEDIA_GET_FREE_SPACE (drive, NULL, &media_sectors); else - NCB_MEDIA_GET_CAPACITY (drive, &media_size, NULL); + NCB_MEDIA_GET_CAPACITY (drive, NULL, &media_sectors); + if (source->type == BRASERO_TRACK_SOURCE_DATA) + img_sectors = burn->priv->image_size / 2048; + else if (source->type == BRASERO_TRACK_SOURCE_AUDIO) + img_sectors = burn->priv->image_size / 2352; + else if (source->type == BRASERO_TRACK_SOURCE_IMAGE) { + if (source->format == BRASERO_IMAGE_FORMAT_CLONE) + img_sectors = burn->priv->image_size / 2448; + else if (source->format == BRASERO_IMAGE_FORMAT_CUE + || source->format == BRASERO_IMAGE_FORMAT_CDRDAO) + img_sectors = burn->priv->image_size / 2352; + else + img_sectors = burn->priv->image_size / 2048; + } + else if (source->type == BRASERO_TRACK_SOURCE_DISC) + NCB_MEDIA_GET_DATA_SIZE (source->contents.drive.disc, NULL, &img_sectors); + else + img_sectors = 0; + /* NOTE: this is useful only for reloads since otherwise we still don't * know what's the image size yet */ if (!(flags & BRASERO_BURN_FLAG_OVERBURN) && (flags & BRASERO_BURN_FLAG_CHECK_SIZE) - && media_size < burn->priv->image_size) { + && media_sectors < img_sectors) { /* This is a recoverable error so try to ask the user again */ result = BRASERO_BURN_NEED_RELOAD; berror = BRASERO_BURN_ERROR_MEDIA_SPACE; @@ -1497,6 +1517,7 @@ } gnome_vfs_uri_unref (uri); + /* it's safe here to check with sizes */ if (burn->priv->image_size > vol_size) { g_set_error (error, BRASERO_BURN_ERROR, @@ -1824,6 +1845,7 @@ const gchar *output, GError **error) { + gint64 img_sectors; GError *ret_error = NULL; BraseroBurnResult result; @@ -1842,13 +1864,31 @@ } if (NCB_DRIVE_GET_TYPE (drive) != NAUTILUS_BURN_DRIVE_TYPE_FILE) { - gint64 media_size; + gint64 media_sectors; - NCB_MEDIA_GET_CAPACITY (drive, &media_size, NULL); + NCB_MEDIA_GET_CAPACITY (drive, NULL, &media_sectors); + if (source->type == BRASERO_TRACK_SOURCE_DATA) + img_sectors = burn->priv->image_size / 2048; + else if (source->type == BRASERO_TRACK_SOURCE_AUDIO) + img_sectors = burn->priv->image_size / 2352; + else if (source->type == BRASERO_TRACK_SOURCE_IMAGE) { + if (source->format == BRASERO_IMAGE_FORMAT_CLONE) + img_sectors = burn->priv->image_size / 2448; + else if (source->format == BRASERO_IMAGE_FORMAT_CUE + || source->format == BRASERO_IMAGE_FORMAT_CDRDAO) + img_sectors = burn->priv->image_size / 2352; + else + img_sectors = burn->priv->image_size / 2048; + } + else if (source->type == BRASERO_TRACK_SOURCE_DISC) + NCB_MEDIA_GET_DATA_SIZE (source->contents.drive.disc, NULL, &img_sectors); + else + img_sectors = 0; + /* check that the image can fit on the media */ if (!(flags & BRASERO_BURN_FLAG_OVERBURN) - && media_size < burn->priv->image_size) { + && media_sectors < img_sectors) { /* This is a recoverable error so try to ask the user again */ result = brasero_burn_reload_dest_media (burn, BRASERO_BURN_ERROR_MEDIA_SPACE, Index: src/burn-medium.c =================================================================== --- a/src/burn-medium.c (revision 311) +++ b/src/burn-medium.c (working copy) @@ -308,6 +308,8 @@ priv = BRASERO_MEDIUM_PRIVATE (self); + BRASERO_BURN_LOG ("Retrieving capacity from atip"); + result = brasero_mmc1_read_atip (fd, &atip_data, sizeof (atip_data), @@ -336,6 +338,8 @@ BraseroScsiResult result; gint size; + BRASERO_BURN_LOG ("Retrieving format capacity"); + priv = BRASERO_MEDIUM_PRIVATE (self); result = brasero_mmc2_read_format_capacities (fd, &hdr, @@ -424,6 +428,8 @@ BraseroScsiWrtSpdDesc *desc; BraseroScsiGetPerfData *wrt_perf = NULL; + BRASERO_BURN_LOG ("Retrieving speed (Get Performance)"); + /* NOTE: this only work if there is RT streaming feature with * wspd bit set to 1. At least an MMC3 drive. */ priv = BRASERO_MEDIUM_PRIVATE (self); @@ -471,7 +477,7 @@ * function but don't report any speed. So if our top speed is 0 then * use the other way to get the speed. It was a Teac */ if (!priv->max_wrt) - return BRASERO_BURN_RETRY; + return BRASERO_BURN_ERR; return BRASERO_BURN_OK; } @@ -491,6 +497,8 @@ gint max_num; int size = 0; + BRASERO_BURN_LOG ("Retrieving speed (2A speeds)"); + priv = BRASERO_MEDIUM_PRIVATE (self); result = brasero_spc1_mode_sense_get_page (fd, BRASERO_SPC_PAGE_STATUS, @@ -506,6 +514,7 @@ page_2A = (BraseroScsiStatusPage *) &data->page; + /* FIXME: the following is not necessarily true */ if (size < sizeof (BraseroScsiStatusPage)) { g_free (data); @@ -554,6 +563,8 @@ BraseroScsiResult result; int size = 0; + BRASERO_BURN_LOG ("Retrieving speed (2A max)"); + priv = BRASERO_MEDIUM_PRIVATE (self); result = brasero_spc1_mode_sense_get_page (fd, @@ -590,11 +601,12 @@ BraseroScsiErrCode *code) { BraseroScsiGetConfigHdr *hdr = NULL; - BraseroScsiRTStreamDesc *stream; BraseroMediumPrivate *priv; BraseroScsiResult result; int size; + BRASERO_BURN_LOG ("Retrieving media profile"); + priv = BRASERO_MEDIUM_PRIVATE (self); result = brasero_mmc2_get_configuration_feature (fd, BRASERO_SCSI_FEAT_REAL_TIME_STREAM, @@ -749,39 +761,35 @@ return BRASERO_BURN_NOT_SUPPORTED; } - BRASERO_BURN_LOG ("medium is %d", priv->info); + /* try all SCSI functions to get write/read speeds in order */ + if (hdr->desc->add_len >= sizeof (BraseroScsiRTStreamDesc)) { + BraseroScsiRTStreamDesc *stream; - /* see how we should get the speeds */ - if (hdr->desc->add_len != sizeof (BraseroScsiRTStreamDesc)) { - g_free (hdr); + /* means it's at least an MMC3 drive */ + stream = (BraseroScsiRTStreamDesc *) hdr->desc->data; + if (stream->wrt_spd) { + result = brasero_medium_get_speed_mmc3 (self, fd, code); + if (result == BRASERO_BURN_OK) + goto end; + } - BRASERO_BURN_LOG ("wrong size for Stream descriptor"); - return BRASERO_BURN_ERR; + if (stream->mp2a) { + result = brasero_medium_get_page_2A_write_speed_desc (self, fd, code); + if (result == BRASERO_BURN_OK) + goto end; + } } - /* try all SCSI functions to get write/read speeds in order */ - stream = (BraseroScsiRTStreamDesc *) hdr->desc->data; - if (stream->wrt_spd) { - /* NOTE: the next function returns either OK or RETRY to make - * sure we always go and get over an error. There are other ways - * to get the information we want */ - result = brasero_medium_get_speed_mmc3 (self, fd, code); - if (result != BRASERO_BURN_RETRY) - goto end; - } + /* fallback for speeds */ + result = brasero_medium_get_page_2A_max_speed (self, fd, code); - if (stream->mp2a) - result = brasero_medium_get_page_2A_write_speed_desc (self, fd, code); - else - result = brasero_medium_get_page_2A_max_speed (self, fd, code); - end: g_free (hdr); if (result != BRASERO_BURN_OK) - return BRASERO_BURN_ERR; + return result; return BRASERO_BURN_OK; } @@ -797,6 +805,8 @@ int size; priv = BRASERO_MEDIUM_PRIVATE (self); + + BRASERO_BURN_LOG ("Testing for Css encrypted media"); result = brasero_mmc2_get_configuration_feature (fd, BRASERO_SCSI_FEAT_DVD_CSS, &hdr, @@ -809,14 +819,16 @@ return BRASERO_BURN_ERR; } - if (hdr->desc->add_len != sizeof (BraseroScsiDVDCssDesc)) { + if (hdr->desc->add_len < sizeof (BraseroScsiDVDCssDesc)) { g_free (hdr); - return BRASERO_BURN_ERR; + return BRASERO_BURN_OK; } /* here we just need to see if this feature is current or not */ - if (hdr->desc->current) + if (hdr->desc->current) { priv->info |= BRASERO_MEDIUM_PROTECTED; + BRASERO_BURN_LOG ("media is Css protected"); + } g_free (hdr); return BRASERO_BURN_OK; @@ -877,13 +889,26 @@ BraseroScsiTrackInfo track_info; BraseroMediumPrivate *priv; BraseroScsiResult result; + int size; + BRASERO_BURN_LOG ("Retrieving track information for %i", track_num); + priv = BRASERO_MEDIUM_PRIVATE (self); + /* at this point we know the type of the disc that's why we set the + * size according to this type. That may help to avoid outrange address + * errors. */ + if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_DL|BRASERO_MEDIUM_WRITABLE)) + size = 48; + else if (BRASERO_MEDIUM_IS (priv->info, BRASERO_MEDIUM_PLUS|BRASERO_MEDIUM_WRITABLE)) + size = 40; + else + size = 36; + result = brasero_mmc1_read_track_info (fd, track_num, &track_info, - sizeof (BraseroScsiTrackInfo), + &size, code); if (result != BRASERO_SCSI_OK) { @@ -921,6 +946,8 @@ BraseroMediumPrivate *priv; BraseroScsiFormattedTocData *toc = NULL; + BRASERO_BURN_LOG ("Reading toc"); + priv = BRASERO_MEDIUM_PRIVATE (self); result = brasero_mmc1_read_toc_formatted (fd, 0, @@ -937,6 +964,8 @@ num = (size - sizeof (BraseroScsiFormattedTocData)) / sizeof (BraseroScsiTocDesc); + BRASERO_BURN_LOG ("%i track(s) found", num); + desc = toc->desc; for (i = 0; i < num; i ++, desc ++) { BraseroMediumTrack *track; @@ -1056,6 +1085,8 @@ BraseroMediumPrivate *priv; BraseroScsiDiscInfoStd *info = NULL; + BRASERO_BURN_LOG ("Retrieving media status"); + priv = BRASERO_MEDIUM_PRIVATE (self); result = brasero_mmc1_read_disc_information_std (fd, @@ -1075,6 +1106,8 @@ if (info->status == BRASERO_SCSI_DISC_EMPTY) { BraseroMediumTrack *track; + BRASERO_BURN_LOG ("Empty media"); + priv->info |= BRASERO_MEDIUM_BLANK; priv->block_size = 2048; @@ -1086,8 +1119,12 @@ goto end; } - if (info->status == BRASERO_SCSI_DISC_INCOMPLETE) + 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) + BRASERO_BURN_LOG ("Closed media"); result = brasero_medium_get_sessions_info (self, fd, code); if (result != BRASERO_BURN_OK) @@ -1112,17 +1149,17 @@ if (result != BRASERO_BURN_OK) return; - if (priv->info & BRASERO_MEDIUM_DVD) { - result = brasero_medium_get_css_feature (object, fd, &code); - if (result != BRASERO_BURN_OK) - return; - } - result = brasero_medium_get_contents (object, fd, &code); if (result != BRASERO_BURN_OK) return; + /* assume that css feature is only for DVD-ROM which might be wrong but some drives + * wrongly reports that css is enabled for some blank DVD+R */ + if (BRASERO_MEDIUM_IS (priv->info, (BRASERO_MEDIUM_DVD/*|BRASERO_MEDIUM_ROM*/))) + brasero_medium_get_css_feature (object, fd, &code); + brasero_medium_get_capacity_by_type (object, fd, &code); + BRASERO_BURN_LOG ("media is %i", priv->info); } static gboolean Index: src/data-disc.c =================================================================== --- a/src/data-disc.c (revision 311) +++ b/src/data-disc.c (working copy) @@ -8048,6 +8048,9 @@ } if (disc->priv->is_loading) { + /* Translators: the following text is the reason why brasero + * failed to load a project: because it is already loading + * another project */ brasero_data_disc_import_session_error (disc, _("loading project")); return; } Index: src/scsi/scsi-read-track-information.c =================================================================== --- a/src/scsi/scsi-read-track-information.c (revision 311) +++ b/src/scsi/scsi-read-track-information.c (working copy) @@ -26,6 +26,8 @@ #include +#include "burn-debug.h" + #include "scsi-error.h" #include "scsi-utils.h" #include "scsi-base.h" @@ -85,115 +87,87 @@ #define BRASERO_SCSI_INCOMPLETE_TRACK 0xFF -/** - * - * NOTE: if media is a CD and track_num = 0 then returns leadin - * but since the other media don't have a leadin they error out. - * if track_num = 255 returns last incomplete track. - */ - -BraseroScsiResult -brasero_mmc1_read_track_info (int fd, - int track_num, - BraseroScsiTrackInfo *track_info, - int size, - BraseroScsiErrCode *error) +static BraseroScsiResult +brasero_read_track_info (BraseroRdTrackInfoCDB *cdb, + BraseroScsiTrackInfo *info, + int *size, + BraseroScsiErrCode *error) { - BraseroRdTrackInfoCDB *cdb; + BraseroScsiTrackInfo hdr; BraseroScsiResult res; + int datasize; - cdb = brasero_scsi_command_new (&info, fd); - cdb->addr_num_type = BRASERO_FIELD_TRACK_NUM; - BRASERO_SET_32 (cdb->blk_addr_trk_ses_num, track_num); - BRASERO_SET_16 (cdb->alloc_len, size); + if (!info || !size) { + BRASERO_SCSI_SET_ERRCODE (error, BRASERO_SCSI_BAD_ARGUMENT); + return BRASERO_SCSI_FAILURE; + } - memset (track_info, 0, sizeof (BraseroScsiTrackInfo)); - res = brasero_scsi_command_issue_sync (cdb, track_info, size, error); - brasero_scsi_command_free (cdb); - return res; -} + /* first ask the drive how long should the data be and then ... */ + datasize = 4; + memset (&hdr, 0, sizeof (info)); + BRASERO_SET_16 (cdb->alloc_len, datasize); + res = brasero_scsi_command_issue_sync (cdb, &hdr, datasize, error); + if (res) + return res; -BraseroScsiResult -brasero_mmc1_read_track_info_for_block (int fd, - int block, - BraseroScsiTrackInfo *track_info, - int size, - BraseroScsiErrCode *error) -{ - BraseroRdTrackInfoCDB *cdb; - BraseroScsiResult res; + /* ... check the size in case of a buggy firmware ... */ + if (BRASERO_GET_16 (hdr.len) + sizeof (hdr.len) >= datasize) { + datasize = BRASERO_GET_16 (hdr.len) + sizeof (hdr.len); - cdb = brasero_scsi_command_new (&info, fd); + if (datasize > *size) { + BRASERO_BURN_LOG ("Oversized data received (%i) setting to %i", datasize, *size); + datasize = *size; + } + else if (*size < datasize) { + BRASERO_BURN_LOG ("Oversized data required (%i) setting to %i", *size, datasize); + *size = datasize; + } + } + else { + BRASERO_BURN_LOG ("Undersized data received (%i) setting to %i", datasize, *size); + datasize = *size; + } - cdb->addr_num_type = BRASERO_FIELD_LBA; - BRASERO_SET_32 (cdb->blk_addr_trk_ses_num, block); - BRASERO_SET_16 (cdb->alloc_len, size); + /* ... and re-issue the command */ + memset (info, 0, sizeof (BraseroScsiTrackInfo)); + BRASERO_SET_16 (cdb->alloc_len, datasize); + res = brasero_scsi_command_issue_sync (cdb, info, datasize, error); - memset (track_info, 0, sizeof (BraseroScsiTrackInfo)); - res = brasero_scsi_command_issue_sync (cdb, track_info, size, error); - brasero_scsi_command_free (cdb); - return res; -} + if (!res) { + if (datasize != BRASERO_GET_16 (info->len) + sizeof (info->len)) + BRASERO_BURN_LOG ("Sizes mismatch asked %i / received %i", + datasize, + BRASERO_GET_16 (info->len) + sizeof (info->len)); -BraseroScsiResult -brasero_mmc1_read_session_first_track_info (int fd, - int session, - BraseroScsiTrackInfo *track_info, - int size, - BraseroScsiErrCode *error) -{ - BraseroRdTrackInfoCDB *cdb; - BraseroScsiResult res; + *size = MIN (datasize, BRASERO_GET_16 (info->len) + sizeof (info->len)); + } - cdb = brasero_scsi_command_new (&info, fd); - - BRASERO_SET_32 (cdb->blk_addr_trk_ses_num, session); - cdb->addr_num_type = BRASERO_FIELD_SESSION_NUM; - BRASERO_SET_16 (cdb->alloc_len, size); - - memset (track_info, 0, sizeof (BraseroScsiTrackInfo)); - res = brasero_scsi_command_issue_sync (cdb, track_info, size, error); - brasero_scsi_command_free (cdb); return res; } +/** + * + * NOTE: if media is a CD and track_num = 0 then returns leadin + * but since the other media don't have a leadin they error out. + * if track_num = 255 returns last incomplete track. + */ + BraseroScsiResult -brasero_mmc1_read_first_open_session_track_info (int fd, - BraseroScsiTrackInfo *track_info, - int size, - BraseroScsiErrCode *error) +brasero_mmc1_read_track_info (int fd, + int track_num, + BraseroScsiTrackInfo *track_info, + int *size, + BraseroScsiErrCode *error) { BraseroRdTrackInfoCDB *cdb; BraseroScsiResult res; cdb = brasero_scsi_command_new (&info, fd); cdb->addr_num_type = BRASERO_FIELD_TRACK_NUM; - BRASERO_SET_32 (cdb->blk_addr_trk_ses_num, BRASERO_SCSI_INCOMPLETE_TRACK); - BRASERO_SET_16 (cdb->alloc_len, size); + BRASERO_SET_32 (cdb->blk_addr_trk_ses_num, track_num); - memset (track_info, 0, sizeof (BraseroScsiTrackInfo)); - res = brasero_scsi_command_issue_sync (cdb, track_info, size, error); + res = brasero_read_track_info (cdb, track_info, size, error); brasero_scsi_command_free (cdb); - return res; -} -BraseroScsiResult -brasero_mmc5_read_first_open_session_track_info (int fd, - BraseroScsiTrackInfo *track_info, - int size, - BraseroScsiErrCode *error) -{ - BraseroRdTrackInfoCDB *cdb; - BraseroScsiResult res; - - cdb = brasero_scsi_command_new (&info, fd); - cdb->open = 1; - cdb->addr_num_type = BRASERO_FIELD_TRACK_NUM; - BRASERO_SET_32 (cdb->blk_addr_trk_ses_num, 1); - BRASERO_SET_16 (cdb->alloc_len, size); - - memset (track_info, 0, sizeof (BraseroScsiTrackInfo)); - res = brasero_scsi_command_issue_sync (cdb, track_info, size, error); - brasero_scsi_command_free (cdb); return res; } Index: src/scsi/scsi-read-track-information.h =================================================================== --- a/src/scsi/scsi-read-track-information.h (revision 311) +++ b/src/scsi/scsi-read-track-information.h (working copy) @@ -29,10 +29,7 @@ #ifndef _SCSI_READ_TRACK_INFORMATION_H #define _SCSI_READ_TRACK_INFORMATION_H -#ifdef __cplusplus -extern "C" -{ -#endif +G_BEGIN_DECLS typedef enum { BRASERO_SCSI_DATA_MODE_1 = 0x01, @@ -135,9 +132,7 @@ #define BRASERO_SCSI_TRACK_NUM_PTR(track) (((track)->track_num_high << 8) + (track)->track_num_low) #define BRASERO_SCSI_SESSION_NUM_PTR(track) (((track)->session_num_high << 8) + (track)->session_num_low) -#ifdef __cplusplus -} -#endif +G_END_DECLS #endif /* _SCSI_READ_TRACK_INFORMATION_H */ Index: src/scsi/scsi-utils.h =================================================================== --- a/src/scsi/scsi-utils.h (revision 311) +++ b/src/scsi/scsi-utils.h (working copy) @@ -55,7 +55,7 @@ strerror (errno)); \ } else { \ BRASERO_BURN_LOG ("SCSI command error: %s", \ - brasero_scsi_strerror (errno)); \ + brasero_scsi_strerror (code)); \ } \ if (err) \ *(err) = code; \ Index: src/scsi/scsi-read-disc-info.c =================================================================== --- a/src/scsi/scsi-read-disc-info.c (revision 311) +++ b/src/scsi/scsi-read-disc-info.c (working copy) @@ -30,6 +30,8 @@ #include +#include "burn-debug.h" + #include "scsi-error.h" #include "scsi-utils.h" #include "scsi-base.h" @@ -93,6 +95,7 @@ BraseroRdDiscInfoCDB *cdb; BraseroScsiResult res; int request_size; + int buffer_size; if (!info_return || !size) { BRASERO_SCSI_SET_ERRCODE (error, BRASERO_SCSI_BAD_ARGUMENT); @@ -122,16 +125,16 @@ goto end; } - if (request_size != BRASERO_GET_16 (buffer->len) + sizeof (buffer->len)) { - BRASERO_SCSI_SET_ERRCODE (error, BRASERO_SCSI_SIZE_MISMATCH); + buffer_size = BRASERO_GET_16 (buffer->len) + + sizeof (buffer->len); - res = BRASERO_SCSI_FAILURE; - g_free (buffer); - goto end; - } + if (request_size != buffer_size) + BRASERO_BURN_LOG ("Sizes mismatch asked %i / received %i", + request_size, + buffer_size); *info_return = buffer; - *size = request_size; + *size = MIN (request_size, buffer_size); end: Index: src/scsi/scsi-get-configuration.c =================================================================== --- a/src/scsi/scsi-get-configuration.c (revision 311) +++ b/src/scsi/scsi-get-configuration.c (working copy) @@ -26,6 +26,8 @@ #include +#include "burn-debug.h" + #include "scsi-error.h" #include "scsi-utils.h" #include "scsi-base.h" @@ -99,18 +101,29 @@ return BRASERO_SCSI_FAILURE; } + /* first issue the command once ... */ memset (&hdr, 0, sizeof (hdr)); - BRASERO_SET_16 (cdb->alloc_len, sizeof (hdr)); res = brasero_scsi_command_issue_sync (cdb, &hdr, sizeof (hdr), error); if (res) return res; - /* ... allocate a buffer and re-issue the command */ + /* ... check the size returned ... */ request_size = BRASERO_GET_32 (hdr.len) + G_STRUCT_OFFSET (BraseroScsiGetConfigHdr, len) + sizeof (hdr.len); + /* NOTE: if size is not valid use the maximum possible size */ + if ((request_size - sizeof (hdr)) % 8) { + BRASERO_BURN_LOG ("Unaligned data (%i) setting to max (65530)", request_size); + request_size = 65530; + } + else if (request_size <= sizeof (hdr)) { + BRASERO_BURN_LOG ("Undersized data (%i) setting to max (65530)", request_size); + request_size = 65530; + } + + /* ... allocate a buffer and re-issue the command */ buffer = (BraseroScsiGetConfigHdr *) g_new0 (uchar, request_size); BRASERO_SET_16 (cdb->alloc_len, request_size); @@ -125,16 +138,13 @@ G_STRUCT_OFFSET (BraseroScsiGetConfigHdr, len) + sizeof (hdr.len); - if (buffer_size != request_size) { - g_free (buffer); + if (buffer_size != request_size) + BRASERO_BURN_LOG ("Sizes mismatch asked %i / received %i", + request_size, + buffer_size); - BRASERO_SCSI_SET_ERRCODE (error, BRASERO_SCSI_SIZE_MISMATCH); - return BRASERO_SCSI_FAILURE; - } - *data = buffer; - *size = request_size; - + *size = MIN (buffer_size, request_size); return BRASERO_SCSI_OK; } @@ -148,34 +158,24 @@ BraseroGetConfigCDB *cdb; BraseroScsiResult res; + g_return_val_if_fail (data != NULL, BRASERO_SCSI_FAILURE); + g_return_val_if_fail (size != NULL, BRASERO_SCSI_FAILURE); + cdb = brasero_scsi_command_new (&info, fd); BRASERO_SET_16 (cdb->feature_num, type); cdb->returned_data = BRASERO_GET_CONFIG_RETURN_ONLY_FEATURE; res = brasero_get_configuration (cdb, data, size, error); brasero_scsi_command_free (cdb); - return res; -} -BraseroScsiResult -brasero_mmc2_get_configuration_all_features (int fd, - int only_current, - BraseroScsiGetConfigHdr **data, - int *size, - BraseroScsiErrCode *error) -{ - BraseroGetConfigCDB *cdb; - BraseroScsiResult res; + /* make sure the desc is the one we want */ + if ((*data) && BRASERO_GET_16 ((*data)->desc->code) != type) { + BRASERO_SCSI_SET_ERRCODE (error, BRASERO_SCSI_TYPE_MISMATCH); - cdb = brasero_scsi_command_new (&info, fd); - BRASERO_SET_16 (cdb->feature_num, BRASERO_SCSI_FEAT_PROFILES); + g_free (*data); + *size = 0; + return BRASERO_SCSI_FAILURE; + } - if (only_current) - cdb->returned_data = BRASERO_GET_CONFIG_RETURN_ALL_CURRENT; - else - cdb->returned_data = BRASERO_GET_CONFIG_RETURN_ALL_FEATURES; - - res = brasero_get_configuration (cdb, data, size, error); - brasero_scsi_command_free (cdb); return res; } Index: src/scsi/scsi-get-configuration.h =================================================================== --- a/src/scsi/scsi-get-configuration.h (revision 311) +++ b/src/scsi/scsi-get-configuration.h (working copy) @@ -177,7 +177,6 @@ uchar inq2 :1; uchar reserved0 :6; - uchar mmc4 [0]; uchar reserved1 [3]; }; Index: src/scsi/scsi-mmc1.h =================================================================== --- a/src/scsi/scsi-mmc1.h (revision 311) +++ b/src/scsi/scsi-mmc1.h (working copy) @@ -52,16 +52,10 @@ BraseroScsiErrCode *error); BraseroScsiResult -brasero_mmc1_read_first_open_session_track_info (int fd, - BraseroScsiTrackInfo *track_info, - int size, - BraseroScsiErrCode *error); - -BraseroScsiResult brasero_mmc1_read_track_info (int fd, int track_num, BraseroScsiTrackInfo *track_info, - int size, + int *size, BraseroScsiErrCode *error); G_END_DECLS Index: src/scsi/scsi-get-performance.c =================================================================== --- a/src/scsi/scsi-get-performance.c (revision 311) +++ b/src/scsi/scsi-get-performance.c (working copy) @@ -25,6 +25,8 @@ #include #include +#include "burn-debug.h" + #include "scsi-error.h" #include "scsi-utils.h" #include "scsi-command.h" @@ -112,22 +114,37 @@ return BRASERO_SCSI_FAILURE; } + /* Issue the command once to get the size ... */ memset (&hdr, 0, sizeof (hdr)); BRASERO_SET_16 (cdb->max_desc, 0); res = brasero_scsi_command_issue_sync (cdb, &hdr, sizeof (hdr), error); if (res) return res; - /* ... allocate a buffer and re-issue the command */ + /* ... check the request size ... */ request_size = BRASERO_GET_32 (hdr.len) + G_STRUCT_OFFSET (BraseroScsiGetPerfHdr, len) + sizeof (hdr.len); - desc_num = (request_size - sizeof (BraseroScsiGetPerfHdr)) / sizeof_descriptors; - BRASERO_SET_16 (cdb->max_desc, desc_num); + if (request_size > 2048) { + BRASERO_BURN_LOG ("Oversized data (%i) setting to max (2048)", request_size); + request_size = 2048; + } + else if ((request_size - sizeof (hdr)) % sizeof_descriptors) { + BRASERO_BURN_LOG ("Unaligned data (%i) setting to max (2048)", request_size); + request_size = 2048; + } + else if (request_size < sizeof (hdr)) { + BRASERO_BURN_LOG ("Undersized data (%i) setting to max (2048)", request_size); + request_size = 2048; + } + desc_num = (request_size - sizeof (hdr)) / sizeof_descriptors; + + /* ... allocate a buffer and re-issue the command */ buffer = (BraseroScsiGetPerfData *) g_new0 (uchar, request_size); + BRASERO_SET_16 (cdb->max_desc, desc_num); res = brasero_scsi_command_issue_sync (cdb, buffer, request_size, error); if (res) { g_free (buffer); @@ -139,48 +156,18 @@ G_STRUCT_OFFSET (BraseroScsiGetPerfHdr, len) + sizeof (buffer->hdr.len); - if (buffer_size != request_size) { - g_free (buffer); + if (request_size != buffer_size) + BRASERO_BURN_LOG ("Sizes mismatch asked %i / received %i", + request_size, + buffer_size); - BRASERO_SCSI_SET_ERRCODE (error, BRASERO_SCSI_SIZE_MISMATCH); - return BRASERO_SCSI_FAILURE; - } - *data = buffer; - *data_size = request_size; + *data_size = MIN (buffer_size, request_size); return res; } /** - * MMC2 command extension - */ - -BraseroScsiResult -brasero_mmc2_get_performance_perf (int fd, - BraseroScsiPerfParam param, - BraseroScsiGetPerfData **data, - int *size, - BraseroScsiErrCode *error) -{ - BraseroGetPerformanceCDB *cdb; - BraseroScsiResult res; - - cdb = brasero_scsi_command_new (&info, fd); - cdb->type = BRASERO_GET_PERFORMANCE_PERF_TYPE; - - if (param & BRASERO_SCSI_PERF_LIST) - cdb->except= 0x01; - - if (param & BRASERO_SCSI_PERF_WRITE) - cdb->write = 0x01; - - res = brasero_get_performance (cdb, sizeof (BraseroScsiPerfDesc), data, size, error); - brasero_scsi_command_free (cdb); - return res; -} - -/** * MMC3 command extension */ Index: src/scsi/scsi-get-performance.h =================================================================== --- a/src/scsi/scsi-get-performance.h (revision 311) +++ b/src/scsi/scsi-get-performance.h (working copy) @@ -29,10 +29,7 @@ #ifndef _BURN_GET_PERFORMANCE_H #define _BURN_GET_PERFORMANCE_H -#ifdef __cplusplus -extern "C" -{ -#endif +G_BEGIN_DECLS #if G_BYTE_ORDER == G_LITTLE_ENDIAN @@ -88,15 +85,7 @@ #endif -struct _BraseroScsiPerfDesc { - uchar start_lba [4]; - uchar start_perf [4]; - uchar end_lba [4]; - uchar end_perf [4]; -}; - typedef struct _BraseroScsiGetPerfHdr BraseroScsiGetPerfHdr; -typedef struct _BraseroScsiPerfDesc BraseroScsiPerfDesc; typedef struct _BraseroScsiWrtSpdDesc BraseroScsiWrtSpdDesc; struct _BraseroScsiGetPerfData { @@ -105,16 +94,8 @@ }; typedef struct _BraseroScsiGetPerfData BraseroScsiGetPerfData; -typedef enum { - BRASERO_SCSI_PERF_READ = 0, - BRASERO_SCSI_PERF_WRITE = 1, - BRASERO_SCSI_PERF_LIST = 1 << 1, -} BraseroScsiPerfParam; +G_END_DECLS -#ifdef __cplusplus -} -#endif - #endif /* _BURN_GET_PERFORMANCE_H */