Implemented some ATIP functionality

This commit is contained in:
Thomas Schmitt 2006-10-21 10:34:15 +00:00
parent 4718ad99f9
commit b6a04cb493
10 changed files with 225 additions and 10 deletions

View File

@ -172,6 +172,7 @@ or
#define Cdrskin_libburn_has_audioxtR 1 #define Cdrskin_libburn_has_audioxtR 1
#define Cdrskin_libburn_has_get_start_end_lbA 1 #define Cdrskin_libburn_has_get_start_end_lbA 1
#define Cdrskin_libburn_has_burn_disc_unsuitablE 1 #define Cdrskin_libburn_has_burn_disc_unsuitablE 1
#define Cdrskin_libburn_has_read_atiP 1
#endif #endif
#ifndef Cdrskin_libburn_versioN #ifndef Cdrskin_libburn_versioN
@ -3326,7 +3327,7 @@ ex:;
int Cdrskin_atip(struct CdrskiN *skin, int flag) int Cdrskin_atip(struct CdrskiN *skin, int flag)
{ {
int ret,is_not_really_erasable= 0; int ret,is_not_really_erasable= 0;
double x_speed; double x_speed_max, x_speed_min= -1.0;
enum burn_disc_status s; enum burn_disc_status s;
struct burn_drive *drive; struct burn_drive *drive;
@ -3400,10 +3401,26 @@ int Cdrskin_atip(struct CdrskiN *skin, int flag)
#endif /* Cdrskin_atip_speed_brokeN */ #endif /* Cdrskin_atip_speed_brokeN */
#ifdef Cdrskin_libburn_has_read_atiP
ret= burn_disc_read_atip(drive);
if(ret>0) {
ret= burn_drive_get_min_write_speed(drive);
x_speed_min= ((double) ret)/Cdrskin_libburn_cd_speed_factoR;
}
#endif
#ifdef Cdrskin_libburn_has_burn_disc_unsuitablE
if(burn_disc_get_status(drive) == BURN_DISC_UNSUITABLE) {
printf("Current: UNSUITABLE MEDIA\n");
{ret= 0; goto ex;}
}
#endif
ret= burn_drive_get_write_speed(drive); ret= burn_drive_get_write_speed(drive);
x_speed= ((double) ret)/Cdrskin_libburn_cd_speed_factoR; x_speed_max= ((double) ret)/Cdrskin_libburn_cd_speed_factoR;
printf("cdrskin: burn_drive_get_write_speed = %d (%.1fx)\n",ret,x_speed); if(x_speed_min<0)
x_speed_min= x_speed_max;
printf("cdrskin: burn_drive_get_write_speed = %d (%.1fx)\n",ret,x_speed_max);
if(skin->verbosity>=Cdrskin_verbose_progresS) { if(skin->verbosity>=Cdrskin_verbose_progresS) {
if(burn_disc_erasable(drive)) if(burn_disc_erasable(drive))
printf("Current: CD-RW\n"); printf("Current: CD-RW\n");
@ -3425,14 +3442,16 @@ int Cdrskin_atip(struct CdrskiN *skin, int flag)
ret= burn_drive_get_start_end_lba(drive,&start_lba,&end_lba,0); ret= burn_drive_get_start_end_lba(drive,&start_lba,&end_lba,0);
if(ret>0) { if(ret>0) {
burn_lba_to_msf(start_lba,&min,&sec,&fr); burn_lba_to_msf(start_lba,&min,&sec,&fr);
printf(" ATIP start of lead in: %d (%d:%d/%d)\n",start_lba,min,sec,fr); printf(" ATIP start of lead in: %d (%-2.2d:%-2.2d/%-2.2d)\n",
start_lba,min,sec,fr);
burn_lba_to_msf(end_lba,&min,&sec,&fr); burn_lba_to_msf(end_lba,&min,&sec,&fr);
printf(" ATIP start of lead out: %d (%d:%d/%d)\n",end_lba,min,sec,fr); printf(" ATIP start of lead out: %d (%-2.2d:%-2.2d/%-2.2d)\n",
end_lba,min,sec,fr);
} }
} }
#endif /* Cdrskin_libburn_has_get_start_end_lbA */ #endif /* Cdrskin_libburn_has_get_start_end_lbA */
printf(" 1T speed low: %.f 1T speed high: %.f\n",x_speed,x_speed); printf(" 1T speed low: %.f 1T speed high: %.f\n",x_speed_min,x_speed_max);
ret= 1; ret= 1;
ex:; ex:;
Cdrskin_release_drive(skin,0); Cdrskin_release_drive(skin,0);

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2006.10.20.151602" #define Cdrskin_timestamP "2006.10.21.103352"

View File

@ -663,6 +663,12 @@ int burn_drive_get_write_speed(struct burn_drive *d)
return d->mdata->max_write_speed; return d->mdata->max_write_speed;
} }
/* ts A61021 : New API function */
int burn_drive_get_min_write_speed(struct burn_drive *d)
{
return d->mdata->min_write_speed;
}
/* ts A51221 */ /* ts A51221 */
static char *enumeration_whitelist[BURN_DRIVE_WHITELIST_LEN]; static char *enumeration_whitelist[BURN_DRIVE_WHITELIST_LEN];
@ -1136,3 +1142,19 @@ int burn_disc_pretend_blank(struct burn_drive *d)
return 1; return 1;
} }
/* ts A61021: new API function */
int burn_disc_read_atip(struct burn_drive *d)
{
if (burn_drive_is_released(d)) {
libdax_msgs_submit(libdax_messenger,
d->global_index, 0x0002010e,
LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
"Attempt to read ATIP from ungrabbed drive",
0, 0);
return -1;
}
d->read_atip(d);
/* >>> some control of success would be nice :) */
return 1;
}

View File

@ -639,7 +639,17 @@ enum burn_disc_status burn_disc_get_status(struct burn_drive *drive);
failed to declare themselves either blank or (partially) filled. failed to declare themselves either blank or (partially) filled.
@return 1 drive status has been set , 0 = unsuitable drive status @return 1 drive status has been set , 0 = unsuitable drive status
*/ */
int burn_disc_pretend_blank(struct burn_drive *d); int burn_disc_pretend_blank(struct burn_drive *drive);
/* ts A61021 */
/** Reads ATIP information from inserted media. To be obtained via
burn_drive_get_write_speed(), burn_drive_get_min_write_speed(),
burn_drive_get_start_end_lba(). The drive must be grabbed for this call.
@param drive The drive to query.
@return 1=sucess, 0=no valid ATIP info read, -1 severe error
*/
int burn_disc_read_atip(struct burn_drive *drive);
/* ts A61020 */ /* ts A61020 */
@ -652,7 +662,7 @@ int burn_disc_pretend_blank(struct burn_drive *d);
@param flag Bitfield for control purposes (unused yet, submit 0) @param flag Bitfield for control purposes (unused yet, submit 0)
@return 1 if lba values are valid , 0 if invalid @return 1 if lba values are valid , 0 if invalid
*/ */
int burn_drive_get_start_end_lba(struct burn_drive *d, int burn_drive_get_start_end_lba(struct burn_drive *drive,
int *start_lba, int *end_lba, int flag); int *start_lba, int *end_lba, int flag);
@ -1019,6 +1029,16 @@ void burn_read_opts_set_hardware_error_retries(struct burn_read_opts *opts,
*/ */
int burn_drive_get_write_speed(struct burn_drive *d); int burn_drive_get_write_speed(struct burn_drive *d);
/* ts A61021 */
/** Gets the minimum write speed for a drive. This might differ from
burn_drive_get_write_speed() only after burn_disc_read_atip()
@param d Drive to query
@return Minimum write speed in K/s
*/
int burn_drive_get_min_write_speed(struct burn_drive *d);
/** Gets the maximum read speed for a drive /** Gets the maximum read speed for a drive
@param d Drive to query @param d Drive to query
@return Maximum read speed in K/s @return Maximum read speed in K/s

View File

@ -319,7 +319,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
0x0002010b (FATAL,HIGH) = Burn run failed 0x0002010b (FATAL,HIGH) = Burn run failed
0x0002010c (FATAL,HIGH) = Failed to transfer command to drive 0x0002010c (FATAL,HIGH) = Failed to transfer command to drive
0x0002010d (DEBUG,HIGH) = Could not inquire TOC 0x0002010d (DEBUG,HIGH) = Could not inquire TOC
0x0002010e 0x0002010e (FATAL,HIGH) = Attempt to read ATIP from ungrabbed drive
0x0002010f 0x0002010f
0x00020110 (FATAL,HIGH) = Persistent drive address too long 0x00020110 (FATAL,HIGH) = Persistent drive address too long
0x00020111 (FATAL,HIGH) = Could not allocate new auxiliary object 0x00020111 (FATAL,HIGH) = Could not allocate new auxiliary object

View File

@ -439,6 +439,17 @@ void mmc_read_atip(struct burn_drive *d)
struct buffer buf; struct buffer buf;
struct command c; struct command c;
/* ts A61021 */
unsigned char *data;
/* Speed values from A1:
With 4 cdrecord tells 10 or 8 where MMC-1 says 8.
cdrecord 8 appear on 4xCD-RW and thus seem to be quite invalid.
My CD-R (>=24 speed) tell no A1.
The higher non-MMC-1 values are hearsay.
*/
static int speed_value[16]= { 0, 2, 4, 6, 10, -5, 16, -7,
24, 32, 40, 48, -12, -13, -14, -15};
mmc_function_spy("mmc_read_atip"); mmc_function_spy("mmc_read_atip");
memcpy(c.opcode, MMC_GET_ATIP, sizeof(MMC_GET_ATIP)); memcpy(c.opcode, MMC_GET_ATIP, sizeof(MMC_GET_ATIP));
c.retry = 1; c.retry = 1;
@ -450,6 +461,125 @@ void mmc_read_atip(struct burn_drive *d)
c.dir = FROM_DRIVE; c.dir = FROM_DRIVE;
d->issue_command(d, &c); d->issue_command(d, &c);
burn_print(1, "atip shit for you\n"); burn_print(1, "atip shit for you\n");
/* ts A61021 */
data = c.page->data;
d->erasable= !!(data[6]&64);
d->start_lba= burn_msf_to_lba(data[8],data[9],data[10]);
d->end_lba= burn_msf_to_lba(data[12],data[13],data[14]);
if (data[6]&4) {
if (speed_value[(data[16]>>4)&7] > 0)
d->mdata->min_write_speed =
speed_value[(data[16]>>4)&7]*176;
if (speed_value[(data[16])&15] > 0)
d->mdata->max_write_speed =
speed_value[(data[16])&15]*176;
}
#ifdef Burn_mmc_be_verbous_about_atiP
{ int i;
fprintf(stderr,"libburn_experimental: Returned ATIP Data\n");
for(i= 0; i<28; i++)
fprintf(stderr,"%3.3d (0x%2.2x)%s",
data[i],data[i],((i+1)%5 ? " ":"\n"));
fprintf(stderr,"\n");
fprintf(stderr,
"libburn_experimental: Indicative Target Writing Power= %d\n",
(data[4]>>4)&7);
fprintf(stderr,
"libburn_experimental: Reference speed= %d ->%d\n",
data[4]&7, speed_value[data[4]&7]);
fprintf(stderr,
"libburn_experimental: Is %sunrestricted\n",
(data[5]&64?"":"not "));
fprintf(stderr,
"libburn_experimental: Is %serasable, sub-type %d\n",
(data[6]&64?"":"not "),(data[6]>>3)&3);
fprintf(stderr,
"libburn_experimental: lead in: %d (%-2.2d:%-2.2d/%-2.2d)\n",
burn_msf_to_lba(data[8],data[9],data[10]),
data[8],data[9],data[10]);
fprintf(stderr,
"libburn_experimental: lead out: %d (%-2.2d:%-2.2d/%-2.2d)\n",
burn_msf_to_lba(data[12],data[13],data[14]),
data[12],data[13],data[14]);
if(data[6]&4)
fprintf(stderr,
"libburn_experimental: A1 speed low %d speed high %d\n",
speed_value[(data[16]>>4)&7], speed_value[(data[16])&7]);
if(data[6]&2)
fprintf(stderr,
"libburn_experimental: A2 speed low %d speed high %d\n",
speed_value[(data[20]>>4)&7], speed_value[(data[20])&7]);
if(data[6]&1)
fprintf(stderr,
"libburn_experimental: A3 speed low %d speed high %d\n",
speed_value[(data[24]>>4)&7], speed_value[(data[24])&7]);
}
#endif /* Burn_mmc_be_verbous_about_atiP */
/* ts A61020
http://www.t10.org/ftp/t10/drafts/mmc/mmc-r10a.pdf , table 77 :
0 ATIP Data Length MSB
1 ATIP Data Length LSB
2 Reserved
3 Reserved
4 bit7=1, bit4-6="Indicative Target Writing Power", bit3=reserved ,
bit0-2="Reference speed"
5 bit7=0, bit6="URU" , bit0-5=reserved
6 bit7=1, bit6="Disc Type", bit3-4="Disc Sub-Type",
bit2="A1", bit1="A2", bit0="A3"
7 reserved
8 ATIP Start Time of lead-in (Min)
9 ATIP Start Time of lead-in (Sec)
10 ATIP Start Time of lead-in (Frame)
11 reserved
12 ATIP Last Possible Start Time of lead-out (Min)
13 ATIP Last Possible Start Time of lead-out (Sec)
14 ATIP Last Possible Start Time of lead-out (Frame)
15 reserved
16 bit7=0, bit4-6="Lowest Usable CLV Recording speed"
bit0-3="Highest Usable CLV Recording speed"
17 bit7=0, bit4-6="Power Multiplication Factor p",
bit1-3="Target y value of the Modulation/Power function", bit0=reserved
18 bit7=1, bit4-6="Recommended Erase/Write Power Ratio (P(inf)/W(inf))"
bit0-3=reserved
19 reserved
20-22 A2 Values
23 reserved
24-26 A3 Values
27 reserved
Disc Type - zero indicates CD-R media; one indicates CD-RW media.
Disc Sub-Type - shall be set to zero.
A1 - when set to one, indicates that bytes 16-18 are valid.
Lowest Usable CLV Recording Speed
000b Reserved
001b 2X
010b - 111b Reserved
Highest CLV Recording Speeds
000b Reserved
001b 2X
010b 4X
011b 6X
100b 8X
101b - 111b Reserved
MMC-3 seems to recommend MODE SENSE (5Ah) page 2Ah rather than A1, A2, A3.
This page is loaded in libburn function spc_sense_caps() .
Speed is given in kbytes/sec there. But i suspect this to be independent
of media. So one would habe to associate the speed descriptor blocks with
the ATIP media characteristics ? How ?
*/
} }
void mmc_read_sectors(struct burn_drive *d, void mmc_read_sectors(struct burn_drive *d,

View File

@ -208,6 +208,7 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
out.start_lba= -2000000000; out.start_lba= -2000000000;
out.end_lba= -2000000000; out.end_lba= -2000000000;
out.read_atip = mmc_read_atip;
out.grab = sg_grab; out.grab = sg_grab;
out.release = sg_release; out.release = sg_release;

View File

@ -443,6 +443,7 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
/* ts A61020 */ /* ts A61020 */
out.start_lba= -2000000000; out.start_lba= -2000000000;
out.end_lba= -2000000000; out.end_lba= -2000000000;
out.read_atip = mmc_read_atip;
out.grab = sg_grab; out.grab = sg_grab;
out.release = sg_release; out.release = sg_release;

View File

@ -157,10 +157,24 @@ void spc_sense_caps(struct burn_drive *d)
m->cdrw_write = page[3] & 2; m->cdrw_write = page[3] & 2;
m->cdr_read = page[2] & 1; m->cdr_read = page[2] & 1;
m->cdr_write = page[3] & 1; m->cdr_write = page[3] & 1;
/* ts A61021 : these fields are marked obsolete in MMC 3 */
m->max_read_speed = page[8] * 256 + page[9]; m->max_read_speed = page[8] * 256 + page[9];
m->cur_read_speed = page[14] * 256 + page[15]; m->cur_read_speed = page[14] * 256 + page[15];
/* in MMC-3 : see [30-31] and blocks beginning at [32] */
m->max_write_speed = page[18] * 256 + page[19]; m->max_write_speed = page[18] * 256 + page[19];
/* New field to be set by atip */
m->min_write_speed = m->max_write_speed;
/* in MMC-3 : [28-29] */
m->cur_write_speed = page[20] * 256 + page[21]; m->cur_write_speed = page[20] * 256 + page[21];
/* >>> ts A61021 : iterate over all speeds :
data[30-31]: number of speed performance descriptor blocks
data[32-35]: block 0 : [+2-3] speed in kbytes/sec
*/
m->c2_pointers = page[5] & 16; m->c2_pointers = page[5] & 16;
m->valid = 1; m->valid = 1;
m->underrun_proof = page[4] & 128; m->underrun_proof = page[4] & 128;

View File

@ -79,6 +79,10 @@ struct scsi_mode_data
int simulate; int simulate;
int max_read_speed; int max_read_speed;
int max_write_speed; int max_write_speed;
/* ts A61021 */
int min_write_speed;
int cur_read_speed; int cur_read_speed;
int cur_write_speed; int cur_write_speed;
int retry_page_length; int retry_page_length;
@ -146,6 +150,10 @@ struct burn_drive
/* lower level functions */ /* lower level functions */
void (*erase) (struct burn_drive *, int); void (*erase) (struct burn_drive *, int);
void (*getcaps) (struct burn_drive *); void (*getcaps) (struct burn_drive *);
/* ts A61021 */
void (*read_atip) (struct burn_drive *);
int (*write) (struct burn_drive *, int, struct buffer *); int (*write) (struct burn_drive *, int, struct buffer *);
void (*read_toc) (struct burn_drive *); void (*read_toc) (struct burn_drive *);
void (*lock) (struct burn_drive *); void (*lock) (struct burn_drive *);