1 /* @(#)drv_bd.c 1.21 13/12/10 Copyright 2007-2013 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)drv_bd.c 1.21 13/12/10 Copyright 2007-2013 J. Schilling";
6 #endif
7 /*
8 * Copyright (c) 2007-2013 J. Schilling
9 */
10 /*
11 * The contents of this file are subject to the terms of the
12 * Common Development and Distribution License, Version 1.0 only
13 * (the "License"). You may not use this file except in compliance
14 * with the License.
15 *
16 * See the file CDDL.Schily.txt in this distribution for details.
17 * A copy of the CDDL is also available via the Internet at
18 * http://www.opensource.org/licenses/cddl1.txt
19 *
20 * When distributing Covered Code, include this CDDL HEADER in each
21 * file and include the License file CDDL.Schily.txt from this distribution.
22 */
23
24 /*
25 * BD-R/RE device implementation for
26 * SCSI-3/mmc-3 conforming drives
27 *
28 * XXX Aktualisieren:
29 * Check recovery - DUMMY
30 * Load Media - OK
31 * Get Disktype - Disk Status & Size (read ATIP -> BD structure)
32 * Check Session ?? - Nicht vorhanden
33 * Check Disk size - Nach Status & size + Next wr. Addr.
34 * Set Speed/Dummy - Speed auf BD -> dummy
35 * Open Session - Set Write Parameter & ??? -> DAO
36 * LOOP
37 * Open Track - Set Write Parameter ???
38 * Get Next wr. Addr. -> DUMMY "0" ???
39 * Write Track Data OK
40 * Close Track - Flush Cache -> DUMMY
41 * END
42 * Fixate - Close Track/Session -> Flush Cache
43 * Unload Media - OK
44 *
45 * Verbose levels:
46 * 0 silent
47 * 1 print laser log & track sizes
48 * 2 print disk info & write parameters
49 * 3 print log pages & dvd structure
50 *
51 * Copyright (c) 2007-2008 J. Schilling
52 */
53 /*
54 * The contents of this file are subject to the terms of the
55 * Common Development and Distribution License, Version 1.0 only
56 * (the "License"). You may not use this file except in compliance
57 * with the License.
58 *
59 * See the file CDDL.Schily.txt in this distribution for details.
60 * A copy of the CDDL is also available via the Internet at
61 * http://www.opensource.org/licenses/cddl1.txt
62 *
63 * When distributing Covered Code, include this CDDL HEADER in each
64 * file and include the License file CDDL.Schily.txt from this distribution.
65 */
66
67 /*#define BD_DEBUG*/
68 #ifndef DEBUG
69 #define DEBUG
70 #endif
71 #include <schily/mconfig.h>
72
73 #include <schily/stdio.h>
74 #include <schily/stdlib.h>
75 #include <schily/unistd.h> /* Include sys/types.h to make off_t available */
76 #include <schily/standard.h>
77 #include <schily/string.h>
78 #include <schily/time.h>
79
80 #include <schily/utypes.h>
81 #include <schily/btorder.h>
82 #include <schily/intcvt.h>
83 #include <schily/schily.h>
84 #include <schily/nlsdefs.h>
85
86 #include <scg/scgcmd.h>
87 #include <scg/scsidefs.h>
88 #include <scg/scsireg.h>
89 #include <scg/scsitransp.h>
90
91 #include "scsimmc.h"
92 #include "scsilog.h"
93 #include "mmcvendor.h"
94 #include "cdrecord.h"
95
96
97 extern char *driveropts;
98
99 extern int lverbose;
100 extern int xdebug;
101
102 #define strbeg(s1, s2) (strstr((s2), (s1)) == (s2))
103
104 LOCAL cdr_t *identify_bd __PR((SCSI *scgp, cdr_t *, struct scsi_inquiry *));
105 LOCAL int attach_bd __PR((SCSI *scgp, cdr_t *));
106 LOCAL void di_to_dstat __PR((struct disk_info *dip, dstat_t *dsp));
107 LOCAL int init_bd __PR((SCSI *scgp, cdr_t *dp));
108 LOCAL int getdisktype_bd __PR((SCSI *scgp, cdr_t *dp));
109 LOCAL int prdiskstatus_bd __PR((SCSI *scgp, cdr_t *dp));
110 LOCAL int speed_select_bd __PR((SCSI *scgp, cdr_t *dp, int *speedp));
111 LOCAL int next_wr_addr_bdre __PR((SCSI *scgp, track_t *trackp, long *ap));
112 LOCAL int next_wr_addr_bdr __PR((SCSI *scgp, track_t *trackp, long *ap));
113 LOCAL int open_track_bd __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
114 LOCAL long rzone_size __PR((track_t *trackp));
115 LOCAL int close_track_bd __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
116 /*LOCAL int open_session_bd __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));*/
117 LOCAL int fixate_bdre __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
118 LOCAL int fixate_bdr __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
119 LOCAL int blank_bd __PR((SCSI *scgp, cdr_t *dp, long addr, int blanktype));
120 LOCAL int format_bd __PR((SCSI *scgp, cdr_t *dp, int fmtflags));
121 LOCAL int waitformat __PR((SCSI *scgp, int secs));
122 LOCAL int stats_bd __PR((SCSI *scgp, cdr_t *dp));
123
124 EXPORT int format_unit __PR((SCSI *scgp,
125 void *fmt, int length,
126 int list_format, int dgdl,
127 int interlv, int pattern, int timeout));
128 LOCAL void print_bd_info __PR((SCSI *_scgp));
129 LOCAL void print_bd00 __PR((Uchar *dp));
130 LOCAL void print_bd09 __PR((Uchar *dp));
131 LOCAL void print_bd0A __PR((Uchar *dp));
132
133 /*
134 * SCSI-3/mmc-3 conformant BD-R or BD-RE writer
135 * Checks the current medium and then returns either
136 * cdr_bdr or cdr_bdre
137 */
138 cdr_t cdr_bd = {
139 0, 0, 0,
140 0,
141 CDR2_NOCD|CDR2_BD,
142 CDR_CDRW_ALL,
143 WM_NONE,
144 1000, 1000,
145 "mmc_bd",
146 "generic SCSI-3/mmc-3 BD-R/BD-RE driver (checks media)",
147 0,
148 (dstat_t *)0,
149 identify_bd,
150 attach_bd,
151 (int(*)__PR((SCSI *scgp, cdr_t *)))cmd_ill, /* init */
152 drive_getdisktype,
153 no_diskstatus,
154 scsi_load,
155 scsi_unload,
156 read_buff_cap,
157 cmd_dummy, /* recovery_needed */
158 (int(*)__PR((SCSI *, cdr_t *, int)))cmd_dummy, /* recover */
159 (int(*)__PR((SCSI *scgp, cdr_t *, int *)))cmd_dummy, /* Speed */
160 select_secsize,
161 (int(*)__PR((SCSI *scgp, track_t *, long *)))cmd_ill, /* next_wr_addr */
162 (int(*)__PR((SCSI *, Ulong)))cmd_ill, /* reserve_track */
163 scsi_cdr_write,
164 (int(*)__PR((track_t *, void *, BOOL)))cmd_dummy, /* gen_cue */
165 no_sendcue,
166 (int(*)__PR((SCSI *, cdr_t *, track_t *)))cmd_dummy, /* leadin */
167 (int(*)__PR((SCSI *scgp, cdr_t *, track_t *)))cmd_dummy, /* open track */
168 (int(*)__PR((SCSI *scgp, cdr_t *, track_t *)))cmd_dummy, /* close track */
169 (int(*)__PR((SCSI *scgp, cdr_t *, track_t *)))cmd_dummy, /* open session */
170 cmd_dummy, /* close session */
171 cmd_dummy, /* abort */
172 read_session_offset,
173 (int(*)__PR((SCSI *scgp, cdr_t *, track_t *)))cmd_dummy, /* fixation */
174 cmd_dummy, /* stats */
175 blank_dummy,
176 format_dummy,
177 (int(*)__PR((SCSI *, caddr_t, int, int)))NULL, /* no OPC */
178 cmd_dummy, /* opt1 */
179 cmd_dummy, /* opt2 */
180 };
181
182 /*
183 * SCSI-3/mmc-3 conformant BD-ROM writer
184 */
185 cdr_t cdr_bdrom = {
186 0, 0, 0,
187 0,
188 CDR2_NOCD|CDR2_BD,
189 CDR_CDRW_ALL,
190 WM_SAO,
191 1000, 1000,
192 "mmc_bdrom",
193 "generic SCSI-3/mmc-3 BD-ROM driver",
194 0,
195 (dstat_t *)0,
196 identify_bd,
197 attach_bd,
198 init_bd,
199 getdisktype_bd,
200 prdiskstatus_bd,
201 scsi_load,
202 scsi_unload,
203 read_buff_cap,
204 cmd_dummy, /* recovery_needed */
205 (int(*)__PR((SCSI *, cdr_t *, int)))cmd_dummy, /* recover */
206 speed_select_bd,
207 select_secsize,
208 next_wr_addr_bdr,
209 (int(*)__PR((SCSI *, Ulong)))cmd_ill, /* reserve_track */
210 scsi_cdr_write,
211 (int(*)__PR((track_t *, void *, BOOL)))cmd_dummy, /* gen_cue */
212 no_sendcue,
213 (int(*)__PR((SCSI *, cdr_t *, track_t *)))cmd_ill, /* leadin */
214 (int(*)__PR((SCSI *scgp, cdr_t *, track_t *)))cmd_ill, /* open track */
215 (int(*)__PR((SCSI *scgp, cdr_t *, track_t *)))cmd_ill, /* close track */
216 (int(*)__PR((SCSI *scgp, cdr_t *, track_t *)))cmd_ill, /* open session */
217 cmd_dummy, /* close session */
218 cmd_dummy, /* abort */
219 read_session_offset,
220 fixate_bdr,
221 stats_bd,
222 blank_bd,
223 format_dummy,
224 (int(*)__PR((SCSI *, caddr_t, int, int)))NULL, /* no OPC */
225 cmd_dummy, /* opt1 */
226 cmd_dummy, /* opt2 */
227 };
228
229 /*
230 * SCSI-3/mmc-3 conformant BD-R writer
231 */
232 cdr_t cdr_bdr = {
233 0, 0, 0,
234 0,
235 CDR2_NOCD|CDR2_BD,
236 CDR_CDRW_ALL,
237 WM_SAO,
238 1000, 1000,
239 "mmc_bdr",
240 "generic SCSI-3/mmc-3 BD-R driver",
241 0,
242 (dstat_t *)0,
243 identify_bd,
244 attach_bd,
245 init_bd,
246 getdisktype_bd,
247 prdiskstatus_bd,
248 scsi_load,
249 scsi_unload,
250 read_buff_cap,
251 cmd_dummy, /* recovery_needed */
252 (int(*)__PR((SCSI *, cdr_t *, int)))cmd_dummy, /* recover */
253 speed_select_bd,
254 select_secsize,
255 next_wr_addr_bdr,
256 (int(*)__PR((SCSI *, Ulong)))cmd_ill, /* reserve_track */
257 scsi_cdr_write,
258 (int(*)__PR((track_t *, void *, BOOL)))cmd_dummy, /* gen_cue */
259 no_sendcue,
260 (int(*)__PR((SCSI *, cdr_t *, track_t *)))cmd_dummy, /* leadin */
261 open_track_bd,
262 close_track_bd,
263 (int(*)__PR((SCSI *scgp, cdr_t *, track_t *)))cmd_dummy, /* open session */
264 cmd_dummy, /* close session */
265 cmd_dummy, /* abort */
266 read_session_offset,
267 fixate_bdr,
268 stats_bd,
269 blank_bd,
270 format_dummy,
271 (int(*)__PR((SCSI *, caddr_t, int, int)))NULL, /* no OPC */
272 cmd_dummy, /* opt1 */
273 cmd_dummy, /* opt2 */
274 };
275
276 /*
277 * SCSI-3/mmc-3 conformant BD-RE writer
278 */
279 cdr_t cdr_bdre = {
280 0, 0, 0,
281 0,
282 CDR2_NOCD|CDR2_BD,
283 CDR_CDRW_ALL,
284 WM_SAO,
285 1000, 1000,
286 "mmc_bdre",
287 "generic SCSI-3/mmc-3 BD-RE driver",
288 0,
289 (dstat_t *)0,
290 identify_bd,
291 attach_bd,
292 init_bd,
293 getdisktype_bd,
294 prdiskstatus_bd,
295 scsi_load,
296 scsi_unload,
297 read_buff_cap,
298 cmd_dummy, /* recovery_needed */
299 (int(*)__PR((SCSI *, cdr_t *, int)))cmd_dummy, /* recover */
300 speed_select_bd,
301 select_secsize,
302 next_wr_addr_bdre,
303 (int(*)__PR((SCSI *, Ulong)))cmd_ill, /* reserve_track */
304 scsi_cdr_write,
305 (int(*)__PR((track_t *, void *, BOOL)))cmd_dummy, /* gen_cue */
306 no_sendcue,
307 (int(*)__PR((SCSI *, cdr_t *, track_t *)))cmd_dummy, /* leadin */
308 open_track_bd,
309 close_track_bd,
310 (int(*)__PR((SCSI *scgp, cdr_t *, track_t *)))cmd_dummy, /* open session */
311 cmd_dummy, /* close session */
312 cmd_dummy, /* abort */
313 read_session_offset,
314 fixate_bdre,
315 stats_bd,
316 blank_bd,
317 format_bd,
318 (int(*)__PR((SCSI *, caddr_t, int, int)))NULL, /* no OPC */
319 cmd_dummy, /* opt1 */
320 cmd_dummy, /* opt2 */
321 };
322
323 LOCAL cdr_t *
identify_bd(scgp,dp,ip)324 identify_bd(scgp, dp, ip)
325 SCSI *scgp;
326 cdr_t *dp;
327 struct scsi_inquiry *ip;
328 {
329 Uchar mode[0x100];
330 struct cd_mode_page_2A *mp;
331 int profile;
332
333 if (ip->type != INQ_WORM && ip->type != INQ_ROMD)
334 return ((cdr_t *)0);
335
336 allow_atapi(scgp, TRUE); /* Try to switch to 10 byte mode cmds */
337
338 scgp->silent++;
339 mp = mmc_cap(scgp, mode); /* Get MMC capabilities */
340 scgp->silent--;
341 if (mp == NULL)
342 return (NULL); /* Pre SCSI-3/mmc drive */
343
344 /*
345 * At this point we know that we have a SCSI-3/mmc compliant drive.
346 * Unfortunately ATAPI drives violate the SCSI spec in returning
347 * a response data format of '1' which from the SCSI spec would
348 * tell us not to use the "PF" bit in mode select. As ATAPI drives
349 * require the "PF" bit to be set, we 'correct' the inquiry data.
350 *
351 * XXX xxx_identify() should not have any side_effects ??
352 */
353 if (ip->data_format < 2)
354 ip->data_format = 2;
355
356 profile = get_curprofile(scgp);
357 if (xdebug)
358 printf(_("Current profile: 0x%04X\n"), profile);
359
360 if (profile == 0x0043) {
361 dp = &cdr_bdre;
362 } else if ((profile == 0x0041) || (profile == 0x0042)) {
363 dp = &cdr_bdr;
364 } else if (profile == 0x0040) {
365 dp = &cdr_bdrom;
366 } else {
367 errmsgno(EX_BAD, _("Found unsupported 0x%X profile.\n"), profile);
368 return ((cdr_t *)0);
369 }
370
371 return (dp);
372 }
373
374 LOCAL int
attach_bd(scgp,dp)375 attach_bd(scgp, dp)
376 SCSI *scgp;
377 cdr_t *dp;
378 {
379 Uchar mode[0x100];
380 struct cd_mode_page_2A *mp;
381 struct ricoh_mode_page_30 *rp = NULL;
382 Ulong xspeed;
383 Ulong mp2Aspeed;
384
385
386 allow_atapi(scgp, TRUE); /* Try to switch to 10 byte mode cmds */
387
388 scgp->silent++;
389 mp = mmc_cap(scgp, NULL); /* Get MMC capabilities in allocated mp */
390 scgp->silent--;
391 if (mp == NULL)
392 return (-1); /* Pre SCSI-3/mmc drive */
393
394 dp->cdr_cdcap = mp; /* Store MMC cap pointer */
395
396 /*
397 * XXX hier sollte drive max write speed & drive cur write speed
398 * XXX gesetzt werden.
399 */
400 dp->cdr_dstat->ds_dr_max_rspeed = a_to_u_2_byte(mp->max_read_speed)/4495;
401 if (dp->cdr_dstat->ds_dr_max_rspeed == 0)
402 dp->cdr_dstat->ds_dr_max_rspeed = 14;
403 dp->cdr_dstat->ds_dr_cur_rspeed = a_to_u_2_byte(mp->cur_read_speed)/4495;
404 if (dp->cdr_dstat->ds_dr_cur_rspeed == 0)
405 dp->cdr_dstat->ds_dr_cur_rspeed = 14;
406
407 dp->cdr_dstat->ds_dr_max_wspeed = a_to_u_2_byte(mp->max_write_speed)/4495;
408 if (mp->p_len >= 28)
409 dp->cdr_dstat->ds_dr_cur_wspeed = a_to_u_2_byte(mp->v3_cur_write_speed)/4495;
410 else
411 dp->cdr_dstat->ds_dr_cur_wspeed = a_to_u_2_byte(mp->cur_write_speed)/4495;
412
413 /*
414 * NEC drives incorrectly return CD speed values in mode page 2A.
415 * Try MMC3 get performance in hope that values closer to DVD speeds
416 * are always more correct than what is found in mode page 2A.
417 */
418 xspeed = 0;
419 scsi_get_perf_maxspeed(scgp, NULL, &xspeed, NULL);
420
421 mp2Aspeed = a_to_u_2_byte(mp->max_write_speed);
422
423 if (lverbose > 2) {
424 printf(_("max page 2A speed %lu (%lux), max perf speed %lu (%lux)\n"),
425 mp2Aspeed, mp2Aspeed/4495,
426 xspeed, xspeed/4495);
427 }
428
429 if ((is_cdspeed(mp2Aspeed) && !is_cdspeed(xspeed)) ||
430 (mp2Aspeed < 10000 && xspeed > 10000)) {
431 dp->cdr_dstat->ds_dr_max_wspeed = xspeed/4495;
432 xspeed = 0;
433 scsi_get_perf_curspeed(scgp, NULL, &xspeed, NULL);
434 if (xspeed > 0)
435 dp->cdr_dstat->ds_dr_cur_wspeed = xspeed / 4495;
436 }
437
438 if (dp->cdr_speedmax > dp->cdr_dstat->ds_dr_max_wspeed)
439 dp->cdr_speedmax = dp->cdr_dstat->ds_dr_max_wspeed;
440
441 if (dp->cdr_speeddef > dp->cdr_speedmax)
442 dp->cdr_speeddef = dp->cdr_speedmax;
443
444 rp = get_justlink_ricoh(scgp, mode);
445
446 if (mp->p_len >= 28)
447 dp->cdr_flags |= CDR_MMC3;
448 if (get_curprofile(scgp) >= 0)
449 dp->cdr_flags |= CDR_MMC3;
450 if (mp->p_len >= 24)
451 dp->cdr_flags |= CDR_MMC2;
452 dp->cdr_flags |= CDR_MMC;
453
454 if (mp->loading_type == LT_TRAY)
455 dp->cdr_flags |= CDR_TRAYLOAD;
456 else if (mp->loading_type == LT_CADDY)
457 dp->cdr_flags |= CDR_CADDYLOAD;
458
459 if (mp->BUF != 0)
460 dp->cdr_flags |= CDR_BURNFREE;
461
462 check_writemodes_mmc(scgp, dp);
463 /*
464 * To avoid that silly people try to call cdrecord will write modes
465 * that are illegal for DVDs, we clear anything that does now work.
466 */
467 dp->cdr_flags &= ~(CDR_RAW|CDR_RAW16|CDR_RAW96P|CDR_RAW96R|CDR_SRAW96P|CDR_SRAW96R);
468 dp->cdr_flags &= ~(CDR_TAO);
469
470 if (mp->BUF != 0) {
471 dp->cdr_flags |= CDR_BURNFREE;
472 } else if (rp) {
473 if ((dp->cdr_cmdflags & F_DUMMY) && rp->TWBFS && rp->BUEFS)
474 dp->cdr_flags |= CDR_BURNFREE;
475
476 if (rp->BUEFS)
477 dp->cdr_flags |= CDR_BURNFREE;
478 }
479
480 if (rp && rp->AWSCS)
481 dp->cdr_flags |= CDR_FORCESPEED;
482
483
484 if ((dp->cdr_flags & (CDR_SAO)) != (CDR_SAO)) {
485 /*
486 * XXX Ist dies ueberhaupt noch notwendig seit wir nicht
487 * XXX mehr CDR_TAO vorgaukeln muessen?
488 *
489 * Das Panasonic DVD-R mag check_writemodes_mmc() nicht
490 * hilft das vielleicht?
491 */
492 dp->cdr_flags |= CDR_SAO;
493 }
494
495 if (driveropts != NULL) {
496 char *p;
497
498 if (strcmp(driveropts, "help") == 0) {
499 mmc_opthelp(scgp, dp, 0);
500 }
501
502 p = hasdrvopt(driveropts, "burnfree");
503 if (p == NULL)
504 p = hasdrvopt(driveropts, "burnproof");
505 if (p != NULL && (dp->cdr_flags & CDR_BURNFREE) != 0) {
506 if (*p == '1') {
507 dp->cdr_dstat->ds_cdrflags |= RF_BURNFREE;
508 } else if (*p == '0') {
509 dp->cdr_dstat->ds_cdrflags &= ~RF_BURNFREE;
510 }
511 }
512
513 p = hasdrvopt(driveropts, "forcespeed");
514 if (p != NULL && *p == '1' && (dp->cdr_flags & CDR_FORCESPEED) != 0) {
515 dp->cdr_dstat->ds_cdrflags |= RF_FORCESPEED;
516 }
517 }
518
519 /*
520 * Raise the default timeout.
521 * The first write takes a long time as it writes the lead in.
522 */
523 if (scgp->deftimeout < 100)
524 scg_settimeout(scgp, 100); /* 1:40 */
525
526 return (0);
527 }
528
529 LOCAL void
di_to_dstat(dip,dsp)530 di_to_dstat(dip, dsp)
531 struct disk_info *dip;
532 dstat_t *dsp;
533 {
534 dsp->ds_diskid = a_to_u_4_byte(dip->disk_id);
535
536 dsp->ds_flags |= DSF_NOCD|DSF_BD; /* This is a BD */
537
538 if (dip->did_v)
539 dsp->ds_flags |= DSF_DID_V;
540 dsp->ds_disktype = dip->disk_type;
541 dsp->ds_diskstat = dip->disk_status;
542 dsp->ds_sessstat = dip->sess_status;
543 if (dip->erasable)
544 dsp->ds_flags |= DSF_ERA;
545
546 dsp->ds_trfirst = dip->first_track;
547 dsp->ds_trlast = dip->last_track_ls;
548 dsp->ds_trfirst_ls = dip->first_track_ls;
549
550 #ifdef nono
551 /*
552 * On BD systems, there is no lead out start time
553 * in the disk info because there is no time based data.
554 */
555 dsp->ds_maxblocks = msf_to_lba(dip->last_lead_out[1],
556 dip->last_lead_out[2],
557 dip->last_lead_out[3], TRUE);
558 #endif
559 }
560
561 LOCAL int
init_bd(scgp,dp)562 init_bd(scgp, dp)
563 SCSI *scgp;
564 cdr_t *dp;
565 {
566 return (speed_select_bd(scgp, dp, NULL));
567 }
568
569 LOCAL int
getdisktype_bd(scgp,dp)570 getdisktype_bd(scgp, dp)
571 SCSI *scgp;
572 cdr_t *dp;
573 {
574 extern char *buf;
575 dstat_t *dsp = dp->cdr_dstat;
576 struct disk_info *dip;
577 Uchar mode[0x100];
578 struct rzone_info *rp;
579 struct dvd_structure_00 *sp;
580 int len;
581 BOOL did_dummy = FALSE;
582 BOOL did_reload = FALSE;
583 int profile;
584 Int32_t maxblocks;
585 Ulong end_lba;
586
587 if ((dp->cdr_dstat->ds_cdrflags & RF_PRATIP) != 0) {
588 if (((dsp->ds_cdrflags & (RF_WRITE|RF_BLANK)) == 0) ||
589 lverbose > 1) {
590 /*
591 * Das BD Medieninfo ist so lang, da� wir es
592 * beim Schreiben mit -v noch nicht ausgeben.
593 */
594 print_bd_info(scgp);
595 }
596 }
597
598 again:
599 dip = (struct disk_info *)buf;
600 if (get_diskinfo(scgp, dip, sizeof (*dip)) < 0)
601 return (-1);
602
603 /*
604 * Check for non writable disk first.
605 */
606 #ifdef BD_DEBUG
607 error(_("DISK STATUS %X\n"), dip->disk_status);
608 #endif
609 if (dip->disk_status == DS_COMPLETE &&
610 (dsp->ds_cdrflags & (RF_WRITE|RF_BLANK)) == RF_WRITE) {
611
612 profile = get_curprofile(scgp);
613 if (profile == 0x0043) { /* This is a BD-RE */
614 if (dp->cdr_cmdflags & F_FIX)
615 return (0);
616 }
617
618
619 if (!did_dummy) {
620 int xspeed = 0xFFFF;
621 int oflags = dp->cdr_cmdflags;
622
623 /*
624 * Try to clear the dummy bit to reset the virtual
625 * drive status. Not all drives support it even though
626 * it is mentioned in the MMC standard.
627 */
628 if (lverbose)
629 printf(_("Trying to clear drive status.\n"));
630
631 dp->cdr_cmdflags &= ~F_DUMMY;
632 speed_select_bd(scgp, dp, &xspeed);
633 dp->cdr_cmdflags = oflags;
634 scgp->silent++;
635 rezero_unit(scgp);
636 scgp->silent--;
637 did_dummy = TRUE;
638 goto again;
639 }
640 if (!did_reload && profile == 0x0043) { /* This is a BD-RE */
641 scgp->silent++;
642 len = read_scsi(scgp, buf, 0, 1);
643 scgp->silent--;
644 if (len < 0) {
645 /*
646 * DVD+RW "complete" but unreadable
647 * Trying to clear drive status did not work...
648 * This happens if the DVD+RW media was erased
649 * by the Ricoh Vendor Unique command
650 */
651 reload_media(scgp, dp);
652 did_reload = TRUE;
653 goto again;
654 }
655 }
656 /*
657 * Trying to clear drive status did not work...
658 * XXX This most likely makes no sense with DVD+R
659 */
660 /* reload_media(scgp, dp);*/
661 }
662 if (get_diskinfo(scgp, dip, sizeof (*dip)) < 0)
663 return (-1);
664 di_to_dstat(dip, dsp);
665
666 #ifdef BD_DEBUG
667 error("dtype %d era %d sess stat %d disk stat %d\n",
668 dip->dtype,
669 dip->erasable,
670 dip->sess_status,
671 dip->disk_status);
672 error("Dirty %d Format status %d\n", dip->dbit, dip->bg_format_stat);
673 error("disk type %X\n",
674 dip->disk_type);
675 {
676 long nwa = -1;
677
678 next_wr_addr_bdr(scgp, (track_t *)NULL, &nwa);
679 error("NWA: %ld\n", nwa);
680 }
681 #endif
682
683
684 profile = get_curprofile(scgp);
685 if (profile == 0x0043) {
686 dsp->ds_flags |= DSF_BD_RE; /* This is a BD-RE */
687 if (dip->disk_status == DS_EMPTY) { /* Unformatted */
688 dsp->ds_flags |= DSF_NEED_FORMAT;
689 if ((dp->cdr_dstat->ds_cdrflags & RF_PRATIP) != 0)
690 print_format_capacities(scgp);
691 return (0);
692 }
693 } else if (profile == 0x0041 || profile == 0x0042) {
694 dsp->ds_flags |= DSF_BD; /* This is a BD-R */
695 }
696 #ifdef BD_DEBUG
697 error("profile %X dsp->ds_flags 0x%X\n", profile, dsp->ds_flags);
698 #endif
699
700 /*
701 * This information is based on a logical recording zone
702 * and may not always be correct.
703 * XXX Check this if we want to support anything else but
704 * XXX one data track on DAO mode. The current firmware
705 * XXX of the recorder supports only this method but future
706 * XXX releases may support more.
707 */
708 fillbytes((caddr_t)mode, sizeof (mode), '\0');
709 rp = (struct rzone_info *)mode;
710 read_rzone_info(scgp, (caddr_t)rp, sizeof (struct rzone_info));
711
712 if ((dp->cdr_dstat->ds_cdrflags & RF_PRATIP) != 0) {
713 if (((dsp->ds_cdrflags & (RF_WRITE|RF_BLANK)) == 0) ||
714 lverbose > 1) {
715 przone(rp);
716 print_format_capacities(scgp);
717 }
718 }
719 #define needed_for_pioneer_a06
720 #ifdef needed_for_pioneer_a06
721 /*
722 * Old code used with the S101 seems to be needed for DVD+RW
723 * and the Pioneer A06 if the medium is not yet fully formatted.
724 */
725 dsp->ds_maxblocks = a_to_u_4_byte(rp->rzone_size);
726 #ifdef BD_DEBUG
727 error("MAXBLO %d from rzone size\n", dsp->ds_maxblocks);
728 #endif
729 if (dsp->ds_maxblocks == 0)
730 #endif
731 dsp->ds_maxblocks = a_to_u_4_byte(rp->free_blocks);
732 #ifdef BD_DEBUG
733 error("MAXBLO %d\n", dsp->ds_maxblocks);
734 error("MAXBLO %d from free_blocks\n", (int)a_to_u_4_byte(rp->free_blocks));
735 #endif
736 if (rp->nwa_v)
737 dsp->ds_maxblocks += a_to_u_4_byte(rp->next_recordable_addr);
738 #ifdef BD_DEBUG
739 error("NWAv %d Next rec addr %d\n", rp->nwa_v, (int)a_to_u_4_byte(rp->next_recordable_addr));
740 #endif
741 maxblocks = dsp->ds_maxblocks;
742
743 /*
744 * XXX this was: if (dip->disk_status == DS_EMPTY)
745 */
746 if (dip->disk_status == DS_COMPLETE && profile != 0x0043)
747 return (drive_getdisktype(scgp, dp));
748
749 /*
750 * This information is based on the physical pre recorded information.
751 * First try to find the len supported by the actual drive.
752 */
753 fillbytes((caddr_t)mode, sizeof (mode), '\0');
754 if (read_dvd_structure(scgp, (caddr_t)mode, 2, 1, 0, 0, 0) < 0) {
755 errmsgno(EX_BAD, _("Cannot read BD structure.\n"));
756 return (drive_getdisktype(scgp, dp));
757 }
758 len = a_to_u_2_byte(mode);
759 len += 2; /* Data len is not included */
760
761 if (len > sizeof (struct dvd_structure_00)) {
762 len = sizeof (struct dvd_structure_00);
763 /*
764 * The ACARD TECH AEC-7720 ATAPI<->SCSI adaptor
765 * chokes if we try to transfer odd byte counts (rounds up to
766 * even byte counts and thus causes a DMA overflow and a
767 * bus reset), so make the byte count even.
768 */
769 len += 1;
770 len &= ~1;
771 }
772 fillbytes((caddr_t)mode, sizeof (mode), '\0');
773 sp = (struct dvd_structure_00 *)mode;
774 read_dvd_structure(scgp, (caddr_t)sp, len, 1, 0, 0, 0);
775 /* if (lverbose > 1)*/
776 /* print_dvd00(sp);*/
777 /*
778 * Bei Pioneer ist Phys End ist nur bei dem S101 != 0.
779 * Bei Panasonic ist Phys End == Phys Start.
780 */
781 if ((profile != 0x0043) &&
782 (a_to_u_3_byte(sp->phys_end) != 0) &&
783 (dsp->ds_maxblocks !=
784 (long)(a_to_u_3_byte(sp->phys_end) - a_to_u_3_byte(sp->phys_start) + 1))) {
785 printf(_("WARNING: Phys disk size %ld differs from rzone size %ld! Prerecorded disk?\n"),
786 (long)(a_to_u_3_byte(sp->phys_end) - a_to_u_3_byte(sp->phys_start) + 1),
787 (long)dsp->ds_maxblocks);
788 printf(_("WARNING: Phys start: %ld Phys end %ld\n"),
789 (long)a_to_u_3_byte(sp->phys_start),
790 (long)a_to_u_3_byte(sp->phys_end));
791 }
792 #ifdef BD_DEBUG
793 error("MAXBLOx %d\n", dsp->ds_maxblocks);
794 #endif
795 if ((long)dsp->ds_maxblocks == 0) {
796 dsp->ds_maxblocks = a_to_u_3_byte(sp->phys_end) - a_to_u_3_byte(sp->phys_start) + 1;
797 }
798 #ifdef BD_DEBUG
799 error("MAXBLOx %d\n", dsp->ds_maxblocks);
800 error("phys start %d phys end %d\n", a_to_u_3_byte(sp->phys_start), a_to_u_3_byte(sp->phys_end));
801 error("MAXBLO %d from phys end - phys start\n", (int)(a_to_u_3_byte(sp->phys_end) - a_to_u_3_byte(sp->phys_start) + 1));
802 #endif
803
804 /*
805 * Workaround for some drive media combinations.
806 * At least the drive 'HL-DT-ST' 'BD-RE BH10LS30 ' '1.00'
807 * does not report maxblocks correctly with any BD media.
808 */
809 end_lba = 0L;
810 scsi_get_perf_maxspeed(scgp, (Ulong *)NULL, (Ulong *)NULL, &end_lba);
811 #ifdef BD_DEBUG
812 error("end_lba; %lu\n", end_lba);
813 #endif
814 if ((Int32_t)end_lba > dsp->ds_maxblocks) {
815 if (maxblocks == 0)
816 printf(_("WARNING: Drive returns zero media size, correcting.\n"));
817 dsp->ds_maxblocks = end_lba + 1;
818 }
819
820 #ifdef BD_DEBUG
821 error("FINAL MAXBLO %d\n", dsp->ds_maxblocks);
822 #endif
823 return (drive_getdisktype(scgp, dp));
824 }
825
826 LOCAL int
prdiskstatus_bd(scgp,dp)827 prdiskstatus_bd(scgp, dp)
828 SCSI *scgp;
829 cdr_t *dp;
830 {
831 return (prdiskstatus(scgp, dp, FALSE));
832 }
833
834
835 LOCAL int
speed_select_bd(scgp,dp,speedp)836 speed_select_bd(scgp, dp, speedp)
837 SCSI *scgp;
838 cdr_t *dp;
839 int *speedp;
840 {
841 Uchar mode[0x100];
842 Uchar moder[0x100];
843 int len;
844 struct cd_mode_page_05 *mp;
845 struct ricoh_mode_page_30 *rp = NULL;
846 int val;
847 Ulong ul;
848 BOOL forcespeed = FALSE;
849 BOOL dummy = (dp->cdr_cmdflags & F_DUMMY) != 0;
850 int curspeed = 1;
851
852 if (speedp)
853 curspeed = *speedp;
854
855 fillbytes((caddr_t)mode, sizeof (mode), '\0');
856
857 if (!get_mode_params(scgp, 0x05, _("CD write parameter"),
858 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len))
859 return (-1);
860 if (len == 0)
861 return (-1);
862
863 mp = (struct cd_mode_page_05 *)
864 (mode + sizeof (struct scsi_mode_header) +
865 ((struct scsi_mode_header *)mode)->blockdesc_len);
866 #ifdef DEBUG
867 if (lverbose > 1)
868 scg_prbytes(_("CD write parameter:"), (Uchar *)mode, len);
869 #endif
870
871
872 if (get_curprofile(scgp) == 0x0043) { /* This is a BD-RE */
873 if (dummy != 0) {
874 errmsgno(EX_BAD, _("BD-RE has no -dummy mode.\n"));
875 return (-1);
876 }
877 if (dp->cdr_cmdflags & F_FIX)
878 return (0);
879 }
880 mp->test_write = dummy != 0;
881 /*
882 * Set default values:
883 * Write type = 02 (disk at once)
884 * Track mode = 00 Reserved on Pioneer DVR-S101
885 * Data block type = 00 Reserved on Pioneer DVR-S101
886 * Session format = 00 Reserved on Pioneer DVR-S101
887 * XXX DVR-S101 uses ls_v and link size violating
888 * XXX the current MMC2 spec.
889 */
890 mp->write_type = WT_SAO;
891
892 #ifdef DEBUG
893 if (lverbose > 1)
894 scg_prbytes(_("CD write parameter:"), (Uchar *)mode, len);
895 #endif
896 if (!set_mode_params(scgp, _("CD write parameter"), mode, len, 0, -1)) {
897 return (-1);
898 }
899
900 /*
901 * Neither set nor get speed.
902 */
903 if (speedp == 0)
904 return (0);
905
906
907 rp = get_justlink_ricoh(scgp, moder);
908 if ((dp->cdr_flags & CDR_FORCESPEED) != 0) {
909 forcespeed = rp && rp->AWSCD != 0;
910 }
911
912 if (lverbose && (dp->cdr_flags & CDR_FORCESPEED) != 0)
913 printf(_("Forcespeed is %s.\n"), forcespeed?_("ON"):_("OFF"));
914
915 if (!forcespeed && (dp->cdr_dstat->ds_cdrflags & RF_FORCESPEED) != 0) {
916 printf(_("Turning forcespeed on\n"));
917 forcespeed = TRUE;
918 }
919 if (forcespeed && (dp->cdr_dstat->ds_cdrflags & RF_FORCESPEED) == 0) {
920 printf(_("Turning forcespeed off\n"));
921 forcespeed = FALSE;
922 }
923 if ((dp->cdr_flags & CDR_FORCESPEED) != 0) {
924
925 if (rp) {
926 rp->AWSCD = forcespeed?1:0;
927 set_mode_params(scgp, _("Ricoh Vendor Page"), moder, moder[0]+1, 0, -1);
928 rp = get_justlink_ricoh(scgp, moder);
929 }
930 }
931
932 /*
933 * BD single speed is 4495.5 kB/s
934 * Rounding down is guaranteed.
935 */
936 val = curspeed*4496;
937 if (val > 0x7FFFFFFF)
938 val = 0x7FFFFFFF;
939 if (dp->cdr_flags & CDR_MMC3) {
940 if (speed_select_mdvd(scgp, -1, val) < 0)
941 errmsgno(EX_BAD, _("MMC-3 speed select did not work.\n"));
942 } else {
943 if (val > 0xFFFF)
944 val = 0xFFFF;
945 scgp->silent++;
946 if (scsi_set_speed(scgp, -1, val, ROTCTL_CLV) < 0) {
947 /*
948 * Don't complain if it does not work,
949 * BD drives may not have speed setting.
950 */
951 }
952 scgp->silent--;
953 }
954
955 scgp->silent++;
956 if (scsi_get_speed(scgp, 0, &val) >= 0) {
957 if (val > 0) {
958 curspeed = val / 4495;
959 *speedp = curspeed;
960 }
961 }
962 /*
963 * NEC drives incorrectly return CD speed values in mode page 2A.
964 * Try MMC3 get performance in hope that values closer to BD speeds
965 * are always more correct than what is found in mode page 2A.
966 */
967 ul = 0;
968 if (scsi_get_perf_curspeed(scgp, NULL, &ul, NULL) >= 0) {
969 if (is_cdspeed(val) && !is_cdspeed(ul)) {
970 curspeed = ul / 4495;
971 *speedp = curspeed;
972 }
973 }
974 scgp->silent--;
975 return (0);
976 }
977 /*--------------------------------------------------------------------------*/
978
979 LOCAL long dvd_next_addr;
980
981 LOCAL int
next_wr_addr_bdre(scgp,trackp,ap)982 next_wr_addr_bdre(scgp, trackp, ap)
983 SCSI *scgp;
984 track_t *trackp;
985 long *ap;
986 {
987 if (trackp == 0 || trackp->track <= 1) {
988 dvd_next_addr = 0;
989 }
990 if (ap)
991 *ap = dvd_next_addr;
992 return (0);
993 }
994
995 LOCAL int
next_wr_addr_bdr(scgp,trackp,ap)996 next_wr_addr_bdr(scgp, trackp, ap)
997 SCSI *scgp;
998 track_t *trackp;
999 long *ap;
1000 {
1001 struct disk_info di;
1002 struct rzone_info rz;
1003 int tracks;
1004 long next_addr = -1;
1005
1006 if (trackp == 0) {
1007 fillbytes((caddr_t)&di, sizeof (di), '\0');
1008 if (get_diskinfo(scgp, &di, sizeof (di)) < 0)
1009 return (-1);
1010
1011 tracks = di.last_track_ls + di.last_track_ls_msb * 256;
1012 fillbytes((caddr_t)&rz, sizeof (rz), '\0');
1013 if (get_trackinfo(scgp, (caddr_t)&rz, TI_TYPE_TRACK, tracks, sizeof (rz)) < 0)
1014 return (-1);
1015 if (!rz.nwa_v)
1016 return (-1);
1017 next_addr = a_to_4_byte(rz.next_recordable_addr);
1018 if (ap)
1019 *ap = next_addr;
1020 return (0);
1021 }
1022 if (trackp->track <= 1) {
1023 /*
1024 * XXX This is a workaround for the filesize > 2GB problem.
1025 * XXX Check this if we support more than one track DAO
1026 * XXX or if we give up this hack in favour of real 64bit
1027 * XXX filesize support.
1028 */
1029 fillbytes((caddr_t)&rz, sizeof (rz), '\0');
1030 read_rzone_info(scgp, (caddr_t)&rz, sizeof (struct rzone_info));
1031 dvd_next_addr = a_to_4_byte(rz.next_recordable_addr);
1032 #ifdef BD_DEBUG
1033 error("NWA: %ld valid: %d\n", dvd_next_addr, rz.nwa_v);
1034 #endif
1035 if (lverbose > 1)
1036 printf(_("next writable addr: %ld valid: %d\n"), dvd_next_addr, rz.nwa_v);
1037 }
1038 if (ap)
1039 *ap = dvd_next_addr;
1040 return (0);
1041 }
1042
1043 LOCAL int
open_track_bd(scgp,dp,trackp)1044 open_track_bd(scgp, dp, trackp)
1045 SCSI *scgp;
1046 cdr_t *dp;
1047 track_t *trackp;
1048 {
1049 Uchar mode[0x100];
1050 int len;
1051 long sectors;
1052 struct cd_mode_page_05 *mp;
1053
1054 if (trackp->track > 1) /* XXX Hack to make one 'track' from several */
1055 return (0); /* XXX files in Disk at once mode only. */
1056
1057 fillbytes((caddr_t)mode, sizeof (mode), '\0');
1058
1059 if (!get_mode_params(scgp, 0x05, _("CD write parameter"),
1060 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len))
1061 return (-1);
1062 if (len == 0)
1063 return (-1);
1064
1065 mp = (struct cd_mode_page_05 *)
1066 (mode + sizeof (struct scsi_mode_header) +
1067 ((struct scsi_mode_header *)mode)->blockdesc_len);
1068
1069 /*
1070 * XXX as long as the Pioneer DVR-S101 only supports a single
1071 * XXX data track in DAO mode,
1072 * XXX do not set:
1073 * XXX track_mode
1074 * XXX copy
1075 * XXX dbtype
1076 *
1077 * Track mode = 00 Reserved on Pioneer DVR-S101
1078 * Data block type = 00 Reserved on Pioneer DVR-S101
1079 * Session format = 00 Reserved on Pioneer DVR-S101
1080 * XXX DVR-S101 uses ls_v and link size violating
1081 * XXX the current MMC2 spec.
1082 */
1083 /* XXX look into drv_mmc.c for re-integration of above settings */
1084
1085 #ifdef DEBUG
1086 if (lverbose > 1)
1087 scg_prbytes(_("CD write parameter:"), (Uchar *)mode, len);
1088 #endif
1089 if (!set_mode_params(scgp, _("CD write parameter"), mode, len, 0, trackp->secsize))
1090 return (-1);
1091
1092 /*
1093 * Compile vitual track list
1094 */
1095 sectors = rzone_size(trackp);
1096 #ifdef __needed_for_bd__
1097 if (sectors < 0)
1098 return (-1);
1099 #endif
1100 #ifdef __needed_for_bd__
1101 return (reserve_tr_rzone(scgp, sectors));
1102 #else
1103 return (0);
1104 #endif
1105 }
1106
1107 /*
1108 * XXX rzone_size(trackp) mu� aufgerufen werden, daher mu�
1109 * XXX auch f�r DVD+RW eine non-dummy open_track() Funktion da sein.
1110 */
1111 /*
1112 * XXX Hack to make one 'track' from several
1113 * XXX files in Disk at once mode only.
1114 * XXX Calculate track size and reserve rzone.
1115 */
1116 LOCAL long
rzone_size(trackp)1117 rzone_size(trackp)
1118 track_t *trackp; /* Called with &track[1] */
1119 {
1120 int i;
1121 BOOL vtracks = FALSE;
1122 long sectors = 0L;
1123 Llong ttrsize = 0L;
1124 Llong tamount = 0L;
1125 Llong amount;
1126 long secsize = trackp->secsize;
1127
1128 for (i = 0; i < MAX_TRACK; i++) {
1129 if (is_last(&trackp[i]))
1130 break;
1131 }
1132 if (i >= 1)
1133 vtracks = TRUE;
1134 if (vtracks && lverbose)
1135 printf(_("Compiling virtual track list ...\n"));
1136
1137 for (i = 0; i < MAX_TRACK; i++) {
1138 if (trackp[i].tracksize < (tsize_t)0) {
1139 errmsgno(EX_BAD, _("VTrack %d has unknown length.\n"), i);
1140 return (-1);
1141 }
1142 amount = roundup(trackp[i].tracksize, secsize);
1143 amount += (Llong)trackp[i].padsecs * secsize;
1144 sectors += amount/secsize;
1145 ttrsize += trackp[i].tracksize;
1146 tamount += amount;
1147 if (vtracks && lverbose)
1148 printf(_("Vtrack: %d size: %lld bytes %lld rounded (%lld sectors)\n"),
1149 (int)trackp[i].track, (Llong)trackp[i].tracksize,
1150 amount, amount / (Llong)secsize);
1151
1152 if (is_last(&trackp[i]))
1153 break;
1154
1155 /*
1156 * XXX Is it possible for a BD that input sector size
1157 * XXX differes from output sector size?
1158 * XXX I believe that not.
1159 */
1160 if (trackp[i].tracksize % secsize) {
1161 comerrno(EX_BAD, _("Virtual track %d is not a multiple of secsize.\n"), (int)trackp[i].track);
1162 }
1163 }
1164
1165 if (vtracks && lverbose)
1166 printf(_("Vtracks: %d size: %lld bytes %lld rounded (%ld sectors) total\n"),
1167 i+1, ttrsize, tamount, sectors);
1168
1169 return (sectors);
1170 }
1171
1172 LOCAL int
close_track_bd(scgp,dp,trackp)1173 close_track_bd(scgp, dp, trackp)
1174 SCSI *scgp;
1175 cdr_t *dp;
1176 track_t *trackp;
1177 {
1178 long sectors = 0L;
1179 Llong amount;
1180 long secsize = trackp->secsize;
1181
1182 /*
1183 * Compute the start of the next "track" for the hack
1184 * that allows to have a track in more than one file.
1185 * XXX Check this if the vtrack code is removed.
1186 */
1187 amount = roundup(trackp->tracksize, secsize);
1188 amount += (Llong)trackp->padsecs * secsize;
1189 sectors += amount/secsize;
1190
1191 dvd_next_addr += sectors;
1192
1193 return (0);
1194 }
1195
1196 #ifdef __needed_for_dvd_plusr__
1197 LOCAL int
open_session_dvd(scgp,dp,trackp)1198 open_session_dvd(scgp, dp, trackp)
1199 SCSI *scgp;
1200 cdr_t *dp;
1201 track_t *trackp;
1202 {
1203 Uchar mode[0x100];
1204 Uchar moder[0x100];
1205 int len;
1206 struct cd_mode_page_05 *mp;
1207 struct ricoh_mode_page_30 *rp = NULL;
1208 BOOL burnfree = FALSE;
1209
1210 fillbytes((caddr_t)mode, sizeof (mode), '\0');
1211
1212 if (!get_mode_params(scgp, 0x05, _("CD write parameter"),
1213 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len))
1214 return (-1);
1215 if (len == 0)
1216 return (-1);
1217
1218 mp = (struct cd_mode_page_05 *)
1219 (mode + sizeof (struct scsi_mode_header) +
1220 ((struct scsi_mode_header *)mode)->blockdesc_len);
1221
1222 /*
1223 * XXX as long as the Pioneer DVR-S101 only supports a single
1224 * XXX data track in DAO mode,
1225 * XXX do not set:
1226 * XXX multi_session
1227 * XXX sessipon_format
1228 *
1229 * Track mode = 00 Reserved on Pioneer DVR-S101
1230 * Data block type = 00 Reserved on Pioneer DVR-S101
1231 * Session format = 00 Reserved on Pioneer DVR-S101
1232 * XXX DVR-S101 uses ls_v and link size violating
1233 * XXX the current MMC2 spec.
1234 */
1235 /* XXX look into drv_mmc.c for re-integration of above settings */
1236 mp->write_type = WT_SAO;
1237
1238
1239 rp = get_justlink_ricoh(scgp, moder);
1240
1241 if (dp->cdr_cdcap->BUF != 0) {
1242 burnfree = mp->BUFE != 0;
1243 } else if ((dp->cdr_flags & CDR_BURNFREE) != 0) {
1244 burnfree = rp && rp->BUEFE != 0;
1245 }
1246
1247 if (lverbose && (dp->cdr_flags & CDR_BURNFREE) != 0)
1248 printf(_("BURN-Free is %s.\n"), burnfree?_("ON"):_("OFF"));
1249
1250 if (!burnfree && (dp->cdr_dstat->ds_cdrflags & RF_BURNFREE) != 0) {
1251 printf(_("Turning BURN-Free on\n"));
1252 burnfree = TRUE;
1253 }
1254 if (burnfree && (dp->cdr_dstat->ds_cdrflags & RF_BURNFREE) == 0) {
1255 printf(_("Turning BURN-Free off\n"));
1256 burnfree = FALSE;
1257 }
1258 if (dp->cdr_cdcap->BUF != 0) {
1259 mp->BUFE = burnfree?1:0;
1260 } else if ((dp->cdr_flags & CDR_BURNFREE) != 0) {
1261
1262 if (rp)
1263 rp->BUEFE = burnfree?1:0;
1264 }
1265 if (rp) {
1266 i_to_2_byte(rp->link_counter, 0);
1267 if (xdebug)
1268 scg_prbytes(_("Mode Select Data "), moder, moder[0]+1);
1269
1270 set_mode_params(scgp, _("Ricoh Vendor Page"), moder, moder[0]+1, 0, -1);
1271 rp = get_justlink_ricoh(scgp, moder);
1272 }
1273
1274 #ifdef DEBUG
1275 if (lverbose > 1)
1276 scg_prbytes(_("CD write parameter:"), (Uchar *)mode, len);
1277 #endif
1278 if (!set_mode_params(scgp, _("CD write parameter"), mode, len, 0, -1))
1279 return (-1);
1280
1281 return (0);
1282 }
1283 #endif
1284
1285 /*
1286 * We need to loop here because of a firmware bug in Pioneer DVD writers.
1287 */
1288 LOCAL int
fixate_bdre(scgp,dp,trackp)1289 fixate_bdre(scgp, dp, trackp)
1290 SCSI *scgp;
1291 cdr_t *dp;
1292 track_t *trackp;
1293 {
1294 int oldtimeout = scgp->deftimeout;
1295 int ret = 0;
1296 int i;
1297 #define MAX_TRIES 15
1298
1299 /*
1300 * XXX Is this timeout needed for BD-RE too?
1301 * XXX It was introduced for DVD-R that writes at least 800 MB
1302 */
1303 if (scgp->deftimeout < 1000)
1304 scg_settimeout(scgp, 1000);
1305
1306 /*scgp->verbose++;*/
1307 scgp->silent++;
1308 for (i = 0; i <= MAX_TRIES; i++) {
1309 if (scsi_flush_cache(scgp, TRUE) < 0) {
1310 if (!scsi_in_progress(scgp) || i >= MAX_TRIES) {
1311 if (scgp->verbose <= 0) {
1312 scg_printerr(scgp);
1313 scg_printresult(scgp); /* XXX restore key/code in future */
1314 }
1315 printf(_("Trouble flushing the cache\n"));
1316 scgp->silent--;
1317 scg_settimeout(scgp, oldtimeout);
1318 return (-1);
1319 }
1320 sleep(1);
1321 } else {
1322 break;
1323 }
1324 }
1325 scgp->silent--;
1326 waitformat(scgp, 300);
1327
1328 #ifdef __needed__ /* BD-RE does not need (permit) a close session */
1329 scgp->silent++;
1330 for (i = 0; i <= MAX_TRIES; i++) {
1331 if (scsi_close_tr_session(scgp, CL_TYPE_SESSION, 0, TRUE) < 0) {
1332 if (!scsi_in_progress(scgp) || i >= MAX_TRIES) {
1333 if (scgp->verbose <= 0) {
1334 scg_printerr(scgp);
1335 scg_printresult(scgp); /* XXX restore key/code in future */
1336 }
1337 printf(_("Trouble closing the session\n"));
1338 break;
1339 }
1340 sleep(1);
1341 } else {
1342 break;
1343 }
1344 }
1345 scgp->silent--;
1346 /*scgp->verbose--;*/
1347 #endif /* __needed__ */
1348
1349 waitformat(scgp, 300);
1350
1351 scg_settimeout(scgp, oldtimeout);
1352 return (ret);
1353 #undef MAX_TRIES
1354 }
1355
1356
1357 LOCAL int
fixate_bdr(scgp,dp,trackp)1358 fixate_bdr(scgp, dp, trackp)
1359 SCSI *scgp;
1360 cdr_t *dp;
1361 track_t *trackp;
1362 {
1363 int oldtimeout = scgp->deftimeout;
1364 int ret = 0;
1365 int key = 0;
1366 int code = 0;
1367 int trackno;
1368 int i;
1369 #define MAX_TRIES 15
1370
1371 /*
1372 * XXX Is this timeout needed for BD-R too?
1373 * XXX It was introduced for DVD-R that writes at least 800 MB
1374 */
1375 if (scgp->deftimeout < 1000)
1376 scg_settimeout(scgp, 1000);
1377
1378 /*scgp->verbose++;*/
1379 scgp->silent++;
1380 for (i = 0; i <= MAX_TRIES; i++) {
1381 if (scsi_flush_cache(scgp, TRUE) < 0) {
1382 if (!scsi_in_progress(scgp) || i >= MAX_TRIES) {
1383 if (scgp->verbose <= 0) {
1384 scg_printerr(scgp);
1385 scg_printresult(scgp); /* XXX restore key/code in future */
1386 }
1387 printf(_("Trouble flushing the cache\n"));
1388 scgp->silent--;
1389 scg_settimeout(scgp, oldtimeout);
1390 return (-1);
1391 }
1392 sleep(1);
1393 } else {
1394 break;
1395 }
1396 }
1397 scgp->silent--;
1398 key = scg_sense_key(scgp);
1399 code = scg_sense_code(scgp);
1400 waitformat(scgp, 600);
1401 /*
1402 * With CDs we used to close the invisible track (0xFF) but
1403 * with DVDs this may not work anymore if the unit is MMC-3
1404 * or above. Use the real track/border number instead.
1405 * We always use the "IMMED" flag - is this OK?
1406 */
1407 trackno = trackp->trackno;
1408 if (trackno <= 0)
1409 trackno = 1;
1410 scgp->silent++;
1411 for (i = 0; i <= MAX_TRIES; i++) {
1412 if (scsi_close_tr_session(scgp, CL_TYPE_TRACK, trackno, TRUE) < 0) {
1413 if (!scsi_in_progress(scgp) || i >= MAX_TRIES) {
1414 if (scgp->verbose <= 0) {
1415 scg_printerr(scgp);
1416 scg_printresult(scgp); /* XXX restore key/code in future */
1417 }
1418 printf(_("Trouble closing the track\n"));
1419 break;
1420 }
1421 sleep(1);
1422 } else {
1423 break;
1424 }
1425 }
1426 scgp->silent--;
1427 key = scg_sense_key(scgp);
1428 code = scg_sense_code(scgp);
1429 waitformat(scgp, 600);
1430
1431 scgp->silent++;
1432 for (i = 0; i <= MAX_TRIES; i++) {
1433 if (scsi_close_tr_session(scgp, 0x06, 0, TRUE) < 0) {
1434 if (!scsi_in_progress(scgp) || i >= MAX_TRIES) {
1435 if (scgp->verbose <= 0) {
1436 scg_printerr(scgp);
1437 scg_printresult(scgp); /* XXX restore key/code in future */
1438 }
1439 printf(_("Trouble closing the last session\n"));
1440 break;
1441 }
1442 sleep(1);
1443 } else {
1444 break;
1445 }
1446 }
1447 scgp->silent--;
1448 key = scg_sense_key(scgp);
1449 code = scg_sense_code(scgp);
1450 waitformat(scgp, 600);
1451 /*scgp->verbose--;*/
1452
1453 scg_settimeout(scgp, oldtimeout);
1454 return (ret);
1455 #undef MAX_TRIES
1456 }
1457
1458
1459 /*--------------------------------------------------------------------------*/
1460
1461 LOCAL int
blank_bd(scgp,dp,addr,blanktype)1462 blank_bd(scgp, dp, addr, blanktype)
1463 SCSI *scgp;
1464 cdr_t *dp;
1465 long addr;
1466 int blanktype;
1467 {
1468 BOOL cdrr = FALSE; /* Read CD-R */
1469 BOOL cdwr = FALSE; /* Write CD-R */
1470 BOOL cdrrw = FALSE; /* Read CD-RW */
1471 BOOL cdwrw = FALSE; /* Write CD-RW */
1472 BOOL dvdwr = FALSE; /* DVD writer */
1473
1474 int ret;
1475
1476 mmc_check(scgp, &cdrr, &cdwr, &cdrrw, &cdwrw, NULL, &dvdwr);
1477
1478 ret = blank_simul(scgp, dp, addr, blanktype);
1479 waitformat(scgp, 600);
1480 scsi_flush_cache(scgp, TRUE);
1481 waitformat(scgp, 600);
1482 return (ret);
1483 }
1484
1485 LOCAL int
format_bd(scgp,dp,fmtflags)1486 format_bd(scgp, dp, fmtflags)
1487 SCSI *scgp;
1488 cdr_t *dp;
1489 int fmtflags;
1490 {
1491 /*
1492 * 1.3 Formatting
1493 * --------------
1494 *
1495 * - For efficiency, please use the Format command only on blank discs
1496 *
1497 * - The command is:
1498 * - "04 11 00 00 00 00 00 00 00 00 00 00
1499 * ^^^
1500 * 0x10 Format Data
1501 * 0x01 Format Code == 1
1502 * 00 82 00 08 00 B4 74 00 C3 00 30 00"
1503 * ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^
1504 * Format Format
1505 * header descriptor
1506 * 0x80 FOV
1507 * 0x20 IMMED
1508 * len == 0x08
1509 */
1510 char cap_buf[4096];
1511 char fmt_buf[128];
1512 int len;
1513 int i;
1514 struct scsi_cap_data *cp;
1515 struct scsi_format_cap_desc *lp;
1516 struct scsi_format_header *fhp;
1517 long blocks = 0;
1518 long blen = 0;
1519 struct timeval starttime;
1520 struct timeval stoptime;
1521 #ifdef BD_DEBUG
1522 struct timeval stoptime2;
1523 #endif
1524
1525 len = get_format_capacities(scgp, cap_buf, sizeof (cap_buf));
1526 if (len < 0)
1527 return (-1);
1528
1529 #ifdef BD_DEBUG
1530 error(_("Cap len: %d\n"), len);
1531 scg_prbytes(_("Format cap:"), (Uchar *)cap_buf, len);
1532 #endif
1533
1534 cp = (struct scsi_cap_data *)cap_buf;
1535 lp = cp->list;
1536 len -= sizeof (struct scsi_format_cap_header);
1537 if (lp->desc_type == 2) {
1538 if ((dp->cdr_cmdflags & F_FORCE) == 0) {
1539 errmsgno(EX_BAD, _("Medium is already formatted.\n"));
1540 return (-1);
1541 }
1542 }
1543 #ifdef BD_DEBUG
1544 error("hd len: %d len: %d\n", cp->hd.len, len);
1545 #endif
1546
1547 for (i = len; i >= sizeof (struct scsi_format_cap_desc);
1548 i -= sizeof (struct scsi_format_cap_desc), lp++) {
1549 #ifdef BD_DEBUG
1550 error("blocks %ld fmt 0x%X desc %d blen: %ld\n",
1551 (long)a_to_u_4_byte(lp->nblock),
1552 lp->fmt_type,
1553 lp->desc_type,
1554 (long)a_to_u_3_byte(lp->blen));
1555 #endif
1556 if (lp->fmt_type == FCAP_TYPE_BDRE_SPARE) {
1557 blocks = a_to_u_4_byte(lp->nblock);
1558 blen = (long)a_to_u_3_byte(lp->blen);
1559 break;
1560 }
1561 }
1562 if (blocks == 0) {
1563 errmsgno(EX_BAD, _("BD-RE Full format with spares, capacity not found.\n"));
1564 return (-1);
1565 }
1566
1567 fhp = (struct scsi_format_header *)fmt_buf;
1568 lp = (struct scsi_format_cap_desc *)&fmt_buf[4];
1569 fillbytes((caddr_t)fmt_buf, sizeof (fmt_buf), '\0');
1570
1571 fhp->enable = 1;
1572 fhp->immed = 1;
1573 i_to_2_byte(fhp->length, 8);
1574 i_to_4_byte(lp->nblock, blocks);
1575 lp->fmt_type = FCAP_TYPE_BDRE_SPARE;
1576 lp->desc_type = 3; /* Quick certification */
1577 i_to_3_byte(lp->blen, blen);
1578
1579 #ifdef BD_DEBUG
1580 scg_prbytes(_("Format desc:"), (Uchar *)fmt_buf, 12);
1581 #endif
1582
1583 if (lverbose) {
1584 /*
1585 * XXX evt. restart Format ansagen...
1586 */
1587 printf(_("Formatting media\n"));
1588 flush();
1589 }
1590 starttime.tv_sec = 0;
1591 starttime.tv_usec = 0;
1592 stoptime = starttime;
1593 gettimeofday(&starttime, (struct timezone *)0);
1594
1595 if (format_unit(scgp, fhp, /*fhp->length*/ 8 + sizeof (struct scsi_format_header),
1596 1, 0, 0, 0,
1597 blocks > 20000000 ? 11000:5300) < 0) {
1598 return (-1);
1599 }
1600
1601
1602 #ifdef BD_DEBUG
1603 /* if (ret >= 0 && lverbose) {*/
1604 if (1) {
1605 gettimeofday(&stoptime, (struct timezone *)0);
1606 prtimediff(_("Format time: "), &starttime, &stoptime);
1607 }
1608 #endif
1609 waitformat(scgp, 300);
1610
1611 #ifdef BD_DEBUG
1612 gettimeofday(&stoptime2, (struct timezone *)0);
1613 prtimediff(_("Format WAIT time: "), &stoptime, &stoptime2);
1614 prtimediff(_("Format time TOTAL: "), &starttime, &stoptime2);
1615 #endif
1616 return (0);
1617 }
1618
1619 LOCAL int
waitformat(scgp,secs)1620 waitformat(scgp, secs)
1621 SCSI *scgp;
1622 int secs;
1623 {
1624 Uchar sensebuf[CCS_SENSE_LEN];
1625 int printed = 0;
1626 int i;
1627 int key;
1628 #define W_SLEEP 2
1629
1630 scgp->silent++;
1631 for (i = 0; i < secs/W_SLEEP; i++) {
1632 if (test_unit_ready(scgp) >= 0) {
1633 scgp->silent--;
1634 return (0);
1635 }
1636 key = scg_sense_key(scgp);
1637 if (key != SC_UNIT_ATTENTION && key != SC_NOT_READY)
1638 break;
1639 request_sense_b(scgp, (caddr_t)sensebuf, sizeof (sensebuf));
1640 #ifdef XXX
1641 scg_prbytes("Sense:", sensebuf, sizeof (sensebuf));
1642 scgp->scmd->u_scb.cmd_scb[0] = 2;
1643 movebytes(sensebuf, scgp->scmd->u_sense.cmd_sense, sizeof (sensebuf));
1644 scgp->scmd->sense_count = sizeof (sensebuf);
1645 scg_printerr(scgp);
1646 #endif
1647 /*
1648 * status: 0x2 (CHECK CONDITION)
1649 * Sense Bytes: F0 00 00 00 24 1C 10 0C 00 00 00 00 04 04 00 80 03 F6
1650 * Sense Key: 0x0 No Additional Sense, Segment 0
1651 * Sense Code: 0x04 Qual 0x04 (logical unit not ready, format in progress) Fru 0x0
1652 * Sense flags: Blk 2366480 (valid)
1653 * cmd finished after 0.000s timeout 100s
1654 * Das Fehlt:
1655 * operation 1% done
1656 */
1657
1658 if (lverbose && (sensebuf[15] & 0x80)) {
1659 printed++;
1660 error(_("operation %d%% done\r"),
1661 (100*(sensebuf[16] << 8 |
1662 sensebuf[17]))/(unsigned)65536);
1663 }
1664 sleep(W_SLEEP);
1665 }
1666 scgp->silent--;
1667 if (printed)
1668 error("\n");
1669 return (-1);
1670 #undef W_SLEEP
1671 }
1672
1673 LOCAL int
stats_bd(scgp,dp)1674 stats_bd(scgp, dp)
1675 SCSI *scgp;
1676 cdr_t *dp;
1677 {
1678 Uchar mode[256];
1679 struct ricoh_mode_page_30 *rp;
1680 UInt32_t count;
1681
1682 if ((dp->cdr_dstat->ds_cdrflags & RF_BURNFREE) == 0)
1683 return (0);
1684
1685 rp = get_justlink_ricoh(scgp, mode);
1686 if (rp) {
1687 count = a_to_u_2_byte(rp->link_counter);
1688 if (lverbose) {
1689 if (count == 0)
1690 printf(_("BURN-Free was not used.\n"));
1691 else
1692 printf(_("BURN-Free was %d times used.\n"),
1693 (int)count);
1694 }
1695 }
1696 return (0);
1697 }
1698
1699 #ifdef NEEDED
1700 #define FMTDAT 0x10
1701 #define CMPLST 0x08
1702
1703 EXPORT int
format_unit(scgp,fmt,length,list_format,dgdl,interlv,pattern,timeout)1704 format_unit(scgp, fmt, length, list_format, dgdl, interlv, pattern, timeout)
1705 SCSI *scgp;
1706 void *fmt;
1707 int length;
1708 int list_format; /* 0 if fmt == 0 */
1709 int dgdl; /* disable grown defect list */
1710 int interlv;
1711 int pattern;
1712 int timeout;
1713 {
1714 register struct scg_cmd *scmd = scgp->scmd;
1715
1716 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
1717 scmd->addr = (caddr_t)fmt;
1718 scmd->size = length;
1719 scmd->flags = SCG_DISRE_ENA;
1720 scmd->cdb_len = SC_G0_CDBLEN;
1721 scmd->sense_len = CCS_SENSE_LEN;
1722 if (timeout < 0)
1723 timeout = 24*3600; /* Kein Timeout XXX kann haengen */
1724 scmd->timeout = timeout;
1725 scmd->cdb.g0_cdb.cmd = 0x04; /* Format Unit */
1726 scmd->cdb.g0_cdb.lun = scg_lun(scgp);
1727 scmd->cdb.g0_cdb.high_addr = (fmt?FMTDAT:0)|(dgdl?CMPLST:0)|list_format;
1728 scmd->cdb.g0_cdb.mid_addr = pattern;
1729 scmd->cdb.g0_cdb.count = interlv;
1730
1731 #ifdef BD_DEBUG
1732 scg_prbytes(_("Format CDB: "), (u_char *)scmd->cdb.cmd_cdb, scmd->cdb_len);
1733
1734 /* if (scgp->verbose && fmt)*/
1735 scg_prbytes(_("Format Data:"), (u_char *)fmt, length);
1736 #endif
1737
1738 scgp->cmdname = "format unit";
1739
1740 return (scg_cmd(scgp));
1741 }
1742 #endif /* NEEDED */
1743
1744 LOCAL void
print_bd_info(scgp)1745 print_bd_info(scgp)
1746 SCSI *scgp;
1747 {
1748 Uchar mode[4096];
1749 int ret;
1750 int i;
1751
1752 if (lverbose > 2)
1753 printf(_("Entering BD info....\n"));
1754 /*
1755 * The ACARD TECH AEC-7720 ATAPI<->SCSI adaptor
1756 * chokes if we try to transfer odd byte counts (rounds up to
1757 * even byte counts and thus causes a DMA overflow and a
1758 * bus reset), so make the byte count even.
1759 * It also chokes if we try to transfer more than 0x40 bytes with
1760 * mode_sense of all pages. As we don't want to avoid this
1761 * command here, we need to wait until the drive recoveres
1762 * from the reset?? it receives after the adapter dies.
1763 */
1764 if (lverbose > 1)
1765 mode_sense(scgp, mode, 250, 0x3F, 0);
1766 if (lverbose > 2)
1767 scg_prbytes(_("Mode: "), mode, 250 - scg_getresid(scgp));
1768 wait_unit_ready(scgp, 120);
1769 if (lverbose > 1) {
1770 printf(_("Supported BD (readable) structures:"));
1771 scgp->silent++;
1772 for (i = 0; i <= 255; i++) {
1773 fillbytes((caddr_t)mode, sizeof (mode), '\0');
1774 ret = read_dvd_structure(scgp, (caddr_t)mode, sizeof (mode), 1, 0, 0, i);
1775 if (ret >= 0 && (sizeof (mode) - scg_getresid(scgp)) > 4)
1776 printf(" %02X", i);
1777 }
1778 scgp->silent--;
1779 printf("\n");
1780 /* printf("Page: %d ret: %d len: %d\n", i, ret, sizeof (mode) - scg_getresid(scgp));*/
1781 if (lverbose > 2)
1782 scg_prbytes(_("Page FF: "), mode, sizeof (mode) - scg_getresid(scgp));
1783 if (sizeof (mode) - scg_getresid(scgp) > 4) {
1784 int len = a_to_u_2_byte(mode) - 2;
1785 Uchar *p = &mode[4];
1786 int m;
1787
1788 len /= 4;
1789 for (i = 0; i < len; i++) {
1790 m = p[1] & 0xC0;
1791 printf(_("Page %02X %s (%02X) len %d\n"),
1792 *p & 0xFF,
1793 m == 0xC0 ?
1794 _("read/write") :
1795 (m == 0x80 ? _(" write") :
1796 (m == 0x40 ? _("read ") : _("unknown "))),
1797 p[1] & 0xFF,
1798 a_to_u_2_byte(&p[2]));
1799 p += 4;
1800 }
1801 }
1802 }
1803 wait_unit_ready(scgp, 120);
1804
1805 /*
1806 * Disk Information 0x00
1807 */
1808 fillbytes((caddr_t)mode, sizeof (mode), '\0');
1809 scgp->silent++;
1810 ret = read_dvd_structure(scgp, (caddr_t)mode, sizeof (mode), 1, 0, 0, 0);
1811 scgp->silent--;
1812 if (ret >= 0) {
1813 if (lverbose > 2) {
1814 scg_prbytes(_("BD structure[0]: "),
1815 mode, sizeof (mode) - scg_getresid(scgp));
1816 /* scg_prascii("BD structure[0]: ", mode, sizeof (mode) - scg_getresid(scgp));*/
1817 }
1818 print_bd00(mode);
1819 }
1820
1821 #ifdef DEBUG
1822 fillbytes((caddr_t)mode, sizeof (mode), '\0');
1823 scgp->silent++;
1824 ret = read_dvd_structure(scgp, (caddr_t)mode, sizeof (mode), 1, 0, 0, 0x09);
1825 scgp->silent--;
1826 if (ret >= 0) {
1827 if (lverbose > 2) {
1828 scg_prbytes(_("BD structure[0x09]: "),
1829 mode, sizeof (mode) - scg_getresid(scgp));
1830 scg_prascii(_("BD structure[0x09]: "), mode, sizeof (mode) - scg_getresid(scgp));
1831 }
1832 print_bd09(mode);
1833 }
1834 fillbytes((caddr_t)mode, sizeof (mode), '\0');
1835 scgp->silent++;
1836 ret = read_dvd_structure(scgp, (caddr_t)mode, sizeof (mode), 1, 0, 0, 0x0A);
1837 scgp->silent--;
1838 if (ret >= 0) {
1839 if (lverbose > 2) {
1840 scg_prbytes(_("BD structure[0x0A]: "),
1841 mode, sizeof (mode) - scg_getresid(scgp));
1842 scg_prascii(_("BD structure[0x0A]: "), mode, sizeof (mode) - scg_getresid(scgp));
1843 }
1844 print_bd0A(mode);
1845 }
1846 fillbytes((caddr_t)mode, sizeof (mode), '\0');
1847 scgp->silent++;
1848 ret = read_dvd_structure(scgp, (caddr_t)mode, sizeof (mode), 1, 0, 0, 0xC0);
1849 scgp->silent--;
1850 if (ret >= 0) {
1851 if (lverbose > 2) {
1852 scg_prbytes(_("BD structure[0xC0]: "),
1853 mode, sizeof (mode) - scg_getresid(scgp));
1854 scg_prascii(_("BD structure[0xC0]: "), mode, sizeof (mode) - scg_getresid(scgp));
1855 }
1856 }
1857 #endif
1858 }
1859
1860 LOCAL void
print_bd00(dp)1861 print_bd00(dp)
1862 Uchar *dp;
1863 {
1864 Uchar *bd = &((Uchar *)dp)[4];
1865 #ifdef BD_DEBUG
1866 int len = a_to_2_byte(dp)+2;
1867
1868 error("len %d\n", len);
1869 scg_prbytes("BD structure[0]: ", bd, 255);
1870 scg_prascii("BD structure[0]: ", bd, 255);
1871 printf("ID: '%.3s'\n", &bd[8]);
1872 printf("Disk size: %2.2X\n", bd[11]);
1873 scg_prbytes("Format dep content: ", &bd[12], 100);
1874 scg_prascii("Format dep content: ", &bd[12], 100);
1875 printf("Manufacturer: '%.6s'\n", &bd[12+88]);
1876 printf("Type: '%.3s'\n", &bd[12+94]);
1877 #endif
1878
1879 printf(_("Disk type: '%.3s' (BD-%s)\n"), &bd[8],
1880 bd[10] == 'O' ? "ROM":
1881 (bd[10] == 'R' ? "R" :
1882 (bd[10] == 'W' ? "RE": "???")));
1883 printf(_("Disk class: %2.2X\n"), bd[11]);
1884 printf(_("Manufacturer: '%.6s'\n"), &bd[12+88]);
1885 printf(_("Media type: '%.3s'\n"), &bd[12+94]);
1886
1887 }
1888
1889 LOCAL void
print_bd09(dp)1890 print_bd09(dp)
1891 Uchar *dp;
1892 {
1893 Uchar *bd = &((Uchar *)dp)[4];
1894 #ifdef BD_DEBUG
1895 int len = a_to_2_byte(dp)+2;
1896
1897 error("len %d\n", len);
1898 scg_prbytes("BD structure[09]: ", bd, len);
1899 scg_prascii("BD structure[09]: ", bd, len);
1900 #endif
1901
1902 printf(_("Disk: is %sin cartridge\n"),
1903 (bd[4] & 0x80) == 0 ? _("not "): "");
1904 if (bd[4] & 0x80) {
1905 printf(_("Disk: was %staken out of cartridge\n"),
1906 (bd[4] & 0x40) == 0 ? _("not "): "");
1907 }
1908 printf(_("Media cartrige: write protect is %s\n"),
1909 (bd[4] & 0x04) ? _("on"): _("off"));
1910 }
1911
1912 LOCAL void
print_bd0A(dp)1913 print_bd0A(dp)
1914 Uchar *dp;
1915 {
1916 #ifdef BD_DEBUG
1917 int len = a_to_2_byte(dp)+2;
1918 Uchar *bd = &((Uchar *)dp)[4];
1919
1920 error("len %d\n", len);
1921 scg_prbytes("BD structure[0A]: ", bd, len);
1922 scg_prascii("BD structure[0A]: ", bd, len);
1923 #endif
1924
1925 printf(_("Free Spare Blocks: %lu\n"), (unsigned long)
1926 a_to_4_byte(&dp[8]));
1927 printf(_("Alloc Spare Blocks: %lu\n"), (unsigned long)
1928 a_to_4_byte(&dp[12]));
1929 }
1930