diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index 9218638..2e84856 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2009.09.06.112121" +#define Cdrskin_timestamP "2009.09.09.125305" diff --git a/libburn/drive.c b/libburn/drive.c index f423506..ec10698 100644 --- a/libburn/drive.c +++ b/libburn/drive.c @@ -521,6 +521,7 @@ int burn_drive_release_fl(struct burn_drive *d, int flag) d->unlock(d); if ((flag & 7) == 1) d->eject(d); + burn_drive_snooze(d, 0); d->release(d); } @@ -2621,7 +2622,7 @@ int burn_drive_set_media_capacity_remaining(struct burn_drive *d, off_t value) /* ts A81215 : API */ int burn_get_read_capacity(struct burn_drive *d, int *capacity, int flag) { - *capacity = d->media_read_capacity; + *capacity = d->media_read_capacity + 1; return (d->media_read_capacity != 0x7fffffff); } @@ -2642,3 +2643,37 @@ int burn_disc_get_media_id(struct burn_drive *d, return ret; } + +/* ts A90909 : API */ +/** + @param valid Replies bits which indicate the validity of other reply + parameters or the state of certain CD info bits: + bit0= disc_type valid + bit1= disc_id valid + bit2= bar_code valid + bit3= disc_app_code valid + bit4= Disc is unrestricted (URU bit) + bit31= Disc is nominally erasable (Erasable bit) + This will be set with overwriteable media which + libburn normally considers to be unerasable blank. +*/ +int burn_disc_get_cd_info(struct burn_drive *d, char disc_type[80], + unsigned int *disc_id, char bar_code[9], int *app_code, + int *valid) +{ + if (d->disc_type == 0x00) { + strcpy(disc_type, "CD-DA or CD-ROM"); + } else if (d->disc_type == 0x10) { + strcpy(disc_type, "CD-I"); + } else if (d->disc_type == 0x20) { + strcpy(disc_type, "CD-ROM XA"); + } else { + strcpy(disc_type, "undefined"); + } + *disc_id = d->disc_id; + memcpy(bar_code, d->disc_bar_code, 8); + bar_code[9]= 0; + *app_code = d->disc_app_code; + *valid = d->disc_info_valid | ((!!d->erasable) << 31); + return 1; +} diff --git a/libburn/libburn.h b/libburn/libburn.h index 822a774..d0ad863 100644 --- a/libburn/libburn.h +++ b/libburn/libburn.h @@ -1161,6 +1161,35 @@ int burn_drive_get_start_end_lba(struct burn_drive *drive, char *burn_guess_cd_manufacturer(int m_li, int s_li, int f_li, int m_lo, int s_lo, int f_lo, int flag); +/* ts A90909 */ +/** Retrieve some media information which is mainly specific to CD. For other + media only the bits in reply parameter valid are supposed to be meaningful. + @param drive The drive to query. + @param disc_type A string saying either "CD-DA or CD-ROM", or "CD-I", + or ""CD-ROM XA", or "undefined". + @param disc_id A 32 bit number read from the media. (Meaning unclear yet) + @param bar_code 8 hex digits from a barcode on media read by the drive + (if the drive has a bar code reader built in). + @param app_code The Host Application Code which must be set in the Write + Parameters Page if the media is not unrestricted (URU==0). + @param valid Replies bits which indicate the validity of other reply + parameters or the state of certain CD info bits: + bit0= disc_type is valid + bit1= disc_id is valid + bit2= bar_code is valid + bit3= disc_app_code is valid + bit4= Disc is unrestricted (URU bit, 51h READ DISC INFO) + This seems to be broken with my drives. The bit is + 0 and the validity bit for disc_app_code is 0 too. + bit31= Disc is nominally erasable (Erasable bit) + This will be set with overwriteable media which + libburn normally considers to be unerasable blank. + @since 0.7.2 +*/ +int burn_disc_get_cd_info(struct burn_drive *d, char disc_type[80], + unsigned int *disc_id, char bar_code[9], int *app_code, + int *valid); + /* ts A61110 */ /** Read start lba and Next Writeable Address of a track from media. diff --git a/libburn/mmc.c b/libburn/mmc.c index c646ea5..5f47542 100644 --- a/libburn/mmc.c +++ b/libburn/mmc.c @@ -1054,8 +1054,7 @@ int mmc_fake_toc(struct burn_drive *d) } /* ts A71128 : My DVD-ROM drive issues no reliable track info. One has to try 43h READ TOC/PMA/ATIP Form 0. */ - if ((d->current_profile == 0x10 || d->current_profile == 0x40) && - d->last_track_no <= 1) { + if ((d->current_profile == 0x10) && d->last_track_no <= 1) { ret = mmc_read_toc_fmt0(d); return ret; } @@ -1586,15 +1585,7 @@ static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len) mmc_get_configuration(d); -/* ts A70910 : found this as condition for mmc_function_spy() which went up - if (*alloc_len < 2) -*/ - scsi_init_command(&c, MMC_GET_DISC_INFO, sizeof(MMC_GET_DISC_INFO)); -/* - memcpy(c.opcode, MMC_GET_DISC_INFO, sizeof(MMC_GET_DISC_INFO)); - c.oplen = sizeof(MMC_GET_DISC_INFO); -*/ c.dxfer_len = *alloc_len; c.opcode[7]= (c.dxfer_len >> 8) & 0xff; c.opcode[8]= c.dxfer_len & 0xff; @@ -1616,13 +1607,31 @@ static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len) *alloc_len = len + 2; if (old_alloc_len < 34) return 1; - if (*alloc_len < 24) /* data[23] is the last byte used here */ + if (*alloc_len < 24) /* data[23] is the last mandatory byte here */ return 0; if (len + 2 > old_alloc_len) len = old_alloc_len - 2; d->erasable = !!(data[2] & 16); + /* ts A90908 */ + d->disc_type = data[8]; + d->disc_info_valid = 1; + d->disc_id = mmc_four_char_to_int(data + 12); + d->disc_info_valid |= (!!(data[7] & 128)) << 1; + if (len + 2 > 31 && (data[7] & 64)) { + memcpy(d->disc_bar_code, data + 24, 8); + d->disc_bar_code[9] = 0; + d->disc_info_valid |= 4; + } + if (len + 2 > 32 && (data[7] & 16)) { + d->disc_app_code = data[32]; + d->disc_info_valid |= 8; + } + if (data[7] & 32) { + d->disc_info_valid |= 16; + } + disc_status = data[2] & 3; d->state_of_last_session = (data[2] >> 2) & 3; number_of_sessions = (data[9] << 8) | data[4]; @@ -1656,12 +1665,26 @@ static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len) } #endif /* Libburn_support_bd_r_readonlY */ + /* MMC-5 6.22.3.1.16: + Last Session Lead-in Start Address bytes 16 to 19 + Last Possible Lead-out Start Address bytes 20 to 23 + MSF for CD, LBA else + */ + if(d->current_profile == 0x08 || d->current_profile == 0x09 || + d->current_profile == 0x0a) { + d->last_lead_in = + burn_msf_to_lba(data[17], data[18], data[19]); + d->last_lead_out = + burn_msf_to_lba(data[21], data[22], data[23]); + } else { + d->last_lead_in = mmc_four_char_to_int(data + 16); + d->last_lead_out = mmc_four_char_to_int(data + 20); + } + switch (disc_status) { case 0: regard_as_blank:; d->toc_entries = 0; - d->start_lba = burn_msf_to_lba(data[17], data[18], data[19]); - d->end_lba = burn_msf_to_lba(data[21], data[22], data[23]); /* fprintf(stderr, "libburn_experimental: start_lba = %d (%d %d %d) , end_lba = %d (%d %d %d)\n", @@ -1670,6 +1693,8 @@ regard_as_blank:; */ d->status = BURN_DISC_BLANK; + d->start_lba = d->last_lead_in; + d->end_lba = d->last_lead_out; break; case 1: d->status = BURN_DISC_APPENDABLE; @@ -4213,6 +4238,13 @@ int mmc_setup_drive(struct burn_drive *d) d->needs_close_session = 0; d->needs_sync_cache = 0; d->bg_format_status = -1; + d->last_lead_in = -2000000000; + d->last_lead_out = -2000000000; + d->disc_type = 0xff; + d->disc_id = 0; + memset(d->disc_bar_code, 0, 9); + d->disc_app_code = 0; + d->disc_info_valid = 0; d->num_format_descr = 0; d->complete_sessions = 0; d->state_of_last_session = -1; diff --git a/libburn/transport.h b/libburn/transport.h index efb1d27..6f3b55b 100644 --- a/libburn/transport.h +++ b/libburn/transport.h @@ -216,7 +216,17 @@ struct burn_drive int stream_recording_start; /* ts A61218 from 51h READ DISC INFORMATION */ + int last_lead_in; + int last_lead_out; int bg_format_status; /* 0=needs format start, 1=needs format restart*/ + int disc_type; /* 0="CD-DA or CD-ROM", 0x10="CD-I", 0x20="CD-ROM XA" */ + unsigned int disc_id; /* a "32 bit binary integer" */ + char disc_bar_code[9]; + int disc_app_code; + int disc_info_valid; /* bit0= disc_type , bit1= disc_id , + bit2= disc_bar_code , bit3= disc_app_code + bit4= URU bit is set (= unrestricted use) + */ /* ts A70108 from 23h READ FORMAT CAPACITY mmc5r03c.pdf 6.24 */ int format_descr_type; /* 1=unformatted, 2=formatted, 3=unclear */