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