1 /* @(#)drv_mmc.c 1.200 12/03/16 Copyright 1997-2012 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)drv_mmc.c 1.200 12/03/16 Copyright 1997-2012 J. Schilling";
6 #endif
7 /*
8 * CDR device implementation for
9 * SCSI-3/mmc conforming drives
10 * e.g. Yamaha CDR-400, Ricoh MP6200
11 *
12 * Copyright (c) 1997-2012 J. Schilling
13 */
14 /*
15 * The contents of this file are subject to the terms of the
16 * Common Development and Distribution License, Version 1.0 only
17 * (the "License"). You may not use this file except in compliance
18 * with the License.
19 *
20 * See the file CDDL.Schily.txt in this distribution for details.
21 * A copy of the CDDL is also available via the Internet at
22 * http://www.opensource.org/licenses/cddl1.txt
23 *
24 * When distributing Covered Code, include this CDDL HEADER in each
25 * file and include the License file CDDL.Schily.txt from this distribution.
26 */
27
28 /*#define DEBUG*/
29 #define PRINT_ATIP
30 #include <schily/mconfig.h>
31
32 #include <schily/stdio.h>
33 #include <schily/standard.h>
34 #include <schily/fcntl.h>
35 #include <schily/errno.h>
36 #include <schily/string.h>
37 #include <schily/stdlib.h>
38 #include <schily/unistd.h>
39 #include <schily/time.h>
40
41 #include <schily/utypes.h>
42 #include <schily/btorder.h>
43 #include <schily/intcvt.h>
44 #include <schily/schily.h>
45 #include <schily/nlsdefs.h>
46
47 #include <scg/scgcmd.h>
48 #include <scg/scsidefs.h>
49 #include <scg/scsireg.h>
50 #include <scg/scsitransp.h>
51
52 #include "scsimmc.h"
53 #include "mmcvendor.h"
54 #include "cdrecord.h"
55
56 extern char *driveropts;
57
58 extern int debug;
59 extern int lverbose;
60 extern int xdebug;
61
62 LOCAL int curspeed = 1;
63
64 LOCAL char clv_to_speed[16] = {
65 /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
66 0, 2, 4, 6, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
67 };
68
69 LOCAL char hs_clv_to_speed[16] = {
70 /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
71 0, 2, 4, 6, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
72 };
73
74 LOCAL char us_clv_to_speed[16] = {
75 /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
76 0, 2, 4, 8, 0, 0, 16, 0, 24, 32, 40, 48, 0, 0, 0, 0
77 };
78
79 #ifdef __needed__
80 LOCAL int mmc_load __PR((SCSI *scgp, cdr_t *dp));
81 LOCAL int mmc_unload __PR((SCSI *scgp, cdr_t *dp));
82 #endif
83 EXPORT void mmc_opthelp __PR((SCSI *scgp, cdr_t *dp, int excode));
84 EXPORT char *hasdrvopt __PR((char *optstr, char *optname));
85 EXPORT char *hasdrvoptx __PR((char *optstr, char *optname, int flag));
86 LOCAL cdr_t *identify_mmc __PR((SCSI *scgp, cdr_t *, struct scsi_inquiry *));
87 LOCAL int attach_mmc __PR((SCSI *scgp, cdr_t *));
88 EXPORT int check_writemodes_mmc __PR((SCSI *scgp, cdr_t *dp));
89 LOCAL int deflt_writemodes_mmc __PR((SCSI *scgp, BOOL reset_dummy));
90 LOCAL void di_to_dstat __PR((struct disk_info *dip, dstat_t *dsp));
91 LOCAL int get_atip __PR((SCSI *scgp, struct atipinfo *atp));
92 #ifdef PRINT_PMA
93 LOCAL int get_pma __PR((SCSI *scgp));
94 #endif
95 LOCAL int init_mmc __PR((SCSI *scgp, cdr_t *dp));
96 LOCAL int getdisktype_mmc __PR((SCSI *scgp, cdr_t *dp));
97 LOCAL int prdiskstatus_mmc __PR((SCSI *scgp, cdr_t *dp));
98 LOCAL int speed_select_mmc __PR((SCSI *scgp, cdr_t *dp, int *speedp));
99 LOCAL int mmc_set_speed __PR((SCSI *scgp, int readspeed, int writespeed, int rotctl));
100 LOCAL int next_wr_addr_mmc __PR((SCSI *scgp, track_t *trackp, long *ap));
101 LOCAL int write_leadin_mmc __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
102 LOCAL int open_track_mmc __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
103 LOCAL int close_track_mmc __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
104 LOCAL int open_session_mmc __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
105 LOCAL int waitfix_mmc __PR((SCSI *scgp, int secs));
106 LOCAL int fixate_mmc __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
107 LOCAL int blank_mmc __PR((SCSI *scgp, cdr_t *dp, long addr, int blanktype));
108 LOCAL int send_opc_mmc __PR((SCSI *scgp, caddr_t, int cnt, int doopc));
109 LOCAL int opt1_mmc __PR((SCSI *scgp, cdr_t *dp));
110 LOCAL int opt2_mmc __PR((SCSI *scgp, cdr_t *dp));
111 LOCAL int scsi_sony_write __PR((SCSI *scgp, caddr_t bp, long sectaddr, long size, int blocks, BOOL islast));
112 LOCAL int gen_cue_mmc __PR((track_t *trackp, void *vcuep, BOOL needgap));
113 LOCAL void fillcue __PR((struct mmc_cue *cp, int ca, int tno, int idx, int dataform, int scms, msf_t *mp));
114 LOCAL int send_cue_mmc __PR((SCSI *scgp, cdr_t *dp, track_t *trackp));
115 LOCAL int stats_mmc __PR((SCSI *scgp, cdr_t *dp));
116 LOCAL BOOL mmc_isplextor __PR((SCSI *scgp));
117 LOCAL BOOL mmc_isyamaha __PR((SCSI *scgp));
118 LOCAL void do_varirec_plextor __PR((SCSI *scgp));
119 LOCAL int do_gigarec_plextor __PR((SCSI *scgp));
120 LOCAL int drivemode_plextor __PR((SCSI *scgp, caddr_t bp, int cnt, int modecode, void *modeval));
121 LOCAL int drivemode2_plextor __PR((SCSI *scgp, caddr_t bp, int cnt, int modecode, void *modeval));
122 LOCAL int check_varirec_plextor __PR((SCSI *scgp));
123 LOCAL int check_gigarec_plextor __PR((SCSI *scgp));
124 LOCAL int varirec_plextor __PR((SCSI *scgp, BOOL on, int val));
125 LOCAL int gigarec_plextor __PR((SCSI *scgp, int val));
126 LOCAL Int32_t gigarec_mult __PR((int code, Int32_t val));
127 LOCAL int check_ss_hide_plextor __PR((SCSI *scgp));
128 LOCAL int check_speed_rd_plextor __PR((SCSI *scgp));
129 LOCAL int check_powerrec_plextor __PR((SCSI *scgp));
130 LOCAL int ss_hide_plextor __PR((SCSI *scgp, BOOL do_ss, BOOL do_hide));
131 LOCAL int speed_rd_plextor __PR((SCSI *scgp, BOOL do_speedrd));
132 LOCAL int powerrec_plextor __PR((SCSI *scgp, BOOL do_powerrec));
133 LOCAL int get_speeds_plextor __PR((SCSI *scgp, int *selp, int *maxp, int *lastp));
134 LOCAL int bpc_plextor __PR((SCSI *scgp, int mode, int *bpp));
135 LOCAL int plextor_enable __PR((SCSI *scgp));
136 LOCAL int plextor_disable __PR((SCSI *scgp));
137 LOCAL int plextor_getauth __PR((SCSI *scgp, void *dp, int cnt));
138 LOCAL int plextor_setauth __PR((SCSI *scgp, void *dp, int cnt));
139 LOCAL int set_audiomaster_yamaha __PR((SCSI *scgp, cdr_t *dp, BOOL keep_mode));
140
141 EXPORT struct ricoh_mode_page_30 * get_justlink_ricoh __PR((SCSI *scgp, Uchar *mode));
142 LOCAL int force_speed_yamaha __PR((SCSI *scgp, int readspeed, int writespeed));
143 LOCAL BOOL get_tattoo_yamaha __PR((SCSI *scgp, BOOL print, Int32_t *irp, Int32_t *orp));
144 LOCAL int do_tattoo_yamaha __PR((SCSI *scgp, FILE *f));
145 LOCAL int yamaha_write_buffer __PR((SCSI *scgp, int mode, int bufferid, long offset,
146 long parlen, void *buffer, long buflen));
147
148 #ifdef __needed__
149 LOCAL int
mmc_load(scgp,dp)150 mmc_load(scgp, dp)
151 SCSI *scgp;
152 cdr_t *dp;
153 {
154 return (scsi_load_unload(scgp, 1));
155 }
156
157 LOCAL int
mmc_unload(scgp,dp)158 mmc_unload(scgp, dp)
159 SCSI *scgp;
160 cdr_t *dp;
161 {
162 return (scsi_load_unload(scgp, 0));
163 }
164 #endif
165
166 /*
167 * MMC CD-writer
168 */
169 cdr_t cdr_mmc = {
170 0, 0, 0,
171 CDR_SWABAUDIO,
172 0,
173 CDR_CDRW_ALL,
174 WM_SAO,
175 372, 372,
176 "mmc_cdr",
177 "generic SCSI-3/mmc CD-R/CD-RW driver",
178 0,
179 (dstat_t *)0,
180 identify_mmc,
181 attach_mmc,
182 init_mmc,
183 getdisktype_mmc,
184 prdiskstatus_mmc,
185 scsi_load,
186 scsi_unload,
187 read_buff_cap,
188 cmd_dummy, /* recovery_needed */
189 (int(*)__PR((SCSI *, cdr_t *, int)))cmd_dummy, /* recover */
190 speed_select_mmc,
191 select_secsize,
192 next_wr_addr_mmc,
193 (int(*)__PR((SCSI *, Ulong)))cmd_ill, /* reserve_track */
194 scsi_cdr_write,
195 gen_cue_mmc,
196 send_cue_mmc,
197 write_leadin_mmc,
198 open_track_mmc,
199 close_track_mmc,
200 open_session_mmc,
201 cmd_dummy,
202 cmd_dummy, /* abort */
203 read_session_offset,
204 fixate_mmc,
205 stats_mmc,
206 blank_mmc,
207 format_dummy,
208 send_opc_mmc,
209 opt1_mmc,
210 opt2_mmc,
211 };
212
213 /*
214 * Sony MMC CD-writer
215 */
216 cdr_t cdr_mmc_sony = {
217 0, 0, 0,
218 CDR_SWABAUDIO,
219 0,
220 CDR_CDRW_ALL,
221 WM_SAO,
222 372, 372,
223 "mmc_cdr_sony",
224 "generic SCSI-3/mmc CD-R/CD-RW driver (Sony 928 variant)",
225 0,
226 (dstat_t *)0,
227 identify_mmc,
228 attach_mmc,
229 init_mmc,
230 getdisktype_mmc,
231 prdiskstatus_mmc,
232 scsi_load,
233 scsi_unload,
234 read_buff_cap,
235 cmd_dummy, /* recovery_needed */
236 (int(*)__PR((SCSI *, cdr_t *, int)))cmd_dummy, /* recover */
237 speed_select_mmc,
238 select_secsize,
239 next_wr_addr_mmc,
240 (int(*)__PR((SCSI *, Ulong)))cmd_ill, /* reserve_track */
241 scsi_sony_write,
242 gen_cue_mmc,
243 send_cue_mmc,
244 write_leadin_mmc,
245 open_track_mmc,
246 close_track_mmc,
247 open_session_mmc,
248 cmd_dummy,
249 cmd_dummy, /* abort */
250 read_session_offset,
251 fixate_mmc,
252 cmd_dummy, /* stats */
253 blank_mmc,
254 format_dummy,
255 send_opc_mmc,
256 opt1_mmc,
257 opt2_mmc,
258 };
259
260 /*
261 * SCSI-3/mmc conformant CD-ROM drive
262 */
263 cdr_t cdr_cd = {
264 0, 0, 0,
265 CDR_ISREADER|CDR_SWABAUDIO,
266 0,
267 CDR_CDRW_NONE,
268 WM_NONE,
269 372, 372,
270 "mmc_cd",
271 "generic SCSI-3/mmc CD-ROM driver",
272 0,
273 (dstat_t *)0,
274 identify_mmc,
275 attach_mmc,
276 cmd_dummy,
277 drive_getdisktype,
278 prdiskstatus_mmc,
279 scsi_load,
280 scsi_unload,
281 read_buff_cap,
282 cmd_dummy, /* recovery_needed */
283 (int(*)__PR((SCSI *, cdr_t *, int)))cmd_dummy, /* recover */
284 speed_select_mmc,
285 select_secsize,
286 (int(*)__PR((SCSI *scgp, track_t *, long *)))cmd_ill, /* next_wr_addr */
287 (int(*)__PR((SCSI *, Ulong)))cmd_ill, /* reserve_track */
288 scsi_cdr_write,
289 (int(*)__PR((track_t *, void *, BOOL)))cmd_dummy, /* gen_cue */
290 no_sendcue,
291 (int(*)__PR((SCSI *, cdr_t *, track_t *)))cmd_dummy, /* leadin */
292 open_track_mmc,
293 close_track_mmc,
294 (int(*)__PR((SCSI *scgp, cdr_t *, track_t *)))cmd_dummy,
295 cmd_dummy,
296 cmd_dummy, /* abort */
297 read_session_offset,
298 (int(*)__PR((SCSI *scgp, cdr_t *, track_t *)))cmd_dummy, /* fixation */
299 cmd_dummy, /* stats */
300 blank_dummy,
301 format_dummy,
302 (int(*)__PR((SCSI *, caddr_t, int, int)))NULL, /* no OPC */
303 cmd_dummy, /* opt1 */
304 cmd_dummy, /* opt2 */
305 };
306
307 /*
308 * Old pre SCSI-3/mmc CD drive
309 */
310 cdr_t cdr_oldcd = {
311 0, 0, 0,
312 CDR_ISREADER,
313 0,
314 CDR_CDRW_NONE,
315 WM_NONE,
316 372, 372,
317 "scsi2_cd",
318 "generic SCSI-2 CD-ROM driver",
319 0,
320 (dstat_t *)0,
321 identify_mmc,
322 drive_attach,
323 cmd_dummy,
324 drive_getdisktype,
325 prdiskstatus_mmc,
326 scsi_load,
327 scsi_unload,
328 buf_dummy,
329 cmd_dummy, /* recovery_needed */
330 (int(*)__PR((SCSI *, cdr_t *, int)))cmd_dummy, /* recover */
331 speed_select_mmc,
332 select_secsize,
333 (int(*)__PR((SCSI *scg, track_t *, long *)))cmd_ill, /* next_wr_addr */
334 (int(*)__PR((SCSI *, Ulong)))cmd_ill, /* reserve_track */
335 scsi_cdr_write,
336 (int(*)__PR((track_t *, void *, BOOL)))cmd_dummy, /* gen_cue */
337 no_sendcue,
338 (int(*)__PR((SCSI *, cdr_t *, track_t *)))cmd_dummy, /* leadin */
339 open_track_mmc,
340 close_track_mmc,
341 (int(*)__PR((SCSI *scgp, cdr_t *, track_t *)))cmd_dummy,
342 cmd_dummy,
343 cmd_dummy, /* abort */
344 read_session_offset_philips,
345 (int(*)__PR((SCSI *scgp, cdr_t *, track_t *)))cmd_dummy, /* fixation */
346 cmd_dummy, /* stats */
347 blank_dummy,
348 format_dummy,
349 (int(*)__PR((SCSI *, caddr_t, int, int)))NULL, /* no OPC */
350 cmd_dummy, /* opt1 */
351 cmd_dummy, /* opt2 */
352 };
353
354 /*
355 * SCSI-3/mmc conformant CD, DVD or BE writer
356 * Checks the current medium and then returns either cdr_mmc or cdr_dvd
357 */
358 cdr_t cdr_cd_dvd = {
359 0, 0, 0,
360 CDR_SWABAUDIO,
361 0,
362 CDR_CDRW_ALL,
363 WM_NONE,
364 372, 372,
365 "mmc_cd_dvd",
366 "generic SCSI-3/mmc CD/DVD/BD driver (checks media)",
367 0,
368 (dstat_t *)0,
369 identify_mmc,
370 attach_mmc,
371 cmd_dummy,
372 drive_getdisktype,
373 no_diskstatus,
374 scsi_load,
375 scsi_unload,
376 read_buff_cap,
377 cmd_dummy, /* recovery_needed */
378 (int(*)__PR((SCSI *, cdr_t *, int)))cmd_dummy, /* recover */
379 speed_select_mmc,
380 select_secsize,
381 (int(*)__PR((SCSI *scgp, track_t *, long *)))cmd_ill, /* next_wr_addr */
382 (int(*)__PR((SCSI *, Ulong)))cmd_ill, /* reserve_track */
383 scsi_cdr_write,
384 (int(*)__PR((track_t *, void *, BOOL)))cmd_dummy, /* gen_cue */
385 no_sendcue,
386 (int(*)__PR((SCSI *, cdr_t *, track_t *)))cmd_dummy, /* leadin */
387 open_track_mmc,
388 close_track_mmc,
389 (int(*)__PR((SCSI *scgp, cdr_t *, track_t *)))cmd_dummy,
390 cmd_dummy,
391 cmd_dummy, /* abort */
392 read_session_offset,
393 (int(*)__PR((SCSI *scgp, cdr_t *, track_t *)))cmd_dummy, /* fixation */
394 cmd_dummy, /* stats */
395 blank_dummy,
396 format_dummy,
397 (int(*)__PR((SCSI *, caddr_t, int, int)))NULL, /* no OPC */
398 cmd_dummy, /* opt1 */
399 cmd_dummy, /* opt2 */
400 };
401
402 EXPORT void
mmc_opthelp(scgp,dp,excode)403 mmc_opthelp(scgp, dp, excode)
404 SCSI *scgp;
405 cdr_t *dp;
406 int excode;
407 {
408 BOOL haveopts = FALSE;
409
410 error(_("Driver options:\n"));
411 if (dp->cdr_flags & CDR_BURNFREE) {
412 error("burnfree Prepare writer to use BURN-Free technology\n");
413 error("noburnfree Disable using BURN-Free technology\n");
414 haveopts = TRUE;
415 }
416 if (dp->cdr_flags & CDR_VARIREC) {
417 error("varirec=val Set VariRec Laserpower to -2, -1, 0, 1, 2\n");
418 error(" Only works for audio and if speed is set to 4\n");
419 haveopts = TRUE;
420 }
421 if (dp->cdr_flags & CDR_GIGAREC) {
422 error("gigarec=val Set GigaRec capacity ratio to 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4\n");
423 haveopts = TRUE;
424 }
425 if (dp->cdr_flags & CDR_AUDIOMASTER) {
426 error("audiomaster Turn Audio Master feature on (SAO CD-R Audio/Data only)\n");
427 haveopts = TRUE;
428 }
429 if (dp->cdr_flags & CDR_FORCESPEED) {
430 error("forcespeed Tell the drive to force speed even for low quality media\n");
431 haveopts = TRUE;
432 }
433 if (dp->cdr_flags & CDR_SPEEDREAD) {
434 error("speedread Tell the drive to read as fast as possible\n");
435 error("nospeedread Disable to read as fast as possible\n");
436 haveopts = TRUE;
437 }
438 if (dp->cdr_flags & CDR_DISKTATTOO) {
439 error("tattooinfo Print image size info for DiskT@2 feature\n");
440 error("tattoofile=name Use 'name' as DiskT@2 image file\n");
441 haveopts = TRUE;
442 }
443 if (dp->cdr_flags & CDR_SINGLESESS) {
444 error("singlesession Tell the drive to behave as single session only drive\n");
445 error("nosinglesession Disable single session only mode\n");
446 haveopts = TRUE;
447 }
448 if (dp->cdr_flags & CDR_HIDE_CDR) {
449 error("hidecdr Tell the drive to hide CD-R media\n");
450 error("nohidecdr Disable hiding CD-R media\n");
451 haveopts = TRUE;
452 }
453 if (dp->cdr_flags & CDR_LAYER_JUMP) {
454 error("layerbreak Write DVD-R/DL media in automatic layer jump mode\n");
455 haveopts = TRUE;
456 }
457 if ((dp->cdr_flags & CDR_LAYER_JUMP) || get_curprofile(scgp) == 0x2B) {
458 error("layerbreak=val Set jayer jump address for DVD+-R/DL media\n");
459 haveopts = TRUE;
460 }
461 if (!haveopts) {
462 error("None supported for this drive.\n");
463 }
464 exit(excode);
465 }
466
467 EXPORT char *
hasdrvopt(optstr,optname)468 hasdrvopt(optstr, optname)
469 char *optstr;
470 char *optname;
471 {
472 return (hasdrvoptx(optstr, optname, 1));
473 }
474
475 EXPORT char *
hasdrvoptx(optstr,optname,flag)476 hasdrvoptx(optstr, optname, flag)
477 char *optstr;
478 char *optname;
479 int flag;
480 {
481 char *ep;
482 char *np;
483 char *ret = NULL;
484 int optnamelen;
485 int optlen;
486 BOOL not = FALSE;
487
488 if (optstr == NULL)
489 return (ret);
490
491 optnamelen = strlen(optname);
492
493 while (*optstr) {
494 not = FALSE; /* Reset before every token */
495 if ((ep = strchr(optstr, ',')) != NULL) {
496 optlen = ep - optstr;
497 np = &ep[1];
498 } else {
499 optlen = strlen(optstr);
500 np = &optstr[optlen];
501 }
502 if ((ep = strchr(optstr, '=')) != NULL) {
503 if (ep < np)
504 optlen = ep - optstr;
505 }
506 if (optstr[0] == '!') {
507 optstr++;
508 optlen--;
509 not = TRUE;
510 }
511 if (strncmp(optstr, "no", 2) == 0) {
512 optstr += 2;
513 optlen -= 2;
514 not = TRUE;
515 }
516 if (optlen == optnamelen &&
517 strncmp(optstr, optname, optlen) == 0) {
518 ret = &optstr[optlen];
519 break;
520 }
521 optstr = np;
522 }
523 if (ret != NULL) {
524 if (*ret == ',' || *ret == '\0') {
525 if (flag) {
526 if (not)
527 return ("0");
528 return ("1");
529 }
530 if (not)
531 return (NULL);
532 return ("");
533 }
534 if (*ret == '=') {
535 if (not)
536 return (NULL);
537 return (++ret);
538 }
539 }
540 return (ret);
541 }
542
543 LOCAL cdr_t *
identify_mmc(scgp,dp,ip)544 identify_mmc(scgp, dp, ip)
545 SCSI *scgp;
546 cdr_t *dp;
547 struct scsi_inquiry *ip;
548 {
549 BOOL cdrr = FALSE; /* Read CD-R */
550 BOOL cdwr = FALSE; /* Write CD-R */
551 BOOL cdrrw = FALSE; /* Read CD-RW */
552 BOOL cdwrw = FALSE; /* Write CD-RW */
553 BOOL dvdwr = FALSE; /* DVD writer */
554 BOOL is_dvd = FALSE; /* use DVD driver*/
555 Uchar mode[0x100];
556 struct cd_mode_page_2A *mp;
557 int profile;
558
559 if (ip->type != INQ_WORM && ip->type != INQ_ROMD)
560 return ((cdr_t *)0);
561
562 allow_atapi(scgp, TRUE); /* Try to switch to 10 byte mode cmds */
563
564 scgp->silent++;
565 mp = mmc_cap(scgp, mode); /* Get MMC capabilities */
566 scgp->silent--;
567 if (mp == NULL)
568 return (&cdr_oldcd); /* Pre SCSI-3/mmc drive */
569
570 /*
571 * At this point we know that we have a SCSI-3/mmc compliant drive.
572 * Unfortunately ATAPI drives violate the SCSI spec in returning
573 * a response data format of '1' which from the SCSI spec would
574 * tell us not to use the "PF" bit in mode select. As ATAPI drives
575 * require the "PF" bit to be set, we 'correct' the inquiry data.
576 *
577 * XXX xxx_identify() should not have any side_effects ??
578 */
579 if (ip->data_format < 2)
580 ip->data_format = 2;
581
582 /*
583 * First handle exceptions....
584 */
585 if (strncmp(ip->inq_vendor_info, "SONY", 4) == 0 &&
586 strncmp(ip->inq_prod_ident, "CD-R CDU928E", 14) == 0) {
587 return (&cdr_mmc_sony);
588 }
589
590 /*
591 * Now try to do it the MMC-3 way....
592 */
593 profile = get_curprofile(scgp);
594 if (xdebug)
595 printf("Current profile: 0x%04X\n", profile);
596 if (profile == 0) {
597 if (xdebug)
598 print_profiles(scgp);
599 /*
600 * If the current profile is 0x0000, then the
601 * drive does not know about the media. First
602 * close the tray and then try to issue the
603 * get_curprofile() command again.
604 */
605 scgp->silent++;
606 load_media(scgp, dp, FALSE);
607 scgp->silent--;
608 profile = get_curprofile(scgp);
609 scsi_prevent_removal(scgp, 0);
610 if (xdebug)
611 printf("Current profile: 0x%04X\n", profile);
612 }
613 if (profile >= 0) {
614 if (lverbose)
615 print_profiles(scgp);
616 if (lverbose > 1)
617 print_features(scgp);
618 /* NONE DVD-MINUS-END */
619 if (profile == 0 || profile > 0x19) {
620 is_dvd = FALSE;
621 dp = &cdr_cd;
622
623 if (profile == 0) { /* No Medium */
624 BOOL is_cdr = FALSE;
625
626 /*
627 * Check for CD-writer
628 */
629 get_wproflist(scgp, &is_cdr, NULL,
630 NULL, NULL);
631 if (is_cdr)
632 return (&cdr_mmc);
633 /*
634 * Other MMC-3 drive without media
635 */
636 return (dp);
637 }
638 if (profile <= 0x1F || /* DVD+RW DVD+R */
639 profile == 0x2B) { /* DVD+R/DL */
640 extern cdr_t cdr_dvdplus;
641
642 dp = &cdr_dvdplus;
643 dp = dp->cdr_identify(scgp, dp, scgp->inq);
644 return (dp);
645 } else if (profile >= 0x40 && profile <= 0x4F) {
646 extern cdr_t cdr_bd;
647
648 dp = &cdr_bd;
649 dp = dp->cdr_identify(scgp, dp, scgp->inq);
650 return (dp);
651 } else if (profile >= 0x50 && profile <= 0x5F) {
652 errmsgno(EX_BAD,
653 "Found unsupported HD-DVD 0x%X profile.\n", profile);
654 errmsgno(EX_BAD,
655 "If you need HD-DVD support, sponsor a sample drive.\n");
656 return ((cdr_t *)0);
657 } else {
658 errmsgno(EX_BAD,
659 "Found unsupported 0x%X profile.\n", profile);
660 return ((cdr_t *)0);
661 }
662 } else if (profile >= 0x10 && profile <= 0x19) {
663 extern cdr_t cdr_dvd;
664
665 dp = &cdr_dvd;
666 dp = dp->cdr_identify(scgp, dp, scgp->inq);
667 return (dp);
668 }
669 } else {
670 /*
671 * profile < 0
672 */
673 if (xdebug)
674 printf("Drive is pre MMC-3\n");
675 }
676
677 mmc_getval(mp, &cdrr, &cdwr, &cdrrw, &cdwrw, NULL, &dvdwr);
678
679 if (!cdwr && !cdwrw) { /* SCSI-3/mmc CD drive */
680 /*
681 * If the drive does not support to write CD's, we select the
682 * CD-ROM driver here. If we have DVD-R/DVD-RW support compiled
683 * in, we may later decide to switch to the DVD driver.
684 */
685 dp = &cdr_cd;
686 } else {
687 /*
688 * We need to set the driver to cdr_mmc because we may come
689 * here with driver set to cdr_cd_dvd which is not a driver
690 * that may be used for actual CD/DVD writing.
691 */
692 dp = &cdr_mmc;
693 }
694
695 /*#define DVD_DEBUG*/
696 #ifdef DVD_DEBUG
697 if (1) { /* Always check for DVD media in debug mode */
698 #else
699 if (profile < 0 && ((cdwr || cdwrw) && dvdwr)) {
700 #endif
701 char xb[32];
702
703 /*
704 * Be careful here. It has been reported that the
705 * Pioneer DVR-110 will lock up in case that
706 * read_dvd_structure() is called if a non-DVD medium is
707 * loaded. For this reason, we only come here with
708 * Pre MMC-3 drives.
709 */
710 #ifndef DVD_DEBUG
711 scgp->silent++;
712 #else
713 error("identify_dvd: checking for DVD media\n");
714 #endif
715 if (read_dvd_structure(scgp, (caddr_t)xb, 32, 0, 0, 0, 0) >= 0) {
716 /*
717 * If read DVD structure is supported and works, then
718 * we must have a DVD media in the drive. Signal to
719 * use the DVD driver.
720 */
721 is_dvd = TRUE;
722 } else {
723 if (scg_sense_key(scgp) == SC_NOT_READY) {
724 /*
725 * If the SCSI sense key is NOT READY, then the
726 * drive does not know about the media. First
727 * close the tray and then try to issue the
728 * read_dvd_structure() command again.
729 */
730 load_media(scgp, dp, FALSE);
731 if (read_dvd_structure(scgp, (caddr_t)xb, 32, 0, 0, 0, 0) >= 0) {
732 is_dvd = TRUE;
733 }
734 scsi_prevent_removal(scgp, 0);
735 }
736 }
737 #ifndef DVD_DEBUG
738 scgp->silent--;
739 #else
740 error("identify_dvd: is_dvd: %d\n", is_dvd);
741 #endif
742 }
743 if (is_dvd) {
744 extern cdr_t cdr_dvd;
745
746 dp = &cdr_dvd;
747 dp = dp->cdr_identify(scgp, dp, scgp->inq);
748 return (dp);
749 }
750 return (dp);
751 }
752
753 LOCAL int
attach_mmc(scgp,dp)754 attach_mmc(scgp, dp)
755 SCSI *scgp;
756 cdr_t *dp;
757 {
758 int ret;
759 Uchar mode[0x100];
760 struct cd_mode_page_2A *mp;
761 struct ricoh_mode_page_30 *rp = NULL;
762
763 allow_atapi(scgp, TRUE); /* Try to switch to 10 byte mode cmds */
764
765 scgp->silent++;
766 mp = mmc_cap(scgp, NULL); /* Get MMC capabilities in allocated mp */
767 scgp->silent--;
768 if (mp == NULL)
769 return (-1); /* Pre SCSI-3/mmc drive */
770
771 dp->cdr_cdcap = mp; /* Store MMC cap pointer */
772
773 dp->cdr_dstat->ds_dr_max_rspeed = a_to_u_2_byte(mp->max_read_speed)/176;
774 if (dp->cdr_dstat->ds_dr_max_rspeed == 0)
775 dp->cdr_dstat->ds_dr_max_rspeed = 372;
776 dp->cdr_dstat->ds_dr_cur_rspeed = a_to_u_2_byte(mp->cur_read_speed)/176;
777 if (dp->cdr_dstat->ds_dr_cur_rspeed == 0)
778 dp->cdr_dstat->ds_dr_cur_rspeed = 372;
779
780 dp->cdr_dstat->ds_dr_max_wspeed = a_to_u_2_byte(mp->max_write_speed)/176;
781 if (mp->p_len >= 28)
782 dp->cdr_dstat->ds_dr_cur_wspeed = a_to_u_2_byte(mp->v3_cur_write_speed)/176;
783 else
784 dp->cdr_dstat->ds_dr_cur_wspeed = a_to_u_2_byte(mp->cur_write_speed)/176;
785
786 if (dp->cdr_speedmax > dp->cdr_dstat->ds_dr_max_wspeed)
787 dp->cdr_speedmax = dp->cdr_dstat->ds_dr_max_wspeed;
788
789 if (dp->cdr_speeddef > dp->cdr_speedmax)
790 dp->cdr_speeddef = dp->cdr_speedmax;
791
792 rp = get_justlink_ricoh(scgp, mode);
793
794 if (mp->p_len >= 28)
795 dp->cdr_flags |= CDR_MMC3;
796 if (mp->p_len >= 24)
797 dp->cdr_flags |= CDR_MMC2;
798 dp->cdr_flags |= CDR_MMC;
799
800 if (mp->loading_type == LT_TRAY)
801 dp->cdr_flags |= CDR_TRAYLOAD;
802 else if (mp->loading_type == LT_CADDY)
803 dp->cdr_flags |= CDR_CADDYLOAD;
804
805 if (mp->BUF != 0) {
806 dp->cdr_flags |= CDR_BURNFREE;
807 } else if (rp) {
808 if ((dp->cdr_cmdflags & F_DUMMY) && rp->TWBFS && rp->BUEFS)
809 dp->cdr_flags |= CDR_BURNFREE;
810
811 if (rp->BUEFS)
812 dp->cdr_flags |= CDR_BURNFREE;
813 }
814
815 if (mmc_isplextor(scgp)) {
816 char *p;
817
818 p = hasdrvopt(driveropts, "plexdisable");
819 if (p != NULL && *p == '1') {
820 plextor_disable(scgp);
821 } else {
822 p = NULL;
823 }
824
825 if (check_varirec_plextor(scgp) >= 0)
826 dp->cdr_flags |= CDR_VARIREC;
827
828 if (check_gigarec_plextor(scgp) < 0 && p == NULL)
829 plextor_enable(scgp);
830
831 if (check_gigarec_plextor(scgp) >= 0)
832 dp->cdr_flags |= CDR_GIGAREC;
833
834 if (check_ss_hide_plextor(scgp) >= 0)
835 dp->cdr_flags |= CDR_SINGLESESS|CDR_HIDE_CDR;
836
837 if (check_powerrec_plextor(scgp) >= 0)
838 dp->cdr_flags |= CDR_FORCESPEED;
839
840 if (check_speed_rd_plextor(scgp) >= 0)
841 dp->cdr_flags |= CDR_SPEEDREAD;
842
843 /*
844 * Newer Plextor drives
845 */
846 if (set_audiomaster_yamaha(scgp, dp, FALSE) >= 0)
847 dp->cdr_flags |= CDR_AUDIOMASTER;
848 }
849 if (mmc_isyamaha(scgp)) {
850 if (set_audiomaster_yamaha(scgp, dp, FALSE) >= 0)
851 dp->cdr_flags |= CDR_AUDIOMASTER;
852
853 /*
854 * Starting with CRW 2200 / CRW 3200
855 */
856 if ((mp->p_len+2) >= (unsigned)28)
857 dp->cdr_flags |= CDR_FORCESPEED;
858
859 if (get_tattoo_yamaha(scgp, FALSE, 0, 0))
860 dp->cdr_flags |= CDR_DISKTATTOO;
861 }
862
863 if (rp && rp->AWSCS)
864 dp->cdr_flags |= CDR_FORCESPEED;
865
866 #ifdef FUTURE_ROTCTL
867 if (mp->p_len >= 28) {
868 int val;
869
870 val = dp->cdr_dstat->ds_dr_cur_wspeed;
871 if (val == 0)
872 val = 372;
873
874 scgp->verbose++;
875 if (scsi_set_speed(scgp, -1, val, ROTCTL_CAV) < 0) {
876 error("XXX\n");
877 }
878 scgp->verbose--;
879 }
880 #endif
881
882 check_writemodes_mmc(scgp, dp);
883
884 if (driveropts != NULL) {
885 char *p;
886
887 if (strcmp(driveropts, "help") == 0) {
888 mmc_opthelp(scgp, dp, 0);
889 }
890
891 p = hasdrvopt(driveropts, "burnfree");
892 if (p == NULL)
893 p = hasdrvopt(driveropts, "burnproof");
894 if (p != NULL && (dp->cdr_flags & CDR_BURNFREE) != 0) {
895 if (*p == '1') {
896 dp->cdr_dstat->ds_cdrflags |= RF_BURNFREE;
897 } else if (*p == '0') {
898 dp->cdr_dstat->ds_cdrflags &= ~RF_BURNFREE;
899 }
900 }
901
902 p = hasdrvopt(driveropts, "varirec");
903 if (p != NULL && (dp->cdr_flags & CDR_VARIREC) != 0) {
904 dp->cdr_dstat->ds_cdrflags |= RF_VARIREC;
905 }
906
907 p = hasdrvopt(driveropts, "gigarec");
908 if (p != NULL && (dp->cdr_flags & CDR_GIGAREC) != 0) {
909 dp->cdr_dstat->ds_cdrflags |= RF_GIGAREC;
910 }
911
912 p = hasdrvopt(driveropts, "audiomaster");
913 if (p != NULL && *p == '1' && (dp->cdr_flags & CDR_AUDIOMASTER) != 0) {
914 dp->cdr_dstat->ds_cdrflags |= RF_AUDIOMASTER;
915 dp->cdr_dstat->ds_cdrflags &= ~RF_BURNFREE;
916 }
917 p = hasdrvopt(driveropts, "forcespeed");
918 if (p != NULL && *p == '1' && (dp->cdr_flags & CDR_FORCESPEED) != 0) {
919 dp->cdr_dstat->ds_cdrflags |= RF_FORCESPEED;
920 }
921 p = hasdrvopt(driveropts, "tattooinfo");
922 if (p != NULL && *p == '1' && (dp->cdr_flags & CDR_DISKTATTOO) != 0) {
923 get_tattoo_yamaha(scgp, TRUE, 0, 0);
924 }
925 p = hasdrvopt(driveropts, "tattoofile");
926 if (p != NULL && (dp->cdr_flags & CDR_DISKTATTOO) != 0) {
927 FILE *f;
928
929 if ((f = fileopen(p, "rb")) == NULL)
930 comerr("Cannot open '%s'.\n", p);
931
932 if (do_tattoo_yamaha(scgp, f) < 0)
933 errmsgno(EX_BAD, "Cannot do DiskT@2.\n");
934 fclose(f);
935 }
936 p = hasdrvopt(driveropts, "singlesession");
937 if (p != NULL && (dp->cdr_flags & CDR_SINGLESESS) != 0) {
938 if (*p == '1') {
939 dp->cdr_dstat->ds_cdrflags |= RF_SINGLESESS;
940 } else if (*p == '0') {
941 dp->cdr_dstat->ds_cdrflags &= ~RF_SINGLESESS;
942 }
943 }
944 p = hasdrvopt(driveropts, "hidecdr");
945 if (p != NULL && (dp->cdr_flags & CDR_HIDE_CDR) != 0) {
946 if (*p == '1') {
947 dp->cdr_dstat->ds_cdrflags |= RF_HIDE_CDR;
948 } else if (*p == '0') {
949 dp->cdr_dstat->ds_cdrflags &= ~RF_HIDE_CDR;
950 }
951 }
952 p = hasdrvopt(driveropts, "speedread");
953 if (p != NULL && (dp->cdr_flags & CDR_SPEEDREAD) != 0) {
954 if (*p == '1') {
955 dp->cdr_dstat->ds_cdrflags |= RF_SPEEDREAD;
956 } else if (*p == '0') {
957 dp->cdr_dstat->ds_cdrflags &= ~RF_SPEEDREAD;
958 }
959 }
960 }
961
962 if ((ret = get_supported_cdrw_media_types(scgp)) < 0) {
963 dp->cdr_cdrw_support = CDR_CDRW_ALL;
964 return (0);
965 }
966 dp->cdr_cdrw_support = ret;
967 if (lverbose > 1)
968 printf("Supported CD-RW media types: %02X\n", dp->cdr_cdrw_support);
969
970 return (0);
971 }
972
973
974 EXPORT int
check_writemodes_mmc(scgp,dp)975 check_writemodes_mmc(scgp, dp)
976 SCSI *scgp;
977 cdr_t *dp;
978 {
979 Uchar mode[0x100];
980 int len;
981 struct cd_mode_page_05 *mp;
982
983 if (xdebug)
984 printf("Checking possible write modes: ");
985
986 /*
987 * Reset mp->test_write (-dummy) here.
988 */
989 deflt_writemodes_mmc(scgp, TRUE);
990
991 fillbytes((caddr_t)mode, sizeof (mode), '\0');
992
993 scgp->silent++;
994 if (!get_mode_params(scgp, 0x05, "CD write parameter",
995 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) {
996 scgp->silent--;
997 return (-1);
998 }
999 if (len == 0) {
1000 scgp->silent--;
1001 return (-1);
1002 }
1003
1004 mp = (struct cd_mode_page_05 *)
1005 (mode + sizeof (struct scsi_mode_header) +
1006 ((struct scsi_mode_header *)mode)->blockdesc_len);
1007 #ifdef DEBUG
1008 scg_prbytes("CD write parameter:", (Uchar *)mode, len);
1009 #endif
1010
1011 /*
1012 * mp->test_write has already been reset in deflt_writemodes_mmc()
1013 * Do not reset mp->test_write (-dummy) here. It should be set
1014 * only at one place and only one time.
1015 */
1016
1017 mp->write_type = WT_TAO;
1018 mp->track_mode = TM_DATA;
1019 mp->dbtype = DB_ROM_MODE1;
1020
1021 if (set_mode_params(scgp, "CD write parameter", mode, len, 0, -1)) {
1022 dp->cdr_flags |= CDR_TAO;
1023 if (xdebug)
1024 printf("TAO ");
1025 } else
1026 dp->cdr_flags &= ~CDR_TAO;
1027
1028 mp->write_type = WT_PACKET;
1029 mp->track_mode |= TM_INCREMENTAL;
1030 /* mp->fp = (trackp->pktsize > 0) ? 1 : 0;*/
1031 /* i_to_4_byte(mp->packet_size, trackp->pktsize);*/
1032 mp->fp = 0;
1033 i_to_4_byte(mp->packet_size, 0);
1034
1035 if (set_mode_params(scgp, "CD write parameter", mode, len, 0, -1)) {
1036 dp->cdr_flags |= CDR_PACKET;
1037 if (xdebug)
1038 printf("PACKET ");
1039 } else
1040 dp->cdr_flags &= ~CDR_PACKET;
1041 mp->fp = 0;
1042 i_to_4_byte(mp->packet_size, 0);
1043 mp->track_mode = TM_DATA;
1044
1045
1046 mp->write_type = WT_SAO;
1047
1048 if (set_mode_params(scgp, "CD write parameter", mode, len, 0, -1)) {
1049 dp->cdr_flags |= CDR_SAO;
1050 if (xdebug)
1051 printf("SAO ");
1052 } else
1053 dp->cdr_flags &= ~CDR_SAO;
1054
1055 if (dp->cdr_flags & CDR_SAO) {
1056 mp->dbtype = DB_RAW_PQ;
1057
1058 #ifdef __needed__
1059 if (set_mode_params(scgp, "CD write parameter", mode, len, 0, -1)) {
1060 dp->cdr_flags |= CDR_SRAW16;
1061 if (xdebug)
1062 printf("SAO/R16 ");
1063 }
1064 #endif
1065
1066 mp->dbtype = DB_RAW_PW;
1067
1068 if (set_mode_params(scgp, "CD write parameter", mode, len, 0, -1)) {
1069 dp->cdr_flags |= CDR_SRAW96P;
1070 if (xdebug)
1071 printf("SAO/R96P ");
1072 }
1073
1074 mp->dbtype = DB_RAW_PW_R;
1075
1076 if (set_mode_params(scgp, "CD write parameter", mode, len, 0, -1)) {
1077 dp->cdr_flags |= CDR_SRAW96R;
1078 if (xdebug)
1079 printf("SAO/R96R ");
1080 }
1081 }
1082
1083 mp->write_type = WT_RAW;
1084 mp->dbtype = DB_RAW_PQ;
1085
1086 if (set_mode_params(scgp, "CD write parameter", mode, len, 0, -1)) {
1087 dp->cdr_flags |= CDR_RAW;
1088 dp->cdr_flags |= CDR_RAW16;
1089 if (xdebug)
1090 printf("RAW/R16 ");
1091 }
1092
1093 mp->dbtype = DB_RAW_PW;
1094
1095 if (set_mode_params(scgp, "CD write parameter", mode, len, 0, -1)) {
1096 dp->cdr_flags |= CDR_RAW;
1097 dp->cdr_flags |= CDR_RAW96P;
1098 if (xdebug)
1099 printf("RAW/R96P ");
1100 }
1101
1102 mp->dbtype = DB_RAW_PW_R;
1103
1104 if (set_mode_params(scgp, "CD write parameter", mode, len, 0, -1)) {
1105 dp->cdr_flags |= CDR_RAW;
1106 dp->cdr_flags |= CDR_RAW96R;
1107 if (xdebug)
1108 printf("RAW/R96R ");
1109 }
1110
1111 mp->track_mode = TM_DATA;
1112 mp->write_type = WT_LAYER_JUMP;
1113
1114 if (set_mode_params(scgp, "CD write parameter", mode, len, 0, -1) &&
1115 has_profile(scgp, 0x16) == 1) {
1116 dp->cdr_flags |= CDR_LAYER_JUMP;
1117 if (xdebug)
1118 printf("LAYER JUMP ");
1119 } else
1120 dp->cdr_flags &= ~CDR_LAYER_JUMP;
1121
1122 if (xdebug)
1123 printf("\n");
1124
1125 /*
1126 * Reset mp->test_write (-dummy) here.
1127 */
1128 deflt_writemodes_mmc(scgp, TRUE);
1129 scgp->silent--;
1130
1131 return (0);
1132 }
1133
1134 LOCAL int
deflt_writemodes_mmc(scgp,reset_dummy)1135 deflt_writemodes_mmc(scgp, reset_dummy)
1136 SCSI *scgp;
1137 BOOL reset_dummy;
1138 {
1139 Uchar mode[0x100];
1140 int len;
1141 struct cd_mode_page_05 *mp;
1142
1143 fillbytes((caddr_t)mode, sizeof (mode), '\0');
1144
1145 scgp->silent++;
1146 if (!get_mode_params(scgp, 0x05, "CD write parameter",
1147 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) {
1148 scgp->silent--;
1149 return (-1);
1150 }
1151 if (len == 0) {
1152 scgp->silent--;
1153 return (-1);
1154 }
1155
1156 mp = (struct cd_mode_page_05 *)
1157 (mode + sizeof (struct scsi_mode_header) +
1158 ((struct scsi_mode_header *)mode)->blockdesc_len);
1159 #ifdef DEBUG
1160 scg_prbytes("CD write parameter:", (Uchar *)mode, len);
1161 error("Audio pause len: %d\n", a_to_2_byte(mp->audio_pause_len));
1162 #endif
1163
1164 /*
1165 * This is the only place where we reset mp->test_write (-dummy)
1166 */
1167 if (reset_dummy)
1168 mp->test_write = 0;
1169
1170 /*
1171 * Set default values:
1172 * Write type = 01 (track at once)
1173 * Track mode = 04 (CD-ROM)
1174 * Data block type = 08 (CD-ROM)
1175 * Session format = 00 (CD-ROM)
1176 *
1177 * XXX Note: the same code appears in check_writemodes_mmc() and
1178 * XXX in speed_select_mmc().
1179 */
1180 mp->write_type = WT_TAO;
1181 mp->track_mode = TM_DATA;
1182 mp->dbtype = DB_ROM_MODE1;
1183 mp->session_format = SES_DA_ROM; /* Matsushita has illegal def. value */
1184
1185 i_to_2_byte(mp->audio_pause_len, 150); /* LG has illegal def. value */
1186
1187 #ifdef DEBUG
1188 scg_prbytes("CD write parameter:", (Uchar *)mode, len);
1189 #endif
1190 if (!set_mode_params(scgp, "CD write parameter", mode, len, 0, -1)) {
1191
1192 mp->write_type = WT_SAO;
1193 mp->LS_V = 0;
1194 mp->copy = 0;
1195 mp->fp = 0;
1196 mp->multi_session = MS_NONE;
1197 mp->host_appl_code = 0;
1198
1199 if (!set_mode_params(scgp, "CD write parameter", mode, len, 0, -1)) {
1200 scgp->silent--;
1201 return (-1);
1202 }
1203 }
1204 scgp->silent--;
1205 return (0);
1206 }
1207
1208 #ifdef PRINT_ATIP
1209 LOCAL void atip_printspeed __PR((char *fmt, int speedindex, char speedtab[]));
1210 LOCAL void print_atip __PR((SCSI *scgp, struct atipinfo *atp));
1211 #endif /* PRINT_ATIP */
1212
1213 LOCAL void
di_to_dstat(dip,dsp)1214 di_to_dstat(dip, dsp)
1215 struct disk_info *dip;
1216 dstat_t *dsp;
1217 {
1218 dsp->ds_diskid = a_to_u_4_byte(dip->disk_id);
1219 if (dip->did_v)
1220 dsp->ds_flags |= DSF_DID_V;
1221 dsp->ds_disktype = dip->disk_type;
1222 dsp->ds_diskstat = dip->disk_status;
1223 dsp->ds_sessstat = dip->sess_status;
1224 if (dip->erasable)
1225 dsp->ds_flags |= DSF_ERA;
1226
1227 dsp->ds_trfirst = dip->first_track;
1228 dsp->ds_trlast = dip->last_track_ls;
1229 dsp->ds_trfirst_ls = dip->first_track_ls;
1230
1231 dsp->ds_maxblocks = msf_to_lba(dip->last_lead_out[1],
1232 dip->last_lead_out[2],
1233 dip->last_lead_out[3], TRUE);
1234 /*
1235 * Check for 0xFF:0xFF/0xFF which is an indicator for a complete disk
1236 */
1237 if (dsp->ds_maxblocks == 1166730)
1238 dsp->ds_maxblocks = -1L;
1239
1240 dsp->ds_first_leadin = msf_to_lba(dip->last_lead_in[1],
1241 dip->last_lead_in[2],
1242 dip->last_lead_in[3], FALSE);
1243 if (dsp->ds_first_leadin > 0)
1244 dsp->ds_first_leadin = 0;
1245
1246 if (dsp->ds_last_leadout == 0 && dsp->ds_maxblocks >= 0)
1247 dsp->ds_last_leadout = dsp->ds_maxblocks;
1248 }
1249
1250 LOCAL int
get_atip(scgp,atp)1251 get_atip(scgp, atp)
1252 SCSI *scgp;
1253 struct atipinfo *atp;
1254 {
1255 int len;
1256 int ret;
1257
1258 fillbytes((caddr_t)atp, sizeof (*atp), '\0');
1259
1260 /*
1261 * Used to be 2 instead of sizeof (struct tocheader), but all
1262 * other places in the code use sizeof (struct tocheader) too and
1263 * some Y2k ATAPI drives as used by IOMEGA create a DMA overrun if we
1264 * try to transfer only 2 bytes.
1265 */
1266 if (read_toc(scgp, (caddr_t)atp, 0, sizeof (struct tocheader), 0, FMT_ATIP) < 0)
1267 return (-1);
1268 len = a_to_u_2_byte(atp->hd.len);
1269 len += 2;
1270 ret = read_toc(scgp, (caddr_t)atp, 0, len, 0, FMT_ATIP);
1271
1272 #ifdef DEBUG
1273 scg_prbytes("ATIP info:", (Uchar *)atp,
1274 len-scg_getresid(scgp));
1275 #endif
1276 /*
1277 * Yamaha sometimes returns zeroed ATIP info for disks without ATIP
1278 */
1279 if (atp->desc.lead_in[1] == 0 &&
1280 atp->desc.lead_in[2] == 0 &&
1281 atp->desc.lead_in[3] == 0 &&
1282 atp->desc.lead_out[1] == 0 &&
1283 atp->desc.lead_out[2] == 0 &&
1284 atp->desc.lead_out[3] == 0)
1285 return (-1);
1286
1287 if (atp->desc.lead_in[1] >= 0x90 && debug) {
1288 /*
1289 * Only makes sense with buggy Ricoh firmware.
1290 */
1291 errmsgno(EX_BAD, "Converting ATIP from BCD\n");
1292 atp->desc.lead_in[1] = from_bcd(atp->desc.lead_in[1]);
1293 atp->desc.lead_in[2] = from_bcd(atp->desc.lead_in[2]);
1294 atp->desc.lead_in[3] = from_bcd(atp->desc.lead_in[3]);
1295
1296 atp->desc.lead_out[1] = from_bcd(atp->desc.lead_out[1]);
1297 atp->desc.lead_out[2] = from_bcd(atp->desc.lead_out[2]);
1298 atp->desc.lead_out[3] = from_bcd(atp->desc.lead_out[3]);
1299 }
1300
1301 return (ret);
1302 }
1303
1304 #ifdef PRINT_PMA
1305
1306 LOCAL int
1307 /*get_pma(atp)*/
get_pma(scgp)1308 get_pma(scgp)
1309 SCSI *scgp;
1310 /* struct atipinfo *atp;*/
1311 {
1312 int len;
1313 int ret;
1314 char atp[1024];
1315
1316 fillbytes((caddr_t)atp, sizeof (*atp), '\0');
1317
1318 /*
1319 * Used to be 2 instead of sizeof (struct tocheader), but all
1320 * other places in the code use sizeof (struct tocheader) too and
1321 * some Y2k ATAPI drives as used by IOMEGA create a DMA overrun if we
1322 * try to transfer only 2 bytes.
1323 */
1324 /* if (read_toc(scgp, (caddr_t)atp, 0, 2, 1, FMT_PMA) < 0)*/
1325 /* if (read_toc(scgp, (caddr_t)atp, 0, 2, 0, FMT_PMA) < 0)*/
1326 if (read_toc(scgp, (caddr_t)atp, 0, sizeof (struct tocheader), 0, FMT_PMA) < 0)
1327 return (-1);
1328 /* len = a_to_u_2_byte(atp->hd.len);*/
1329 len = a_to_u_2_byte(atp);
1330 len += 2;
1331 /* ret = read_toc(scgp, (caddr_t)atp, 0, len, 1, FMT_PMA);*/
1332 ret = read_toc(scgp, (caddr_t)atp, 0, len, 0, FMT_PMA);
1333
1334 #ifdef DEBUG
1335 scg_prbytes("PMA:", (Uchar *)atp,
1336 len-scg_getresid(scgp));
1337 #endif
1338 ret = read_toc(scgp, (caddr_t)atp, 0, len, 1, FMT_PMA);
1339
1340 #ifdef DEBUG
1341 scg_prbytes("PMA:", (Uchar *)atp,
1342 len-scg_getresid(scgp));
1343 #endif
1344 return (ret);
1345 }
1346
1347 #endif /* PRINT_PMA */
1348
1349 LOCAL int
init_mmc(scgp,dp)1350 init_mmc(scgp, dp)
1351 SCSI *scgp;
1352 cdr_t *dp;
1353 {
1354 return (speed_select_mmc(scgp, dp, NULL));
1355 }
1356
1357 LOCAL int
getdisktype_mmc(scgp,dp)1358 getdisktype_mmc(scgp, dp)
1359 SCSI *scgp;
1360 cdr_t *dp;
1361 {
1362 extern char *buf;
1363 dstat_t *dsp = dp->cdr_dstat;
1364 struct disk_info *dip;
1365 Uchar mode[0x100];
1366 msf_t msf;
1367 BOOL did_atip = FALSE;
1368 BOOL did_dummy = FALSE;
1369 int profile;
1370
1371 msf.msf_min = msf.msf_sec = msf.msf_frame = 0;
1372
1373 if (dsp->ds_type == DST_UNKNOWN) {
1374 profile = get_curprofile(scgp);
1375 if (profile >= 0)
1376 dsp->ds_type = profile;
1377 }
1378
1379 /*
1380 * It seems that there are drives that do not support to
1381 * read ATIP (e.g. HP 7100)
1382 * Also if a NON CD-R media is inserted, this will never work.
1383 * For this reason, make a failure non-fatal.
1384 */
1385 scgp->silent++;
1386 if (get_atip(scgp, (struct atipinfo *)mode) >= 0) {
1387 struct atipinfo *atp = (struct atipinfo *)mode;
1388
1389 msf.msf_min = mode[8];
1390 msf.msf_sec = mode[9];
1391 msf.msf_frame = mode[10];
1392 if (atp->desc.erasable) {
1393 dsp->ds_flags |= DSF_ERA;
1394 if (atp->desc.sub_type == 1)
1395 dsp->ds_flags |= DSF_HIGHSP_ERA;
1396 else if (atp->desc.sub_type == 2)
1397 dsp->ds_flags |= DSF_ULTRASP_ERA;
1398 else if (atp->desc.sub_type == 3)
1399 dsp->ds_flags |= DSF_ULTRASP_ERA | DSF_ULTRASPP_ERA;
1400 }
1401 if (atp->desc.a1_v) {
1402 if (atp->desc.clv_low != 0)
1403 dsp->ds_at_min_speed = clv_to_speed[atp->desc.clv_low];
1404 if (atp->desc.clv_high != 0)
1405 dsp->ds_at_max_speed = clv_to_speed[atp->desc.clv_high];
1406
1407 if (atp->desc.erasable && atp->desc.sub_type == 1) {
1408 if (atp->desc.clv_high != 0)
1409 dsp->ds_at_max_speed = hs_clv_to_speed[atp->desc.clv_high];
1410 }
1411 }
1412 if (atp->desc.a2_v && atp->desc.erasable && (atp->desc.sub_type == 2 || atp->desc.sub_type == 3)) {
1413 Uint vlow;
1414 Uint vhigh;
1415
1416 vlow = (atp->desc.a2[0] >> 4) & 0x07;
1417 vhigh = atp->desc.a2[0] & 0x0F;
1418 if (vlow != 0)
1419 dsp->ds_at_min_speed = us_clv_to_speed[vlow];
1420 if (vhigh != 0)
1421 dsp->ds_at_max_speed = us_clv_to_speed[vhigh];
1422 }
1423 did_atip = TRUE;
1424 }
1425 scgp->silent--;
1426
1427 #ifdef PRINT_ATIP
1428 if ((dp->cdr_dstat->ds_cdrflags & RF_PRATIP) != 0 && did_atip) {
1429 print_atip(scgp, (struct atipinfo *)mode);
1430 pr_manufacturer(&msf,
1431 ((struct atipinfo *)mode)->desc.erasable,
1432 ((struct atipinfo *)mode)->desc.uru);
1433 }
1434 #endif
1435 if ((dp->cdr_dstat->ds_cdrflags & RF_PRATIP) != 0) {
1436 print_format_capacities(scgp);
1437 }
1438 again:
1439 dip = (struct disk_info *)buf;
1440 if (get_diskinfo(scgp, dip, sizeof (*dip)) < 0)
1441 return (-1);
1442
1443 /*
1444 * Check for non writable disk first.
1445 */
1446 if (dip->disk_status == DS_COMPLETE &&
1447 (dsp->ds_cdrflags & (RF_WRITE|RF_BLANK)) == RF_WRITE) {
1448 if (!did_dummy) {
1449 int xspeed = 0xFFFF;
1450 int oflags = dp->cdr_cmdflags;
1451
1452 /*
1453 * Try to clear the dummy bit to reset the virtual
1454 * drive status. Not all drives support it even though
1455 * it is mentioned in the MMC standard.
1456 */
1457 if (lverbose)
1458 printf("Trying to clear drive status.\n");
1459
1460 dp->cdr_cmdflags &= ~F_DUMMY;
1461 speed_select_mmc(scgp, dp, &xspeed);
1462 dp->cdr_cmdflags = oflags;
1463 did_dummy = TRUE;
1464 goto again;
1465 }
1466 /*
1467 * Trying to clear drive status did not work...
1468 */
1469 reload_media(scgp, dp);
1470 }
1471 if (get_diskinfo(scgp, dip, sizeof (*dip)) < 0)
1472 return (-1);
1473 di_to_dstat(dip, dsp);
1474 if (!did_atip && dsp->ds_first_leadin < 0)
1475 lba_to_msf(dsp->ds_first_leadin, &msf);
1476
1477 if ((dp->cdr_dstat->ds_cdrflags & RF_PRATIP) != 0 && !did_atip) {
1478 print_min_atip(dsp->ds_first_leadin, dsp->ds_last_leadout);
1479 if (dsp->ds_first_leadin < 0)
1480 pr_manufacturer(&msf,
1481 dip->erasable,
1482 dip->uru);
1483 }
1484 dsp->ds_maxrblocks = disk_rcap(&msf, dsp->ds_maxblocks,
1485 dip->erasable,
1486 dip->uru);
1487
1488
1489 #ifdef PRINT_ATIP
1490 #ifdef DEBUG
1491 if (get_atip(scgp, (struct atipinfo *)mode) < 0)
1492 return (-1);
1493 /*
1494 * Get pma gibt �rger mit CW-7502
1495 * Wenn Die Disk leer ist, dann stuerzt alles ab.
1496 * Firmware 4.02 kann nicht get_pma
1497 */
1498 if (dip->disk_status != DS_EMPTY) {
1499 #ifdef PRINT_PMA
1500 /* get_pma();*/
1501 #endif
1502 }
1503 printf("ATIP lead in: %ld (%02d:%02d/%02d)\n",
1504 msf_to_lba(mode[8], mode[9], mode[10], FALSE),
1505 mode[8], mode[9], mode[10]);
1506 printf("ATIP lead out: %ld (%02d:%02d/%02d)\n",
1507 msf_to_lba(mode[12], mode[13], mode[14], TRUE),
1508 mode[12], mode[13], mode[14]);
1509 print_diskinfo(dip, TRUE);
1510 print_atip(scgp, (struct atipinfo *)mode);
1511 #endif
1512 #endif /* PRINT_ATIP */
1513 return (drive_getdisktype(scgp, dp));
1514 }
1515
1516 LOCAL int
prdiskstatus_mmc(scgp,dp)1517 prdiskstatus_mmc(scgp, dp)
1518 SCSI *scgp;
1519 cdr_t *dp;
1520 {
1521 return (prdiskstatus(scgp, dp, TRUE));
1522 }
1523
1524 #ifdef PRINT_ATIP
1525
1526 #define IS(what, flag) printf("Disk Is %s%s\n", flag?"":"not ", what);
1527
1528 char *cdr_subtypes[] = {
1529 "Normal Rewritable (CLV) media",
1530 "High speed Rewritable (CAV) media",
1531 "Medium Type A, low Beta category (A-)",
1532 "Medium Type A, high Beta category (A+)",
1533 "Medium Type B, low Beta category (B-)",
1534 "Medium Type B, high Beta category (B+)",
1535 "Medium Type C, low Beta category (C-)",
1536 "Medium Type C, high Beta category (C+)",
1537 };
1538
1539 char *cdrw_subtypes[] = {
1540 "Normal Rewritable (CLV) media",
1541 "High speed Rewritable (CAV) media",
1542 "Ultra High speed Rewritable media",
1543 "Ultra High speed+ Rewritable media",
1544 "Medium Type B, low Beta category (B-)",
1545 "Medium Type B, high Beta category (B+)",
1546 "Medium Type C, low Beta category (C-)",
1547 "Medium Type C, high Beta category (C+)",
1548 };
1549
1550 LOCAL void
atip_printspeed(fmt,speedindex,speedtab)1551 atip_printspeed(fmt, speedindex, speedtab)
1552 char *fmt;
1553 int speedindex;
1554 char speedtab[];
1555 {
1556 printf("%s:", fmt);
1557 if (speedtab[speedindex] == 0) {
1558 printf(" %2d (reserved val %2d)",
1559 speedtab[speedindex], speedindex);
1560 } else {
1561 printf(" %2d", speedtab[speedindex]);
1562 }
1563 }
1564
1565 LOCAL void
print_atip(scgp,atp)1566 print_atip(scgp, atp)
1567 SCSI *scgp;
1568 struct atipinfo *atp;
1569 {
1570 char *sub_type;
1571 char *speedvtab = clv_to_speed;
1572
1573 if (scgp->verbose)
1574 scg_prbytes("ATIP info: ", (Uchar *)atp, sizeof (*atp));
1575
1576 printf("ATIP info from disk:\n");
1577 printf(" Indicated writing power: %d\n", atp->desc.ind_wr_power);
1578 if (atp->desc.erasable || atp->desc.ref_speed)
1579 printf(" Reference speed: %d\n", clv_to_speed[atp->desc.ref_speed]);
1580 IS("unrestricted", atp->desc.uru);
1581 /* printf(" Disk application code: %d\n", atp->desc.res5_05);*/
1582 IS("erasable", atp->desc.erasable);
1583 if (atp->desc.erasable)
1584 sub_type = cdrw_subtypes[atp->desc.sub_type];
1585 else
1586 sub_type = cdr_subtypes[atp->desc.sub_type];
1587 if (atp->desc.sub_type)
1588 printf(" Disk sub type: %s (%d)\n", sub_type, atp->desc.sub_type);
1589 printf(" ATIP start of lead in: %ld (%02d:%02d/%02d)\n",
1590 msf_to_lba(atp->desc.lead_in[1],
1591 atp->desc.lead_in[2],
1592 atp->desc.lead_in[3], FALSE),
1593 atp->desc.lead_in[1],
1594 atp->desc.lead_in[2],
1595 atp->desc.lead_in[3]);
1596 printf(" ATIP start of lead out: %ld (%02d:%02d/%02d)\n",
1597 msf_to_lba(atp->desc.lead_out[1],
1598 atp->desc.lead_out[2],
1599 atp->desc.lead_out[3], TRUE),
1600 atp->desc.lead_out[1],
1601 atp->desc.lead_out[2],
1602 atp->desc.lead_out[3]);
1603 if (atp->desc.a1_v) {
1604 if (atp->desc.erasable && atp->desc.sub_type == 1) {
1605 speedvtab = hs_clv_to_speed;
1606 }
1607 if (atp->desc.a2_v && (atp->desc.sub_type == 2 || atp->desc.sub_type == 3)) {
1608 speedvtab = us_clv_to_speed;
1609 }
1610 if (atp->desc.clv_low != 0 || atp->desc.clv_high != 0) {
1611 atip_printspeed(" 1T speed low",
1612 atp->desc.clv_low, speedvtab);
1613 atip_printspeed(" 1T speed high",
1614 atp->desc.clv_high, speedvtab);
1615 printf("\n");
1616 }
1617 }
1618 if (atp->desc.a2_v) {
1619 Uint vlow;
1620 Uint vhigh;
1621
1622 vlow = (atp->desc.a2[0] >> 4) & 0x07;
1623 vhigh = atp->desc.a2[0] & 0x0F;
1624
1625 if (vlow != 0 || vhigh != 0) {
1626 atip_printspeed(" 2T speed low",
1627 vlow, speedvtab);
1628 atip_printspeed(" 2T speed high",
1629 vhigh, speedvtab);
1630 printf("\n");
1631 }
1632 }
1633 if (atp->desc.a1_v) {
1634 printf(" power mult factor: %d %d\n", atp->desc.power_mult, atp->desc.tgt_y_pow);
1635 if (atp->desc.erasable)
1636 printf(" recommended erase/write power: %d\n", atp->desc.rerase_pwr_ratio);
1637 }
1638 if (atp->desc.a1_v) {
1639 printf(" A1 values: %02X %02X %02X\n",
1640 (&atp->desc.res15)[1],
1641 (&atp->desc.res15)[2],
1642 (&atp->desc.res15)[3]);
1643 }
1644 if (atp->desc.a2_v) {
1645 printf(" A2 values: %02X %02X %02X\n",
1646 atp->desc.a2[0],
1647 atp->desc.a2[1],
1648 atp->desc.a2[2]);
1649 }
1650 if (atp->desc.a3_v) {
1651 printf(" A3 values: %02X %02X %02X\n",
1652 atp->desc.a3[0],
1653 atp->desc.a3[1],
1654 atp->desc.a3[2]);
1655 }
1656 }
1657 #endif /* PRINT_ATIP */
1658
1659 LOCAL int
speed_select_mmc(scgp,dp,speedp)1660 speed_select_mmc(scgp, dp, speedp)
1661 SCSI *scgp;
1662 cdr_t *dp;
1663 int *speedp;
1664 {
1665 Uchar mode[0x100];
1666 Uchar moder[0x100];
1667 int len;
1668 struct cd_mode_page_05 *mp;
1669 struct ricoh_mode_page_30 *rp = NULL;
1670 int val;
1671 BOOL forcespeed = FALSE;
1672 BOOL dummy = (dp->cdr_cmdflags & F_DUMMY) != 0;
1673
1674 if (speedp)
1675 curspeed = *speedp;
1676
1677 /*
1678 * Do not reset mp->test_write (-dummy) here.
1679 */
1680 deflt_writemodes_mmc(scgp, FALSE);
1681
1682 fillbytes((caddr_t)mode, sizeof (mode), '\0');
1683
1684 if (!get_mode_params(scgp, 0x05, "CD write parameter",
1685 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len))
1686 return (-1);
1687 if (len == 0)
1688 return (-1);
1689
1690 mp = (struct cd_mode_page_05 *)
1691 (mode + sizeof (struct scsi_mode_header) +
1692 ((struct scsi_mode_header *)mode)->blockdesc_len);
1693 #ifdef DEBUG
1694 scg_prbytes("CD write parameter:", (Uchar *)mode, len);
1695 #endif
1696
1697
1698 mp->test_write = dummy != 0;
1699
1700 #ifdef DEBUG
1701 scg_prbytes("CD write parameter:", (Uchar *)mode, len);
1702 #endif
1703 if (!set_mode_params(scgp, "CD write parameter", mode, len, 0, -1))
1704 return (-1);
1705
1706 /*
1707 * Neither set nor get speed.
1708 */
1709 if (speedp == 0)
1710 return (0);
1711
1712
1713 rp = get_justlink_ricoh(scgp, moder);
1714 if (mmc_isyamaha(scgp)) {
1715 forcespeed = FALSE;
1716 } else if (mmc_isplextor(scgp) && (dp->cdr_flags & CDR_FORCESPEED) != 0) {
1717 int pwr;
1718
1719 pwr = check_powerrec_plextor(scgp);
1720 if (pwr >= 0)
1721 forcespeed = (pwr == 0);
1722 } else if ((dp->cdr_flags & CDR_FORCESPEED) != 0) {
1723 forcespeed = rp && rp->AWSCD != 0;
1724 }
1725
1726 if (lverbose && (dp->cdr_flags & CDR_FORCESPEED) != 0)
1727 printf("Forcespeed is %s.\n", forcespeed?"ON":"OFF");
1728
1729 if (!forcespeed && (dp->cdr_dstat->ds_cdrflags & RF_FORCESPEED) != 0) {
1730 printf("Turning forcespeed on\n");
1731 forcespeed = TRUE;
1732 }
1733 if (forcespeed && (dp->cdr_dstat->ds_cdrflags & RF_FORCESPEED) == 0) {
1734 printf("Turning forcespeed off\n");
1735 forcespeed = FALSE;
1736 }
1737 if (mmc_isplextor(scgp) && (dp->cdr_flags & CDR_FORCESPEED) != 0) {
1738 powerrec_plextor(scgp, !forcespeed);
1739 }
1740 if (!mmc_isyamaha(scgp) && (dp->cdr_flags & CDR_FORCESPEED) != 0) {
1741
1742 if (rp) {
1743 rp->AWSCD = forcespeed?1:0;
1744 set_mode_params(scgp, "Ricoh Vendor Page", moder, moder[0]+1, 0, -1);
1745 rp = get_justlink_ricoh(scgp, moder);
1746 }
1747 }
1748
1749 /*
1750 * 44100 * 2 * 2 = 176400 bytes/s
1751 *
1752 * The right formula would be:
1753 * tmp = (((long)curspeed) * 1764) / 10;
1754 *
1755 * But the standard is rounding the wrong way.
1756 * Furtunately rounding down is guaranteed.
1757 */
1758 val = curspeed*177;
1759 if (val > 0xFFFF)
1760 val = 0xFFFF;
1761 if (mmc_isyamaha(scgp) && forcespeed) {
1762 if (force_speed_yamaha(scgp, -1, val) < 0)
1763 return (-1);
1764 } else if (mmc_set_speed(scgp, -1, val, ROTCTL_CLV) < 0) {
1765 return (-1);
1766 }
1767
1768 if (scsi_get_speed(scgp, 0, &val) >= 0) {
1769 if (val > 0) {
1770 curspeed = val / 176;
1771 *speedp = curspeed;
1772 }
1773 }
1774 return (0);
1775 }
1776
1777 /*
1778 * Some drives do not round up when writespeed is e.g. 1 and
1779 * the minimum write speed of the drive is higher. Try to increment
1780 * the write speed unti it gets accepted by the drive.
1781 */
1782 LOCAL int
mmc_set_speed(scgp,readspeed,writespeed,rotctl)1783 mmc_set_speed(scgp, readspeed, writespeed, rotctl)
1784 SCSI *scgp;
1785 int readspeed;
1786 int writespeed;
1787 int rotctl;
1788 {
1789 int rs;
1790 int ws;
1791 int ret = -1;
1792 int c;
1793 int k;
1794
1795 if (scsi_get_speed(scgp, &rs, &ws) >= 0) {
1796 if (readspeed < 0)
1797 readspeed = rs;
1798 if (writespeed < 0)
1799 writespeed = ws;
1800 }
1801 if (writespeed < 0 || writespeed > 0xFFFF)
1802 return (ret);
1803
1804 scgp->silent++;
1805 while (writespeed <= 0xFFFF) {
1806 ret = scsi_set_speed(scgp, readspeed, writespeed, rotctl);
1807 if (ret >= 0)
1808 break;
1809 c = scg_sense_code(scgp);
1810 k = scg_sense_key(scgp);
1811 /*
1812 * Abort quickly if it does not make sense to repeat.
1813 * 0x24 == Invalid field in cdb
1814 * 0x24 means illegal speed.
1815 */
1816 if ((k != SC_ILLEGAL_REQUEST) || (c != 0x24)) {
1817 if (scgp->silent <= 1)
1818 scg_printerr(scgp);
1819 scgp->silent--;
1820 return (-1);
1821 }
1822 writespeed += 177;
1823 }
1824 if (ret < 0 && scgp->silent <= 1)
1825 scg_printerr(scgp);
1826 scgp->silent--;
1827
1828 return (ret);
1829 }
1830
1831 LOCAL int
next_wr_addr_mmc(scgp,trackp,ap)1832 next_wr_addr_mmc(scgp, trackp, ap)
1833 SCSI *scgp;
1834 track_t *trackp;
1835 long *ap;
1836 {
1837 struct track_info track_info;
1838 long next_addr;
1839 int result = -1;
1840
1841
1842 /*
1843 * Reading info for current track may require doing the get_trackinfo
1844 * with either the track number (if the track is currently being written)
1845 * or with 0xFF (if the track hasn't been started yet and is invisible
1846 */
1847
1848 if (trackp != 0 && trackp->track > 0 && is_packet(trackp)) {
1849 scgp->silent++;
1850 result = get_trackinfo(scgp, (caddr_t)&track_info, TI_TYPE_TRACK,
1851 trackp->trackno,
1852 sizeof (track_info));
1853 scgp->silent--;
1854 }
1855
1856 if (result < 0) {
1857 if (get_trackinfo(scgp, (caddr_t)&track_info, TI_TYPE_TRACK, 0xFF,
1858 sizeof (track_info)) < 0) {
1859 errmsgno(EX_BAD, "Cannot get next writable address for 'invisible' track.\n");
1860 errmsgno(EX_BAD, "This means that we are checking recorded media.\n");
1861 errmsgno(EX_BAD, "This media cannot be written in streaming mode anymore.\n");
1862 errmsgno(EX_BAD, "If you like to write to 'preformatted' RW media, try to blank the media first.\n");
1863 return (-1);
1864 }
1865 }
1866 if (scgp->verbose)
1867 scg_prbytes("track info:", (Uchar *)&track_info,
1868 sizeof (track_info)-scg_getresid(scgp));
1869 next_addr = a_to_4_byte(track_info.next_writable_addr);
1870 if (ap)
1871 *ap = next_addr;
1872 return (0);
1873 }
1874
1875 LOCAL int
write_leadin_mmc(scgp,dp,trackp)1876 write_leadin_mmc(scgp, dp, trackp)
1877 SCSI *scgp;
1878 cdr_t *dp;
1879 track_t *trackp;
1880 {
1881 Uint i;
1882 long startsec = 0L;
1883
1884 /* if (flags & F_SAO) {*/
1885 if (wm_base(dp->cdr_dstat->ds_wrmode) == WM_SAO) {
1886 if (debug || lverbose) {
1887 printf("Sending CUE sheet...\n");
1888 flush();
1889 }
1890 if ((*dp->cdr_send_cue)(scgp, dp, trackp) < 0) {
1891 errmsgno(EX_BAD, "Cannot send CUE sheet.\n");
1892 return (-1);
1893 }
1894
1895 (*dp->cdr_next_wr_address)(scgp, &trackp[0], &startsec);
1896 if (trackp[0].flags & TI_TEXT) {
1897 startsec = dp->cdr_dstat->ds_first_leadin;
1898 printf("SAO startsec: %ld\n", startsec);
1899 } else if (startsec <= 0 && startsec != -150) {
1900 errmsgno(EX_BAD, "WARNING: Drive returns wrong startsec (%ld) using -150\n",
1901 startsec);
1902 startsec = -150;
1903 }
1904 if (debug)
1905 printf("SAO startsec: %ld\n", startsec);
1906
1907 if (trackp[0].flags & TI_TEXT) {
1908 if (startsec > 0) {
1909 errmsgno(EX_BAD, "CD-Text must be in first session.\n");
1910 return (-1);
1911 }
1912 if (debug || lverbose)
1913 printf("Writing lead-in...\n");
1914 if (write_cdtext(scgp, dp, startsec) < 0)
1915 return (-1);
1916
1917 dp->cdr_dstat->ds_cdrflags |= RF_LEADIN;
1918 } else for (i = 1; i <= trackp->tracks; i++) {
1919 trackp[i].trackstart += startsec +150;
1920 }
1921 #ifdef XXX
1922 if (debug || lverbose)
1923 printf("Writing lead-in...\n");
1924
1925 pad_track(scgp, dp, &trackp[1], -150, (Llong)0,
1926 FALSE, 0);
1927 #endif
1928 }
1929 /* if (flags & F_RAW) {*/
1930 if (wm_base(dp->cdr_dstat->ds_wrmode) == WM_RAW) {
1931 /*
1932 * In RAW write mode, we now write the lead in (TOC).
1933 */
1934 (*dp->cdr_next_wr_address)(scgp, &trackp[0], &startsec);
1935 if (startsec > -4500) {
1936 /*
1937 * There must be at least 1 minute lead-in.
1938 */
1939 errmsgno(EX_BAD, "WARNING: Drive returns wrong startsec (%ld) using %ld from ATIP\n",
1940 startsec, (long)dp->cdr_dstat->ds_first_leadin);
1941 startsec = dp->cdr_dstat->ds_first_leadin;
1942 }
1943 if (startsec > -4500) {
1944 errmsgno(EX_BAD, "Illegal startsec (%ld)\n", startsec);
1945 return (-1);
1946 }
1947 if (debug || lverbose)
1948 printf("Writing lead-in at sector %ld\n", startsec);
1949 if (write_leadin(scgp, dp, trackp, startsec) < 0)
1950 return (-1);
1951 dp->cdr_dstat->ds_cdrflags |= RF_LEADIN;
1952 }
1953 return (0);
1954 }
1955
1956 int st2mode[] = {
1957 0, /* 0 */
1958 TM_DATA, /* 1 ST_ROM_MODE1 */
1959 TM_DATA, /* 2 ST_ROM_MODE2 */
1960 0, /* 3 */
1961 0, /* 4 ST_AUDIO_NOPRE */
1962 TM_PREEM, /* 5 ST_AUDIO_PRE */
1963 0, /* 6 */
1964 0, /* 7 */
1965 };
1966
1967 LOCAL int
open_track_mmc(scgp,dp,trackp)1968 open_track_mmc(scgp, dp, trackp)
1969 SCSI *scgp;
1970 cdr_t *dp;
1971 track_t *trackp;
1972 {
1973 Uchar mode[0x100];
1974 int len;
1975 struct cd_mode_page_05 *mp;
1976
1977 if (!is_tao(trackp) && !is_packet(trackp)) {
1978 if (trackp->pregapsize > 0 && (trackp->flags & TI_PREGAP) == 0) {
1979 if (lverbose) {
1980 printf("Writing pregap for track %d at %ld\n",
1981 (int)trackp->trackno,
1982 trackp->trackstart-trackp->pregapsize);
1983 }
1984 if (trackp->track == 1 && is_hidden(trackp)) {
1985 pad_track(scgp, dp, trackp,
1986 trackp->trackstart-trackp->pregapsize,
1987 (Llong)(trackp->pregapsize-trackp->trackstart)*trackp->secsize,
1988 FALSE, 0);
1989 if (write_track_data(scgp, dp, track_base(trackp)) < 0)
1990 return (-1);
1991 } else {
1992 /*
1993 * XXX Do we need to check isecsize too?
1994 */
1995 pad_track(scgp, dp, trackp,
1996 trackp->trackstart-trackp->pregapsize,
1997 (Llong)trackp->pregapsize*trackp->secsize,
1998 FALSE, 0);
1999 }
2000 }
2001 return (0);
2002 }
2003
2004 fillbytes((caddr_t)mode, sizeof (mode), '\0');
2005
2006 if (!get_mode_params(scgp, 0x05, "CD write parameter",
2007 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len))
2008 return (-1);
2009 if (len == 0)
2010 return (-1);
2011
2012 mp = (struct cd_mode_page_05 *)
2013 (mode + sizeof (struct scsi_mode_header) +
2014 ((struct scsi_mode_header *)mode)->blockdesc_len);
2015
2016
2017 /* mp->track_mode = ???;*/
2018 mp->track_mode = st2mode[trackp->sectype & ST_MASK];
2019 /* mp->copy = ???;*/
2020 mp->dbtype = trackp->dbtype;
2021
2022 /*i_to_short(mp->audio_pause_len, 300);*/
2023 /*i_to_short(mp->audio_pause_len, 150);*/
2024 /*i_to_short(mp->audio_pause_len, 0);*/
2025
2026 if (is_packet(trackp)) {
2027 mp->write_type = WT_PACKET;
2028 mp->track_mode |= TM_INCREMENTAL;
2029 mp->fp = (trackp->pktsize > 0) ? 1 : 0;
2030 i_to_4_byte(mp->packet_size, trackp->pktsize);
2031 } else if (is_tao(trackp)) {
2032 mp->write_type = WT_TAO;
2033 mp->fp = 0;
2034 i_to_4_byte(mp->packet_size, 0);
2035 } else {
2036 errmsgno(EX_BAD, "Unknown write mode.\n");
2037 return (-1);
2038 }
2039 if (trackp->isrc) {
2040 mp->ISRC[0] = 0x80; /* Set ISRC valid */
2041 strncpy((char *)&mp->ISRC[1], trackp->isrc, 12);
2042
2043 } else {
2044 fillbytes(&mp->ISRC[0], sizeof (mp->ISRC), '\0');
2045 }
2046
2047 #ifdef DEBUG
2048 scg_prbytes("CD write parameter:", (Uchar *)mode, len);
2049 #endif
2050 if (!set_mode_params(scgp, "CD write parameter", mode, len, 0, trackp->secsize))
2051 return (-1);
2052
2053 return (0);
2054 }
2055
2056 LOCAL int
close_track_mmc(scgp,dp,trackp)2057 close_track_mmc(scgp, dp, trackp)
2058 SCSI *scgp;
2059 cdr_t *dp;
2060 track_t *trackp;
2061 {
2062 int ret;
2063
2064 if (!is_tao(trackp) && !is_packet(trackp))
2065 return (0);
2066
2067 if (scsi_flush_cache(scgp, (dp->cdr_cmdflags&F_IMMED) != 0) < 0) {
2068 printf("Trouble flushing the cache\n");
2069 return (-1);
2070 }
2071 wait_unit_ready(scgp, 300); /* XXX Wait for ATAPI */
2072 if (is_packet(trackp) && !is_noclose(trackp)) {
2073 /* close the incomplete track */
2074 ret = scsi_close_tr_session(scgp, CL_TYPE_TRACK, 0xFF,
2075 (dp->cdr_cmdflags&F_IMMED) != 0);
2076 wait_unit_ready(scgp, 300); /* XXX Wait for ATAPI */
2077 return (ret);
2078 }
2079 return (0);
2080 }
2081
2082 int toc2sess[] = {
2083 SES_DA_ROM, /* CD-DA */
2084 SES_DA_ROM, /* CD-ROM */
2085 SES_XA, /* CD-ROM XA mode 1 */
2086 SES_XA, /* CD-ROM XA MODE 2 */
2087 SES_CDI, /* CDI */
2088 SES_DA_ROM, /* Invalid - use default */
2089 SES_DA_ROM, /* Invalid - use default */
2090 };
2091
2092 LOCAL int
open_session_mmc(scgp,dp,trackp)2093 open_session_mmc(scgp, dp, trackp)
2094 SCSI *scgp;
2095 cdr_t *dp;
2096 track_t *trackp;
2097 {
2098 Uchar mode[0x100];
2099 int len;
2100 struct cd_mode_page_05 *mp;
2101
2102 fillbytes((caddr_t)mode, sizeof (mode), '\0');
2103
2104 if (!get_mode_params(scgp, 0x05, "CD write parameter",
2105 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len))
2106 return (-1);
2107 if (len == 0)
2108 return (-1);
2109
2110 mp = (struct cd_mode_page_05 *)
2111 (mode + sizeof (struct scsi_mode_header) +
2112 ((struct scsi_mode_header *)mode)->blockdesc_len);
2113
2114 mp->write_type = WT_TAO; /* fix to allow DAO later */
2115 /*
2116 * We need to set the right dbtype here because Sony drives
2117 * don't like multi session in to be set with DB_ROM_MODE1
2118 * which is set by us at the beginning as default as some drives
2119 * have illegal default values.
2120 */
2121 mp->track_mode = st2mode[trackp[0].sectype & ST_MASK];
2122 mp->dbtype = trackp[0].dbtype;
2123
2124 if (!is_tao(trackp) && !is_packet(trackp)) {
2125 mp->write_type = WT_SAO;
2126 if (dp->cdr_dstat->ds_cdrflags & RF_AUDIOMASTER)
2127 mp->write_type = 8;
2128 mp->track_mode = 0;
2129 mp->dbtype = DB_RAW;
2130 }
2131 if (is_raw(trackp)) {
2132 mp->write_type = WT_RAW;
2133 mp->track_mode = 0;
2134
2135 if (is_raw16(trackp)) {
2136 mp->dbtype = DB_RAW_PQ;
2137 } else if (is_raw96r(trackp)) {
2138 mp->dbtype = DB_RAW_PW_R;
2139 } else {
2140 mp->dbtype = DB_RAW_PW;
2141 }
2142 }
2143
2144 mp->multi_session = (track_base(trackp)->tracktype & TOCF_MULTI) ?
2145 MS_MULTI : MS_NONE;
2146 mp->session_format = toc2sess[track_base(trackp)->tracktype & TOC_MASK];
2147
2148 if (trackp->isrc) {
2149 mp->media_cat_number[0] = 0x80; /* Set MCN valid */
2150 strncpy((char *)&mp->media_cat_number[1], trackp->isrc, 13);
2151
2152 } else {
2153 fillbytes(&mp->media_cat_number[0], sizeof (mp->media_cat_number), '\0');
2154 }
2155 #ifdef DEBUG
2156 scg_prbytes("CD write parameter:", (Uchar *)mode, len);
2157 #endif
2158 if (!set_mode_params(scgp, "CD write parameter", mode, len, 0, -1))
2159 return (-1);
2160
2161 return (0);
2162 }
2163
2164 LOCAL int
waitfix_mmc(scgp,secs)2165 waitfix_mmc(scgp, secs)
2166 SCSI *scgp;
2167 int secs;
2168 {
2169 char dibuf[16];
2170 int i;
2171 int key;
2172 #define W_SLEEP 2
2173
2174 scgp->silent++;
2175 for (i = 0; i < secs/W_SLEEP; i++) {
2176 if (read_disk_info(scgp, dibuf, sizeof (dibuf)) >= 0) {
2177 scgp->silent--;
2178 return (0);
2179 }
2180 key = scg_sense_key(scgp);
2181 if (key != SC_UNIT_ATTENTION && key != SC_NOT_READY)
2182 break;
2183 sleep(W_SLEEP);
2184 }
2185 scgp->silent--;
2186 return (-1);
2187 #undef W_SLEEP
2188 }
2189
2190 LOCAL int
fixate_mmc(scgp,dp,trackp)2191 fixate_mmc(scgp, dp, trackp)
2192 SCSI *scgp;
2193 cdr_t *dp;
2194 track_t *trackp;
2195 {
2196 int ret = 0;
2197 int key = 0;
2198 int code = 0;
2199 struct timeval starttime;
2200 struct timeval stoptime;
2201 int dummy = (track_base(trackp)->tracktype & TOCF_DUMMY) != 0;
2202
2203 starttime.tv_sec = 0;
2204 starttime.tv_usec = 0;
2205 stoptime = starttime;
2206 gettimeofday(&starttime, (struct timezone *)0);
2207
2208 if (dummy && lverbose)
2209 printf("WARNING: Some drives don't like fixation in dummy mode.\n");
2210
2211 scgp->silent++;
2212 if (is_tao(trackp) || is_packet(trackp)) {
2213 ret = scsi_close_tr_session(scgp, CL_TYPE_SESSION, 0,
2214 (dp->cdr_cmdflags&F_IMMED) != 0);
2215 } else {
2216 if (scsi_flush_cache(scgp, (dp->cdr_cmdflags&F_IMMED) != 0) < 0) {
2217 if (!scsi_in_progress(scgp))
2218 printf("Trouble flushing the cache\n");
2219 }
2220 }
2221 scgp->silent--;
2222 key = scg_sense_key(scgp);
2223 code = scg_sense_code(scgp);
2224
2225 scgp->silent++;
2226 if (debug && !unit_ready(scgp)) {
2227 error("Early return from fixating. Ret: %d Key: %d, Code: %d\n", ret, key, code);
2228 }
2229 scgp->silent--;
2230
2231 if (ret >= 0) {
2232 wait_unit_ready(scgp, 420/curspeed); /* XXX Wait for ATAPI */
2233 waitfix_mmc(scgp, 420/curspeed); /* XXX Wait for ATAPI */
2234 return (ret);
2235 }
2236
2237 if ((dummy != 0 && (key != SC_ILLEGAL_REQUEST)) ||
2238 /*
2239 * Try to suppress messages from drives that don't like fixation
2240 * in -dummy mode.
2241 */
2242 ((dummy == 0) &&
2243 (((key != SC_UNIT_ATTENTION) && (key != SC_NOT_READY)) ||
2244 ((code != 0x2E) && (code != 0x04))))) {
2245 /*
2246 * UNIT ATTENTION/2E seems to be a magic for old Mitsumi ATAPI drives
2247 * NOT READY/ code 4 qual 7 (logical unit not ready, operation in progress)
2248 * seems to be a magic for newer Mitsumi ATAPI drives
2249 * NOT READY/ code 4 qual 8 (logical unit not ready, long write in progress)
2250 * seems to be a magic for SONY drives
2251 * when returning early from fixating.
2252 * Try to supress the error message in this case to make
2253 * simple minded users less confused.
2254 */
2255 scg_printerr(scgp);
2256 scg_printresult(scgp); /* XXX restore key/code in future */
2257 }
2258
2259 if (debug && !unit_ready(scgp)) {
2260 error("Early return from fixating. Ret: %d Key: %d, Code: %d\n", ret, key, code);
2261 }
2262
2263 wait_unit_ready(scgp, 420); /* XXX Wait for ATAPI */
2264 waitfix_mmc(scgp, 420/curspeed); /* XXX Wait for ATAPI */
2265
2266 if (!dummy &&
2267 (ret >= 0 || (key == SC_UNIT_ATTENTION && code == 0x2E))) {
2268 /*
2269 * Some ATAPI drives (e.g. Mitsumi) imply the
2270 * IMMED bit in the SCSI cdb. As there seems to be no
2271 * way to properly check for the real end of the
2272 * fixating process we wait for the expected time.
2273 */
2274 gettimeofday(&stoptime, (struct timezone *)0);
2275 timevaldiff(&starttime, &stoptime);
2276 if (stoptime.tv_sec < (220 / curspeed)) {
2277 unsigned secs;
2278
2279 if (lverbose) {
2280 printf("Actual fixating time: %ld seconds\n",
2281 (long)stoptime.tv_sec);
2282 }
2283 secs = (280 / curspeed) - stoptime.tv_sec;
2284 if (lverbose) {
2285 printf("ATAPI early return: sleeping %d seconds.\n",
2286 secs);
2287 }
2288 sleep(secs);
2289 }
2290 }
2291 return (ret);
2292 }
2293
2294 char *blank_types[] = {
2295 "entire disk",
2296 "PMA, TOC, pregap",
2297 "incomplete track",
2298 "reserved track",
2299 "tail of track",
2300 "closing of last session",
2301 "last session",
2302 "reserved blanking type",
2303 };
2304
2305 LOCAL int
blank_mmc(scgp,dp,addr,blanktype)2306 blank_mmc(scgp, dp, addr, blanktype)
2307 SCSI *scgp;
2308 cdr_t *dp;
2309 long addr;
2310 int blanktype;
2311 {
2312 BOOL cdrr = FALSE; /* Read CD-R */
2313 BOOL cdwr = FALSE; /* Write CD-R */
2314 BOOL cdrrw = FALSE; /* Read CD-RW */
2315 BOOL cdwrw = FALSE; /* Write CD-RW */
2316 int ret;
2317
2318 mmc_check(scgp, &cdrr, &cdwr, &cdrrw, &cdwrw, NULL, NULL);
2319 if (!cdwrw)
2320 return (blank_dummy(scgp, dp, addr, blanktype));
2321
2322 if (lverbose) {
2323 printf("Blanking %s\n", blank_types[blanktype & 0x07]);
2324 flush();
2325 }
2326
2327 ret = scsi_blank(scgp, addr, blanktype, (dp->cdr_cmdflags&F_IMMED) != 0);
2328 if (ret < 0)
2329 return (ret);
2330
2331 wait_unit_ready(scgp, 90*60/curspeed); /* XXX Wait for ATAPI */
2332 waitfix_mmc(scgp, 90*60/curspeed); /* XXX Wait for ATAPI */
2333 return (ret);
2334 }
2335
2336 LOCAL int
send_opc_mmc(scgp,bp,cnt,doopc)2337 send_opc_mmc(scgp, bp, cnt, doopc)
2338 SCSI *scgp;
2339 caddr_t bp;
2340 int cnt;
2341 int doopc;
2342 {
2343 int ret;
2344
2345 scgp->silent++;
2346 ret = send_opc(scgp, bp, cnt, doopc);
2347 scgp->silent--;
2348
2349 if (ret >= 0)
2350 return (ret);
2351
2352 /* BEGIN CSTYLED */
2353 /*
2354 * Hack for a mysterioys drive ....
2355 * Device type : Removable CD-ROM
2356 * Version : 0
2357 * Response Format: 1
2358 * Vendor_info : 'RWD '
2359 * Identifikation : 'RW2224 '
2360 * Revision : '2.53'
2361 * Device seems to be: Generic mmc CD-RW.
2362 *
2363 * Performing OPC...
2364 * CDB: 54 01 00 00 00 00 00 00 00 00
2365 * Sense Bytes: 70 00 06 00 00 00 00 0A 00 00 00 00 5A 03 00 00
2366 * Sense Key: 0x6 Unit Attention, Segment 0
2367 * Sense Code: 0x5A Qual 0x03 (operator selected write permit) Fru 0x0
2368 * Sense flags: Blk 0 (not valid)
2369 */
2370 /* END CSTYLED */
2371 if (scg_sense_key(scgp) == SC_UNIT_ATTENTION &&
2372 scg_sense_code(scgp) == 0x5A &&
2373 scg_sense_qual(scgp) == 0x03)
2374 return (0);
2375
2376 /*
2377 * Do not make the condition:
2378 * "Power calibration area almost full" a fatal error.
2379 * It just flags that we have a single and last chance to write now.
2380 */
2381 if ((scg_sense_key(scgp) == SC_RECOVERABLE_ERROR ||
2382 scg_sense_key(scgp) == SC_MEDIUM_ERROR) &&
2383 scg_sense_code(scgp) == 0x73 &&
2384 scg_sense_qual(scgp) == 0x01)
2385 return (0);
2386
2387 /*
2388 * Send OPC is optional.
2389 */
2390 if (scg_sense_key(scgp) != SC_ILLEGAL_REQUEST) {
2391 if (scgp->silent <= 0)
2392 scg_printerr(scgp);
2393 return (ret);
2394 }
2395 return (0);
2396 }
2397
2398 LOCAL int
opt1_mmc(scgp,dp)2399 opt1_mmc(scgp, dp)
2400 SCSI *scgp;
2401 cdr_t *dp;
2402 {
2403 int oflags = dp->cdr_dstat->ds_cdrflags;
2404
2405 if ((dp->cdr_dstat->ds_cdrflags & RF_AUDIOMASTER) != 0) {
2406 printf("Turning Audio Master Q. R. on\n");
2407 if (set_audiomaster_yamaha(scgp, dp, TRUE) < 0)
2408 return (-1);
2409 if (!debug && lverbose <= 1)
2410 dp->cdr_dstat->ds_cdrflags &= ~RF_PRATIP;
2411 if (getdisktype_mmc(scgp, dp) < 0) {
2412 dp->cdr_dstat->ds_cdrflags = oflags;
2413 return (-1);
2414 }
2415 dp->cdr_dstat->ds_cdrflags = oflags;
2416 if (oflags & RF_PRATIP) {
2417 msf_t msf;
2418 lba_to_msf(dp->cdr_dstat->ds_first_leadin, &msf);
2419 printf("New start of lead in: %ld (%02d:%02d/%02d)\n",
2420 (long)dp->cdr_dstat->ds_first_leadin,
2421 msf.msf_min,
2422 msf.msf_sec,
2423 msf.msf_frame);
2424 lba_to_msf(dp->cdr_dstat->ds_maxblocks, &msf);
2425 printf("New start of lead out: %ld (%02d:%02d/%02d)\n",
2426 (long)dp->cdr_dstat->ds_maxblocks,
2427 msf.msf_min,
2428 msf.msf_sec,
2429 msf.msf_frame);
2430 }
2431 }
2432 if (mmc_isplextor(scgp)) {
2433 int gcode;
2434
2435 if ((dp->cdr_flags & (CDR_SINGLESESS|CDR_HIDE_CDR)) != 0) {
2436 if (ss_hide_plextor(scgp,
2437 (dp->cdr_dstat->ds_cdrflags & RF_SINGLESESS) != 0,
2438 (dp->cdr_dstat->ds_cdrflags & RF_HIDE_CDR) != 0) < 0)
2439 return (-1);
2440 }
2441
2442 if ((dp->cdr_flags & CDR_SPEEDREAD) != 0) {
2443 if (speed_rd_plextor(scgp,
2444 (dp->cdr_dstat->ds_cdrflags & RF_SPEEDREAD) != 0) < 0)
2445 return (-1);
2446 }
2447
2448 if ((dp->cdr_cmdflags & F_SETDROPTS) ||
2449 (wm_base(dp->cdr_dstat->ds_wrmode) == WM_SAO) ||
2450 (wm_base(dp->cdr_dstat->ds_wrmode) == WM_RAW))
2451 gcode = do_gigarec_plextor(scgp);
2452 else
2453 gcode = gigarec_plextor(scgp, 0);
2454 if (gcode != 0) {
2455 msf_t msf;
2456
2457 dp->cdr_dstat->ds_first_leadin =
2458 gigarec_mult(gcode, dp->cdr_dstat->ds_first_leadin);
2459 dp->cdr_dstat->ds_maxblocks =
2460 gigarec_mult(gcode, dp->cdr_dstat->ds_maxblocks);
2461
2462 if (oflags & RF_PRATIP) {
2463 lba_to_msf(dp->cdr_dstat->ds_first_leadin, &msf);
2464 printf("New start of lead in: %ld (%02d:%02d/%02d)\n",
2465 (long)dp->cdr_dstat->ds_first_leadin,
2466 msf.msf_min,
2467 msf.msf_sec,
2468 msf.msf_frame);
2469 lba_to_msf(dp->cdr_dstat->ds_maxblocks, &msf);
2470 printf("New start of lead out: %ld (%02d:%02d/%02d)\n",
2471 (long)dp->cdr_dstat->ds_maxblocks,
2472 msf.msf_min,
2473 msf.msf_sec,
2474 msf.msf_frame);
2475 }
2476 }
2477 }
2478 return (0);
2479 }
2480
2481 LOCAL int
opt2_mmc(scgp,dp)2482 opt2_mmc(scgp, dp)
2483 SCSI *scgp;
2484 cdr_t *dp;
2485 {
2486 Uchar mode[0x100];
2487 Uchar moder[0x100];
2488 int len;
2489 struct cd_mode_page_05 *mp;
2490 struct ricoh_mode_page_30 *rp = NULL;
2491 BOOL burnfree = FALSE;
2492
2493 fillbytes((caddr_t)mode, sizeof (mode), '\0');
2494
2495 if (!get_mode_params(scgp, 0x05, "CD write parameter",
2496 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len))
2497 return (-1);
2498 if (len == 0)
2499 return (-1);
2500
2501 mp = (struct cd_mode_page_05 *)
2502 (mode + sizeof (struct scsi_mode_header) +
2503 ((struct scsi_mode_header *)mode)->blockdesc_len);
2504
2505
2506 rp = get_justlink_ricoh(scgp, moder);
2507
2508 if (dp->cdr_cdcap->BUF != 0) {
2509 burnfree = mp->BUFE != 0;
2510 } else if ((dp->cdr_flags & CDR_BURNFREE) != 0) {
2511 burnfree = rp && rp->BUEFE != 0;
2512 }
2513
2514 if (lverbose && (dp->cdr_flags & CDR_BURNFREE) != 0)
2515 printf("BURN-Free is %s.\n", burnfree?"ON":"OFF");
2516
2517 if (!burnfree && (dp->cdr_dstat->ds_cdrflags & RF_BURNFREE) != 0) {
2518 printf("Turning BURN-Free on\n");
2519 burnfree = TRUE;
2520 }
2521 if (burnfree && (dp->cdr_dstat->ds_cdrflags & RF_BURNFREE) == 0) {
2522 printf("Turning BURN-Free off\n");
2523 burnfree = FALSE;
2524 }
2525 if (dp->cdr_cdcap->BUF != 0) {
2526 mp->BUFE = burnfree?1:0;
2527 } else if ((dp->cdr_flags & CDR_BURNFREE) != 0) {
2528
2529 if (rp)
2530 rp->BUEFE = burnfree?1:0;
2531 }
2532 if (rp) {
2533 /*
2534 * Clear Just-Link counter
2535 */
2536 i_to_2_byte(rp->link_counter, 0);
2537 if (xdebug)
2538 scg_prbytes("Mode Select Data ", moder, moder[0]+1);
2539
2540 if (!set_mode_params(scgp, "Ricoh Vendor Page", moder, moder[0]+1, 0, -1))
2541 return (-1);
2542 rp = get_justlink_ricoh(scgp, moder);
2543 }
2544
2545 #ifdef DEBUG
2546 scg_prbytes("CD write parameter:", (Uchar *)mode, len);
2547 #endif
2548 if (!set_mode_params(scgp, "CD write parameter", mode, len, 0, -1))
2549 return (-1);
2550
2551 if (mmc_isplextor(scgp)) {
2552 /*
2553 * Clear Burn-Proof counter
2554 */
2555 scgp->silent++;
2556 bpc_plextor(scgp, 1, NULL);
2557 scgp->silent--;
2558
2559 do_varirec_plextor(scgp);
2560 }
2561
2562 return (0);
2563 }
2564
2565 LOCAL int
scsi_sony_write(scgp,bp,sectaddr,size,blocks,islast)2566 scsi_sony_write(scgp, bp, sectaddr, size, blocks, islast)
2567 SCSI *scgp;
2568 caddr_t bp; /* address of buffer */
2569 long sectaddr; /* disk address (sector) to put */
2570 long size; /* number of bytes to transfer */
2571 int blocks; /* sector count */
2572 BOOL islast; /* last write for track */
2573 {
2574 return (write_xg5(scgp, bp, sectaddr, size, blocks));
2575 }
2576
2577 Uchar db2df[] = {
2578 0x00, /* 0 2352 bytes of raw data */
2579 0xFF, /* 1 2368 bytes (raw data + P/Q Subchannel) */
2580 0xFF, /* 2 2448 bytes (raw data + P-W Subchannel) */
2581 0xFF, /* 3 2448 bytes (raw data + P-W raw Subchannel)*/
2582 0xFF, /* 4 - Reserved */
2583 0xFF, /* 5 - Reserved */
2584 0xFF, /* 6 - Reserved */
2585 0xFF, /* 7 - Vendor specific */
2586 0x10, /* 8 2048 bytes Mode 1 (ISO/IEC 10149) */
2587 0x30, /* 9 2336 bytes Mode 2 (ISO/IEC 10149) */
2588 0xFF, /* 10 2048 bytes Mode 2! (CD-ROM XA form 1) */
2589 0xFF, /* 11 2056 bytes Mode 2 (CD-ROM XA form 1) */
2590 0xFF, /* 12 2324 bytes Mode 2 (CD-ROM XA form 2) */
2591 0xFF, /* 13 2332 bytes Mode 2 (CD-ROM XA 1/2+subhdr) */
2592 0xFF, /* 14 - Reserved */
2593 0xFF, /* 15 - Vendor specific */
2594 };
2595
2596 LOCAL int
gen_cue_mmc(trackp,vcuep,needgap)2597 gen_cue_mmc(trackp, vcuep, needgap)
2598 track_t *trackp;
2599 void *vcuep;
2600 BOOL needgap;
2601 {
2602 int tracks = trackp->tracks;
2603 int i;
2604 struct mmc_cue **cuep = vcuep;
2605 struct mmc_cue *cue;
2606 struct mmc_cue *cp;
2607 int ncue = 0;
2608 int icue = 0;
2609 int pgsize;
2610 msf_t m;
2611 int ctl;
2612 int df;
2613 int scms;
2614
2615 cue = malloc(1);
2616
2617 for (i = 0; i <= tracks; i++) {
2618 ctl = (st2mode[trackp[i].sectype & ST_MASK]) << 4;
2619 if (is_copy(&trackp[i]))
2620 ctl |= TM_ALLOW_COPY << 4;
2621 if (is_quadro(&trackp[i]))
2622 ctl |= TM_QUADRO << 4;
2623 df = db2df[trackp[i].dbtype & 0x0F];
2624 if (trackp[i].tracktype == TOC_XA2 &&
2625 trackp[i].sectype == (SECT_MODE_2_MIX|ST_MODE_RAW)) {
2626 /*
2627 * Hack for CUE with MODE2/CDI and
2628 * trackp[i].dbtype == DB_RAW
2629 */
2630 df = 0x21;
2631 }
2632
2633 if (trackp[i].isrc) { /* MCN or ISRC */
2634 ncue += 2;
2635 cue = realloc(cue, ncue * sizeof (*cue));
2636 cp = &cue[icue++];
2637 if (i == 0) {
2638 cp->cs_ctladr = 0x02;
2639 movebytes(&trackp[i].isrc[0], &cp->cs_tno, 7);
2640 cp = &cue[icue++];
2641 cp->cs_ctladr = 0x02;
2642 movebytes(&trackp[i].isrc[7], &cp->cs_tno, 7);
2643 } else {
2644 cp->cs_ctladr = 0x03;
2645 cp->cs_tno = i;
2646 movebytes(&trackp[i].isrc[0], &cp->cs_index, 6);
2647 cp = &cue[icue++];
2648 cp->cs_ctladr = 0x03;
2649 cp->cs_tno = i;
2650 movebytes(&trackp[i].isrc[6], &cp->cs_index, 6);
2651 }
2652 }
2653 if (i == 0) { /* Lead in */
2654 df &= ~7; /* Mask off data size & nonRAW subch */
2655 if (df < 0x10)
2656 df |= 1;
2657 else
2658 df |= 4;
2659 if (trackp[0].flags & TI_TEXT) /* CD-Text in Lead-in*/
2660 df |= 0x40;
2661 lba_to_msf(-150, &m);
2662 cue = realloc(cue, ++ncue * sizeof (*cue));
2663 cp = &cue[icue++];
2664 fillcue(cp, ctl|0x01, i, 0, df, 0, &m);
2665 } else {
2666 scms = 0;
2667
2668 if (is_scms(&trackp[i]))
2669 scms = 0x80;
2670 pgsize = trackp[i].pregapsize;
2671 if (pgsize == 0 && needgap)
2672 pgsize++;
2673 lba_to_msf(trackp[i].trackstart-pgsize, &m);
2674 cue = realloc(cue, ++ncue * sizeof (*cue));
2675 cp = &cue[icue++];
2676 fillcue(cp, ctl|0x01, i, 0, df, scms, &m);
2677
2678 if (trackp[i].nindex == 1) {
2679 lba_to_msf(trackp[i].trackstart, &m);
2680 cue = realloc(cue, ++ncue * sizeof (*cue));
2681 cp = &cue[icue++];
2682 fillcue(cp, ctl|0x01, i, 1, df, scms, &m);
2683 } else {
2684 int idx;
2685 long *idxlist;
2686
2687 ncue += trackp[i].nindex;
2688 idxlist = trackp[i].tindex;
2689 cue = realloc(cue, ncue * sizeof (*cue));
2690
2691 for (idx = 1; idx <= trackp[i].nindex; idx++) {
2692 lba_to_msf(trackp[i].trackstart + idxlist[idx], &m);
2693 cp = &cue[icue++];
2694 fillcue(cp, ctl|0x01, i, idx, df, scms, &m);
2695 }
2696 }
2697 }
2698 }
2699 /* Lead out */
2700 ctl = (st2mode[trackp[tracks+1].sectype & ST_MASK]) << 4;
2701 if (is_copy(&trackp[i]))
2702 ctl |= TM_ALLOW_COPY << 4;
2703 if (is_quadro(&trackp[i]))
2704 ctl |= TM_QUADRO << 4;
2705 df = db2df[trackp[tracks+1].dbtype & 0x0F];
2706 if (trackp[i].tracktype == TOC_XA2 &&
2707 trackp[i].sectype == (SECT_MODE_2_MIX|ST_MODE_RAW)) {
2708 /*
2709 * Hack for CUE with MODE2/CDI and
2710 * trackp[i].dbtype == DB_RAW
2711 */
2712 df = 0x21;
2713 }
2714 df &= ~7; /* Mask off data size & nonRAW subch */
2715 if (df < 0x10)
2716 df |= 1;
2717 else
2718 df |= 4;
2719 lba_to_msf(trackp[tracks+1].trackstart, &m);
2720 cue = realloc(cue, ++ncue * sizeof (*cue));
2721 cp = &cue[icue++];
2722 fillcue(cp, ctl|0x01, 0xAA, 1, df, 0, &m);
2723
2724 if (lverbose > 1) {
2725 for (i = 0; i < ncue; i++) {
2726 scg_prbytes("", (Uchar *)&cue[i], 8);
2727 }
2728 }
2729 if (cuep)
2730 *cuep = cue;
2731 else
2732 free(cue);
2733 return (ncue);
2734 }
2735
2736 LOCAL void
fillcue(cp,ca,tno,idx,dataform,scms,mp)2737 fillcue(cp, ca, tno, idx, dataform, scms, mp)
2738 struct mmc_cue *cp; /* The target cue entry */
2739 int ca; /* Control/adr for this entry */
2740 int tno; /* Track number for this entry */
2741 int idx; /* Index for this entry */
2742 int dataform; /* Data format for this entry */
2743 int scms; /* Serial copy management */
2744 msf_t *mp; /* MSF value for this entry */
2745 {
2746 cp->cs_ctladr = ca; /* XXX wie lead in */
2747 cp->cs_tno = tno;
2748 cp->cs_index = idx;
2749 cp->cs_dataform = dataform; /* XXX wie lead in */
2750 cp->cs_scms = scms;
2751 cp->cs_min = mp->msf_min;
2752 cp->cs_sec = mp->msf_sec;
2753 cp->cs_frame = mp->msf_frame;
2754 }
2755
2756 LOCAL int
send_cue_mmc(scgp,dp,trackp)2757 send_cue_mmc(scgp, dp, trackp)
2758 SCSI *scgp;
2759 cdr_t *dp;
2760 track_t *trackp;
2761 {
2762 struct mmc_cue *cp;
2763 int ncue;
2764 int ret;
2765 Uint i;
2766
2767 for (i = 1; i <= trackp->tracks; i++) {
2768 if (trackp[i].tracksize < (tsize_t)0) {
2769 errmsgno(EX_BAD, "Track %d has unknown length.\n", i);
2770 return (-1);
2771 }
2772 }
2773 ncue = (*dp->cdr_gen_cue)(trackp, &cp, FALSE);
2774
2775 scgp->silent++;
2776 ret = send_cue_sheet(scgp, (caddr_t)cp, ncue*8);
2777 scgp->silent--;
2778 free(cp);
2779 if (ret < 0) {
2780 errmsgno(EX_BAD, "CUE sheet not accepted. Retrying with minimum pregapsize = 1.\n");
2781 ncue = (*dp->cdr_gen_cue)(trackp, &cp, TRUE);
2782 ret = send_cue_sheet(scgp, (caddr_t)cp, ncue*8);
2783 if (ret < 0) {
2784 errmsgno(EX_BAD,
2785 "CUE sheet still not accepted. Please try to write in RAW (-raw96r) mode.\n");
2786 }
2787 free(cp);
2788 }
2789 return (ret);
2790 }
2791
2792 LOCAL int
stats_mmc(scgp,dp)2793 stats_mmc(scgp, dp)
2794 SCSI *scgp;
2795 cdr_t *dp;
2796 {
2797 Uchar mode[256];
2798 struct ricoh_mode_page_30 *rp;
2799 UInt32_t count;
2800
2801 if (mmc_isplextor(scgp) && lverbose) {
2802 int sels;
2803 int maxs;
2804 int lasts;
2805
2806 /*
2807 * Run it in silent mode as old drives do not support it.
2808 * As this function looks to be a part of the PowerRec
2809 * features, we may want to check
2810 * dp->cdr_flags & CDR_FORCESPEED
2811 */
2812 scgp->silent++;
2813 if (get_speeds_plextor(scgp, &sels, &maxs, &lasts) >= 0) {
2814 printf("Last selected write speed: %dx\n",
2815 sels / 176);
2816 printf("Max media write speed: %dx\n",
2817 maxs / 176);
2818 printf("Last actual write speed: %dx\n",
2819 lasts / 176);
2820 }
2821 scgp->silent--;
2822 }
2823
2824 if ((dp->cdr_dstat->ds_cdrflags & RF_BURNFREE) == 0)
2825 return (0);
2826
2827 if (mmc_isplextor(scgp)) {
2828 int i = 0;
2829 int ret;
2830
2831 /*
2832 * Read Burn-Proof counter
2833 */
2834 scgp->silent++;
2835 ret = bpc_plextor(scgp, 2, &i);
2836 scgp->silent--;
2837 if (ret < 0)
2838 return (-1);
2839 count = i;
2840 /*
2841 * Clear Burn-Proof counter
2842 */
2843 bpc_plextor(scgp, 1, NULL);
2844 } else {
2845 rp = get_justlink_ricoh(scgp, mode);
2846 if (rp)
2847 count = a_to_u_2_byte(rp->link_counter);
2848 else
2849 return (-1);
2850 }
2851 if (lverbose) {
2852 if (count == 0)
2853 printf("BURN-Free was never needed.\n");
2854 else
2855 printf("BURN-Free was %d times used.\n",
2856 (int)count);
2857 }
2858 return (0);
2859 }
2860 /*--------------------------------------------------------------------------*/
2861 LOCAL BOOL
mmc_isplextor(scgp)2862 mmc_isplextor(scgp)
2863 SCSI *scgp;
2864 {
2865 if (scgp->inq != NULL &&
2866 strncmp(scgp->inq->inq_vendor_info, "PLEXTOR", 7) == 0) {
2867 return (TRUE);
2868 }
2869 return (FALSE);
2870 }
2871
2872 LOCAL BOOL
mmc_isyamaha(scgp)2873 mmc_isyamaha(scgp)
2874 SCSI *scgp;
2875 {
2876 if (scgp->inq != NULL &&
2877 strncmp(scgp->inq->inq_vendor_info, "YAMAHA", 6) == 0) {
2878 return (TRUE);
2879 }
2880 return (FALSE);
2881 }
2882
2883 LOCAL void
do_varirec_plextor(scgp)2884 do_varirec_plextor(scgp)
2885 SCSI *scgp;
2886 {
2887 char *p;
2888 int voff;
2889
2890 p = hasdrvopt(driveropts, "varirec");
2891 if (p == NULL || curspeed != 4) {
2892 if (check_varirec_plextor(scgp) >= 0)
2893 varirec_plextor(scgp, FALSE, 0);
2894 } else {
2895 char *ep;
2896 ep = astoi(p, &voff);
2897 if (*ep != '\0' && *ep != ',')
2898 comerrno(EX_BAD,
2899 "Bad varirec value '%s'.\n", p);
2900 if (check_varirec_plextor(scgp) < 0)
2901 comerrno(EX_BAD, "Drive does not support VariRec.\n");
2902 varirec_plextor(scgp, TRUE, voff);
2903 }
2904 }
2905
2906 /*
2907 * GigaRec value table
2908 */
2909 struct gr {
2910 Uchar val;
2911 char vadd;
2912 char *name;
2913 } gr[] = {
2914 { 0x00, 0, "off", },
2915 { 0x00, 0, "1.0", },
2916 { 0x01, 2, "1.2", },
2917 { 0x02, 3, "1.3", },
2918 { 0x03, 4, "1.4", },
2919 { 0x04, 1, "1.1", },
2920 { 0x81, -2, "0.8", },
2921 { 0x82, -3, "0.7", },
2922 { 0x83, -4, "0.6", },
2923 { 0x84, -1, "0.9", },
2924 { 0x00, 0, NULL, },
2925 };
2926
2927 LOCAL int
do_gigarec_plextor(scgp)2928 do_gigarec_plextor(scgp)
2929 SCSI *scgp;
2930 {
2931 char *p;
2932 int val = 0; /* Make silly GCC happy */
2933
2934 p = hasdrvopt(driveropts, "gigarec");
2935 if (p == NULL) {
2936 if (check_gigarec_plextor(scgp) >= 0)
2937 gigarec_plextor(scgp, 0);
2938 } else {
2939 struct gr *gp = gr;
2940
2941 if (strlen(p) >= 3) {
2942 for (; gp->name != NULL; gp++) {
2943 if (strncmp(p, gp->name, 3) == 0) {
2944 if (p[3] != '\0' && p[3] != ',')
2945 continue;
2946 val = gp->val;
2947 break;
2948 }
2949 }
2950 }
2951 if (gp->name == NULL)
2952 comerrno(EX_BAD,
2953 "Bad gigarec value '%s'.\n", p);
2954 if (check_gigarec_plextor(scgp) < 0)
2955 comerrno(EX_BAD, "Drive does not support GigaRec.\n");
2956 return (gigarec_plextor(scgp, val));
2957 }
2958 return (0);
2959 }
2960
2961 LOCAL int
drivemode_plextor(scgp,bp,cnt,modecode,modeval)2962 drivemode_plextor(scgp, bp, cnt, modecode, modeval)
2963 SCSI *scgp;
2964 caddr_t bp;
2965 int cnt;
2966 int modecode;
2967 void *modeval;
2968 {
2969 register struct scg_cmd *scmd = scgp->scmd;
2970
2971 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
2972 scmd->flags = SCG_DISRE_ENA;
2973 if (modeval == NULL) {
2974 scmd->flags |= SCG_RECV_DATA;
2975 scmd->addr = bp;
2976 scmd->size = cnt;
2977 } else {
2978 scmd->cdb.g5_cdb.res = 0x08;
2979 }
2980 scmd->cdb_len = SC_G5_CDBLEN;
2981 scmd->sense_len = CCS_SENSE_LEN;
2982 scmd->cdb.g5_cdb.cmd = 0xE9;
2983 scmd->cdb.g5_cdb.lun = scg_lun(scgp);
2984 scmd->cdb.g1_cdb.addr[0] = modecode;
2985 if (modeval)
2986 movebytes(modeval, &scmd->cdb.g1_cdb.addr[1], 6);
2987 else
2988 i_to_2_byte(&scmd->cdb.cmd_cdb[9], cnt);
2989
2990 scgp->cmdname = "plextor drive mode";
2991
2992 if (scg_cmd(scgp) < 0)
2993 return (-1);
2994 return (0);
2995 }
2996
2997 /*
2998 * #defines for drivemode_plextor()...
2999 */
3000 #define MODE_CODE_SH 0x01 /* Mode code for Single Session & Hide-CDR */
3001 #define MB1_SS 0x01 /* Single Session Mode */
3002 #define MB1_HIDE_CDR 0x02 /* Hide CDR Media */
3003
3004 #define MODE_CODE_VREC 0x02 /* Mode code for Vari Rec */
3005
3006 #define MODE_CODE_GREC 0x04 /* Mode code for Giga Rec */
3007
3008 #define MODE_CODE_SPEED 0xbb /* Mode code for Speed Read */
3009 #define MBbb_SPEAD_READ 0x01 /* Spead Read */
3010 /* Danach Speed auf 0xFFFF 0xFFFF setzen */
3011
3012 LOCAL int
drivemode2_plextor(scgp,bp,cnt,modecode,modeval)3013 drivemode2_plextor(scgp, bp, cnt, modecode, modeval)
3014 SCSI *scgp;
3015 caddr_t bp;
3016 int cnt;
3017 int modecode;
3018 void *modeval;
3019 {
3020 register struct scg_cmd *scmd = scgp->scmd;
3021
3022 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
3023 scmd->flags = SCG_DISRE_ENA;
3024 if (modeval == NULL) {
3025 scmd->flags |= SCG_RECV_DATA;
3026 scmd->addr = bp;
3027 scmd->size = cnt;
3028 } else {
3029 scmd->cdb.g5_cdb.res = 0x08;
3030 }
3031 scmd->cdb_len = SC_G5_CDBLEN;
3032 scmd->sense_len = CCS_SENSE_LEN;
3033 scmd->cdb.g5_cdb.cmd = 0xED;
3034 scmd->cdb.g5_cdb.lun = scg_lun(scgp);
3035 scmd->cdb.g1_cdb.addr[0] = modecode;
3036 if (modeval)
3037 scmd->cdb.g5_cdb.reladr = *(char *)modeval != 0 ? 1 : 0;
3038 else
3039 i_to_2_byte(&scmd->cdb.cmd_cdb[8], cnt);
3040
3041 scgp->cmdname = "plextor drive mode2";
3042
3043 if (scg_cmd(scgp) < 0)
3044 return (-1);
3045
3046 return (0);
3047 }
3048
3049 LOCAL int
check_varirec_plextor(scgp)3050 check_varirec_plextor(scgp)
3051 SCSI *scgp;
3052 {
3053 int modecode = 2;
3054 Uchar pgetmode[8];
3055
3056 fillbytes(pgetmode, sizeof (pgetmode), '\0');
3057 scgp->silent++;
3058 if (drivemode_plextor(scgp, (caddr_t)pgetmode, sizeof (pgetmode), modecode, NULL) < 0) {
3059 scgp->silent--;
3060 return (-1);
3061 }
3062 scgp->silent--;
3063
3064 return (0);
3065 }
3066
3067 LOCAL int
check_gigarec_plextor(scgp)3068 check_gigarec_plextor(scgp)
3069 SCSI *scgp;
3070 {
3071 int modecode = 4;
3072 Uchar pgetmode[8];
3073
3074 fillbytes(pgetmode, sizeof (pgetmode), '\0');
3075 scgp->silent++;
3076 if (drivemode_plextor(scgp, (caddr_t)pgetmode, sizeof (pgetmode), modecode, NULL) < 0) {
3077 scgp->silent--;
3078 return (-1);
3079 }
3080 scgp->silent--;
3081
3082 return (0);
3083 }
3084
3085 LOCAL int
varirec_plextor(scgp,on,val)3086 varirec_plextor(scgp, on, val)
3087 SCSI *scgp;
3088 BOOL on;
3089 int val;
3090 {
3091 int modecode = 2;
3092 Uchar psetmode[8];
3093 Uchar pgetmode[8];
3094
3095 fillbytes(pgetmode, sizeof (pgetmode), '\0');
3096 scgp->silent++;
3097 if (drivemode_plextor(scgp, (caddr_t)pgetmode, sizeof (pgetmode), modecode, NULL) < 0) {
3098 scgp->silent--;
3099 return (-1);
3100 }
3101 scgp->silent--;
3102
3103 if (lverbose > 1)
3104 scg_prbytes("Modes", pgetmode, sizeof (pgetmode));
3105
3106
3107 fillbytes(psetmode, sizeof (psetmode), '\0');
3108 psetmode[0] = on?1:0;
3109 if (on) {
3110 /*
3111 * Before -2 .. +2
3112 * Since PX-716: -4 .. +4
3113 */
3114 if (val < -2 || val > 2)
3115 comerrno(EX_BAD, "Bad VariRec offset %d\n", val);
3116 printf("Turning Varirec on.\n");
3117 printf("Varirec offset is %d.\n", val);
3118
3119 if (val > 0) {
3120 psetmode[1] = val & 0x7F;
3121 } else {
3122 psetmode[1] = (-val) & 0x7F;
3123 psetmode[1] |= 0x80;
3124 }
3125 }
3126
3127 if (drivemode_plextor(scgp, NULL, 0, modecode, psetmode) < 0)
3128 return (-1);
3129
3130 fillbytes(pgetmode, sizeof (pgetmode), '\0');
3131 if (drivemode_plextor(scgp, (caddr_t)pgetmode, sizeof (pgetmode), modecode, NULL) < 0)
3132 return (-1);
3133
3134 if (lverbose > 1)
3135 scg_prbytes("Modes", pgetmode, sizeof (pgetmode));
3136
3137 return (0);
3138 }
3139
3140 LOCAL int
gigarec_plextor(scgp,val)3141 gigarec_plextor(scgp, val)
3142 SCSI *scgp;
3143 int val;
3144 {
3145 int modecode = 4;
3146 Uchar psetmode[8];
3147 Uchar pgetmode[8];
3148
3149 fillbytes(pgetmode, sizeof (pgetmode), '\0');
3150 scgp->silent++;
3151 if (drivemode_plextor(scgp, (caddr_t)pgetmode, sizeof (pgetmode), modecode, NULL) < 0) {
3152 scgp->silent--;
3153 return (-1);
3154 }
3155 scgp->silent--;
3156
3157 if (lverbose > 1)
3158 scg_prbytes("Modes", pgetmode, sizeof (pgetmode));
3159
3160
3161 fillbytes(psetmode, sizeof (psetmode), '\0');
3162 psetmode[1] = val;
3163
3164 if (drivemode_plextor(scgp, NULL, 0, modecode, psetmode) < 0)
3165 return (-1);
3166
3167 fillbytes(pgetmode, sizeof (pgetmode), '\0');
3168 if (drivemode_plextor(scgp, (caddr_t)pgetmode, sizeof (pgetmode), modecode, NULL) < 0)
3169 return (-1);
3170
3171 if (lverbose > 1)
3172 scg_prbytes("Modes", pgetmode, sizeof (pgetmode));
3173
3174 {
3175 struct gr *gp = gr;
3176
3177 for (; gp->name != NULL; gp++) {
3178 if (pgetmode[3] == gp->val)
3179 break;
3180 }
3181 if (gp->name == NULL)
3182 printf("Unknown GigaRec value 0x%X.\n", pgetmode[3]);
3183 else
3184 printf("GigaRec %sis %s.\n", gp->val?"value ":"", gp->name);
3185 }
3186 return (pgetmode[3]);
3187 }
3188
3189 LOCAL Int32_t
gigarec_mult(code,val)3190 gigarec_mult(code, val)
3191 int code;
3192 Int32_t val;
3193 {
3194 Int32_t add;
3195 struct gr *gp = gr;
3196
3197 for (; gp->name != NULL; gp++) {
3198 if (code == gp->val)
3199 break;
3200 }
3201 if (gp->vadd == 0)
3202 return (val);
3203
3204 add = val * gp->vadd / 10;
3205 return (val + add);
3206 }
3207
3208 LOCAL int
check_ss_hide_plextor(scgp)3209 check_ss_hide_plextor(scgp)
3210 SCSI *scgp;
3211 {
3212 int modecode = 1;
3213 Uchar pgetmode[8];
3214
3215 fillbytes(pgetmode, sizeof (pgetmode), '\0');
3216 scgp->silent++;
3217 if (drivemode_plextor(scgp, (caddr_t)pgetmode, sizeof (pgetmode), modecode, NULL) < 0) {
3218 scgp->silent--;
3219 return (-1);
3220 }
3221 scgp->silent--;
3222
3223 return (pgetmode[2] & 0x03);
3224 }
3225
3226 LOCAL int
check_speed_rd_plextor(scgp)3227 check_speed_rd_plextor(scgp)
3228 SCSI *scgp;
3229 {
3230 int modecode = 0xBB;
3231 Uchar pgetmode[8];
3232
3233 fillbytes(pgetmode, sizeof (pgetmode), '\0');
3234 scgp->silent++;
3235 if (drivemode_plextor(scgp, (caddr_t)pgetmode, sizeof (pgetmode), modecode, NULL) < 0) {
3236 scgp->silent--;
3237 return (-1);
3238 }
3239 scgp->silent--;
3240
3241 return (pgetmode[2] & 0x01);
3242 }
3243
3244 LOCAL int
check_powerrec_plextor(scgp)3245 check_powerrec_plextor(scgp)
3246 SCSI *scgp;
3247 {
3248 int modecode = 0;
3249 Uchar pgetmode[8];
3250
3251 fillbytes(pgetmode, sizeof (pgetmode), '\0');
3252 scgp->silent++;
3253 if (drivemode2_plextor(scgp, (caddr_t)pgetmode, sizeof (pgetmode), modecode, NULL) < 0) {
3254 scgp->silent--;
3255 return (-1);
3256 }
3257 scgp->silent--;
3258
3259 if (pgetmode[2] & 1)
3260 return (1);
3261
3262 return (0);
3263 }
3264
3265 LOCAL int
ss_hide_plextor(scgp,do_ss,do_hide)3266 ss_hide_plextor(scgp, do_ss, do_hide)
3267 SCSI *scgp;
3268 BOOL do_ss;
3269 BOOL do_hide;
3270 {
3271 int modecode = 1;
3272 Uchar psetmode[8];
3273 Uchar pgetmode[8];
3274 BOOL is_ss;
3275 BOOL is_hide;
3276
3277 fillbytes(pgetmode, sizeof (pgetmode), '\0');
3278 scgp->silent++;
3279 if (drivemode_plextor(scgp, (caddr_t)pgetmode, sizeof (pgetmode), modecode, NULL) < 0) {
3280 scgp->silent--;
3281 return (-1);
3282 }
3283 scgp->silent--;
3284
3285 if (lverbose > 1)
3286 scg_prbytes("Modes", pgetmode, sizeof (pgetmode));
3287
3288
3289 is_ss = (pgetmode[2] & MB1_SS) != 0;
3290 is_hide = (pgetmode[2] & MB1_HIDE_CDR) != 0;
3291
3292 if (lverbose > 0) {
3293 printf("Single session is %s.\n", is_ss ? "ON":"OFF");
3294 printf("Hide CDR is %s.\n", is_hide ? "ON":"OFF");
3295 }
3296
3297 fillbytes(psetmode, sizeof (psetmode), '\0');
3298 psetmode[0] = pgetmode[2]; /* Copy over old values */
3299 if (do_ss >= 0) {
3300 if (do_ss)
3301 psetmode[0] |= MB1_SS;
3302 else
3303 psetmode[0] &= ~MB1_SS;
3304 }
3305 if (do_hide >= 0) {
3306 if (do_hide)
3307 psetmode[0] |= MB1_HIDE_CDR;
3308 else
3309 psetmode[0] &= ~MB1_HIDE_CDR;
3310 }
3311
3312 if (do_ss >= 0 && do_ss != is_ss)
3313 printf("Turning single session %s.\n", do_ss?"on":"off");
3314 if (do_hide >= 0 && do_hide != is_hide)
3315 printf("Turning hide CDR %s.\n", do_hide?"on":"off");
3316
3317 if (drivemode_plextor(scgp, NULL, 0, modecode, psetmode) < 0)
3318 return (-1);
3319
3320 fillbytes(pgetmode, sizeof (pgetmode), '\0');
3321 if (drivemode_plextor(scgp, (caddr_t)pgetmode, sizeof (pgetmode), modecode, NULL) < 0)
3322 return (-1);
3323
3324 if (lverbose > 1)
3325 scg_prbytes("Modes", pgetmode, sizeof (pgetmode));
3326
3327 return (0);
3328 }
3329
3330 LOCAL int
speed_rd_plextor(scgp,do_speedrd)3331 speed_rd_plextor(scgp, do_speedrd)
3332 SCSI *scgp;
3333 BOOL do_speedrd;
3334 {
3335 int modecode = 0xBB;
3336 Uchar psetmode[8];
3337 Uchar pgetmode[8];
3338 BOOL is_speedrd;
3339
3340 fillbytes(pgetmode, sizeof (pgetmode), '\0');
3341 scgp->silent++;
3342 if (drivemode_plextor(scgp, (caddr_t)pgetmode, sizeof (pgetmode), modecode, NULL) < 0) {
3343 scgp->silent--;
3344 return (-1);
3345 }
3346 scgp->silent--;
3347
3348 if (lverbose > 1)
3349 scg_prbytes("Modes", pgetmode, sizeof (pgetmode));
3350
3351
3352 is_speedrd = (pgetmode[2] & MBbb_SPEAD_READ) != 0;
3353
3354 if (lverbose > 0)
3355 printf("Speed-Read is %s.\n", is_speedrd ? "ON":"OFF");
3356
3357 fillbytes(psetmode, sizeof (psetmode), '\0');
3358 psetmode[0] = pgetmode[2]; /* Copy over old values */
3359 if (do_speedrd >= 0) {
3360 if (do_speedrd)
3361 psetmode[0] |= MBbb_SPEAD_READ;
3362 else
3363 psetmode[0] &= ~MBbb_SPEAD_READ;
3364 }
3365
3366 if (do_speedrd >= 0 && do_speedrd != is_speedrd)
3367 printf("Turning Speed-Read %s.\n", do_speedrd?"on":"off");
3368
3369 if (drivemode_plextor(scgp, NULL, 0, modecode, psetmode) < 0)
3370 return (-1);
3371
3372 fillbytes(pgetmode, sizeof (pgetmode), '\0');
3373 if (drivemode_plextor(scgp, (caddr_t)pgetmode, sizeof (pgetmode), modecode, NULL) < 0)
3374 return (-1);
3375
3376 if (lverbose > 1)
3377 scg_prbytes("Modes", pgetmode, sizeof (pgetmode));
3378
3379 /*
3380 * Set current read speed to new max value.
3381 */
3382 if (do_speedrd >= 0 && do_speedrd != is_speedrd)
3383 scsi_set_speed(scgp, 0xFFFF, -1, ROTCTL_CAV);
3384
3385 return (0);
3386 }
3387
3388 LOCAL int
powerrec_plextor(scgp,do_powerrec)3389 powerrec_plextor(scgp, do_powerrec)
3390 SCSI *scgp;
3391 BOOL do_powerrec;
3392 {
3393 int modecode = 0;
3394 Uchar psetmode[8];
3395 Uchar pgetmode[8];
3396 BOOL is_powerrec;
3397 int speed;
3398
3399 fillbytes(pgetmode, sizeof (pgetmode), '\0');
3400 scgp->silent++;
3401 if (drivemode2_plextor(scgp, (caddr_t)pgetmode, sizeof (pgetmode), modecode, NULL) < 0) {
3402 scgp->silent--;
3403 return (-1);
3404 }
3405 scgp->silent--;
3406
3407 if (lverbose > 1)
3408 scg_prbytes("Modes", pgetmode, sizeof (pgetmode));
3409
3410
3411 is_powerrec = (pgetmode[2] & 1) != 0;
3412
3413 speed = a_to_u_2_byte(&pgetmode[4]);
3414
3415 if (lverbose > 0) {
3416 printf("Power-Rec is %s.\n", is_powerrec ? "ON":"OFF");
3417 printf("Power-Rec write speed: %dx (recommended)\n", speed / 176);
3418 }
3419
3420 fillbytes(psetmode, sizeof (psetmode), '\0');
3421 psetmode[0] = pgetmode[2]; /* Copy over old values */
3422 if (do_powerrec >= 0) {
3423 if (do_powerrec)
3424 psetmode[0] |= 1;
3425 else
3426 psetmode[0] &= ~1;
3427 }
3428
3429 if (do_powerrec >= 0 && do_powerrec != is_powerrec)
3430 printf("Turning Power-Rec %s.\n", do_powerrec?"on":"off");
3431
3432 if (drivemode2_plextor(scgp, NULL, 0, modecode, psetmode) < 0)
3433 return (-1);
3434
3435 fillbytes(pgetmode, sizeof (pgetmode), '\0');
3436 if (drivemode2_plextor(scgp, (caddr_t)pgetmode, sizeof (pgetmode), modecode, NULL) < 0)
3437 return (-1);
3438
3439 if (lverbose > 1)
3440 scg_prbytes("Modes", pgetmode, sizeof (pgetmode));
3441
3442 return (0);
3443 }
3444
3445 LOCAL int
get_speeds_plextor(scgp,selp,maxp,lastp)3446 get_speeds_plextor(scgp, selp, maxp, lastp)
3447 SCSI *scgp;
3448 int *selp;
3449 int *maxp;
3450 int *lastp;
3451 {
3452 register struct scg_cmd *scmd = scgp->scmd;
3453 char buf[10];
3454 int i;
3455
3456 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
3457 fillbytes((caddr_t)buf, sizeof (buf), '\0');
3458 scmd->flags = SCG_DISRE_ENA;
3459 scmd->flags |= SCG_RECV_DATA;
3460 scmd->addr = buf;
3461 scmd->size = sizeof (buf);
3462 scmd->cdb_len = SC_G5_CDBLEN;
3463 scmd->sense_len = CCS_SENSE_LEN;
3464 scmd->cdb.g5_cdb.cmd = 0xEB;
3465 scmd->cdb.g5_cdb.lun = scg_lun(scgp);
3466
3467 i_to_2_byte(&scmd->cdb.cmd_cdb[8], sizeof (buf));
3468
3469 scgp->cmdname = "plextor get speedlist";
3470
3471 if (scg_cmd(scgp) < 0)
3472 return (-1);
3473
3474 i = a_to_u_2_byte(&buf[4]);
3475 if (selp)
3476 *selp = i;
3477
3478 i = a_to_u_2_byte(&buf[6]);
3479 if (maxp)
3480 *maxp = i;
3481
3482 i = a_to_u_2_byte(&buf[8]);
3483 if (lastp)
3484 *lastp = i;
3485
3486 return (0);
3487 }
3488
3489 LOCAL int
bpc_plextor(scgp,mode,bpp)3490 bpc_plextor(scgp, mode, bpp)
3491 SCSI *scgp;
3492 int mode;
3493 int *bpp;
3494 {
3495 register struct scg_cmd *scmd = scgp->scmd;
3496 char buf[4];
3497 int i;
3498
3499 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
3500 fillbytes((caddr_t)buf, sizeof (buf), '\0');
3501 scmd->flags = SCG_DISRE_ENA;
3502 scmd->flags |= SCG_RECV_DATA;
3503 scmd->addr = buf;
3504 scmd->size = sizeof (buf);
3505 scmd->cdb_len = SC_G5_CDBLEN;
3506 scmd->sense_len = CCS_SENSE_LEN;
3507 scmd->cdb.g5_cdb.cmd = 0xF5;
3508 scmd->cdb.g5_cdb.lun = scg_lun(scgp);
3509
3510 scmd->cdb.g5_cdb.addr[1] = 0x08;
3511 scmd->cdb.g5_cdb.addr[2] = mode;
3512
3513 i_to_2_byte(&scmd->cdb.cmd_cdb[8], sizeof (buf));
3514
3515 scgp->cmdname = "plextor read bpc";
3516
3517 if (scg_cmd(scgp) < 0)
3518 return (-1);
3519
3520 if (scg_getresid(scgp) > 2)
3521 return (0);
3522
3523 i = a_to_u_2_byte(buf);
3524 if (bpp)
3525 *bpp = i;
3526
3527 return (0);
3528 }
3529
3530 LOCAL int
plextor_enable(scgp)3531 plextor_enable(scgp)
3532 SCSI *scgp;
3533 {
3534 int ret;
3535 UInt32_t key[4];
3536
3537 scgp->silent++;
3538 ret = plextor_getauth(scgp, key, sizeof (key));
3539 scgp->silent--;
3540 if (ret < 0)
3541 return (ret);
3542
3543 scgp->silent++;
3544 ret = plextor_setauth(scgp, key, sizeof (key));
3545 scgp->silent--;
3546 return (ret);
3547 }
3548
3549 LOCAL int
plextor_disable(scgp)3550 plextor_disable(scgp)
3551 SCSI *scgp;
3552 {
3553 return (plextor_setauth(scgp, NULL, 0));
3554 }
3555
3556 LOCAL int
plextor_getauth(scgp,dp,cnt)3557 plextor_getauth(scgp, dp, cnt)
3558 SCSI *scgp;
3559 void *dp;
3560 int cnt;
3561 {
3562 register struct scg_cmd *scmd = scgp->scmd;
3563
3564 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
3565 scmd->flags = SCG_DISRE_ENA;
3566 scmd->flags |= SCG_RECV_DATA;
3567 scmd->addr = dp;
3568 scmd->size = cnt;
3569 scmd->cdb_len = SC_G5_CDBLEN;
3570 scmd->sense_len = CCS_SENSE_LEN;
3571 scmd->cdb.g5_cdb.cmd = 0xD4;
3572 scmd->cdb.g5_cdb.lun = scg_lun(scgp);
3573 scmd->cdb.cmd_cdb[10] = cnt;
3574
3575 scgp->cmdname = "plextor getauth";
3576
3577 if (scg_cmd(scgp) < 0)
3578 return (-1);
3579 return (0);
3580 }
3581
3582 LOCAL int
plextor_setauth(scgp,dp,cnt)3583 plextor_setauth(scgp, dp, cnt)
3584 SCSI *scgp;
3585 void *dp;
3586 int cnt;
3587 {
3588 register struct scg_cmd *scmd = scgp->scmd;
3589
3590 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
3591 scmd->flags = SCG_DISRE_ENA;
3592 scmd->addr = dp;
3593 scmd->size = cnt;
3594 scmd->cdb_len = SC_G5_CDBLEN;
3595 scmd->sense_len = CCS_SENSE_LEN;
3596 scmd->cdb.g5_cdb.cmd = 0xD5;
3597 scmd->cdb.g5_cdb.lun = scg_lun(scgp);
3598 scmd->cdb.cmd_cdb[1] = 0x01;
3599 if (cnt != 0) /* If cnt == 0 clearauth */
3600 scmd->cdb.cmd_cdb[2] = 0x01;
3601 scmd->cdb.cmd_cdb[10] = cnt;
3602
3603 scgp->cmdname = "plextor setauth";
3604
3605 if (scg_cmd(scgp) < 0)
3606 return (-1);
3607 return (0);
3608 }
3609
3610 LOCAL int
set_audiomaster_yamaha(scgp,dp,keep_mode)3611 set_audiomaster_yamaha(scgp, dp, keep_mode)
3612 SCSI *scgp;
3613 cdr_t *dp;
3614 BOOL keep_mode;
3615 {
3616 Uchar mode[0x100];
3617 int len;
3618 int ret = 0;
3619 struct cd_mode_page_05 *mp;
3620
3621 if (xdebug && !keep_mode)
3622 printf("Checking for Yamaha Audio Master feature: ");
3623
3624 /*
3625 * Do not reset mp->test_write (-dummy) here.
3626 */
3627 deflt_writemodes_mmc(scgp, FALSE);
3628
3629 fillbytes((caddr_t)mode, sizeof (mode), '\0');
3630
3631 scgp->silent++;
3632 if (!get_mode_params(scgp, 0x05, "CD write parameter",
3633 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) {
3634 scgp->silent--;
3635 return (-1);
3636 }
3637 if (len == 0) {
3638 scgp->silent--;
3639 return (-1);
3640 }
3641
3642 mp = (struct cd_mode_page_05 *)
3643 (mode + sizeof (struct scsi_mode_header) +
3644 ((struct scsi_mode_header *)mode)->blockdesc_len);
3645 #ifdef DEBUG
3646 scg_prbytes("CD write parameter:", (Uchar *)mode, len);
3647 #endif
3648
3649 /*
3650 * Do not set mp->test_write (-dummy) here. It should be set
3651 * only at one place and only one time.
3652 */
3653 mp->BUFE = 0;
3654
3655 mp->write_type = 8;
3656 mp->track_mode = 0;
3657 mp->dbtype = DB_RAW;
3658
3659 if (!set_mode_params(scgp, "CD write parameter", mode, len, 0, -1))
3660 ret = -1;
3661
3662 /*
3663 * Do not reset mp->test_write (-dummy) here.
3664 */
3665 if (!keep_mode || ret < 0)
3666 deflt_writemodes_mmc(scgp, FALSE);
3667 scgp->silent--;
3668
3669 return (ret);
3670 }
3671
3672 EXPORT struct ricoh_mode_page_30 *
get_justlink_ricoh(scgp,mode)3673 get_justlink_ricoh(scgp, mode)
3674 SCSI *scgp;
3675 Uchar *mode;
3676 {
3677 Uchar modec[0x100];
3678 int len;
3679 struct ricoh_mode_page_30 *mp;
3680
3681 scgp->silent++;
3682 if (!get_mode_params(scgp, 0x30, "Ricoh Vendor Page", mode, modec, NULL, NULL, &len)) {
3683 scgp->silent--;
3684 return ((struct ricoh_mode_page_30 *)0);
3685 }
3686 scgp->silent--;
3687
3688 /*
3689 * SCSI mode header + 6 bytes mode page 30.
3690 * This is including the Burn-Free counter.
3691 */
3692 if (len < 10)
3693 return ((struct ricoh_mode_page_30 *)0);
3694
3695 if (xdebug) {
3696 error("Mode len: %d\n", len);
3697 scg_prbytes("Mode Sense Data ", mode, len);
3698 scg_prbytes("Mode Sence CData", modec, len);
3699 }
3700
3701 mp = (struct ricoh_mode_page_30 *)
3702 (mode + sizeof (struct scsi_mode_header) +
3703 ((struct scsi_mode_header *)mode)->blockdesc_len);
3704
3705 /*
3706 * 6 bytes mode page 30.
3707 * This is including the Burn-Free counter.
3708 */
3709 if ((len - ((Uchar *)mp - mode) -1) < 5)
3710 return ((struct ricoh_mode_page_30 *)0);
3711
3712 if (xdebug) {
3713 error("Burnfree counter: %d\n", a_to_u_2_byte(mp->link_counter));
3714 }
3715 return (mp);
3716 }
3717
3718 LOCAL int
force_speed_yamaha(scgp,readspeed,writespeed)3719 force_speed_yamaha(scgp, readspeed, writespeed)
3720 SCSI *scgp;
3721 int readspeed;
3722 int writespeed;
3723 {
3724 register struct scg_cmd *scmd = scgp->scmd;
3725
3726 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
3727 scmd->flags = SCG_DISRE_ENA;
3728 scmd->cdb_len = SC_G5_CDBLEN;
3729 scmd->sense_len = CCS_SENSE_LEN;
3730 scmd->cdb.g5_cdb.cmd = 0xBB;
3731 scmd->cdb.g5_cdb.lun = scg_lun(scgp);
3732
3733 if (readspeed < 0)
3734 i_to_2_byte(&scmd->cdb.g5_cdb.addr[0], 0xFFFF);
3735 else
3736 i_to_2_byte(&scmd->cdb.g5_cdb.addr[0], readspeed);
3737 if (writespeed < 0)
3738 i_to_2_byte(&scmd->cdb.g5_cdb.addr[2], 0xFFFF);
3739 else
3740 i_to_2_byte(&scmd->cdb.g5_cdb.addr[2], writespeed);
3741
3742 scmd->cdb.cmd_cdb[11] = 0x80;
3743
3744 scgp->cmdname = "yamaha force cd speed";
3745
3746 if (scg_cmd(scgp) < 0)
3747 return (-1);
3748 return (0);
3749 }
3750
3751 LOCAL BOOL
get_tattoo_yamaha(scgp,print,irp,orp)3752 get_tattoo_yamaha(scgp, print, irp, orp)
3753 SCSI *scgp;
3754 BOOL print;
3755 Int32_t *irp;
3756 Int32_t *orp;
3757 {
3758 Uchar mode[0x100];
3759 int len;
3760 UInt32_t ival;
3761 UInt32_t oval;
3762 Uchar *mp;
3763
3764 scgp->silent++;
3765 if (!get_mode_params(scgp, 0x31, "Yamaha Tattoo Page", mode, NULL, NULL, NULL, &len)) {
3766 scgp->silent--;
3767 return (FALSE);
3768 }
3769 scgp->silent--;
3770
3771 /*
3772 * SCSI mode header + 16 bytes mode page 31.
3773 * This is including the Burn-Free counter.
3774 */
3775 if (len < 20)
3776 return (FALSE);
3777
3778 mp = (Uchar *)
3779 (mode + sizeof (struct scsi_mode_header) +
3780 ((struct scsi_mode_header *)mode)->blockdesc_len);
3781
3782 /*
3783 * 10 bytes mode page 31.
3784 * This is including the Burn-Free counter.
3785 */
3786 if ((len - ((Uchar *)mp - mode) -1) < 10)
3787 return (FALSE);
3788
3789 ival = a_to_u_3_byte(&mp[4]);
3790 oval = a_to_u_3_byte(&mp[7]);
3791
3792 if (irp)
3793 *irp = ival;
3794 if (orp)
3795 *orp = oval;
3796
3797 if (print && ival > 0 && oval > 0) {
3798 printf("DiskT@2 inner r: %d\n", (int)ival);
3799 printf("DiskT@2 outer r: %d\n", (int)oval);
3800 printf("DiskT@2 image size: 3744 x %d pixel.\n",
3801 (int)(oval-ival)+1);
3802 }
3803
3804 return (TRUE);
3805 }
3806
3807 LOCAL int
do_tattoo_yamaha(scgp,f)3808 do_tattoo_yamaha(scgp, f)
3809 SCSI *scgp;
3810 FILE *f;
3811 {
3812 Int32_t ival = 0;
3813 Int32_t oval = 0;
3814 Int32_t lines;
3815 off_t fsize;
3816 char *buf = scgp->bufptr;
3817 long bufsize = scgp->maxbuf;
3818 long nsecs;
3819 long amt;
3820
3821 nsecs = bufsize / 2048;
3822 bufsize = nsecs * 2048;
3823
3824 if (!get_tattoo_yamaha(scgp, FALSE, &ival, &oval)) {
3825 errmsgno(EX_BAD, "Cannot get DiskT@2 info.\n");
3826 return (-1);
3827 }
3828
3829 if (ival == 0 || oval == 0) {
3830 errmsgno(EX_BAD, "DiskT@2 info not valid.\n");
3831 return (-1);
3832 }
3833
3834 lines = oval - ival + 1;
3835 fsize = filesize(f);
3836 if ((fsize % 3744) != 0 || fsize < (lines*3744)) {
3837 errmsgno(EX_BAD, "Illegal DiskT@2 file size.\n");
3838 return (-1);
3839 }
3840 if (fsize > (lines*3744))
3841 fsize = lines*3744;
3842
3843 if (lverbose)
3844 printf("Starting to write DiskT@2 data.\n");
3845 fillbytes(buf, bufsize, '\0');
3846 if ((amt = fileread(f, buf, bufsize)) <= 0) {
3847 errmsg("DiskT@2 file read error.\n");
3848 return (-1);
3849 }
3850
3851 if (yamaha_write_buffer(scgp, 1, 0, ival, amt/2048, buf, amt) < 0) {
3852 errmsgno(EX_BAD, "DiskT@2 1st write error.\n");
3853 return (-1);
3854 }
3855 amt = (amt+2047) / 2048 * 2048;
3856 fsize -= amt;
3857
3858 while (fsize > 0) {
3859 fillbytes(buf, bufsize, '\0');
3860 if ((amt = fileread(f, buf, bufsize)) <= 0) {
3861 errmsg("DiskT@2 file read error.\n");
3862 return (-1);
3863 }
3864 amt = (amt+2047) / 2048 * 2048;
3865 fsize -= amt;
3866 if (yamaha_write_buffer(scgp, 1, 0, 0, amt/2048, buf, amt) < 0) {
3867 errmsgno(EX_BAD, "DiskT@2 write error.\n");
3868 return (-1);
3869 }
3870 }
3871
3872 if (yamaha_write_buffer(scgp, 1, 0, oval, 0, buf, 0) < 0) {
3873 errmsgno(EX_BAD, "DiskT@2 final error.\n");
3874 return (-1);
3875 }
3876
3877 wait_unit_ready(scgp, 1000); /* Wait for DiskT@2 */
3878 waitfix_mmc(scgp, 1000); /* Wait for DiskT@2 */
3879
3880 return (0);
3881 }
3882
3883 /*
3884 * Yamaha specific version of 'write buffer' that offers an additional
3885 * Parameter Length 'parlen' parameter.
3886 */
3887 LOCAL int
yamaha_write_buffer(scgp,mode,bufferid,offset,parlen,buffer,buflen)3888 yamaha_write_buffer(scgp, mode, bufferid, offset, parlen, buffer, buflen)
3889 SCSI *scgp;
3890 int mode;
3891 int bufferid;
3892 long offset;
3893 long parlen;
3894 void *buffer;
3895 long buflen;
3896 {
3897 register struct scg_cmd *scmd = scgp->scmd;
3898 Uchar *CDB;
3899
3900 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
3901 scmd->addr = buffer;
3902 scmd->size = buflen;
3903 scmd->flags = SCG_DISRE_ENA;
3904 scmd->cdb_len = SC_G1_CDBLEN;
3905 scmd->sense_len = CCS_SENSE_LEN;
3906 scmd->cdb.g1_cdb.cmd = 0x3B;
3907
3908 CDB = (Uchar *)scmd->cdb.cmd_cdb;
3909 CDB[1] = mode & 7;
3910 CDB[2] = bufferid;
3911 i_to_3_byte(&CDB[3], offset);
3912 i_to_3_byte(&CDB[6], parlen);
3913
3914 scgp->cmdname = "write_buffer";
3915
3916 if (scg_cmd(scgp) >= 0)
3917 return (1);
3918 return (0);
3919 }
3920