1 /* @(#)drv_dvd.c 1.167 13/12/10 Copyright 1998-2013 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)drv_dvd.c 1.167 13/12/10 Copyright 1998-2013 J. Schilling";
6 #endif
7 /*
8 * DVD-R device implementation for
9 * SCSI-3/mmc-2 conforming drives
10 * Currently it only supports the Pioneer DVD-R S101
11 * as for the near future, there are no other drives.
12 *
13 * Check recovery - DUMMY
14 * Load Media - OK
15 * Get Disktype - Disk Status & Size (read ATIP -> DVD structure)
16 * Check Session ?? - Nicht vorhanden
17 * Check Disk size - Nach Status & size + Next wr. Addr.
18 * Set Speed/Dummy - Speed auf DVD -> dummy
19 * Open Session - Set Write Parameter & ??? -> DAO
20 * LOOP
21 * Open Track - Set Write Parameter ???
22 * Get Next wr. Addr. -> DUMMY "0" ???
23 * Write Track Data OK
24 * Close Track - Flush Cache -> DUMMY
25 * END
26 * Fixate - Close Track/Session -> Flush Cache
27 * Unload Media - OK
28 *
29 * Verbose levels:
30 * 0 silent
31 * 1 print laser log & track sizes
32 * 2 print disk info & write parameters
33 * 3 print log pages & dvd structure
34 *
35 * Copyright (c) 1998-2013 J. Schilling
36 */
37 /*
38 * The contents of this file are subject to the terms of the
39 * Common Development and Distribution License, Version 1.0 only
40 * (the "License"). You may not use this file except in compliance
41 * with the License.
42 *
43 * See the file CDDL.Schily.txt in this distribution for details.
44 * A copy of the CDDL is also available via the Internet at
45 * http://www.opensource.org/licenses/cddl1.txt
46 *
47 * When distributing Covered Code, include this CDDL HEADER in each
48 * file and include the License file CDDL.Schily.txt from this distribution.
49 */
50
51 #ifndef DEBUG
52 #define DEBUG
53 #endif
54 #include <schily/mconfig.h>
55
56 #include <schily/stdio.h>
57 #include <schily/stdlib.h>
58 #include <schily/unistd.h> /* Include sys/types.h to make off_t available */
59 #include <schily/standard.h>
60 #include <schily/string.h>
61
62 #include <schily/utypes.h>
63 #include <schily/btorder.h>
64 #include <schily/intcvt.h>
65 #include <schily/schily.h>
66 #include <schily/nlsdefs.h>
67
68 #include <scg/scgcmd.h>
69 #include <scg/scsidefs.h>
70 #include <scg/scsireg.h>
71 #include <scg/scsitransp.h>
72
73 #include "scsimmc.h"
74 #include "scsilog.h"
75 #include "mmcvendor.h"
76 #include "cdrecord.h"
77
78
79 extern char *driveropts;
80
81 extern int lverbose;
82 extern int xdebug;
83
84 #define strbeg(s1, s2) (strstr((s2), (s1)) == (s2))
85
86 LOCAL cdr_t *identify_dvd __PR((SCSI *scgp, cdr_t *, struct scsi_inquiry *));
87 LOCAL int attach_dvd __PR((SCSI *scgp, cdr_t *));
88 LOCAL void di_to_dstat __PR((struct disk_info *dip, dstat_t *dsp));
89 LOCAL int init_dvd __PR((SCSI *scgp, cdr_t *dp));
90 LOCAL int getdisktype_dvd __PR((SCSI *scgp, cdr_t *dp));
91 LOCAL int prdiskstatus_dvd __PR((SCSI *scgp, cdr_t *dp));
92 LOCAL int speed_select_dvd __PR((SCSI *scgp, cdr_t *dp, int *speedp));
93 LOCAL int session_offset_dvd __PR((SCSI *scgp, long *offp));
94 LOCAL int next_wr_addr_dvd __PR((SCSI *scgp, track_t *trackp, long *ap));
95 LOCAL int open_track_dvd __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
96 LOCAL long rzone_size __PR((track_t *trackp));
97 LOCAL int close_track_dvd __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
98 LOCAL int open_session_dvd __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
99 LOCAL int waitformat __PR((SCSI *scgp, int secs));
100 LOCAL int fixate_dvd __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
101 LOCAL int blank_dvd __PR((SCSI *scgp, cdr_t *dp, long addr, int blanktype));
102 LOCAL int stats_dvd __PR((SCSI *scgp, cdr_t *dp));
103 #ifdef __needed__
104 LOCAL int read_rzone_info __PR((SCSI *scgp, caddr_t bp, int cnt));
105 LOCAL int reserve_rzone __PR((SCSI *scgp, long size));
106 #endif
107 /*LOCAL int send_dvd_structure __PR((SCSI *scgp, caddr_t bp, int cnt));*/
108 #ifdef __needed__
109 LOCAL int set_layerbreak __PR((SCSI *scgp, long tsize, Int32_t lbreak));
110 #endif
111 LOCAL void print_dvd00 __PR((struct dvd_structure_00 *dp));
112 LOCAL void print_dvd01 __PR((struct dvd_structure_01 *dp));
113 LOCAL void print_dvd04 __PR((struct dvd_structure_04 *dp));
114 LOCAL void print_dvd05 __PR((struct dvd_structure_05 *dp));
115 LOCAL void print_dvd0D __PR((struct dvd_structure_0D *dp));
116 LOCAL void print_dvd0E __PR((struct dvd_structure_0E *dp));
117 LOCAL void print_dvd0F __PR((struct dvd_structure_0F *dp));
118 LOCAL void print_dvd20 __PR((struct dvd_structure_20 *dp));
119 LOCAL void print_dvd22 __PR((struct dvd_structure_22 *dp));
120 LOCAL void print_dvd23 __PR((struct dvd_structure_23 *dp));
121 #ifdef __needed__
122 LOCAL void send_dvd0F __PR((SCSI *scgp));
123 #endif
124 /*LOCAL void print_dvd_info __PR((SCSI *scgp));*/
125 EXPORT void print_dvd_info __PR((SCSI *scgp));
126 LOCAL void print_laserlog __PR((SCSI *scgp));
127
128 cdr_t cdr_dvd = {
129 0, 0, 0,
130 CDR_DVD|CDR_SWABAUDIO,
131 CDR2_NOCD,
132 CDR_CDRW_ALL,
133 WM_SAO,
134 1000, 1000,
135 "mmc_dvd",
136 "generic SCSI-3/mmc-2 DVD-R/DVD-RW/DVD-RAM driver",
137 0,
138 (dstat_t *)0,
139 identify_dvd,
140 attach_dvd,
141 init_dvd,
142 getdisktype_dvd,
143 prdiskstatus_dvd,
144 scsi_load,
145 scsi_unload,
146 read_buff_cap,
147 cmd_dummy, /* recovery_needed */
148 (int(*)__PR((SCSI *, cdr_t *, int)))cmd_dummy, /* recover */
149 speed_select_dvd,
150 select_secsize,
151 next_wr_addr_dvd,
152 (int(*)__PR((SCSI *, Ulong)))cmd_ill, /* reserve_track */
153 scsi_cdr_write,
154 (int(*)__PR((track_t *, void *, BOOL)))cmd_dummy, /* gen_cue */
155 (int(*)__PR((SCSI *scgp, cdr_t *, track_t *)))cmd_dummy, /* send_cue */
156 (int(*)__PR((SCSI *, cdr_t *, track_t *)))cmd_dummy, /* leadin */
157 open_track_dvd,
158 close_track_dvd,
159 open_session_dvd,
160 cmd_dummy,
161 cmd_dummy, /* abort */
162 session_offset_dvd,
163 fixate_dvd,
164 stats_dvd,
165 blank_dvd,
166 format_dummy,
167 (int(*)__PR((SCSI *, caddr_t, int, int)))NULL, /* no OPC */
168 cmd_dummy, /* opt1 */
169 cmd_dummy, /* opt2 */
170 };
171
172
173 LOCAL cdr_t *
identify_dvd(scgp,dp,ip)174 identify_dvd(scgp, dp, ip)
175 SCSI *scgp;
176 cdr_t *dp;
177 struct scsi_inquiry *ip;
178 {
179 BOOL dvd = FALSE; /* DVD writer */
180 Uchar mode[0x100];
181 struct cd_mode_page_2A *mp;
182 int profile;
183
184 if (ip->type != INQ_WORM && ip->type != INQ_ROMD)
185 return ((cdr_t *)0);
186
187 allow_atapi(scgp, TRUE); /* Try to switch to 10 byte mode cmds */
188
189 scgp->silent++;
190 mp = mmc_cap(scgp, mode); /* Get MMC capabilities */
191 scgp->silent--;
192 if (mp == NULL)
193 return (NULL); /* Pre SCSI-2/mmc drive */
194
195 /*
196 * At this point we know that we have a SCSI-3/mmc compliant drive.
197 * Unfortunately ATAPI drives violate the SCSI spec in returning
198 * a response data format of '1' which from the SCSI spec would
199 * tell us not to use the "PF" bit in mode select. As ATAPI drives
200 * require the "PF" bit to be set, we 'correct' the inquiry data.
201 *
202 * XXX xxx_identify() should not have any side_effects ??
203 */
204 if (ip->data_format < 2)
205 ip->data_format = 2;
206
207 dvd = mp->dvd_r_write; /* Mode page 0x2A DVD-R writer */
208
209 /*
210 * Be careful, Lite-ON drives are lying in mode page 0x2A.
211 * We need to check the MMC-3 profile list too.
212 */
213 profile = get_curprofile(scgp);
214 if (profile >= 0x11 && profile <= 0x19)
215 dvd = TRUE;
216
217 if (!dvd)
218 get_wproflist(scgp, NULL, &dvd, NULL, NULL);
219
220 if (!dvd) /* Any DVD- writer */
221 return (NULL);
222
223 return (dp);
224 }
225
226 LOCAL int
attach_dvd(scgp,dp)227 attach_dvd(scgp, dp)
228 SCSI *scgp;
229 cdr_t *dp;
230 {
231 Uchar mode[0x100];
232 struct cd_mode_page_2A *mp;
233 struct ricoh_mode_page_30 *rp = NULL;
234 Ulong xspeed;
235 Ulong mp2Aspeed;
236
237
238 allow_atapi(scgp, TRUE); /* Try to switch to 10 byte mode cmds */
239
240 scgp->silent++;
241 mp = mmc_cap(scgp, NULL); /* Get MMC capabilities in allocated mp */
242 scgp->silent--;
243 if (mp == NULL)
244 return (-1); /* Pre SCSI-3/mmc drive */
245
246 dp->cdr_cdcap = mp; /* Store MMC cap pointer */
247
248 /*
249 * XXX hier sollte drive max write speed & drive cur write speed
250 * XXX gesetzt werden.
251 */
252 dp->cdr_dstat->ds_dr_max_rspeed = a_to_u_2_byte(mp->max_read_speed)/1385;
253 if (dp->cdr_dstat->ds_dr_max_rspeed == 0)
254 dp->cdr_dstat->ds_dr_max_rspeed = 47;
255 dp->cdr_dstat->ds_dr_cur_rspeed = a_to_u_2_byte(mp->cur_read_speed)/1385;
256 if (dp->cdr_dstat->ds_dr_cur_rspeed == 0)
257 dp->cdr_dstat->ds_dr_cur_rspeed = 47;
258
259 dp->cdr_dstat->ds_dr_max_wspeed = a_to_u_2_byte(mp->max_write_speed)/1385;
260 if (mp->p_len >= 28)
261 dp->cdr_dstat->ds_dr_cur_wspeed = a_to_u_2_byte(mp->v3_cur_write_speed)/1385;
262 else
263 dp->cdr_dstat->ds_dr_cur_wspeed = a_to_u_2_byte(mp->cur_write_speed)/1385;
264
265 /*
266 * NEC drives incorrectly return CD speed values in mode page 2A.
267 * Try MMC3 get performance in hope that values closer to DVD speeds
268 * are always more correct than what is found in mode page 2A.
269 */
270 xspeed = 0;
271 scsi_get_perf_maxspeed(scgp, NULL, &xspeed, NULL);
272
273 mp2Aspeed = a_to_u_2_byte(mp->max_write_speed);
274
275 if (lverbose > 2) {
276 printf(_("max page 2A speed %lu (%lux), max perf speed %lu (%lux)\n"),
277 mp2Aspeed, mp2Aspeed/1385,
278 xspeed, xspeed/1385);
279 }
280
281 if ((is_cdspeed(mp2Aspeed) && !is_cdspeed(xspeed)) ||
282 (mp2Aspeed < 10000 && xspeed > 10000)) {
283 dp->cdr_dstat->ds_dr_max_wspeed = xspeed/1385;
284 xspeed = 0;
285 scsi_get_perf_curspeed(scgp, NULL, &xspeed, NULL);
286 if (xspeed > 0)
287 dp->cdr_dstat->ds_dr_cur_wspeed = xspeed / 1385;
288 }
289
290 if (dp->cdr_speedmax > dp->cdr_dstat->ds_dr_max_wspeed)
291 dp->cdr_speedmax = dp->cdr_dstat->ds_dr_max_wspeed;
292
293 if (dp->cdr_speeddef > dp->cdr_speedmax)
294 dp->cdr_speeddef = dp->cdr_speedmax;
295
296 rp = get_justlink_ricoh(scgp, mode);
297
298 if (mp->p_len >= 28)
299 dp->cdr_flags |= CDR_MMC3;
300 if (mp->p_len >= 24)
301 dp->cdr_flags |= CDR_MMC2;
302 dp->cdr_flags |= CDR_MMC;
303
304 if (mp->loading_type == LT_TRAY)
305 dp->cdr_flags |= CDR_TRAYLOAD;
306 else if (mp->loading_type == LT_CADDY)
307 dp->cdr_flags |= CDR_CADDYLOAD;
308
309 if (mp->BUF != 0)
310 dp->cdr_flags |= CDR_BURNFREE;
311
312 check_writemodes_mmc(scgp, dp);
313 /*
314 * To avoid that silly people try to call cdrecord will write modes
315 * that are illegal for DVDs, we clear anything that does now work.
316 */
317 dp->cdr_flags &= ~(CDR_RAW|CDR_RAW16|CDR_RAW96P|CDR_RAW96R|CDR_SRAW96P|CDR_SRAW96R);
318 dp->cdr_flags &= ~(CDR_TAO);
319
320 if (scgp->inq != NULL) {
321 if (strbeg("PIONEER", scgp->inq->inq_vendor_info)) {
322 if (strbeg("DVD-RW DVR-103", scgp->inq->inq_prod_ident) ||
323 strbeg("DVD-R DVD-R7322", scgp->inq->inq_prod_ident)) {
324 mp->BUF = 1;
325 }
326 }
327 }
328 if (mp->BUF != 0) {
329 dp->cdr_flags |= CDR_BURNFREE;
330 } else if (rp) {
331 if ((dp->cdr_cmdflags & F_DUMMY) && rp->TWBFS && rp->BUEFS)
332 dp->cdr_flags |= CDR_BURNFREE;
333
334 if (rp->BUEFS)
335 dp->cdr_flags |= CDR_BURNFREE;
336 }
337
338 if (rp && rp->AWSCS)
339 dp->cdr_flags |= CDR_FORCESPEED;
340
341
342 if ((dp->cdr_flags & (CDR_SAO)) != (CDR_SAO)) {
343 /*
344 * XXX Ist dies ueberhaupt noch notwendig seit wir nicht
345 * XXX mehr CDR_TAO vorgaukeln muessen?
346 *
347 * Das Panasonic DVD-R mag check_writemodes_mmc() nicht
348 * hilft das vielleicht?
349 */
350 dp->cdr_flags |= CDR_SAO;
351 }
352
353 if (driveropts != NULL) {
354 char *p;
355
356 if (strcmp(driveropts, "help") == 0) {
357 mmc_opthelp(scgp, dp, 0);
358 }
359
360 p = hasdrvopt(driveropts, "burnfree");
361 if (p == NULL)
362 p = hasdrvopt(driveropts, "burnproof");
363 if (p != NULL && (dp->cdr_flags & CDR_BURNFREE) != 0) {
364 if (*p == '1') {
365 dp->cdr_dstat->ds_cdrflags |= RF_BURNFREE;
366 } else if (*p == '0') {
367 dp->cdr_dstat->ds_cdrflags &= ~RF_BURNFREE;
368 }
369 }
370
371 p = hasdrvopt(driveropts, "forcespeed");
372 if (p != NULL && *p == '1' && (dp->cdr_flags & CDR_FORCESPEED) != 0) {
373 dp->cdr_dstat->ds_cdrflags |= RF_FORCESPEED;
374 }
375
376 p = hasdrvoptx(driveropts, "layerbreak", 0);
377 if (p != NULL && *p != '\0') {
378 char *ep;
379 Llong ll;
380 Int32_t lb;
381
382 ep = astoll(p, &ll);
383 lb = ll;
384 if ((*ep != '\0' && *ep != ',') ||
385 ll <= 0 || ll != lb) {
386 errmsgno(EX_BAD,
387 _("Bad layer break value '%s'.\n"), p);
388 return (-1);
389 }
390 dp->cdr_dstat->ds_layer_break = lb;
391 } else {
392 p = hasdrvopt(driveropts, "layerbreak");
393 if (p != NULL && *p == '1')
394 dp->cdr_dstat->ds_layer_break = 0;
395 }
396 if (dp->cdr_dstat->ds_layer_break >= 0 &&
397 (dp->cdr_flags & CDR_LAYER_JUMP) == 0) {
398 errmsgno(EX_BAD,
399 _("Cannot set layer break on this drive/medium.\n"));
400 return (-1);
401 }
402 if (dp->cdr_dstat->ds_layer_break != -1 &&
403 dp->cdr_dstat->ds_layer_break !=
404 roundup(dp->cdr_dstat->ds_layer_break, 16)) {
405 errmsgno(EX_BAD,
406 _("Layer break at %u is not properly aligned.\n"),
407 dp->cdr_dstat->ds_layer_break);
408 return (-1);
409 }
410 }
411
412 /*
413 * Raise the default timeout.
414 * The first write takes a long time as it writes the lead in.
415 */
416 if (scgp->deftimeout < 100)
417 scg_settimeout(scgp, 100); /* 1:40 */
418
419 return (0);
420 }
421
422 LOCAL void
di_to_dstat(dip,dsp)423 di_to_dstat(dip, dsp)
424 struct disk_info *dip;
425 dstat_t *dsp;
426 {
427 dsp->ds_diskid = a_to_u_4_byte(dip->disk_id);
428
429 dsp->ds_flags |= DSF_NOCD|DSF_DVD; /* This is a DVD */
430
431 if (dip->did_v)
432 dsp->ds_flags |= DSF_DID_V;
433 dsp->ds_disktype = dip->disk_type;
434 dsp->ds_diskstat = dip->disk_status;
435 dsp->ds_sessstat = dip->sess_status;
436 if (dip->erasable)
437 dsp->ds_flags |= DSF_ERA;
438
439 dsp->ds_trfirst = dip->first_track;
440 dsp->ds_trlast = dip->last_track_ls;
441 dsp->ds_trfirst_ls = dip->first_track_ls;
442
443 #ifdef nono
444 /*
445 * On DVD systems, there is no lead out start time
446 * in the disk info because there is no time based data.
447 */
448 dsp->ds_maxblocks = msf_to_lba(dip->last_lead_out[1],
449 dip->last_lead_out[2],
450 dip->last_lead_out[3], TRUE);
451 #endif
452 }
453
454 LOCAL int
init_dvd(scgp,dp)455 init_dvd(scgp, dp)
456 SCSI *scgp;
457 cdr_t *dp;
458 {
459 return (speed_select_dvd(scgp, dp, NULL));
460 }
461
462 LOCAL int
getdisktype_dvd(scgp,dp)463 getdisktype_dvd(scgp, dp)
464 SCSI *scgp;
465 cdr_t *dp;
466 {
467 extern char *buf;
468 dstat_t *dsp = dp->cdr_dstat;
469 struct disk_info *dip;
470 Uchar mode[0x100];
471 struct rzone_info rz;
472 struct rzone_info *rp;
473 struct dvd_structure_00 *sp;
474 int profile;
475 int len;
476 BOOL did_dummy = FALSE;
477
478 if (lverbose > 0)
479 print_laserlog(scgp);
480
481 if (lverbose > 2)
482 print_logpages(scgp);
483
484
485 if (dsp->ds_type == DST_UNKNOWN) {
486 profile = get_curprofile(scgp);
487 if (profile >= 0)
488 dsp->ds_type = profile;
489 }
490
491 if ((dp->cdr_dstat->ds_cdrflags & RF_PRATIP) != 0) {
492 if (((dsp->ds_cdrflags & (RF_WRITE|RF_BLANK)) == 0) ||
493 lverbose > 1) {
494 /*
495 * Das DVD Medieninfo ist so lang, da� wir es
496 * beim Schreiben mit -v noch nicht ausgeben.
497 */
498 print_dvd_info(scgp);
499 }
500 }
501
502 again:
503 dip = (struct disk_info *)buf;
504 if (get_diskinfo(scgp, dip, sizeof (*dip)) < 0)
505 return (-1);
506
507 /*
508 * Check for non writable disk first.
509 */
510 if (dip->disk_status == DS_COMPLETE &&
511 (dsp->ds_cdrflags & (RF_WRITE|RF_BLANK)) == RF_WRITE) {
512 if (!did_dummy) {
513 int xspeed = 0xFFFF;
514 int oflags = dp->cdr_cmdflags;
515
516 /*
517 * Try to clear the dummy bit to reset the virtual
518 * drive status. Not all drives support it even though
519 * it is mentioned in the MMC standard.
520 */
521 if (lverbose)
522 printf(_("Trying to clear drive status.\n"));
523
524 dp->cdr_cmdflags &= ~F_DUMMY;
525 speed_select_dvd(scgp, dp, &xspeed);
526 dp->cdr_cmdflags = oflags;
527 did_dummy = TRUE;
528 goto again;
529 }
530 /*
531 * Trying to clear drive status did not work...
532 */
533 reload_media(scgp, dp);
534 }
535 if (get_diskinfo(scgp, dip, sizeof (*dip)) < 0)
536 return (-1);
537 di_to_dstat(dip, dsp);
538
539 /*
540 * This information is based on a logical recording zone
541 * and may not always be correct.
542 * XXX Check this if we want to support anything else but
543 * XXX one data track on DAO mode. The current firmware
544 * XXX of the recorder supports only this method but future
545 * XXX releases may support more.
546 */
547 fillbytes((caddr_t)mode, sizeof (mode), '\0');
548 rp = (struct rzone_info *)mode;
549 read_rzone_info(scgp, (caddr_t)rp, sizeof (struct rzone_info));
550
551 if ((dp->cdr_dstat->ds_cdrflags & RF_PRATIP) != 0) {
552 if (((dsp->ds_cdrflags & (RF_WRITE|RF_BLANK)) == 0) ||
553 lverbose > 1) {
554 przone(rp);
555 print_format_capacities(scgp);
556 }
557 }
558 movebytes(mode, (caddr_t)&rz, sizeof (struct rzone_info));
559 #ifdef nonono_old_code
560 /*
561 * Old code used with the S101 seems to be a bad idea....
562 * The new code seems to work with all DVD drives.
563 */
564 dsp->ds_maxblocks = a_to_u_4_byte(rp->rzone_size);
565 if (dsp->ds_maxblocks == 0)
566 #endif
567 dsp->ds_maxblocks = a_to_u_4_byte(rp->free_blocks);
568 if (rp->nwa_v)
569 dsp->ds_maxblocks += a_to_u_4_byte(rp->next_recordable_addr);
570
571 /*
572 * This information is based on the physical pre recorded information.
573 * First try to find the len supported by the actual drive.
574 */
575 fillbytes((caddr_t)mode, sizeof (mode), '\0');
576 if (read_dvd_structure(scgp, (caddr_t)mode, 2, 0, 0, 0, 0) < 0) {
577 errmsgno(EX_BAD, _("Cannot read DVD structure.\n"));
578 return (-1);
579 }
580 len = a_to_u_2_byte(mode);
581 len += 2; /* Data len is not included */
582
583 if (len > sizeof (struct dvd_structure_00)) {
584 len = sizeof (struct dvd_structure_00);
585 /*
586 * The ACARD TECH AEC-7720 ATAPI<->SCSI adaptor
587 * chokes if we try to transfer odd byte counts (rounds up to
588 * even byte counts and thus causes a DMA overflow and a
589 * bus reset), so make the byte count even.
590 */
591 len += 1;
592 len &= ~1;
593 }
594 fillbytes((caddr_t)mode, sizeof (mode), '\0');
595 sp = (struct dvd_structure_00 *)mode;
596 read_dvd_structure(scgp, (caddr_t)sp, len, 0, 0, 0, 0);
597 /* if (lverbose > 1)*/
598 /* print_dvd00(sp);*/
599 if (((struct dvd_structure_00 *)sp)->book_type == 1) {
600 dsp->ds_type = DST_DVD_RAM;
601 } else {
602 dsp->ds_type = DST_UNKNOWN;
603 }
604 if (get_curprofile(scgp) == 0x12) {
605 dsp->ds_type = DST_DVD_RAM;
606 }
607 if (dsp->ds_type == DST_DVD_RAM)
608 dsp->ds_maxblocks = a_to_u_4_byte(rz.rzone_size);
609 /*
610 * Bei Pioneer ist Phys End ist nur bei dem S101 != 0.
611 * Bei Panasonic ist Phys End == Phys Start.
612 * Do not print this for -msinfo
613 */
614 if ((dp->cdr_cmdflags & F_MSINFO) == 0 &&
615 (a_to_u_3_byte(sp->phys_end) != 0) &&
616 (dsp->ds_maxblocks !=
617 (long)(a_to_u_3_byte(sp->phys_end) - a_to_u_3_byte(sp->phys_start) + 1))) {
618 /*
619 * NEC 'DVD_RW ND-3500AG' mit 'MCC 03RG20 ' DVD-R (leer):
620 * dsp->ds_maxblocks: 2298496
621 * sp->phys_start: 196608 (0x30000)
622 * sp->phys_end: 2495103
623 * 2298496 = 2495103 - 196608 +1
624 * Bei diesen Parametern gibt es keine Warnung.
625 */
626
627 printf(_("WARNING: Phys disk size %ld differs from rzone size %ld! Prerecorded disk?\n"),
628 (long)(a_to_u_3_byte(sp->phys_end) - a_to_u_3_byte(sp->phys_start) + 1),
629 (long)dsp->ds_maxblocks);
630 printf(_("WARNING: Phys start: %ld Phys end %ld\n"),
631 (long)a_to_u_3_byte(sp->phys_start),
632 (long)a_to_u_3_byte(sp->phys_end));
633
634 /*
635 * Workaround for some drive media combinations.
636 * At least the drive 'HL-DT-ST' 'DVD-RAM GH22NP20' '1.02'
637 * does not report maxblocks correctly with 'MCC 03RG20 ' media.
638 * Use the information from ADIP instead.
639 */
640 if (dsp->ds_maxblocks == 0) {
641 printf(_("WARNING: Drive returns zero media size. Using media size from ADIP.\n"));
642 dsp->ds_maxblocks = a_to_u_3_byte(sp->phys_end) - a_to_u_3_byte(sp->phys_start) + 1;
643 }
644 }
645
646 return (drive_getdisktype(scgp, dp));
647 }
648
649 LOCAL int
prdiskstatus_dvd(scgp,dp)650 prdiskstatus_dvd(scgp, dp)
651 SCSI *scgp;
652 cdr_t *dp;
653 {
654 return (prdiskstatus(scgp, dp, FALSE));
655 }
656
657 LOCAL int
speed_select_dvd(scgp,dp,speedp)658 speed_select_dvd(scgp, dp, speedp)
659 SCSI *scgp;
660 cdr_t *dp;
661 int *speedp;
662 {
663 Uchar mode[0x100];
664 Uchar moder[0x100];
665 int len;
666 struct cd_mode_page_05 *mp;
667 struct ricoh_mode_page_30 *rp = NULL;
668 int val;
669 Ulong ul;
670 BOOL forcespeed = FALSE;
671 BOOL dummy = (dp->cdr_cmdflags & F_DUMMY) != 0;
672 int curspeed = 1;
673
674
675 if (speedp)
676 curspeed = *speedp;
677
678 fillbytes((caddr_t)mode, sizeof (mode), '\0');
679
680 if (!get_mode_params(scgp, 0x05, _("CD write parameter"),
681 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len))
682 return (-1);
683 if (len == 0)
684 return (-1);
685
686 mp = (struct cd_mode_page_05 *)
687 (mode + sizeof (struct scsi_mode_header) +
688 ((struct scsi_mode_header *)mode)->blockdesc_len);
689 #ifdef DEBUG
690 if (lverbose > 1)
691 scg_prbytes(_("CD write parameter:"), (Uchar *)mode, len);
692 #endif
693
694 if (dp->cdr_dstat->ds_type == DST_DVD_RAM && dummy != 0) {
695 errmsgno(EX_BAD, _("DVD-RAM has no -dummy mode.\n"));
696 return (-1);
697 }
698
699 mp->test_write = dummy != 0;
700 /*
701 * Set default values:
702 * Write type = 02 (disk at once)
703 * Track mode = 00 Reserved on Pioneer DVR-S101
704 * Data block type = 00 Reserved on Pioneer DVR-S101
705 * Session format = 00 Reserved on Pioneer DVR-S101
706 * XXX DVR-S101 uses ls_v and link size violating
707 * XXX the current MMC2 spec.
708 */
709 mp->write_type = WT_SAO;
710 if (dp->cdr_dstat->ds_layer_break >= 0)
711 mp->write_type = WT_LAYER_JUMP;
712
713 #ifdef DEBUG
714 if (lverbose > 1)
715 scg_prbytes(_("CD write parameter:"), (Uchar *)mode, len);
716 #endif
717 if (!set_mode_params(scgp, _("CD write parameter"), mode, len, 0, -1))
718 return (-1);
719
720 /*
721 * Neither set nor get speed.
722 */
723 if (speedp == 0)
724 return (0);
725
726
727 rp = get_justlink_ricoh(scgp, moder);
728 if ((dp->cdr_flags & CDR_FORCESPEED) != 0) {
729 forcespeed = rp && rp->AWSCD != 0;
730 }
731
732 if (lverbose && (dp->cdr_flags & CDR_FORCESPEED) != 0)
733 printf(_("Forcespeed is %s.\n"), forcespeed?_("ON"):_("OFF"));
734
735 if (!forcespeed && (dp->cdr_dstat->ds_cdrflags & RF_FORCESPEED) != 0) {
736 printf(_("Turning forcespeed on\n"));
737 forcespeed = TRUE;
738 }
739 if (forcespeed && (dp->cdr_dstat->ds_cdrflags & RF_FORCESPEED) == 0) {
740 printf(_("Turning forcespeed off\n"));
741 forcespeed = FALSE;
742 }
743 if ((dp->cdr_flags & CDR_FORCESPEED) != 0) {
744
745 if (rp) {
746 rp->AWSCD = forcespeed?1:0;
747 set_mode_params(scgp, _("Ricoh Vendor Page"), moder, moder[0]+1, 0, -1);
748 rp = get_justlink_ricoh(scgp, moder);
749 }
750 }
751
752 /*
753 * DVD single speed is 1385 kB/s
754 * Rounding down is guaranteed.
755 */
756 val = curspeed*1390;
757 if (val > 0x7FFFFFFF)
758 val = 0x7FFFFFFF;
759 if (dp->cdr_flags & CDR_MMC3) {
760 if (speed_select_mdvd(scgp, -1, val) < 0)
761 errmsgno(EX_BAD, _("MMC-3 speed select did not work.\n"));
762 } else {
763 if (val > 0xFFFF)
764 val = 0xFFFF;
765 scgp->silent++;
766 if (scsi_set_speed(scgp, -1, val, ROTCTL_CLV) < 0) {
767 /*
768 * Don't complain if it does not work,
769 * DVD drives may not have speed setting.
770 * The DVR-S101 and the DVR-S201 difinitely
771 * don't allow to set the speed.
772 */
773 }
774 scgp->silent--;
775 }
776
777 scgp->silent++;
778 val = 0;
779 if (scsi_get_speed(scgp, 0, &val) >= 0) {
780 if (val > 0) {
781 curspeed = val / 1385;
782 *speedp = curspeed;
783 }
784 }
785 /*
786 * NEC drives incorrectly return CD speed values in mode page 2A.
787 * Try MMC3 get performance in hope that values closer to DVD speeds
788 * are always more correct than what is found in mode page 2A.
789 */
790 ul = 0;
791 if (scsi_get_perf_curspeed(scgp, NULL, &ul, NULL) >= 0) {
792 if (is_cdspeed(val) && !is_cdspeed(ul)) {
793 curspeed = ul / 1385;
794 *speedp = curspeed;
795 }
796 }
797
798 scgp->silent--;
799 return (0);
800 }
801
802 LOCAL int
session_offset_dvd(scgp,offp)803 session_offset_dvd(scgp, offp)
804 SCSI *scgp;
805 long *offp;
806 {
807 return (sessstatus(scgp, FALSE, offp, (long *)NULL));
808 }
809
810 LOCAL long dvd_next_addr;
811
812 LOCAL int
next_wr_addr_dvd(scgp,trackp,ap)813 next_wr_addr_dvd(scgp, trackp, ap)
814 SCSI *scgp;
815 track_t *trackp;
816 long *ap;
817 {
818 struct disk_info di;
819 struct rzone_info rz;
820 int tracks;
821 long next_addr = -1;
822
823 /*
824 * If the track pointer is set to NULL, our caller likes to get
825 * the next writable address for the next (unwritten) session.
826 */
827 if (trackp == 0) {
828 fillbytes((caddr_t)&di, sizeof (di), '\0');
829 if (get_diskinfo(scgp, &di, sizeof (di)) < 0)
830 return (-1);
831
832 tracks = di.last_track_ls + di.last_track_ls_msb * 256;
833 fillbytes((caddr_t)&rz, sizeof (rz), '\0');
834 if (get_trackinfo(scgp, (caddr_t)&rz, TI_TYPE_TRACK, tracks, sizeof (rz)) < 0)
835 return (-1);
836 if (!rz.nwa_v)
837 return (-1);
838 next_addr = a_to_4_byte(rz.next_recordable_addr);
839 if (ap)
840 *ap = next_addr;
841 return (0);
842 }
843 if (trackp->track <= 1) {
844 /*
845 * XXX This is a workaround for the filesize > 2GB problem.
846 * XXX Check this if we support more than one track DAO
847 * XXX or if we give up this hack in favour of real 64bit
848 * XXX filesize support.
849 */
850 fillbytes((caddr_t)&rz, sizeof (rz), '\0');
851 if (track_base(trackp)->tracktype & TOCF_MULTI)
852 get_trackinfo(scgp, (caddr_t)&rz, TI_TYPE_TRACK, trackp->trackno, sizeof (rz));
853 else
854 read_rzone_info(scgp, (caddr_t)&rz, sizeof (struct rzone_info));
855 dvd_next_addr = a_to_4_byte(rz.next_recordable_addr);
856 if (lverbose > 1)
857 printf(_("next writable addr: %ld valid: %d\n"), dvd_next_addr, rz.nwa_v);
858 }
859 if (ap)
860 *ap = dvd_next_addr;
861 return (0);
862 }
863
864 LOCAL int
open_track_dvd(scgp,dp,trackp)865 open_track_dvd(scgp, dp, trackp)
866 SCSI *scgp;
867 cdr_t *dp;
868 track_t *trackp;
869 {
870 Uchar mode[0x100];
871 int len;
872 long sectors;
873 struct cd_mode_page_05 *mp;
874
875 if (trackp->track > 1) /* XXX Hack to make one 'track' from several */
876 return (0); /* XXX files in Disk at once mode only. */
877
878 if (dp->cdr_dstat->ds_type == DST_DVD_RAM) {
879 /*
880 * Compile vitual track list
881 */
882 sectors = rzone_size(trackp);
883 if (sectors < 0)
884 return (-1);
885 return (0); /* No further setup needed */
886 }
887
888 fillbytes((caddr_t)mode, sizeof (mode), '\0');
889
890 if (!get_mode_params(scgp, 0x05, _("CD write parameter"),
891 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len))
892 return (-1);
893 if (len == 0)
894 return (-1);
895
896 mp = (struct cd_mode_page_05 *)
897 (mode + sizeof (struct scsi_mode_header) +
898 ((struct scsi_mode_header *)mode)->blockdesc_len);
899
900 /*
901 * XXX as long as the Pioneer DVR-S101 only supports a single
902 * XXX data track in DAO mode,
903 * XXX do not set:
904 * XXX track_mode
905 * XXX copy
906 * XXX dbtype
907 *
908 * Track mode = 00 Reserved on Pioneer DVR-S101
909 * Data block type = 00 Reserved on Pioneer DVR-S101
910 * Session format = 00 Reserved on Pioneer DVR-S101
911 * XXX DVR-S101 uses ls_v and link size violating
912 * XXX the current MMC2 spec.
913 */
914 /* XXX look into drv_mmc.c for re-integration of above settings */
915
916 #ifdef DEBUG
917 if (lverbose > 1)
918 scg_prbytes(_("CD write parameter:"), (Uchar *)mode, len);
919 #endif
920 if (!set_mode_params(scgp, _("CD write parameter"), mode, len, 0, trackp->secsize))
921 return (-1);
922
923 /*
924 * Compile vitual track list
925 */
926 sectors = rzone_size(trackp);
927 if (sectors < 0)
928 return (-1);
929 return (reserve_tr_rzone(scgp, sectors));
930 }
931
932 /*
933 * XXX Hack to make one 'track' from several
934 * XXX files in Disk at once mode only.
935 * XXX Calculate track size and reserve rzone.
936 */
937 LOCAL long
rzone_size(trackp)938 rzone_size(trackp)
939 track_t *trackp; /* Called with &track[1] */
940 {
941 int i;
942 BOOL vtracks = FALSE;
943 long sectors = 0L;
944 Llong ttrsize = 0L;
945 Llong tamount = 0L;
946 Llong amount;
947 long secsize = trackp->secsize;
948
949 for (i = 0; i < MAX_TRACK; i++) {
950 if (is_last(&trackp[i]))
951 break;
952 }
953 if (i >= 1)
954 vtracks = TRUE;
955 if (vtracks && lverbose)
956 printf(_("Compiling virtual track list ...\n"));
957
958 for (i = 0; i < MAX_TRACK; i++) {
959 if (trackp[i].tracksize < (tsize_t)0) {
960 errmsgno(EX_BAD, _("VTrack %d has unknown length.\n"), i);
961 return (-1);
962 }
963 amount = roundup(trackp[i].tracksize, secsize);
964 amount += (Llong)trackp[i].padsecs * secsize;
965 sectors += amount/secsize;
966 ttrsize += trackp[i].tracksize;
967 tamount += amount;
968 if (vtracks && lverbose)
969 printf(_("Vtrack: %d size: %lld bytes %lld rounded (%lld sectors)\n"),
970 (int)trackp[i].track, (Llong)trackp[i].tracksize,
971 amount, amount / (Llong)secsize);
972
973 if (is_last(&trackp[i]))
974 break;
975
976 /*
977 * XXX Is it possible for a DVD that input sector size
978 * XXX differes from output sector size?
979 * XXX I believe that not.
980 */
981 if (trackp[i].tracksize % secsize) {
982 comerrno(EX_BAD, _("Virtual track %d is not a multiple of secsize.\n"), (int)trackp[i].track);
983 }
984 }
985
986 if (vtracks && lverbose)
987 printf(_("Vtracks: %d size: %lld bytes %lld rounded (%ld sectors) total\n"),
988 i+1, ttrsize, tamount, sectors);
989
990 return (sectors);
991 }
992
993 LOCAL int
close_track_dvd(scgp,dp,trackp)994 close_track_dvd(scgp, dp, trackp)
995 SCSI *scgp;
996 cdr_t *dp;
997 track_t *trackp;
998 {
999 long sectors = 0L;
1000 Llong amount;
1001 long secsize = trackp->secsize;
1002
1003 /*
1004 * Compute the start of the next "track" for the hack
1005 * that allows to have a track in more than one file.
1006 * XXX Check this if the vtrack code is removed.
1007 */
1008 amount = roundup(trackp->tracksize, secsize);
1009 amount += (Llong)trackp->padsecs * secsize;
1010 sectors += amount/secsize;
1011
1012 dvd_next_addr += sectors;
1013
1014 return (0);
1015 }
1016
1017 LOCAL int
open_session_dvd(scgp,dp,trackp)1018 open_session_dvd(scgp, dp, trackp)
1019 SCSI *scgp;
1020 cdr_t *dp;
1021 track_t *trackp;
1022 {
1023 Uchar mode[0x100];
1024 Uchar moder[0x100];
1025 int len;
1026 struct cd_mode_page_05 *mp;
1027 struct ricoh_mode_page_30 *rp = NULL;
1028 BOOL burnfree = FALSE;
1029
1030 fillbytes((caddr_t)mode, sizeof (mode), '\0');
1031
1032 if (!get_mode_params(scgp, 0x05, _("CD write parameter"),
1033 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len))
1034 return (-1);
1035 if (len == 0)
1036 return (-1);
1037
1038 mp = (struct cd_mode_page_05 *)
1039 (mode + sizeof (struct scsi_mode_header) +
1040 ((struct scsi_mode_header *)mode)->blockdesc_len);
1041
1042 /*
1043 * XXX as long as the Pioneer DVR-S101 only supports a single
1044 * XXX data track in DAO mode,
1045 * XXX do not set:
1046 * XXX multi_session
1047 * XXX sessipon_format
1048 *
1049 * Track mode = 00 Reserved on Pioneer DVR-S101
1050 * Data block type = 00 Reserved on Pioneer DVR-S101
1051 * Session format = 00 Reserved on Pioneer DVR-S101
1052 * XXX DVR-S101 uses ls_v and link size violating
1053 * XXX the current MMC2 spec.
1054 */
1055 /* XXX look into drv_mmc.c for re-integration of above settings */
1056 mp->write_type = WT_SAO;
1057 if (dp->cdr_dstat->ds_layer_break >= 0)
1058 mp->write_type = WT_LAYER_JUMP;
1059
1060
1061 rp = get_justlink_ricoh(scgp, moder);
1062
1063 if (dp->cdr_cdcap->BUF != 0) {
1064 burnfree = mp->BUFE != 0;
1065 } else if ((dp->cdr_flags & CDR_BURNFREE) != 0) {
1066 burnfree = rp && rp->BUEFE != 0;
1067 }
1068
1069 if (lverbose && (dp->cdr_flags & CDR_BURNFREE) != 0)
1070 printf(_("BURN-Free is %s.\n"), burnfree?_("ON"):_("OFF"));
1071
1072 if (!burnfree && (dp->cdr_dstat->ds_cdrflags & RF_BURNFREE) != 0) {
1073 printf(_("Turning BURN-Free on\n"));
1074 burnfree = TRUE;
1075 }
1076 if (burnfree && (dp->cdr_dstat->ds_cdrflags & RF_BURNFREE) == 0) {
1077 printf(_("Turning BURN-Free off\n"));
1078 burnfree = FALSE;
1079 }
1080 if (dp->cdr_cdcap->BUF != 0) {
1081 mp->BUFE = burnfree?1:0;
1082 } else if ((dp->cdr_flags & CDR_BURNFREE) != 0) {
1083
1084 if (rp)
1085 rp->BUEFE = burnfree?1:0;
1086 }
1087 if (rp) {
1088 i_to_2_byte(rp->link_counter, 0);
1089 if (xdebug)
1090 scg_prbytes(_("Mode Select Data "), moder, moder[0]+1);
1091
1092 set_mode_params(scgp, _("Ricoh Vendor Page"), moder, moder[0]+1, 0, -1);
1093 rp = get_justlink_ricoh(scgp, moder);
1094 }
1095
1096 /*
1097 * 05 32 40 c5 08 10 00 00
1098 * FUFE + PACKET
1099 * MULTI + NO FP + TM_DATA
1100 * DB_ROM_MODE1
1101 * LINKSIZE == 16
1102 * mp->session_format SES_DA_ROM
1103 */
1104 mp->multi_session = (track_base(trackp)->tracktype & TOCF_MULTI) ?
1105 MS_MULTI : MS_NONE;
1106
1107 /*
1108 * If we are writing in multi-border mode, we need to write in packet
1109 * mode even if we have been told to write on SAO mode.
1110 */
1111 if (track_base(trackp)->tracktype & TOCF_MULTI) {
1112 mp->write_type = WT_PACKET;
1113 mp->track_mode = TM_DATA;
1114 mp->track_mode |= TM_INCREMENTAL;
1115 mp->fp = 0;
1116 i_to_4_byte(mp->packet_size, 0);
1117 mp->link_size = 16;
1118 }
1119
1120 #ifdef DEBUG
1121 if (lverbose > 1)
1122 scg_prbytes(_("CD write parameter:"), (Uchar *)mode, len);
1123 #endif
1124 if (!set_mode_params(scgp, _("CD write parameter"), mode, len, 0, -1))
1125 return (-1);
1126
1127 return (0);
1128 }
1129
1130 LOCAL int
waitformat(scgp,secs)1131 waitformat(scgp, secs)
1132 SCSI *scgp;
1133 int secs;
1134 {
1135 #ifdef DVD_DEBUG
1136 Uchar sensebuf[CCS_SENSE_LEN];
1137 #endif
1138 int i;
1139 int key;
1140 #define W_SLEEP 2
1141
1142 scgp->silent++;
1143 for (i = 0; i < secs/W_SLEEP; i++) {
1144 if (test_unit_ready(scgp) >= 0) {
1145 scgp->silent--;
1146 return (0);
1147 }
1148 key = scg_sense_key(scgp);
1149 if (key != SC_UNIT_ATTENTION && key != SC_NOT_READY)
1150 break;
1151 #ifdef DVD_DEBUG
1152 request_sense_b(scgp, (caddr_t)sensebuf, sizeof (sensebuf));
1153 #ifdef XXX
1154 scg_prbytes(_("Sense:"), sensebuf, sizeof (sensebuf));
1155 scgp->scmd->u_scb.cmd_scb[0] = 2;
1156 movebytes(sensebuf, scgp->scmd->u_sense.cmd_sense, sizeof (sensebuf));
1157 scgp->scmd->sense_count = sizeof (sensebuf);
1158 scg_printerr(scgp);
1159 #endif
1160 /*
1161 * status: 0x2 (CHECK CONDITION)
1162 * Sense Bytes: F0 00 00 00 24 1C 10 0C 00 00 00 00 04 04 00 80 03 F6
1163 * Sense Key: 0x0 No Additional Sense, Segment 0
1164 * Sense Code: 0x04 Qual 0x04 (logical unit not ready, format in progress) Fru 0x0
1165 * Sense flags: Blk 2366480 (valid)
1166 * cmd finished after 0.000s timeout 100s
1167 * Das Fehlt:
1168 * operation 1% done
1169 */
1170
1171 if (sensebuf[15] & 0x80) {
1172 error(_("operation %d%% done\n"),
1173 (100*(sensebuf[16] << 8 |
1174 sensebuf[17]))/(unsigned)65536);
1175 }
1176 #endif /* DVD_DEBUG */
1177 sleep(W_SLEEP);
1178 }
1179 scgp->silent--;
1180 return (-1);
1181 #undef W_SLEEP
1182 }
1183
1184 LOCAL int
fixate_dvd(scgp,dp,trackp)1185 fixate_dvd(scgp, dp, trackp)
1186 SCSI *scgp;
1187 cdr_t *dp;
1188 track_t *trackp;
1189 {
1190 int oldtimeout = scgp->deftimeout;
1191 int ret = 0;
1192 int trackno;
1193
1194 /*
1195 * This is only valid for DAO recording.
1196 * XXX Check this if the DVR-S101 supports more.
1197 * XXX flush cache currently makes sure that
1198 * XXX at least ~ 800 MBytes written to the track.
1199 * XXX flush cache triggers writing the lead out.
1200 */
1201 if (scgp->deftimeout < 1000)
1202 scg_settimeout(scgp, 1000);
1203
1204 if (scsi_flush_cache(scgp, FALSE) < 0) {
1205 printf(_("Trouble flushing the cache\n"));
1206 scg_settimeout(scgp, oldtimeout);
1207 return (-1);
1208 }
1209 waitformat(scgp, 100);
1210 trackno = trackp->trackno;
1211 if (trackno <= 0)
1212 trackno = 1;
1213
1214 scg_settimeout(scgp, oldtimeout);
1215
1216 if (dp->cdr_dstat->ds_type == DST_DVD_RAM) {
1217 /*
1218 * XXX make sure we do not forget DVD-RAM once we did add
1219 * XXX support for multi-border recording.
1220 */
1221 return (ret);
1222 }
1223 if (track_base(trackp)->tracktype & TOCF_MULTI)
1224 scsi_close_tr_session(scgp, CL_TYPE_SESSION, trackno, TRUE);
1225
1226 return (ret);
1227 }
1228
1229 LOCAL int
blank_dvd(scgp,dp,addr,blanktype)1230 blank_dvd(scgp, dp, addr, blanktype)
1231 SCSI *scgp;
1232 cdr_t *dp;
1233 long addr;
1234 int blanktype;
1235 {
1236 /*XXX*/extern char *blank_types[];
1237
1238 BOOL cdrr = FALSE; /* Read CD-R */
1239 BOOL cdwr = FALSE; /* Write CD-R */
1240 BOOL cdrrw = FALSE; /* Read CD-RW */
1241 BOOL cdwrw = FALSE; /* Write CD-RW */
1242 BOOL dvdwr = FALSE; /* DVD writer */
1243 int profile;
1244
1245 mmc_check(scgp, &cdrr, &cdwr, &cdrrw, &cdwrw, NULL, &dvdwr);
1246 /*
1247 * If the drive supports MMC-3, check for a DVD-RW medium.
1248 */
1249 profile = get_curprofile(scgp);
1250 if (profile > 0)
1251 dvdwr = (profile == 0x13) || (profile == 0x14) ||
1252 (profile == 0x17);
1253
1254 if (profile == 0x12) /* DVD-RAM */
1255 return (blank_simul(scgp, dp, addr, blanktype));
1256
1257 if (!dvdwr)
1258 return (blank_dummy(scgp, dp, addr, blanktype));
1259
1260 if (lverbose) {
1261 printf(_("Blanking %s\n"), blank_types[blanktype & 0x07]);
1262 flush();
1263 }
1264
1265 return (scsi_blank(scgp, addr, blanktype, FALSE));
1266 }
1267
1268 LOCAL int
stats_dvd(scgp,dp)1269 stats_dvd(scgp, dp)
1270 SCSI *scgp;
1271 cdr_t *dp;
1272 {
1273 Uchar mode[256];
1274 struct ricoh_mode_page_30 *rp;
1275 UInt32_t count;
1276
1277 if ((dp->cdr_dstat->ds_cdrflags & RF_BURNFREE) == 0)
1278 return (0);
1279
1280 rp = get_justlink_ricoh(scgp, mode);
1281 if (rp) {
1282 count = a_to_u_2_byte(rp->link_counter);
1283 if (lverbose) {
1284 if (count == 0)
1285 printf(_("BURN-Free was not used.\n"));
1286 else
1287 printf(_("BURN-Free was %d times used.\n"),
1288 (int)count);
1289 }
1290 }
1291 return (0);
1292 }
1293
1294 #ifdef __needed__
1295 LOCAL int
read_rzone_info(scgp,bp,cnt)1296 read_rzone_info(scgp, bp, cnt)
1297 SCSI *scgp;
1298 caddr_t bp;
1299 int cnt;
1300 {
1301 register struct scg_cmd *scmd = scgp->scmd;
1302
1303 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
1304 scmd->addr = bp;
1305 scmd->size = cnt;
1306 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
1307 scmd->cdb_len = SC_G1_CDBLEN;
1308 scmd->sense_len = CCS_SENSE_LEN;
1309 scmd->cdb.g1_cdb.cmd = 0x52;
1310 scmd->cdb.g1_cdb.lun = scg_lun(scgp);
1311 /* g1_cdbaddr(&scmd->cdb.g1_cdb, addr);*/
1312 g1_cdblen(&scmd->cdb.g1_cdb, cnt);
1313
1314 scgp->cmdname = "read rzone info";
1315
1316 if (scg_cmd(scgp) < 0)
1317 return (-1);
1318 return (0);
1319 }
1320
1321 LOCAL int
reserve_rzone(scgp,size)1322 reserve_rzone(scgp, size)
1323 SCSI *scgp;
1324 long size; /* number of blocks */
1325 {
1326 register struct scg_cmd *scmd = scgp->scmd;
1327
1328 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
1329 scmd->addr = (caddr_t)0;
1330 scmd->size = 0;
1331 scmd->flags = SCG_DISRE_ENA|SCG_CMD_RETRY;
1332 scmd->cdb_len = SC_G1_CDBLEN;
1333 scmd->sense_len = CCS_SENSE_LEN;
1334 scmd->cdb.g1_cdb.cmd = 0x53;
1335 scmd->cdb.g1_cdb.lun = scg_lun(scgp);
1336
1337 i_to_4_byte(&scmd->cdb.g1_cdb.addr[3], size);
1338
1339 scgp->cmdname = "reserve_rzone";
1340
1341 if (scg_cmd(scgp) < 0)
1342 return (-1);
1343 return (0);
1344 }
1345 #endif
1346
1347 #ifdef _is_this_pioneer_vendor_unique_
1348 LOCAL int
send_dvd_structure(scgp,bp,cnt)1349 send_dvd_structure(scgp, bp, cnt)
1350 SCSI *scgp;
1351 caddr_t bp;
1352 int cnt;
1353 {
1354 register struct scg_cmd *scmd = scgp->scmd;
1355
1356 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
1357 scmd->addr = bp;
1358 scmd->size = cnt;
1359 scmd->flags = SCG_DISRE_ENA;
1360 scmd->cdb_len = SC_G5_CDBLEN;
1361 scmd->sense_len = CCS_SENSE_LEN;
1362 scmd->timeout = 4 * 60; /* Needs up to 2 minutes ??? */
1363 scmd->cdb.g5_cdb.cmd = 0xFB;
1364 scmd->cdb.g5_cdb.lun = scg_lun(scgp);
1365 g5_cdblen(&scmd->cdb.g5_cdb, cnt);
1366
1367 scgp->cmdname = "read dvd structure";
1368
1369 if (scg_cmd(scgp) < 0)
1370 return (-1);
1371 return (0);
1372 }
1373 #endif
1374
1375 #ifdef __needed__
1376 LOCAL int
set_layerbreak(scgp,tsize,lbreak)1377 set_layerbreak(scgp, tsize, lbreak)
1378 SCSI *scgp;
1379 long tsize;
1380 Int32_t lbreak;
1381 {
1382 #ifdef USE_STRUC_22
1383 struct dvd_structure_22 jz;
1384 #endif
1385 struct dvd_structure_23 lb;
1386 int ret;
1387 UInt32_t dsize;
1388 #ifdef USE_STRUC_22
1389 UInt32_t jump_size;
1390 #endif
1391 UInt32_t jump_lba;
1392
1393 #ifdef USE_STRUC_22
1394 /*
1395 * Jump interval size 0x22
1396 */
1397 fillbytes((caddr_t)&jz, sizeof (jz), '\0');
1398 ret = read_dvd_structure(scgp, (caddr_t)&jz, sizeof (jz), 0, 0, 0, 0x22);
1399 if (ret < 0)
1400 return (ret);
1401
1402 jump_size = a_to_u_4_byte(jz.jump_interval_size);
1403
1404 if (jump_size != 0) {
1405
1406 #ifdef AAAA
1407 dsize = roundup(tsize, 16);
1408 jump_lba = dsize / 2;
1409 jump_lba = roundup(jump_lba, 16);
1410 /* jump_lba -= 1;*/
1411 error("jump lba %d\n", jump_lba);
1412 i_to_4_byte(lb.jump_lba, jump_lba);
1413 #else
1414 i_to_4_byte(jz.jump_interval_size, 0);
1415 #endif
1416 ret = send_dvd_structure(scgp, (caddr_t)&jz, sizeof (jz), 0x22);
1417 if (ret < 0)
1418 return (ret);
1419 }
1420 #endif /* USE_STRUC_22 */
1421
1422 /*
1423 * Jump logical block address 0x23
1424 */
1425 fillbytes((caddr_t)&lb, sizeof (lb), '\0');
1426 ret = read_dvd_structure(scgp, (caddr_t)&lb, sizeof (lb), 0, 0, 0, 0x23);
1427 if (ret < 0)
1428 return (ret);
1429
1430 jump_lba = a_to_u_4_byte(lb.jump_lba);
1431 if (lbreak > 0 && lbreak > jump_lba) {
1432 errmsgno(EX_BAD, _("Manual layer break %d > %u not allowed.\n"),
1433 lbreak, jump_lba);
1434 return (-1);
1435 }
1436 dsize = roundup(tsize, 16);
1437 if (lbreak <= 0 && dsize <= (jump_lba+1)) {
1438 /*
1439 * Allow to write DL media with less than single layer size
1440 * in case of manual layer break set up.
1441 */
1442 errmsgno(EX_BAD,
1443 _("Layer 0 size %u is bigger than expected disk size %u.\n"),
1444 (jump_lba+1), dsize);
1445 errmsgno(EX_BAD, _("Use single layer medium.\n"));
1446 return (-1);
1447 }
1448 jump_lba = dsize / 2;
1449 jump_lba = roundup(jump_lba, 16);
1450 if (lbreak > 0 && lbreak < jump_lba) {
1451 errmsgno(EX_BAD, _("Manual layer break %d < %u not allowed.\n"),
1452 lbreak, jump_lba);
1453 return (-1);
1454 }
1455 if (lbreak > 0)
1456 jump_lba = lbreak;
1457 jump_lba -= 1;
1458 i_to_4_byte(lb.jump_lba, jump_lba);
1459
1460 ret = send_dvd_structure(scgp, (caddr_t)&lb, sizeof (lb), 0x23);
1461 return (ret);
1462 }
1463 #endif
1464
1465 LOCAL char ill_booktype[] = "reserved book type";
1466 char *book_types[] = {
1467 "DVD-ROM",
1468 "DVD-RAM",
1469 "DVD-R",
1470 "DVD-RW",
1471 "HD DVD-ROM",
1472 "HD DVD-RAM",
1473 "HD DVD-R",
1474 ill_booktype,
1475 ill_booktype,
1476 "DVD+RW",
1477 "DVD+R",
1478 ill_booktype,
1479 ill_booktype,
1480 "DVD+RW/DL",
1481 "DVD+R/DL",
1482 ill_booktype,
1483 };
1484
1485 LOCAL char res_bvers[] = "reserved book version";
1486 LOCAL char *R_vers[] = {
1487 "0.9x",
1488 "1.0x",
1489 "1.1x",
1490 res_bvers,
1491 "1.9x",
1492 "2.0x",
1493 "> 2.0x",
1494 res_bvers,
1495 res_bvers,
1496 res_bvers,
1497 res_bvers,
1498 res_bvers,
1499 res_bvers,
1500 res_bvers,
1501 res_bvers,
1502 res_bvers,
1503 };
1504
1505 LOCAL char *RW_vers[] = {
1506 "0.9x",
1507 "1.0x",
1508 "1.1x",
1509 "> 1.1x",
1510 res_bvers,
1511 res_bvers,
1512 res_bvers,
1513 res_bvers,
1514 res_bvers,
1515 res_bvers,
1516 res_bvers,
1517 res_bvers,
1518 res_bvers,
1519 res_bvers,
1520 res_bvers,
1521 res_bvers,
1522 };
1523
1524 LOCAL char ill_dsize[] = "illegal size";
1525 char *disc_sizes[] = {
1526 "120mm",
1527 "80mm",
1528 ill_dsize,
1529 ill_dsize,
1530 ill_dsize,
1531 ill_dsize,
1532 ill_dsize,
1533 ill_dsize,
1534 ill_dsize,
1535 ill_dsize,
1536 ill_dsize,
1537 ill_dsize,
1538 ill_dsize,
1539 ill_dsize,
1540 ill_dsize,
1541 ill_dsize,
1542 };
1543
1544 LOCAL char ill_rate[] = "illegal rate";
1545 char *tr_rates[] = {
1546 "2.52 MB/s",
1547 "5.04 MB/s",
1548 "10.08 MB/s",
1549 "20.16 MB/s",
1550 "30.24 MB/s",
1551 ill_rate,
1552 ill_rate,
1553 ill_rate,
1554 ill_rate,
1555 ill_rate,
1556 ill_rate,
1557 ill_rate,
1558 ill_rate,
1559 ill_rate,
1560 ill_rate,
1561 "Not specified",
1562 };
1563
1564 LOCAL char ill_layer[] = "illegal layer type";
1565 char *layer_types[] = {
1566 "Embossed Data",
1567 "Recordable Area",
1568 "Rewritable Area",
1569 ill_layer,
1570 ill_layer,
1571 ill_layer,
1572 ill_layer,
1573 ill_layer,
1574 ill_layer,
1575 ill_layer,
1576 ill_layer,
1577 ill_layer,
1578 ill_layer,
1579 ill_layer,
1580 ill_layer,
1581 ill_layer,
1582 };
1583
1584 LOCAL char ill_dens[] = "illegal density";
1585 char *ldensities[] = {
1586 "0.267 �m/bit",
1587 "0.293 �m/bit",
1588 "0.409-0.435 �m/bit",
1589 "0.280-0.291 �m/bit",
1590 "0.353 �m/bit",
1591 ill_dens,
1592 ill_dens,
1593 ill_dens,
1594 ill_dens,
1595 ill_dens,
1596 ill_dens,
1597 ill_dens,
1598 ill_dens,
1599 ill_dens,
1600 ill_dens,
1601 ill_dens,
1602 };
1603
1604 char *tdensities[] = {
1605 "0.74 �m/track",
1606 "0.80 �m/track",
1607 "0.615 �m/track",
1608 "0.40 �m/track",
1609 "0.34 �m/track",
1610 ill_dens,
1611 ill_dens,
1612 ill_dens,
1613 ill_dens,
1614 ill_dens,
1615 ill_dens,
1616 ill_dens,
1617 ill_dens,
1618 ill_dens,
1619 ill_dens,
1620 ill_dens,
1621 };
1622
1623 LOCAL void
print_dvd00(dp)1624 print_dvd00(dp)
1625 struct dvd_structure_00 *dp;
1626 {
1627 int len = a_to_2_byte(dp->data_len)+2;
1628 long lbr;
1629 char *vers = "";
1630 char *ext_vers = "";
1631 char ev[8];
1632 int evers = 0;
1633
1634 ev[0] = '\0';
1635 if (len >= (27+4))
1636 evers = ((char *)dp)[27+4] & 0xFF;
1637
1638 if (dp->book_type == 2) { /* DVD-R */
1639 vers = R_vers[dp->book_version];
1640 if ((dp->book_version == 5 ||
1641 dp->book_version == 6) &&
1642 evers != 0) {
1643 snprintf(ev, sizeof (ev),
1644 " -> %d.%d",
1645 (evers >> 4) & 0x0F,
1646 evers & 0x0F);
1647 ext_vers = ev;
1648 }
1649
1650 } else if (dp->book_type == 3) { /* DVD-RW */
1651 vers = RW_vers[dp->book_version];
1652 if ((dp->book_version == 2 ||
1653 dp->book_version == 3) &&
1654 evers != 0) {
1655 snprintf(ev, sizeof (ev),
1656 " -> %d.%d",
1657 (evers >> 4) & 0x0F,
1658 evers & 0x0F);
1659 ext_vers = ev;
1660 }
1661 }
1662
1663 printf(_("book type: %s, Version %s%s%s(%d.%d)\n"),
1664 book_types[dp->book_type],
1665 vers, ext_vers, *vers ? " ":"",
1666 dp->book_type,
1667 dp->book_version);
1668 printf(_("disc size: %s (%d)\n"), disc_sizes[dp->disc_size], dp->disc_size);
1669 printf(_("maximum rate: %s (%d)\n"), tr_rates[dp->maximum_rate], dp->maximum_rate);
1670 printf(_("number of layers:%d\n"), dp->numlayers+1);
1671 printf(_("track path: %s Track Path (%d)\n"),
1672 dp->track_path?_("Opposite"):_("Parallel"),
1673 dp->track_path);
1674 printf(_("layer type: %s (%d)\n"), layer_types[dp->layer_type],
1675 dp->layer_type);
1676 printf(_("linear density: %s (%d)\n"), ldensities[dp->linear_density],
1677 dp->linear_density);
1678 printf(_("track density: %s (%d)\n"), tdensities[dp->track_density],
1679 dp->track_density);
1680 printf(_("phys start: %ld (0x%lX) \n"),
1681 a_to_u_3_byte(dp->phys_start),
1682 a_to_u_3_byte(dp->phys_start));
1683 printf(_("phys end: %ld\n"), a_to_u_3_byte(dp->phys_end));
1684 printf(_("end layer 0: %ld\n"), a_to_u_3_byte(dp->end_layer0));
1685 printf(_("bca: %d\n"), dp->bca);
1686 printf(_("phys size:... %ld\n"), a_to_u_3_byte(dp->phys_end) - a_to_u_3_byte(dp->phys_start) + 1);
1687 lbr = a_to_u_3_byte(dp->end_layer0) - a_to_u_3_byte(dp->phys_start) + 1;
1688 if (lbr > 0)
1689 printf(_("layer break at: %ld\n"), lbr);
1690 }
1691
1692 LOCAL void
print_dvd01(dp)1693 print_dvd01(dp)
1694 struct dvd_structure_01 *dp;
1695 {
1696 printf(_("copyr prot type: %d\n"), dp->copyr_prot_type);
1697 printf(_("region mgt info: %d\n"), dp->region_mgt_info);
1698 }
1699
1700 LOCAL void
print_dvd04(dp)1701 print_dvd04(dp)
1702 struct dvd_structure_04 *dp;
1703 {
1704 if (cmpnullbytes(dp->man_info, sizeof (dp->man_info)) <
1705 sizeof (dp->man_info)) {
1706 printf(_("Manufacturing info: '%.2048s'\n"), dp->man_info);
1707 }
1708 }
1709
1710 LOCAL void
print_dvd05(dp)1711 print_dvd05(dp)
1712 struct dvd_structure_05 *dp;
1713 {
1714 printf(_("cpm: %d\n"), dp->cpm);
1715 printf(_("cgms: %d\n"), dp->cgms);
1716 }
1717
1718 LOCAL void
print_dvd0D(dp)1719 print_dvd0D(dp)
1720 struct dvd_structure_0D *dp;
1721 {
1722 printf(_("last rma sector: %d\n"), a_to_u_2_byte(dp->last_rma_sector));
1723 }
1724
1725 LOCAL void
print_dvd0E(dp)1726 print_dvd0E(dp)
1727 struct dvd_structure_0E *dp;
1728 {
1729 int i;
1730 int len = 44;
1731 int c;
1732 char *p = (char *)dp;
1733
1734 if (dp->field_id != 1)
1735 printf(_("field id: %d\n"), dp->field_id);
1736 printf(_("application code:%d\n"), dp->application_code);
1737 printf(_("physical code: %d\n"), dp->phys_data);
1738 printf(_("last rec address:%ld\n"), a_to_u_3_byte(dp->last_recordable_addr));
1739 printf(_("part v./ext code:%X/%X\n"), (Uint)(dp->res_a[0] & 0xF0) >> 4,
1740 dp->res_a[0] & 0xF);
1741
1742 if (dp->field_id_2 != 2)
1743 printf(_("field id2: %d\n"), dp->field_id_2);
1744 printf(_("ind wr. power: %d\n"), dp->ind_wr_power);
1745 printf(_("wavelength code: %d\n"), dp->ind_wavelength);
1746 scg_fprbytes(stdout, _("write str. code:"), dp->opt_wr_strategy, 4);
1747
1748 if (dp->field_id_3 != 3)
1749 printf(_("field id3: %d\n"), dp->field_id_3);
1750 if (dp->field_id_4 != 4)
1751 printf(_("field id4: %d\n"), dp->field_id_4);
1752
1753 printf(_("Manufacturer: '"));
1754 for (i = 0; i < 6; i++) {
1755 c = dp->man_id[i];
1756 if (c >= ' ' && c < 0177)
1757 printf("%c", c);
1758 else if (c != 0)
1759 printf(".");
1760 }
1761 for (i = 0; i < 6; i++) {
1762 c = dp->man_id2[i];
1763 if (c >= ' ' && c < 0177)
1764 printf("%c", c);
1765 else if (c != 0)
1766 printf(".");
1767 }
1768 printf("'\n");
1769 /*
1770 * Next field: opt wr str. II or Manufacturer part III
1771 */
1772 /* scg_prbytes("write str. code:", dp->opt_wr_strategy, 4);*/
1773
1774 if (lverbose <= 1)
1775 return;
1776 printf(_("Prerecorded info : "));
1777 for (i = 0; i < len; i++) {
1778 c = p[i];
1779 if (c >= ' ' && c < 0177)
1780 printf("%c", c);
1781 else
1782 printf(".");
1783 }
1784 printf("\n");
1785 }
1786
1787 LOCAL void
print_dvd0F(dp)1788 print_dvd0F(dp)
1789 struct dvd_structure_0F *dp;
1790 {
1791 printf(_("random: %d\n"), a_to_u_2_byte(dp->random));
1792 printf(_("year: %.4s\n"), dp->year);
1793 printf(_("month: %.2s\n"), dp->month);
1794 printf(_("day: %.2s\n"), dp->day);
1795 printf(_("hour: %.2s\n"), dp->hour);
1796 printf(_("minute: %.2s\n"), dp->minute);
1797 printf(_("second: %.2s\n"), dp->second);
1798 }
1799
1800
1801 #ifdef __needed__
1802 LOCAL void
send_dvd0F(scgp)1803 send_dvd0F(scgp)
1804 SCSI *scgp;
1805 {
1806 struct dvd_structure_0F_w d;
1807
1808 strncpy((char *)d.year, "1998", 4);
1809 strncpy((char *)d.month, "05", 2);
1810 strncpy((char *)d.day, "12", 2);
1811 strncpy((char *)d.hour, "22", 2);
1812 strncpy((char *)d.minute, "59", 2);
1813 strncpy((char *)d.second, "00", 2);
1814 /* send_dvd_structure(scgp, (caddr_t)&d, sizeof (d));*/
1815 }
1816 #endif
1817
1818 LOCAL void
print_dvd20(dp)1819 print_dvd20(dp)
1820 struct dvd_structure_20 *dp;
1821 {
1822 printf(_("L0 init status: %d\n"), dp->res47[0] & 0x80 ? 1 : 0);
1823 printf(_("L0 data areacap: %ld\n"), a_to_u_4_byte(dp->l0_area_cap));
1824 }
1825
1826 LOCAL void
print_dvd22(dp)1827 print_dvd22(dp)
1828 struct dvd_structure_22 *dp;
1829 {
1830 printf(_("Jump intervalsz: %ld\n"), a_to_u_4_byte(dp->jump_interval_size));
1831 }
1832
1833 LOCAL void
print_dvd23(dp)1834 print_dvd23(dp)
1835 struct dvd_structure_23 *dp;
1836 {
1837 printf(_("Jump LBA: %ld\n"), a_to_u_4_byte(dp->jump_lba));
1838 }
1839
1840
1841 #include "adip.h"
1842 /*LOCAL void*/
1843 EXPORT void
print_dvd_info(scgp)1844 print_dvd_info(scgp)
1845 SCSI *scgp;
1846 {
1847 Uchar mode[4096];
1848 int ret;
1849 int i;
1850
1851 if (lverbose > 2)
1852 printf(_("Entering DVD info....\n"));
1853 /*
1854 * The ACARD TECH AEC-7720 ATAPI<->SCSI adaptor
1855 * chokes if we try to transfer odd byte counts (rounds up to
1856 * even byte counts and thus causes a DMA overflow and a
1857 * bus reset), so make the byte count even.
1858 * It also chokes if we try to transfer more than 0x40 bytes with
1859 * mode_sense of all pages. As we don't want to avoid this
1860 * command here, we need to wait until the drive recoveres
1861 * from the reset?? it receives after the adapter dies.
1862 */
1863 /* mode_sense(scgp, mode, 255, 0x3F, 0);*/
1864 /* if (lverbose > 2)*/
1865 /* scg_prbytes("Mode: ", mode, 255 - scg_getresid(scgp));*/
1866
1867 if (lverbose > 1)
1868 mode_sense(scgp, mode, 250, 0x3F, 0);
1869 if (lverbose > 2)
1870 scg_prbytes(_("Mode: "), mode, 250 - scg_getresid(scgp));
1871 wait_unit_ready(scgp, 120);
1872 if (lverbose > 1) {
1873 printf(_("Supported DVD (readable) structures:"));
1874 scgp->silent++;
1875 for (i = 0; i <= 255; i++) {
1876 fillbytes((caddr_t)mode, sizeof (mode), '\0');
1877 ret = read_dvd_structure(scgp, (caddr_t)mode, sizeof (mode), 0, 0, 0, i);
1878 if (ret >= 0 && (sizeof (mode) - scg_getresid(scgp)) > 4)
1879 printf(" %02X", i);
1880 }
1881 scgp->silent--;
1882 printf("\n");
1883 /* printf("Page: %d ret: %d len: %d\n", i, ret, sizeof (mode) - scg_getresid(scgp));*/
1884 if (lverbose > 2)
1885 scg_prbytes(_("Page FF: "), mode, sizeof (mode) - scg_getresid(scgp));
1886 if (sizeof (mode) - scg_getresid(scgp) > 4) {
1887 int len = a_to_u_2_byte(mode) - 2;
1888 Uchar *p = &mode[4];
1889 int m;
1890
1891 len /= 4;
1892 for (i = 0; i < len; i++) {
1893 m = p[1] & 0xC0;
1894 printf(_("Page %02X %s (%02X) len %d\n"),
1895 *p & 0xFF,
1896 m == 0xC0 ?
1897 _("read/write") :
1898 (m == 0x80 ? _(" write") :
1899 (m == 0x40 ? _("read ") : _("unknown "))),
1900 p[1] & 0xFF,
1901 a_to_u_2_byte(&p[2]));
1902 p += 4;
1903 }
1904 }
1905 }
1906 wait_unit_ready(scgp, 120);
1907
1908 /*
1909 * Physical Format information 0x00
1910 */
1911 fillbytes((caddr_t)mode, sizeof (mode), '\0');
1912 scgp->silent++;
1913 ret = read_dvd_structure(scgp, (caddr_t)mode, sizeof (mode), 0, 0, 0, 0);
1914 scgp->silent--;
1915 if (ret >= 0) {
1916 if (lverbose > 2) {
1917 scg_prbytes(_("DVD structure[0]: "),
1918 mode, sizeof (mode) - scg_getresid(scgp));
1919 /* scg_prascii("DVD structure[0]: ", mode, sizeof (mode) - scg_getresid(scgp));*/
1920 }
1921 print_dvd00((struct dvd_structure_00 *)mode);
1922 ret = get_curprofile(scgp);
1923 if (ret == 0x001A || ret == 0x001B) {
1924 /*profile >= 0x0018 && profile < 0x0020*/
1925 printf(_("Manufacturer: '%.8s'\n"), &mode[23]);
1926 printf(_("Media type: '%.3s'\n"), &mode[23+8]);
1927 }
1928 }
1929
1930 /*
1931 * ADIP information 0x11
1932 */
1933 fillbytes((caddr_t)mode, sizeof (mode), '\0');
1934 scgp->silent++;
1935 ret = read_dvd_structure(scgp, (caddr_t)mode, sizeof (mode), 0, 0, 0, 0x11);
1936 scgp->silent--;
1937 if (ret >= 0) {
1938 adip_t *adp;
1939 if (lverbose > 2) {
1940 scg_prbytes(_("DVD structure[11]: "),
1941 mode, sizeof (mode) - scg_getresid(scgp));
1942 scg_prascii(_("DVD structure[11]: "),
1943 mode, sizeof (mode) - scg_getresid(scgp));
1944 }
1945 /* print_dvd0F((struct dvd_structure_0F *)mode);*/
1946 adp = (adip_t *)&mode[4];
1947 #ifndef offsetof
1948 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
1949 #endif
1950 /* printf("size %d %d\n", sizeof (adip_t), offsetof(adip_t, res_controldat));*/
1951 printf(_("Category/Version %02X\n"), adp->cat_vers);
1952 printf(_("Disk size %02X\n"), adp->disk_size);
1953 printf(_("Disk structure %02X\n"), adp->disk_struct);
1954 printf(_("Recoding density %02X\n"), adp->density);
1955
1956 printf(_("Manufacturer: '%.8s'\n"), adp->man_id);
1957 printf(_("Media type: '%.3s'\n"), adp->media_id);
1958 printf(_("Product revision %u\n"), adp->prod_revision);
1959 printf(_("ADIP numbytes %u\n"), adp->adip_numbytes);
1960 printf(_("Reference speed %u\n"), adp->ref_speed);
1961 printf(_("Max speed %u\n"), adp->max_speed);
1962 }
1963
1964 /*
1965 * Layer boundary information 0x20
1966 */
1967 fillbytes((caddr_t)mode, sizeof (mode), '\0');
1968 scgp->silent++;
1969 ret = read_dvd_structure(scgp, (caddr_t)mode, sizeof (mode), 0, 0, 0, 0x20);
1970 scgp->silent--;
1971 if (ret >= 0) {
1972 if (lverbose > 2) {
1973 scg_prbytes(_("DVD structure[20]: "),
1974 mode, sizeof (mode) - scg_getresid(scgp));
1975 scg_prascii(_("DVD structure[20]: "),
1976 mode, sizeof (mode) - scg_getresid(scgp));
1977 }
1978 print_dvd20((struct dvd_structure_20 *)mode);
1979 }
1980
1981 /*
1982 * Jump interval size 0x22
1983 */
1984 fillbytes((caddr_t)mode, sizeof (mode), '\0');
1985 scgp->silent++;
1986 ret = read_dvd_structure(scgp, (caddr_t)mode, sizeof (mode), 0, 0, 0, 0x22);
1987 scgp->silent--;
1988 if (ret >= 0) {
1989 if (lverbose > 2) {
1990 scg_prbytes(_("DVD structure[22]: "),
1991 mode, sizeof (mode) - scg_getresid(scgp));
1992 scg_prascii(_("DVD structure[22]: "),
1993 mode, sizeof (mode) - scg_getresid(scgp));
1994 }
1995 print_dvd22((struct dvd_structure_22 *)mode);
1996 }
1997
1998 /*
1999 * Jump logical block address 0x23
2000 */
2001 fillbytes((caddr_t)mode, sizeof (mode), '\0');
2002 scgp->silent++;
2003 ret = read_dvd_structure(scgp, (caddr_t)mode, sizeof (mode), 0, 0, 0, 0x23);
2004 scgp->silent--;
2005 if (ret >= 0) {
2006 if (lverbose > 2) {
2007 scg_prbytes(_("DVD structure[23]: "),
2008 mode, sizeof (mode) - scg_getresid(scgp));
2009 scg_prascii(_("DVD structure[23]: "),
2010 mode, sizeof (mode) - scg_getresid(scgp));
2011 }
2012 print_dvd23((struct dvd_structure_23 *)mode);
2013 }
2014
2015 /*
2016 * Copyright information 0x01
2017 */
2018 fillbytes((caddr_t)mode, sizeof (mode), '\0');
2019 scgp->silent++;
2020 ret = read_dvd_structure(scgp, (caddr_t)mode, sizeof (mode), 0, 0, 0, 1);
2021 scgp->silent--;
2022 if (ret >= 0) {
2023 if (lverbose > 2) {
2024 scg_prbytes(_("DVD structure[1]: "),
2025 mode, sizeof (mode) - scg_getresid(scgp));
2026 }
2027 print_dvd01((struct dvd_structure_01 *)mode);
2028 }
2029
2030 /*
2031 * Manufacturer information 0x04
2032 */
2033 fillbytes((caddr_t)mode, sizeof (mode), '\0');
2034 scgp->silent++;
2035 ret = read_dvd_structure(scgp, (caddr_t)mode, sizeof (mode), 0, 0, 0, 4);
2036 scgp->silent--;
2037 if (ret >= 0) {
2038 if (lverbose > 2) {
2039 scg_prbytes(_("DVD structure[4]: "),
2040 mode, sizeof (mode) - scg_getresid(scgp));
2041 }
2042 print_dvd04((struct dvd_structure_04 *)mode);
2043 }
2044
2045 /*
2046 * Copyright management information 0x05
2047 */
2048 fillbytes((caddr_t)mode, sizeof (mode), '\0');
2049 scgp->silent++;
2050 ret = read_dvd_structure(scgp, (caddr_t)mode, sizeof (mode), 0, 0, 0, 5);
2051 scgp->silent--;
2052 if (ret >= 0) {
2053 if (lverbose > 2) {
2054 scg_prbytes(_("DVD structure[5]: "),
2055 mode, sizeof (mode) - scg_getresid(scgp));
2056 }
2057 print_dvd05((struct dvd_structure_05 *)mode);
2058 }
2059
2060 /*
2061 * Recording Management Area Data information 0x0D
2062 */
2063 fillbytes((caddr_t)mode, sizeof (mode), '\0');
2064 scgp->silent++;
2065 ret = read_dvd_structure(scgp, (caddr_t)mode, sizeof (mode), 0, 0, 0, 0xD);
2066 scgp->silent--;
2067 if (ret >= 0) {
2068 if (lverbose > 2) {
2069 scg_prbytes(_("DVD structure[D]: "),
2070 mode, sizeof (mode) - scg_getresid(scgp));
2071 }
2072 print_dvd0D((struct dvd_structure_0D *)mode);
2073 }
2074
2075 /*
2076 * Prerecorded information 0x0E
2077 */
2078 fillbytes((caddr_t)mode, sizeof (mode), '\0');
2079 scgp->silent++;
2080 ret = read_dvd_structure(scgp, (caddr_t)mode, sizeof (mode), 0, 0, 0, 0xE);
2081 scgp->silent--;
2082 if (ret >= 0) {
2083 if (lverbose > 2) {
2084 scg_prbytes(_("DVD structure[E]: "),
2085 mode, sizeof (mode) - scg_getresid(scgp));
2086 }
2087 print_dvd0E((struct dvd_structure_0E *)mode);
2088 }
2089
2090 if (lverbose <= 1)
2091 return;
2092
2093 /*
2094 * Unique Disk identifier 0x0F
2095 */
2096 /* send_dvd0F();*/
2097 fillbytes((caddr_t)mode, sizeof (mode), '\0');
2098 scgp->silent++;
2099 ret = read_dvd_structure(scgp, (caddr_t)mode, sizeof (mode), 0, 0, 0, 0xF);
2100 scgp->silent--;
2101 if (ret >= 0) {
2102 if (lverbose > 2) {
2103 scg_prbytes(_("DVD structure[F]: "),
2104 mode, sizeof (mode) - scg_getresid(scgp));
2105 }
2106 print_dvd0F((struct dvd_structure_0F *)mode);
2107 }
2108
2109 fillbytes((caddr_t)mode, sizeof (mode), '\0');
2110 read_rzone_info(scgp, (caddr_t)mode, sizeof (mode));
2111 if (lverbose > 2)
2112 scg_prbytes(_("Rzone info: "), mode, sizeof (mode) - scg_getresid(scgp));
2113 przone((struct rzone_info *)mode);
2114
2115 scgp->verbose++;
2116 log_sense(scgp, (caddr_t)mode, 255, 0x3, 1, 0);
2117 log_sense(scgp, (caddr_t)mode, 255, 0x31, 1, 0);
2118 scgp->verbose--;
2119
2120 if (lverbose > 2)
2121 printf(_("Leaving DVD info.\n"));
2122 }
2123
2124 LOCAL void
print_laserlog(scgp)2125 print_laserlog(scgp)
2126 SCSI *scgp;
2127 {
2128 Uchar log[256];
2129 Uchar *p;
2130 int len = sizeof (log);
2131 long val;
2132
2133 if (!has_log_page(scgp, 0x30, LOG_CUMUL))
2134 return;
2135
2136 p = log + sizeof (scsi_log_hdr);
2137
2138 /*
2139 * This is Pioneer specific so other drives will not have it.
2140 * Not all values may be available with newer Pioneer drives.
2141 */
2142 scgp->silent++;
2143 fillbytes((caddr_t)log, sizeof (log), '\0');
2144 if (get_log(scgp, (caddr_t)log, &len, 0x30, LOG_CUMUL, 0) < 0) {
2145 scgp->silent--;
2146 return;
2147 }
2148 scgp->silent--;
2149
2150 val = a_to_u_4_byte(((struct pioneer_logpage_30_0 *)p)->total_poh);
2151 if (((struct scsi_logp_header *)log)->p_len > 0)
2152 printf(_("Total power on hours: %ld\n"), val);
2153
2154 scgp->silent++;
2155 fillbytes((caddr_t)log, sizeof (log), '\0');
2156 if (get_log(scgp, (caddr_t)log, &len, 0x30, LOG_CUMUL, 1) < 0) {
2157 scgp->silent--;
2158 return;
2159 }
2160 scgp->silent--;
2161
2162 val = a_to_u_4_byte(((struct pioneer_logpage_30_1 *)p)->laser_poh);
2163 if (((struct scsi_logp_header *)log)->p_len > 0)
2164 printf(_("Total laser on hours: %ld\n"), val);
2165
2166 scgp->silent++;
2167 fillbytes((caddr_t)log, sizeof (log), '\0');
2168 if (get_log(scgp, (caddr_t)log, &len, 0x30, LOG_CUMUL, 2) < 0) {
2169 scgp->silent--;
2170 return;
2171 }
2172 scgp->silent--;
2173
2174 val = a_to_u_4_byte(((struct pioneer_logpage_30_2 *)p)->record_poh);
2175 if (((struct scsi_logp_header *)log)->p_len > 0)
2176 printf(_("Total recording hours: %ld\n"), val);
2177 }
2178