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