xorriso  1.5.4.pl02
About: GNU xorriso creates, loads, manipulates and writes ISO 9660 filesystem images with Rock Ridge extensions. It is suitable for incremental data backup and for production of bootable ISO 9660 images. GNU xorriso is a statical compilation of the libraries libburn, libisofs, libisoburn, and libjte.
  Fossies Dox: xorriso-1.5.4.pl02.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

mmc.c
Go to the documentation of this file.
1 /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
2 
3 /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
4  Copyright (c) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>
5  Provided under GPL version 2 or later.
6 */
7 
8 #ifdef HAVE_CONFIG_H
9 #include "../config.h"
10 #endif
11 
12 
13 /* ts A61009 */
14 /* #include <a ssert.h> */
15 
16 #include <stdio.h>
17 #include <string.h>
18 #include <unistd.h>
19 #include <stdlib.h>
20 #include <sys/time.h>
21 #include <pthread.h>
22 #include <ctype.h>
23 
24 /* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
25 #ifndef O_BINARY
26 #define O_BINARY 0
27 #endif
28 
29 #include "error.h"
30 #include "sector.h"
31 #include "libburn.h"
32 #include "transport.h"
33 #include "mmc.h"
34 #include "spc.h"
35 #include "drive.h"
36 #include "debug.h"
37 #include "toc.h"
38 #include "structure.h"
39 #include "options.h"
40 #include "util.h"
41 #include "init.h"
42 
43 
44 /* ts A70223 : in init.c */
46 
47 static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len);
48 
49 
50 #ifdef Libburn_log_in_and_out_streaM
51 /* <<< ts A61031 */
52 #include <sys/types.h>
53 #include <sys/stat.h>
54 #include <fcntl.h>
55 #endif /* Libburn_log_in_and_out_streaM */
56 
57 
58 /* ts A61005 */
59 #include "libdax_msgs.h"
60 extern struct libdax_msgs *libdax_messenger;
61 
62 
63 /* ts A61219 : Based on knowledge from dvd+rw-tools-7.0 and mmc5r03c.pdf */
64 #define Libburn_support_dvd_plus_rW 1
65 
66 /* ts A61229 */
67 #define Libburn_support_dvd_minusrw_overW 1
68 
69 /* ts A70112 */
70 /* ts A80410 : applies to BD-RE too */
71 #define Libburn_support_dvd_raM 1
72 
73 /* ts A70129 */
74 #define Libburn_support_dvd_r_seQ 1
75 
76 /* ts A70306 */
77 #define Libburn_support_dvd_plus_R 1
78 
79 /* ts A70509 : handling 0x41 as read-only type */
80 #define Libburn_support_bd_r_readonlY 1
81 
82 /* ts A81208 */
83 #define Libburn_support_bd_plus_r_srM 1
84 
85 
86 /* ts A80410 : <<< Dangerous experiment: Pretend that DVD-RAM is BD-RE
87  # define Libburn_dvd_ram_as_bd_rE yes
88 */
89 /* ts A80509 : <<< Experiment: pretend that DVD-ROM and CD-ROM are other media
90  like BD-ROM (0x40), BD-R seq (0x41), BD-R random (0x42)
91  # define Libburn_rom_as_profilE 0x40
92 */
93 
94 
95 /* ts A80425 : Prevents command FORMAT UNIT for DVD-RAM or BD-RE.
96  Useful only to test the selection of format descriptors without
97  actually formatting the media.
98  # define Libburn_do_not_format_dvd_ram_or_bd_rE 1
99 */
100 
101 
102 /* ts A90603 : Simulate the command restrictions of an old MMC-1 drive
103  # define Libisofs_simulate_old_mmc1_drivE 1
104 */
105 
106 
107 /* DVD/BD progress report:
108  ts A61219 : It seems to work with a used (i.e. thoroughly formatted) DVD+RW.
109  Error messages of class DEBUG appear because of inability to
110  read TOC or track info. Nevertheless, the written images verify.
111  ts A61220 : Burned to a virgin DVD+RW by help of new mmc_format_unit()
112  (did not test whether it would work without). Burned to a
113  not completely formatted DVD+RW. (Had worked before without
114  mmc_format_unit() but i did not exceed the formatted range
115  as reported by dvd+rw-mediainfo.)
116  ts A61221 : Speed setting now works for both of my drives. The according
117  functions in dvd+rw-tools are a bit intimidating to the reader.
118  I hope it is possible to leave much of this to the drive.
119  And if it fails ... well, it's only speed setting. :))
120  ts A61229 : Burned to several DVD-RW formatted to mode Restricted Overwrite
121  by dvd+rw-format. Needs Libburn_support_dvd_minusrw_overW.
122  ts A61230 : Other than growisofs, libburn does not send a mode page 5 for
123  such DVD-RW (which the MMC-5 standard does deprecate) and it
124  really seems to work without such a page.
125  ts A70101 : Formatted DVD-RW media. Success is varying with media, but
126  dvd+rw-format does not do better with the same media.
127  ts A70112 : Support for writing to DVD-RAM.
128  ts A70130 : Burned a first non-multi sequential DVD-RW. Feature 0021h
129  Incremental Recording vanishes after that and media thus gets
130  not recognized as suitable any more.
131  After a run with -multi another disc still offers 0021h .
132  dvd+rw-mediainfo shows two tracks. The second, an afio archive
133  is readable by afio. Third and forth veryfy too. Suddenly
134  dvd+rw-mediainfo sees lba 0 with track 2. But #2 still verifies
135  if one knows its address.
136  ts A70203 : DVD-RW need to get blanked fully. Then feature 0021h persists.
137  Meanwhile Incremental streaming is supported like CD TAO:
138  with unpredicted size, multi-track, multi-session.
139  ts A70205 : Beginning to implement DVD-R[W] DAO : single track and session,
140  size prediction mandatory.
141  ts A70208 : Finally made tests with DVD-R. Worked exactly as new DVD-RW.
142  ts A70306 : Implemented DVD+R (always -multi for now)
143  ts A70330 : Allowed finalizing of DVD+R.
144  ts A80228 : Made DVD+R/DL support official after nightmorph reported success
145  in http://libburnia-project.org/ticket/13
146  ts A80416 : drive->do_stream_recording brings DVD-RAM to full nominal
147  writing speed at cost of no defect management.
148  ts A80416 : Giulio Orsero reports success with BD-RE writing. With
149  drive->do_stream_recording it does full nominal speed.
150  ts A80506 : Giulio Orsero reports success with BD-RE formatting.
151  BD-RE is now an officially supported profile.
152  ts A81209 : The first two sessions have been written to BD-R SRM
153  (auto formatted without Defect Management).
154  ts A90107 : BD-R is now supported media type
155 */
156 
157 /* ts A70519 : With MMC commands of data direction FROM_DRIVE:
158  Made struct command.dxfer_len equal to Allocation Length
159  of MMC commands. Made sure that not more bytes are allowed
160  for transfer than there are available.
161 */
162 
163 
164 /* ts A70711 Trying to keep writing from clogging the SCSI driver due to
165  full buffer at burner drive: 0=waiting disabled, 1=enabled
166  These are only defaults which can be overwritten by
167  burn_drive_set_buffer_waiting()
168 */
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
175 
176 /* ts B31107 The minimum values to be applied if maximum read speed is
177  requested. Some drives tell only the currently set speed and
178  thus cannot be made faster by using the highest told value.
179  (The fractions get added or subtracted to yield an integer
180  number on the safe side of the intended limit.)
181 */
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)
185 
186 /* ts B31114 The maximum values for minimum speed
187 */
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)
191 
192 
193 static unsigned char MMC_GET_MSINFO[] =
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 };
196 static unsigned char MMC_GET_TOC_FMT0[] = { 0x43, 0, 0, 0, 0, 0, 0, 16, 0, 0 };
197 static unsigned char MMC_GET_ATIP[] = { 0x43, 2, 4, 0, 0, 0, 0, 16, 0, 0 };
198 static unsigned char MMC_GET_LEADTEXT[] = { 0x43, 2, 5, 0, 0, 0, 0, 4, 0, 0 };
199 static unsigned char MMC_GET_DISC_INFO[] =
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 };
204 static unsigned char MMC_SET_SPEED[] =
205  { 0xBB, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
206 static unsigned char MMC_WRITE_12[] =
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 };
209 
210 /* ts A61201 : inserted 0, before 16, */
211 static unsigned char MMC_GET_CONFIGURATION[] =
212  { 0x46, 0, 0, 0, 0, 0, 0, 16, 0, 0 };
213 
214 static unsigned char MMC_SYNC_CACHE[] = { 0x35, 0, 0, 0, 0, 0, 0, 0, 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 };
217 static unsigned char MMC_TRACK_INFO[] = { 0x52, 0, 0, 0, 0, 0, 0, 16, 0, 0 };
218 
219 static unsigned char MMC_SEND_CUE_SHEET[] =
220  { 0x5D, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
221 
222 /* ts A61023 : get size and free space of drive buffer */
223 static unsigned char MMC_READ_BUFFER_CAPACITY[] =
224  { 0x5C, 0, 0, 0, 0, 0, 0, 16, 0, 0 };
225 
226 /* ts A61219 : format DVD+RW (and various others) */
227 static unsigned char MMC_FORMAT_UNIT[] = { 0x04, 0x11, 0, 0, 0, 0 };
228 
229 /* ts A61221 :
230  To set speed for DVD media (0xBB is for CD but works on my LG GSA drive) */
231 static unsigned char MMC_SET_STREAMING[] =
232  { 0xB6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
233 
234 /* ts A61225 :
235  To obtain write speed descriptors (command can do other things too) */
236 static unsigned char MMC_GET_PERFORMANCE[] =
237  { 0xAC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
238 
239 /* ts A70108 : To obtain info about drive and media formatting opportunities */
240 static unsigned char MMC_READ_FORMAT_CAPACITIES[] =
241  { 0x23, 0, 0, 0, 0, 0, 0, 0, 0, 0};
242 
243 /* ts A70205 : To describe the layout of a DVD-R[W] DAO session */
244 static unsigned char MMC_RESERVE_TRACK[] =
245  { 0x53, 0, 0, 0, 0, 0, 0, 0, 0, 0};
246 
247 /* ts A70812 : Read data sectors (for types with 2048 bytes/sector only) */
248 static unsigned char MMC_READ_10[] =
249  { 0x28, 0, 0, 0, 0, 0, 0, 0, 0, 0};
250 
251 /* ts A81210 : Determine the upper limit of readable data size */
252 static unsigned char MMC_READ_CAPACITY[] =
253  { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0};
254 
255 /* ts A90903 : Obtain media type specific information. E.g. manufacturer.
256 */
257 static unsigned char MMC_READ_DISC_STRUCTURE[] =
258  { 0xAD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
259 
260 /* ts B21125 : An alternative to BEh READ CD
261 */
262 static unsigned char MMC_READ_CD_MSF[] =
263  { 0xB9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
264 
266 
267 int mmc_function_spy(struct burn_drive *d, char * text)
268 {
270  fprintf(stderr,"libburn: experimental: mmc_function_spy: %s\n",
271  text);
272  if (d == NULL)
273  return 1;
274  if (d->drive_role != 1) {
275  char msg[4096];
276 
277  sprintf(msg, "Emulated drive caught in SCSI adapter \"%s\"",
278  text);
280  0x0002014c,
282  msg, 0, 0);
283  d->cancel = 1;
284  return 0;
285  }
286  return 1;
287 }
288 
289 int mmc_function_spy_ctrl(int do_tell)
290 {
291  mmc_function_spy_do_tell= !!do_tell;
292  return 1;
293 }
294 
295 
296 /* ts A70201 */
297 int mmc_four_char_to_int(unsigned char *data)
298 {
299  return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
300 }
301 
302 
303 /* ts A70201 */
304 int mmc_int_to_four_char(unsigned char *data, int num)
305 {
306  data[0] = (num >> 24) & 0xff;
307  data[1] = (num >> 16) & 0xff;
308  data[2] = (num >> 8) & 0xff;
309  data[3] = num & 0xff;
310  return 1;
311 }
312 
313 
314 static int mmc_start_for_bit0 = 0;
315 
316 /* @param flag bit0= the calling function should need no START UNIT.
317  (Handling depends on mmc_start_for_bit0)
318 */
319 int mmc_start_if_needed(struct burn_drive *d, int flag)
320 {
321  if (!d->is_stopped)
322  return 2;
323  if ((flag & 1) && !mmc_start_for_bit0)
324  return 2;
325  d->start_unit(d);
326  d->is_stopped = 0;
327  return 1;
328 }
329 
330 
331 int mmc_send_cue_sheet(struct burn_drive *d, struct cue_sheet *s)
332 {
333  struct buffer *buf = NULL;
334  struct command *c;
335 
336  c = &(d->casual_command);
337  mmc_start_if_needed(d, 0);
338  if (mmc_function_spy(d, "mmc_send_cue_sheet") <= 0)
339  return 0;
340  BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
342  c->retry = 1;
343  c->page = buf;
344  c->page->bytes = s->count * 8;
345  c->page->sectors = 0;
346  c->opcode[6] = (c->page->bytes >> 16) & 0xFF;
347  c->opcode[7] = (c->page->bytes >> 8) & 0xFF;
348  c->opcode[8] = c->page->bytes & 0xFF;
349  c->dir = TO_DRIVE;
350  memcpy(c->page->data, s->data, c->page->bytes);
351  d->issue_command(d, c);
352 ex:;
353  BURN_FREE_MEM(buf);
354  if (c->error) {
355  d->cancel = 1;
356  scsi_notify_error(d, c, c->sense, 18, 2);
357  }
358  return !c->error;
359 }
360 
361 
362 /* ts A70205 : Announce size of a DVD-R[W] DAO session.
363  @param size The size in bytes to be announced to the drive.
364  It will get rounded up to align to 32 KiB.
365 */
366 int mmc_reserve_track(struct burn_drive *d, off_t size)
367 {
368  struct command *c;
369  int lba;
370  char msg[80];
371 
372  c = &(d->casual_command);
373  mmc_start_if_needed(d, 0);
374  if (mmc_function_spy(d, "mmc_reserve_track") <= 0)
375  return 0;
376 
378  c->retry = 1;
379 
380  lba = size / 2048;
381  if (size % 2048)
382  lba++;
383  mmc_int_to_four_char(c->opcode+5, lba);
384 
385  sprintf(msg, "reserving track of %d blocks", lba);
386  libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
388  msg, 0, 0);
389 
390  c->page = NULL;
391  c->dir = NO_TRANSFER;
393  d->issue_command(d, c);
394  if (c->error) {
395  d->cancel = 1;
396  scsi_notify_error(d, c, c->sense, 18, 2);
397  }
398  return !c->error;
399 }
400 
401 
402 /* ts A70201 :
403  Common track info fetcher for mmc_get_nwa() and mmc_fake_toc()
404 */
405 int mmc_read_track_info(struct burn_drive *d, int trackno, struct buffer *buf,
406  int alloc_len)
407 {
408  struct command *c;
409 
410  c = &(d->casual_command);
411  mmc_start_if_needed(d, 1);
412  if (mmc_function_spy(d, "mmc_read_track_info") <= 0)
413  return 0;
414 
416  c->dxfer_len = alloc_len;
417  c->opcode[7] = (c->dxfer_len >> 8) & 0xff;
418  c->opcode[8] = c->dxfer_len & 0xff;
419  c->retry = 1;
420  c->opcode[1] = 1;
421  if(trackno<=0) {
422  if (d->current_profile == 0x1a || d->current_profile == 0x13 ||
423  d->current_profile == 0x12 || d->current_profile == 0x42 ||
424  d->current_profile == 0x43)
425  /* DVD+RW , DVD-RW restricted overwrite , DVD-RAM
426  BD-R random recording, BD-RE */
427  trackno = 1;
428  else if (d->current_profile == 0x10 ||
429  d->current_profile == 0x11 ||
430  d->current_profile == 0x14 ||
431  d->current_profile == 0x15 ||
432  d->current_profile == 0x40 ||
433  d->current_profile == 0x41)
434  /* DVD-ROM , DVD-R[W] Sequential ,
435  BD-ROM , BD-R sequential */
436  trackno = d->last_track_no;
437  else /* mmc5r03c.pdf: valid only for CD, DVD+R, DVD+R DL */
438  trackno = 0xFF;
439  }
440  mmc_int_to_four_char(c->opcode + 2, trackno);
441  c->page = buf;
442  memset(buf->data, 0, BUFFER_SIZE);
443  c->dir = FROM_DRIVE;
444  d->issue_command(d, c);
445  if (c->error)
446  return 0;
447  return 1;
448 }
449 
450 
451 /* ts A61110 : added parameters trackno, lba, nwa. Redefined return value.
452  @return 1=nwa is valid , 0=nwa is not valid , -1=error */
453 /* ts A70201 : outsourced 52h READ TRACK INFO command */
454 int mmc_get_nwa(struct burn_drive *d, int trackno, int *lba, int *nwa)
455 {
456  struct buffer *buf = NULL;
457  int ret, num, alloc_len = 20, err;
458  unsigned char *data;
459  char *msg = NULL;
460 
461  if (trackno <= 0)
462  d->next_track_damaged = 0;
463  mmc_start_if_needed(d, 1);
464  if (mmc_function_spy(d, "mmc_get_nwa") <= 0)
465  {ret = -1; goto ex;}
466 
467  /* ts B00327 : Avoid to inquire unsuitable media states */
469  {ret = 0; goto ex;}
470 
471  BURN_ALLOC_MEM(buf, struct buffer, 1);
472  ret = mmc_read_track_info(d, trackno, buf, alloc_len);
473  if (ret <= 0)
474  goto ex;
475  data = buf->data;
476  *lba = mmc_four_char_to_int(data + 8);
477  *nwa = mmc_four_char_to_int(data + 12);
478  num = mmc_four_char_to_int(data + 16);
479 
480  /* Pioneer BD-RW BDR-205 and LITE-ON LTR-48125S return -150 as *nwa
481  of blank media */
482  if (*nwa < *lba && d->status == BURN_DISC_BLANK)
483  *nwa = *lba;
484 
485 #ifdef Libburn_pioneer_dvr_216d_load_mode5
486  /* >>> memorize track mode : data[6] & 0xf */;
487 #endif
488 
489 { static int fake_damage = 0; /* bit0= damage on , bit1= NWA_V off */
490 
491  if (fake_damage & 1)
492  data[5] |= 32; /* Damage bit */
493  if (fake_damage & 2)
494  data[7] &= ~1;
495 
496 }
497 
498  BURN_ALLOC_MEM(msg, char, 160);
499  if (trackno > 0)
500  sprintf(msg, "Track number %d: ", trackno);
501  else
502  sprintf(msg, "Upcoming track: ");
503  if (d->current_profile == 0x1a || d->current_profile == 0x13 ||
504  d->current_profile == 0x12 || d->current_profile == 0x43) {
505  /* overwritable */
506  *lba = *nwa = num = 0;
507 
508  } else if (data[5] & 32) { /* ts B10534 : MMC-5 6.27.3.7 Damage Bit */
509  if (!(data[7] & 1)) { /* NWA_V is set to zero */
510  /* "not closed due to an incomplete write" */
511  strcat(msg, "Damaged, not closed and not writable");
512  err= 0x00020185;
513  } else {
514  /* "may be recorded further in an incremental manner"*/
515  strcat(msg, "Damaged and not closed");
516  err= 0x00020186;
517  }
520  msg, 0, 0);
521  if (trackno <= 0)
522  d->next_track_damaged |= ((!(data[7] & 1)) << 1) | 1;
523  {ret = 0; goto ex;}
524 
525  } else if (!(data[7] & 1)) {
526  /* ts A61106 : MMC-1 Table 142 : NWA_V = NWA Valid Flag */
527  strcat(msg, "No Next-Writable-Address");
529  0x00020184,
531  msg, 0, 0);
532  if (trackno <= 0)
533  d->next_track_damaged |= 2;
534  {ret = 0; goto ex;}
535 
536  }
537  if (num > 0) {
539  ((off_t) num) * ((off_t) 2048));
540  d->media_lba_limit = *nwa + num;
541  } else
542  d->media_lba_limit = 0;
543 
544 /*
545  fprintf(stderr, "LIBBURN_DEBUG: media_lba_limit= %d\n",
546  d->media_lba_limit);
547 */
548 
549  ret = 1;
550 ex:
551  BURN_FREE_MEM(buf);
552  BURN_FREE_MEM(msg);
553  return ret;
554 }
555 
556 /* ts A61009 : function is obviously unused. */
557 /* void mmc_close_disc(struct burn_drive *d, struct burn_write_opts *o) */
559 {
560  struct burn_drive *d = o->drive;
561 
562  if (mmc_function_spy(d, "mmc_close_disc") <= 0)
563  return;
564 
565  libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
567  "HOW THAT ? mmc_close_disc() was called", 0, 0);
568 
569  /* ts A61009 : made impossible by removing redundant parameter d */
570  /* a ssert(o->drive == d); */
571 
572  o->multi = 0;
573  spc_select_write_params(d, NULL, 0, o);
574  mmc_close(d, 1, 0);
575 }
576 
577 /* ts A61009 : function is obviously unused. */
578 /* void mmc_close_session(struct burn_drive *d, struct burn_write_opts *o) */
580 {
581  struct burn_drive *d = o->drive;
582 
583  if (mmc_function_spy(d, "mmc_close_session") <= 0)
584  return;
585 
586  libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
588  "HOW THAT ? mmc_close_session() was called", 0, 0);
589 
590  /* ts A61009 : made impossible by removing redundant parameter d */
591  /* a ssert(o->drive == d); */
592 
593  o->multi = 3;
594  spc_select_write_params(d, NULL, 0, o);
595  mmc_close(d, 1, 0);
596 }
597 
598 /* ts A70227 : extended meaning of session to address all possible values
599  of 5Bh CLOSE TRACK SESSION to address any Close Function.
600  @param session contains the two high bits of Close Function
601  @param track if not 0: sets the lowest bit of Close Function
602 */
603 void mmc_close(struct burn_drive *d, int session, int track)
604 {
605  struct command *c;
606  char msg[256];
607  int key, asc, ascq;
608 
609  c = &(d->casual_command);
610  if (mmc_function_spy(d, "mmc_close") <= 0)
611  return;
612 
614  c->retry = 1;
615 
616  if (!d->do_no_immed)
617  c->opcode[1] |= 1; /* ts A70918 : Immed */
618 
619  /* (ts A61030 : shifted !!session rather than or-ing plain session ) */
620  c->opcode[2] = ((session & 3) << 1) | !!track;
621  c->opcode[4] = track >> 8;
622  c->opcode[5] = track & 0xFF;
623  c->page = NULL;
624  c->dir = NO_TRANSFER;
625  if (d->do_no_immed)
627  else
629  d->issue_command(d, c);
630 
631  /* ts A70918 : Immed : wait for drive to complete command */
632  if (c->error) {
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 : ");
637  scsi_error_msg(d, c->sense, 14, msg + strlen(msg),
638  &key, &asc, &ascq);
640  0x0002017e,
642  msg, 0, 0);
643  d->cancel = 1;
644  return;
645  }
646  spc_human_readable_cmd(c, msg, 160, 0);
647  if (spc_wait_unit_attention(d, 3600, msg, 0) <= 0)
648  d->cancel = 1;
649 }
650 
651 void mmc_get_event(struct burn_drive *d)
652 {
653  struct buffer *buf = NULL;
654  struct command *c;
655  int alloc_len = 8, len, evt_code, loops = 0;
656  unsigned char *evt;
657 
658  c = &(d->casual_command);
659  BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
660  if (mmc_function_spy(d, "mmc_get_event") <= 0)
661  goto ex;
662 
663 again:;
665  c->dxfer_len = 8;
666 
667  /* >>> have a burn_drive element for Notification Class */;
668  c->opcode[4] = 0x7e;
669 
670  c->opcode[7] = (c->dxfer_len >> 8) & 0xff;
671  c->opcode[8] = c->dxfer_len & 0xff;
672  c->retry = 1;
673  c->page = buf;
674  c->page->bytes = 0;
675  c->page->sectors = 0;
676  c->dir = FROM_DRIVE;
677  d->issue_command(d, c);
678  if (c->error)
679  goto ex;
680 
681  evt = c->page->data;
682  len = ((evt[0] << 8) | evt[1]) + 2;
683  if (len < 8)
684  goto ex;
685 
686  /* >>> memorize evt[3] in burn_drive element for Notification Class */;
687  if (evt[3] == 0) /* No event */
688  goto ex;
689 
690  evt_code = evt[4] & 0xf;
691  if (evt_code == 0) /* No change */
692  goto ex;
693 
694  switch (evt[2] & 7) {
695  case 0: /* no events supported */
696  goto ex;
697  case 1: /* Operational change */
698  if (((evt[6] << 8) | evt[7])) {
699  alloc_len = 8;
700  mmc_get_configuration_al(d, &alloc_len);
701  }
702  break;
703  case 2: /* Power Management */
704  if (evt[5] >= 2)
705  d->start_unit(d);
706  break;
707  case 3: /* External request */
708 
709  /* >>> report about external request */;
710 
711  break;
712  case 4: /* Media */
713  if (evt_code == 2) {
714  d->start_unit(d);
715  alloc_len = 8;
716  mmc_get_configuration_al(d, &alloc_len);
717  }
718  break;
719  case 5: /* Multiple Host Events */
720 
721  /* >>> report about foreign host interference */;
722 
723  break;
724 
725  case 6: /* Device busy */
726  if (evt_code == 1 && evt[5]) {
727 
728  /* >>> wait the time announced in evt[6],[7]
729  as 100ms units */;
730  }
731  break;
732  default: /* reserved */
733  break;
734  }
735  loops++;
736  if (loops < 100)
737  goto again;
738 ex:;
739  BURN_FREE_MEM(buf);
740 }
741 
742 
743 /* ts A70711
744  This has become a little monster because of the creative buffer reports of
745  my LG GSA-4082B : Belated, possibly statistically dampened. But only with
746  DVD media. With CD it is ok.
747 */
748 static int mmc_wait_for_buffer_free(struct burn_drive *d, struct buffer *buf)
749 {
750  int usec= 0, need, reported_3s = 0, first_wait = 1;
751  struct timeval t0,tnow;
752  double max_fac, min_fac, waiting;
753 
754 /* Enable to get reported waiting activities and total time.
755 #define Libburn_mmc_wfb_debuG 1
756 */
757 #ifdef Libburn_mmc_wfb_debuG
758  char sleeplist[32768];
759  static int buffer_still_invalid = 1;
760 #endif
761 
762  max_fac = ((double) d->wfb_max_percent) / 100.0;
763 
764  /* Buffer info from the drive is valid only after writing has begun.
765  Caring for buffer space makes sense mostly after max_percent of the
766  buffer was transmitted. */
767  if (d->progress.buffered_bytes <= 0 ||
768  d->progress.buffer_capacity <= 0 ||
769  d->progress.buffered_bytes + buf->bytes <=
770  d->progress.buffer_capacity * max_fac)
771  return 2;
772 
773 #ifdef Libburn_mmc_wfb_debuG
774  if (buffer_still_invalid)
775  fprintf(stderr,
776  "\nLIBBURN_DEBUG: Buffer considered valid now\n");
777  buffer_still_invalid = 0;
778 #endif
779 
780  /* The pessimistic counter does not assume any buffer consumption */
781  if (d->pessimistic_buffer_free - buf->bytes >=
782  ( 1.0 - max_fac) * d->progress.buffer_capacity)
783  return 1;
784 
785  /* There is need to inquire the buffer fill */
786  d->pessimistic_writes++;
787  min_fac = ((double) d->wfb_min_percent) / 100.0;
788  gettimeofday(&t0, NULL);
789 #ifdef Libburn_mmc_wfb_debuG
790  sleeplist[0]= 0;
791  sprintf(sleeplist,"(%d%s %d)",
792  (int) (d->pessimistic_buffer_free - buf->bytes),
793  (d->pbf_altered ? "? -" : " -"),
794  (int) ((1.0 - max_fac) * d->progress.buffer_capacity));
795 #endif
796 
797  while (1) {
798  if ((!first_wait) || d->pbf_altered) {
799  d->pbf_altered = 1;
801  }
802 #ifdef Libburn_mmc_wfb_debuG
803  if(strlen(sleeplist) < sizeof(sleeplist) - 80)
804  sprintf(sleeplist+strlen(sleeplist)," (%d%s %d)",
805  (int) (d->pessimistic_buffer_free - buf->bytes),
806  (d->pbf_altered ? "? -" : " -"),
807  (int) ((1.0 - min_fac) * d->progress.buffer_capacity));
808 #endif
809  gettimeofday(&tnow, NULL);
810  waiting = (tnow.tv_sec - t0.tv_sec) +
811  ((double) (tnow.tv_usec - t0.tv_usec)) / 1.0e6;
812  if (d->pessimistic_buffer_free - buf->bytes >=
813  (1.0 - min_fac) * d->progress.buffer_capacity) {
814 #ifdef Libburn_mmc_wfb_debuG
815  if(strlen(sleeplist) >= sizeof(sleeplist) - 80)
816  strcat(sleeplist," ...");
817  sprintf(sleeplist+strlen(sleeplist)," -> %d [%.6f]",
818  (int) (
819  d->pessimistic_buffer_free - buf->bytes -
820  (1.0 - min_fac) * d->progress.buffer_capacity
821  ), waiting);
822  fprintf(stderr,
823  "\nLIBBURN_DEBUG: sleeplist= %s\n",sleeplist);
824 #endif
825  return 1;
826  }
827 
828  /* Waiting is needed */
829  if (waiting >= 3 && !reported_3s) {
831  0x0002013d,
833  "Waiting for free buffer takes more than 3 seconds",
834  0,0);
835  reported_3s = 1;
836  } else if (d->wfb_timeout_sec > 0 &&
837  waiting > d->wfb_timeout_sec) {
838  d->wait_for_buffer_free = 0;
840  0x0002013d,
842  "Timeout with waiting for free buffer. Now disabled.",
843  0,0);
844  break;
845  }
846 
847  need = (1.0 - min_fac) * d->progress.buffer_capacity +
848  buf->bytes - d->pessimistic_buffer_free;
849  usec = 0;
850  if (d->nominal_write_speed > 0)
851  usec = ((double) need) / 1000.0 /
852  ((double) d->nominal_write_speed) * 1.0e6;
853  else
854  usec = d->wfb_min_usec * 2;
855 
856  /* >>> learn about buffer progress and adjust usec */
857 
858  if (usec < (int) d->wfb_min_usec)
859  usec = d->wfb_min_usec;
860  else if (usec > (int) d->wfb_max_usec)
861  usec = d->wfb_max_usec;
862  usleep(usec);
863  if (d->waited_usec < 0xf0000000)
864  d->waited_usec += usec;
865  d->waited_tries++;
866  if(first_wait)
867  d->waited_writes++;
868 #ifdef Libburn_mmc_wfb_debuG
869  if(strlen(sleeplist) < sizeof(sleeplist) - 80)
870  sprintf(sleeplist+strlen(sleeplist)," %d", usec);
871 #endif
872  first_wait = 0;
873  }
874  return 0;
875 }
876 
877 
878 void mmc_write_12(struct burn_drive *d, int start, struct buffer *buf)
879 {
880  struct command *c;
881  int len;
882 
883  c = &(d->casual_command);
884  mmc_start_if_needed(d, 0);
885  if (mmc_function_spy(d, "mmc_write_12") <= 0)
886  return;
887 
888  len = buf->sectors;
889 
891  c->retry = 1;
892  mmc_int_to_four_char(c->opcode + 2, start);
893  mmc_int_to_four_char(c->opcode + 6, len);
894  c->page = buf;
895  c->dir = TO_DRIVE;
897 
898  d->issue_command(d, c);
899 
900  /* ts A70711 */
901  d->pessimistic_buffer_free -= buf->bytes;
902  d->pbf_altered = 1;
903 }
904 
905 
906 #ifdef Libburn_write_time_debuG
907 
908 static int print_time(int flag)
909 {
910  static struct timeval prev = {0, 0};
911  struct timeval now;
912  int ret, diff;
913 
914  ret = gettimeofday(&now, NULL);
915  if (ret == -1)
916  return 0;
917  if (now.tv_sec - prev.tv_sec < Libburn_scsi_write_timeouT) {
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);
921  }
922  memcpy(&prev, &now, sizeof(struct timeval));
923  return 1;
924 }
925 
926 #endif /* Libburn_write_time_debuG */
927 
928 
929 int mmc_write(struct burn_drive *d, int start, struct buffer *buf)
930 {
931  int cancelled;
932  struct command *c;
933  int len, key, asc, ascq;
934  char *msg = NULL;
935 
936 #ifdef Libburn_write_time_debuG
937  extern int burn_sg_log_scsi;
938 #endif
939 
940 /*
941 fprintf(stderr, "libburn_DEBUG: buffer sectors= %d bytes= %d\n",
942  buf->sectors, buf->bytes);
943 */
944 
945 
946  c = &(d->casual_command);
947 
948 #ifdef Libburn_log_in_and_out_streaM
949  /* <<< ts A61031 */
950  static int tee_fd= -1;
951  if(tee_fd==-1)
952  tee_fd= open("/tmp/libburn_sg_written",
953  O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
954  S_IRUSR | S_IWUSR);
955 #endif /* Libburn_log_in_and_out_streaM */
956 
957  mmc_start_if_needed(d, 0);
958  if (mmc_function_spy(d, "mmc_write") <= 0)
959  return BE_CANCELLED;
960 
961  cancelled = d->cancel;
962  if (cancelled)
963  return BE_CANCELLED;
964 
965  /* ts A70215 */
966  if (d->media_lba_limit > 0 && start >= d->media_lba_limit) {
967 
968  msg = calloc(1, 320);
969  if (msg != NULL) {
970  sprintf(msg,
971  "Exceeding range of permissible write addresses (%d >= %d)",
972  start, d->media_lba_limit);
974  0x0002012d,
976  msg, 0, 0);
977  strcpy(msg, "CDB= ");
978  if (spc_human_readable_cmd(c, msg + strlen(msg),
979  320 - strlen(msg), 1) > 0) {
981  d->global_index, 0x0002012d,
984  msg, 0, 0);
985  }
986  free(msg);
987  }
988  d->cancel = 1; /* No need for mutexing because atomic */
989  return BE_CANCELLED;
990  }
991 
992  len = buf->sectors;
993 
994  /* ts A61009 : buffer fill problems are to be handled by caller */
995  /* a ssert(buf->bytes >= buf->sectors);*/ /* can be == at 0... */
996 
997  /* ts A70711 */
998  if(d->wait_for_buffer_free)
999  mmc_wait_for_buffer_free(d, buf);
1000 
1001 #ifdef Libburn_write_time_debuG
1002  if (burn_sg_log_scsi & 3)
1003  print_time(0);
1004 #endif
1005 
1006  /* ts A80412 */
1007  if(d->do_stream_recording > 0 && start >= d->stream_recording_start) {
1009  mmc_int_to_four_char(c->opcode + 2, start);
1010  mmc_int_to_four_char(c->opcode + 6, len);
1011  c->opcode[10] = 1<<7; /* Streaming bit */
1012  } else {
1014  mmc_int_to_four_char(c->opcode + 2, start);
1015  c->opcode[6] = 0;
1016  c->opcode[7] = (len >> 8) & 0xFF;
1017  c->opcode[8] = len & 0xFF;
1018  }
1019  c->retry = 1;
1020  c->page = buf;
1021  c->dir = TO_DRIVE;
1023 
1024 #ifdef Libburn_log_in_and_out_streaM
1025  /* <<< ts A61031 */
1026  if(tee_fd!=-1) {
1027  write(tee_fd, c->page->data, c->page->bytes);
1028  }
1029 #endif /* Libburn_log_in_and_out_streaM */
1030 
1031  d->issue_command(d, c);
1032 
1033  /* ts A70711 */
1034  d->pessimistic_buffer_free -= buf->bytes;
1035  d->pbf_altered = 1;
1036 
1037  /* ts A61112 : react on eventual error condition */
1038  spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
1039  if (c->error && key != 0) {
1040  int key, asc, ascq;
1041  int err_sev = LIBDAX_MSGS_SEV_FATAL;
1042 
1043  msg = calloc(1, 320);
1044  if (msg != NULL) {
1045  sprintf(msg, "SCSI error on write(%d,%d): ",
1046  start, len);
1047  scsi_error_msg(d, c->sense, 14, msg + strlen(msg),
1048  &key, &asc, &ascq);
1049  }
1050 
1051  /* ts B31023 */
1052  /* Memorize if on DVD-RW write mode is TAO/Incremental and
1053  error [5 64 00] occurs within the first drive buffer fill.
1054  */
1055  if (d->current_profile == 0x14 && d->write_opts != NULL &&
1056  (d->progress.buffer_capacity == 0 ||
1057  start < (int) d->progress.buffer_capacity / 2048) &&
1058  key == 5 && asc == 0x64 && ascq == 0) {
1059  if (d->write_opts->write_type == BURN_WRITE_TAO) {
1060  d->was_feat21h_failure = 1 + (start == 0);
1061  if (d->write_opts->feat21h_fail_sev != 0)
1062  err_sev =
1064  }
1065  }
1066 
1067  if (msg != NULL) {
1069  0x0002011d,
1070  err_sev, LIBDAX_MSGS_PRIO_HIGH,
1071  msg, 0, 0);
1072  strcpy(msg, "CDB= ");
1073  if (spc_human_readable_cmd(c, msg + strlen(msg),
1074  320 - strlen(msg), 0) > 0) {
1076  d->global_index, 0x0002011d,
1077  err_sev, LIBDAX_MSGS_PRIO_HIGH,
1078  msg, 0, 0);
1079  }
1080  free(msg);
1081  }
1082  d->cancel = 1;
1083 
1084  return BE_CANCELLED;
1085  }
1086  d->write_retry_count += c->retry_count;
1087 
1088  return 0;
1089 }
1090 
1091 
1092 /* ts A70201 : Set up an entry for mmc_fake_toc() */
1093 int mmc_fake_toc_entry(struct burn_toc_entry *entry, int session_number,
1094  int track_number,
1095  unsigned char *size_data, unsigned char *start_data,
1096  unsigned char *last_adr_data)
1097 {
1098  int min, sec, frames, num;
1099 
1100  /* mark DVD extensions and Track Info extension as valid */
1101  entry->extensions_valid |= (1 | 2);
1102 
1103  /* defaults are as of mmc5r03.pdf 6.26.3.2.4 Fabricated TOC */
1104  entry->session = session_number & 0xff;
1105  entry->session_msb = (session_number >> 8) & 0xff;
1106  entry->adr = 1;
1107  entry->control = 4;
1108  entry->tno = 0;
1109  entry->point = track_number & 0xff;
1110  entry->point_msb = (track_number >> 8) & 0xff;
1111  num = mmc_four_char_to_int(size_data);
1112  entry->track_blocks = num;
1113  burn_lba_to_msf(num, &min, &sec, &frames);
1114  if (min > 255) {
1115  min = 255;
1116  sec = 255;
1117  frames = 255;
1118  }
1119  entry->min = min;
1120  entry->sec = sec;
1121  entry->frame = frames;
1122  entry->zero = 0;
1123  num = mmc_four_char_to_int(start_data);
1124  entry->start_lba = num;
1125  burn_lba_to_msf(num, &min, &sec, &frames);
1126  if (min > 255) {
1127  min = 255;
1128  sec = 255;
1129  frames = 255;
1130  }
1131  entry->pmin = min;
1132  entry->psec = sec;
1133  entry->pframe = frames;
1134  entry->last_recorded_address = mmc_four_char_to_int(last_adr_data);
1135  return 1;
1136 }
1137 
1138 
1139 /* ts A71128 : for DVD-ROM drives which offer no reliable track information */
1140 static int mmc_read_toc_fmt0_al(struct burn_drive *d, int *alloc_len)
1141 {
1142  struct burn_track *track;
1143  struct burn_session *session;
1144  struct burn_toc_entry *entry;
1145  struct buffer *buf = NULL;
1146  struct command *c = NULL;
1147  int dlen, i, old_alloc_len, session_number, prev_session = -1, ret;
1148  int lba, size;
1149  unsigned char *tdata, size_data[4], start_data[4], end_data[4];
1150 
1151  if (*alloc_len < 4)
1152  {ret = 0; goto ex;}
1153 
1154  BURN_ALLOC_MEM(buf, struct buffer, 1);
1155  BURN_ALLOC_MEM(c, struct command, 1);
1157  c->dxfer_len = *alloc_len;
1158  c->opcode[7] = (c->dxfer_len >> 8) & 0xff;
1159  c->opcode[8] = c->dxfer_len & 0xff;
1160  c->retry = 1;
1161  c->page = buf;
1162  c->page->bytes = 0;
1163  c->page->sectors = 0;
1164  c->dir = FROM_DRIVE;
1165  d->issue_command(d, c);
1166 
1167  if (c->error) {
1168 err_ex:;
1170  0x0002010d,
1172  "Could not inquire TOC", 0,0);
1174  d->toc_entries = 0;
1175  /* Preferring memory leaks over fandangos */
1176  d->toc_entry = calloc(1, sizeof(struct burn_toc_entry));
1177  {ret = 0; goto ex;}
1178  }
1179  dlen = c->page->data[0] * 256 + c->page->data[1];
1180  old_alloc_len = *alloc_len;
1181  *alloc_len = dlen + 2;
1182  if (old_alloc_len < 12)
1183  {ret = 1; goto ex;}
1184  if (dlen + 2 > old_alloc_len)
1185  dlen = old_alloc_len - 2;
1186  d->complete_sessions = 1 + c->page->data[3] - c->page->data[2];
1187 
1188 #ifdef Libburn_disc_with_incomplete_sessioN
1189  /* ts B30112 : number of open sessions */
1190  d->incomplete_sessions = 0;
1191 #endif
1192 
1194  if (dlen - 2 < (d->last_track_no + 1) * 8) {
1196  0x00020159,
1198  "TOC Format 0 returns inconsistent data", 0,0);
1199  goto err_ex;
1200  }
1201 
1203  if (d->toc_entries < 1)
1204  {ret = 0; goto ex;}
1205  d->toc_entry = calloc(d->toc_entries, sizeof(struct burn_toc_entry));
1206  if(d->toc_entry == NULL)
1207  {ret = 0; goto ex;}
1208 
1209  d->disc = burn_disc_create();
1210  if (d->disc == NULL)
1211  {ret = 0; goto ex;}
1212  for (i = 0; i < d->complete_sessions; i++) {
1213  session = burn_session_create();
1214  if (session == NULL)
1215  {ret = 0; goto ex;}
1216  burn_disc_add_session(d->disc, session, BURN_POS_END);
1217  burn_session_free(session);
1218  }
1219 
1220 
1221  for (i = 0; i < d->last_track_no; i++) {
1222  tdata = c->page->data + 4 + i * 8;
1223  session_number = i + 1;
1224  if (session_number != prev_session && prev_session > 0) {
1225  /* leadout entry previous session */
1226  entry = &(d->toc_entry[(i - 1) + prev_session]);
1227  lba = mmc_four_char_to_int(start_data) +
1228  mmc_four_char_to_int(size_data);
1229  mmc_int_to_four_char(start_data, lba);
1230  mmc_int_to_four_char(size_data, 0);
1231  mmc_int_to_four_char(end_data, lba - 1);
1232  mmc_fake_toc_entry(entry, prev_session, 0xA2,
1233  size_data, start_data, end_data);
1234  entry->min= entry->sec= entry->frame= 0;
1235  d->disc->session[prev_session - 1]->leadout_entry =
1236  entry;
1237  }
1238 
1239  /* ??? >>> d->media_capacity_remaining , d->media_lba_limit
1240  as of mmc_fake_toc()
1241  */
1242 
1243  entry = &(d->toc_entry[i + session_number - 1]);
1244  track = burn_track_create();
1245  if (track == NULL)
1246  {ret = -1; goto ex;}
1248  d->disc->session[session_number - 1],
1249  track, BURN_POS_END);
1250  track->entry = entry;
1251  burn_track_free(track);
1252 
1253  memcpy(start_data, tdata + 4, 4);
1254  /* size_data are estimated from next track start */
1255  memcpy(size_data, tdata + 8 + 4, 4);
1256  mmc_int_to_four_char(end_data,
1257  mmc_four_char_to_int(size_data) - 1);
1258  size = mmc_four_char_to_int(size_data) -
1259  mmc_four_char_to_int(start_data);
1260  mmc_int_to_four_char(size_data, size);
1261  mmc_fake_toc_entry(entry, session_number, i + 1,
1262  size_data, start_data, end_data);
1263  if (prev_session != session_number)
1264  d->disc->session[session_number - 1]->firsttrack = i+1;
1265  d->disc->session[session_number - 1]->lasttrack = i+1;
1266  prev_session = session_number;
1267  }
1268  if (prev_session > 0 && prev_session <= d->disc->sessions) {
1269  /* leadout entry of last session of closed disc */
1270  tdata = c->page->data + 4 + d->last_track_no * 8;
1271  entry = &(d->toc_entry[(d->last_track_no - 1) + prev_session]);
1272  memcpy(start_data, tdata + 4, 4);
1273  mmc_int_to_four_char(size_data, 0);
1274  mmc_int_to_four_char(end_data,
1275  mmc_four_char_to_int(start_data) - 1);
1276  mmc_fake_toc_entry(entry, prev_session, 0xA2,
1277  size_data, start_data, end_data);
1278  entry->min= entry->sec= entry->frame= 0;
1279  d->disc->session[prev_session - 1]->leadout_entry = entry;
1280  }
1281  ret = 1;
1282 ex:;
1283  BURN_FREE_MEM(buf);
1284  BURN_FREE_MEM(c);
1285  return ret;
1286 }
1287 
1288 
1289 /* ts A71128 : for DVD-ROM drives which offer no reliable track information */
1290 static int mmc_read_toc_fmt0(struct burn_drive *d)
1291 {
1292  int alloc_len = 4, ret;
1293 
1294  mmc_start_if_needed(d, 1);
1295  if (mmc_function_spy(d, "mmc_read_toc_fmt0") <= 0)
1296  return -1;
1297  ret = mmc_read_toc_fmt0_al(d, &alloc_len);
1298  if (alloc_len >= 12)
1299  ret = mmc_read_toc_fmt0_al(d, &alloc_len);
1300  return ret;
1301 }
1302 
1303 
1304 /* ts A70131 : compose a disc TOC structure from d->complete_sessions
1305  and 52h READ TRACK INFORMATION */
1306 int mmc_fake_toc(struct burn_drive *d)
1307 {
1308  struct burn_track *track;
1309  struct burn_session *session;
1310  struct burn_toc_entry *entry;
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];
1314  char *msg = NULL;
1315 
1316  if (mmc_function_spy(d, "mmc_fake_toc") <= 0)
1317  {ret = -1; goto ex;}
1318  BURN_ALLOC_MEM(buf, struct buffer, 1);
1319 
1320 #ifdef Libburn_disc_with_incomplete_sessioN
1321 
1322  if (d->last_track_no <= 0 ||
1323  d->complete_sessions + d->incomplete_sessions <= 0 ||
1324  d->status == BURN_DISC_BLANK)
1325  {ret = 2; goto ex;}
1326 
1327 #else
1328 
1329  if (d->last_track_no <= 0 || d->complete_sessions <= 0 ||
1330  d->status == BURN_DISC_BLANK)
1331  {ret = 2; goto ex;}
1332 
1333 #endif /* ! Libburn_disc_with_incomplete_sessioN */
1334 
1335 
1337  msg = calloc(1, 160);
1338  if (msg != NULL) {
1339  sprintf(msg,
1340  "Too many logical tracks recorded (%d , max. %d)\n",
1343  0x0002012c,
1345  msg, 0,0);
1346  free(msg);
1347  }
1348  {ret = 0; goto ex;}
1349  }
1350  /* ts A71128 : My DVD-ROM drive issues no reliable track info.
1351  One has to try 43h READ TOC/PMA/ATIP Form 0. */
1352  if ((d->current_profile == 0x10) && d->last_track_no <= 1) {
1353  ret = mmc_read_toc_fmt0(d);
1354  goto ex;
1355  }
1356  d->disc = burn_disc_create();
1357  if (d->disc == NULL)
1358  {ret = -1; goto ex;}
1359  d->toc_entries = d->last_track_no
1361  d->toc_entry = calloc(d->toc_entries, sizeof(struct burn_toc_entry));
1362  if (d->toc_entry == NULL)
1363  {ret = -1; goto ex;}
1364  memset(d->toc_entry, 0,d->toc_entries * sizeof(struct burn_toc_entry));
1365 
1366 #ifdef Libburn_disc_with_incomplete_sessioN
1367 
1368  for (i = 0; i < d->complete_sessions + d->incomplete_sessions; i++) {
1369 
1370 #else
1371 
1372  for (i = 0; i < d->complete_sessions; i++) {
1373 
1374 #endif
1375 
1376  session = burn_session_create();
1377  if (session == NULL)
1378  {ret = -1; goto ex;}
1379  burn_disc_add_session(d->disc, session, BURN_POS_END);
1380  burn_session_free(session);
1381  }
1382 
1383 #ifdef Libburn_disc_with_incomplete_sessioN
1384  d->disc->incomplete_sessions = d->incomplete_sessions;
1385 #endif
1386 
1387  memset(size_data, 0, 4);
1388  memset(start_data, 0, 4);
1389 
1390 
1391  /* Entry Layout :
1392  session 1 track 1 entry 0
1393  ...
1394  session 1 track N entry N-1
1395  leadout 1 entry N
1396  session 2 track N+1 entry N+1
1397  ...
1398  session 2 track M+1 entry M+1
1399  leadout 2 entry M+2
1400  session X track K entry (K-1)+(X-1)
1401  ...
1402  session X track i+1 entry i+(X-1)
1403  leadout X entry i+X
1404  */
1405  for (i = 0; i < d->last_track_no; i++) {
1406  ret = mmc_read_track_info(d, i+1, buf, alloc_len);
1407  if (ret <= 0)
1408  goto ex;
1409  tdata = buf->data;
1410  session_number = (tdata[33] << 8) | tdata[3];
1411  if (session_number <= 0)
1412  continue;
1413 
1414  if (session_number != prev_session && prev_session > 0) {
1415  /* leadout entry previous session */
1416  entry = &(d->toc_entry[(i - 1) + prev_session]);
1417  lba = mmc_four_char_to_int(start_data) +
1418  mmc_four_char_to_int(size_data);
1419  mmc_int_to_four_char(start_data, lba);
1420  mmc_int_to_four_char(size_data, 0);
1421  mmc_int_to_four_char(end_data, lba - 1);
1422  mmc_fake_toc_entry(entry, prev_session, 0xA2,
1423  size_data, start_data, end_data);
1424  entry->min= entry->sec= entry->frame= 0;
1425  d->disc->session[prev_session - 1]->leadout_entry =
1426  entry;
1427  }
1428 
1429 #ifdef Libburn_disc_with_incomplete_sessioN
1430 
1431  if (session_number > d->complete_sessions) {
1432 
1433 #else
1434 
1435  if (session_number > d->disc->sessions) {
1436 
1437 #endif
1438 
1439  if (i == d->last_track_no - 1) {
1440  /* ts A70212 : Last track field Free Blocks */
1442  ((off_t) mmc_four_char_to_int(tdata + 16)) *
1443  ((off_t) 2048));
1444  d->media_lba_limit = 0;
1445  }
1446 
1447 #ifdef Libburn_disc_with_incomplete_sessioN
1448 
1449  if (session_number > d->disc->sessions )
1450  continue;
1451 
1452 #else
1453 
1454  continue;
1455 
1456 #endif
1457 
1458  }
1459 
1460  entry = &(d->toc_entry[i + session_number - 1]);
1461  track = burn_track_create();
1462  if (track == NULL)
1463  {ret = -1; goto ex;}
1465  d->disc->session[session_number - 1],
1466  track, BURN_POS_END);
1467  track->entry = entry;
1468  burn_track_free(track);
1469 
1470  memcpy(size_data, tdata + 24, 4);
1471  memcpy(start_data, tdata + 8, 4);
1472  memcpy(end_data, tdata + 28, 4);
1473  mmc_fake_toc_entry(entry, session_number, i + 1,
1474  size_data, start_data, end_data);
1475  entry->track_status_bits = tdata[5] | (tdata[6] << 8) |
1476  (tdata[7] << 16);
1477  entry->extensions_valid |= 4;
1478 
1479  if (prev_session != session_number)
1480  d->disc->session[session_number - 1]->firsttrack = i+1;
1481  d->disc->session[session_number - 1]->lasttrack = i+1;
1482  prev_session = session_number;
1483  }
1484 
1485  if (prev_session > 0 && prev_session <= d->disc->sessions) {
1486  /* leadout entry of last session of closed disc */
1487  entry = &(d->toc_entry[(d->last_track_no - 1) + prev_session]);
1488  lba = mmc_four_char_to_int(start_data) +
1489  mmc_four_char_to_int(size_data);
1490  mmc_int_to_four_char(start_data, lba);
1491  mmc_int_to_four_char(size_data, 0);
1492  mmc_int_to_four_char(end_data, lba - 1);
1493  mmc_fake_toc_entry(entry, prev_session, 0xA2,
1494  size_data, start_data, end_data);
1495  entry->min= entry->sec= entry->frame= 0;
1496  d->disc->session[prev_session - 1]->leadout_entry = entry;
1497  }
1498  ret = 1;
1499 ex:;
1500  BURN_FREE_MEM(buf);
1501  return ret;
1502 }
1503 
1504 
1505 static int mmc_register_leadout(struct burn_drive *d, int *highest_leadout,
1506  int toc_idx)
1507 {
1508  int lba;
1509 
1510  lba = burn_msf_to_lba(d->toc_entry[toc_idx].pmin,
1511  d->toc_entry[toc_idx].psec,
1512  d->toc_entry[toc_idx].pframe);
1513  if (lba > *highest_leadout)
1514  *highest_leadout = lba;
1515  return 1;
1516 }
1517 
1518 
1519 static int mmc_read_toc_al(struct burn_drive *d, int *alloc_len)
1520 {
1521 /* read full toc, all sessions, in m/s/f form, 4k buffer */
1522 /* ts A70201 : or fake a toc from track information */
1523  struct burn_track *track;
1524  struct burn_session *session;
1525  struct buffer *buf = NULL;
1526  struct command *c = NULL;
1527  int dlen;
1528  int i, old_alloc_len, t_idx, ret, highest_leadout = -1;
1529  unsigned char *tdata;
1530  char *msg = NULL;
1531 
1532  if (*alloc_len < 4)
1533  {ret = 0; goto ex;}
1534 
1535  BURN_ALLOC_MEM(buf, struct buffer, 1);
1536  BURN_ALLOC_MEM(c, struct command, 1);
1537  BURN_ALLOC_MEM(msg, char, 321);
1538 
1539  if (!(d->current_profile == -1 || d->current_is_cd_profile)) {
1540  /* ts A70131 : MMC_GET_TOC uses Response Format 2
1541  For DVD this fails with 5,24,00 */
1542  /* mmc_read_toc_fmt0() uses
1543  Response Format 0: mmc5r03.pdf 6.26.3.2
1544  which does not yield the same result with the same disc
1545  on different drives.
1546  */
1547  /* ts A70201 :
1548  This uses the session count from 51h READ DISC INFORMATION
1549  and the track records from 52h READ TRACK INFORMATION.
1550  mmc_read_toc_fmt0() is used as fallback for dull DVD-ROM.
1551  */
1552  mmc_fake_toc(d);
1553 
1554  if (d->status == BURN_DISC_UNREADY)
1555  d->status = BURN_DISC_FULL;
1556  {ret = 1; goto ex;}
1557  }
1558 
1559  /* ts A90823:
1560  SanDisk Cruzer U3 memory stick stalls on format 2.
1561  Format 0 seems to be more conservative with read-only drives.
1562  */
1563  if (!((d->mdata->p2a_valid > 0 && d->mdata->cdrw_write) ||
1564  d->current_profile != 0x08)) {
1565  ret = mmc_read_toc_fmt0(d);
1566  goto ex;
1567  }
1568 
1570  c->dxfer_len = *alloc_len;
1571  c->opcode[7] = (c->dxfer_len >> 8) & 0xff;
1572  c->opcode[8] = c->dxfer_len & 0xff;
1573  c->retry = 1;
1574  c->page = buf;
1575  c->page->bytes = 0;
1576  c->page->sectors = 0;
1577  c->dir = FROM_DRIVE;
1578  d->issue_command(d, c);
1579 
1580  if (c->error) {
1581 
1582  /* ts A61020 : this snaps on non-blank DVD media */
1583  /* ts A61106 : also snaps on CD with unclosed track/session */
1584  /* Very unsure whether this old measure is ok.
1585  Obviously higher levels do not care about this.
1586  outdated info: DVD+RW burns go on after passing through here.
1587 
1588  d->busy = BURN_DRIVE_IDLE;
1589  */
1591  0x0002010d,
1593  "Could not inquire TOC", 0,0);
1595  d->toc_entries = 0;
1596  /* Preferring memory leaks over fandangos */
1597  d->toc_entry = calloc(1, sizeof(struct burn_toc_entry));
1598  {ret = 0; goto ex;}
1599  }
1600 
1601  dlen = c->page->data[0] * 256 + c->page->data[1];
1602  old_alloc_len = *alloc_len;
1603  *alloc_len = dlen + 2;
1604  if (old_alloc_len < 15)
1605  {ret = 1; goto ex;}
1606  if (dlen + 2 > old_alloc_len)
1607  dlen = old_alloc_len - 2;
1608  d->toc_entries = (dlen - 2) / 11;
1609  if (d->toc_entries < 1)
1610  {ret = 0; goto ex;}
1611 /*
1612  some drives fail this check.
1613 
1614  ts A61007 : if re-enabled then not via Assert.
1615  a ssert(((dlen - 2) % 11) == 0);
1616 */
1617  /* ts A81202: plus number of sessions as reserve for leadout default */
1618  d->toc_entry = calloc(d->toc_entries + (unsigned char) c->page->data[3],
1619  sizeof(struct burn_toc_entry));
1620  if(d->toc_entry == NULL) /* ts A70825 */
1621  {ret = 0; goto ex;}
1622  tdata = c->page->data + 4;
1623 
1624  d->disc = burn_disc_create();
1625  if (d->disc == NULL) /* ts A70825 */
1626  {ret = 0; goto ex;}
1627 
1628  for (i = 0; i < c->page->data[3]; i++) {
1629  session = burn_session_create();
1630  if (session == NULL) /* ts A70825 */
1631  {ret = 0; goto ex;}
1632  burn_disc_add_session(d->disc, session, BURN_POS_END);
1633  burn_session_free(session);
1634  }
1635 
1636  /* ts A61022 */
1637 
1638  for (i = 0; i < d->toc_entries; i++, tdata += 11) {
1639 
1640 /*
1641  fprintf(stderr, "libburn_experimental: toc entry #%d : %d %d %d\n",i,tdata[8], tdata[9], tdata[10]);
1642 */
1643 
1644 #ifdef Libburn_allow_first_hiddeN
1645  /* ts B00430 : this causes problems because the track has
1646  no entry. One would have to coordinate this
1647  with other parts of libburn.
1648  */
1649  if (tdata[3] == 1) {
1650  if (burn_msf_to_lba(tdata[8], tdata[9], tdata[10])) {
1651  d->disc->session[0]->hidefirst = 1;
1652  track = burn_track_create();
1654  session[tdata[0] - 1],
1655  track, BURN_POS_END);
1656  burn_track_free(track);
1657  }
1658  }
1659 #endif /* Libburn_allow_first_hiddeN */
1660 
1661  if (tdata[0] <= 0 || tdata[0] > d->disc->sessions)
1662  tdata[0] = d->disc->sessions;
1663  if (tdata[3] < 100 && tdata[0] > 0) {
1664  track = burn_track_create();
1665  burn_session_add_track(d->disc->session[tdata[0] - 1],
1666  track, BURN_POS_END);
1667  track->entry = &d->toc_entry[i];
1668  burn_track_free(track);
1669  }
1670  d->toc_entry[i].session = tdata[0];
1671  d->toc_entry[i].adr = tdata[1] >> 4;
1672  d->toc_entry[i].control = tdata[1] & 0xF;
1673  d->toc_entry[i].tno = tdata[2];
1674  d->toc_entry[i].point = tdata[3];
1675  d->toc_entry[i].min = tdata[4];
1676  d->toc_entry[i].sec = tdata[5];
1677  d->toc_entry[i].frame = tdata[6];
1678  d->toc_entry[i].zero = tdata[7];
1679  d->toc_entry[i].pmin = tdata[8];
1680  d->toc_entry[i].psec = tdata[9];
1681  d->toc_entry[i].pframe = tdata[10];
1682  if (tdata[3] == 0xA0)
1683  d->disc->session[tdata[0] - 1]->firsttrack = tdata[8];
1684  if (tdata[3] == 0xA1)
1685  d->disc->session[tdata[0] - 1]->lasttrack = tdata[8];
1686  if (tdata[3] == 0xA2) {
1687  d->disc->session[tdata[0] - 1]->leadout_entry =
1688  &d->toc_entry[i];
1689  /* ts B60305 */
1690  mmc_register_leadout(d, &highest_leadout, i);
1691  }
1692  }
1693 
1694  /* ts A70131 : was (d->status != BURN_DISC_BLANK) */
1695  if (d->status == BURN_DISC_UNREADY)
1696  d->status = BURN_DISC_FULL;
1697  toc_find_modes(d);
1698 
1699  /* ts A81202 ticket 146 : a drive reported a session with no leadout */
1700  for (i = 0; i < d->disc->sessions; i++) {
1701  if (d->disc->session[i]->leadout_entry != NULL)
1702  continue;
1703  sprintf(msg, "Session %d of %d encountered without leadout",
1704  i + 1, d->disc->sessions);
1706  0x00020160,
1708  msg, 0, 0);
1709 
1710  /* Produce default leadout entry from last track of session
1711  which will thus get its size set to 0 */;
1712  if (d->disc->session[i]->track != NULL &&
1713  d->disc->session[i]->tracks > 0) {
1714  t_idx = d->toc_entries++;
1715  memcpy(d->toc_entry + t_idx,
1716  d->disc->session[i]->track[
1717  d->disc->session[i]->tracks - 1]->entry,
1718  sizeof(struct burn_toc_entry));
1719  d->toc_entry[t_idx].point = 0xA2;
1720  d->disc->session[i]->leadout_entry =
1721  d->toc_entry + t_idx;
1722  } else {
1724  sprintf(msg,
1725  "Empty session %d deleted. Now %d sessions.",
1726  i + 1, d->disc->sessions);
1728  0x00020161,
1730  msg, 0, 0);
1731  i--;
1732  }
1733  }
1734 
1735  /* A80808 */
1737 
1738  /* ts B60304
1739  Most drives report READ CAPACITY of TAO CD too high by 2 blocks.
1740  TOC format 2 always reports 2 blocks more than are readable.
1741  So here it is possible to check and mark as trusted.
1742  */
1743  if (highest_leadout > 0 && d->media_read_capacity != 0x7fffffff &&
1744  !d->mr_capacity_trusted) {
1745  if (highest_leadout - 3 == d->media_read_capacity) {
1746  d->mr_capacity_trusted = 1;
1748  0x00000002, LIBDAX_MSGS_SEV_DEBUG,
1750  "Trusting READ CAPACITY by 2 extra blocks in TOC. Assuming TAO.",
1751  0, 0);
1752  }
1753  }
1754 
1755  ret = 1;
1756 ex:;
1757  BURN_FREE_MEM(msg);
1758  BURN_FREE_MEM(c);
1759  BURN_FREE_MEM(buf);
1760  return ret;
1761 }
1762 
1763 
1764 void mmc_read_toc(struct burn_drive *d)
1765 {
1766  int alloc_len = 4, ret;
1767 
1768  mmc_start_if_needed(d, 1);
1769  if (mmc_function_spy(d, "mmc_read_toc") <= 0)
1770  return;
1771 
1772  ret = mmc_read_toc_al(d, &alloc_len);
1773 /*
1774  fprintf(stderr,
1775  "LIBBURN_DEBUG: 43h READ TOC alloc_len = %d , ret = %d\n",
1776  alloc_len, ret);
1777 */
1778  if (alloc_len >= 15)
1779  ret = mmc_read_toc_al(d, &alloc_len);
1780  if (ret <= 0)
1781  return;
1782 }
1783 
1784 
1785 /* ts A70131 : This tries to get the start of the last complete session */
1786 /* man mkisofs , option -C :
1787  The first number is the sector number of the first sector in
1788  the last session of the disk that should be appended to.
1789 */
1790 int mmc_read_multi_session_c1(struct burn_drive *d, int *trackno, int *start)
1791 {
1792  struct buffer *buf = NULL;
1793  struct command *c = NULL;
1794  unsigned char *tdata;
1795  int num_sessions, session_no, num_tracks, alloc_len = 12, ret;
1796  struct burn_disc *disc;
1797  struct burn_session **sessions;
1798  struct burn_track **tracks;
1799  struct burn_toc_entry toc_entry;
1800 
1801  BURN_ALLOC_MEM(buf, struct buffer, 1);
1802  BURN_ALLOC_MEM(c, struct command, 1);
1803  mmc_start_if_needed(d, 1);
1804  if (mmc_function_spy(d, "mmc_read_multi_session_c1") <= 0)
1805  {ret = 0; goto ex;}
1806 
1807  /* First try to evaluate the possibly loaded TOC before issuing
1808  a MMC command. This search obtains the first track of the last
1809  complete session which has a track.
1810  */
1811  *trackno = 0;
1812  disc = burn_drive_get_disc(d);
1813  if (disc == NULL)
1814  goto inquire_drive;
1815  sessions = burn_disc_get_sessions(disc, &num_sessions);
1816  for (session_no = 0; session_no<num_sessions; session_no++) {
1817  tracks = burn_session_get_tracks(sessions[session_no],
1818  &num_tracks);
1819  if (tracks == NULL || num_tracks <= 0)
1820  continue;
1821  burn_track_get_entry(tracks[0], &toc_entry);
1822  if (toc_entry.extensions_valid & 1) { /* DVD extension valid */
1823  *start = toc_entry.start_lba;
1824  *trackno = (toc_entry.point_msb << 8)| toc_entry.point;
1825  } else {
1826  *start = burn_msf_to_lba(toc_entry.pmin,
1827  toc_entry.psec, toc_entry.pframe);
1828  *trackno = toc_entry.point;
1829  }
1830  }
1831  burn_disc_free(disc);
1832  if(*trackno > 0)
1833  {ret = 1; goto ex;}
1834 
1835 inquire_drive:;
1836  /* mmc5r03.pdf 6.26.3.3.3 states that with non-CD this would
1837  be a useless fake always starting at track 1, lba 0.
1838  My drives return useful data, though.
1839  MMC-3 states that DVD had no tracks. So maybe this mandatory fake
1840  is a forgotten legacy ?
1841  */
1843  c->dxfer_len = alloc_len;
1844  c->opcode[7]= (c->dxfer_len >> 8) & 0xff;
1845  c->opcode[8]= c->dxfer_len & 0xff;
1846  c->retry = 1;
1847  c->page = buf;
1848  c->page->bytes = 0;
1849  c->page->sectors = 0;
1850  c->dir = FROM_DRIVE;
1851  d->issue_command(d, c);
1852 
1853  if (c->error)
1854  {ret = 0; goto ex;}
1855 
1856  tdata = c->page->data + 4;
1857  *trackno = tdata[2];
1858  *start = mmc_four_char_to_int(tdata + 4);
1859  ret = 1;
1860 ex:;
1861  BURN_FREE_MEM(buf);
1862  BURN_FREE_MEM(c);
1863  return ret;
1864 }
1865 
1866 
1867 /* ts A61201 */
1868 char *mmc_obtain_profile_name(int profile_number)
1869 {
1870  static char *texts[0x53] = {NULL};
1871  int i, max_pno = 0x53;
1872 
1873  if (texts[0] == NULL) {
1874  for (i = 0; i<max_pno; i++)
1875  texts[i] = "";
1876  /* mmc5r03c.pdf , Table 89, Spelling: guessed cdrecord style */
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";
1903  }
1904  if (profile_number<0 || profile_number>=max_pno)
1905  return "";
1906  return texts[profile_number];
1907 }
1908 
1909 
1910 /* ts A90603 : to be used if the drive knows no GET CONFIGURATION
1911 */
1912 static int mmc_guess_profile(struct burn_drive *d, int flag)
1913 {
1914  int cp;
1915 
1916  cp = 0;
1917  if (d->status == BURN_DISC_BLANK ||
1918  d->status == BURN_DISC_APPENDABLE) {
1919  cp = 0x09;
1920  } else if (d->status == BURN_DISC_FULL) {
1921  cp = 0x08;
1922  }
1923  if (cp)
1924  if (d->erasable)
1925  cp = 0x0a;
1926  d->current_profile = cp;
1927  if (cp == 0)
1928  return 0;
1929  d->current_is_cd_profile = 1;
1932  return 1;
1933 }
1934 
1935 
1936 static int mmc_read_disc_info_al(struct burn_drive *d, int *alloc_len)
1937 {
1938  struct buffer *buf = NULL;
1939  unsigned char *data;
1940  struct command *c = NULL;
1941  char *msg = NULL;
1942  /* ts A70131 : had to move mmc_read_toc() to end of function */
1943  int do_read_toc = 0, disc_status, len, old_alloc_len;
1944  int ret, number_of_sessions = -1;
1945  int key, asc, ascq;
1946 
1947  BURN_ALLOC_MEM(buf, struct buffer, 1);
1948  BURN_ALLOC_MEM(c, struct command, 1);
1949 
1950  /* ts A61020 */
1951  d->start_lba = d->end_lba = -2000000000;
1952  d->erasable = 0;
1953  d->last_track_no = 1;
1954 
1955  /* ts B10730 */
1956  d->sent_default_page_05 = 0;
1957  /* ts A70212 - A70215 */
1958  d->media_capacity_remaining = 0;
1959  d->media_lba_limit = 0;
1960 
1961  /* ts A81210 */
1962  d->media_read_capacity = 0x7fffffff;
1963  d->mr_capacity_trusted = -1;
1964 
1965  /* ts A61202 */
1966  d->toc_entries = 0;
1967  if (d->status == BURN_DISC_EMPTY)
1968  {ret = 1; goto ex;}
1969 
1971 
1973  c->dxfer_len = *alloc_len;
1974  c->opcode[7]= (c->dxfer_len >> 8) & 0xff;
1975  c->opcode[8]= c->dxfer_len & 0xff;
1976  c->retry = 1;
1977  c->page = buf;
1978  c->page->sectors = 0;
1979  c->page->bytes = 0;
1980  c->dir = FROM_DRIVE;
1981  d->issue_command(d, c);
1982 
1983  if (c->error) {
1984  spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
1985  if (key == 5 && asc == 0x20 && ascq == 0) {
1986  /* ts B11031 : qemu -cdrom does not know
1987  051h READ DISC INFORMATION
1988  */
1989  ret = mmc_read_toc_fmt0(d);
1990  if (ret > 0) {
1991 
1992  /* >>> ??? anything more to be set ? */;
1993 
1994  mmc_read_capacity(d);
1995  *alloc_len = 0;
1996  goto ex;
1997  }
1998  }
1999 
2000  d->busy = BURN_DRIVE_IDLE;
2001  {ret = 0; goto ex;}
2002  }
2003 
2004  data = c->page->data;
2005  len = (data[0] << 8) | data[1];
2006  old_alloc_len = *alloc_len;
2007  *alloc_len = len + 2;
2008  if (old_alloc_len < 34)
2009  {ret = 1; goto ex;}
2010  if (*alloc_len < 24) /* data[23] is the last mandatory byte here */
2011  {ret = 0; goto ex;}
2012  if (len + 2 > old_alloc_len)
2013  len = old_alloc_len - 2;
2014 
2015  d->erasable = !!(data[2] & 16);
2016 
2017  /* ts A90908 */
2018  d->disc_type = data[8];
2019  d->disc_info_valid = 1;
2020  d->disc_id = mmc_four_char_to_int(data + 12);
2021  d->disc_info_valid |= (!!(data[7] & 128)) << 1;
2022  if (len + 2 > 31 && (data[7] & 64)) {
2023  memcpy(d->disc_bar_code, data + 24, 8);
2024  d->disc_bar_code[8] = 0;
2025  d->disc_info_valid |= 4;
2026  }
2027  if (len + 2 > 32 && (data[7] & 16)) {
2028  d->disc_app_code = data[32];
2029  d->disc_info_valid |= 8;
2030  }
2031  if (data[7] & 32)
2032  d->disc_info_valid |= 16;
2033  if (data[2] & 16)
2034  d->disc_info_valid |= 32;
2035 
2036  disc_status = data[2] & 3;
2037  d->state_of_last_session = (data[2] >> 2) & 3;
2038  number_of_sessions = (data[9] << 8) | data[4];
2039 
2040  if (d->current_profile == 0x10 || d->current_profile == 0x40) {
2041  /* DVD-ROM , BD-ROM */
2042  disc_status = 2; /* always full and finalized */
2043  d->erasable = 0; /* never erasable */
2044  }
2045 
2046 #ifdef Libburn_support_bd_r_readonlY
2047  /* <<< For now: declaring BD-R read-only
2048  */
2049 #ifndef Libburn_support_bd_plus_r_srM
2050  if (d->current_profile == 0x41) {
2051  /* BD-R seq as readonly dummy */
2052  disc_status = 2; /* always full and finalized */
2053  d->erasable = 0; /* never erasable */
2054  }
2055 #endif
2056  if (d->current_profile == 0x42) {
2057  /* BD-R rnd */
2058  disc_status = 2; /* always full and finalized */
2059  d->erasable = 0; /* never erasable */
2060  }
2061 #endif /* Libburn_support_bd_r_readonlY */
2062 
2063  /* MMC-5 6.22.3.1.16:
2064  Last Session Lead-in Start Address bytes 16 to 19
2065  Last Possible Lead-out Start Address bytes 20 to 23
2066  MSF for CD, LBA else
2067  */
2068  if(d->current_profile == 0x08 || d->current_profile == 0x09 ||
2069  d->current_profile == 0x0a) {
2070  d->last_lead_in =
2071  burn_msf_to_lba(data[17], data[18], data[19]);
2072  d->last_lead_out =
2073  burn_msf_to_lba(data[21], data[22], data[23]);
2074  } else {
2075  d->last_lead_in = mmc_four_char_to_int(data + 16);
2076  d->last_lead_out = mmc_four_char_to_int(data + 20);
2077  }
2078 
2079  switch (disc_status) {
2080  case 0:
2081 regard_as_blank:;
2082  d->toc_entries = 0;
2083 
2084 /*
2085  fprintf(stderr, "libburn_experimental: start_lba = %d (%d %d %d) , end_lba = %d (%d %d %d)\n",
2086  d->start_lba, data[17], data[18], data[19],
2087  d->end_lba, data[21], data[22], data[23]);
2088 */
2089 
2090  d->status = BURN_DISC_BLANK;
2091  d->start_lba = d->last_lead_in;
2092  d->end_lba = d->last_lead_out;
2093  break;
2094  case 1:
2095  case 2:
2096  if (disc_status == 2)
2097  d->status = BURN_DISC_FULL;
2098  else
2100 
2101  /* ts A81210 */
2102  ret = mmc_read_capacity(d);
2103  /* Freshly formatted, unwritten BD-R pretend to be appendable
2104  but in our model they need to be regarded as blank.
2105  Criterion: BD-R seq, read capacity known and 0,
2106  declared appendable, single empty session
2107  */
2108  if (d->current_profile == 0x41 &&
2109  d->status == BURN_DISC_APPENDABLE &&
2110  ret > 0 && d->media_read_capacity == 0 &&
2111  d->state_of_last_session == 0 && number_of_sessions == 1)
2112  goto regard_as_blank;
2113 
2114  if (d->current_profile == 0x41 &&
2115  d->status == BURN_DISC_APPENDABLE &&
2116  d->state_of_last_session == 1) {
2117 
2118  /* ??? apply this test to other media types ? */
2119 
2121  0x00020169,
2123  "Last session on media is still open.", 0, 0);
2124  }
2125 
2126  do_read_toc = 1;
2127  break;
2128  case 3:
2129  /* ts A91009 : DVD-RAM has disc status "others" */
2130  mmc_read_capacity(d);
2131  break;
2132  }
2133 
2134  /* ts A90603 : An MMC-1 drive might not know the media type yet */
2135  if (d->current_is_guessed_profile && d->current_profile == 0)
2136  mmc_guess_profile(d, 0);
2137 
2138  if ((d->current_profile != 0 || d->status != BURN_DISC_UNREADY)
2139  && ! d->current_is_supported_profile) {
2140  if (!(d->silent_on_scsi_error == 1 ||
2141  d->silent_on_scsi_error == 2)) {
2142  msg = calloc(1, 160);
2143  if (msg != NULL) {
2144  sprintf(msg,
2145  "Unsuitable media detected. Profile %4.4Xh %s",
2148  d->global_index, 0x0002011e,
2149  d->silent_on_scsi_error == 3 ?
2152  LIBDAX_MSGS_PRIO_HIGH, msg, 0,0);
2153  free(msg);
2154  }
2155  }
2157  {ret = 0; goto ex;}
2158  }
2159 
2160  /* ts A61217 :
2161  growisofs performs OPC if (data[0]<<8)|data[1]<=32
2162  which indicates no OPC entries are attached to the
2163  reply from the drive.
2164  ts A91104 :
2165  Actually growisofs performs OPC only on DVD-R[W].
2166  */
2167  d->num_opc_tables = 0;
2168  if(((data[0] << 8) | data[1]) > 32) /* i.e. > 34 bytes are available */
2169  d->num_opc_tables = data[33];
2170 
2171  /* ts A61219 : mmc5r03c.pdf 6.22.3.1.13 BG Format Status
2172  0=blank (not yet started)
2173  1=started but neither running nor complete
2174  2=in progress
2175  3=completed
2176  */
2177  d->bg_format_status = data[7] & 3;
2178 
2179  /* Preliminarily declare blank:
2180  ts A61219 : DVD+RW (is not bg_format_status==0 "blank")
2181  ts A61229 : same for DVD-RW Restricted overwrite
2182  ts A70112 : same for DVD-RAM
2183  */
2184  if (d->current_profile == 0x1a || d->current_profile == 0x13 ||
2185  d->current_profile == 0x12 || d->current_profile == 0x43)
2186  d->status = BURN_DISC_BLANK;
2187 
2188 #ifdef Libburn_disc_with_incomplete_sessioN
2189  /* ts B30112 : number of open sessions */
2190  d->incomplete_sessions = 0;
2191 #endif
2192 
2193  if (d->status == BURN_DISC_BLANK) {
2194  d->last_track_no = 1; /* The "incomplete track" */
2195  d->complete_sessions = 0;
2196  } else {
2197  /* ts A70131 : number of closed sessions */
2198  d->complete_sessions = number_of_sessions;
2199  /* mmc5r03c.pdf 6.22.3.1.3 State of Last Session: 3=complete */
2200  if (d->state_of_last_session != 3 &&
2201  d->complete_sessions >= 1) {
2202  d->complete_sessions--;
2203 
2204 #ifdef Libburn_disc_with_incomplete_sessioN
2205  d->incomplete_sessions++;
2206 #endif
2207 
2208  }
2209 
2210  /* ts A70129 : mmc5r03c.pdf 6.22.3.1.7
2211  This includes the "incomplete track" if the disk is
2212  appendable. I.e number of complete tracks + 1. */
2213  d->last_track_no = (data[11] << 8) | data[6];
2214  }
2215  if (d->current_profile != 0x0a && d->current_profile != 0x13 &&
2216  d->current_profile != 0x14 && d->status != BURN_DISC_FULL)
2217  d->erasable = 0; /* stay in sync with burn_disc_erase() */
2218 
2219  if (do_read_toc)
2220  mmc_read_toc(d);
2221  ret = 1;
2222 ex:
2223  BURN_FREE_MEM(buf);
2224  BURN_FREE_MEM(c);
2225  return ret;
2226 }
2227 
2228 
2230 {
2231  int alloc_len = 34, ret;
2232 
2233  mmc_start_if_needed(d, 1);
2234  if (mmc_function_spy(d, "mmc_read_disc_info") <= 0)
2235  return;
2236 
2237  ret = mmc_read_disc_info_al(d, &alloc_len);
2238 /*
2239  fprintf(stderr,"LIBBURN_DEBUG: 51h alloc_len = %d , ret = %d\n",
2240  alloc_len, ret);
2241 */
2242  if (ret <= 0)
2243  return;
2244 
2245  /* for now there is no need to inquire the variable length part */
2246 }
2247 
2248 
2249 /* @param flag bit= do not allocate text_packs
2250 */
2251 static int mmc_get_leadin_text_al(struct burn_drive *d,
2252  unsigned char **text_packs, int *alloc_len,
2253  int flag)
2254 {
2255  struct buffer *buf = NULL;
2256  struct command *c = NULL;
2257  unsigned char *data;
2258  int ret, data_length;
2259 
2260  *text_packs = NULL;
2261 
2262  BURN_ALLOC_MEM(buf, struct buffer, 1);
2263  BURN_ALLOC_MEM(c, struct command, 1);
2264 
2266  c->dxfer_len = *alloc_len;
2267  c->opcode[7]= (c->dxfer_len >> 8) & 0xff;
2268  c->opcode[8]= c->dxfer_len & 0xff;
2269  c->retry = 1;
2270  c->page = buf;
2271  c->page->bytes = 0;
2272  c->page->sectors = 0;
2273 
2274  c->dir = FROM_DRIVE;
2275  d->issue_command(d, c);
2276  if (c->error)
2277  {ret = 0; goto ex;}
2278 
2279  data = c->page->data;
2280  data_length = (data[0] << 8) + data[1];
2281  *alloc_len = data_length + 2;
2282  if (*alloc_len >= 22 && !(flag & 1)) {
2283  BURN_ALLOC_MEM(*text_packs, unsigned char, *alloc_len - 4);
2284  memcpy(*text_packs, data + 4, *alloc_len - 4);
2285  }
2286  ret = 1;
2287 ex:;
2288  BURN_FREE_MEM(c);
2289  BURN_FREE_MEM(buf);
2290  return ret;
2291 }
2292 
2293 
2294 /* ts B11201 */
2295 /* Read the CD-TEXT data from the Lead-in of an Audio CD
2296 */
2298  unsigned char **text_packs, int *num_packs, int flag)
2299 {
2300  int alloc_len = 4, ret;
2301 
2302  *num_packs = 0;
2303  if (mmc_function_spy(d, "mmc_get_leadin_text") <= 0)
2304  return -1;
2305  ret = mmc_get_leadin_text_al(d, text_packs, &alloc_len, 1);
2306  if (ret <= 0 || alloc_len < 22)
2307  return (ret > 0 ? 0 : ret);
2308  ret = mmc_get_leadin_text_al(d, text_packs, &alloc_len, 0);
2309  if (ret <= 0 || alloc_len < 22) {
2310  if (*text_packs != NULL)
2311  free(*text_packs);
2312  *text_packs = NULL;
2313  return (ret > 0 ? 0 : ret);
2314  }
2315  *num_packs = (alloc_len - 4) / 18;
2316  return ret;
2317 }
2318 
2319 
2320 void mmc_read_atip(struct burn_drive *d)
2321 {
2322  struct buffer *buf = NULL;
2323  struct command *c = NULL;
2324  int alloc_len = 28;
2325 
2326  /* ts A61021 */
2327  unsigned char *data;
2328  /* Speed values from A1:
2329  With 4 cdrecord tells "10" or "8" where MMC-1 says "8".
2330  cdrecord "8" appear on 4xCD-RW and thus seem to be quite invalid.
2331  My CD-R (>=24 speed) tell no A1.
2332  The higher non-MMC-1 values are hearsay.
2333  */
2334  /* 0, 2, 4, 6, 10, -, 16, -, */
2335  static int speed_value[16]= { 0, 353, 706, 1059, 1764, -5, 2824, -7,
2336  4234, 5646, 7056, 8468, -12, -13, -14, -15};
2337  /* 24, 32, 40, 48, -, -, -, - */
2338 
2339  BURN_ALLOC_MEM_VOID(buf, struct buffer, 1);
2340  BURN_ALLOC_MEM_VOID(c, struct command, 1);
2341  mmc_start_if_needed(d, 1);
2342  if (mmc_function_spy(d, "mmc_read_atip") <= 0)
2343  goto ex;
2344 
2346  c->dxfer_len = alloc_len;
2347  c->opcode[7] = (c->dxfer_len >> 8) & 0xff;
2348  c->opcode[8] = c->dxfer_len & 0xff;
2349  c->retry = 1;
2350  c->page = buf;
2351  c->page->bytes = 0;
2352  c->page->sectors = 0;
2353 
2354  c->dir = FROM_DRIVE;
2355  d->issue_command(d, c);
2356  /* ts B00501 : now caring for error */
2357  if (c->error) {
2358  d->erasable = 0;
2359  d->start_lba = 0;
2360  d->end_lba = 0;
2361  goto ex;
2362  }
2363 
2364  /* ts A61021 */
2365  data = c->page->data;
2366  d->erasable = !!(data[6]&64);
2367  d->start_lba = burn_msf_to_lba(data[8],data[9],data[10]);
2368  d->end_lba = burn_msf_to_lba(data[12],data[13],data[14]);
2369 
2370  /* ts B21124 : LITE-ON LTR-48125S returns crap on pressed
2371  audio CD and CD-ROM
2372  */
2373  if (d->start_lba >= d->end_lba) {
2374  d->start_lba = 0;
2375  d->end_lba = 0;
2376  }
2377 
2378  if (data[6]&4) {
2379  if (speed_value[(data[16]>>4)&7] > 0) {
2380  d->mdata->min_write_speed =
2381  speed_value[(data[16]>>4)&7];
2382  if (speed_value[(data[16])&15] <= 0)
2383  d->mdata->max_write_speed =
2384  speed_value[(data[16]>>4)&7];
2385  }
2386  if (speed_value[(data[16])&15] > 0) {
2387  d->mdata->max_write_speed =
2388  speed_value[(data[16])&15];
2389  if (speed_value[(data[16]>>4)&7] <= 0)
2390  d->mdata->min_write_speed =
2391  speed_value[(data[16])&15];
2392  }
2393  }
2394 
2395 #ifdef Burn_mmc_be_verbous_about_atiP
2396  { int i;
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");
2402 
2403  fprintf(stderr,
2404  "libburn_experimental: Indicative Target Writing Power= %d\n",
2405  (data[4]>>4)&7);
2406  fprintf(stderr,
2407  "libburn_experimental: Reference speed= %d ->%d\n",
2408  data[4]&7, speed_value[data[4]&7]);
2409  fprintf(stderr,
2410  "libburn_experimental: Is %sunrestricted\n",
2411  (data[5]&64?"":"not "));
2412  fprintf(stderr,
2413  "libburn_experimental: Is %serasable, sub-type %d\n",
2414  (data[6]&64?"":"not "),(data[6]>>3)&3);
2415  fprintf(stderr,
2416  "libburn_experimental: lead in: %d (%-2.2d:%-2.2d/%-2.2d)\n",
2417  burn_msf_to_lba(data[8],data[9],data[10]),
2418  data[8],data[9],data[10]);
2419  fprintf(stderr,
2420  "libburn_experimental: lead out: %d (%-2.2d:%-2.2d/%-2.2d)\n",
2421  burn_msf_to_lba(data[12],data[13],data[14]),
2422  data[12],data[13],data[14]);
2423  if(data[6]&4)
2424  fprintf(stderr,
2425  "libburn_experimental: A1 speed low %d speed high %d\n",
2426  speed_value[(data[16]>>4)&7], speed_value[(data[16])&7]);
2427  if(data[6]&2)
2428  fprintf(stderr,
2429  "libburn_experimental: A2 speed low %d speed high %d\n",
2430  speed_value[(data[20]>>4)&7], speed_value[(data[20])&7]);
2431  if(data[6]&1)
2432  fprintf(stderr,
2433  "libburn_experimental: A3 speed low %d speed high %d\n",
2434  speed_value[(data[24]>>4)&7], speed_value[(data[24])&7]);
2435  }
2436 
2437 #endif /* Burn_mmc_be_verbous_about_atiP */
2438 
2439 /* ts A61020
2440 http://www.t10.org/ftp/t10/drafts/mmc/mmc-r10a.pdf , table 77 :
2441 
2442  0 ATIP Data Length MSB
2443  1 ATIP Data Length LSB
2444  2 Reserved
2445  3 Reserved
2446  4 bit7=1, bit4-6="Indicative Target Writing Power", bit3=reserved ,
2447  bit0-2="Reference speed"
2448  5 bit7=0, bit6="URU" , bit0-5=reserved
2449  6 bit7=1, bit6="Disc Type", bit3-4="Disc Sub-Type",
2450  bit2="A1", bit1="A2", bit0="A3"
2451  7 reserved
2452  8 ATIP Start Time of lead-in (Min)
2453  9 ATIP Start Time of lead-in (Sec)
2454 10 ATIP Start Time of lead-in (Frame)
2455 11 reserved
2456 12 ATIP Last Possible Start Time of lead-out (Min)
2457 13 ATIP Last Possible Start Time of lead-out (Sec)
2458 14 ATIP Last Possible Start Time of lead-out (Frame)
2459 15 reserved
2460 16 bit7=0, bit4-6="Lowest Usable CLV Recording speed"
2461  bit0-3="Highest Usable CLV Recording speed"
2462 17 bit7=0, bit4-6="Power Multiplication Factor p",
2463  bit1-3="Target y value of the Modulation/Power function", bit0=reserved
2464 18 bit7=1, bit4-6="Recommended Erase/Write Power Ratio (P(inf)/W(inf))"
2465  bit0-3=reserved
2466 19 reserved
2467 20-22 A2 Values
2468 23 reserved
2469 24-26 A3 Values
2470 27 reserved
2471 
2472 Disc Type - zero indicates CD-R media; one indicates CD-RW media.
2473 
2474 Disc Sub-Type - shall be set to zero.
2475 
2476 A1 - when set to one, indicates that bytes 16-18 are valid.
2477 
2478 Lowest Usable CLV Recording Speed
2479 000b Reserved
2480 001b 2X
2481 010b - 111b Reserved
2482 
2483 Highest CLV Recording Speeds
2484 000b Reserved
2485 001b 2X
2486 010b 4X
2487 011b 6X
2488 100b 8X
2489 101b - 111b Reserved
2490 
2491 MMC-3 seems to recommend MODE SENSE (5Ah) page 2Ah rather than A1, A2, A3.
2492 This page is loaded in libburn function spc_sense_caps() .
2493 Speed is given in kbytes/sec there. But i suspect this to be independent
2494 of media. So one would habe to associate the speed descriptor blocks with
2495 the ATIP media characteristics ? How ?
2496 
2497 */
2498 
2499 ex:;
2500  BURN_FREE_MEM(buf);
2501  BURN_FREE_MEM(c);
2502 }
2503 
2504 
2505 int mmc_eval_read_error(struct burn_drive *d, struct command *c, char *what,
2506  int start_m, int start_s, int start_f,
2507  int end_m, int end_s, int end_f, int flag)
2508 {
2509  char *msg = NULL;
2510  int key, asc, ascq, silent;
2511 
2512  if (!c->error)
2513  return 0;
2514 
2515  msg = calloc(1, 256);
2516  if (msg != NULL) {
2517  if (start_s < 0 || start_f < 0 || end_s < 0 || end_f < 0) {
2518  sprintf(msg,
2519  "SCSI error on %s(%d,%d): ", what, start_m, end_m);
2520  } else {
2521  sprintf(msg, "SCSI error on %s(%dm%ds%df,%dm%ds%df): ",
2522  what,
2523  start_m, start_s, start_f, end_m, end_s, end_f);
2524  }
2525  scsi_error_msg(d, c->sense, 14, msg + strlen(msg),
2526  &key, &asc, &ascq);
2527  silent = (d->silent_on_scsi_error == 1);
2528  if (key == 5 && asc == 0x64 && ascq == 0x0) {
2529  d->had_particular_error |= 1;
2530  if (d->silent_on_scsi_error == 2)
2531  silent = 1;
2532  }
2533  if(!silent)
2535  d->global_index,
2536  0x00020144,
2537  d->silent_on_scsi_error == 3 ?
2539  LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
2540  free(msg);
2541  }
2542  return BE_CANCELLED;
2543 }
2544 
2545 
2546 /* ts B21119 : Derived from older mmc_read_sectors()
2547  @param flag bit0= set DAP bit (also with o->dap_bit)
2548 */
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,
2553  const struct burn_read_opts *o, struct buffer *buf, int flag)
2554 {
2555  int req, ret, dap_bit;
2556  int subcodes_audio = 0, subcodes_data = 0;
2557  struct command *c;
2558 #ifdef Libburn_mmc_report_recovereD
2559  int report_recovered_errors = 0;
2560 #endif
2561 
2562  c = &(d->casual_command);
2563  mmc_start_if_needed(d, 0);
2564  if (mmc_function_spy(d, "mmc_read_cd_msf") <= 0)
2565  return -1;
2566 
2567  dap_bit = flag & 1;
2568  if (o != NULL) {
2569  subcodes_audio = o->subcodes_audio;
2570  subcodes_data = o->subcodes_data;
2571  dap_bit |= o->dap_bit;
2572 
2573 #ifdef Libburn_mmc_report_recovereD
2574  report_recovered_errors = o->report_recovered_errors;
2575 #endif
2576  }
2577 
2579  c->retry = 1;
2580  c->opcode[1] = ((sec_type & 7) << 2) | ((!!dap_bit) << 1);
2581  c->opcode[3] = start_m;
2582  c->opcode[4] = start_s;
2583  c->opcode[5] = start_f;
2584  c->opcode[6] = end_m;
2585  c->opcode[7] = end_s;
2586  c->opcode[8] = end_f;
2587 
2588  req = main_ch & 0xf8;
2589 
2590 #ifdef Libburn_mmc_report_recovereD
2591  /* ts A61106 : LG GSA-4082B dislikes this. key=5h asc=24h ascq=00h */
2592  if (d->busy == BURN_DRIVE_GRABBING || report_recovered_errors)
2593  req |= 2;
2594 #endif /* Libburn_mmc_report_recovereD */
2595 
2596  c->opcode[9] = req;
2597 
2598  c->opcode[10] = 0;
2599 /* always read the subcode, throw it away later, since we don't know
2600  what we're really reading
2601 */
2602 /* >>> ts B21125 : This is very obscure:
2603  MMC-3 has sub channel selection 001b as "RAW"
2604  MMC-5 does neither mention 001b nor "RAW".
2605  And why should a non-grabbed drive get here ?
2606 */
2607  if (d->busy == BURN_DRIVE_GRABBING || subcodes_audio || subcodes_data)
2608  c->opcode[10] = 1;
2609 
2610 /* <<< ts B21125 : test with sub channel selection 100b
2611  no data, only sub channel
2612  c->opcode[9] = 0;
2613  c->opcode[10] = 4;
2614  Did not help either with reading before LBA -150
2615 */
2616 /* <<< ts B21125 : test with sub channel selection 001b and no user data
2617  c->opcode[9] = 0;
2618  c->opcode[10] = 1;
2619 */
2620 
2621  c->page = buf;
2622  c->dir = FROM_DRIVE;
2623  d->issue_command(d, c);
2624  ret = mmc_eval_read_error(d, c, "read_cd_msf",
2625  start_m, start_s, start_f,
2626  end_m, end_s, end_f, 0);
2627  return ret;
2628 }
2629 
2630 
2631 /* ts B21119 : Derived from older mmc_read_sectors()
2632  @param flag bit0= set DAP bit (also with o->dap_bit)
2633 */
2634 int mmc_read_cd(struct burn_drive *d, int start, int len,
2635  int sec_type, int main_ch,
2636  const struct burn_read_opts *o, struct buffer *buf, int flag)
2637 {
2638  int temp, req, ret, dap_bit;
2639  int subcodes_audio = 0, subcodes_data = 0;
2640  struct command *c;
2641 
2642 #ifdef Libburn_mmc_report_recovereD
2643  int report_recovered_errors = 0;
2644 #endif
2645 
2646 /* # define Libburn_read_cd_by_msF 1 */
2647 #ifdef Libburn_read_cd_by_msF
2648 
2649  int start_m, start_s, start_f, end_m, end_s, end_f;
2650 
2651  burn_lba_to_msf(start, &start_m, &start_s, &start_f);
2652  burn_lba_to_msf(start + len, &end_m, &end_s, &end_f);
2653  ret = mmc_read_cd_msf(d, start_m, start_s, start_f,
2654  end_m, end_s, end_f,
2655  sec_type, main_ch, o, buf, flag);
2656  return ret;
2657 
2658 #endif /* Libburn_read_cd_by_msF */
2659 
2660  c = &(d->casual_command);
2661  mmc_start_if_needed(d, 0);
2662  if (mmc_function_spy(d, "mmc_read_cd") <= 0)
2663  return -1;
2664 
2665  dap_bit = flag & 1;
2666  if (o != NULL) {
2667  subcodes_audio = o->subcodes_audio;
2668  subcodes_data = o->subcodes_data;
2669  dap_bit |= o->dap_bit;
2670 
2671 #ifdef Libburn_mmc_report_recovereD
2672  report_recovered_errors = o->report_recovered_errors;
2673 #endif
2674  }
2675 
2677  c->retry = 1;
2678  c->opcode[1] = ((sec_type & 7) << 2) | ((!!dap_bit) << 1);
2679  temp = start;
2680  c->opcode[5] = temp & 0xFF;
2681  temp >>= 8;
2682  c->opcode[4] = temp & 0xFF;
2683  temp >>= 8;
2684  c->opcode[3] = temp & 0xFF;
2685  temp >>= 8;
2686  c->opcode[2] = temp & 0xFF;
2687  c->opcode[8] = len & 0xFF;
2688  len >>= 8;
2689  c->opcode[7] = len & 0xFF;
2690  len >>= 8;
2691  c->opcode[6] = len & 0xFF;
2692  req = main_ch & 0xf8;
2693 
2694 #ifdef Libburn_mmc_report_recovereD
2695  /* ts A61106 : LG GSA-4082B dislikes this. key=5h asc=24h ascq=00h */
2696  if (d->busy == BURN_DRIVE_GRABBING || report_recovered_errors)
2697  req |= 2;
2698 #endif /* Libburn_mmc_report_recovereD */
2699 
2700  c->opcode[9] = req;
2701  c->opcode[10] = 0;
2702 /* always read the subcode, throw it away later, since we don't know
2703  what we're really reading
2704 */
2705 /* >>> ts B21125 : This is very obscure:
2706  MMC-3 has sub channel selection 001b as "RAW"
2707  MMC-5 does neither mention 001b nor "RAW".
2708  And why should a non-grabbed drive get here ?
2709 */
2710  if (d->busy == BURN_DRIVE_GRABBING || subcodes_audio || subcodes_data)
2711  c->opcode[10] = 1;
2712 
2713 /* <<< ts B21125 : test with sub channel selection 100b
2714  c->opcode[10] = 4;
2715 */
2716 /* <<< ts B21125 : test with sub channel selection 001b and no user data
2717  c->opcode[9] = 0;
2718  c->opcode[10] = 1;
2719 */
2720 
2721  c->page = buf;
2722  c->dir = FROM_DRIVE;
2723  d->issue_command(d, c);
2724  ret = mmc_eval_read_error(d, c, "read_cd", start, -1, -1,
2725  len, -1, -1, 0);
2726  return ret;
2727 }
2728 
2729 void mmc_erase(struct burn_drive *d, int fast)
2730 {
2731  struct command *c;
2732 
2733  c = &(d->casual_command);
2734  mmc_start_if_needed(d, 0);
2735  if (mmc_function_spy(d, "mmc_erase") <= 0)
2736  return;
2737 
2738  scsi_init_command(c, MMC_BLANK, sizeof(MMC_BLANK));
2739  if (!d->do_no_immed)
2740  c->opcode[1] = 16; /* IMMED set to 1 */
2741  c->opcode[1] |= !!fast;
2742  c->retry = 1;
2743  c->page = NULL;
2744  c->dir = NO_TRANSFER;
2745  if (d->do_no_immed)
2747  else
2749  d->issue_command(d, c);
2750  if (c->error) {
2751  d->cancel = 1;
2752  scsi_notify_error(d, c, c->sense, 14, 2);
2753  }
2754 }
2755 
2756 void mmc_read_lead_in(struct burn_drive *d, struct buffer *buf)
2757 {
2758  struct command *c;
2759 
2760  c = &(d->casual_command);
2761  mmc_start_if_needed(d, 0);
2762  if (mmc_function_spy(d, "mmc_read_lead_in") <= 0)
2763  return;
2764 
2766  c->retry = 1;
2767  c->opcode[5] = 0;
2768  c->opcode[4] = 0;
2769  c->opcode[3] = 0;
2770  c->opcode[2] = 0xF0;
2771  c->opcode[8] = 1;
2772  c->opcode[7] = 0;
2773  c->opcode[6] = 0;
2774  c->opcode[9] = 0;
2775  c->opcode[10] = 2;
2776  c->page = buf;
2777  c->dir = FROM_DRIVE;
2778  d->issue_command(d, c);
2779 }
2780 
2782 {
2783  struct command *c;
2784 
2785  c = &(d->casual_command);
2786  mmc_start_if_needed(d, 0);
2787  if (mmc_function_spy(d, "mmc_perform_opc") <= 0)
2788  return;
2789 
2791  c->retry = 1;
2792  c->opcode[1] = 1;
2793  c->page = NULL;
2794  c->dir = NO_TRANSFER;
2796  d->issue_command(d, c);
2797 }
2798 
2799 
2800 /* ts A61221 : Learned much from dvd+rw-tools-7.0 set_speed_B6h() but then
2801  made own experiments on base of mmc5r03c.pdf 6.8.3 and 6.39 in the hope
2802  to achieve a leaner solution
2803  ts A70712 : That leaner solution does not suffice for my LG GSA-4082B.
2804  Meanwhile there is a speed descriptor list anyway.
2805 */
2807  int r_speed, int w_speed, int end_lba)
2808 {
2809  struct buffer *buf = NULL;
2810  struct command *c = NULL;
2811  int b, eff_end_lba, ret;
2812  char *msg = NULL;
2813  unsigned char *pd;
2814  int key, asc, ascq;
2815 
2816  BURN_ALLOC_MEM(buf, struct buffer, 1);
2817  BURN_ALLOC_MEM(c, struct command, 1);
2818  BURN_ALLOC_MEM(msg, char, 256);
2819  mmc_start_if_needed(d, 1);
2820  if (mmc_function_spy(d, "mmc_set_streaming") <= 0)
2821  {ret = 0; goto ex;}
2822 
2824  c->retry = 1;
2825  c->page = buf;
2826  c->page->bytes = 28;
2827  c->opcode[9] = (c->page->bytes >> 8) & 0xff;
2828  c->opcode[10] = c->page->bytes & 0xff;
2829  c->page->sectors = 0;
2830  c->dir = TO_DRIVE;
2831  memset(c->page->data, 0, c->page->bytes);
2832  pd = c->page->data;
2833 
2834  pd[0] = 0; /* WRC=0 (Default Rotation Control), RDD=Exact=RA=0 */
2835  if (d->set_streaming_exact_bit)
2836  pd[0] |= 2; /* Exact= 1 */
2837 
2838  if (w_speed == 0)
2839  w_speed = 0x10000000; /* ~ 2 TB/s */
2840  else if (w_speed < 0)
2841  w_speed = 177; /* 1x CD */
2842  if (r_speed == 0)
2843  r_speed = 0x10000000; /* ~ 2 TB/s */
2844  else if (r_speed < 0)
2845  r_speed = 177; /* 1x CD */
2846  if (end_lba == 0) {
2847  /* Default computed from 4.7e9 */
2848  eff_end_lba = 2294921 - 1;
2849  if (d->mdata->max_end_lba > 0)
2850  eff_end_lba = d->mdata->max_end_lba - 1;
2851  } else
2852  eff_end_lba = end_lba;
2853 
2854  sprintf(msg,
2855  "mmc_set_streaming: end_lba=%d , r=%d , w=%d , exact=%d",
2856  eff_end_lba, r_speed, w_speed, !!(pd[0] & 2));
2859  msg, 0, 0);
2860 
2861  /* start_lba is 0 , 1000 = 1 second as base time for data rate */
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;
2868  }
2869 
2870 /* <<<
2871  fprintf(stderr,"LIBBURN_EXPERIMENTAL : B6h Performance descriptor:\n");
2872  for (b = 0; b < 28 ; b++)
2873  fprintf(stderr, "%2.2X%c", pd[b], ((b+1)%4 ? ' ' : '\n'));
2874 */
2875 
2876 
2877  d->issue_command(d, c);
2878  if (c->error) {
2879  spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
2880  if (key != 0 && d->silent_on_scsi_error != 1 &&
2881  d->silent_on_scsi_error != 2) {
2882  sprintf(msg,
2883  "SCSI error on set_streaming(%d): ", w_speed);
2884  scsi_error_msg(d, c->sense, 14, msg + strlen(msg),
2885  &key, &asc, &ascq);
2887  0x00020124,
2888  d->silent_on_scsi_error == 3 ?
2890  LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
2891  }
2892  if (key != 0)
2893  d->set_streaming_err = 1;
2894  {ret = 0; goto ex;}
2895  }
2896  ret = 1;
2897 ex:;
2898  BURN_FREE_MEM(msg);
2899  BURN_FREE_MEM(c);
2900  BURN_FREE_MEM(buf);
2901  return ret;
2902 }
2903 
2904 
2905 void mmc_set_speed(struct burn_drive *d, int r, int w)
2906 {
2907  struct command *c;
2908  int ret, end_lba = 0, get_max, get_min;
2909  struct burn_speed_descriptor *best_sd = NULL;
2910 
2911  c = &(d->casual_command);
2912  mmc_start_if_needed(d, 1);
2913  if (mmc_function_spy(d, "mmc_set_speed") <= 0)
2914  return;
2915 
2916  if (r <= 0 || w <= 0) {
2917  /* ts A70712 : now searching for best speed descriptor */
2918  /* ts B31030 : keeping max read speed from sinking too low */
2919  if (r <= 0) {
2920  get_max = (r == 0);
2921  get_min = (r == -1);
2922  burn_drive_get_best_speed(d, r, &best_sd, 1 | 2);
2923  if (best_sd != NULL) {
2924  r = best_sd->read_speed;
2925  end_lba = best_sd->end_lba;
2926  }
2927  if (get_max) {
2928  if (d->current_is_cd_profile) {
2929  if (r < Libburn_cd_max_read_speeD)
2931  } else if (d->current_profile >= 0x10 &&
2932  d->current_profile <= 0x2f) {
2935  } else if (d->current_profile >= 0x40 &&
2936  d->current_profile <= 0x43) {
2937  if (r < Libburn_bd_max_read_speeD)
2939  }
2940  } else if(get_min) {
2941  if (d->current_is_cd_profile) {
2942  if (r > Libburn_cd_min_read_speeD)
2944  } else if (d->current_profile >= 0x10 &&
2945  d->current_profile <= 0x2f) {
2948  } else if (d->current_profile >= 0x40 &&
2949  d->current_profile <= 0x43) {
2950  if (r > Libburn_bd_min_read_speeD)
2952  }
2953  }
2954  }
2955  if (w <= 0) {
2956  burn_drive_get_best_speed(d, w, &best_sd, 2);
2957  if (best_sd != NULL) {
2958  w = best_sd->write_speed;
2959  d->nominal_write_speed = w;
2960  if (end_lba < best_sd->end_lba)
2961  end_lba = best_sd->end_lba;
2962  }
2963  }
2964  }
2965 
2966  /* A70711 */
2967  d->nominal_write_speed = w;
2968 
2969  /* ts A61221 : try to set DVD speed via command B6h */
2970  if (strstr(d->current_profile_text, "DVD") == d->current_profile_text
2971  || strstr(d->current_profile_text, "BD") == d->current_profile_text
2972  || d->set_streaming_exact_bit) {
2973  ret = mmc_set_streaming(d, r, w, end_lba);
2974  if (ret != 0)
2975  return; /* success or really fatal failure */
2976  }
2977 
2978  /* ts A61112 : MMC standards prescribe FFFFh as max speed.
2979  But libburn.h prescribes 0.
2980  ts A70715 : <0 now means minimum speed */
2981  if (r == 0 || r > 0xffff)
2982  r = 0xffff;
2983  else if (r < 0)
2984  r = 177; /* 1x CD */
2985  if (w == 0 || w > 0xffff)
2986  w = 0xffff;
2987  else if (w < 0)
2988  w = 177; /* 1x CD */
2989 
2991  c->retry = 1;
2992  c->opcode[2] = r >> 8;
2993  c->opcode[3] = r & 0xFF;
2994  c->opcode[4] = w >> 8;
2995  c->opcode[5] = w & 0xFF;
2996  c->page = NULL;
2997  c->dir = NO_TRANSFER;
2998  d->issue_command(d, c);
2999 }
3000 
3001 
3002 /* ts A61201 : found in unfunctional state
3003  */
3004 static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len)
3005 {
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;
3011  struct command *c = NULL;
3012  int phys_if_std = 0;
3013  char *phys_name = "";
3014  struct burn_feature_descr *recent_feature = NULL, *new_feature;
3015  char *msg = NULL;
3016 
3017 /* Enable this to get loud and repeated reports about the feature set :
3018  # define Libburn_print_feature_descriptorS 1
3019 */
3020 #ifdef Libburn_print_feature_descriptorS
3021  int prf_number;
3022 
3023  only_current = 0;
3024 #endif
3025 
3026  if (*alloc_len < 8)
3027  {ret = 0; goto ex;}
3028 
3029  BURN_ALLOC_MEM(buf, struct buffer, 1);
3030  BURN_ALLOC_MEM(c, struct command, 1);
3031  d->current_profile = 0;
3032  d->current_profile_text[0] = 0;
3033  d->current_is_cd_profile = 0;
3036  d->num_profiles = 0;
3037  if (d->features != NULL)
3039  d->current_has_feat21h = 0;
3040  d->current_feat21h_link_size = -1;
3041  d->current_feat23h_byte4 = 0;
3042  d->current_feat23h_byte8 = 0;
3043  d->current_feat2fh_byte4 = -1;
3044 
3046  sizeof(MMC_GET_CONFIGURATION));
3047  c->dxfer_len= *alloc_len;
3048  c->retry = 1;
3049  c->opcode[7] = (c->dxfer_len >> 8) & 0xff;
3050  c->opcode[8] = c->dxfer_len & 0xff;
3051  c->page = buf;
3052  c->page->sectors = 0;
3053  c->page->bytes = 0;
3054  c->dir = FROM_DRIVE;
3055  d->issue_command(d, c);
3056 
3057 #ifdef Libisofs_simulate_old_mmc1_drivE
3058  c->error = 1;
3059  c->sense[0] = 0x70; /* Fixed format sense data */
3060  c->sense[2] = 0x5;
3061  c->sense[12] = 0x20;
3062  c->sense[13] = 0x0;
3063 #endif /* Libisofs_simulate_old_mmc1_drivE */
3064 
3065  if (c->error) {
3066  /* ts A90603 : MMC-1 drive do not know 46h GET CONFIGURATION */
3067  spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
3068  if (key == 0x5 && asc == 0x20 && ascq == 0x0) {
3070  /* Will yield a non-zero profile only after
3071  mmc_read_disc_info_al() was called */
3072  mmc_guess_profile(d, 0);
3073  }
3074  {ret = 0; goto ex;}
3075  }
3076  old_alloc_len = *alloc_len;
3077  *alloc_len = len = mmc_four_char_to_int(c->page->data) + 4;
3078  if (len > old_alloc_len)
3079  len = old_alloc_len;
3080  if (len < 8)
3081  {ret = 0; goto ex;}
3082  if (len > 4096) {
3083  /* MMC-5 6.6.2.1, Note 11: The maximum is less than 1 KB */
3084  BURN_ALLOC_MEM(msg, char, 256);
3085  sprintf(msg, "Implausible length announcement from SCSI command GET CONFIGURATION: %d", *alloc_len);
3087  0x000201a9,
3089  msg, 0, 0);
3090  ret = 0; goto ex;
3091  }
3092 
3093  cp = (c->page->data[6]<<8) | c->page->data[7];
3094 
3095 #ifdef Libburn_rom_as_profilE
3096  if (cp == 0x08 || cp == 0x10 || cp==0x40)
3097  cp = Libburn_rom_as_profilE;
3098 #endif /* Libburn_rom_as_profilE */
3099 
3100  d->current_profile = cp;
3102 
3103  /* Read-only supported media */
3104 
3105  if (cp == 0x08) /* CD-ROM */
3107  if (cp == 0x10) /* DVD-ROM */
3109  if (cp == 0x40) /* BD-ROM */
3111 
3112 #ifdef Libburn_support_bd_r_readonlY
3113 #ifndef Libburn_support_bd_plus_r_srM
3114  if (cp == 0x41) /* BD-R sequential (here as read-only dummy) */
3116 #endif
3117  if (cp == 0x42) /* BD-R random recording */
3119 #endif
3120 
3121 
3122  /* Write supported media (they get declared suitable in
3123  burn_disc_get_multi_caps) */
3124 
3125  if (cp == 0x09 || cp == 0x0a)
3127 
3128 #ifdef Libburn_support_dvd_plus_rW
3129  if (cp == 0x1a)
3131 #endif
3132 #ifdef Libburn_support_dvd_minusrw_overW
3133  if (cp == 0x13)
3135 #endif
3136 #ifdef Libburn_support_dvd_raM
3137  if (cp == 0x12 || cp == 0x43) { /* DVD-RAM , BD-RE */
3139 
3140 #ifdef Libburn_dvd_ram_as_bd_rE
3141  cp = d->current_profile = 0x43;
3143 #endif
3144 
3145  }
3146 #endif
3147 #ifdef Libburn_support_dvd_r_seQ
3148  if (cp == 0x11 || cp == 0x14) /* DVD-R, DVD-RW */
3150  if (cp == 0x15) /* DVD-R/DL */
3152 #endif
3153 #ifdef Libburn_support_dvd_plus_R
3154  if (cp == 0x1b || cp == 0x2b) /* DVD+R , DVD+R/DL */
3156 #endif
3157 #ifdef Libburn_support_bd_plus_r_srM
3158  if (cp == 0x41) /* BD-R SRM */
3160 #endif
3161 
3162  /* ts A70127 : Interpret list of profile and feature descriptors.
3163  see mmc5r03c.pdf 5.2
3164  */
3165  up_to = c->page->data + len;
3166 
3167 #ifdef Libburn_print_feature_descriptorS
3168  fprintf(stderr,
3169  "-----------------------------------------------------------------\n");
3170  fprintf(stderr,
3171  "LIBBURN_EXPERIMENTAL : feature list length = %d , shown = %d\n",
3172  len, (int) (up_to - c->page->data));
3173 #endif /* Libburn_print_feature_descriptorS */
3174 
3175  for (descr = c->page->data + 8; descr + 3 < up_to; descr += descr_len){
3176  descr_len = 4 + descr[3];
3177  feature_code = (descr[0] << 8) | descr[1];
3178  feature_is_current = descr[2] & 1;
3179 
3180  ret = burn_feature_descr_new(&new_feature, descr,
3181  up_to - descr, 0);
3182  if (ret > 0) {
3183  if (d->features == NULL)
3184  d->features = new_feature;
3185  else
3186  recent_feature->next = new_feature;
3187  recent_feature = new_feature;
3188  }
3189 
3190  if (only_current && !feature_is_current)
3191  continue;
3192 
3193 #ifdef Libburn_print_feature_descriptorS
3194  fprintf(stderr,
3195  "LIBBURN_EXPERIMENTAL : %s feature %4.4Xh :",
3196  (descr[2] & 1) ? "+" : "-",
3197  feature_code);
3198  if (feature_code != 0x00)
3199  for (i = 2; i < descr_len; i++)
3200  fprintf(stderr, " %2.2X", descr[i]);
3201  fprintf(stderr, "\n");
3202 #endif /* Libburn_print_feature_descriptorS */
3203 
3204  if (feature_code == 0x0) {
3205  prf_end = descr + 4 + descr[3];
3206  d->num_profiles = descr[3] / 4;
3207  if (d->num_profiles > 64)
3208  d->num_profiles = 64;
3209  if (d->num_profiles > 0)
3210  memcpy(d->all_profiles, descr + 4,
3211  d->num_profiles * 4);
3212  for (prf = descr + 4; prf + 2 < prf_end; prf += 4) {
3213 
3214 #ifdef Libburn_print_feature_descriptorS
3215  prf_number = (prf[0] << 8) | prf[1];
3216  fprintf(stderr,
3217  "LIBBURN_EXPERIMENTAL : %s profile %4.4Xh \"%s\"\n",
3218  prf[2] & 1 ? "+" : "-",
3219  prf_number,
3220  mmc_obtain_profile_name(prf_number));
3221 #endif /* Libburn_print_feature_descriptorS */
3222 
3223  }
3224 
3225  } else if (feature_code == 0x21) {
3226 
3227  d->current_has_feat21h = feature_is_current;
3228  for (i = 0; i < descr[7]; i++) {
3229  if (i == 0 || descr[8 + i] == 16)
3231  descr[8 + i];
3232 
3233 #ifdef Libburn_print_feature_descriptorS
3234  fprintf(stderr,
3235  "LIBBURN_EXPERIMENTAL : + Link Size = %d\n",
3236  descr[8 + i]);
3237 #endif /* Libburn_print_feature_descriptorS */
3238 
3239  }
3240 
3241  } else if (feature_code == 0x23) {
3242  if (feature_is_current) {
3243  d->current_feat23h_byte4 = descr[4];
3244  d->current_feat23h_byte8 = descr[8];
3245  }
3246 #ifdef Libburn_print_feature_descriptorS
3247  if (cp >= 0x41 && cp <= 0x43)
3248  fprintf(stderr,
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" : "");
3255 #endif /* Libburn_print_feature_descriptorS */
3256 
3257  } else if (feature_code == 0x2F) {
3258  if (feature_is_current)
3259  d->current_feat2fh_byte4 = descr[4];
3260 
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),
3264  !!(descr[4] & 2));
3265 #endif /* Libburn_print_feature_descriptorS */
3266 
3267  } else if (feature_code == 0x01) {
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 ||
3275  phys_if_std == 6)
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)
3280  phys_name = "USB";
3281 
3282  d->phys_if_std = phys_if_std;
3283  strcpy(d->phys_if_name, phys_name);
3284 
3285 #ifdef Libburn_print_feature_descriptorS
3286 
3287  fprintf(stderr,
3288  "LIBBURN_EXPERIMENTAL : Phys. Interface Standard %Xh \"%s\"\n",
3289  phys_if_std, phys_name);
3290 
3291  } else if (feature_code == 0x107) {
3292 
3293  fprintf(stderr, "LIBBURN_EXPERIMENTAL : CD SPEED = %d , page 2Ah = %d , SET STREAMING = %d\n",
3294  !!(descr[4] & 8), !!(descr[4] & 4),
3295  !!(descr[4] & 2));
3296 
3297 #endif /* Libburn_print_feature_descriptorS */
3298 
3299  } else if (feature_code == 0x108 || feature_code == 0x10c) {
3300  int c_limit;
3301 
3302 #ifdef Libburn_print_feature_descriptorS
3303  int i;
3304  fprintf(stderr, "LIBBURN_EXPERIMENTAL : %s = ",
3305  feature_code == 0x108 ?
3306  "Drive Serial Number" : "Drive Firmware Date");
3307 #endif /* Libburn_print_feature_descriptorS */
3308 
3309  c_limit = descr[3] - 2 * (feature_code == 0x10c);
3310  if (feature_code == 0x108) {
3311  if (d->drive_serial_number != NULL)
3314  char, c_limit + 1);
3315  memcpy(d->drive_serial_number, descr + 4,
3316  c_limit);
3317  d->drive_serial_number[c_limit] = 0;
3318  d->drive_serial_number_len = c_limit;
3319  }
3320 
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]);
3326  else
3327  fprintf(stderr, "%c", descr[4 + i]);
3328  fprintf(stderr, "\n");
3329 
3330 #endif /* Libburn_print_feature_descriptorS */
3331 
3332  }
3333  }
3334  ret = 1;
3335 ex:
3336  BURN_FREE_MEM(msg);
3337  BURN_FREE_MEM(buf);
3338  BURN_FREE_MEM(c);
3339  return ret;
3340 }
3341 
3342 
3344 {
3345  int alloc_len = 8, ret;
3346 
3347  if (d->current_profile > 0 && d->current_profile < 0xffff)
3348  return;
3349 
3350  mmc_start_if_needed(d, 1);
3351  if (mmc_function_spy(d, "mmc_get_configuration") <= 0)
3352  return;
3353 
3354  /* first command execution to learn Allocation Length */
3355  ret = mmc_get_configuration_al(d, &alloc_len);
3356 /*
3357  fprintf(stderr,"LIBBURN_DEBUG: 46h alloc_len = %d , ret = %d\n",
3358  alloc_len, ret);
3359 */
3360  if (alloc_len > 8 && ret > 0) {
3361  /* second execution with announced length */
3362  mmc_get_configuration_al(d, &alloc_len);
3363  }
3364 }
3365 
3366 
3367 /* ts A70108 */
3368 /* mmc5r03c.pdf 6.24 */
3370  int *alloc_len, int top_wanted)
3371 {
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;
3376  struct command *c = NULL;
3377  unsigned char *dpt;
3378 
3379  BURN_ALLOC_MEM(buf, struct buffer, 1);
3380  BURN_ALLOC_MEM(c, struct command, 1);
3381  if (*alloc_len < 4)
3382  {ret = 0; goto ex;}
3383 
3384  d->format_descr_type = 3;
3385  d->format_curr_max_size = 0;
3386  d->format_curr_blsas = 0;
3387  d->best_format_type = -1;
3388  d->best_format_size = 0;
3389 
3391  sizeof(MMC_READ_FORMAT_CAPACITIES));
3392  c->dxfer_len = *alloc_len;
3393  c->retry = 1;
3394  c->opcode[7]= (c->dxfer_len >> 8) & 0xff;
3395  c->opcode[8]= c->dxfer_len & 0xff;
3396  c->page = buf;
3397  c->page->sectors = 0;
3398  c->page->bytes = 0;
3399  c->dir = FROM_DRIVE;
3400 
3401  d->issue_command(d, c);
3402  if (c->error)
3403  {ret = 0; goto ex;}
3404 
3405  len = c->page->data[3];
3406  old_alloc_len = *alloc_len;
3407  *alloc_len = len + 4;
3408  if (old_alloc_len < 12)
3409  {ret = 1; goto ex;}
3410  if (len + 4 > old_alloc_len)
3411  len = old_alloc_len - 4;
3412  if (len < 8)
3413  {ret = 0; goto ex;}
3414 
3415  dpt = c->page->data + 4;
3416  /* decode 6.24.3.2 Current/Maximum Capacity Descriptor */
3417  d->format_descr_type = dpt[4] & 3;
3418  d->format_curr_max_size = (((off_t) dpt[0]) << 24)
3419  + (dpt[1] << 16) + (dpt[2] << 8) + dpt[3];
3421  d->format_curr_max_size = 0;
3422  d->format_curr_blsas = (dpt[5] << 16) + (dpt[6] << 8) + dpt[7];
3423  d->format_curr_max_size *= (off_t) 2048;
3424  if((d->current_profile == 0x12 || d->current_profile == 0x43)
3425  && d->media_capacity_remaining == 0) {
3428  d->media_lba_limit = d->format_curr_max_size / 2048;
3429  }
3430 
3431 
3432 #ifdef Libburn_dvd_ram_as_bd_rE
3433  /* <<< dummy format descriptor list as obtained from
3434  dvd+rw-mediainfo by Giulio Orsero in April 2008
3435  */
3436  d->num_format_descr = 5;
3437  d->format_descriptors[0].type = 0x00;
3438  d->format_descriptors[0].size = (off_t) 11826176 * (off_t) 2048;
3439  d->format_descriptors[0].tdp = 0x3000;
3440  d->format_descriptors[1].type = 0x30;
3441  d->format_descriptors[1].size = (off_t) 11826176 * (off_t) 2048;
3442  d->format_descriptors[1].tdp = 0x3000;
3443  d->format_descriptors[2].type = 0x30;
3444  d->format_descriptors[2].size = (off_t) 11564032 * (off_t) 2048;
3445  d->format_descriptors[2].tdp = 0x5000;
3446  d->format_descriptors[3].type = 0x30;
3447  d->format_descriptors[3].size = (off_t) 12088320 * (off_t) 2048;
3448  d->format_descriptors[3].tdp = 0x1000;
3449  d->format_descriptors[4].type = 0x31;
3450  d->format_descriptors[4].size = (off_t) 12219392 * (off_t) 2048;
3451  d->format_descriptors[4].tdp = 0x800;
3452  d->best_format_type = 0x00;
3453  d->best_format_size = (off_t) 11826176 * (off_t) 2048;
3454 
3455  /* silencing compiler warnings about unused variables */
3456  num_blocks = size = sign = i = max_score = num_descr = score = type = 0;
3457 
3458  if (d->current_profile == 0x12 || d->current_profile == 0x43)
3459  {ret = 1; goto ex;}
3460  d->num_format_descr = 0;
3461 
3462 #endif /* Libburn_dvd_ram_as_bd_rE */
3463 
3464  if (top_wanted == 0x00 || top_wanted == 0x10)
3465  sign = -1; /* the caller clearly desires full format */
3466 
3467  /* 6.24.3.3 Formattable Capacity Descriptors */
3468  num_descr = (len - 8) / 8;
3469  for (i = 0; i < num_descr; i++) {
3470  dpt = c->page->data + 12 + 8 * i;
3471  num_blocks = mmc_four_char_to_int(dpt);
3472  size = num_blocks * (off_t) 2048;
3473  type = dpt[4] >> 2;
3474 
3475  if (i < 32) {
3476  d->format_descriptors[i].type = type;
3477  d->format_descriptors[i].size = size;
3478  d->format_descriptors[i].tdp =
3479  (dpt[5] << 16) + (dpt[6] << 8) + dpt[7];
3480  d->num_format_descr = i + 1;
3481  }
3482  /* Criterion is proximity to quick intermediate state */
3483  if (type == 0x00) { /* full format (with lead out) */
3484  score = 1 * sign;
3485  } else if (type == 0x10) { /* DVD-RW full format */
3486  score = 10 * sign;
3487  } else if(type == 0x13) { /* DVD-RW quick grow last session */
3488  score = 100 * sign;
3489  } else if(type == 0x15) { /* DVD-RW Quick */
3490  score = 50 * sign;
3491  if(d->current_profile == 0x13) {
3493  size);
3494  d->media_lba_limit = num_blocks;
3495  }
3496  } else if(type == 0x26) { /* DVD+RW */
3497  score = 1 * sign;
3499  d->media_lba_limit = num_blocks;
3500  } else {
3501  continue;
3502  }
3503  if (type == top_wanted)
3504  score += 1000000000;
3505  if (score > max_score) {
3506  d->best_format_type = type;
3507  d->best_format_size = size;
3508  max_score = score;
3509  }
3510  }
3511  ret = 1;
3512 ex:
3513  BURN_FREE_MEM(buf);
3514  BURN_FREE_MEM(c);
3515  return ret;
3516 }
3517 
3518 
3519 int mmc_read_format_capacities(struct burn_drive *d, int top_wanted)
3520 {
3521  int alloc_len = 4, ret;
3522 
3523  mmc_start_if_needed(d, 1);
3524  if (mmc_function_spy(d, "mmc_read_format_capacities") <= 0)
3525  return 0;
3526 
3527  ret = mmc_read_format_capacities_al(d, &alloc_len, top_wanted);
3528 /*
3529  fprintf(stderr,"LIBBURN_DEBUG: 23h alloc_len = %d , ret = %d\n",
3530  alloc_len, ret);
3531 */
3532  if (alloc_len >= 12 && ret > 0)
3533  ret = mmc_read_format_capacities_al(d, &alloc_len, top_wanted);
3534 
3535  return ret;
3536 }
3537 
3538 
3540 {
3541  struct command *c = NULL;
3542  char *msg = NULL;
3543  int key, asc, ascq;
3544 
3545  if (mmc_function_spy(d, "mmc_sync_cache") <= 0)
3546  goto ex;
3547 
3548  BURN_ALLOC_MEM_VOID(c, struct command, 1);
3549  BURN_ALLOC_MEM_VOID(msg, char, 256);
3550 
3552  c->retry = 1;
3553  if (!d->do_no_immed)
3554  c->opcode[1] |= 2; /* ts A70918 : Immed */
3555  c->page = NULL;
3556  c->dir = NO_TRANSFER;
3557  if (d->do_no_immed)
3559  else
3561 
3562  libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
3564  "syncing cache", 0, 0);
3565  if(d->wait_for_buffer_free) {
3566  sprintf(msg,
3567  "Checked buffer %u times. Waited %u+%u times = %.3f s",
3569  d->waited_tries - d->waited_writes,
3570  ((double) d->waited_usec) / 1.0e6);
3572  0x0002013f,
3574  msg, 0,0);
3575  }
3576 
3577  d->issue_command(d, c);
3578 
3579  /* ts A70918 */
3580  if (c->error) {
3581  sprintf(msg, "Failed to synchronize drive cache");
3582  sprintf(msg + strlen(msg), ". SCSI error : ");
3583  scsi_error_msg(d, c->sense, 14, msg + strlen(msg),
3584  &key, &asc, &ascq);
3586  0x0002017f,
3588  msg, 0, 0);
3589  d->cancel = 1;
3590  goto ex;
3591  }
3592 
3593  spc_human_readable_cmd(c, msg, 160, 0);
3594  if (spc_wait_unit_attention(d, 3600, msg, 0) <= 0)
3595  d->cancel = 1;
3596  else
3597  d->needs_sync_cache = 0;
3598 ex:
3599  BURN_FREE_MEM(msg);
3600  BURN_FREE_MEM(c);
3601 }
3602 
3603 
3604 /* ts A61023 : http://libburn.pykix.org/ticket/14
3605  get size and free space of drive buffer
3606 */
3608 {
3609  struct buffer *buf = NULL;
3610  struct command *c = NULL;
3611  unsigned char *data;
3612  int alloc_len = 12, ret;
3613 
3614  BURN_ALLOC_MEM(buf, struct buffer, 1);
3615  BURN_ALLOC_MEM(c, struct command, 1);
3616  if (mmc_function_spy(d, "mmc_read_buffer_capacity") <= 0)
3617  {ret = 0; goto ex;}
3618 
3620  sizeof(MMC_READ_BUFFER_CAPACITY));
3621  c->dxfer_len = alloc_len;
3622  c->opcode[7] = (c->dxfer_len >> 8) & 0xff;
3623  c->opcode[8] = c->dxfer_len & 0xff;
3624  c->retry = 1;
3625  c->page = buf;
3626  memset(c->page->data, 0, alloc_len);
3627  c->page->bytes = 0;
3628  c->page->sectors = 0;
3629 
3630  c->dir = FROM_DRIVE;
3631  d->issue_command(d, c);
3632 
3633  /* >>> ??? error diagnostics */
3634  if (c->error)
3635  {ret = 0; goto ex;}
3636 
3637  data = c->page->data;
3638 
3640  (data[4]<<24)|(data[5]<<16)|(data[6]<<8)|data[7];
3642  (data[8]<<24)|(data[9]<<16)|(data[10]<<8)|data[11];
3644  /* Default mad buffer usage to 50 percent */
3646  }
3648  d->pbf_altered = 0;
3650  double fill;
3651 
3652  fill = d->progress.buffer_capacity
3654  if (fill < d->progress.buffer_min_fill && fill>=0)
3655  d->progress.buffer_min_fill = fill;
3656  }
3657  ret = 1;
3658 ex:;
3659  BURN_FREE_MEM(c);
3660  BURN_FREE_MEM(buf);
3661  return ret;
3662 }
3663 
3664 
3665 /* ts A61219 : learned much from dvd+rw-tools-7.0: plus_rw_format()
3666  and mmc5r03c.pdf, 6.5 FORMAT UNIT */
3667 /*
3668  @param size The size (in bytes) to be sent with the FORMAT command
3669  @param flag bit1+2: size mode
3670  0 = use parameter size as far as it makes sense
3671  1 = insist in size 0 even if there is a better default known
3672  2 = without bit7: format to maximum available size
3673  with bit7 : take size from indexed format descriptor
3674  3 = format to default size
3675  bit3= expand format up to at least size
3676  bit4= enforce re-format of (partly) formatted media
3677  bit5= try to disable eventual defect management
3678  bit6= try to avoid lengthy media certification
3679  bit7= bit8 to bit15 contain the index of the format to use
3680  bit8-bit15 = see bit7
3681  bit16= enable POW on blank BD-R
3682 */
3683 int mmc_format_unit(struct burn_drive *d, off_t size, int flag)
3684 {
3685  struct buffer *buf = NULL;
3686  struct command *c = 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]; /* profile+filltext+index */
3693  int key, asc, ascq;
3694  int full_format_type = 0x00; /* Full Format (or 0x10 for DVD-RW ?) */
3695 
3696  BURN_ALLOC_MEM(buf, struct buffer, 1);
3697  BURN_ALLOC_MEM(c, struct command, 1);
3698  BURN_ALLOC_MEM(msg, char, 256);
3699  mmc_start_if_needed(d, 0);
3700  if (mmc_function_spy(d, "mmc_format_unit") <= 0)
3701  {ret = 0; goto ex;}
3702  size_mode = (flag >> 1) & 3;
3703 
3705  c->retry = 1;
3706  c->page = buf;
3707  c->page->bytes = 12;
3708  c->page->sectors = 0;
3709  c->dir = TO_DRIVE;
3710  if (d->do_no_immed)
3712  else
3714  memset(c->page->data, 0, c->page->bytes);
3715 
3716  descr[0] = 0;
3717  if (!d->do_no_immed)
3718  c->page->data[1] = 0x02; /* Immed */
3719  c->page->data[3] = 8; /* Format descriptor length */
3720  num_of_blocks = size / 2048;
3721  mmc_int_to_four_char(c->page->data + 4, num_of_blocks);
3722 
3723  if (flag & 128) { /* explicitly chosen format descriptor */
3724  /* use case: the app knows what to do */
3725 
3726  ret = mmc_read_format_capacities(d, -1);
3727  if (ret <= 0)
3728  goto selected_not_suitable;
3729  index = (flag >> 8) & 0xff;
3730  if(index < 0 || index >= d->num_format_descr) {
3731 selected_not_suitable:;
3733  0x00020132,
3735  "Selected format is not suitable for libburn",
3736  0, 0);
3737  {ret = 0; goto ex;}
3738  }
3739  if (!(d->current_profile == 0x13 ||
3740  d->current_profile == 0x14 ||
3741  d->current_profile == 0x1a ||
3742  d->current_profile == 0x12 ||
3743  d->current_profile == 0x41 ||
3744  d->current_profile == 0x43))
3745  goto unsuitable_media;
3746 
3747  format_type = d->format_descriptors[index].type;
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;
3755  if (flag & 4) {
3756  num_of_blocks =
3757  d->format_descriptors[index].size / 2048;
3758  mmc_int_to_four_char(c->page->data + 4, num_of_blocks);
3759  }
3760  if (format_type != 0x26)
3761  for (i = 0; i < 3; i++)
3762  c->page->data[9 + i] =
3763  ( d->format_descriptors[index].tdp >>
3764  (16 - 8 * i)) & 0xff;
3765  if (format_type == 0x30 || format_type == 0x31) {
3766  format_sub_type = 0;
3767  if (flag & 64) {
3768  if (d->current_feat23h_byte4 & 2)
3769  /* Quick certification */
3770  format_sub_type = 3;
3771  } else {
3772  if (d->current_feat23h_byte4 & 1)
3773  /* Full certification */
3774  format_sub_type = 2;
3775  }
3776  } else if (format_type == 0x32 ||
3777  (format_type == 0x00 && d->current_profile == 0x41)) {
3778  if (flag & (1 << 16))
3779  format_sub_type = 0; /* SRM + POW */
3780  else
3781  format_sub_type = 1; /* SRM (- POW) */
3782  }
3783  if (d->current_profile == 0x12 && format_type !=0x01 &&
3784  (flag & 64)) {
3785  /* DCRT and CmpList, see below */
3786  c->page->data[1] |= 0x20;
3787  c->opcode[1] |= 0x08;
3788  }
3789  c->page->data[1] |= 0x80; /* FOV = this flag vector is valid */
3790  sprintf(descr, "%s (descr %d)", d->current_profile_text,index);
3791  return_immediately = 1; /* caller must do the waiting */
3792 
3793  } else if (d->current_profile == 0x1a) { /* DVD+RW */
3794  /* use case: background formatting during write !(flag&4)
3795  de-icing as explicit formatting action (flag&4)
3796  */
3797 
3798  /* mmc5r03c.pdf , 6.5.4.2.14, DVD+RW Basic Format */
3799  format_type = 0x26;
3800 
3801  /* >>> ??? is this "| 8" a bug ? */
3802 
3803  if ((size <= 0 && !(flag & 2)) || (flag & (4 | 8))) {
3804  /* maximum capacity */
3805  memset(c->page->data + 4, 0xff, 4);
3806  num_of_blocks = 0xffffffff;
3807  }
3808 
3809  if(d->bg_format_status == 2 ||
3810  (d->bg_format_status == 3 && !(flag & 16))) {
3811  sprintf(msg,"FORMAT UNIT ignored. Already %s.",
3812  (d->bg_format_status == 2 ? "in progress" :
3813  "completed"));
3815  0x00020120,
3817  msg, 0,0);
3818  {ret = 2; goto ex;}
3819  }
3820  if (!(flag & 16)) /* if not re-format is desired */
3821  if (d->bg_format_status == 1) /* is partly formatted */
3822  c->page->data[11] = 1; /* Restart bit */
3823  sprintf(descr, "DVD+RW (fs=%d,rs=%d)",
3824  d->bg_format_status, (c->page->data[11] == 1));
3825  if (flag & 4)
3826  return_immediately = 1;/* caller must do the waiting */
3827 
3828  } else if (d->current_profile == 0x13 && !(flag & 16)) {
3829  /*DVD-RW restricted overwrite*/
3830  /* use case: quick grow formatting during write */
3831 
3832  ret = mmc_read_format_capacities(d, 0x13);
3833  if (ret > 0) {
3834  if (d->best_format_type == 0x13) {
3835  if (d->best_format_size <= 0)
3836  {ret = 1; goto ex;}
3837  } else {
3838  if (d->format_descr_type == 2) /* formatted */
3839  {ret = 1; goto ex;}
3840  if (d->format_descr_type == 3){/*intermediate*/
3841  d->needs_close_session = 1;
3842  {ret = 1; goto ex;}
3843  }
3844  /* does trying make sense at all ? */
3845  tolerate_failure = 1;
3846  }
3847  }
3848  if (d->best_format_type == 0x13 && (flag & (4 | 8))) {
3849  num_of_blocks = d->best_format_size / 2048;
3850  if (flag & 8) {
3851  /* num_of_blocks needed to reach size */
3852  diff = (size - d->format_curr_max_size) /32768;
3853  if ((size - d->format_curr_max_size) % 32768)
3854  diff++;
3855  diff *= 16;
3856  if (diff < num_of_blocks)
3857  num_of_blocks = diff;
3858  }
3859  if (num_of_blocks > 0)
3860  mmc_int_to_four_char(c->page->data + 4,
3861  num_of_blocks);
3862  }
3863  /* 6.5.4.2.8 , DVD-RW Quick Grow Last Border */
3864  format_type = 0x13;
3865  c->page->data[11] = 16; /* block size * 2k */
3866  sprintf(descr, "DVD-RW quick grow");
3867 
3868  } else if (d->current_profile == 0x14 ||
3869  (d->current_profile == 0x13 && (flag & 16))) {
3870  /* DVD-RW sequential recording (or Overwrite for re-format) */
3871  /* use case : transition from Sequential to Overwrite
3872  re-formatting of Overwrite media */
3873 
3874  /* To Restricted Overwrite */
3875  /* 6.5.4.2.10 Format Type = 15h (DVD-RW Quick) */
3876  /* or 6.5.4.2.1 Format Type = 00h (Full Format) */
3877  /* or 6.5.4.2.5 Format Type = 10h (DVD-RW Full Format) */
3879  (flag & 4) ? full_format_type : 0x15);
3880  if (d->best_format_type == 0x15 ||
3881  d->best_format_type == full_format_type) {
3882  if ((flag & 4)
3883  || d->best_format_type == full_format_type) {
3884  num_of_blocks = d->best_format_size / 2048;
3885  mmc_int_to_four_char(c->page->data + 4,
3886  num_of_blocks);
3887  }
3888 
3889  } else {
3890 no_suitable_formatting_type:;
3892  0x00020131,
3894  "No suitable formatting type offered by drive",
3895  0, 0);
3896  {ret = 0; goto ex;}
3897  }
3898  format_type = d->best_format_type;
3899  sprintf(descr, "DVD-RW %s",
3900  format_type == 0x15 ? "quick" : "full");
3901  return_immediately = 1; /* caller must do the waiting */
3902 
3903  } else if (d->current_profile == 0x12) {
3904  /* ts A80417 : DVD-RAM */
3905  /* 6.5.4.2.1 Format Type = 00h (Full Format)
3906  6.5.4.2.2 Format Type = 01h (Spare Area Expansion)
3907  */
3908  index = format_00_index = -1;
3909  format_size = format_00_max_size = -1;
3910  for (i = 0; i < d->num_format_descr; i++) {
3911  format_type = d->format_descriptors[i].type;
3912  i_size = d->format_descriptors[i].size;
3913  if (format_type != 0x00 && format_type != 0x01)
3914  continue;
3915  if (flag & 32) { /* No defect mgt */
3916  /* Search for largest 0x00 format descriptor */
3917  if (format_type != 0x00)
3918  continue;
3919  if (i_size < format_size)
3920  continue;
3921  format_size = i_size;
3922  index = i;
3923  continue;
3924  } else if (flag & 4) { /*Max or default size with mgt*/
3925  /* Search for second largest 0x00
3926  format descriptor. For max size allow
3927  format type 0x01.
3928  */
3929  if (format_type == 0x00) {
3930  if (i_size < format_size)
3931  continue;
3932  if (i_size < format_00_max_size) {
3933  format_size = i_size;
3934  index = i;
3935  continue;
3936  }
3937  format_size = format_00_max_size;
3938  index = format_00_index;
3939  format_00_max_size = i_size;
3940  format_00_index = i;
3941  continue;
3942  }
3943  if (size_mode==3)
3944  continue;
3945  if (i_size > format_size) {
3946  format_size = i_size;
3947  index = i;
3948  }
3949  continue;
3950  }
3951  /* Search for smallest 0x0 or 0x01
3952  descriptor >= size */;
3953  if (d->format_descriptors[i].size >= size &&
3954  (format_size < 0 || i_size < format_size)
3955  ) {
3956  format_size = i_size;
3957  index = i;
3958  }
3959  }
3960  if(index < 0 && (flag & 4) && !(flag & 32)) {
3961  format_size = format_00_max_size;
3962  index = format_00_index;
3963  }
3964  if(index < 0)
3965  goto no_suitable_formatting_type;
3966  format_type = d->format_descriptors[index].type;
3967  num_of_blocks = d->format_descriptors[index].size / 2048;
3968  mmc_int_to_four_char(c->page->data + 4, num_of_blocks);
3969  for (i = 0; i < 3; i++)
3970  c->page->data[9 + i] =
3971  ( d->format_descriptors[index].tdp >>
3972  (16 - 8 * i)) & 0xff;
3973  sprintf(descr, "%s", d->current_profile_text);
3974  return_immediately = 1; /* caller must do the waiting */
3975  c->page->data[1] |= 0x80; /* FOV = this flag vector is valid */
3976 
3977  if ((flag & 64) && format_type != 0x01) {
3978  /* MMC-5 6.5.3.2 , 6.5.4.2.1.2
3979  DCRT: Disable Certification and maintain number
3980  of blocks
3981  CmpList: Override maintaining of number of blocks
3982  with DCRT
3983  */
3984  /* ts A80426 : prevents change of formatted size
3985  with PHILIPS SPD3300L and Verbatim 3x DVD-RAM
3986  and format_type 0x00. Works on TSSTcorp SH-S203B
3987  */
3988  c->page->data[1] |= 0x20;
3989  c->opcode[1] |= 0x08;
3990  }
3991 
3992  } else if (d->current_profile == 0x41) {
3993  /* BD-R SRM */
3994 
3995  index = -1;
3996  format_size = -1;
3997  if (d->num_format_descr <= 0)
3998  goto no_suitable_formatting_type;
3999  if (d->format_descriptors[0].type != 0)
4000  goto no_suitable_formatting_type;
4001  for (i = 0; i < d->num_format_descr; i++) {
4002  format_type = d->format_descriptors[i].type;
4003  i_size = d->format_descriptors[i].size;
4004  if (format_type != 0x00 && format_type != 0x32)
4005  continue;
4006  if (flag & 32) { /* No defect mgt */
4007  /* ts A81211 : MMC-5 6.5.4.2.17.1
4008  When formatted with Format Type 32h,
4009  the BD-R disc is required to allocate
4010  a non-zero number of spares.
4011  */
4012  goto no_suitable_formatting_type;
4013 
4014  } else if(size_mode == 2) { /* max payload size */
4015  /* search largest 0x32 format descriptor */
4016  if(format_type != 0x32)
4017  continue;
4018  } else if(size_mode == 3) { /* default payload size */
4019  if (format_type == 0x00) {
4020  index = i;
4021  break;
4022  }
4023  continue;
4024  } else { /* defect managed format with size wish */
4025 
4026 #ifdef Libburn_bd_r_format_olD
4027 
4028  /* search for smallest 0x32 >= size */
4029  if(format_type != 0x32)
4030  continue;
4031  if (i_size < size)
4032  continue;
4033  if (format_size >= 0 && i_size >= format_size)
4034  continue;
4035  index = i;
4036  format_size = i_size;
4037  continue;
4038 
4039 #else /* Libburn_bd_r_format_olD */
4040 
4041  /* search largest and smallest 0x32 */
4042  if(format_type != 0x32)
4043  continue;
4044  if (i_size < min_size || min_size < 0)
4045  min_size = i_size;
4046  if (i_size > max_size)
4047  max_size = i_size;
4048 
4049 #endif /* ! Libburn_bd_r_format_olD */
4050 
4051  }
4052  /* common for all cases which search largest
4053  descriptors */
4054  if (i_size > format_size) {
4055  format_size = i_size;
4056  index = i;
4057  }
4058  }
4059  if (size_mode == 2 && index < 0 && !(flag & 32))
4060  index = 0;
4061  if (index < 0)
4062  goto no_suitable_formatting_type;
4063  format_type = d->format_descriptors[index].type;
4064  if (flag & (1 << 16))
4065  format_sub_type = 0; /* SRM + POW */
4066  else
4067  format_sub_type = 1; /* SRM (- POW) */
4068 
4069 #ifdef Libburn_bd_r_format_olD
4070  if (0) {
4071 #else
4072  if (size_mode == 0 || size_mode == 1) {
4073 #endif /* ! Libburn_bd_r_format_olD */
4074 
4075  if (min_size < 0 || max_size < 0)
4076  goto no_suitable_formatting_type;
4077  if (size <= 0)
4078  size = min_size;
4079  if (size % 0x10000)
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;
4086  mmc_int_to_four_char(c->page->data + 4, num_of_blocks);
4087  for (i = 0; i < 3; i++)
4088  c->page->data[9 + i] = 0;
4089  } else {
4090  num_of_blocks =
4091  d->format_descriptors[index].size / 2048;
4092  mmc_int_to_four_char(c->page->data + 4, num_of_blocks);
4093  for (i = 0; i < 3; i++)
4094  c->page->data[9 + i] =
4095  ( d->format_descriptors[index].tdp >>
4096  (16 - 8 * i)) & 0xff;
4097  }
4098  sprintf(descr, "%s", d->current_profile_text);
4099  return_immediately = 1; /* caller must do the waiting */
4100  c->page->data[1] |= 0x80; /* FOV = this flag vector is valid */
4101 
4102  } else if (d->current_profile == 0x43) {
4103  /* BD-RE */
4104  index = -1;
4105  format_size = -1;
4106  if (d->num_format_descr <= 0)
4107  goto no_suitable_formatting_type;
4108  if (d->format_descriptors[0].type != 0)
4109  goto no_suitable_formatting_type;
4110  for (i = 0; i < d->num_format_descr; i++) {
4111  format_type = d->format_descriptors[i].type;
4112  i_size = d->format_descriptors[i].size;
4113  if (format_type != 0x00 && format_type != 0x30 &&
4114  format_type != 0x31)
4115  continue;
4116  if (flag & 32) { /* No defect mgt */
4117  /* search largest format 0x31 */
4118  if(format_type != 0x31)
4119  continue;
4120  } else if(size_mode == 2) { /* max payload size */
4121  /* search largest 0x30 format descriptor */
4122  if(format_type != 0x30)
4123  continue;
4124  } else if(size_mode == 3) { /* default payload size */
4125  if (accept_count < 1)
4126  index = 0; /* this cannot certify */
4127 
4128  /* ts A81129
4129  LG GGW-H20L YL03 refuses on 0x30 with
4130  "Quick certification". dvd+rw-format
4131  does 0x00 by default and succeeds quickly.
4132  */
4133  if ((flag & 64) && format_type == 0x00) {
4134  index = i;
4135  break;
4136  }
4137 
4138  if(format_type != 0x30)
4139  continue;
4140  accept_count++;
4141  if (accept_count == 1)
4142  index = i;
4143  continue;
4144  } else { /* defect managed format with size wish */
4145 
4146 #ifdef Libburn_bd_re_format_olD
4147 
4148  /* search for smallest 0x30 >= size */
4149  if(format_type != 0x30)
4150  continue;
4151  if (i_size < size)
4152  continue;
4153  if (format_size >= 0 && i_size >= format_size)
4154  continue;
4155  index = i;
4156  format_size = i_size;
4157  continue;
4158 
4159 #else /* Libburn_bd_re_format_olD */
4160 
4161  /* search largest and smallest 0x30 */
4162  if(format_type != 0x30)
4163  continue;
4164  if (i_size < min_size || min_size < 0)
4165  min_size = i_size;
4166  if (i_size > max_size)
4167  max_size = i_size;
4168 
4169 #endif /* ! Libburn_bd_re_format_olD */
4170 
4171  }
4172  /* common for all cases which search largest
4173  descriptors */
4174  if (i_size > format_size) {
4175  format_size = i_size;
4176  index = i;
4177  }
4178  }
4179 
4180  if (size_mode == 2 && index < 0 && !(flag & 32))
4181  index = 0;
4182  if (index < 0)
4183  goto no_suitable_formatting_type;
4184  format_type = d->format_descriptors[index].type;
4185  if (format_type == 0x30 || format_type == 0x31) {
4186  if ((flag & 64) || !(d->current_feat23h_byte4 & 3)) {
4187  format_sub_type = 0;
4188  if (!(flag & 64))
4190  d->global_index, 0x0002019e,
4193  "Drive does not support media certification",
4194  0, 0);
4195  } else {
4196  /* With Certification */
4197  if (d->current_feat23h_byte4 & 1)
4198  format_sub_type = 2; /* Full */
4199  else
4200  format_sub_type = 3; /* Quick */
4201  }
4202  }
4203 
4204 #ifdef Libburn_bd_re_format_olD
4205  if (0) {
4206 #else
4207  if (size_mode == 0 || size_mode == 1) {
4208 #endif /* ! Libburn_bd_re_format_olD */
4209 
4210  if (min_size < 0 || max_size < 0)
4211  goto no_suitable_formatting_type;
4212  if (size <= 0)
4213  size = min_size;
4214  if (size % 0x10000)
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;
4221  mmc_int_to_four_char(c->page->data + 4, num_of_blocks);
4222  for (i = 0; i < 3; i++)
4223  c->page->data[9 + i] = 0;
4224  } else {
4225  num_of_blocks =
4226  d->format_descriptors[index].size / 2048;
4227  mmc_int_to_four_char(c->page->data + 4, num_of_blocks);
4228  for (i = 0; i < 3; i++)
4229  c->page->data[9 + i] =
4230  ( d->format_descriptors[index].tdp >>
4231  (16 - 8 * i)) & 0xff;
4232  }
4233  sprintf(descr, "%s", d->current_profile_text);
4234  return_immediately = 1; /* caller must do the waiting */
4235  c->page->data[1] |= 0x80; /* FOV = this flag vector is valid */
4236 
4237  } else {
4238 
4239  /* >>> other formattable types to come */
4240 
4241 unsuitable_media:;
4242  sprintf(msg, "Unsuitable media detected. Profile %4.4Xh %s",
4245  0x0002011e,
4247  msg, 0, 0);
4248  {ret = 0; goto ex;}
4249  }
4250  c->page->data[8] = (format_type << 2) | (format_sub_type & 3);
4251 
4252  /* MMC-5 Table 253 , column Type Dependent Parameter */
4253  if (format_type == 0x00 || format_type == 0x01 ||
4254  format_type == 0x31) {
4255  /* Block Length 0x0800 = 2k */
4256  c->page->data[ 9] = 0x00;
4257  c->page->data[10] = 0x08;
4258  c->page->data[11] = 0x00;
4259  } else if (format_type >= 0x10 && format_type <= 0x15) {
4260  /* ECC block size = 16 * 2k */
4261  c->page->data[ 9] = 0;
4262  c->page->data[10] = 0;
4263  c->page->data[11] = 16;
4264  }
4265 
4266  sprintf(msg, "Format type %2.2Xh \"%s\", blocks = %.f",
4267  format_type, descr, (double) num_of_blocks);
4270  msg, 0, 0);
4271  sprintf(msg, "CDB: ");
4272  for (i = 0; i < 6; i++)
4273  sprintf(msg + strlen(msg), "%2.2X ", c->opcode[i]);
4276  msg, 0, 0);
4277  sprintf(msg, "Format list: ");
4278  for (i = 0; i < 12; i++)
4279  sprintf(msg + strlen(msg), "%2.2X ", c->page->data[i]);
4280  strcat(msg, "\n");
4283  msg, 0, 0);
4284 
4285 #ifdef Libburn_do_not_format_dvd_ram_or_bd_rE
4286  if(d->current_profile == 0x43 || d->current_profile == 0x12) {
4287  sprintf(msg,
4288  "Formatting of %s not implemented yet - This is a dummy",
4291  0x00000002,
4293  msg, 0, 0);
4294  {ret = 1; goto ex;}
4295  }
4296 #endif /* Libburn_do_not_format_dvd_ram_or_bd_rE */
4297 
4298 /* <<<
4299 fprintf(stderr, "\nlibburn_DEBUG: FORMAT UNIT temporarily disabled.\n");
4300 ret = 1; goto ex;
4301  */
4302 
4303  d->issue_command(d, c);
4304  if (c->error && !tolerate_failure) {
4305  spc_decode_sense(c->sense, 0, &key, &asc, &ascq);
4306  if (key != 0) {
4307  sprintf(msg, "SCSI error on format_unit(%s): ", descr);
4308  scsi_error_msg(d, c->sense, 14, msg + strlen(msg),
4309  &key, &asc, &ascq);
4311  0x00020122,
4313  msg, 0, 0);
4314 
4315  }
4316  {ret = 0; goto ex;}
4317  } else if ((!c->error) && (format_type == 0x13 || format_type == 0x15))
4318  d->needs_close_session = 1;
4319  if (return_immediately)
4320  {ret = 1; goto ex;}
4321  usleep(1000000); /* there seems to be a little race condition */
4322  for (ret = 0; ret <= 0 ;) {
4323  usleep(50000);
4324  ret = spc_test_unit_ready(d);
4325  }
4326  mmc_sync_cache(d);
4327  ret = 1;
4328 ex:;
4329  BURN_FREE_MEM(msg);
4330  BURN_FREE_MEM(c);
4331  BURN_FREE_MEM(buf);
4332  return ret;
4333 }
4334 
4335 
4336 /* ts B40107 : Outsourced from mmc_get_performance_al()
4337 */
4338 static int new_burn_speed_descr(struct burn_drive *d, int sd_source,
4339  struct burn_speed_descriptor **sd, int flag)
4340 {
4341  int ret;
4342 
4344  NULL, d->mdata->speed_descriptors, 0);
4345  if (ret <= 0)
4346  return ret;
4347 
4348  *sd = d->mdata->speed_descriptors;
4349  (*sd)->source = sd_source;
4350  if (d->current_profile > 0) {
4351  (*sd)->profile_loaded = d->current_profile;
4352  strcpy((*sd)->profile_name, d->current_profile_text);
4353  }
4354  return 1;
4355 }
4356 
4357 
4358 /* ts B40107 : Outsourced from mmc_get_performance_al()
4359  and extended for descr_type 0x00
4360  @param flag bit0= register speed descriptors
4361 */
4362 static int interpret_performance(struct burn_drive *d, struct command *c,
4363  int descr_type, int *alloc_len, int *max_descr,
4364  int *num_descr, int flag)
4365 {
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;
4371  unsigned char *pd;
4372  struct burn_speed_descriptor *sd;
4373 
4374  /* ts A61225 : 1 = report about speed descriptors */
4375  static int speed_debug = 0;
4376 
4377  len = mmc_four_char_to_int(c->page->data);
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;
4385  {ret = 1; goto ex;}
4386  }
4387  if (old_alloc_len < 16)
4388  {ret = 1; goto ex;}
4389  if (len < 12)
4390  {ret = 0; goto ex;}
4391 
4392  min_write_speed = d->mdata->min_write_speed;
4393  max_write_speed = d->mdata->max_write_speed;
4394  pd = c->page->data;
4395  if (*num_descr > *max_descr)
4396  *num_descr = *max_descr;
4397  for (i = 0; i < *num_descr && (flag & 1); i++) {
4398  end_lba = read_speed = write_speed = start_speed = 0;
4399 
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])
4405  << (24 - 8 * b);
4406  read_speed += pd[8 + i*16 + 8 + b]
4407  << (24 - 8 * b);
4408  write_speed += pd[8 + i*16 + 12 + b]
4409  << (24 - 8 * b);
4410  }
4411  if (end_lba > 0x7ffffffe)
4412  end_lba = 0x7ffffffe;
4413 
4414  if (speed_debug)
4415  fprintf(stderr,
4416  "LIBBURN_DEBUG: kB/s: write=%d read=%d end=%lu exact=%d\n",
4418  end_lba, exact_bit);
4419 
4420  ret = new_burn_speed_descr(d, 2, &sd, 0);
4421  if (ret > 0) {
4422  sd->wrc = (pd[8 + i*16] >> 3 ) & 3;
4423  sd->exact = exact_bit;
4424  sd->mrw = pd[8 + i*16] & 1;
4425  sd->end_lba = end_lba;
4426  sd->write_speed = write_speed;
4427  sd->read_speed = read_speed;
4428  }
4429 
4430  } else { /* descr_type == 0 */
4431  for (b = 0; b < 4 ; b++) {
4432  start_speed += pd[8 + i*16 + 4 + b]
4433  << (24 - 8 * b);
4434  end_lba += ((unsigned long int)
4435  pd[8 + i*16 + 8 + b])
4436  << (24 - 8 * b);
4437  read_speed += pd[8 + i*16 + 12 + b]
4438  << (24 - 8 * b);
4439  }
4440 
4441  if (speed_debug)
4442  fprintf(stderr,
4443  "LIBBURN_DEBUG: start=%d end=%d lba=%lu\n",
4444  start_speed, read_speed, end_lba);
4445 
4446  if (end_lba > 0x7ffffffe)
4447  end_lba = 0x7ffffffe;
4448  ret = new_burn_speed_descr(d, 3, &sd, 0);
4449  if (ret > 0) {
4450  sd->end_lba = end_lba;
4451  sd->read_speed = start_speed;
4452  }
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;
4457  ret = new_burn_speed_descr(d, 3, &sd, 0);
4458  if (ret > 0) {
4459  sd->end_lba = end_lba;
4460  sd->read_speed = read_speed;
4461  }
4462  }
4463 
4464  if ((int) end_lba > d->mdata->max_end_lba)
4465  d->mdata->max_end_lba = end_lba;
4466  if ((int) end_lba < d->mdata->min_end_lba)
4467  d->mdata->min_end_lba = end_lba;
4468  if (write_speed > 0 && write_speed < min_write_speed)
4469  min_write_speed = write_speed;
4470  if (write_speed > max_write_speed)
4471  max_write_speed = write_speed;
4472  if (read_speed > 0 && read_speed < min_read_speed)
4473  min_read_speed = read_speed;
4474  if (read_speed > max_read_speed)
4475  max_read_speed = read_speed;
4476  }
4477  if (min_write_speed < 0x7fffffff)
4478  d->mdata->min_write_speed = min_write_speed;
4479  if (max_write_speed > 0)
4480  d->mdata->max_write_speed = max_write_speed;
4481  /* there is no mdata->min_read_speed yet
4482  if (min_read_speed < 0x7fffffff)
4483  d->mdata->min_read_speed = min_read_speed;
4484  */
4485  if (max_read_speed > 0)
4486  d->mdata->max_read_speed = max_read_speed;
4487 
4488  ret = 1;
4489 ex:;
4490  return ret;
4491 }
4492 
4493 
4494 /* ts A61225 */
4495 /* @param flag bit0= register speed descriptors
4496 */
4497 static int mmc_get_performance_al(struct burn_drive *d, int descr_type,
4498  int *alloc_len, int *max_descr, int flag)
4499 {
4500  int num_descr, ret;
4501  struct buffer *buf = NULL;
4502  struct command *c = NULL;
4503 
4504  BURN_ALLOC_MEM(buf, struct buffer, 1);
4505  BURN_ALLOC_MEM(c, struct command, 1);
4506 
4507  if (d->current_profile < 0)
4509 
4510  if (*alloc_len < 8)
4511  {ret = 0; goto ex;}
4512  if (descr_type != 0x00 && descr_type != 0x03)
4513  {ret = 0; goto ex;}
4514 
4516  sizeof(MMC_GET_PERFORMANCE));
4517 
4518  /* >>> future: maintain a list of write descriptors
4519  if (max_descr > d->max_write_descr - d->num_write_descr)
4520  max_descr = d->max_write_descr;
4521  */
4522  c->dxfer_len = *alloc_len;
4523 
4524  if (descr_type == 0x00)
4525  c->opcode[1] = 0x10; /* Data Type: nominal read performance */
4526  c->opcode[8] = ( *max_descr >> 8 ) & 0xff;
4527  c->opcode[9] = ( *max_descr >> 0 ) & 0xff;
4528  c->opcode[10] = descr_type;
4529  c->retry = 1;
4530  c->page = buf;
4531  c->page->sectors = 0;
4532  c->page->bytes = 0;
4533  c->dir = FROM_DRIVE;
4534  d->issue_command(d, c);
4535 
4536 #ifdef Libisofs_simulate_old_mmc1_drivE
4537  c->error = 1;
4538  c->sense[0] = 0x70; /* Fixed format sense data */
4539  c->sense[2] = 0x5;
4540  c->sense[12] = 0x20;
4541  c->sense[13] = 0x0;
4542 #endif /* Libisofs_simulate_old_mmc1_drivE */
4543 
4544  if (c->error)
4545  {ret = 0; goto ex;}
4546 
4547  ret = interpret_performance(d, c, descr_type, alloc_len, max_descr,
4548  &num_descr, flag);
4549  if (ret <= 0)
4550  goto ex;
4551 
4552  ret = num_descr;
4553 ex:;
4554  BURN_FREE_MEM(buf);
4555  BURN_FREE_MEM(c);
4556  return ret;
4557 }
4558 
4559 
4560 int mmc_get_performance(struct burn_drive *d, int descr_type, int flag)
4561 {
4562  int alloc_len = 8, max_descr = 0, ret;
4563 
4564  mmc_start_if_needed(d, 1);
4565  if (mmc_function_spy(d, "mmc_get_write_performance") <= 0)
4566  return 0;
4567 
4568  /* first command execution to learn number of descriptors and
4569  dxfer_len
4570  */
4571  ret = mmc_get_performance_al(d, descr_type, &alloc_len, &max_descr, 0);
4572  if (max_descr > 0 && ret > 0) {
4573  /* Some drives announce only 1 descriptor if asked for 0.
4574  So ask twice for non-0 descriptors.
4575  */
4576  ret = mmc_get_performance_al(d, descr_type,
4577  &alloc_len, &max_descr, 0);
4578  }
4579 /*
4580  fprintf(stderr,"LIBBURN_DEBUG: ACh alloc_len = %d , ret = %d\n",
4581  alloc_len, ret);
4582 */
4583  if (max_descr > 0 && ret > 0) {
4584  /* final execution with announced length */
4585  max_descr = (alloc_len - 8) / 16;
4586  ret = mmc_get_performance_al(d, descr_type,
4587  &alloc_len, &max_descr, 1);
4588  }
4589  return ret;
4590 }
4591 
4592 
4594 {
4595  int ret;
4596 
4597  ret = mmc_get_performance(d, 0x03, 0);
4598  return ret;
4599 }
4600 
4601 
4602 /* ts A61229 : outsourced from spc_select_write_params() */
4603 /* Note: Page data is not zeroed here in order not to overwrite preset
4604  defaults. Thus
4605  memset(pd, 0, 2 + d->mdata->write_page_length);
4606  is the eventual duty of the caller.
4607 */
4609  int tnum, const struct burn_write_opts *o,
4610  unsigned char *pd)
4611 {
4612  unsigned char *catalog = NULL;
4613  char isrc_text[13 + 21]; /* should suffice for 64 bit oversize */
4614  struct isrc *isrc;
4615 
4616  pd[0] = 5;
4617  pd[1] = d->mdata->write_page_length;
4618 
4619  if (d->current_profile == 0x13) {
4620  /* A61229 : DVD-RW restricted overwrite */
4621  /* learned from transport.hxx : page05_setup()
4622  and mmc3r10g.pdf table 347 */
4623  /* BUFE (burnproof), no LS_V (i.e. default Link Size, i hope),
4624  no simulate, write type 0 = packet */
4625  pd[2] = (1 << 6);
4626  /* no multi, fixed packet, track mode 5 */
4627  pd[3] = (1 << 5) | 5;
4628  /* Data Block Type */
4629  pd[4] = 8;
4630  /* Link size dummy */
4631  pd[5] = 0;
4632  } else if ((d->current_profile == 0x14 || d->current_profile == 0x11 ||
4633  d->current_profile == 0x15)
4634  && o->write_type == BURN_WRITE_SAO) {
4635  /* ts A70205 : DVD-R[W][/DL] : Disc-at-once, DAO */
4636  /* Learned from dvd+rw-tools and mmc5r03c.pdf .
4637  See doc/cookbook.txt for more detailed references. */
4638 
4639  /* BUFE , LS_V = 0, Test Write, Write Type = 2 SAO (DAO) */
4640  pd[2] = ((!!o->underrun_proof) << 6)
4641  | ((!!o->simulate) << 4)
4642  | 2;
4643 
4644  /* No multi-session , FP = 0 , Copy = 0, Track Mode = 5 */
4645  pd[3] = 5;
4646 
4647 #ifdef Libburn_pioneer_dvr_216d_load_mode5
4648 
4649  /* >>> use track mode from mmc_get_nwa() */
4650  /* >>> pd[3] = (pd[3] & ~0xf) | (d->track_inf[5] & 0xf); */
4651 
4652 #endif
4653 
4654  /* Data Block Type = 8 */
4655  pd[4] = 8;
4656 
4657  } else if (d->current_profile == 0x14 || d->current_profile == 0x11 ||
4658  d->current_profile == 0x15) {
4659  /* ts A70128 : DVD-R[W][/DL] Incremental Streaming */
4660  /* Learned from transport.hxx : page05_setup()
4661  and mmc5r03c.pdf 7.5, 4.2.3.4 Table 17
4662  and spc3r23.pdf 6.8, 7.4.3 */
4663 
4664  /* BUFE , LS_V = 1, Test Write,
4665  Write Type = 0 Packet/Incremental */
4666  pd[2] = ((!!o->underrun_proof) << 6)
4667  | (1 << 5)
4668  | ((!!o->simulate) << 4);
4669  /* Multi-session , FP = 1 , Track Mode = 5 */
4670  pd[3] = ((3 * !!o->multi) << 6) | (1 << 5) | 5;
4671  /* Data Block Type = 8 */
4672  pd[4] = 8;
4673  /* Link Size */
4674  if (d->current_feat21h_link_size >= 0)
4675  pd[5] = d->current_feat21h_link_size;
4676  else
4677  pd[5] = 16;
4678  if (d->current_feat21h_link_size != 16) {
4679  char msg[80];
4680 
4681  sprintf(msg,
4682  "Feature 21h Link Size = %d (expected 16)\n",
4684  libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
4686  msg, 0, 0);
4687  }
4688  /* Packet Size */
4689  pd[13] = 16;
4690 
4691  } else if (d->current_profile == 0x1a || d->current_profile == 0x1b ||
4692  d->current_profile == 0x2b || d->current_profile == 0x12 ||
4693  d->current_profile == 0x41 || d->current_profile == 0x42 ||
4694  d->current_profile == 0x43) {
4695  /* not with DVD+R[W][/DL] or DVD-RAM or BD-R[E] */;
4696  return 0;
4697  } else {
4698  /* Traditional setup for CD */
4699 
4700  pd[2] = ((!!o->underrun_proof) << 6)
4701  | ((!!o->simulate) << 4)
4702  | (o->write_type & 0x0f);
4703 
4704  /* ts A61106 : MMC-1 table 110 : multi==0 or multi==3 */
4705  pd[3] = ((3 * !!o->multi) << 6) | (o->control & 0x0f);
4706 
4707  pd[4] = spc_block_type(o->block_type);
4708 
4709 /*
4710 fprintf(stderr, "libburn_EXPERIMENTAL: block_type = %d, pd[4]= %u\n",
4711  o->block_type, (unsigned int) pd[4]);
4712 */
4713 
4714  /* ts A61104 */
4715  if(!(o->control&4)) /* audio (MMC-1 table 61) */
4716  if(o->write_type == BURN_WRITE_TAO)
4717  pd[4] = 0; /* Data Block Type: Raw Data */
4718 
4719  pd[14] = 0; /* audio pause length MSB */
4720  pd[15] = 150; /* audio pause length LSB */
4721 
4722 /*XXX need session format! */
4723 /* ts A61229 : but session format (pd[8]) = 0 seems ok */
4724 
4725  /* Media Catalog Number at byte 16 to 31,
4726  MMC-5, 7.5, Tables 664, 670
4727  */
4728  if (o->has_mediacatalog)
4729  catalog = (unsigned char *) o->mediacatalog;
4730  else if (s != NULL) {
4731  if (s->mediacatalog[0])
4732  catalog = s->mediacatalog;
4733  }
4734  if (catalog != NULL && d->mdata->write_page_length >= 30) {
4735  pd[16] = 0x80; /* MCVAL */
4736  memcpy(pd + 17, catalog, 13);
4737  }
4738 
4739  /* ISRC at bytes 32 to 47. Tables 664, 671 */
4740  /* SCMS at byte 3 bit 4 */
4741  isrc_text[0] = 0;
4742  if (s != NULL && o->write_type == BURN_WRITE_TAO) {
4743  if (tnum >= 0 && tnum < s->tracks) {
4744  if (s->track[tnum]->isrc.has_isrc) {
4745  isrc = &(s->track[tnum]->isrc);
4746  isrc_text[0] = isrc->country[0];
4747  isrc_text[1] = isrc->country[1];
4748  isrc_text[2] = isrc->owner[0];
4749  isrc_text[3] = isrc->owner[1];
4750  isrc_text[4] = isrc->owner[2];
4751  sprintf(isrc_text + 5, "%-2.2u",
4752  (unsigned int) isrc->year);
4753  sprintf(isrc_text + 7, "%-5.5u",
4754  isrc->serial);
4755  isrc_text[12]= 0;
4756  }
4757  if ((s->track[tnum]->mode & BURN_SCMS) &&
4758  !(s->track[tnum]->mode & BURN_COPY))
4759  pd[3] |= 0x10;
4760  }
4761  }
4762  if (isrc_text[0] != 0 && d->mdata->write_page_length >= 46) {
4763  pd[32] = 0x80; /* TCVAL */
4764  memcpy(pd + 33, isrc_text, 12);
4765  }
4766  }
4767  return 1;
4768 }
4769 
4770 
4771 /* A70812 ts */
4772 int mmc_read_10(struct burn_drive *d, int start,int amount, struct buffer *buf)
4773 {
4774  struct command *c;
4775  char *msg = NULL;
4776  int key, asc, ascq, silent;
4777 
4778  c = &(d->casual_command);
4779  mmc_start_if_needed(d, 0);
4780  if (mmc_function_spy(d, "mmc_read_10") <= 0)
4781  return -1;
4782 
4783  if (amount > BUFFER_SIZE / 2048)
4784  return -1;
4785 
4787  c->dxfer_len = amount * 2048;
4788  c->retry = 1;
4789  mmc_int_to_four_char(c->opcode + 2, start);
4790  c->opcode[7] = (amount >> 8) & 0xFF;
4791  c->opcode[8] = amount & 0xFF;
4792  c->page = buf;
4793  c->page->bytes = 0;
4794  c->page->sectors = 0;
4795  c->dir = FROM_DRIVE;
4796  d->issue_command(d, c);
4797 
4798  /* <<< replace by mmc_eval_read_error */;
4799  if (c->error) {
4800  msg = calloc(1, 256);
4801  if (msg != NULL) {
4802  sprintf(msg,
4803  "SCSI error on read_10(%d,%d): ", start, amount);
4804  scsi_error_msg(d, c->sense, 14, msg + strlen(msg),
4805  &key, &asc, &ascq);
4806  silent = (d->silent_on_scsi_error == 1);
4807  if (key == 5 && asc == 0x64 && ascq == 0x0) {
4808  d->had_particular_error |= 1;
4809  if (d->silent_on_scsi_error == 2)
4810  silent = 1;
4811  }
4812  if(!silent)
4814  d->global_index,
4815  0x00020144,
4816  (d->silent_on_scsi_error == 3) ?
4818  LIBDAX_MSGS_PRIO_HIGH, msg, 0, 0);
4819  free(msg);
4820  }
4821  return BE_CANCELLED;
4822  }
4823 
4824  buf->sectors = amount;
4825  buf->bytes = amount * 2048;
4826  return 0;
4827 }
4828 
4829 
4830 #ifdef Libburn_develop_quality_scaN
4831 
4832 /* B21108 ts : Vendor specific command REPORT ERROR RATE, see
4833  http://liggydee.cdfreaks.com/ddl/errorcheck.pdf
4834 */
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)
4838 {
4839  struct buffer *buf = NULL;
4840  struct command *c;
4841  char *msg = 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};
4845 
4846  BURN_ALLOC_MEM(buf, struct buffer, 1);
4847  BURN_ALLOC_MEM(c, struct command, 1);
4848  mmc_start_if_needed(d, 0);
4849  if (mmc_function_spy(d, "mmc_nec_optiarc_f3") <= 0)
4850  return -1;
4851 
4852  scsi_init_command(c, MMC_NEC_OPTIARC_F3, sizeof(MMC_NEC_OPTIARC_F3));
4853  if (sub_op == 3) {
4854  c->dxfer_len = 8;
4855  c->dir = FROM_DRIVE;
4856  } else {
4857  c->dxfer_len = 0;
4858  c->dir = NO_TRANSFER;
4859  }
4860  c->retry = 0;
4861  c->opcode[1] = sub_op;
4862  mmc_int_to_four_char(c->opcode + 2, start_lba);
4863  c->opcode[8] = rate_period;
4864  c->page = buf;
4865  c->page->bytes = 0;
4866  c->page->sectors = 0;
4867  d->issue_command(d, c);
4868  if (c->error) {
4869  msg = calloc(1, 256);
4870  if (msg != NULL) {
4871  sprintf(msg,
4872  "SCSI error on nec_optiarc_f3(%d, %d, %d): ",
4873  sub_op, start_lba, rate_period);
4874  scsi_error_msg(d, c->sense, 14, msg + strlen(msg),
4875  &key, &asc, &ascq);
4877  d->global_index, 0x00020144,
4879  msg, 0, 0);
4880  free(msg);
4881  }
4882  return BE_CANCELLED;
4883  }
4884 
4885  if (sub_op == 3) {
4886  *ret_lba = mmc_four_char_to_int(c->page->data);
4887  *error_rate1 = c->page->data[4] * 256 + c->page->data[5];
4888  *error_rate2 = c->page->data[6] * 256 + c->page->data[7];
4889  }
4890 
4891  ret = 1;
4892 ex:;
4893  BURN_FREE_MEM(c);
4894  BURN_FREE_MEM(buf);
4895  return ret;
4896 }
4897 
4898 #endif /* Libburn_develop_quality_scaN */
4899 
4900 
4901 /* ts A81210 : Determine the upper limit of readable data size */
4903 {
4904  struct buffer *buf = NULL;
4905  struct command *c = NULL;
4906  int alloc_len= 8, ret;
4907 
4908  BURN_ALLOC_MEM(buf, struct buffer, 1);
4909  BURN_ALLOC_MEM(c, struct command, 1);
4910  d->media_read_capacity = 0x7fffffff;
4911  d->mr_capacity_trusted = -1;
4912  mmc_start_if_needed(d, 1);
4913  if (mmc_function_spy(d, "mmc_read_capacity") <= 0)
4914  {ret = 0; goto ex;}
4915 
4917  c->dxfer_len = alloc_len;
4918  c->retry = 1;
4919  c->page = buf;
4920  c->page->bytes = 0;
4921  c->page->sectors = 0;
4922  c->dir = FROM_DRIVE;
4923  d->issue_command(d, c);
4925  if (d->media_read_capacity < 0) {
4926  d->media_read_capacity = 0x7fffffff;
4927  {ret = 0; goto ex;}
4928  }
4929  if (d->current_profile >= 0x08 && d->current_profile <= 0x0A)
4930  d->mr_capacity_trusted = 0;
4931  else
4932  d->mr_capacity_trusted = 1;
4933  ret = 1;
4934 ex:;
4935  BURN_FREE_MEM(c);
4936  BURN_FREE_MEM(buf);
4937  return ret;
4938 }
4939 
4940 
4941 /* ts A90903 */
4942 /* mmc5r03c.pdf 6.23 ADh READ DISC STRUCTURE obtains media specific information
4943 */
4944 static int mmc_read_disc_structure_al(struct burn_drive *d, int *alloc_len,
4945  int media_type, int layer_number, int format,
4946  int min_len, char **reply, int *reply_len,
4947  int flag)
4948 {
4949  struct buffer *buf = NULL;
4950  int old_alloc_len, len, ret;
4951  struct command *c = NULL;
4952  unsigned char *dpt;
4953 
4954  BURN_ALLOC_MEM(buf, struct buffer, 1);
4955  BURN_ALLOC_MEM(c, struct command, 1);
4956  *reply = NULL;
4957  *reply_len = 0;
4958 
4959  if (*alloc_len < 4)
4960  {ret = 0; goto ex;}
4961 
4963  sizeof(MMC_READ_DISC_STRUCTURE));
4964  c->dxfer_len = *alloc_len;
4965  c->retry = 1;
4966  c->opcode[1]= media_type;
4967  c->opcode[7]= format;
4968  c->opcode[8]= (c->dxfer_len >> 8) & 0xff;
4969  c->opcode[9]= c->dxfer_len & 0xff;
4970  c->page = buf;
4971  c->page->sectors = 0;
4972  c->page->bytes = 0;
4973  c->dir = FROM_DRIVE;
4974 
4975  d->issue_command(d, c);
4976  if (c->error)
4977  {ret = 0; goto ex;}
4978 
4979  len = (c->page->data[0] << 8) | (c->page->data[1]);
4980  old_alloc_len = *alloc_len;
4981  *alloc_len = len + 2;
4982  if (old_alloc_len <= 4)
4983  {ret = 1; goto ex;}
4984  if (len + 2 > old_alloc_len)
4985  len = old_alloc_len - 2;
4986  if (len < 4)
4987  {ret = 0; goto ex;}
4988 
4989  dpt = c->page->data + 4;
4990  if (len - 2 < min_len)
4991  {ret = 0; goto ex;}
4992  *reply = calloc(len - 2, 1);
4993  if (*reply == NULL)
4994  {ret = 0; goto ex;}
4995  *reply_len = len - 2;
4996  memcpy(*reply, dpt, len - 2);
4997  ret = 1;
4998 ex:;
4999  BURN_FREE_MEM(c);
5000  BURN_FREE_MEM(buf);
5001  return ret;
5002 }
5003 
5004 
5006  int media_type, int layer_number, int format, int min_len,
5007  char **reply, int *reply_len, int flag)
5008 {
5009  int alloc_len = 4, ret;
5010  char msg[80];
5011 
5012  mmc_start_if_needed(d, 1);
5013  if (mmc_function_spy(d, "mmc_read_disc_structure") <= 0)
5014  return 0;
5015 
5016  ret = mmc_read_disc_structure_al(d, &alloc_len,
5017  media_type, layer_number, format, min_len,
5018  reply, reply_len, 0);
5019 /*
5020  fprintf(stderr,"LIBBURN_DEBUG: ADh alloc_len = %d , ret = %d\n",
5021  alloc_len, ret);
5022 */
5023  if (ret <= 0)
5024  return ret;
5025  if (alloc_len < 12) {
5026  sprintf(msg,
5027  "READ DISC STRUCTURE announces only %d bytes of reply\n",
5028  alloc_len);
5029  libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
5031  msg, 0, 0);
5032  ret = 0;
5033 
5034 /* ts A91205
5035  LG GH22LS30 revision 1.00 returns for DVD-R format
5036  code 0x0E an allocation length of 4 (= 0 payload).
5037  A MS-Windows tool can inquire media code "RITEKF1",
5038  though.
5039  This macro causes a try to unconditionally read the
5040  desired payload bytes. The drive then returns 35
5041  bytes as requested and the media id is "RITEKF1".
5042  Nevertheless this is not a generally usable gesture
5043  because older GNU/Linux USB dislikes requests to fetch
5044  more bytes than the drive will deliver.
5045 
5046  # define Libburn_enforce_structure_code_0x0E 1
5047 */
5048 
5049 #ifdef Libburn_enforce_structure_code_0x0E
5050  if (format == 0x0E) {
5051  alloc_len = min_len + 4;
5052  ret = mmc_read_disc_structure_al(d, &alloc_len,
5053  media_type, layer_number, format, min_len,
5054  reply, reply_len, 0);
5055  if (*reply_len < min_len || *reply == NULL)
5056  ret = 0;
5057  sprintf(msg, "READ DISC STRUCTURE returns %d bytes of required %d\n",
5058  *reply_len + 4, min_len + 4);
5059  libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
5061  msg, 0, 0);
5062  }
5063 #endif
5064 
5065  } else
5066  ret = mmc_read_disc_structure_al(d, &alloc_len,
5067  media_type, layer_number, format, min_len,
5068  reply, reply_len, 0);
5069  return ret;
5070 }
5071 
5072 /* ts A90903 */
5073 /*
5074  @param flag bit0= set bit1 in flag for burn_util_make_printable_word
5075  and do not append media revision
5076  bit1= truncate media_code1 to 6 characters (else 8)
5077 */
5078 static int mmc_set_product_id(char *reply,
5079  int manuf_idx, int type_idx, int rev_idx,
5080  char **product_id, char **media_code1, char **media_code2, int flag)
5081 {
5082  int ret;
5083 
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)
5089  return -1;
5090  if (flag & 2)
5091  sprintf(*media_code1, "%.6s", reply + manuf_idx);
5092  else
5093  sprintf(*media_code1, "%.8s", reply + manuf_idx);
5094  ret = burn_util_make_printable_word(media_code1,
5095  1 | ((flag & 1) << 1));
5096  if (ret <= 0)
5097  return -1;
5098  sprintf(*media_code2, "%.3s%s", reply + type_idx,
5099  (flag & 1) ? "" : "xxxx");
5100  ret = burn_util_make_printable_word(media_code2,
5101  1 | ((flag & 1) << 1));
5102  if (ret <= 0)
5103  return -1;
5104  if (!(flag & 1)) {
5105  sprintf(*media_code2 + strlen(*media_code2) - 4, "/%d",
5106  (int) ((unsigned char *) reply)[rev_idx]);
5107  }
5108  sprintf(*product_id, "%s/%s", *media_code1, *media_code2);
5109  return 1;
5110 }
5111 
5112 
5113 /* ts A90903 */
5114 /* MMC backend of API call burn_disc_get_media_id()
5115  See also doc/mediainfo.txt
5116  @param flag Bitfield for control purposes
5117  bit0= do not escape " _/" (not suitable for
5118  burn_guess_manufacturer())
5119 
5120 */
5122  char **product_id, char **media_code1, char **media_code2,
5123  char **book_type, int flag)
5124 {
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;
5128 
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"};
5134 
5135  *product_id = *media_code1 = *media_code2 = *book_type = NULL;
5136  prf = d->current_profile;
5137  if (prf == 0x09 || prf == 0x0A) {
5138 
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) {
5144  ret = -1;
5145  goto ex;
5146  }
5147  ret = burn_disc_read_atip(d);
5148  if (ret <= 0)
5149  goto ex;
5150  ret = burn_drive_get_start_end_lba(d, &start_lba, &end_lba, 0);
5151  if (ret <= 0)
5152  goto ex;
5153  burn_lba_to_msf(start_lba, &min, &sec, &fr);
5154  sprintf(*media_code1, "%2.2dm%2.2ds%2.2df", min, sec, fr);
5155  burn_lba_to_msf(end_lba, &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);
5158  ret = 1;
5159  goto ex; /* No booktype with CD media */
5160 
5161  } else if (prf == 0x11 || prf == 0x13 || prf == 0x14 || prf == 0x15) {
5162  /* DVD-R */
5163 
5164  ret = mmc_read_disc_structure(d, 0, 0, 0x0E, 31, &reply,
5165  &reply_len, 0);
5166  if (ret <= 0)
5167  goto ex;
5168  /* ECMA-279 for DVD-R promises a third sixpack in field 5,
5169  but ECMA-338 for DVD-RW defines a different meaning.
5170  DVD-R and DVD-RW bear unprintable characters in there.
5171  */
5172  if (reply[16] != 3 || reply[24] != 4) {
5173  ret = 0;
5174  goto ex;
5175  }
5176  *media_code1 = calloc(19, 1);
5177  *media_code2 = strdup("");
5178  if (*media_code1 == NULL || *media_code2 == NULL) {
5179  ret = -1;
5180  goto ex;
5181  }
5182  memcpy(*media_code1, reply + 17, 6);
5183  memcpy(*media_code1 + 6, reply + 25, 6);
5184 
5185  /* Clean out 0 bytes */
5186  wpt = *media_code1;
5187  for (i = 0; i < 18; i++)
5188  if ((*media_code1)[i])
5189  *(wpt++) = (*media_code1)[i];
5190  *wpt = 0;
5191  ret = burn_util_make_printable_word(media_code1,
5192  1 | ((flag & 1) << 1));
5193  if (ret <= 0)
5194  goto ex;
5195  *product_id = strdup(*media_code1);
5196  if (*product_id == NULL) {
5197  ret = -1;
5198  goto ex;
5199  }
5200 
5201  } else if (prf == 0x1a || prf == 0x1b || prf == 0x2b) { /* DVD+R[W] */
5202 
5203  /* Check whether the drive supports format 11h */
5204  has_11h = 0;
5205  ret = mmc_read_disc_structure(d, 0, 0, 0xff, 4, &reply,
5206  &reply_len, 0);
5207  if (ret > 0) {
5208  for (i = 0; i < reply_len; i += 4) {
5209  if (reply[i] == 0x11 && (reply[i + 1] & 64))
5210  has_11h = 1;
5211  }
5212  }
5213  if (reply != NULL)
5214  free(reply);
5215  reply = NULL;
5216  ret = mmc_read_disc_structure(d, 0, 0, 0x11, 29, &reply,
5217  &reply_len, 0);
5218  if (ret <= 0) {
5219  /* Hope for format 00h */
5220  has_11h = 0;
5221  } else {
5222  /* Dig out manufacturer, media type and revision */
5223  ret = mmc_set_product_id(reply, 19, 27, 28,
5224  product_id, media_code1, media_code2,
5225  flag & 1);
5226  if (ret <= 0)
5227  goto ex;
5228  }
5229  } else if (prf == 0x41 || prf == 0x43 || prf == 0x40 || prf == 0x42) {
5230  /* BD */
5231  media_type = 1;
5232  ret = mmc_read_disc_structure(d, 1, 0, 0x00, 112, &reply,
5233  &reply_len, 0);
5234  if (ret <= 0)
5235  goto ex;
5236  if (reply[0] != 'D' || reply[1] != 'I') {
5237  ret = 0;
5238  goto ex;
5239  }
5240  /* Dig out manufacturer, media type and revision */
5241  ret = mmc_set_product_id(reply, 100, 106, 111,
5242  product_id, media_code1, media_code2,
5243  2 | (flag & 1));
5244  if (ret <= 0)
5245  goto ex;
5246 
5247  } else {
5248 
5249  /* Source of DVD-RAM manufacturer and media id not found yet */
5250  ret = 0;
5251  goto ex;
5252  }
5253 
5254  if (reply != NULL)
5255  free(reply);
5256  reply = NULL;
5257  ret = mmc_read_disc_structure(d, media_type, 0, 0x00, 1,
5258  &reply, &reply_len, 0);
5259  if (ret <= 0)
5260  goto ex;
5261  bt = (reply[0] >> 4) & 0xf;
5262  *book_type = calloc(80 + strlen(books[bt]), 1);
5263  if (*book_type == NULL) {
5264  ret = -1;
5265  goto ex;
5266  }
5267  sprintf(*book_type, "%2.2Xh, %s book [revision %d]",
5268  bt, books[bt], reply[0] & 0xf);
5269 
5270  if (has_11h == 0 && *product_id == NULL && reply_len > 28) {
5271  /* DVD+ with no format 11h */
5272  /* Get manufacturer and media type from bytes 19 and 27 */
5273  ret = mmc_set_product_id(reply, 19, 27, 28, product_id,
5274  media_code1, media_code2,
5275  flag & 1);
5276  if (*product_id == NULL) {
5277  ret = 0;
5278  goto ex;
5279  }
5280  }
5281 
5282  ret = 1;
5283 ex:;
5284  if (reply != NULL)
5285  free(reply);
5286  if (ret <= 0) {
5287  if (*product_id != NULL)
5288  free(*product_id);
5289  if (*media_code1 != NULL)
5290  free(*media_code1);
5291  if (*media_code2 != NULL)
5292  free(*media_code2);
5293  if (*book_type != NULL)
5294  free(*book_type);
5295  *product_id = *media_code1 = *media_code2 = *book_type = NULL;
5296  }
5297  return ret;
5298 }
5299 
5300 
5301 /* ts B00924
5302  MMC-5, 6.23.3.3.4 Format Code 0Ah: Spare Area Information
5303 */
5305  int *alloc_blocks, int *free_blocks, int flag)
5306 {
5307  int ret, reply_len, prf;
5308  char *reply = NULL;
5309 
5310  prf = d->current_profile;
5311  if (!(prf == 0x41 || prf == 0x43 || prf == 0x42))
5312  return 0; /* Not a BD loaded */
5313 
5314  ret = mmc_read_disc_structure(d, 1, 0, 0x0a, 12, &reply,
5315  &reply_len, 0);
5316  if (ret <= 0)
5317  goto ex;
5318  *alloc_blocks = mmc_four_char_to_int((unsigned char *) reply + 8);
5319  *free_blocks = mmc_four_char_to_int((unsigned char *) reply + 4);
5320  ret = 1;
5321 ex:;
5322  if (reply != NULL)
5323  free(reply);
5324  return ret;
5325 }
5326 
5327 
5328 /* ts B10801
5329  MMC-5, 6.23.3.2.1 Format Code 00h: Physical Format Information
5330  6.23.3.2.16 Format Code 10h: Format Information of
5331  Control Data Zone in the Lead-in
5332  disk_category
5333 */
5334 int mmc_get_phys_format_info(struct burn_drive *d, int *disk_category,
5335  char **book_name, int *part_version, int *num_layers,
5336  int *num_blocks, int flag)
5337 {
5338  int ret, reply_len, prf;
5339  char *reply = NULL;
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"
5345  };
5346 
5347  prf = d->current_profile;
5348  if (!(prf == 0x11 || prf == 0x13 || prf == 0x14 || prf == 0x15 ||
5349  prf == 0x51))
5350  return 0; /* Not a [HD] DVD-R[W] loaded */
5351  ret = mmc_read_disc_structure(d, 0, 0, 0x10, 12, &reply,
5352  &reply_len, 0);
5353  if (ret <= 0)
5354  goto ex;
5355  if(reply_len < 12) {
5356  libdax_msgs_submit(libdax_messenger, -1, 0x00000002,
5358  "READ DISC STRUCTURE format 10h: Less than 12 bytes",
5359  0, 0);
5360  {ret = 0; goto ex;}
5361  }
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;
5368  ret = 1;
5369 ex:;
5370  if (reply != NULL)
5371  free(reply);
5372  return ret;
5373 }
5374 
5375 
5376 /* ts A61021 : the mmc specific part of sg.c:enumerate_common()
5377 */
5379 {
5380  d->read_atip = mmc_read_atip;
5381  d->read_toc = mmc_read_toc;
5382  d->write = mmc_write;
5383  d->erase = mmc_erase;
5384  d->read_cd = mmc_read_cd;
5386  d->set_speed = mmc_set_speed;
5390  d->get_nwa = mmc_get_nwa;
5398  d->read_10 = mmc_read_10;
5399 
5400 
5401  /* ts A70302 */
5402  d->phys_if_std = -1;
5403  d->phys_if_name[0] = 0;
5404 
5405  /* ts A61020 */
5406  d->start_lba = -2000000000;
5407  d->end_lba = -2000000000;
5408 
5409  d->do_simulate= 0;
5410 
5411  /* ts A61201 - A90815*/
5412  d->erasable = 0;
5413  d->current_profile = -1;
5414  d->current_profile_text[0] = 0;
5415  d->current_is_cd_profile = 0;
5418  memset(d->all_profiles, 0, 256);
5419  d->num_profiles = 0;
5420  d->current_has_feat21h = 0;
5421  d->current_feat21h_link_size = -1;
5422  d->current_feat23h_byte4 = 0;
5423  d->current_feat23h_byte8 = 0;
5424  d->current_feat2fh_byte4 = -1;
5425  d->next_track_damaged = 0;
5426  d->needs_close_session = 0;
5427  d->needs_sync_cache = 0;
5428  d->bg_format_status = -1;
5429  d->num_opc_tables = -1;
5430  d->last_lead_in = -2000000000;
5431  d->last_lead_out = -2000000000;
5432  d->disc_type = 0xff;
5433  d->disc_id = 0;
5434  memset(d->disc_bar_code, 0, 9);
5435  d->disc_app_code = 0;
5436  d->disc_info_valid = 0;
5437  d->num_format_descr = 0;
5438  d->complete_sessions = 0;
5439 
5440 #ifdef Libburn_disc_with_incomplete_sessioN
5441  d->incomplete_sessions = 0;
5442 #endif
5443 
5444  d->state_of_last_session = -1;
5445  d->last_track_no = 1;
5446  d->media_capacity_remaining = 0;
5447  d->media_lba_limit = 0;
5448  d->media_read_capacity = 0x7fffffff;
5449  d->mr_capacity_trusted = 0;
5450  d->pessimistic_buffer_free = 0;
5451  d->pbf_altered = 0;
5453  d->nominal_write_speed = 0;
5454  d->pessimistic_writes = 0;
5455  d->waited_writes = 0;
5456  d->waited_tries = 0;
5457  d->waited_usec = 0;
5463  d->sent_default_page_05 = 0;
5464 
5465  return 1;
5466 }
5467 
5468 
5469 /* @param flag bit0= really add to text, else only count
5470 */
5471 static void burn__add_to_text(char *text, int *text_len, char *to_add,
5472  int flag)
5473 {
5474  (*text_len) += strlen(to_add);
5475  if (flag & 1)
5476  strcat(text, to_add);
5477 }
5478 
5479 /* @param flag bit0= really add to text, else only count
5480 */
5481 static void burn__add_hex_to_text(char *text, int *text_len,
5482  unsigned char *to_add, int add_length,
5483  int flag)
5484 {
5485  int i, l;
5486 
5487  (*text_len) += 3 * add_length;
5488  if (!(flag & 1))
5489  return;
5490  l = strlen(text);
5491  for (i = 0; i < add_length; i++)
5492  sprintf(text + l + 3 * i, " %2.2x", to_add[i]);
5493 }
5494 
5495 int burn_make_feature_text(struct burn_drive *d, unsigned int feature_code,
5496  unsigned char flags,
5497  unsigned char additional_length,
5498  unsigned char *feature_data,
5499  char **text, int flag)
5500 {
5501  char *feature_name, addon[320], *cpt;
5502  int text_len, ret, i, pass;
5503  unsigned int phys_is, lmt, num;
5504 
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,
5518  0x10d, 0x110,
5519  0xffff
5520  };
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",
5529  "DVD+RW",
5530  "DVD+R", "Rigid Restricted Overwrite", "CD Track at Once",
5531  "CD Mastering",
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",
5535  "BD Write 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",
5543  "AACS", "VCPS",
5544  ""
5545  };
5546  static unsigned short legacy_codes[] = {
5547  0x30, 0x31, 0x32, 0x103, 0xffff
5548  };
5549  static unsigned int phys_is_codes[] = {
5550  0x00, 0x01, 0x02, 0x03,
5551  0x04, 0x05, 0x06, 0x07,
5552  0x08, 0xffff,
5553  0xffffffff
5554  };
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",
5559  ""
5560  };
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)"
5565  };
5566 
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];
5571  break;
5572  }
5573  }
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)";
5578  break;
5579  }
5580  }
5581  }
5582  if (feature_code >= 0xff00 && feature_code <= 0xffff)
5583  feature_name = "(Vendor Specific)";
5584 
5585  *text = NULL;
5586  for (pass = 0; pass < 2; pass++) {
5587  if (pass == 1) {
5588  BURN_ALLOC_MEM(*text, char, text_len + 1);
5589  }
5590  text_len = 0;
5591 
5592  sprintf(addon, "%4.4x %c : ", feature_code,
5593  (flags & 1) ? '+' : '-');
5594  burn__add_to_text(*text, &text_len, addon, pass);
5595 
5596  burn__add_to_text(*text, &text_len, feature_name, pass);
5597 
5598  /* Version, Persistent, Current */
5599  sprintf(addon, " : %1.1x,%c :",
5600  (flags >> 2) & 15, (flags & 2) ? 'P' : 'N');
5601  burn__add_to_text(*text, &text_len, addon, pass);
5602 
5603  burn__add_hex_to_text(*text, &text_len,
5604  feature_data, (int) additional_length, pass);
5605  burn__add_to_text(*text, &text_len, " :", pass);
5606 
5607  if (feature_code == 0x01 && additional_length >= 4) {
5608  /* Core : Physical Interface Standard , INQ2, DBE */
5609  phys_is = mmc_four_char_to_int(feature_data);
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];
5614  break;
5615  }
5616 
5617  }
5618  num = 0;
5619  if (additional_length >= 9)
5620  num = feature_data[8];
5621  sprintf(addon,
5622  " PhysInterface=%x/%s , INQ2=%d , DBE=%d",
5623  phys_is, cpt, (num >> 1) & 1, num & 1);
5624  burn__add_to_text(*text, &text_len, addon, pass);
5625 
5626  } else if (feature_code == 0x03 && additional_length >= 1) {
5627  /* Removable Medium : Lock, Pvnt Jmpr, Eject,
5628  Loading mechanism Type
5629  */
5630  num = feature_data[0];
5631  lmt = (num >> 5) & 7;
5632  sprintf(addon,
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);
5636  burn__add_to_text(*text, &text_len, addon, pass);
5637 
5638  } else if (feature_code == 0x10 && additional_length >= 4) {
5639  /* Random Readable: Logical Block Size, Blocking */
5640  num = 0;
5641  if (additional_length >= 6)
5642  num = (feature_data[4] << 8) | feature_data[5];
5643  sprintf(addon, " BlockSize=%d , Blocking=%u",
5644  mmc_four_char_to_int(feature_data), num);
5645  num = 0;
5646  if (additional_length >= 7)
5647  num = feature_data[6];
5648  sprintf(addon + strlen(addon), " , PP=%d", num & 1);
5649  burn__add_to_text(*text, &text_len, addon, pass);
5650 
5651  } else if (feature_code == 0x1e && additional_length >= 1) {
5652  /* CD Read: DAP, C2 Flags, CD-Text */
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);
5657  burn__add_to_text(*text, &text_len, addon, pass);
5658 
5659  } else if (feature_code == 0x1f && additional_length >= 1) {
5660  /* DVD Read: MULTI110, Dual-R */
5661  num = 0;
5662  if (additional_length >= 3)
5663  num = feature_data[2];
5664  sprintf(addon, " MULTI10=%d , DualR=%d",
5665  feature_data[0] & 1, num & 1);
5666  burn__add_to_text(*text, &text_len, addon, pass);
5667 
5668  } else if (feature_code == 0x20 && additional_length >= 4) {
5669  /* Random Writable: Last LBA, Logical Block Size,
5670  Blocking, PP */
5671  num = 0;
5672  if (additional_length >= 8)
5673  num = mmc_four_char_to_int(feature_data + 4);
5674  sprintf(addon, " LastLBA=%d , BlockSize=%u",
5675  mmc_four_char_to_int(feature_data), num);
5676  num = 0;
5677  if (additional_length >= 10)
5678  num = (feature_data[8] << 8) | feature_data[9];
5679  sprintf(addon + strlen(addon), " , Blocking=%u", num);
5680  num = 0;
5681  if (additional_length >= 11)
5682  num = feature_data[10];
5683  sprintf(addon + strlen(addon), " , PP=%u", num);
5684  burn__add_to_text(*text, &text_len, addon, pass);
5685 
5686  } else if (feature_code == 0x21 && additional_length >= 2) {
5687  /* Incremental Streaming Writable :
5688  Data Block Types , TRIO , ARSV , BUF
5689  Number of Link Sizes
5690  */
5691  num = 0;
5692  if (additional_length >= 3)
5693  num = feature_data[2];
5694  sprintf(addon,
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);
5698  num = 0;
5699  if (additional_length >= 4)
5700  num = feature_data[3];
5701  sprintf(addon + strlen(addon), " , NumLinkSizes=%d",
5702  num);
5703  burn__add_to_text(*text, &text_len, addon, pass);
5704 
5705  } else if (feature_code == 0x23 && additional_length >= 1) {
5706  /* Formattable: RENoSA, Expand, QCert, Cert, RRM */
5707  num = feature_data[0];
5708  sprintf(addon,
5709  " RENoSA=%d , Expand=%d , QCert=%d , Cert=%d",
5710  (num >> 3) & 1, (num >> 2) & 1,
5711  (num >> 1) & 1, num & 1);
5712  num = 0;
5713  if (additional_length >= 5)
5714  num = feature_data[4];
5715  sprintf(addon + strlen(addon), " , RRM=%d", num & 1);
5716  burn__add_to_text(*text, &text_len, addon, pass);
5717 
5718  } else if (feature_code == 0x24 && additional_length >= 1) {
5719  /* Defect Management : SSA */
5720  sprintf(addon, " SSA=%d", (feature_data[0] >> 7) & 1);
5721  burn__add_to_text(*text, &text_len, addon, pass);
5722 
5723  } else if (feature_code == 0x28 && additional_length >= 1) {
5724  /* MRW */
5725  num = feature_data[0];
5726  sprintf(addon,
5727  " DVDPWrite=%d , DVDPRead=%d , CDWrite=%d",
5728  (num >> 2) & 1, (num >> 1) & 1, num & 1);
5729  burn__add_to_text(*text, &text_len, addon, pass);
5730 
5731  } else if (feature_code == 0x2a && additional_length >= 1) {
5732  /* DVD+RW */
5733  num = 0;
5734  if (additional_length >= 2)
5735  num = feature_data[1];
5736  sprintf(addon,
5737  " Write=%d , QuickStart=%d , CloseOnly=%d",
5738  feature_data[0] & 1, (num >> 1) & 1, num & 1);
5739  burn__add_to_text(*text, &text_len, addon, pass);
5740 
5741  } else if (feature_code == 0x2b && additional_length >= 1) {
5742  /* DVD+R */
5743  sprintf(addon, " Write=%d", feature_data[0] & 1);
5744  burn__add_to_text(*text, &text_len, addon, pass);
5745 
5746  } else if (feature_code == 0x2c && additional_length >= 1) {
5747  /* Rigid Restricted Overwrite */
5748  num = feature_data[0];
5749  sprintf(addon,
5750  " DSDG=%d , DSDR=%d , Intermediate=%d , Blank=%d",
5751  (num >> 3) & 1, (num >> 2) & 1,
5752  (num >> 1) & 1, num & 1);
5753  burn__add_to_text(*text, &text_len, addon, pass);
5754 
5755  } else if (feature_code == 0x2d && additional_length >= 1) {
5756  /* CD Track at Once */
5757  num= feature_data[0];
5758  sprintf(addon,
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);
5763  num = 0;
5764  if (additional_length >= 4)
5765  num = (feature_data[2] << 8) | feature_data[3];
5766  sprintf(addon + strlen(addon), " , DataTypeSupp=%4.4x",
5767  num);
5768  burn__add_to_text(*text, &text_len, addon, pass);
5769 
5770  } else if (feature_code == 0x2e && additional_length >= 1) {
5771  /* CD Mastering (SAO) */
5772  num = feature_data[0];
5773  sprintf(addon,
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);
5778  num = 0;
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);
5784  burn__add_to_text(*text, &text_len, addon, pass);
5785 
5786  } else if (feature_code == 0x2f && additional_length >= 1) {
5787  /* DVD-R/RW Write */
5788  num = feature_data[0];
5789  sprintf(addon,
5790  " BUF=%d , RDL=%d , TestWrite=%d , DVDRW=%d",
5791  (num >> 6) & 1, (num >> 3) & 1,
5792  (num >> 2) & 1, (num >> 1) & 1);
5793  burn__add_to_text(*text, &text_len, addon, pass);
5794 
5795  } else if (feature_code == 0x33 && additional_length >= 4) {
5796  /* Layer Jump Recording */
5797  sprintf(addon, " NumLinkSizes=%d", feature_data[3]);
5798  burn__add_to_text(*text, &text_len, addon, pass);
5799 
5800  } else if (feature_code == 0x37 && additional_length >= 2) {
5801  /* CD-RW Media Write Support */
5802  addon[0]= 0;
5803  for (i = 7; i >= 0; i--) {
5804  sprintf(addon + strlen(addon),
5805  " Subtype%d=%d%s",
5806  i, (feature_data[1] >> i) & 1,
5807  i > 0 ? " ," : "");
5808  }
5809  burn__add_to_text(*text, &text_len, addon, pass);
5810 
5811  } else if (feature_code == 0x3a && additional_length >= 2) {
5812  /* DVD+RW Dual Layer */
5813  sprintf(addon,
5814  " Write=%d , QuickStart=%d , CloseOnly=%d",
5815  feature_data[0] & 1,
5816  (feature_data[1] >> 1) & 1,
5817  feature_data[1] & 1);
5818  burn__add_to_text(*text, &text_len, addon, pass);
5819 
5820  } else if (feature_code == 0x3b && additional_length >= 1) {
5821  /* DVD+R Dual Layer */
5822  sprintf(addon, " Write=%d", feature_data[0] & 1);
5823  burn__add_to_text(*text, &text_len, addon, pass);
5824 
5825  } else if (feature_code == 0x50 && additional_length >= 1) {
5826  /* HD DVD Read */
5827  num = 0;
5828  if (additional_length >= 3)
5829  num = feature_data[2];
5830  sprintf(addon, " HDDVDR=%d , HDDVDRAM=%d",
5831  feature_data[0] & 1, num & 1);
5832  burn__add_to_text(*text, &text_len, addon, pass);
5833 
5834  } else if (feature_code == 0x51 && additional_length >= 1) {
5835  /* HD DVD Write */
5836  num = 0;
5837  if (additional_length >= 3)
5838  num = feature_data[2];
5839  sprintf(addon, " HDDVDR=%d , HDDVDRAM=%d",
5840  feature_data[0] & 1, num & 1);
5841  burn__add_to_text(*text, &text_len, addon, pass);
5842 
5843  } else if (feature_code == 0x101 && additional_length >= 1) {
5844  /* SMART */
5845  sprintf(addon, " PP=%d", feature_data[0] & 1);
5846  burn__add_to_text(*text, &text_len, addon, pass);
5847 
5848  } else if (feature_code == 0x102 && additional_length >= 1) {
5849  /* Embedded Changer */
5850  num = 0;
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);
5856  burn__add_to_text(*text, &text_len, addon, pass);
5857 
5858  } else if (feature_code == 0x105 && additional_length >= 1) {
5859  /* Timeout */
5860  num = 0;
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);
5865  burn__add_to_text(*text, &text_len, addon, pass);
5866 
5867  } else if (feature_code == 0x106 && additional_length >= 4) {
5868  /* DVD CSS */
5869  sprintf(addon, " CSSVersion=%d",
5870  (int) feature_data[3]);
5871  burn__add_to_text(*text, &text_len, addon, pass);
5872 
5873  } else if (feature_code == 0x107 && additional_length >= 1) {
5874  /* Real Time Streaming */
5875  num = feature_data[0];
5876  sprintf(addon,