Implemented some ATIP functionality
This commit is contained in:
parent
4718ad99f9
commit
b6a04cb493
@ -172,6 +172,7 @@ or
|
||||
#define Cdrskin_libburn_has_audioxtR 1
|
||||
#define Cdrskin_libburn_has_get_start_end_lbA 1
|
||||
#define Cdrskin_libburn_has_burn_disc_unsuitablE 1
|
||||
#define Cdrskin_libburn_has_read_atiP 1
|
||||
#endif
|
||||
|
||||
#ifndef Cdrskin_libburn_versioN
|
||||
@ -3326,7 +3327,7 @@ ex:;
|
||||
int Cdrskin_atip(struct CdrskiN *skin, int flag)
|
||||
{
|
||||
int ret,is_not_really_erasable= 0;
|
||||
double x_speed;
|
||||
double x_speed_max, x_speed_min= -1.0;
|
||||
enum burn_disc_status s;
|
||||
struct burn_drive *drive;
|
||||
|
||||
@ -3400,10 +3401,26 @@ int Cdrskin_atip(struct CdrskiN *skin, int flag)
|
||||
|
||||
#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);
|
||||
x_speed= ((double) ret)/Cdrskin_libburn_cd_speed_factoR;
|
||||
printf("cdrskin: burn_drive_get_write_speed = %d (%.1fx)\n",ret,x_speed);
|
||||
x_speed_max= ((double) ret)/Cdrskin_libburn_cd_speed_factoR;
|
||||
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(burn_disc_erasable(drive))
|
||||
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);
|
||||
if(ret>0) {
|
||||
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);
|
||||
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 */
|
||||
|
||||
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;
|
||||
ex:;
|
||||
Cdrskin_release_drive(skin,0);
|
||||
|
@ -1 +1 @@
|
||||
#define Cdrskin_timestamP "2006.10.20.151602"
|
||||
#define Cdrskin_timestamP "2006.10.21.103352"
|
||||
|
@ -663,6 +663,12 @@ int burn_drive_get_write_speed(struct burn_drive *d)
|
||||
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 */
|
||||
static char *enumeration_whitelist[BURN_DRIVE_WHITELIST_LEN];
|
||||
@ -1136,3 +1142,19 @@ int burn_disc_pretend_blank(struct burn_drive *d)
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
@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 */
|
||||
@ -652,7 +662,7 @@ int burn_disc_pretend_blank(struct burn_drive *d);
|
||||
@param flag Bitfield for control purposes (unused yet, submit 0)
|
||||
@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);
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
/* 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
|
||||
@param d Drive to query
|
||||
@return Maximum read speed in K/s
|
||||
|
@ -319,7 +319,7 @@ Range "scdbackup" : 0x00020000 to 0x0002ffff
|
||||
0x0002010b (FATAL,HIGH) = Burn run failed
|
||||
0x0002010c (FATAL,HIGH) = Failed to transfer command to drive
|
||||
0x0002010d (DEBUG,HIGH) = Could not inquire TOC
|
||||
0x0002010e
|
||||
0x0002010e (FATAL,HIGH) = Attempt to read ATIP from ungrabbed drive
|
||||
0x0002010f
|
||||
0x00020110 (FATAL,HIGH) = Persistent drive address too long
|
||||
0x00020111 (FATAL,HIGH) = Could not allocate new auxiliary object
|
||||
|
130
libburn/mmc.c
130
libburn/mmc.c
@ -439,6 +439,17 @@ void mmc_read_atip(struct burn_drive *d)
|
||||
struct buffer buf;
|
||||
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");
|
||||
memcpy(c.opcode, MMC_GET_ATIP, sizeof(MMC_GET_ATIP));
|
||||
c.retry = 1;
|
||||
@ -450,6 +461,125 @@ void mmc_read_atip(struct burn_drive *d)
|
||||
c.dir = FROM_DRIVE;
|
||||
d->issue_command(d, &c);
|
||||
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,
|
||||
|
@ -208,6 +208,7 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
||||
|
||||
out.start_lba= -2000000000;
|
||||
out.end_lba= -2000000000;
|
||||
out.read_atip = mmc_read_atip;
|
||||
|
||||
out.grab = sg_grab;
|
||||
out.release = sg_release;
|
||||
|
@ -443,6 +443,7 @@ static void enumerate_common(char *fname, int bus_no, int host_no,
|
||||
/* ts A61020 */
|
||||
out.start_lba= -2000000000;
|
||||
out.end_lba= -2000000000;
|
||||
out.read_atip = mmc_read_atip;
|
||||
|
||||
out.grab = sg_grab;
|
||||
out.release = sg_release;
|
||||
|
@ -157,10 +157,24 @@ void spc_sense_caps(struct burn_drive *d)
|
||||
m->cdrw_write = page[3] & 2;
|
||||
m->cdr_read = page[2] & 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->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];
|
||||
/* 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];
|
||||
|
||||
/* >>> 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->valid = 1;
|
||||
m->underrun_proof = page[4] & 128;
|
||||
|
@ -79,6 +79,10 @@ struct scsi_mode_data
|
||||
int simulate;
|
||||
int max_read_speed;
|
||||
int max_write_speed;
|
||||
|
||||
/* ts A61021 */
|
||||
int min_write_speed;
|
||||
|
||||
int cur_read_speed;
|
||||
int cur_write_speed;
|
||||
int retry_page_length;
|
||||
@ -146,6 +150,10 @@ struct burn_drive
|
||||
/* lower level functions */
|
||||
void (*erase) (struct burn_drive *, int);
|
||||
void (*getcaps) (struct burn_drive *);
|
||||
|
||||
/* ts A61021 */
|
||||
void (*read_atip) (struct burn_drive *);
|
||||
|
||||
int (*write) (struct burn_drive *, int, struct buffer *);
|
||||
void (*read_toc) (struct burn_drive *);
|
||||
void (*lock) (struct burn_drive *);
|
||||
|
Loading…
Reference in New Issue
Block a user