1 /* @(#)drv_sony.c	1.89 12/03/16 Copyright 1997-2012 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static	UConst char sccsid[] =
5 	"@(#)drv_sony.c	1.89 12/03/16 Copyright 1997-2012 J. Schilling";
6 #endif
7 /*
8  *	CDR device implementation for
9  *	Sony
10  *
11  *	Copyright (c) 1997-2012 J. Schilling
12  */
13 /*
14  * The contents of this file are subject to the terms of the
15  * Common Development and Distribution License, Version 1.0 only
16  * (the "License").  You may not use this file except in compliance
17  * with the License.
18  *
19  * See the file CDDL.Schily.txt in this distribution for details.
20  * A copy of the CDDL is also available via the Internet at
21  * http://www.opensource.org/licenses/cddl1.txt
22  *
23  * When distributing Covered Code, include this CDDL HEADER in each
24  * file and include the License file CDDL.Schily.txt from this distribution.
25  */
26 
27 /*#define	SONY_DEBUG*/
28 
29 #include <schily/mconfig.h>
30 
31 #include <schily/stdio.h>
32 #include <schily/stdlib.h>
33 #include <schily/unistd.h>	/* Include sys/types.h to make off_t available */
34 #include <schily/standard.h>
35 #include <schily/fcntl.h>
36 #include <schily/errno.h>
37 #include <schily/string.h>
38 #include <schily/time.h>
39 
40 #include <schily/utypes.h>
41 #include <schily/btorder.h>
42 #include <schily/intcvt.h>
43 #include <schily/schily.h>
44 #include <schily/nlsdefs.h>
45 
46 #include <scg/scgcmd.h>
47 #include <scg/scsidefs.h>
48 #include <scg/scsireg.h>
49 #include <scg/scsitransp.h>
50 
51 #include "cdrecord.h"
52 
53 #ifdef	SONY_DEBUG
54 #	define		inc_verbose()	scgp->verbose++
55 #	define		dec_verbose()	scgp->verbose--
56 #else
57 #	define		inc_verbose()
58 #	define		dec_verbose()
59 #endif
60 
61 extern	int	debug;
62 extern	int	lverbose;
63 
64 #if defined(_BIT_FIELDS_LTOH)	/* Intel byteorder */
65 
66 struct sony_924_mode_page_20 {	/* mastering information */
67 		MP_P_CODE;		/* parsave & pagecode */
68 	Uchar	p_len;			/* 0x06 = 6 Bytes */
69 	Uchar	subcode_header_off;
70 	Ucbit	res3_0		: 1;
71 	Ucbit	speudo		: 1;
72 	Ucbit	res3_2		: 1;
73 	Ucbit	c2po		: 1;
74 	Ucbit	subcode_ecc	: 1;
75 	Ucbit	res3_567	: 3;
76 	Uchar	res_4;
77 	Uchar	cue_sheet_opt;
78 	Uchar	res[2];
79 };
80 
81 #else				/* Motorola byteorder */
82 
83 struct sony_924_mode_page_20 {	/* mastering information */
84 		MP_P_CODE;		/* parsave & pagecode */
85 	Uchar	p_len;			/* 0x06 = 6 Bytes */
86 	Uchar	subcode_header_off;
87 	Ucbit	res3_567	: 3;
88 	Ucbit	subcode_ecc	: 1;
89 	Ucbit	c2po		: 1;
90 	Ucbit	res3_2		: 1;
91 	Ucbit	speudo		: 1;
92 	Ucbit	res3_0		: 1;
93 	Uchar	res_4;
94 	Uchar	cue_sheet_opt;
95 	Uchar	res[2];
96 };
97 #endif
98 
99 struct sony_924_mode_page_22 {	/* disk information */
100 		MP_P_CODE;		/* parsave & pagecode */
101 	Uchar	p_len;			/* 0x1E = 30 Bytes */
102 	Uchar	disk_style;
103 	Uchar	disk_type;
104 	Uchar	first_track;
105 	Uchar	last_track;
106 	Uchar	numsess;
107 	Uchar	res_7;
108 	Uchar	disk_appl_code[4];
109 	Uchar	last_start_time[4];
110 	Uchar	disk_status;
111 	Uchar	num_valid_nra;
112 	Uchar	track_info_track;
113 	Uchar	post_gap;
114 	Uchar	disk_id_code[4];
115 	Uchar	lead_in_start[4];
116 	Uchar	res[4];
117 };
118 
119 struct sony_924_mode_page_23 {	/* track information */
120 		MP_P_CODE;		/* parsave & pagecode */
121 	Uchar	p_len;			/* 0x22 = 34 Bytes */
122 	Uchar	res_2;
123 	Uchar	track_num;
124 	Uchar	data_form;
125 	Uchar	write_method;
126 	Uchar	session;
127 	Uchar	track_status;
128 	Uchar	start_lba[4];
129 	Uchar	next_recordable_addr[4];
130 	Uchar	blank_area_cap[4];
131 	Uchar	fixed_packet_size[4];
132 	Uchar	res_24;
133 	Uchar	starting_msf[3];
134 	Uchar	res_28;
135 	Uchar	ending_msf[3];
136 	Uchar	res_32;
137 	Uchar	next_rec_time[3];
138 };
139 
140 struct sony_924_mode_page_31 {	/* drive speed */
141 		MP_P_CODE;		/* parsave & pagecode */
142 	Uchar	p_len;			/* 0x02 = 2 Bytes */
143 	Uchar	speed;
144 	Uchar	res;
145 };
146 
147 struct cdd_52x_mode_data {
148 	struct scsi_mode_header	header;
149 	union cdd_pagex	{
150 		struct sony_924_mode_page_20	page_s20;
151 		struct sony_924_mode_page_22	page_s22;
152 		struct sony_924_mode_page_23	page_s23;
153 		struct sony_924_mode_page_31	page_s31;
154 	} pagex;
155 };
156 
157 struct sony_write_parameter {
158 	Uchar	res0;			/* Reserved (must be zero)	*/
159 	Uchar	len;			/* Parameter length 0x32 == 52	*/
160 	Uchar	res2;			/* Reserved (must be zero)	*/
161 #if defined(_BIT_FIELDS_LTOH)	/* Intel byteorder */
162 	Ucbit	res3_05		: 6;	/* Reserved			*/
163 	Ucbit	ms		: 2;	/* Multi session mode		*/
164 #else				/* Motorola byteorder */
165 	Ucbit	ms		: 2;	/* Multi session mode		*/
166 	Ucbit	res3_05		: 6;	/* Reserved			*/
167 #endif
168 	Uchar	resx[12];
169 #if defined(_BIT_FIELDS_LTOH)	/* Intel byteorder */
170 	Ucbit	res16_06	: 7;	/* Reserved			*/
171 	Ucbit	mcval		: 1;	/* MCN valid			*/
172 #else				/* Motorola byteorder */
173 	Ucbit	mcval		: 1;	/* MCN valid			*/
174 	Ucbit	res16_06	: 7;	/* Reserved			*/
175 #endif
176 	Uchar	mcn[15];
177 #if defined(_BIT_FIELDS_LTOH)	/* Intel byteorder */
178 	Ucbit	res32_06	: 7;	/* Reserved			*/
179 	Ucbit	icval		: 1;	/* ISRC valid			*/
180 #else				/* Motorola byteorder */
181 	Ucbit	icval		: 1;	/* ISRC valid			*/
182 	Ucbit	res32_06	: 7;	/* Reserved			*/
183 #endif
184 	Uchar	isrc[15];
185 	Uchar	subheader[4];
186 };
187 
188 struct sony_cue {
189 	Uchar	cs_ctladr;		/* CTL/ADR for this track	*/
190 	Uchar	cs_tno;			/* This track number		*/
191 	Uchar	cs_index;		/* Index within this track	*/
192 	Uchar	cs_dataform;		/* Data form 			*/
193 					/* Bit 0..5 Main channel Format	*/
194 					/* Bit 6..7 SubChannel format	*/
195 	Uchar	cs_zero;		/* Reserved or MCN/ISRC		*/
196 	Uchar	cs_min;			/* Absolute time minutes	*/
197 	Uchar	cs_sec;			/* Absolute time seconds	*/
198 	Uchar	cs_frame;		/* Absolute time frames		*/
199 };
200 
201 
202 #define	strbeg(s1, s2)	(strstr((s2), (s1)) == (s2))
203 
204 LOCAL	int	write_start_sony	__PR((SCSI *scgp, caddr_t bp, int size));
205 LOCAL	int	write_continue_sony	__PR((SCSI *scgp, caddr_t bp, long sectaddr, long size, int blocks, BOOL islast));
206 LOCAL	int	discontinue_sony	__PR((SCSI *scgp));
207 LOCAL	int	write_track_sony	__PR((SCSI *scgp, long track, int sectype));
208 LOCAL	int	close_track_sony	__PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
209 #ifdef	__needed__
210 LOCAL	int	flush_sony		__PR((SCSI *scgp, int track));
211 #endif
212 LOCAL	int	finalize_sony		__PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
213 LOCAL	int	recover_sony		__PR((SCSI *scgp, cdr_t *dp, int track));
214 #ifdef	__needed__
215 LOCAL	int	set_wr_parameter_sony	__PR((SCSI *scgp, caddr_t bp, int size));
216 #endif
217 LOCAL	int	next_wr_addr_sony	__PR((SCSI *scgp, track_t *trackp, long *ap));
218 LOCAL	int	reserve_track_sony	__PR((SCSI *scgp, unsigned long len));
219 LOCAL	int	init_sony		__PR((SCSI *scgp, cdr_t *dp));
220 LOCAL	int	getdisktype_sony	__PR((SCSI *scgp, cdr_t *dp));
221 LOCAL	void	di_to_dstat_sony	__PR((struct sony_924_mode_page_22 *dip, dstat_t *dsp));
222 LOCAL	int	speed_select_sony	__PR((SCSI *scgp, cdr_t *dp, int *speedp));
223 LOCAL	int	next_writable_address_sony __PR((SCSI *scgp, long *ap, int track, int sectype, int tracktype));
224 LOCAL	int	new_track_sony		__PR((SCSI *scgp, int track, int sectype, int tracktype));
225 LOCAL	int	open_track_sony		__PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
226 LOCAL	int	open_session_sony	__PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
227 LOCAL	int	abort_session_sony	__PR((SCSI *scgp, cdr_t *dp));
228 LOCAL	int	get_page22_sony		__PR((SCSI *scgp, char *mode));
229 LOCAL	int	gen_cue_sony		__PR((track_t *trackp, void *vcuep, BOOL needgap));
230 LOCAL	void	fillcue			__PR((struct sony_cue *cp, int ca, int tno, int idx, int dataform, int scms, msf_t *mp));
231 LOCAL	int	send_cue_sony		__PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
232 LOCAL	int	write_leadin_sony	__PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
233 LOCAL	int	sony_attach		__PR((SCSI *scgp, cdr_t *dp));
234 #ifdef	SONY_DEBUG
235 LOCAL	void	print_sony_mp22		__PR((struct sony_924_mode_page_22 *xp, int len));
236 LOCAL	void	print_sony_mp23		__PR((struct sony_924_mode_page_23 *xp, int len));
237 #endif
238 LOCAL	int	buf_cap_sony		__PR((SCSI *scgp, long *, long *));
239 
240 cdr_t	cdr_sony_cdu924 = {
241 	0, 0, 0,
242 	CDR_TAO|CDR_SAO|CDR_CADDYLOAD|CDR_SWABAUDIO,
243 	0,
244 	CDR_CDRW_NONE,
245 	WM_SAO,
246 	2, 4,
247 	"sony_cdu924",
248 	"driver for Sony CDU-924 / CDU-948",
249 	0,
250 	(dstat_t *)0,
251 	drive_identify,
252 	sony_attach,
253 	init_sony,
254 	getdisktype_sony,
255 	no_diskstatus,
256 	scsi_load,
257 	scsi_unload,
258 	buf_cap_sony,
259 	cmd_dummy,					/* recovery_needed */
260 	recover_sony,
261 	speed_select_sony,
262 	select_secsize,
263 	next_wr_addr_sony,
264 	reserve_track_sony,
265 	write_continue_sony,
266 	gen_cue_sony,
267 	send_cue_sony,
268 	write_leadin_sony,
269 	open_track_sony,
270 	close_track_sony,
271 	open_session_sony,
272 	cmd_dummy,
273 	abort_session_sony,
274 	read_session_offset_philips,
275 	finalize_sony,
276 	cmd_dummy,					/* stats	*/
277 	blank_dummy,
278 	format_dummy,
279 	(int(*)__PR((SCSI *, caddr_t, int, int)))NULL,	/* no OPC	*/
280 	cmd_dummy,					/* opt1		*/
281 	cmd_dummy,					/* opt2		*/
282 };
283 
284 LOCAL int
write_start_sony(scgp,bp,size)285 write_start_sony(scgp, bp, size)
286 	SCSI	*scgp;
287 	caddr_t	bp;		/* address of CUE buffer */
288 	int	size;		/* number of bytes in CUE buffer */
289 {
290 	register struct	scg_cmd	*scmd = scgp->scmd;
291 
292 	fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
293 	scmd->addr = bp;
294 	scmd->size = size;
295 	scmd->flags = SCG_DISRE_ENA|SCG_CMD_RETRY;
296 	scmd->cdb_len = SC_G1_CDBLEN;
297 	scmd->sense_len = CCS_SENSE_LEN;
298 	scmd->sense_len = 26;
299 	scmd->cdb.g1_cdb.cmd = 0xE0;
300 	scmd->cdb.g1_cdb.lun = scg_lun(scgp);
301 	g0_cdbaddr(&scmd->cdb.g0_cdb, size); /* Hack, but Sony is silly */
302 
303 	scgp->cmdname = "write_start";
304 
305 	if (scg_cmd(scgp) < 0)
306 		return (-1);
307 	return (0);
308 }
309 
310 LOCAL int
write_continue_sony(scgp,bp,sectaddr,size,blocks,islast)311 write_continue_sony(scgp, bp, sectaddr, size, blocks, islast)
312 	SCSI	*scgp;
313 	caddr_t	bp;		/* address of buffer */
314 	long	sectaddr;	/* disk address (sector) to put */
315 	long	size;		/* number of bytes to transfer */
316 	int	blocks;		/* sector count */
317 	BOOL	islast;		/* last write for track */
318 {
319 	register struct	scg_cmd	*scmd = scgp->scmd;
320 
321 	fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
322 	scmd->addr = bp;
323 	scmd->size = size;
324 	scmd->flags = SCG_DISRE_ENA|SCG_CMD_RETRY;
325 	scmd->cdb_len = SC_G1_CDBLEN;
326 	scmd->sense_len = CCS_SENSE_LEN;
327 	scmd->cdb.g1_cdb.cmd = 0xE1;
328 	scmd->cdb.g1_cdb.lun = scg_lun(scgp);
329 	g0_cdbaddr(&scmd->cdb.g0_cdb, size); /* Hack, but Sony is silly */
330 
331 	scgp->cmdname = "write_continue";
332 
333 	if (scg_cmd(scgp) < 0) {
334 		/*
335 		 * XXX This seems to happen only sometimes.
336 		 */
337 		if (scg_sense_code(scgp) != 0x80)
338 			return (-1);
339 	}
340 	return (size - scg_getresid(scgp));
341 }
342 
343 LOCAL int
discontinue_sony(scgp)344 discontinue_sony(scgp)
345 	SCSI	*scgp;
346 {
347 	register struct	scg_cmd	*scmd = scgp->scmd;
348 
349 	fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
350 	scmd->flags = SCG_DISRE_ENA|SCG_CMD_RETRY;
351 	scmd->cdb_len = SC_G1_CDBLEN;
352 	scmd->sense_len = CCS_SENSE_LEN;
353 	scmd->cdb.g1_cdb.cmd = 0xE2;
354 	scmd->cdb.g1_cdb.lun = scg_lun(scgp);
355 
356 	scgp->cmdname = "discontinue";
357 
358 	if (scg_cmd(scgp) < 0)
359 		return (-1);
360 	return (0);
361 }
362 
363 LOCAL int
write_track_sony(scgp,track,sectype)364 write_track_sony(scgp, track, sectype)
365 	SCSI	*scgp;
366 	long	track;		/* track number 0 == new track */
367 	int	sectype;	/* no sectype for Sony write track */
368 {
369 	register struct	scg_cmd	*scmd = scgp->scmd;
370 
371 	fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
372 	scmd->flags = SCG_DISRE_ENA|SCG_CMD_RETRY;
373 	scmd->cdb_len = SC_G1_CDBLEN;
374 	scmd->sense_len = CCS_SENSE_LEN;
375 	scmd->cdb.g1_cdb.cmd = 0xF5;
376 	scmd->cdb.g1_cdb.lun = scg_lun(scgp);
377 	g1_cdbaddr(&scmd->cdb.g1_cdb, track);
378 
379 	scgp->cmdname = "write_track";
380 
381 	if (scg_cmd(scgp) < 0)
382 		return (-1);
383 	return (0);
384 }
385 
386 /* XXX NOCH NICHT FERTIG */
387 LOCAL int
close_track_sony(scgp,dp,trackp)388 close_track_sony(scgp, dp, trackp)
389 	SCSI	*scgp;
390 	cdr_t	*dp;
391 	track_t	*trackp;
392 {
393 	register struct	scg_cmd	*scmd = scgp->scmd;
394 	int	track = 0;
395 
396 	if (!is_tao(trackp) && !is_packet(trackp))
397 		return (0);
398 
399 	fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
400 	scmd->flags = SCG_DISRE_ENA;
401 	scmd->cdb_len = SC_G1_CDBLEN;
402 	scmd->sense_len = CCS_SENSE_LEN;
403 	scmd->cdb.g1_cdb.cmd = 0xF0;
404 	scmd->cdb.g1_cdb.lun = scg_lun(scgp);
405 	g1_cdbaddr(&scmd->cdb.g1_cdb, track);
406 /* XXX Padding ??? (bit 0 in addr[0] / CDB[2]) */
407 
408 	scgp->cmdname = "close_track";
409 
410 	if (scg_cmd(scgp) < 0)
411 		return (-1);
412 
413 	/*
414 	 * Clear the silly "error situation" from Sony� dummy write end
415 	 * but notify if real errors occurred.
416 	 */
417 	scgp->silent++;
418 	if (test_unit_ready(scgp) < 0 && scg_sense_code(scgp) != 0xD4) {
419 		scgp->cmdname = "close_track/test_unit_ready";
420 		scg_printerr(scgp);
421 	}
422 	scgp->silent--;
423 
424 	return (0);
425 }
426 
427 LOCAL int
finalize_sony(scgp,dp,trackp)428 finalize_sony(scgp, dp, trackp)
429 	SCSI	*scgp;
430 	cdr_t	*dp;
431 	track_t	*trackp;
432 {
433 	register struct	scg_cmd	*scmd = scgp->scmd;
434 	int	dummy = track_base(trackp)->tracktype & TOCF_DUMMY;
435 
436 	if (!is_tao(trackp) && !is_packet(trackp)) {
437 		wait_unit_ready(scgp, 240);
438 		return (0);
439 	}
440 	if (dummy) {
441 		printf(_("Fixating is not possible in dummy write mode.\n"));
442 		return (0);
443 	}
444 	fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
445 	scmd->flags = SCG_DISRE_ENA;
446 	scmd->cdb_len = SC_G1_CDBLEN;
447 	scmd->sense_len = CCS_SENSE_LEN;
448 	scmd->timeout = 8 * 60;		/* Needs up to 4 minutes */
449 	scmd->cdb.g1_cdb.cmd = 0xF1;
450 	scmd->cdb.g1_cdb.lun = scg_lun(scgp);
451 	scmd->cdb.g1_cdb.count[1] = ((track_base(trackp)->tracktype & TOCF_MULTI) ? 1 : 0);
452 /* XXX Padding ??? (bit 0 in addr[0] / CDB[2]) */
453 
454 	scgp->cmdname = "finalize";
455 
456 	if (scg_cmd(scgp) < 0)
457 		return (-1);
458 	return (0);
459 }
460 
461 #ifdef	__needed__
462 LOCAL int
flush_sony(scgp,track)463 flush_sony(scgp, track)
464 	SCSI	*scgp;
465 	int	track;
466 {
467 	register struct	scg_cmd	*scmd = scgp->scmd;
468 
469 	fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
470 	scmd->flags = SCG_DISRE_ENA;
471 	scmd->cdb_len = SC_G1_CDBLEN;
472 	scmd->sense_len = CCS_SENSE_LEN;
473 	scmd->timeout = 8 * 60;		/* Needs up to 4 minutes */
474 	scmd->cdb.g1_cdb.cmd = 0xF2;
475 	scmd->cdb.g1_cdb.lun = scg_lun(scgp);
476 	scmd->cdb.cmd_cdb[5] = track;
477 /* XXX POE ???	   (bit 1 in addr[0] / CDB[2]) */
478 /* XXX Padding ??? (bit 0 in addr[0] / CDB[2]) */
479 /* XXX Partial flush ??? (CDB[3]) */
480 
481 	scgp->cmdname = "flush";
482 
483 	if (scg_cmd(scgp) < 0)
484 		return (-1);
485 	return (0);
486 }
487 #endif
488 
489 LOCAL int
recover_sony(scgp,dp,track)490 recover_sony(scgp, dp, track)
491 	SCSI	*scgp;
492 	cdr_t	*dp;
493 	int	track;
494 {
495 	register struct	scg_cmd	*scmd = scgp->scmd;
496 
497 	fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
498 	scmd->flags = SCG_DISRE_ENA;
499 	scmd->cdb_len = SC_G1_CDBLEN;
500 	scmd->sense_len = CCS_SENSE_LEN;
501 	scmd->cdb.g1_cdb.cmd = 0xF6;
502 	scmd->cdb.g1_cdb.lun = scg_lun(scgp);
503 	scmd->cdb.g1_cdb.addr[3] = track;
504 
505 	scgp->cmdname = "recover";
506 
507 	if (scg_cmd(scgp) < 0)
508 		return (-1);
509 	return (0);
510 }
511 
512 #ifdef	__needed__
513 LOCAL int
set_wr_parameter_sony(scgp,bp,size)514 set_wr_parameter_sony(scgp, bp, size)
515 	SCSI	*scgp;
516 	caddr_t	bp;
517 	int	size;
518 {
519 	register struct	scg_cmd	*scmd = scgp->scmd;
520 
521 	fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
522 	scmd->addr = bp;
523 	scmd->size = size;
524 	scmd->flags = SCG_DISRE_ENA;
525 	scmd->cdb_len = SC_G1_CDBLEN;
526 	scmd->sense_len = CCS_SENSE_LEN;
527 	scmd->cdb.g1_cdb.cmd = 0xF8;
528 	scmd->cdb.g1_cdb.lun = scg_lun(scgp);
529 	g1_cdblen(&scmd->cdb.g1_cdb, size);
530 
531 	scgp->cmdname = "set_write_parameter";
532 
533 	if (scg_cmd(scgp) < 0)
534 		return (-1);
535 	return (0);
536 }
537 #endif
538 
539 LOCAL int
next_wr_addr_sony(scgp,trackp,ap)540 next_wr_addr_sony(scgp, trackp, ap)
541 	SCSI	*scgp;
542 	track_t	*trackp;
543 	long	*ap;
544 {
545 	if (next_writable_address_sony(scgp, ap, 0, 0, 0) < 0)
546 		return (-1);
547 	return (0);
548 }
549 
550 LOCAL int
reserve_track_sony(scgp,len)551 reserve_track_sony(scgp, len)
552 	SCSI	*scgp;
553 	unsigned long len;
554 {
555 	register struct	scg_cmd	*scmd = scgp->scmd;
556 
557 	fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
558 	scmd->flags = SCG_DISRE_ENA;
559 	scmd->cdb_len = SC_G1_CDBLEN;
560 	scmd->sense_len = CCS_SENSE_LEN;
561 	scmd->cdb.g1_cdb.cmd = 0xF3;
562 	scmd->cdb.g1_cdb.lun = scg_lun(scgp);
563 	i_to_4_byte(&scmd->cdb.cmd_cdb[5], len);
564 
565 	scgp->cmdname = "reserve_track";
566 
567 	if (scg_cmd(scgp) < 0)
568 		return (-1);
569 	return (0);
570 }
571 
572 LOCAL int
init_sony(scgp,dp)573 init_sony(scgp, dp)
574 	SCSI	*scgp;
575 	cdr_t	*dp;
576 {
577 	return (speed_select_sony(scgp, dp, NULL));
578 }
579 
580 
581 #define	IS(what, flag)	printf(_("  Is %s%s\n"), flag?"":_("not "), what);
582 
583 LOCAL int
getdisktype_sony(scgp,dp)584 getdisktype_sony(scgp, dp)
585 	SCSI	*scgp;
586 	cdr_t	*dp;
587 {
588 	dstat_t	*dsp = dp->cdr_dstat;
589 	long	dummy;
590 	long	lst;
591 	msf_t	msf;
592 
593 	char			mode[256];
594 	struct scsi_mode_page_header	*mp;
595 	struct sony_924_mode_page_22	*xp;
596 
597 	dummy = get_page22_sony(scgp, mode);
598 	if (dummy >= 0) {
599 		mp = (struct scsi_mode_page_header *)
600 			(mode + sizeof (struct scsi_mode_header) +
601 			((struct scsi_mode_header *)mode)->blockdesc_len);
602 
603 		xp = (struct sony_924_mode_page_22 *)mp;
604 
605 		if (xp->disk_appl_code[0] == 0xFF)
606 			dummy = -1;
607 	} else {
608 		return (drive_getdisktype(scgp, dp));
609 	}
610 
611 	if ((dp->cdr_dstat->ds_cdrflags & RF_PRATIP) != 0 && dummy >= 0) {
612 
613 		printf(_("ATIP info from disk:\n"));
614 		printf(_("  Indicated writing power: %d\n"),
615 				(unsigned)(xp->disk_appl_code[1] & 0x70) >> 4);
616 		IS(_("unrestricted"), xp->disk_appl_code[2] & 0x40);
617 		printf(_("  Disk application code: %d\n"), xp->disk_appl_code[2] & 0x3F);
618 		msf.msf_min = xp->lead_in_start[1];
619 		msf.msf_sec = xp->lead_in_start[2];
620 		msf.msf_frame = xp->lead_in_start[3];
621 		lst = msf_to_lba(msf.msf_min, msf.msf_sec, msf.msf_frame, FALSE);
622 		if (lst  < -150) {
623 			/*
624 			 * The Sony CDU 920 seems to deliver 00:00/00 for
625 			 * lead-in start time, dont use it.
626 			 */
627 			printf(_("  ATIP start of lead in:  %ld (%02d:%02d/%02d)\n"),
628 				msf_to_lba(msf.msf_min, msf.msf_sec, msf.msf_frame, FALSE),
629 				msf.msf_min, msf.msf_sec, msf.msf_frame);
630 		}
631 		msf.msf_min = xp->last_start_time[1];
632 		msf.msf_sec = xp->last_start_time[2];
633 		msf.msf_frame = xp->last_start_time[3];
634 		printf(_("  ATIP start of lead out: %ld (%02d:%02d/%02d)\n"),
635 			msf_to_lba(msf.msf_min, msf.msf_sec, msf.msf_frame, TRUE),
636 			msf.msf_min, msf.msf_sec, msf.msf_frame);
637 		if (lst  < -150) {
638 			/*
639 			 * The Sony CDU 920 seems to deliver 00:00/00 for
640 			 * lead-in start time, dont use it.
641 			 */
642 			msf.msf_min = xp->lead_in_start[1];
643 			msf.msf_sec = xp->lead_in_start[2];
644 			msf.msf_frame = xp->lead_in_start[3];
645 			pr_manufacturer(&msf,
646 					FALSE,	/* Always not erasable */
647 					(xp->disk_appl_code[2] & 0x40) != 0);
648 		}
649 	}
650 	if (dummy >= 0)
651 		di_to_dstat_sony(xp, dsp);
652 	return (drive_getdisktype(scgp, dp));
653 }
654 
655 LOCAL void
di_to_dstat_sony(dip,dsp)656 di_to_dstat_sony(dip, dsp)
657 	struct sony_924_mode_page_22	*dip;
658 	dstat_t	*dsp;
659 {
660 	msf_t	msf;
661 
662 	dsp->ds_diskid = a_to_u_4_byte(dip->disk_id_code);
663 #ifdef	PROTOTYPES
664 	if (dsp->ds_diskid != 0xFFFFFFFFUL)
665 #else
666 	if (dsp->ds_diskid != (Ulong)0xFFFFFFFF)
667 #endif
668 		dsp->ds_flags |= DSF_DID_V;
669 	dsp->ds_diskstat = (dip->disk_status >> 6) & 0x03;
670 #ifdef	XXX
671 	/*
672 	 * There seems to be no MMC equivalent...
673 	 */
674 	dsp->ds_sessstat = dip->sess_status;
675 #endif
676 
677 	dsp->ds_maxblocks = msf_to_lba(dip->last_start_time[1],
678 					dip->last_start_time[2],
679 					dip->last_start_time[3], TRUE);
680 	/*
681 	 * Check for 0xFF:0xFF/0xFF which is an indicator for a complete disk
682 	 */
683 	if (dsp->ds_maxblocks == 716730)
684 		dsp->ds_maxblocks = -1L;
685 
686 	if (dsp->ds_first_leadin == 0) {
687 		dsp->ds_first_leadin = msf_to_lba(dip->lead_in_start[1],
688 						dip->lead_in_start[2],
689 						dip->lead_in_start[3], FALSE);
690 		/*
691 		 * Check for illegal values (> 0)
692 		 * or for empty field (-150) with CDU-920.
693 		 */
694 		if (dsp->ds_first_leadin > 0 || dsp->ds_first_leadin == -150)
695 			dsp->ds_first_leadin = 0;
696 	}
697 
698 	if (dsp->ds_last_leadout == 0 && dsp->ds_maxblocks >= 0)
699 		dsp->ds_last_leadout = dsp->ds_maxblocks;
700 
701 	msf.msf_min = dip->lead_in_start[1];
702 	msf.msf_sec = dip->lead_in_start[2];
703 	msf.msf_frame = dip->lead_in_start[3];
704 	dsp->ds_maxrblocks = disk_rcap(&msf, dsp->ds_maxblocks,
705 					FALSE,	/* Always not erasable */
706 					(dip->disk_appl_code[2] & 0x40) != 0);
707 }
708 
709 
710 int	sony_speeds[] = {
711 		-1,		/* Speed null is not allowed */
712 		0,		/* Single speed */
713 		1,		/* Double speed */
714 		-1,		/* Three times */
715 		3,		/* Quad speed */
716 };
717 
718 LOCAL int
speed_select_sony(scgp,dp,speedp)719 speed_select_sony(scgp, dp, speedp)
720 	SCSI	*scgp;
721 	cdr_t	*dp;
722 	int	*speedp;
723 {
724 	struct cdd_52x_mode_data md;
725 	int	count;
726 	int	err;
727 	int	speed = 1;
728 	BOOL	dummy = (dp->cdr_cmdflags & F_DUMMY) != 0;
729 
730 	if (speedp) {
731 		speed = *speedp;
732 		if (speed < 1 || speed > 4 || sony_speeds[speed] < 0)
733 			return (-1);
734 	}
735 
736 	fillbytes((caddr_t)&md, sizeof (md), '\0');
737 
738 	count  = sizeof (struct scsi_mode_header) +
739 		sizeof (struct sony_924_mode_page_20);
740 
741 	md.pagex.page_s20.p_code = 0x20;
742 	md.pagex.page_s20.p_len =  0x06;
743 	md.pagex.page_s20.speudo = dummy?1:0;
744 
745 	/*
746 	 * Set Cue sheet option. This is documented for the 924 and
747 	 * seems to be supported for the 948 too.
748 	 */
749 	md.pagex.page_s20.cue_sheet_opt = 0x03;
750 
751 	err = mode_select(scgp, (Uchar *)&md, count, 0, 1);
752 	if (err < 0)
753 		return (err);
754 
755 	if (speedp == 0)
756 		return (0);
757 
758 	fillbytes((caddr_t)&md, sizeof (md), '\0');
759 
760 	count  = sizeof (struct scsi_mode_header) +
761 		sizeof (struct sony_924_mode_page_31);
762 
763 	md.pagex.page_s31.p_code = 0x31;
764 	md.pagex.page_s31.p_len =  0x02;
765 	md.pagex.page_s31.speed = sony_speeds[speed];
766 
767 	return (mode_select(scgp, (Uchar *)&md, count, 0, 1));
768 }
769 
770 LOCAL int
next_writable_address_sony(scgp,ap,track,sectype,tracktype)771 next_writable_address_sony(scgp, ap, track, sectype, tracktype)
772 	SCSI	*scgp;
773 	long	*ap;
774 	int	track;
775 	int	sectype;
776 	int	tracktype;
777 {
778 	struct	scsi_mode_page_header *mp;
779 	char			mode[256];
780 	int			len = 0x30;
781 	int			page = 0x23;
782 	struct sony_924_mode_page_23	*xp;
783 
784 	fillbytes((caddr_t)mode, sizeof (mode), '\0');
785 
786 	inc_verbose();
787 	if (!get_mode_params(scgp, page, _("CD track information"),
788 			(Uchar *)mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) {
789 		dec_verbose();
790 		return (-1);
791 	}
792 	dec_verbose();
793 	if (len == 0)
794 		return (-1);
795 
796 	mp = (struct scsi_mode_page_header *)
797 		(mode + sizeof (struct scsi_mode_header) +
798 		((struct scsi_mode_header *)mode)->blockdesc_len);
799 
800 
801 	xp = (struct sony_924_mode_page_23 *)mp;
802 
803 #ifdef	SONY_DEBUG
804 	print_sony_mp23(xp, len);
805 #endif
806 	if (ap)
807 		*ap = a_to_4_byte(xp->next_recordable_addr);
808 	return (0);
809 }
810 
811 
812 LOCAL int
new_track_sony(scgp,track,sectype,tracktype)813 new_track_sony(scgp, track, sectype, tracktype)
814 	SCSI	*scgp;
815 	int	track;
816 	int	sectype;
817 	int	tracktype;
818 {
819 	struct	scsi_mode_page_header *mp;
820 	char			mode[256];
821 	int			len = 0x30;
822 	int			page = 0x23;
823 	struct sony_924_mode_page_23	*xp;
824 	int	i;
825 
826 	fillbytes((caddr_t)mode, sizeof (mode), '\0');
827 	get_page22_sony(scgp, mode);
828 
829 	fillbytes((caddr_t)mode, sizeof (mode), '\0');
830 
831 	inc_verbose();
832 	if (!get_mode_params(scgp, page, _("CD track information"),
833 			(Uchar *)mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) {
834 		dec_verbose();
835 		return (-1);
836 	}
837 	dec_verbose();
838 	if (len == 0)
839 		return (-1);
840 
841 	mp = (struct scsi_mode_page_header *)
842 		(mode + sizeof (struct scsi_mode_header) +
843 		((struct scsi_mode_header *)mode)->blockdesc_len);
844 
845 
846 	xp = (struct sony_924_mode_page_23 *)mp;
847 
848 #ifdef	SONY_DEBUG
849 	print_sony_mp23(xp, len);
850 #endif
851 
852 	xp->write_method = 0;	/* Track at one recording */
853 
854 	if (sectype & ST_AUDIOMASK) {
855 		xp->data_form = (sectype & ST_MASK) == ST_AUDIO_PRE ? 0x02 : 0x00;
856 	} else {
857 		if (tracktype == TOC_ROM) {
858 			xp->data_form = (sectype & ST_MASK) == ST_ROM_MODE1 ? 0x10 : 0x11;
859 		} else if (tracktype == TOC_XA1) {
860 			xp->data_form = 0x12;
861 		} else if (tracktype == TOC_XA2) {
862 			xp->data_form = 0x12;
863 		} else if (tracktype == TOC_CDI) {
864 			xp->data_form = 0x12;
865 		}
866 	}
867 
868 	((struct scsi_modesel_header *)mode)->sense_data_len	= 0;
869 	((struct scsi_modesel_header *)mode)->res2		= 0;
870 
871 	i = ((struct scsi_mode_header *)mode)->blockdesc_len;
872 	if (i > 0) {
873 		i_to_3_byte(
874 			((struct scsi_mode_data *)mode)->blockdesc.nlblock,
875 								0);
876 	}
877 
878 	if (mode_select(scgp, (Uchar *)mode, len, 0, scgp->inq->data_format >= 2) < 0) {
879 		return (-1);
880 	}
881 
882 	return (0);
883 }
884 
885 LOCAL int
open_track_sony(scgp,dp,trackp)886 open_track_sony(scgp, dp, trackp)
887 	SCSI	*scgp;
888 	cdr_t	*dp;
889 	track_t *trackp;
890 {
891 	if (!is_tao(trackp) && !is_packet(trackp)) {
892 		if (trackp->pregapsize > 0 && (trackp->flags & TI_PREGAP) == 0) {
893 			if (lverbose) {
894 				printf(_("Writing pregap for track %d at %ld\n"),
895 					(int)trackp->trackno,
896 					trackp->trackstart-trackp->pregapsize);
897 			}
898 			if (trackp->track == 1 && is_hidden(trackp)) {
899 				pad_track(scgp, dp, trackp,
900 					trackp->trackstart-trackp->pregapsize,
901 					(Llong)(trackp->pregapsize-trackp->trackstart)*trackp->secsize,
902 					FALSE, 0);
903 				if (write_track_data(scgp, dp, track_base(trackp)) < 0)
904 					return (-1);
905 			} else {
906 				/*
907 				 * XXX Do we need to check isecsize too?
908 				 */
909 				pad_track(scgp, dp, trackp,
910 					trackp->trackstart-trackp->pregapsize,
911 					(Llong)trackp->pregapsize*trackp->secsize,
912 					FALSE, 0);
913 			}
914 		}
915 		return (0);
916 	}
917 
918 	if (select_secsize(scgp, trackp->secsize) < 0)
919 		return (-1);
920 
921 	if (new_track_sony(scgp, trackp->trackno, trackp->sectype, trackp->tracktype & TOC_MASK) < 0)
922 		return (-1);
923 
924 	if (write_track_sony(scgp, 0L, trackp->sectype) < 0)
925 		return (-1);
926 
927 	return (0);
928 }
929 
930 LOCAL int
open_session_sony(scgp,dp,trackp)931 open_session_sony(scgp, dp, trackp)
932 	SCSI	*scgp;
933 	cdr_t	*dp;
934 	track_t	*trackp;
935 {
936 	struct	scsi_mode_page_header *mp;
937 	char			mode[256];
938 	int	i;
939 	int	len = 0x30;
940 	struct sony_924_mode_page_22	*xp;
941 
942 	fillbytes((caddr_t)mode, sizeof (mode), '\0');
943 
944 	if ((len = get_page22_sony(scgp, mode)) < 0)
945 		return (-1);
946 
947 	mp = (struct scsi_mode_page_header *)
948 		(mode + sizeof (struct scsi_mode_header) +
949 		((struct scsi_mode_header *)mode)->blockdesc_len);
950 
951 	xp = (struct sony_924_mode_page_22 *)mp;
952 
953 	xp->disk_type = toc2sess[track_base(trackp)->tracktype & TOC_MASK];
954 
955 	if (is_tao(track_base(trackp))) {
956 #ifdef	__needed__
957 		if ((track_base(trackp)->tracktype & TOC_MASK) == TOC_DA)
958 			xp->disk_style = 0x80;
959 		else
960 			xp->disk_style = 0xC0;
961 #endif
962 	} else if (is_sao(track_base(trackp))) {
963 		/*
964 		 * We may only change this value if the disk is empty.
965 		 * i.e. when disk_status & 0xC0 == 0x00
966 		 */
967 		if ((xp->disk_status & 0xC0) != 0) {
968 			if (xp->disk_style != 0x00)
969 				errmsgno(EX_BAD, _("Cannot change disk stile for recorded disk.\n"));
970 		}
971 		xp->disk_style = 0x00;
972 	}
973 
974 	((struct scsi_modesel_header *)mode)->sense_data_len	= 0;
975 	((struct scsi_modesel_header *)mode)->res2		= 0;
976 
977 	i = ((struct scsi_mode_header *)mode)->blockdesc_len;
978 	if (i > 0) {
979 		i_to_3_byte(
980 			((struct scsi_mode_data *)mode)->blockdesc.nlblock,
981 								0);
982 	}
983 
984 	if (mode_select(scgp, (Uchar *)mode, len, 0, scgp->inq->data_format >= 2) < 0) {
985 		return (-1);
986 	}
987 /*
988  * XXX set write parameter f�r SAO mit Multi Session (948 only?)
989  * XXX set_wr_parameter_sony(scgp, bp, size);
990  */
991 	return (0);
992 }
993 
994 LOCAL int
abort_session_sony(scgp,dp)995 abort_session_sony(scgp, dp)
996 	SCSI	*scgp;
997 	cdr_t	*dp;
998 {
999 	return (discontinue_sony(scgp));
1000 }
1001 
1002 LOCAL int
get_page22_sony(scgp,mode)1003 get_page22_sony(scgp, mode)
1004 	SCSI	*scgp;
1005 	char	*mode;
1006 {
1007 	struct	scsi_mode_page_header *mp;
1008 	int	len = 0x30;
1009 	int	page = 0x22;
1010 	struct sony_924_mode_page_22	*xp;
1011 
1012 	fillbytes((caddr_t)mode, sizeof (mode), '\0');
1013 
1014 	inc_verbose();
1015 	if (!get_mode_params(scgp, page, _("CD disk information"),
1016 			(Uchar *)mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) {
1017 		dec_verbose();
1018 		return (-1);
1019 	}
1020 	dec_verbose();
1021 	if (len == 0)
1022 		return (-1);
1023 
1024 	mp = (struct scsi_mode_page_header *)
1025 		(mode + sizeof (struct scsi_mode_header) +
1026 		((struct scsi_mode_header *)mode)->blockdesc_len);
1027 
1028 	xp = (struct sony_924_mode_page_22 *)mp;
1029 
1030 #ifdef	SONY_DEBUG
1031 	print_sony_mp22(xp, len);
1032 #endif
1033 	return (len);
1034 }
1035 
1036 /*--------------------------------------------------------------------------*/
1037 
1038 LOCAL Uchar	db2df[] = {
1039 	0x01,			/*  0 2352 bytes of raw data			*/
1040 	0xFF,			/*  1 2368 bytes (raw data + P/Q Subchannel)	*/
1041 	0xFF,			/*  2 2448 bytes (raw data + P-W Subchannel)	*/
1042 	0xFF,			/*  3 2448 bytes (raw data + P-W raw Subchannel)*/
1043 	0xFF,			/*  4 -    Reserved				*/
1044 	0xFF,			/*  5 -    Reserved				*/
1045 	0xFF,			/*  6 -    Reserved				*/
1046 	0xFF,			/*  7 -    Vendor specific			*/
1047 	0x11,			/*  8 2048 bytes Mode 1 (ISO/IEC 10149)		*/
1048 	0xFF,			/*  9 2336 bytes Mode 2 (ISO/IEC 10149)		*/
1049 	0xFF,			/* 10 2048 bytes Mode 2! (CD-ROM XA form 1)	*/
1050 	0xFF,			/* 11 2056 bytes Mode 2 (CD-ROM XA form 1)	*/
1051 	0xFF,			/* 12 2324 bytes Mode 2 (CD-ROM XA form 2)	*/
1052 	0xFF,			/* 13 2332 bytes Mode 2 (CD-ROM XA 1/2+subhdr)	*/
1053 	0xFF,			/* 14 -    Reserved				*/
1054 	0xFF,			/* 15 -    Vendor specific			*/
1055 };
1056 
1057 LOCAL int
gen_cue_sony(trackp,vcuep,needgap)1058 gen_cue_sony(trackp, vcuep, needgap)
1059 	track_t	*trackp;
1060 	void	*vcuep;
1061 	BOOL	needgap;
1062 {
1063 	int	tracks = trackp->tracks;
1064 	int	i;
1065 	struct sony_cue	**cuep = vcuep;
1066 	struct sony_cue	*cue;
1067 	struct sony_cue	*cp;
1068 	int	ncue = 0;
1069 	int	icue = 0;
1070 	int	pgsize;
1071 	msf_t	m;
1072 	int	ctl;
1073 	int	df;
1074 	int	scms;
1075 
1076 	cue = malloc(1);
1077 
1078 	for (i = 0; i <= tracks; i++) {
1079 		ctl = (st2mode[trackp[i].sectype & ST_MASK]) << 4;
1080 		if (is_copy(&trackp[i]))
1081 			ctl |= TM_ALLOW_COPY << 4;
1082 		df = db2df[trackp[i].dbtype & 0x0F];
1083 
1084 #ifdef	__supported__
1085 		if (trackp[i].isrc) {	/* MCN or ISRC */
1086 			ncue += 2;
1087 			cue = realloc(cue, ncue * sizeof (*cue));
1088 			cp = &cue[icue++];
1089 			if (i == 0) {
1090 				cp->cs_ctladr = 0x02;
1091 				movebytes(&trackp[i].isrc[0], &cp->cs_tno, 7);
1092 				cp = &cue[icue++];
1093 				cp->cs_ctladr = 0x02;
1094 				movebytes(&trackp[i].isrc[7], &cp->cs_tno, 7);
1095 			} else {
1096 				cp->cs_ctladr = 0x03;
1097 				cp->cs_tno = i;
1098 				movebytes(&trackp[i].isrc[0], &cp->cs_index, 6);
1099 				cp = &cue[icue++];
1100 				cp->cs_ctladr = 0x03;
1101 				cp->cs_tno = i;
1102 				movebytes(&trackp[i].isrc[6], &cp->cs_index, 6);
1103 			}
1104 		}
1105 #endif
1106 		if (i == 0) {	/* Lead in */
1107 			df &= ~7;
1108 			if (trackp[0].flags & TI_TEXT)	/* CD-Text in Lead-in*/
1109 				df |= 0xC0;
1110 			lba_to_msf(-150, &m);
1111 			cue = realloc(cue, ++ncue * sizeof (*cue));
1112 			cp = &cue[icue++];
1113 			fillcue(cp, ctl|0x01, i, 0, df, 0, &m);
1114 		} else {
1115 			scms = 0;
1116 
1117 			if (is_scms(&trackp[i]))
1118 				scms = 0x80;
1119 			pgsize = trackp[i].pregapsize;
1120 			if (pgsize == 0 && needgap)
1121 				pgsize++;
1122 			lba_to_msf(trackp[i].trackstart-pgsize, &m);
1123 			cue = realloc(cue, ++ncue * sizeof (*cue));
1124 			cp = &cue[icue++];
1125 			fillcue(cp, ctl|0x01, i, 0, df, scms, &m);
1126 
1127 			if (trackp[i].nindex == 1) {
1128 				lba_to_msf(trackp[i].trackstart, &m);
1129 				cue = realloc(cue, ++ncue * sizeof (*cue));
1130 				cp = &cue[icue++];
1131 				fillcue(cp, ctl|0x01, i, 1, df, scms, &m);
1132 			} else {
1133 				int	idx;
1134 				long	*idxlist;
1135 
1136 				ncue += trackp[i].nindex;
1137 				idxlist = trackp[i].tindex;
1138 				cue = realloc(cue, ncue * sizeof (*cue));
1139 
1140 				for (idx = 1; idx <= trackp[i].nindex; idx++) {
1141 					lba_to_msf(trackp[i].trackstart + idxlist[idx], &m);
1142 					cp = &cue[icue++];
1143 					fillcue(cp, ctl|0x01, i, idx, df, scms, &m);
1144 				}
1145 			}
1146 		}
1147 	}
1148 	/* Lead out */
1149 	ctl = (st2mode[trackp[tracks+1].sectype & ST_MASK]) << 4;
1150 	df = db2df[trackp[tracks+1].dbtype & 0x0F];
1151 	df &= ~7;
1152 	lba_to_msf(trackp[tracks+1].trackstart, &m);
1153 	cue = realloc(cue, ++ncue * sizeof (*cue));
1154 	cp = &cue[icue++];
1155 	fillcue(cp, ctl|0x01, 0xAA, 1, df, 0, &m);
1156 
1157 	if (lverbose > 1) {
1158 		for (i = 0; i < ncue; i++) {
1159 			scg_prbytes("", (Uchar *)&cue[i], 8);
1160 		}
1161 	}
1162 	if (cuep)
1163 		*cuep = cue;
1164 	else
1165 		free(cue);
1166 	return (ncue);
1167 }
1168 
1169 
1170 LOCAL void
fillcue(cp,ca,tno,idx,dataform,scms,mp)1171 fillcue(cp, ca, tno, idx, dataform, scms, mp)
1172 	struct sony_cue *cp;	/* The target cue entry		*/
1173 	int	ca;		/* Control/adr for this entry	*/
1174 	int	tno;		/* Track number for this entry	*/
1175 	int	idx;		/* Index for this entry		*/
1176 	int	dataform;	/* Data format for this entry	*/
1177 	int	scms;		/* Serial copy management	*/
1178 	msf_t	*mp;		/* MSF value for this entry	*/
1179 {
1180 	cp->cs_ctladr = ca;
1181 	if (tno <= 99)
1182 		cp->cs_tno = to_bcd(tno);
1183 	else
1184 		cp->cs_tno = tno;
1185 	cp->cs_index = to_bcd(idx);
1186 	cp->cs_dataform = dataform;
1187 	cp->cs_zero = scms;
1188 	cp->cs_min = to_bcd(mp->msf_min);
1189 	cp->cs_sec = to_bcd(mp->msf_sec);
1190 	cp->cs_frame = to_bcd(mp->msf_frame);
1191 }
1192 
1193 LOCAL int
send_cue_sony(scgp,dp,trackp)1194 send_cue_sony(scgp, dp, trackp)
1195 	SCSI	*scgp;
1196 	cdr_t	*dp;
1197 	track_t	*trackp;
1198 {
1199 	struct sony_cue *cp;
1200 	int		ncue;
1201 	int		ret;
1202 	Uint		i;
1203 	struct timeval starttime;
1204 	struct timeval stoptime;
1205 	int		disktype;
1206 
1207 	disktype = toc2sess[track_base(trackp)->tracktype & TOC_MASK];
1208 
1209 	for (i = 1; i <= trackp->tracks; i++) {
1210 		if (trackp[i].tracksize < (tsize_t)0) {
1211 			errmsgno(EX_BAD, _("Track %d has unknown length.\n"), i);
1212 			return (-1);
1213 		}
1214 	}
1215 	ncue = (*dp->cdr_gen_cue)(trackp, &cp, FALSE);
1216 
1217 	starttime.tv_sec = 0;
1218 	starttime.tv_usec = 0;
1219 	stoptime = starttime;
1220 	gettimeofday(&starttime, (struct timezone *)0);
1221 
1222 	scgp->silent++;
1223 	ret  = write_start_sony(scgp, (caddr_t)cp, ncue*8);
1224 	scgp->silent--;
1225 	free(cp);
1226 	if (ret < 0) {
1227 		errmsgno(EX_BAD, _("CUE sheet not accepted. Retrying with minimum pregapsize = 1.\n"));
1228 		ncue = (*dp->cdr_gen_cue)(trackp, &cp, TRUE);
1229 		ret  = write_start_sony(scgp, (caddr_t)cp, ncue*8);
1230 		free(cp);
1231 	}
1232 	if (ret >= 0 && lverbose) {
1233 		gettimeofday(&stoptime, (struct timezone *)0);
1234 		prtimediff(_("Write Lead-in time: "), &starttime, &stoptime);
1235 	}
1236 	return (ret);
1237 }
1238 
1239 LOCAL int
write_leadin_sony(scgp,dp,trackp)1240 write_leadin_sony(scgp, dp, trackp)
1241 	SCSI	*scgp;
1242 	cdr_t	*dp;
1243 	track_t *trackp;
1244 {
1245 	Uint	i;
1246 	long	startsec = 0L;
1247 
1248 /*	if (flags & F_SAO) {*/
1249 	if (wm_base(dp->cdr_dstat->ds_wrmode) == WM_SAO) {
1250 		if (debug || lverbose) {
1251 			printf(_("Sending CUE sheet...\n"));
1252 			flush();
1253 		}
1254 		if (trackp[0].flags & TI_TEXT) {
1255 			if (dp->cdr_speeddef != 4) {
1256 				errmsgno(EX_BAD,
1257 				_("The CDU-924 does not support CD-Text, disabling.\n"));
1258 
1259 				trackp[0].flags &= ~TI_TEXT;
1260 			}
1261 		}
1262 		if ((*dp->cdr_send_cue)(scgp, dp, trackp) < 0) {
1263 			errmsgno(EX_BAD, _("Cannot send CUE sheet.\n"));
1264 			return (-1);
1265 		}
1266 
1267 		if (trackp[0].flags & TI_TEXT) {
1268 			startsec = dp->cdr_dstat->ds_first_leadin;
1269 			printf(_("SAO startsec: %ld\n"), startsec);
1270 		} else {
1271 			startsec = -150;
1272 		}
1273 		if (debug)
1274 			printf(_("SAO startsec: %ld\n"), startsec);
1275 
1276 		if (trackp[0].flags & TI_TEXT) {
1277 			if (startsec > 0) {
1278 				errmsgno(EX_BAD, _("CD-Text must be in first session.\n"));
1279 				return (-1);
1280 			}
1281 			if (debug || lverbose)
1282 				printf(_("Writing lead-in...\n"));
1283 			if (write_cdtext(scgp, dp, startsec) < 0)
1284 				return (-1);
1285 
1286 			dp->cdr_dstat->ds_cdrflags |= RF_LEADIN;
1287 		} else for (i = 1; i <= trackp->tracks; i++) {
1288 			trackp[i].trackstart += startsec +150;
1289 		}
1290 	}
1291 	return (0);
1292 }
1293 
1294 /*--------------------------------------------------------------------------*/
1295 
1296 static const char *sd_cdu_924_error_str[] = {
1297 
1298 	"\200\000write complete",				/* 80 00 */
1299 	"\201\000logical unit is reserved",			/* 81 00 */
1300 	"\205\000audio address not valid",			/* 85 00 */
1301 	"\210\000illegal cue sheet",				/* 88 00 */
1302 	"\211\000inappropriate command",			/* 89 00 */
1303 
1304 	"\266\000media load mechanism failed",			/* B6 00 */
1305 	"\271\000audio play operation aborted",			/* B9 00 */
1306 	"\277\000buffer overflow for read all subcodes command", /* BF 00 */
1307 	"\300\000unrecordable disk",				/* C0 00 */
1308 	"\301\000illegal track status",				/* C1 00 */
1309 	"\302\000reserved track present",			/* C2 00 */
1310 	"\303\000buffer data size error",			/* C3 00 */
1311 	"\304\001illegal data form for reserve track command",	/* C4 01 */
1312 	"\304\002unable to reserve track, because track mode has been changed",	/* C4 02 */
1313 	"\305\000buffer error during at once recording",	/* C5 00 */
1314 	"\306\001unwritten area encountered",			/* C6 01 */
1315 	"\306\002link blocks encountered",			/* C6 02 */
1316 	"\306\003nonexistent block encountered",		/* C6 03 */
1317 	"\307\000disk style mismatch",				/* C7 00 */
1318 	"\310\000no table of contents",				/* C8 00 */
1319 	"\311\000illegal block length for write command",	/* C9 00 */
1320 	"\312\000power calibration error",			/* CA 00 */
1321 	"\313\000write error",					/* CB 00 */
1322 	"\313\001write error track recovered",			/* CB 01 */
1323 	"\314\000not enough space",				/* CC 00 */
1324 	"\315\000no track present to finalize",			/* CD 00 */
1325 	"\316\000unrecoverable track descriptor encountered",	/* CE 00 */
1326 	"\317\000damaged track present",			/* CF 00 */
1327 	"\320\000pma area full",				/* D0 00 */
1328 	"\321\000pca area full",				/* D1 00 */
1329 	"\322\000unrecoverable damaged track cause too small writing area",	/* D2 00 */
1330 	"\323\000no bar code",					/* D3 00 */
1331 	"\323\001not enough bar code margin",			/* D3 01 */
1332 	"\323\002no bar code start pattern",			/* D3 02 */
1333 	"\323\003illegal bar code length",			/* D3 03 */
1334 	"\323\004illegal bar code format",			/* D3 04 */
1335 	"\324\000exit from pseudo track at once recording",	/* D4 00 */
1336 	NULL
1337 };
1338 
1339 LOCAL int
sony_attach(scgp,dp)1340 sony_attach(scgp, dp)
1341 	SCSI	*scgp;
1342 	cdr_t	*dp;
1343 {
1344 	if (scgp->inq != NULL) {
1345 		if (strbeg("CD-R   CDU94", scgp->inq->inq_prod_ident)) {
1346 			dp->cdr_speeddef = 4;
1347 		}
1348 	}
1349 	scg_setnonstderrs(scgp, sd_cdu_924_error_str);
1350 	return (0);
1351 }
1352 
1353 #ifdef	SONY_DEBUG
1354 LOCAL void
print_sony_mp22(xp,len)1355 print_sony_mp22(xp, len)
1356 	struct sony_924_mode_page_22	*xp;
1357 	int				len;
1358 {
1359 	printf("disk style: %X\n", xp->disk_style);
1360 	printf("disk type: %X\n", xp->disk_type);
1361 	printf("first track: %X\n", xp->first_track);
1362 	printf("last track: %X\n", xp->last_track);
1363 	printf("numsess:    %X\n", xp->numsess);
1364 	printf("disk appl code: %lX\n", a_to_u_4_byte(xp->disk_appl_code));
1365 	printf("last start time: %lX\n", a_to_u_4_byte(xp->last_start_time));
1366 	printf("disk status: %X\n", xp->disk_status);
1367 	printf("num valid nra: %X\n", xp->num_valid_nra);
1368 	printf("track info track: %X\n", xp->track_info_track);
1369 	printf("post gap: %X\n", xp->post_gap);
1370 	printf("disk id code: %lX\n", a_to_u_4_byte(xp->disk_id_code));
1371 	printf("lead in start: %lX\n", a_to_u_4_byte(xp->lead_in_start));
1372 }
1373 
1374 LOCAL void
print_sony_mp23(xp,len)1375 print_sony_mp23(xp, len)
1376 	struct sony_924_mode_page_23	*xp;
1377 	int				len;
1378 {
1379 	printf("len: %d\n", len);
1380 
1381 	printf("track num: %X\n", xp->track_num);
1382 	printf("data form: %X\n", xp->data_form);
1383 	printf("write method: %X\n", xp->write_method);
1384 	printf("session: %X\n", xp->session);
1385 	printf("track status: %X\n", xp->track_status);
1386 
1387 /*
1388  * XXX Check for signed/unsigned a_to_*() conversion.
1389  */
1390 	printf("start lba: %lX\n", a_to_4_byte(xp->start_lba));
1391 	printf("next recordable addr: %lX\n", a_to_4_byte(xp->next_recordable_addr));
1392 	printf("blank area cap: %lX\n", a_to_u_4_byte(xp->blank_area_cap));
1393 	printf("fixed packet size: %lX\n", a_to_u_4_byte(xp->fixed_packet_size));
1394 	printf("starting msf: %lX\n", a_to_u_4_byte(xp->starting_msf));
1395 	printf("ending msf: %lX\n", a_to_u_4_byte(xp->ending_msf));
1396 	printf("next rec time: %lX\n", a_to_u_4_byte(xp->next_rec_time));
1397 }
1398 #endif
1399 
1400 LOCAL int
buf_cap_sony(scgp,sp,fp)1401 buf_cap_sony(scgp, sp, fp)
1402 	SCSI	*scgp;
1403 	long	*sp;	/* Size pointer */
1404 	long	*fp;	/* Free pointer */
1405 {
1406 	char	resp[8];
1407 	Ulong	freespace;
1408 	Ulong	bufsize;
1409 	int	per;
1410 	register struct	scg_cmd	*scmd = scgp->scmd;
1411 
1412 	fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
1413 	scmd->addr = (caddr_t)resp;
1414 	scmd->size = sizeof (resp);
1415 	scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
1416 	scmd->cdb_len = SC_G1_CDBLEN;
1417 	scmd->sense_len = CCS_SENSE_LEN;
1418 	scmd->cdb.g1_cdb.cmd = 0xEC;		/* Read buffer cap */
1419 	scmd->cdb.g1_cdb.lun = scg_lun(scgp);
1420 
1421 	scgp->cmdname = "read buffer cap sony";
1422 
1423 	if (scg_cmd(scgp) < 0)
1424 		return (-1);
1425 
1426 	bufsize   = a_to_u_3_byte(&resp[1]);
1427 	freespace = a_to_u_3_byte(&resp[5]);
1428 	if (sp)
1429 		*sp = bufsize;
1430 	if (fp)
1431 		*fp = freespace;
1432 
1433 	if (scgp->verbose || (sp == 0 && fp == 0))
1434 		printf(_("BFree: %ld K BSize: %ld K\n"), freespace >> 10, bufsize >> 10);
1435 
1436 	if (bufsize == 0)
1437 		return (0);
1438 	per = (100 * (bufsize - freespace)) / bufsize;
1439 	if (per < 0)
1440 		return (0);
1441 	if (per > 100)
1442 		return (100);
1443 	return (per);
1444 }
1445