50 #ifdef Libburn_log_in_and_out_streaM
52 #include <sys/types.h>
64 #define Libburn_support_dvd_plus_rW 1
67 #define Libburn_support_dvd_minusrw_overW 1
71 #define Libburn_support_dvd_raM 1
74 #define Libburn_support_dvd_r_seQ 1
77 #define Libburn_support_dvd_plus_R 1
80 #define Libburn_support_bd_r_readonlY 1
83 #define Libburn_support_bd_plus_r_srM 1
169 #define Libburn_wait_for_buffer_freE 0
170 #define Libburn_wait_for_buffer_min_useC 10000
171 #define Libburn_wait_for_buffer_max_useC 100000
172 #define Libburn_wait_for_buffer_tio_seC 120
173 #define Libburn_wait_for_buffer_min_perC 65
174 #define Libburn_wait_for_buffer_max_perC 95
182 #define Libburn_cd_max_read_speeD (52 * 150)
183 #define Libburn_dvd_max_read_speeD (24 * 1385)
184 #define Libburn_bd_max_read_speeD (20 * 4495.625 + 0.5)
188 #define Libburn_cd_min_read_speeD ( 1 * 150)
189 #define Libburn_dvd_min_read_speeD ( 1 * 1385)
190 #define Libburn_bd_min_read_speeD ( 1 * 4495.625 - 0.625)
194 { 0x43, 0, 1, 0, 0, 0, 0, 16, 0, 0 };
195 static unsigned char MMC_GET_TOC[] = { 0x43, 2, 2, 0, 0, 0, 0, 16, 0, 0 };
197 static unsigned char MMC_GET_ATIP[] = { 0x43, 2, 4, 0, 0, 0, 0, 16, 0, 0 };
200 { 0x51, 0, 0, 0, 0, 0, 0, 16, 0, 0 };
201 static unsigned char MMC_READ_CD[] = { 0xBE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
202 static unsigned char MMC_BLANK[] = { 0xA1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
203 static unsigned char MMC_SEND_OPC[] = { 0x54, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
205 { 0xBB, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
207 { 0xAA, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
208 static unsigned char MMC_WRITE_10[] = { 0x2A, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
212 { 0x46, 0, 0, 0, 0, 0, 0, 16, 0, 0 };
215 static unsigned char MMC_GET_EVENT[] = { 0x4A, 1, 0, 0, 0x7e, 0, 0, 0, 8, 0 };
216 static unsigned char MMC_CLOSE[] = { 0x5B, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
220 { 0x5D, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
224 { 0x5C, 0, 0, 0, 0, 0, 0, 16, 0, 0 };
232 { 0xB6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
237 { 0xAC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
241 { 0x23, 0, 0, 0, 0, 0, 0, 0, 0, 0};
245 { 0x53, 0, 0, 0, 0, 0, 0, 0, 0, 0};
249 { 0x28, 0, 0, 0, 0, 0, 0, 0, 0, 0};
253 { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0};
258 { 0xAD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
263 { 0xB9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
270 fprintf(stderr,
"libburn: experimental: mmc_function_spy: %s\n",
277 sprintf(msg,
"Emulated drive caught in SCSI adapter \"%s\"",
299 return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
306 data[0] = (num >> 24) & 0xff;
307 data[1] = (num >> 16) & 0xff;
308 data[2] = (num >> 8) & 0xff;
309 data[3] = num & 0xff;
333 struct buffer *buf = NULL;
385 sprintf(msg,
"reserving track of %d blocks", lba);
456 struct buffer *buf = NULL;
457 int ret, num, alloc_len = 20, err;
485 #ifdef Libburn_pioneer_dvr_216d_load_mode5
489 {
static int fake_damage = 0;
500 sprintf(msg,
"Track number %d: ", trackno);
502 sprintf(msg,
"Upcoming track: ");
506 *lba = *nwa = num = 0;
508 }
else if (
data[5] & 32) {
509 if (!(
data[7] & 1)) {
511 strcat(msg,
"Damaged, not closed and not writable");
515 strcat(msg,
"Damaged and not closed");
525 }
else if (!(
data[7] & 1)) {
527 strcat(msg,
"No Next-Writable-Address");
539 ((off_t) num) * ((off_t) 2048));
567 "HOW THAT ? mmc_close_disc() was called", 0, 0);
588 "HOW THAT ? mmc_close_session() was called", 0, 0);
620 c->
opcode[2] = ((session & 3) << 1) | !!track;
621 c->
opcode[4] = track >> 8;
622 c->
opcode[5] = track & 0xFF;
633 sprintf(msg,
"Failed to close %s (%d)",
634 session > 1 ?
"disc" : session > 0 ?
"session" :
"track",
635 ((session & 3) << 1) | !!track);
636 sprintf(msg + strlen(msg),
". SCSI error : ");
653 struct buffer *buf = NULL;
655 int alloc_len = 8, len, evt_code, loops = 0;
682 len = ((evt[0] << 8) | evt[1]) + 2;
690 evt_code = evt[4] & 0xf;
694 switch (evt[2] & 7) {
698 if (((evt[6] << 8) | evt[7])) {
726 if (evt_code == 1 && evt[5]) {
750 int usec= 0, need, reported_3s = 0, first_wait = 1;
751 struct timeval t0,tnow;
752 double max_fac, min_fac, waiting;
757 #ifdef Libburn_mmc_wfb_debuG
758 char sleeplist[32768];
759 static int buffer_still_invalid = 1;
773 #ifdef Libburn_mmc_wfb_debuG
774 if (buffer_still_invalid)
776 "\nLIBBURN_DEBUG: Buffer considered valid now\n");
777 buffer_still_invalid = 0;
788 gettimeofday(&t0, NULL);
789 #ifdef Libburn_mmc_wfb_debuG
791 sprintf(sleeplist,
"(%d%s %d)",
802 #ifdef Libburn_mmc_wfb_debuG
803 if(strlen(sleeplist) <
sizeof(sleeplist) - 80)
804 sprintf(sleeplist+strlen(sleeplist),
" (%d%s %d)",
809 gettimeofday(&tnow, NULL);
810 waiting = (tnow.tv_sec - t0.tv_sec) +
811 ((
double) (tnow.tv_usec - t0.tv_usec)) / 1.0e6;
814 #ifdef Libburn_mmc_wfb_debuG
815 if(strlen(sleeplist) >=
sizeof(sleeplist) - 80)
816 strcat(sleeplist,
" ...");
817 sprintf(sleeplist+strlen(sleeplist),
" -> %d [%.6f]",
823 "\nLIBBURN_DEBUG: sleeplist= %s\n",sleeplist);
829 if (waiting >= 3 && !reported_3s) {
833 "Waiting for free buffer takes more than 3 seconds",
842 "Timeout with waiting for free buffer. Now disabled.",
851 usec = ((double) need) / 1000.0 /
868 #ifdef Libburn_mmc_wfb_debuG
869 if(strlen(sleeplist) <
sizeof(sleeplist) - 80)
870 sprintf(sleeplist+strlen(sleeplist),
" %d", usec);
906 #ifdef Libburn_write_time_debuG
908 static int print_time(
int flag)
910 static struct timeval prev = {0, 0};
914 ret = gettimeofday(&now, NULL);
918 diff = (now.tv_sec - prev.tv_sec) * 1000000 +
919 ((
int) (now.tv_usec) - (
int) prev.tv_usec);
920 fprintf(stderr,
"\nlibburn_DEBUG: %d.%-6d : %d\n", (
int) now.tv_sec, (
int) now.tv_usec, diff);
922 memcpy(&prev, &now,
sizeof(
struct timeval));
933 int len, key, asc, ascq;
936 #ifdef Libburn_write_time_debuG
948 #ifdef Libburn_log_in_and_out_streaM
950 static int tee_fd= -1;
952 tee_fd= open(
"/tmp/libburn_sg_written",
953 O_WRONLY | O_CREAT | O_TRUNC |
O_BINARY,
968 msg = calloc(1, 320);
971 "Exceeding range of permissible write addresses (%d >= %d)",
977 strcpy(msg,
"CDB= ");
979 320 - strlen(msg), 1) > 0) {
1001 #ifdef Libburn_write_time_debuG
1016 c->
opcode[7] = (len >> 8) & 0xFF;
1017 c->
opcode[8] = len & 0xFF;
1024 #ifdef Libburn_log_in_and_out_streaM
1039 if (c->
error && key != 0) {
1043 msg = calloc(1, 320);
1045 sprintf(msg,
"SCSI error on write(%d,%d): ",
1058 key == 5 && asc == 0x64 && ascq == 0) {
1072 strcpy(msg,
"CDB= ");
1074 320 - strlen(msg), 0) > 0) {
1095 unsigned char *size_data,
unsigned char *start_data,
1096 unsigned char *last_adr_data)
1098 int min, sec, frames, num;
1104 entry->
session = session_number & 0xff;
1105 entry->
session_msb = (session_number >> 8) & 0xff;
1109 entry->
point = track_number & 0xff;
1110 entry->
point_msb = (track_number >> 8) & 0xff;
1121 entry->
frame = frames;
1145 struct buffer *buf = NULL;
1147 int dlen, i, old_alloc_len, session_number, prev_session = -1, ret;
1149 unsigned char *tdata, size_data[4], start_data[4], end_data[4];
1172 "Could not inquire TOC", 0,0);
1180 old_alloc_len = *alloc_len;
1181 *alloc_len = dlen + 2;
1182 if (old_alloc_len < 12)
1184 if (dlen + 2 > old_alloc_len)
1185 dlen = old_alloc_len - 2;
1188 #ifdef Libburn_disc_with_incomplete_sessioN
1198 "TOC Format 0 returns inconsistent data", 0,0);
1210 if (d->
disc == NULL)
1214 if (session == NULL)
1223 session_number = i + 1;
1224 if (session_number != prev_session && prev_session > 0) {
1226 entry = &(d->
toc_entry[(i - 1) + prev_session]);
1233 size_data, start_data, end_data);
1243 entry = &(d->
toc_entry[i + session_number - 1]);
1246 {ret = -1;
goto ex;}
1250 track->
entry = entry;
1253 memcpy(start_data, tdata + 4, 4);
1255 memcpy(size_data, tdata + 8 + 4, 4);
1262 size_data, start_data, end_data);
1263 if (prev_session != session_number)
1266 prev_session = session_number;
1268 if (prev_session > 0 && prev_session <= d->disc->sessions) {
1272 memcpy(start_data, tdata + 4, 4);
1277 size_data, start_data, end_data);
1292 int alloc_len = 4, ret;
1298 if (alloc_len >= 12)
1311 struct buffer *buf = NULL;
1312 int i, session_number, prev_session = -1, ret, lba, alloc_len = 34;
1313 unsigned char *tdata, size_data[4], start_data[4], end_data[4];
1317 {ret = -1;
goto ex;}
1320 #ifdef Libburn_disc_with_incomplete_sessioN
1337 msg = calloc(1, 160);
1340 "Too many logical tracks recorded (%d , max. %d)\n",
1357 if (d->
disc == NULL)
1358 {ret = -1;
goto ex;}
1363 {ret = -1;
goto ex;}
1366 #ifdef Libburn_disc_with_incomplete_sessioN
1377 if (session == NULL)
1378 {ret = -1;
goto ex;}
1383 #ifdef Libburn_disc_with_incomplete_sessioN
1387 memset(size_data, 0, 4);
1388 memset(start_data, 0, 4);
1410 session_number = (tdata[33] << 8) | tdata[3];
1411 if (session_number <= 0)
1414 if (session_number != prev_session && prev_session > 0) {
1416 entry = &(d->
toc_entry[(i - 1) + prev_session]);
1423 size_data, start_data, end_data);
1429 #ifdef Libburn_disc_with_incomplete_sessioN
1447 #ifdef Libburn_disc_with_incomplete_sessioN
1460 entry = &(d->
toc_entry[i + session_number - 1]);
1463 {ret = -1;
goto ex;}
1467 track->
entry = entry;
1470 memcpy(size_data, tdata + 24, 4);
1471 memcpy(start_data, tdata + 8, 4);
1472 memcpy(end_data, tdata + 28, 4);
1474 size_data, start_data, end_data);
1479 if (prev_session != session_number)
1482 prev_session = session_number;
1485 if (prev_session > 0 && prev_session <= d->disc->sessions) {
1494 size_data, start_data, end_data);
1513 if (lba > *highest_leadout)
1514 *highest_leadout = lba;
1525 struct buffer *buf = NULL;
1528 int i, old_alloc_len, t_idx, ret, highest_leadout = -1;
1529 unsigned char *tdata;
1593 "Could not inquire TOC", 0,0);
1602 old_alloc_len = *alloc_len;
1603 *alloc_len = dlen + 2;
1604 if (old_alloc_len < 15)
1606 if (dlen + 2 > old_alloc_len)
1607 dlen = old_alloc_len - 2;
1625 if (d->
disc == NULL)
1628 for (i = 0; i < c->
page->
data[3]; i++) {
1630 if (session == NULL)
1638 for (i = 0; i < d->
toc_entries; i++, tdata += 11) {
1644 #ifdef Libburn_allow_first_hiddeN
1649 if (tdata[3] == 1) {
1654 session[tdata[0] - 1],
1663 if (tdata[3] < 100 && tdata[0] > 0) {
1682 if (tdata[3] == 0xA0)
1684 if (tdata[3] == 0xA1)
1686 if (tdata[3] == 0xA2) {
1703 sprintf(msg,
"Session %d of %d encountered without leadout",
1725 "Empty session %d deleted. Now %d sessions.",
1750 "Trusting READ CAPACITY by 2 extra blocks in TOC. Assuming TAO.",
1766 int alloc_len = 4, ret;
1778 if (alloc_len >= 15)
1792 struct buffer *buf = NULL;
1794 unsigned char *tdata;
1795 int num_sessions, session_no, num_tracks, alloc_len = 12, ret;
1816 for (session_no = 0; session_no<num_sessions; session_no++) {
1819 if (tracks == NULL || num_tracks <= 0)
1828 *trackno = toc_entry.
point;
1857 *trackno = tdata[2];
1870 static char *texts[0x53] = {NULL};
1871 int i, max_pno = 0x53;
1873 if (texts[0] == NULL) {
1874 for (i = 0; i<max_pno; i++)
1877 texts[0x01] =
"Non-removable disk";
1878 texts[0x02] =
"Removable disk";
1879 texts[0x03] =
"MO erasable";
1880 texts[0x04] =
"Optical write once";
1881 texts[0x05] =
"AS-MO";
1882 texts[0x08] =
"CD-ROM";
1883 texts[0x09] =
"CD-R";
1884 texts[0x0a] =
"CD-RW";
1885 texts[0x10] =
"DVD-ROM";
1886 texts[0x11] =
"DVD-R sequential recording";
1887 texts[0x12] =
"DVD-RAM";
1888 texts[0x13] =
"DVD-RW restricted overwrite";
1889 texts[0x14] =
"DVD-RW sequential recording";
1890 texts[0x15] =
"DVD-R/DL sequential recording";
1891 texts[0x16] =
"DVD-R/DL layer jump recording";
1892 texts[0x1a] =
"DVD+RW";
1893 texts[0x1b] =
"DVD+R";
1894 texts[0x2a] =
"DVD+RW/DL";
1895 texts[0x2b] =
"DVD+R/DL";
1896 texts[0x40] =
"BD-ROM";
1897 texts[0x41] =
"BD-R sequential recording";
1898 texts[0x42] =
"BD-R random recording";
1899 texts[0x43] =
"BD-RE";
1900 texts[0x50] =
"HD-DVD-ROM";
1901 texts[0x51] =
"HD-DVD-R";
1902 texts[0x52] =
"HD-DVD-RAM";
1904 if (profile_number<0 || profile_number>=max_pno)
1906 return texts[profile_number];
1938 struct buffer *buf = NULL;
1939 unsigned char *
data;
1943 int do_read_toc = 0, disc_status, len, old_alloc_len;
1944 int ret, number_of_sessions = -1;
1985 if (key == 5 && asc == 0x20 && ascq == 0) {
2005 len = (data[0] << 8) | data[1];
2006 old_alloc_len = *alloc_len;
2007 *alloc_len = len + 2;
2008 if (old_alloc_len < 34)
2010 if (*alloc_len < 24)
2012 if (len + 2 > old_alloc_len)
2013 len = old_alloc_len - 2;
2022 if (len + 2 > 31 && (data[7] & 64)) {
2027 if (len + 2 > 32 && (data[7] & 16)) {
2036 disc_status = data[2] & 3;
2038 number_of_sessions = (data[9] << 8) | data[4];
2046 #ifdef Libburn_support_bd_r_readonlY
2049 #ifndef Libburn_support_bd_plus_r_srM
2079 switch (disc_status) {
2096 if (disc_status == 2)
2112 goto regard_as_blank;
2123 "Last session on media is still open.", 0, 0);
2142 msg = calloc(1, 160);
2145 "Unsuitable media detected. Profile %4.4Xh %s",
2168 if(((data[0] << 8) | data[1]) > 32)
2188 #ifdef Libburn_disc_with_incomplete_sessioN
2204 #ifdef Libburn_disc_with_incomplete_sessioN
2231 int alloc_len = 34, ret;
2252 unsigned char **text_packs,
int *alloc_len,
2255 struct buffer *buf = NULL;
2257 unsigned char *data;
2258 int ret, data_length;
2280 data_length = (data[0] << 8) + data[1];
2281 *alloc_len = data_length + 2;
2282 if (*alloc_len >= 22 && !(flag & 1)) {
2284 memcpy(*text_packs, data + 4, *alloc_len - 4);
2298 unsigned char **text_packs,
int *num_packs,
int flag)
2300 int alloc_len = 4, ret;
2306 if (ret <= 0 || alloc_len < 22)
2307 return (ret > 0 ? 0 : ret);
2309 if (ret <= 0 || alloc_len < 22) {
2310 if (*text_packs != NULL)
2313 return (ret > 0 ? 0 : ret);
2315 *num_packs = (alloc_len - 4) / 18;
2322 struct buffer *buf = NULL;
2327 unsigned char *data;
2335 static int speed_value[16]= { 0, 353, 706, 1059, 1764, -5, 2824, -7,
2336 4234, 5646, 7056, 8468, -12, -13, -14, -15};
2379 if (speed_value[(data[16]>>4)&7] > 0) {
2381 speed_value[(data[16]>>4)&7];
2382 if (speed_value[(data[16])&15] <= 0)
2384 speed_value[(data[16]>>4)&7];
2386 if (speed_value[(data[16])&15] > 0) {
2388 speed_value[(data[16])&15];
2389 if (speed_value[(data[16]>>4)&7] <= 0)
2391 speed_value[(data[16])&15];
2395 #ifdef Burn_mmc_be_verbous_about_atiP
2397 fprintf(stderr,
"libburn_experimental: Returned ATIP Data\n");
2398 for(i= 0; i<28; i++)
2399 fprintf(stderr,
"%3.3d (0x%2.2x)%s",
2400 data[i],data[i],(((i + 1) % 5) ?
" " :
"\n"));
2401 fprintf(stderr,
"\n");
2404 "libburn_experimental: Indicative Target Writing Power= %d\n",
2407 "libburn_experimental: Reference speed= %d ->%d\n",
2408 data[4]&7, speed_value[data[4]&7]);
2410 "libburn_experimental: Is %sunrestricted\n",
2411 (data[5]&64?
"":
"not "));
2413 "libburn_experimental: Is %serasable, sub-type %d\n",
2414 (data[6]&64?
"":
"not "),(data[6]>>3)&3);
2416 "libburn_experimental: lead in: %d (%-2.2d:%-2.2d/%-2.2d)\n",
2418 data[8],data[9],data[10]);
2420 "libburn_experimental: lead out: %d (%-2.2d:%-2.2d/%-2.2d)\n",
2422 data[12],data[13],data[14]);
2425 "libburn_experimental: A1 speed low %d speed high %d\n",
2426 speed_value[(data[16]>>4)&7], speed_value[(data[16])&7]);
2429 "libburn_experimental: A2 speed low %d speed high %d\n",
2430 speed_value[(data[20]>>4)&7], speed_value[(data[20])&7]);
2433 "libburn_experimental: A3 speed low %d speed high %d\n",
2434 speed_value[(data[24]>>4)&7], speed_value[(data[24])&7]);
2506 int start_m,
int start_s,
int start_f,
2507 int end_m,
int end_s,
int end_f,
int flag)
2510 int key, asc, ascq, silent;
2515 msg = calloc(1, 256);
2517 if (start_s < 0 || start_f < 0 || end_s < 0 || end_f < 0) {
2519 "SCSI error on %s(%d,%d): ", what, start_m, end_m);
2521 sprintf(msg,
"SCSI error on %s(%dm%ds%df,%dm%ds%df): ",
2523 start_m, start_s, start_f, end_m, end_s, end_f);
2528 if (key == 5 && asc == 0x64 && ascq == 0x0) {
2550 int start_m,
int start_s,
int start_f,
2551 int end_m,
int end_s,
int end_f,
2552 int sec_type,
int main_ch,
2555 int req, ret, dap_bit;
2556 int subcodes_audio = 0, subcodes_data = 0;
2558 #ifdef Libburn_mmc_report_recovereD
2559 int report_recovered_errors = 0;
2573 #ifdef Libburn_mmc_report_recovereD
2580 c->
opcode[1] = ((sec_type & 7) << 2) | ((!!dap_bit) << 1);
2588 req = main_ch & 0xf8;
2590 #ifdef Libburn_mmc_report_recovereD
2625 start_m, start_s, start_f,
2626 end_m, end_s, end_f, 0);
2635 int sec_type,
int main_ch,
2638 int temp, req, ret, dap_bit;
2639 int subcodes_audio = 0, subcodes_data = 0;
2642 #ifdef Libburn_mmc_report_recovereD
2643 int report_recovered_errors = 0;
2647 #ifdef Libburn_read_cd_by_msF
2649 int start_m, start_s, start_f, end_m, end_s, end_f;
2654 end_m, end_s, end_f,
2655 sec_type, main_ch, o, buf, flag);
2671 #ifdef Libburn_mmc_report_recovereD
2678 c->
opcode[1] = ((sec_type & 7) << 2) | ((!!dap_bit) << 1);
2680 c->
opcode[5] = temp & 0xFF;
2682 c->
opcode[4] = temp & 0xFF;
2684 c->
opcode[3] = temp & 0xFF;
2686 c->
opcode[2] = temp & 0xFF;
2687 c->
opcode[8] = len & 0xFF;
2689 c->
opcode[7] = len & 0xFF;
2691 c->
opcode[6] = len & 0xFF;
2692 req = main_ch & 0xf8;
2694 #ifdef Libburn_mmc_report_recovereD
2807 int r_speed,
int w_speed,
int end_lba)
2809 struct buffer *buf = NULL;
2811 int b, eff_end_lba, ret;
2839 w_speed = 0x10000000;
2840 else if (w_speed < 0)
2843 r_speed = 0x10000000;
2844 else if (r_speed < 0)
2848 eff_end_lba = 2294921 - 1;
2852 eff_end_lba = end_lba;
2855 "mmc_set_streaming: end_lba=%d , r=%d , w=%d , exact=%d",
2856 eff_end_lba, r_speed, w_speed, !!(pd[0] & 2));
2862 for (b = 0; b < 4 ; b++) {
2863 pd[8+b] = (eff_end_lba >> (24 - 8 * b)) & 0xff;
2864 pd[12+b] = (r_speed >> (24 - 8 * b)) & 0xff;
2865 pd[16+b] = (1000 >> (24 - 8 * b)) & 0xff;
2866 pd[20+b] = (w_speed >> (24 - 8 * b)) & 0xff;
2867 pd[24+b] = (1000 >> (24 - 8 * b)) & 0xff;
2883 "SCSI error on set_streaming(%d): ", w_speed);
2908 int ret, end_lba = 0, get_max, get_min;
2916 if (r <= 0 || w <= 0) {
2921 get_min = (r == -1);
2923 if (best_sd != NULL) {
2940 }
else if(get_min) {
2957 if (best_sd != NULL) {
2960 if (end_lba < best_sd->
end_lba)
2981 if (r == 0 || r > 0xffff)
2985 if (w == 0 || w > 0xffff)
3006 struct buffer *buf = NULL;
3007 int len, cp, descr_len = 0, feature_code, only_current = 1, i;
3008 int old_alloc_len, key, asc, ascq, ret;
3009 int feature_is_current;
3010 unsigned char *descr, *prf, *up_to, *prf_end;
3012 int phys_if_std = 0;
3013 char *phys_name =
"";
3020 #ifdef Libburn_print_feature_descriptorS
3057 #ifdef Libisofs_simulate_old_mmc1_drivE
3061 c->
sense[12] = 0x20;
3068 if (key == 0x5 && asc == 0x20 && ascq == 0x0) {
3076 old_alloc_len = *alloc_len;
3078 if (len > old_alloc_len)
3079 len = old_alloc_len;
3085 sprintf(msg,
"Implausible length announcement from SCSI command GET CONFIGURATION: %d", *alloc_len);
3095 #ifdef Libburn_rom_as_profilE
3096 if (cp == 0x08 || cp == 0x10 || cp==0x40)
3097 cp = Libburn_rom_as_profilE;
3112 #ifdef Libburn_support_bd_r_readonlY
3113 #ifndef Libburn_support_bd_plus_r_srM
3125 if (cp == 0x09 || cp == 0x0a)
3128 #ifdef Libburn_support_dvd_plus_rW
3132 #ifdef Libburn_support_dvd_minusrw_overW
3136 #ifdef Libburn_support_dvd_raM
3137 if (cp == 0x12 || cp == 0x43) {
3140 #ifdef Libburn_dvd_ram_as_bd_rE
3147 #ifdef Libburn_support_dvd_r_seQ
3148 if (cp == 0x11 || cp == 0x14)
3153 #ifdef Libburn_support_dvd_plus_R
3154 if (cp == 0x1b || cp == 0x2b)
3157 #ifdef Libburn_support_bd_plus_r_srM
3167 #ifdef Libburn_print_feature_descriptorS
3169 "-----------------------------------------------------------------\n");
3171 "LIBBURN_EXPERIMENTAL : feature list length = %d , shown = %d\n",
3172 len, (
int) (up_to - c->
page->
data));
3175 for (descr = c->
page->
data + 8; descr + 3 < up_to; descr += descr_len){
3176 descr_len = 4 + descr[3];
3178 feature_is_current = descr[2] & 1;
3186 recent_feature->
next = new_feature;
3187 recent_feature = new_feature;
3190 if (only_current && !feature_is_current)
3193 #ifdef Libburn_print_feature_descriptorS
3195 "LIBBURN_EXPERIMENTAL : %s feature %4.4Xh :",
3196 (descr[2] & 1) ?
"+" :
"-",
3199 for (i = 2; i < descr_len; i++)
3200 fprintf(stderr,
" %2.2X", descr[i]);
3201 fprintf(stderr,
"\n");
3205 prf_end = descr + 4 + descr[3];
3212 for (prf = descr + 4; prf + 2 < prf_end; prf += 4) {
3214 #ifdef Libburn_print_feature_descriptorS
3215 prf_number = (prf[0] << 8) | prf[1];
3217 "LIBBURN_EXPERIMENTAL : %s profile %4.4Xh \"%s\"\n",
3218 prf[2] & 1 ?
"+" :
"-",
3228 for (i = 0; i < descr[7]; i++) {
3229 if (i == 0 || descr[8 + i] == 16)
3233 #ifdef Libburn_print_feature_descriptorS
3235 "LIBBURN_EXPERIMENTAL : + Link Size = %d\n",
3242 if (feature_is_current) {
3246 #ifdef Libburn_print_feature_descriptorS
3247 if (cp >= 0x41 && cp <= 0x43)
3249 "LIBBURN_EXPERIMENTAL : BD formats: %s%s%s%s%s\n",
3250 descr[4] & 1 ?
" Cert" :
"",
3251 descr[4] & 2 ?
" QCert" :
"",
3252 descr[4] & 4 ?
" Expand" :
"",
3253 descr[4] & 8 ?
" RENoSA" :
"",
3254 descr[8] & 1 ?
" RRM" :
"");
3258 if (feature_is_current)
3261 #ifdef Libburn_print_feature_descriptorS
3262 fprintf(stderr,
"LIBBURN_EXPERIMENTAL : BUF = %d , Test Write = %d , DVD-RW = %d\n",
3263 !!(descr[4] & 64), !!(descr[4] & 4),
3268 phys_if_std = (descr[4] << 24) | (descr[5] << 16) |
3269 (descr[6] << 8) | descr[7];
3270 if (phys_if_std == 1)
3271 phys_name =
"SCSI Family";
3272 else if(phys_if_std == 2)
3273 phys_name =
"ATAPI";
3274 else if(phys_if_std == 3 || phys_if_std == 4 ||
3276 phys_name =
"IEEE 1394 FireWire";
3277 else if(phys_if_std == 7)
3278 phys_name =
"Serial ATAPI";
3279 else if(phys_if_std == 8)
3285 #ifdef Libburn_print_feature_descriptorS
3288 "LIBBURN_EXPERIMENTAL : Phys. Interface Standard %Xh \"%s\"\n",
3289 phys_if_std, phys_name);
3293 fprintf(stderr,
"LIBBURN_EXPERIMENTAL : CD SPEED = %d , page 2Ah = %d , SET STREAMING = %d\n",
3294 !!(descr[4] & 8), !!(descr[4] & 4),
3302 #ifdef Libburn_print_feature_descriptorS
3304 fprintf(stderr,
"LIBBURN_EXPERIMENTAL : %s = ",
3306 "Drive Serial Number" :
"Drive Firmware Date");
3321 #ifdef Libburn_print_feature_descriptorS
3322 for (i = 0; i < c_limit; i++)
3323 if (descr[4 + i] < 0x20 || descr[4 + i] > 0x7e
3324 || descr[4 + i] ==
'\\')
3325 fprintf(stderr,
"\\%2.2X",descr[4 + i]);
3327 fprintf(stderr,
"%c", descr[4 + i]);
3328 fprintf(stderr,
"\n");
3345 int alloc_len = 8, ret;
3360 if (alloc_len > 8 && ret > 0) {
3370 int *alloc_len,
int top_wanted)
3372 struct buffer *buf = NULL;
3373 int len, type, score, num_descr, max_score = -2000000000, i, sign = 1;
3374 int old_alloc_len, ret;
3375 off_t size, num_blocks;
3406 old_alloc_len = *alloc_len;
3407 *alloc_len = len + 4;
3408 if (old_alloc_len < 12)
3410 if (len + 4 > old_alloc_len)
3411 len = old_alloc_len - 4;
3419 + (dpt[1] << 16) + (dpt[2] << 8) + dpt[3];
3432 #ifdef Libburn_dvd_ram_as_bd_rE
3456 num_blocks = size = sign = i = max_score = num_descr = score = type = 0;
3464 if (top_wanted == 0x00 || top_wanted == 0x10)
3468 num_descr = (len - 8) / 8;
3469 for (i = 0; i < num_descr; i++) {
3472 size = num_blocks * (off_t) 2048;
3479 (dpt[5] << 16) + (dpt[6] << 8) + dpt[7];
3485 }
else if (type == 0x10) {
3487 }
else if(type == 0x13) {
3489 }
else if(type == 0x15) {
3496 }
else if(type == 0x26) {
3503 if (type == top_wanted)
3504 score += 1000000000;
3505 if (score > max_score) {
3521 int alloc_len = 4, ret;
3532 if (alloc_len >= 12 && ret > 0)
3564 "syncing cache", 0, 0);
3567 "Checked buffer %u times. Waited %u+%u times = %.3f s",
3581 sprintf(msg,
"Failed to synchronize drive cache");
3582 sprintf(msg + strlen(msg),
". SCSI error : ");
3609 struct buffer *buf = NULL;
3611 unsigned char *data;
3612 int alloc_len = 12, ret;
3626 memset(c->
page->
data, 0, alloc_len);
3640 (data[4]<<24)|(data[5]<<16)|(data[6]<<8)|data[7];
3642 (data[8]<<24)|(data[9]<<16)|(data[10]<<8)|data[11];
3654 if (fill < d->progress.buffer_min_fill && fill>=0)
3685 struct buffer *buf = NULL;
3687 int ret, tolerate_failure = 0, return_immediately = 0, i, format_type;
3688 int index, format_sub_type = 0, format_00_index, size_mode;
3689 int accept_count = 0;
3690 off_t num_of_blocks = 0, diff, format_size, i_size, format_00_max_size;
3691 off_t min_size = -1, max_size = -1;
3692 char *msg = NULL, descr[80 + 10 + 22];
3694 int full_format_type = 0x00;
3702 size_mode = (flag >> 1) & 3;
3720 num_of_blocks = size / 2048;
3728 goto selected_not_suitable;
3729 index = (flag >> 8) & 0xff;
3731 selected_not_suitable:;
3735 "Selected format is not suitable for libburn",
3745 goto unsuitable_media;
3748 if (!(format_type == 0x00 || format_type == 0x01 ||
3749 format_type == 0x10 ||
3750 format_type == 0x11 || format_type == 0x13 ||
3751 format_type == 0x15 || format_type == 0x26 ||
3752 format_type == 0x30 || format_type == 0x31 ||
3753 format_type == 0x32))
3754 goto selected_not_suitable;
3760 if (format_type != 0x26)
3761 for (i = 0; i < 3; i++)
3764 (16 - 8 * i)) & 0xff;
3765 if (format_type == 0x30 || format_type == 0x31) {
3766 format_sub_type = 0;
3770 format_sub_type = 3;
3774 format_sub_type = 2;
3776 }
else if (format_type == 0x32 ||
3778 if (flag & (1 << 16))
3779 format_sub_type = 0;
3781 format_sub_type = 1;
3791 return_immediately = 1;
3803 if ((size <= 0 && !(flag & 2)) || (flag & (4 | 8))) {
3805 memset(c->
page->
data + 4, 0xff, 4);
3806 num_of_blocks = 0xffffffff;
3811 sprintf(msg,
"FORMAT UNIT ignored. Already %s.",
3823 sprintf(descr,
"DVD+RW (fs=%d,rs=%d)",
3826 return_immediately = 1;
3845 tolerate_failure = 1;
3856 if (diff < num_of_blocks)
3857 num_of_blocks = diff;
3859 if (num_of_blocks > 0)
3866 sprintf(descr,
"DVD-RW quick grow");
3879 (flag & 4) ? full_format_type : 0x15);
3890 no_suitable_formatting_type:;
3894 "No suitable formatting type offered by drive",
3899 sprintf(descr,
"DVD-RW %s",
3900 format_type == 0x15 ?
"quick" :
"full");
3901 return_immediately = 1;
3908 index = format_00_index = -1;
3909 format_size = format_00_max_size = -1;
3913 if (format_type != 0x00 && format_type != 0x01)
3917 if (format_type != 0x00)
3919 if (i_size < format_size)
3921 format_size = i_size;
3924 }
else if (flag & 4) {
3929 if (format_type == 0x00) {
3930 if (i_size < format_size)
3932 if (i_size < format_00_max_size) {
3933 format_size = i_size;
3937 format_size = format_00_max_size;
3938 index = format_00_index;
3939 format_00_max_size = i_size;
3940 format_00_index = i;
3945 if (i_size > format_size) {
3946 format_size = i_size;
3954 (format_size < 0 || i_size < format_size)
3956 format_size = i_size;
3960 if(index < 0 && (flag & 4) && !(flag & 32)) {
3961 format_size = format_00_max_size;
3962 index = format_00_index;
3965 goto no_suitable_formatting_type;
3969 for (i = 0; i < 3; i++)
3972 (16 - 8 * i)) & 0xff;
3974 return_immediately = 1;
3977 if ((flag & 64) && format_type != 0x01) {
3998 goto no_suitable_formatting_type;
4000 goto no_suitable_formatting_type;
4004 if (format_type != 0x00 && format_type != 0x32)
4012 goto no_suitable_formatting_type;
4014 }
else if(size_mode == 2) {
4016 if(format_type != 0x32)
4018 }
else if(size_mode == 3) {
4019 if (format_type == 0x00) {
4026 #ifdef Libburn_bd_r_format_olD
4029 if(format_type != 0x32)
4033 if (format_size >= 0 && i_size >= format_size)
4036 format_size = i_size;
4042 if(format_type != 0x32)
4044 if (i_size < min_size || min_size < 0)
4046 if (i_size > max_size)
4054 if (i_size > format_size) {
4055 format_size = i_size;
4059 if (size_mode == 2 && index < 0 && !(flag & 32))
4062 goto no_suitable_formatting_type;
4064 if (flag & (1 << 16))
4065 format_sub_type = 0;
4067 format_sub_type = 1;
4069 #ifdef Libburn_bd_r_format_olD
4072 if (size_mode == 0 || size_mode == 1) {
4075 if (min_size < 0 || max_size < 0)
4076 goto no_suitable_formatting_type;
4080 size += 0x10000 - (size % 0x10000);
4081 if (size < min_size)
4082 goto no_suitable_formatting_type;
4083 else if(size > max_size)
4084 goto no_suitable_formatting_type;
4085 num_of_blocks = size / 2048;
4087 for (i = 0; i < 3; i++)
4093 for (i = 0; i < 3; i++)
4096 (16 - 8 * i)) & 0xff;
4099 return_immediately = 1;
4107 goto no_suitable_formatting_type;
4109 goto no_suitable_formatting_type;
4113 if (format_type != 0x00 && format_type != 0x30 &&
4114 format_type != 0x31)
4118 if(format_type != 0x31)
4120 }
else if(size_mode == 2) {
4122 if(format_type != 0x30)
4124 }
else if(size_mode == 3) {
4125 if (accept_count < 1)
4133 if ((flag & 64) && format_type == 0x00) {
4138 if(format_type != 0x30)
4141 if (accept_count == 1)
4146 #ifdef Libburn_bd_re_format_olD
4149 if(format_type != 0x30)
4153 if (format_size >= 0 && i_size >= format_size)
4156 format_size = i_size;
4162 if(format_type != 0x30)
4164 if (i_size < min_size || min_size < 0)
4166 if (i_size > max_size)
4174 if (i_size > format_size) {
4175 format_size = i_size;
4180 if (size_mode == 2 && index < 0 && !(flag & 32))
4183 goto no_suitable_formatting_type;
4185 if (format_type == 0x30 || format_type == 0x31) {
4187 format_sub_type = 0;
4193 "Drive does not support media certification",
4198 format_sub_type = 2;
4200 format_sub_type = 3;
4204 #ifdef Libburn_bd_re_format_olD
4207 if (size_mode == 0 || size_mode == 1) {
4210 if (min_size < 0 || max_size < 0)
4211 goto no_suitable_formatting_type;
4215 size += 0x10000 - (size % 0x10000);
4216 if (size < min_size)
4217 goto no_suitable_formatting_type;
4218 else if(size > max_size)
4219 goto no_suitable_formatting_type;
4220 num_of_blocks = size / 2048;
4222 for (i = 0; i < 3; i++)
4228 for (i = 0; i < 3; i++)
4231 (16 - 8 * i)) & 0xff;
4234 return_immediately = 1;
4242 sprintf(msg,
"Unsuitable media detected. Profile %4.4Xh %s",
4250 c->
page->
data[8] = (format_type << 2) | (format_sub_type & 3);
4253 if (format_type == 0x00 || format_type == 0x01 ||
4254 format_type == 0x31) {
4259 }
else if (format_type >= 0x10 && format_type <= 0x15) {
4266 sprintf(msg,
"Format type %2.2Xh \"%s\", blocks = %.f",
4267 format_type, descr, (
double) num_of_blocks);
4271 sprintf(msg,
"CDB: ");
4272 for (i = 0; i < 6; i++)
4273 sprintf(msg + strlen(msg),
"%2.2X ", c->
opcode[i]);
4277 sprintf(msg,
"Format list: ");
4278 for (i = 0; i < 12; i++)
4279 sprintf(msg + strlen(msg),
"%2.2X ", c->
page->
data[i]);
4285 #ifdef Libburn_do_not_format_dvd_ram_or_bd_rE
4288 "Formatting of %s not implemented yet - This is a dummy",
4304 if (c->
error && !tolerate_failure) {
4307 sprintf(msg,
"SCSI error on format_unit(%s): ", descr);
4317 }
else if ((!c->
error) && (format_type == 0x13 || format_type == 0x15))
4319 if (return_immediately)
4322 for (ret = 0; ret <= 0 ;) {
4349 (*sd)->
source = sd_source;
4363 int descr_type,
int *alloc_len,
int *max_descr,
4364 int *num_descr,
int flag)
4366 int len, i, b, ret, old_alloc_len;
4367 int exact_bit, read_speed, write_speed, start_speed;
4368 int min_write_speed = 0x7fffffff, max_write_speed = 0;
4369 int min_read_speed = 0x7fffffff, max_read_speed = 0;
4370 unsigned long end_lba;
4375 static int speed_debug = 0;
4378 old_alloc_len = *alloc_len;
4379 *alloc_len = len + 4;
4380 if (len + 4 > old_alloc_len)
4381 len = old_alloc_len - 4;
4382 *num_descr = ( *alloc_len - 8 ) / 16;
4383 if (*max_descr == 0) {
4384 *max_descr = *num_descr;
4387 if (old_alloc_len < 16)
4395 if (*num_descr > *max_descr)
4396 *num_descr = *max_descr;
4397 for (i = 0; i < *num_descr && (flag & 1); i++) {
4400 if (descr_type == 0x03) {
4401 exact_bit = !!(pd[8 + i*16] & 2);
4402 for (b = 0; b < 4 ; b++) {
4403 end_lba += ((
unsigned long int)
4404 pd[8 + i*16 + 4 + b])
4416 "LIBBURN_DEBUG: kB/s: write=%d read=%d end=%lu exact=%d\n",
4422 sd->
wrc = (pd[8 + i*16] >> 3 ) & 3;
4423 sd->
exact = exact_bit;
4424 sd->
mrw = pd[8 + i*16] & 1;
4431 for (b = 0; b < 4 ; b++) {
4432 start_speed += pd[8 + i*16 + 4 + b]
4434 end_lba += ((
unsigned long int)
4435 pd[8 + i*16 + 8 + b])
4443 "LIBBURN_DEBUG: start=%d end=%d lba=%lu\n",
4453 if (start_speed > 0 && start_speed < min_read_speed)
4454 min_read_speed = start_speed;
4455 if (start_speed > max_read_speed)
4456 max_read_speed = start_speed;
4466 if ((
int) end_lba < d->mdata->min_end_lba)
4477 if (min_write_speed < 0x7fffffff)
4479 if (max_write_speed > 0)
4485 if (max_read_speed > 0)
4498 int *alloc_len,
int *max_descr,
int flag)
4501 struct buffer *buf = NULL;
4512 if (descr_type != 0x00 && descr_type != 0x03)
4524 if (descr_type == 0x00)
4526 c->
opcode[8] = ( *max_descr >> 8 ) & 0xff;
4527 c->
opcode[9] = ( *max_descr >> 0 ) & 0xff;
4528 c->
opcode[10] = descr_type;
4536 #ifdef Libisofs_simulate_old_mmc1_drivE
4540 c->
sense[12] = 0x20;
4562 int alloc_len = 8, max_descr = 0, ret;
4572 if (max_descr > 0 && ret > 0) {
4577 &alloc_len, &max_descr, 0);
4583 if (max_descr > 0 && ret > 0) {
4585 max_descr = (alloc_len - 8) / 16;
4587 &alloc_len, &max_descr, 1);
4612 unsigned char *catalog = NULL;
4613 char isrc_text[13 + 21];
4627 pd[3] = (1 << 5) | 5;
4647 #ifdef Libburn_pioneer_dvr_216d_load_mode5
4670 pd[3] = ((3 * !!o->
multi) << 6) | (1 << 5) | 5;
4682 "Feature 21h Link Size = %d (expected 16)\n",
4730 else if (s != NULL) {
4736 memcpy(pd + 17, catalog, 13);
4743 if (tnum >= 0 && tnum < s->tracks) {
4751 sprintf(isrc_text + 5,
"%-2.2u",
4753 sprintf(isrc_text + 7,
"%-5.5u",
4764 memcpy(pd + 33, isrc_text, 12);
4776 int key, asc, ascq, silent;
4790 c->
opcode[7] = (amount >> 8) & 0xFF;
4791 c->
opcode[8] = amount & 0xFF;
4800 msg = calloc(1, 256);
4803 "SCSI error on read_10(%d,%d): ", start, amount);
4807 if (key == 5 && asc == 0x64 && ascq == 0x0) {
4825 buf->
bytes = amount * 2048;
4830 #ifdef Libburn_develop_quality_scaN
4835 int mmc_nec_optiarc_f3(
struct burn_drive *d,
int sub_op,
4836 int start_lba,
int rate_period,
4837 int *ret_lba,
int *error_rate1,
int *error_rate2)
4839 struct buffer *buf = NULL;
4842 int key, asc, ascq, ret;
4843 static unsigned char MMC_NEC_OPTIARC_F3[] =
4844 { 0xF3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
4863 c->
opcode[8] = rate_period;
4869 msg = calloc(1, 256);
4872 "SCSI error on nec_optiarc_f3(%d, %d, %d): ",
4873 sub_op, start_lba, rate_period);
4904 struct buffer *buf = NULL;
4906 int alloc_len= 8, ret;
4945 int media_type,
int layer_number,
int format,
4946 int min_len,
char **reply,
int *reply_len,
4949 struct buffer *buf = NULL;
4950 int old_alloc_len, len, ret;
4966 c->
opcode[1]= media_type;
4980 old_alloc_len = *alloc_len;
4981 *alloc_len = len + 2;
4982 if (old_alloc_len <= 4)
4984 if (len + 2 > old_alloc_len)
4985 len = old_alloc_len - 2;
4990 if (len - 2 < min_len)
4992 *reply = calloc(len - 2, 1);
4995 *reply_len = len - 2;
4996 memcpy(*reply, dpt, len - 2);
5006 int media_type,
int layer_number,
int format,
int min_len,
5007 char **reply,
int *reply_len,
int flag)
5009 int alloc_len = 4, ret;
5017 media_type, layer_number, format, min_len,
5018 reply, reply_len, 0);
5025 if (alloc_len < 12) {
5027 "READ DISC STRUCTURE announces only %d bytes of reply\n",
5049 #ifdef Libburn_enforce_structure_code_0x0E
5050 if (format == 0x0E) {
5051 alloc_len = min_len + 4;
5053 media_type, layer_number, format, min_len,
5054 reply, reply_len, 0);
5055 if (*reply_len < min_len || *reply == NULL)
5057 sprintf(msg,
"READ DISC STRUCTURE returns %d bytes of required %d\n",
5058 *reply_len + 4, min_len + 4);
5067 media_type, layer_number, format, min_len,
5068 reply, reply_len, 0);
5079 int manuf_idx,
int type_idx,
int rev_idx,
5080 char **product_id,
char **media_code1,
char **media_code2,
int flag)
5084 *product_id = calloc(17, 1);
5085 *media_code1 = calloc(9, 1);
5086 *media_code2 = calloc(8, 1);
5087 if (*product_id == NULL ||
5088 *media_code1 == NULL || *media_code2 == NULL)
5091 sprintf(*media_code1,
"%.6s", reply + manuf_idx);
5093 sprintf(*media_code1,
"%.8s", reply + manuf_idx);
5095 1 | ((flag & 1) << 1));
5098 sprintf(*media_code2,
"%.3s%s", reply + type_idx,
5099 (flag & 1) ?
"" :
"xxxx");
5101 1 | ((flag & 1) << 1));
5105 sprintf(*media_code2 + strlen(*media_code2) - 4,
"/%d",
5106 (
int) ((
unsigned char *) reply)[rev_idx]);
5108 sprintf(*product_id,
"%s/%s", *media_code1, *media_code2);
5122 char **product_id,
char **media_code1,
char **media_code2,
5123 char **book_type,
int flag)
5125 int prf, ret, reply_len, i, has_11h = -1, bt, start_lba, end_lba;
5126 int min, sec, fr, media_type = 0;
5127 char *reply = NULL, *wpt;
5129 static char *books[16] = {
5130 "DVD-ROM",
"DVD-RAM",
"DVD-R",
"DVD-RW",
5131 "HD DVD-ROM",
"HD DVD-RAM",
"HD DVD-R",
"unknown",
5132 "unknown",
"DVD+RW",
"DVD+R",
"unknown",
5133 "unknown",
"DVD+RW DL",
"DVD+R DL",
"unknown"};
5135 *product_id = *media_code1 = *media_code2 = *book_type = NULL;
5137 if (prf == 0x09 || prf == 0x0A) {
5139 *product_id = calloc(20, 1);
5140 *media_code1 = calloc(10, 1);
5141 *media_code2 = calloc(10, 1);
5142 if (*product_id == NULL ||
5143 *media_code1 == NULL || *media_code2 == NULL) {
5154 sprintf(*media_code1,
"%2.2dm%2.2ds%2.2df", min, sec, fr);
5156 sprintf(*media_code2,
"%2.2dm%2.2ds%2.2df", min, sec, fr);
5157 sprintf(*product_id,
"%s/%s", *media_code1, *media_code2);
5161 }
else if (prf == 0x11 || prf == 0x13 || prf == 0x14 || prf == 0x15) {
5172 if (reply[16] != 3 || reply[24] != 4) {
5176 *media_code1 = calloc(19, 1);
5177 *media_code2 = strdup(
"");
5178 if (*media_code1 == NULL || *media_code2 == NULL) {
5182 memcpy(*media_code1, reply + 17, 6);
5183 memcpy(*media_code1 + 6, reply + 25, 6);
5187 for (i = 0; i < 18; i++)
5188 if ((*media_code1)[i])
5189 *(wpt++) = (*media_code1)[i];
5192 1 | ((flag & 1) << 1));
5195 *product_id = strdup(*media_code1);
5196 if (*product_id == NULL) {
5201 }
else if (prf == 0x1a || prf == 0x1b || prf == 0x2b) {
5208 for (i = 0; i < reply_len; i += 4) {
5209 if (reply[i] == 0x11 && (reply[i + 1] & 64))
5224 product_id, media_code1, media_code2,
5229 }
else if (prf == 0x41 || prf == 0x43 || prf == 0x40 || prf == 0x42) {
5236 if (reply[0] !=
'D' || reply[1] !=
'I') {
5242 product_id, media_code1, media_code2,
5258 &reply, &reply_len, 0);
5261 bt = (reply[0] >> 4) & 0xf;
5262 *book_type = calloc(80 + strlen(books[bt]), 1);
5263 if (*book_type == NULL) {
5267 sprintf(*book_type,
"%2.2Xh, %s book [revision %d]",
5268 bt, books[bt], reply[0] & 0xf);
5270 if (has_11h == 0 && *product_id == NULL && reply_len > 28) {
5274 media_code1, media_code2,
5276 if (*product_id == NULL) {
5287 if (*product_id != NULL)
5289 if (*media_code1 != NULL)
5291 if (*media_code2 != NULL)
5293 if (*book_type != NULL)
5295 *product_id = *media_code1 = *media_code2 = *book_type = NULL;
5305 int *alloc_blocks,
int *free_blocks,
int flag)
5307 int ret, reply_len, prf;
5311 if (!(prf == 0x41 || prf == 0x43 || prf == 0x42))
5335 char **book_name,
int *part_version,
int *num_layers,
5336 int *num_blocks,
int flag)
5338 int ret, reply_len, prf;
5340 static char book_names[][16] = {
5341 "DVD-ROM",
"DVD-RAM",
"DVD-R",
"DVD-RW",
5342 "HD DVD-ROM",
"HD DVD-RAM",
"HD DVD-R",
"unknown",
5343 "unknown",
"DVD+RW",
"DVD+R",
"unknown",
"unknown",
5344 "unknown",
"DVD+RW DL",
"DVD+R DL",
"unknown"
5348 if (!(prf == 0x11 || prf == 0x13 || prf == 0x14 || prf == 0x15 ||
5355 if(reply_len < 12) {
5358 "READ DISC STRUCTURE format 10h: Less than 12 bytes",
5362 *disk_category = (reply[0] >> 4) & 0xf;
5363 *book_name = book_names[*disk_category];
5364 *part_version = reply[0] & 0xf;
5365 *num_layers = ((reply[2] >> 5) & 0x3) + 1;
5366 *num_blocks = ((reply[9] << 16) | (reply[10] << 8) | reply[11]) -
5367 ((reply[5] << 16) | (reply[6] << 8) | reply[7]) + 1;
5440 #ifdef Libburn_disc_with_incomplete_sessioN
5474 (*text_len) += strlen(to_add);
5476 strcat(text, to_add);
5482 unsigned char *to_add,
int add_length,
5487 (*text_len) += 3 * add_length;
5491 for (i = 0; i < add_length; i++)
5492 sprintf(text + l + 3 * i,
" %2.2x", to_add[i]);
5496 unsigned char flags,
5497 unsigned char additional_length,
5498 unsigned char *feature_data,
5499 char **text,
int flag)
5501 char *feature_name, addon[320], *cpt;
5502 int text_len, ret, i, pass;
5503 unsigned int phys_is, lmt, num;
5505 static unsigned short feature_codes[] = {
5506 0x00, 0x01, 0x02, 0x03,
5507 0x04, 0x10, 0x1d, 0x1e,
5508 0x1f, 0x20, 0x21, 0x22,
5509 0x23, 0x24, 0x25, 0x26,
5510 0x27, 0x28, 0x29, 0x2a,
5511 0x2b, 0x2c, 0x2d, 0x2e,
5512 0x2f, 0x33, 0x37, 0x38,
5513 0x3a, 0x3b, 0x40, 0x41,
5514 0x42, 0x50, 0x51, 0x80,
5515 0x100, 0x101, 0x102, 0x104,
5516 0x105, 0x106, 0x107, 0x108,
5517 0x109, 0x10a, 0x10b, 0x10c,
5521 static char feature_names[][40] = {
5522 "Profile List",
"Core",
"Morphing",
"Removable Medium",
5523 "Write Protect",
"Random Readable",
"Multi-Read",
"CD Read",
5524 "DVD Read",
"Random Writable",
5525 "Incremental Streaming Writable",
"Sector Erasable",
5526 "Formattable",
"Hardware Defect Management",
"Write Once",
5527 "Restricted Overwrite",
5528 "CD-RW CAV Write",
"MRW",
"Enhanced Defect Reporting",
5530 "DVD+R",
"Rigid Restricted Overwrite",
"CD Track at Once",
5532 "DVD-R/-RW Write",
"Layer Jump Recording",
5533 "CD-RW Media Write Support",
"BD-R POW",
5534 "DVD+RW Dual Layer",
"DVD+R Dual Layer",
"BD Read Feature",
5536 "TSR",
"HD DVD Read",
"HD DVD Write",
"Hybrid Disc",
5537 "Power Management",
"SMART",
"Embedded Changer",
5538 "Microcode Upgrade",
5539 "Timeout",
"DVD-CSS",
"Real Time Streaming",
5540 "Drive Serial Number",
5541 "Media Serial Number",
"DCBs",
"DVD CPRM",
5542 "Firmware Information",
5546 static unsigned short legacy_codes[] = {
5547 0x30, 0x31, 0x32, 0x103, 0xffff
5549 static unsigned int phys_is_codes[] = {
5550 0x00, 0x01, 0x02, 0x03,
5551 0x04, 0x05, 0x06, 0x07,
5555 static char phys_is_names[][40] = {
5556 "Unspecified",
"SCSI_Family",
"ATAPI",
"IEEE_1394-1995",
5557 "IEEE_1394A",
"Fibre_Channel",
"IEEE_1394B",
"Serial_ATAPI",
5558 "USB",
"Vendor_Unique",
5561 static char load_mech_names[8][40] = {
5562 "Caddy/Slot",
"Tray",
"Pop-up",
"(Reserved)",
5563 "Embedded_changer_individually",
"Embedded_changer_magazine",
5564 "(Reserved)",
"(Reserved)"
5567 feature_name =
"(Reserved)";
5568 for (i = 0; feature_codes[i] != 0xffff; i++) {
5569 if (feature_codes[i] == feature_code) {
5570 feature_name = feature_names[i];
5574 if (feature_codes[i] == 0xffff) {
5575 for (i = 0; legacy_codes[i] != 0xffff; i++) {
5576 if (legacy_codes[i] == feature_code) {
5577 feature_name =
"(Legacy)";
5582 if (feature_code >= 0xff00 && feature_code <= 0xffff)
5583 feature_name =
"(Vendor Specific)";
5586 for (pass = 0; pass < 2; pass++) {
5592 sprintf(addon,
"%4.4x %c : ", feature_code,
5593 (flags & 1) ?
'+' :
'-');
5599 sprintf(addon,
" : %1.1x,%c :",
5600 (flags >> 2) & 15, (flags & 2) ?
'P' :
'N');
5604 feature_data, (
int) additional_length, pass);
5607 if (feature_code == 0x01 && additional_length >= 4) {
5610 cpt =
"(Not_Recognizable)";
5611 for (i = 0; phys_is_codes[i] != 0xffffffff; i++) {
5612 if (phys_is_codes[i] == phys_is) {
5613 cpt = phys_is_names[i];
5619 if (additional_length >= 9)
5620 num = feature_data[8];
5622 " PhysInterface=%x/%s , INQ2=%d , DBE=%d",
5623 phys_is, cpt, (num >> 1) & 1, num & 1);
5626 }
else if (feature_code == 0x03 && additional_length >= 1) {
5630 num = feature_data[0];
5631 lmt = (num >> 5) & 7;
5633 " LoadMechType=%x/%s , Eject=%d , PvntJmpr=%d , Lock=%d",
5634 lmt, load_mech_names[lmt], (num >> 3) & 1,
5635 (num >> 2) & 1, num & 1);
5638 }
else if (feature_code == 0x10 && additional_length >= 4) {
5641 if (additional_length >= 6)
5642 num = (feature_data[4] << 8) | feature_data[5];
5643 sprintf(addon,
" BlockSize=%d , Blocking=%u",
5646 if (additional_length >= 7)
5647 num = feature_data[6];
5648 sprintf(addon + strlen(addon),
" , PP=%d", num & 1);
5651 }
else if (feature_code == 0x1e && additional_length >= 1) {
5653 sprintf(addon,
" DAP=%d , C2Flags=%d , CDText=%d",
5654 (feature_data[0] >> 7) & 1,
5655 (feature_data[0] >> 1) & 1,
5656 feature_data[0] & 1);
5659 }
else if (feature_code == 0x1f && additional_length >= 1) {
5662 if (additional_length >= 3)
5663 num = feature_data[2];
5664 sprintf(addon,
" MULTI10=%d , DualR=%d",
5665 feature_data[0] & 1, num & 1);
5668 }
else if (feature_code == 0x20 && additional_length >= 4) {
5672 if (additional_length >= 8)
5674 sprintf(addon,
" LastLBA=%d , BlockSize=%u",
5677 if (additional_length >= 10)
5678 num = (feature_data[8] << 8) | feature_data[9];
5679 sprintf(addon + strlen(addon),
" , Blocking=%u", num);
5681 if (additional_length >= 11)
5682 num = feature_data[10];
5683 sprintf(addon + strlen(addon),
" , PP=%u", num);
5686 }
else if (feature_code == 0x21 && additional_length >= 2) {
5692 if (additional_length >= 3)
5693 num = feature_data[2];
5695 " DataBlockTypes=%2.2x%2.2x , TRIO=%d , ARSV=%d , BUF=%d",
5696 feature_data[0], feature_data[1],
5697 (num >> 2) & 1, (num >> 1) & 1, num & 1);
5699 if (additional_length >= 4)
5700 num = feature_data[3];
5701 sprintf(addon + strlen(addon),
" , NumLinkSizes=%d",
5705 }
else if (feature_code == 0x23 && additional_length >= 1) {
5707 num = feature_data[0];
5709 " RENoSA=%d , Expand=%d , QCert=%d , Cert=%d",
5710 (num >> 3) & 1, (num >> 2) & 1,
5711 (num >> 1) & 1, num & 1);
5713 if (additional_length >= 5)
5714 num = feature_data[4];
5715 sprintf(addon + strlen(addon),
" , RRM=%d", num & 1);
5718 }
else if (feature_code == 0x24 && additional_length >= 1) {
5720 sprintf(addon,
" SSA=%d", (feature_data[0] >> 7) & 1);
5723 }
else if (feature_code == 0x28 && additional_length >= 1) {
5725 num = feature_data[0];
5727 " DVDPWrite=%d , DVDPRead=%d , CDWrite=%d",
5728 (num >> 2) & 1, (num >> 1) & 1, num & 1);
5731 }
else if (feature_code == 0x2a && additional_length >= 1) {
5734 if (additional_length >= 2)
5735 num = feature_data[1];
5737 " Write=%d , QuickStart=%d , CloseOnly=%d",
5738 feature_data[0] & 1, (num >> 1) & 1, num & 1);
5741 }
else if (feature_code == 0x2b && additional_length >= 1) {
5743 sprintf(addon,
" Write=%d", feature_data[0] & 1);
5746 }
else if (feature_code == 0x2c && additional_length >= 1) {
5748 num = feature_data[0];
5750 " DSDG=%d , DSDR=%d , Intermediate=%d , Blank=%d",
5751 (num >> 3) & 1, (num >> 2) & 1,
5752 (num >> 1) & 1, num & 1);
5755 }
else if (feature_code == 0x2d && additional_length >= 1) {
5757 num= feature_data[0];
5759 " BUF=%d , RWRaw=%d , RWPack=%d , TestWrite=%d , CD-RW=%d , RWSubcode=%d",
5760 (num >> 6) & 1, (num >> 4) & 1,
5761 (num >> 3) & 1, (num >> 2) & 1,
5762 (num >> 1) & 1, num & 1);
5764 if (additional_length >= 4)
5765 num = (feature_data[2] << 8) | feature_data[3];
5766 sprintf(addon + strlen(addon),
" , DataTypeSupp=%4.4x",
5770 }
else if (feature_code == 0x2e && additional_length >= 1) {
5772 num = feature_data[0];
5774 " BUF=%d , SAO=%d , RawMS=%d , Raw=%d , TestWrite=%d , CD-RW=%d , RW=%d",
5775 (num >> 6) & 1, (num >> 5) & 1, (num >> 4) & 1,
5776 (num >> 3) & 1, (num >> 2) & 1,
5777 (num >> 1) & 1, num & 1);
5779 if (additional_length >= 4)
5780 num = (feature_data[1] << 16) |
5781 (feature_data[2] << 8) | feature_data[3];
5782 sprintf(addon + strlen(addon),
5783 " , MaxCueSheetLen=%u", num);
5786 }
else if (feature_code == 0x2f && additional_length >= 1) {
5788 num = feature_data[0];
5790 " BUF=%d , RDL=%d , TestWrite=%d , DVDRW=%d",
5791 (num >> 6) & 1, (num >> 3) & 1,
5792 (num >> 2) & 1, (num >> 1) & 1);
5795 }
else if (feature_code == 0x33 && additional_length >= 4) {
5797 sprintf(addon,
" NumLinkSizes=%d", feature_data[3]);
5800 }
else if (feature_code == 0x37 && additional_length >= 2) {
5803 for (i = 7; i >= 0; i--) {
5804 sprintf(addon + strlen(addon),
5806 i, (feature_data[1] >> i) & 1,
5811 }
else if (feature_code == 0x3a && additional_length >= 2) {
5814 " Write=%d , QuickStart=%d , CloseOnly=%d",
5815 feature_data[0] & 1,
5816 (feature_data[1] >> 1) & 1,
5817 feature_data[1] & 1);
5820 }
else if (feature_code == 0x3b && additional_length >= 1) {
5822 sprintf(addon,
" Write=%d", feature_data[0] & 1);
5825 }
else if (feature_code == 0x50 && additional_length >= 1) {
5828 if (additional_length >= 3)
5829 num = feature_data[2];
5830 sprintf(addon,
" HDDVDR=%d , HDDVDRAM=%d",
5831 feature_data[0] & 1, num & 1);
5834 }
else if (feature_code == 0x51 && additional_length >= 1) {
5837 if (additional_length >= 3)
5838 num = feature_data[2];
5839 sprintf(addon,
" HDDVDR=%d , HDDVDRAM=%d",
5840 feature_data[0] & 1, num & 1);
5843 }
else if (feature_code == 0x101 && additional_length >= 1) {
5845 sprintf(addon,
" PP=%d", feature_data[0] & 1);
5848 }
else if (feature_code == 0x102 && additional_length >= 1) {
5851 if (additional_length >= 4)
5852 num = feature_data[3];
5853 sprintf(addon,
" SCC=%d , SDP=%d , HighestSlotNo=%u",
5854 (feature_data[0] >> 4) & 1,
5855 (feature_data[0] >> 2) & 1, num & 31);
5858 }
else if (feature_code == 0x105 && additional_length >= 1) {
5861 if (additional_length >= 4)
5862 num = (feature_data[2] << 8) | feature_data[3];
5863 sprintf(addon,
" Group3=%d , UnitLength=%u",
5864 feature_data[0] & 1, num);
5867 }
else if (feature_code == 0x106 && additional_length >= 4) {
5869 sprintf(addon,
" CSSVersion=%d",
5870 (
int) feature_data[3]);
5873 }
else if (feature_code == 0x107 && additional_length >= 1) {
5875 num = feature_data[0];