2 * This file has been modified for the cdrkit suite.
4 * The behaviour and appearence of the program code below can differ to a major
5 * extent from the version distributed by the original author(s).
7 * For details, see Changelog file distributed with the cdrkit package. If you
8 * received this file from another source then ask the distributing person for
9 * a log of modifications.
13 /* @(#)drv_mmc.c 1.163 06/01/12 Copyright 1997-2006 J. Schilling */
15 * CDR device implementation for
16 * SCSI-3/mmc conforming drives
17 * e.g. Yamaha CDR-400, Ricoh MP6200
19 * Copyright (c) 1997-2006 J. Schilling
22 * This program is free software; you can redistribute it and/or modify
23 * it under the terms of the GNU General Public License version 2
24 * as published by the Free Software Foundation.
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
31 * You should have received a copy of the GNU General Public License along with
32 * this program; see the file COPYING. If not, write to the Free Software
33 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
54 #include <usal/usalcmd.h>
55 #include <usal/scsidefs.h>
56 #include <usal/scsireg.h>
57 #include <usal/scsitransp.h>
60 #include "mmcvendor.h"
62 #include "scsi_scan.h"
64 extern char *driveropts;
70 static int curspeed = 1;
72 static char clv_to_speed[16] = {
73 /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
74 0, 2, 4, 6, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
77 static char hs_clv_to_speed[16] = {
78 /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
79 0, 2, 4, 6, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
82 static char us_clv_to_speed[16] = {
83 /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
84 0, 2, 4, 8, 0, 0, 16, 0, 24, 32, 40, 48, 0, 0, 0, 0
88 static int mmc_load(SCSI *usalp, cdr_t *dp);
89 static int mmc_unload(SCSI *usalp, cdr_t *dp);
91 void mmc_opthelp(cdr_t *dp, int excode);
92 char *hasdrvopt(char *optstr, char *optname);
93 static cdr_t *identify_mmc(SCSI *usalp, cdr_t *, struct scsi_inquiry *);
94 static int attach_mmc(SCSI *usalp, cdr_t *);
95 static int attach_mdvd(SCSI *usalp, cdr_t *);
96 int check_writemodes_mmc(SCSI *usalp, cdr_t *dp);
97 int check_writemodes_mdvd(SCSI *usalp, cdr_t *dp);
98 static int deflt_writemodes_mmc(SCSI *usalp, BOOL reset_dummy);
99 static int deflt_writemodes_mdvd(SCSI *usalp, BOOL reset_dummy);
100 static int get_diskinfo(SCSI *usalp, struct disk_info *dip);
101 static void di_to_dstat(struct disk_info *dip, dstat_t *dsp);
102 static int get_atip(SCSI *usalp, struct atipinfo *atp);
104 static int get_pma(SCSI *usalp);
106 static int init_mmc(SCSI *usalp, cdr_t *dp);
107 static int getdisktype_mmc(SCSI *usalp, cdr_t *dp);
108 static int getdisktype_mdvd(SCSI *usalp, cdr_t *dp);
109 static int speed_select_mmc(SCSI *usalp, cdr_t *dp, int *speedp);
110 static int speed_select_mdvd(SCSI *usalp, cdr_t *dp, int *speedp);
111 static int mmc_set_speed(SCSI *usalp, int readspeed, int writespeed,
113 static int next_wr_addr_mmc(SCSI *usalp, track_t *trackp, long *ap);
114 static int next_wr_addr_mdvd(SCSI *usalp, track_t *trackp, long *ap);
115 static int write_leadin_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp);
116 static int open_track_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp);
117 static int open_track_mdvd(SCSI *usalp, cdr_t *dp, track_t *trackp);
118 static int close_track_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp);
119 static int close_track_mdvd(SCSI *usalp, cdr_t *dp, track_t *trackp);
120 static int open_session_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp);
121 static int open_session_mdvd(SCSI *usalp, cdr_t *dp, track_t *trackp);
122 static int waitfix_mmc(SCSI *usalp, int secs);
123 static int fixate_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp);
124 static int fixate_mdvd(SCSI *usalp, cdr_t *dp, track_t *trackp);
125 static int blank_mmc(SCSI *usalp, cdr_t *dp, long addr, int blanktype);
126 static int format_mdvd(SCSI *usalp, cdr_t *dp, int formattype);
127 static int send_opc_mmc(SCSI *usalp, caddr_t, int cnt, int doopc);
128 static int opt1_mmc(SCSI *usalp, cdr_t *dp);
129 static int opt1_mdvd(SCSI *usalp, cdr_t *dp);
130 static int opt2_mmc(SCSI *usalp, cdr_t *dp);
131 static int scsi_sony_write(SCSI *usalp, caddr_t bp, long sectaddr, long size,
132 int blocks, BOOL islast);
133 static int gen_cue_mmc(track_t *trackp, void *vcuep, BOOL needgap);
134 static void fillcue(struct mmc_cue *cp, int ca, int tno, int idx, int dataform,
135 int scms, msf_t *mp);
136 static int send_cue_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp);
137 static int stats_mmc(SCSI *usalp, cdr_t *dp);
138 static BOOL mmc_isplextor(SCSI *usalp);
139 static BOOL mmc_isyamaha(SCSI *usalp);
140 static void do_varirec_plextor(SCSI *usalp);
141 static int do_gigarec_plextor(SCSI *usalp);
142 static int drivemode_plextor(SCSI *usalp, caddr_t bp, int cnt, int modecode,
144 static int drivemode2_plextor(SCSI *usalp, caddr_t bp, int cnt, int modecode,
146 static int check_varirec_plextor(SCSI *usalp);
147 static int check_gigarec_plextor(SCSI *usalp);
148 static int varirec_plextor(SCSI *usalp, BOOL on, int val);
149 static int gigarec_plextor(SCSI *usalp, int val);
150 static Int32_t gigarec_mult(int code, Int32_t val);
151 static int check_ss_hide_plextor(SCSI *usalp);
152 static int check_speed_rd_plextor(SCSI *usalp);
153 static int check_powerrec_plextor(SCSI *usalp);
154 static int ss_hide_plextor(SCSI *usalp, BOOL do_ss, BOOL do_hide);
155 static int speed_rd_plextor(SCSI *usalp, BOOL do_speedrd);
156 static int powerrec_plextor(SCSI *usalp, BOOL do_powerrec);
157 static int get_speeds_plextor(SCSI *usalp, int *selp, int *maxp, int *lastp);
158 static int bpc_plextor(SCSI *usalp, int mode, int *bpp);
159 static int set_audiomaster_yamaha(SCSI *usalp, cdr_t *dp, BOOL keep_mode);
161 struct ricoh_mode_page_30 * get_justlink_ricoh(SCSI *usalp, Uchar *mode);
162 static int force_speed_yamaha(SCSI *usalp, int readspeed, int writespeed);
163 static BOOL get_tattoo_yamaha(SCSI *usalp, BOOL print, Int32_t *irp,
165 static int do_tattoo_yamaha(SCSI *usalp, FILE *f);
166 static int yamaha_write_buffer(SCSI *usalp, int mode, int bufferid, long offset,
167 long parlen, void *buffer, long buflen);
168 static int dvd_dual_layer_split(SCSI *usalp, cdr_t *dp, long tsize);
170 extern int reserve_track(SCSI *usalp, Ulong size); /* FIXME */
171 extern int scsi_format(SCSI *usalp, caddr_t addr, int size, BOOL background); /* FIXME */
175 mmc_load(SCSI *usalp, cdr_t *dp)
177 return (scsi_load_unload(usalp, 1));
181 mmc_unload(SCSI *usalp, cdr_t *dp)
183 return (scsi_load_unload(usalp, 0));
196 "generic SCSI-3/mmc CD-R/CD-RW driver",
206 cmd_dummy, /* check_recovery */
207 (int(*)(SCSI *, cdr_t *, int))cmd_dummy, /* recover */
211 (int(*)(SCSI *, Ulong))cmd_ill, /* reserve_track */
220 cmd_dummy, /* abort */
237 "generic SCSI-3/mmc DVD-R(W) driver",
247 cmd_dummy, /* check_recovery */
248 (int(*)__PR((SCSI *, cdr_t *, int)))cmd_dummy, /* recover */
252 (int(*)(SCSI *, Ulong))cmd_ill, /* reserve_track */
254 (int(*)__PR((track_t *, void *, BOOL)))cmd_dummy, /* gen_cue */
255 (int(*)__PR((SCSI *usalp, cdr_t *, track_t *)))cmd_dummy, /* send_cue */
261 cmd_dummy, /* abort */
270 dvd_dual_layer_split,
276 cdr_t cdr_mmc_sony = {
282 "generic SCSI-3/mmc CD-R/CD-RW driver (Sony 928 variant)",
292 cmd_dummy, /* check_recovery */
293 (int(*)(SCSI *, cdr_t *, int))cmd_dummy, /* recover */
297 (int(*)(SCSI *, Ulong))cmd_ill, /* reserve_track */
306 cmd_dummy, /* abort */
309 cmd_dummy, /* stats */
318 * SCSI-3/mmc conformant CD-ROM drive
322 CDR_ISREADER|CDR_SWABAUDIO,
326 "generic SCSI-3/mmc CD-ROM driver",
336 cmd_dummy, /* check_recovery */
337 (int(*)(SCSI *, cdr_t *, int))cmd_dummy, /* recover */
340 (int(*)(SCSI *usalp, track_t *, long *))cmd_ill, /* next_wr_addr */
341 (int(*)(SCSI *, Ulong))cmd_ill, /* reserve_track */
343 (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */
345 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
348 (int(*)(SCSI *usalp, cdr_t *, track_t *))cmd_dummy,
350 cmd_dummy, /* abort */
352 (int(*)(SCSI *usalp, cdr_t *, track_t *))cmd_dummy, /* fixation */
353 cmd_dummy, /* stats */
356 (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */
357 cmd_dummy, /* opt1 */
358 cmd_dummy, /* opt2 */
362 * Old pre SCSI-3/mmc CD drive
370 "generic SCSI-2 CD-ROM driver",
380 cmd_dummy, /* check_recovery */
381 (int(*)(SCSI *, cdr_t *, int))cmd_dummy, /* recover */
384 (int(*)(SCSI *usal, track_t *, long *))cmd_ill, /* next_wr_addr */
385 (int(*)(SCSI *, Ulong))cmd_ill, /* reserve_track */
387 (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */
389 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
392 (int(*)(SCSI *usalp, cdr_t *, track_t *))cmd_dummy,
394 cmd_dummy, /* abort */
395 read_session_offset_philips,
396 (int(*)(SCSI *usalp, cdr_t *, track_t *))cmd_dummy, /* fixation */
397 cmd_dummy, /* stats */
400 (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */
401 cmd_dummy, /* opt1 */
402 cmd_dummy, /* opt2 */
406 * SCSI-3/mmc conformant CD or DVD writer
407 * Checks the current medium and then returns either cdr_mmc or cdr_dvd
415 "generic SCSI-3/mmc CD/DVD driver (checks media)",
425 cmd_dummy, /* check_recovery */
426 (int(*)(SCSI *, cdr_t *, int))cmd_dummy, /* recover */
429 (int(*)(SCSI *usalp, track_t *, long *))cmd_ill, /* next_wr_addr */
430 (int(*)(SCSI *, Ulong))cmd_ill, /* reserve_track */
432 (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */
434 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
437 (int(*)(SCSI *usalp, cdr_t *, track_t *))cmd_dummy,
439 cmd_dummy, /* abort */
441 (int(*)(SCSI *usalp, cdr_t *, track_t *))cmd_dummy, /* fixation */
442 cmd_dummy, /* stats */
445 (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */
446 cmd_dummy, /* opt1 */
447 cmd_dummy, /* opt2 */
451 mmc_opthelp(cdr_t *dp, int excode)
453 BOOL haveopts = FALSE;
455 fprintf(stderr, "Driver options:\n");
456 if (dp->cdr_flags & CDR_BURNFREE) {
457 fprintf(stderr, "burnfree Prepare writer to use BURN-Free technology\n");
458 fprintf(stderr, "noburnfree Disable using BURN-Free technology\n");
461 if (dp->cdr_flags & CDR_VARIREC) {
462 fprintf(stderr, "varirec=val Set VariRec Laserpower to -2, -1, 0, 1, 2\n");
463 fprintf(stderr, " Only works for audio and if speed is set to 4\n");
466 if (dp->cdr_flags & CDR_GIGAREC) {
467 fprintf(stderr, "gigarec=val Set GigaRec capacity ratio to 0.6, 0.7, 0.8, 1.0, 1.2, 1.3, 1.4\n");
470 if (dp->cdr_flags & CDR_AUDIOMASTER) {
471 fprintf(stderr, "audiomaster Turn Audio Master feature on (SAO CD-R Audio/Data only)\n");
474 if (dp->cdr_flags & CDR_FORCESPEED) {
475 fprintf(stderr, "forcespeed Tell the drive to force speed even for low quality media\n");
478 if (dp->cdr_flags & CDR_SPEEDREAD) {
479 fprintf(stderr, "speedread Tell the drive to read as fast as possible\n");
480 fprintf(stderr, "nospeedread Disable to read as fast as possible\n");
483 if (dp->cdr_flags & CDR_DISKTATTOO) {
484 fprintf(stderr, "tattooinfo Print image size info for DiskT@2 feature\n");
485 fprintf(stderr, "tattoofile=name Use 'name' as DiskT@2 image file\n");
488 if (dp->cdr_flags & CDR_SINGLESESS) {
489 fprintf(stderr, "singlesession Tell the drive to behave as single session only drive\n");
490 fprintf(stderr, "nosinglesession Disable single session only mode\n");
493 if (dp->cdr_flags & CDR_HIDE_CDR) {
494 fprintf(stderr, "hidecdr Tell the drive to hide CD-R media\n");
495 fprintf(stderr, "nohidecdr Disable hiding CD-R media\n");
499 fprintf(stderr, "None supported for this drive.\n");
505 hasdrvopt(char *optstr, char *optname)
517 optnamelen = strlen(optname);
520 not = FALSE; /* Reset before every token */
521 if ((ep = strchr(optstr, ',')) != NULL) {
522 optlen = ep - optstr;
525 optlen = strlen(optstr);
526 np = &optstr[optlen];
528 if ((ep = strchr(optstr, '=')) != NULL) {
530 optlen = ep - optstr;
532 if (optstr[0] == '!') {
537 if (strncmp(optstr, "no", 2) == 0) {
542 if (strncmp(optstr, optname, optlen) == 0) {
543 ret = &optstr[optlen];
549 if (*ret == ',' || *ret == '\0') {
564 identify_mmc(SCSI *usalp, cdr_t *dp, struct scsi_inquiry *ip)
566 BOOL cdrr = FALSE; /* Read CD-R */
567 BOOL cdwr = FALSE; /* Write CD-R */
568 BOOL cdrrw = FALSE; /* Read CD-RW */
569 BOOL cdwrw = FALSE; /* Write CD-RW */
570 BOOL dvdwr = FALSE; /* DVD writer */
571 BOOL is_dvd = FALSE; /* use DVD driver*/
573 struct cd_mode_page_2A *mp;
576 if (ip->type != INQ_WORM && ip->type != INQ_ROMD)
579 allow_atapi(usalp, TRUE); /* Try to switch to 10 byte mode cmds */
582 mp = mmc_cap(usalp, mode); /* Get MMC capabilities */
585 return (&cdr_oldcd); /* Pre SCSI-3/mmc drive */
588 * At this point we know that we have a SCSI-3/mmc compliant drive.
589 * Unfortunately ATAPI drives violate the SCSI spec in returning
590 * a response data format of '1' which from the SCSI spec would
591 * tell us not to use the "PF" bit in mode select. As ATAPI drives
592 * require the "PF" bit to be set, we 'correct' the inquiry data.
594 * XXX xxx_identify() should not have any side_effects ??
596 if (ip->data_format < 2)
600 * First handle exceptions....
602 if (strncmp(ip->vendor_info, "SONY", 4) == 0 &&
603 strncmp(ip->prod_ident, "CD-R CDU928E", 14) == 0) {
604 return (&cdr_mmc_sony);
608 * Now try to do it the MMC-3 way....
610 profile = get_curprofile(usalp);
612 printf("Current profile: 0x%04X\n", profile);
615 print_profiles(usalp);
617 * If the current profile is 0x0000, then the
618 * drive does not know about the media. First
619 * close the tray and then try to issue the
620 * get_curprofile() command again.
623 load_media(usalp, dp, FALSE);
625 profile = get_curprofile(usalp);
626 scsi_prevent_removal(usalp, 0);
628 printf("Current profile: 0x%04X\n", profile);
632 print_profiles(usalp);
633 if (profile == 0 || (profile >= 0x10 && profile <= 0x15) || profile > 0x19) {
638 * 13h DVD-RW (Restricted overwrite)
639 * 14h DVD-RW (Sequential recording)
645 if (profile == 0x11 || profile == 0x13 || profile == 0x14 || profile == 0x1A || profile == 0x1B || profile == 0x2B) {
652 if (profile == 0) { /* No Medium */
656 * Check for CD-writer
658 get_wproflist(usalp, &is_cdr, NULL,
663 * Other MMC-3 drive without media
666 } if (profile == 0x12) { /* DVD-RAM */
668 "Found unsupported DVD-RAM media.\n");
675 printf("Drive is pre MMC-3\n");
678 mmc_getval(mp, &cdrr, &cdwr, &cdrrw, &cdwrw, NULL, &dvdwr);
680 if (!cdwr && !cdwrw) { /* SCSI-3/mmc CD drive */
682 * If the drive does not support to write CD's, we select the
683 * CD-ROM driver here. If we have DVD-R/DVD-RW support compiled
684 * in, we may later decide to switch to the DVD driver.
689 * We need to set the driver to cdr_mmc because we may come
690 * here with driver set to cdr_cd_dvd which is not a driver
691 * that may be used for actual CD/DVD writing.
696 /*#define DVD_DEBUG*/
698 if (1) { /* Always check for DVD media in debug mode */
700 if ((cdwr || cdwrw) && dvdwr) {
707 fprintf(stderr, "identify_dvd: checking for DVD media\n");
709 if (read_dvd_structure(usalp, (caddr_t)xb, 32, 0, 0, 0) >= 0) {
711 * If read DVD structure is supported and works, then
712 * we must have a DVD media in the drive. Signal to
713 * use the DVD driver.
717 if (usal_sense_key(usalp) == SC_NOT_READY) {
719 * If the SCSI sense key is NOT READY, then the
720 * drive does not know about the media. First
721 * close the tray and then try to issue the
722 * read_dvd_structure() command again.
724 load_media(usalp, dp, FALSE);
725 if (read_dvd_structure(usalp, (caddr_t)xb, 32, 0, 0, 0) >= 0) {
728 scsi_prevent_removal(usalp, 0);
734 fprintf(stderr, "identify_dvd: is_dvd: %d\n", is_dvd);
739 fprintf(stderr, "Found DVD media: using cdr_mdvd.\n");
742 dp->profile = profile;
748 attach_mmc(SCSI *usalp, cdr_t *dp)
752 struct cd_mode_page_2A *mp;
753 struct ricoh_mode_page_30 *rp = NULL;
755 allow_atapi(usalp, TRUE); /* Try to switch to 10 byte mode cmds */
758 mp = mmc_cap(usalp, NULL); /* Get MMC capabilities in allocated mp */
761 return (-1); /* Pre SCSI-3/mmc drive */
763 dp->cdr_cdcap = mp; /* Store MMC cap pointer */
765 dp->cdr_dstat->ds_dr_max_rspeed = a_to_u_2_byte(mp->max_read_speed)/176;
766 if (dp->cdr_dstat->ds_dr_max_rspeed == 0)
767 dp->cdr_dstat->ds_dr_max_rspeed = 372;
768 dp->cdr_dstat->ds_dr_cur_rspeed = a_to_u_2_byte(mp->cur_read_speed)/176;
769 if (dp->cdr_dstat->ds_dr_cur_rspeed == 0)
770 dp->cdr_dstat->ds_dr_cur_rspeed = 372;
772 dp->cdr_dstat->ds_dr_max_wspeed = a_to_u_2_byte(mp->max_write_speed)/176;
774 dp->cdr_dstat->ds_dr_cur_wspeed = a_to_u_2_byte(mp->v3_cur_write_speed)/176;
776 dp->cdr_dstat->ds_dr_cur_wspeed = a_to_u_2_byte(mp->cur_write_speed)/176;
778 if (dp->cdr_speedmax > dp->cdr_dstat->ds_dr_max_wspeed)
779 dp->cdr_speedmax = dp->cdr_dstat->ds_dr_max_wspeed;
781 if (dp->cdr_speeddef > dp->cdr_speedmax)
782 dp->cdr_speeddef = dp->cdr_speedmax;
784 rp = get_justlink_ricoh(usalp, mode);
787 dp->cdr_flags |= CDR_MMC3;
789 dp->cdr_flags |= CDR_MMC2;
790 dp->cdr_flags |= CDR_MMC;
792 if (mp->loading_type == LT_TRAY)
793 dp->cdr_flags |= CDR_TRAYLOAD;
794 else if (mp->loading_type == LT_CADDY)
795 dp->cdr_flags |= CDR_CADDYLOAD;
798 dp->cdr_flags |= CDR_BURNFREE;
800 if ((dp->cdr_cmdflags & F_DUMMY) && rp->TWBFS && rp->BUEFS)
801 dp->cdr_flags |= CDR_BURNFREE;
804 dp->cdr_flags |= CDR_BURNFREE;
807 if (mmc_isplextor(usalp)) {
808 if (check_varirec_plextor(usalp) >= 0)
809 dp->cdr_flags |= CDR_VARIREC;
811 if (check_gigarec_plextor(usalp) >= 0)
812 dp->cdr_flags |= CDR_GIGAREC;
814 if (check_ss_hide_plextor(usalp) >= 0)
815 dp->cdr_flags |= CDR_SINGLESESS|CDR_HIDE_CDR;
817 if (check_powerrec_plextor(usalp) >= 0)
818 dp->cdr_flags |= CDR_FORCESPEED;
820 if (check_speed_rd_plextor(usalp) >= 0)
821 dp->cdr_flags |= CDR_SPEEDREAD;
823 if (mmc_isyamaha(usalp)) {
824 if (set_audiomaster_yamaha(usalp, dp, FALSE) >= 0)
825 dp->cdr_flags |= CDR_AUDIOMASTER;
828 * Starting with CRW 2200 / CRW 3200
830 if ((mp->p_len+2) >= (unsigned)28)
831 dp->cdr_flags |= CDR_FORCESPEED;
833 if (get_tattoo_yamaha(usalp, FALSE, 0, 0))
834 dp->cdr_flags |= CDR_DISKTATTOO;
838 dp->cdr_flags |= CDR_FORCESPEED;
841 if (mp->p_len >= 28) {
844 val = dp->cdr_dstat->ds_dr_cur_wspeed;
849 if (scsi_set_speed(usalp, -1, val, ROTCTL_CAV) < 0) {
850 fprintf(stderr, "XXX\n");
856 check_writemodes_mmc(usalp, dp);
858 /* Enable Burnfree by default, it can be disabled later */
859 if ((dp->cdr_flags & CDR_BURNFREE) != 0)
860 dp->cdr_dstat->ds_cdrflags |= RF_BURNFREE;
862 if (driveropts != NULL) {
865 if (strcmp(driveropts, "help") == 0) {
869 p = hasdrvopt(driveropts, "varirec");
870 if (p != NULL && (dp->cdr_flags & CDR_VARIREC) != 0) {
871 dp->cdr_dstat->ds_cdrflags |= RF_VARIREC;
874 p = hasdrvopt(driveropts, "gigarec");
875 if (p != NULL && (dp->cdr_flags & CDR_GIGAREC) != 0) {
876 dp->cdr_dstat->ds_cdrflags |= RF_GIGAREC;
879 p = hasdrvopt(driveropts, "audiomaster");
880 if (p != NULL && *p == '1' && (dp->cdr_flags & CDR_AUDIOMASTER) != 0) {
881 dp->cdr_dstat->ds_cdrflags |= RF_AUDIOMASTER;
882 dp->cdr_dstat->ds_cdrflags &= ~RF_BURNFREE;
884 p = hasdrvopt(driveropts, "forcespeed");
885 if (p != NULL && *p == '1' && (dp->cdr_flags & CDR_FORCESPEED) != 0) {
886 dp->cdr_dstat->ds_cdrflags |= RF_FORCESPEED;
888 p = hasdrvopt(driveropts, "tattooinfo");
889 if (p != NULL && *p == '1' && (dp->cdr_flags & CDR_DISKTATTOO) != 0) {
890 get_tattoo_yamaha(usalp, TRUE, 0, 0);
892 p = hasdrvopt(driveropts, "tattoofile");
893 if (p != NULL && (dp->cdr_flags & CDR_DISKTATTOO) != 0) {
896 if ((f = fileopen(p, "rb")) == NULL)
897 comerr("Cannot open '%s'.\n", p);
899 if (do_tattoo_yamaha(usalp, f) < 0)
900 errmsgno(EX_BAD, "Cannot do DiskT@2.\n");
903 p = hasdrvopt(driveropts, "singlesession");
904 if (p != NULL && (dp->cdr_flags & CDR_SINGLESESS) != 0) {
906 dp->cdr_dstat->ds_cdrflags |= RF_SINGLESESS;
907 } else if (*p == '0') {
908 dp->cdr_dstat->ds_cdrflags &= ~RF_SINGLESESS;
911 p = hasdrvopt(driveropts, "hidecdr");
912 if (p != NULL && (dp->cdr_flags & CDR_HIDE_CDR) != 0) {
914 dp->cdr_dstat->ds_cdrflags |= RF_HIDE_CDR;
915 } else if (*p == '0') {
916 dp->cdr_dstat->ds_cdrflags &= ~RF_HIDE_CDR;
919 p = hasdrvopt(driveropts, "speedread");
920 if (p != NULL && (dp->cdr_flags & CDR_SPEEDREAD) != 0) {
922 dp->cdr_dstat->ds_cdrflags |= RF_SPEEDREAD;
923 } else if (*p == '0') {
924 dp->cdr_dstat->ds_cdrflags &= ~RF_SPEEDREAD;
929 if ((ret = get_supported_cdrw_media_types(usalp)) < 0) {
930 dp->cdr_cdrw_support = CDR_CDRW_ALL;
933 dp->cdr_cdrw_support = ret;
935 printf("Supported CD-RW media types: %02X\n", dp->cdr_cdrw_support);
941 attach_mdvd(SCSI *usalp, cdr_t *dp)
943 struct cd_mode_page_2A *mp;
946 allow_atapi(usalp, TRUE);/* Try to switch to 10 byte mode cmds */
949 mp = mmc_cap(usalp, NULL);/* Get MMC capabilities in allocated mp */
952 return (-1); /* Pre SCSI-3/mmc drive */
954 dp->cdr_cdcap = mp; /* Store MMC cap pointer */
956 dp->cdr_dstat->ds_dr_max_rspeed = a_to_u_2_byte(mp->max_read_speed)/1385;
957 if (dp->cdr_dstat->ds_dr_max_rspeed == 0)
958 dp->cdr_dstat->ds_dr_max_rspeed = 1385;
959 dp->cdr_dstat->ds_dr_cur_rspeed = a_to_u_2_byte(mp->cur_read_speed)/1385;
960 if (dp->cdr_dstat->ds_dr_cur_rspeed == 0)
961 dp->cdr_dstat->ds_dr_cur_rspeed = 1385;
963 dp->cdr_dstat->ds_dr_max_wspeed = a_to_u_2_byte(mp->max_write_speed)/1385;
965 dp->cdr_dstat->ds_dr_cur_wspeed = a_to_u_2_byte(mp->v3_cur_write_speed)/1385;
967 dp->cdr_dstat->ds_dr_cur_wspeed = a_to_u_2_byte(mp->cur_write_speed)/1385;
969 if (dp->cdr_speedmax > dp->cdr_dstat->ds_dr_max_wspeed)
970 dp->cdr_speedmax = dp->cdr_dstat->ds_dr_max_wspeed;
972 if (dp->cdr_speeddef > dp->cdr_speedmax)
973 dp->cdr_speeddef = dp->cdr_speedmax;
976 if (mp->loading_type == LT_TRAY)
977 dp->cdr_flags |= CDR_TRAYLOAD;
978 else if (mp->loading_type == LT_CADDY)
979 dp->cdr_flags |= CDR_CADDYLOAD;
982 dp->cdr_flags |= CDR_BURNFREE;
984 check_writemodes_mdvd(usalp, dp);
986 if (driveropts != NULL) {
987 if (strcmp(driveropts, "help") == 0) {
996 check_writemodes_mmc(SCSI *usalp, cdr_t *dp)
1000 struct cd_mode_page_05 *mp;
1003 printf("Checking possible write modes: ");
1006 * Reset mp->test_write (-dummy) here.
1008 deflt_writemodes_mmc(usalp, TRUE);
1010 fillbytes((caddr_t)mode, sizeof (mode), '\0');
1013 if (!get_mode_params(usalp, 0x05, "CD write parameter",
1014 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) {
1023 mp = (struct cd_mode_page_05 *)
1024 (mode + sizeof (struct scsi_mode_header) +
1025 ((struct scsi_mode_header *)mode)->blockdesc_len);
1027 usal_prbytes("CD write parameter:", (Uchar *)mode, len);
1031 * mp->test_write has already been reset in deflt_writemodes_mmc()
1032 * Do not reset mp->test_write (-dummy) here. It should be set
1033 * only at one place and only one time.
1036 mp->write_type = WT_TAO;
1037 mp->track_mode = TM_DATA;
1038 mp->dbtype = DB_ROM_MODE1;
1040 if (set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) {
1041 dp->cdr_flags |= CDR_TAO;
1045 dp->cdr_flags &= ~CDR_TAO;
1047 mp->write_type = WT_PACKET;
1048 mp->track_mode |= TM_INCREMENTAL;
1049 /* mp->fp = (trackp->pktsize > 0) ? 1 : 0;*/
1050 /* i_to_4_byte(mp->packet_size, trackp->pktsize);*/
1052 i_to_4_byte(mp->packet_size, 0);
1054 if (set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) {
1055 dp->cdr_flags |= CDR_PACKET;
1059 dp->cdr_flags &= ~CDR_PACKET;
1061 i_to_4_byte(mp->packet_size, 0);
1062 mp->track_mode = TM_DATA;
1063 mp->write_type = WT_SAO;
1065 if (set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) {
1066 dp->cdr_flags |= CDR_SAO;
1070 dp->cdr_flags &= ~CDR_SAO;
1072 if (dp->cdr_flags & CDR_SAO) {
1073 mp->dbtype = DB_RAW_PQ;
1076 if (set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) {
1077 dp->cdr_flags |= CDR_SRAW16;
1083 mp->dbtype = DB_RAW_PW;
1085 if (set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) {
1086 dp->cdr_flags |= CDR_SRAW96P;
1088 printf("SAO/R96P ");
1091 mp->dbtype = DB_RAW_PW_R;
1093 if (set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) {
1094 dp->cdr_flags |= CDR_SRAW96R;
1096 printf("SAO/R96R ");
1100 mp->write_type = WT_RAW;
1101 mp->dbtype = DB_RAW_PQ;
1103 if (set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) {
1104 dp->cdr_flags |= CDR_RAW;
1105 dp->cdr_flags |= CDR_RAW16;
1110 mp->dbtype = DB_RAW_PW;
1112 if (set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) {
1113 dp->cdr_flags |= CDR_RAW;
1114 dp->cdr_flags |= CDR_RAW96P;
1116 printf("RAW/R96P ");
1119 mp->dbtype = DB_RAW_PW_R;
1121 if (set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) {
1122 dp->cdr_flags |= CDR_RAW;
1123 dp->cdr_flags |= CDR_RAW96R;
1125 printf("RAW/R96R ");
1132 * Reset mp->test_write (-dummy) here.
1134 deflt_writemodes_mmc(usalp, TRUE);
1141 check_writemodes_mdvd(SCSI *usalp, cdr_t *dp)
1145 struct cd_mode_page_05 *mp;
1148 printf("Checking possible write modes: ");
1150 deflt_writemodes_mdvd(usalp, FALSE);
1152 fillbytes((caddr_t)mode, sizeof(mode), '\0');
1155 if (!get_mode_params(usalp, 0x05, "DVD write parameter",
1156 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) {
1165 mp = (struct cd_mode_page_05 *)
1166 (mode + sizeof(struct scsi_mode_header) +
1167 ((struct scsi_mode_header *)mode)->blockdesc_len);
1171 /*We only check for PACKET and SAO since these are the only supported modes for DVD */
1172 /*XXX these checks are irrelevant because they are not medium sensitive. ie the device returns
1173 error only when it does not support a given mode for ALL mediums. It should check using
1174 GET CONFIGURATION command.*/
1176 mp->write_type = WT_PACKET;
1178 i_to_4_byte(mp->packet_size, 0);
1180 if (set_mode_params(usalp, "DVD write parameter", mode, len, 0, -1)) {
1181 dp->cdr_flags |= CDR_PACKET;
1185 dp->cdr_flags &= ~CDR_PACKET;
1187 i_to_4_byte(mp->packet_size, 0);
1188 mp->track_mode = TM_DATA;
1191 mp->write_type = WT_SAO;
1193 if (set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) {
1194 dp->cdr_flags |= CDR_SAO;
1198 dp->cdr_flags &= ~CDR_SAO;
1204 deflt_writemodes_mdvd(usalp, TRUE);
1210 deflt_writemodes_mmc(SCSI *usalp, BOOL reset_dummy)
1214 struct cd_mode_page_05 *mp;
1216 fillbytes((caddr_t)mode, sizeof (mode), '\0');
1219 if (!get_mode_params(usalp, 0x05, "CD write parameter",
1220 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) {
1229 mp = (struct cd_mode_page_05 *)
1230 (mode + sizeof (struct scsi_mode_header) +
1231 ((struct scsi_mode_header *)mode)->blockdesc_len);
1233 usal_prbytes("CD write parameter:", (Uchar *)mode, len);
1234 fprintf(stderr, "Audio pause len: %d\n", a_to_2_byte(mp->audio_pause_len));
1238 * This is the only place where we reset mp->test_write (-dummy)
1244 * Set default values:
1245 * Write type = 01 (track at once)
1246 * Track mode = 04 (CD-ROM)
1247 * Data block type = 08 (CD-ROM)
1248 * Session format = 00 (CD-ROM)
1250 * XXX Note: the same code appears in check_writemodes_mmc() and
1251 * XXX in speed_select_mmc().
1253 mp->write_type = WT_TAO;
1254 mp->track_mode = TM_DATA;
1255 mp->dbtype = DB_ROM_MODE1;
1256 mp->session_format = SES_DA_ROM; /* Matsushita has illegal def. value */
1258 i_to_2_byte(mp->audio_pause_len, 150); /* LG has illegal def. value */
1261 usal_prbytes("CD write parameter:", (Uchar *)mode, len);
1263 if (!set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) {
1265 mp->write_type = WT_SAO;
1269 mp->multi_session = MS_NONE;
1270 mp->host_appl_code = 0;
1272 if (!set_mode_params(usalp, "CD write parameter", mode, len, 0, -1)) {
1282 deflt_writemodes_mdvd(SCSI *usalp, BOOL reset_dummy)
1286 struct cd_mode_page_05 *mp;
1288 fillbytes((caddr_t)mode, sizeof(mode), '\0');
1291 if (!get_mode_params(usalp, 0x05, "DVD write parameter",
1292 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) {
1301 mp = (struct cd_mode_page_05 *)
1302 (mode + sizeof(struct scsi_mode_header) +
1303 ((struct scsi_mode_header *)mode)->blockdesc_len);
1307 * This is the only place where we reset mp->test_write (-dummy) for DVD
1313 * Set default values:
1314 * Write type = 02 (session at once)
1316 * XXX Note: the same code appears in check_writemodes_mmc() and
1317 * XXX in speed_select_mmc().
1319 mp->write_type = WT_SAO;
1320 mp->track_mode = TM_DATA;
1321 mp->dbtype = DB_ROM_MODE1;
1322 mp->session_format = SES_DA_ROM;
1325 if (set_mode_params(usalp, "DVD write parameter", mode, len, 0, -1) < 0) {
1334 static void print_di(struct disk_info *dip);
1335 static void atip_printspeed(char *fmt, int speedindex, char speedtab[]);
1336 static void print_atip(SCSI *usalp, struct atipinfo *atp);
1337 #endif /* PRINT_ATIP */
1340 get_diskinfo(SCSI *usalp, struct disk_info *dip)
1345 fillbytes((caddr_t)dip, sizeof (*dip), '\0');
1348 * Used to be 2 instead of 4 (now). But some Y2k ATAPI drives as used
1349 * by IOMEGA create a DMA overrun if we try to transfer only 2 bytes.
1351 /* if (read_disk_info(usalp, (caddr_t)dip, 2) < 0)*/
1352 if (read_disk_info(usalp, (caddr_t)dip, 4) < 0)
1354 len = a_to_u_2_byte(dip->data_len);
1356 ret = read_disk_info(usalp, (caddr_t)dip, len);
1359 usal_prbytes("Disk info:", (Uchar *)dip,
1360 len-usal_getresid(usalp));
1366 di_to_dstat(struct disk_info *dip, dstat_t *dsp)
1368 dsp->ds_diskid = a_to_u_4_byte(dip->disk_id);
1370 dsp->ds_flags |= DSF_DID_V;
1371 dsp->ds_disktype = dip->disk_type;
1372 dsp->ds_diskstat = dip->disk_status;
1373 dsp->ds_sessstat = dip->sess_status;
1375 dsp->ds_flags |= DSF_ERA;
1377 dsp->ds_trfirst = dip->first_track;
1378 dsp->ds_trlast = dip->last_track_ls;
1379 dsp->ds_trfirst_ls = dip->first_track_ls;
1381 dsp->ds_maxblocks = msf_to_lba(dip->last_lead_out[1],
1382 dip->last_lead_out[2],
1383 dip->last_lead_out[3], TRUE);
1385 * Check for 0xFF:0xFF/0xFF which is an indicator for a complete disk
1387 if (dsp->ds_maxblocks == 1166730)
1388 dsp->ds_maxblocks = -1L;
1390 dsp->ds_first_leadin = msf_to_lba(dip->last_lead_in[1],
1391 dip->last_lead_in[2],
1392 dip->last_lead_in[3], FALSE);
1393 if (dsp->ds_first_leadin > 0)
1394 dsp->ds_first_leadin = 0;
1396 if (dsp->ds_last_leadout == 0 && dsp->ds_maxblocks >= 0)
1397 dsp->ds_last_leadout = dsp->ds_maxblocks;
1398 dsp->ds_trfirst=dip->first_track;
1399 dsp->ds_trlast=dip->last_track_ls;
1400 dsp->ds_trfirst_ls=dip->first_track_ls;
1404 get_atip(SCSI *usalp, struct atipinfo *atp)
1409 fillbytes((caddr_t)atp, sizeof (*atp), '\0');
1412 * Used to be 2 instead of sizeof (struct tocheader), but all
1413 * other places in the code use sizeof (struct tocheader) too and
1414 * some Y2k ATAPI drives as used by IOMEGA create a DMA overrun if we
1415 * try to transfer only 2 bytes.
1417 if (read_toc(usalp, (caddr_t)atp, 0, sizeof (struct tocheader), 0, FMT_ATIP) < 0)
1419 len = a_to_u_2_byte(atp->hd.len);
1421 ret = read_toc(usalp, (caddr_t)atp, 0, len, 0, FMT_ATIP);
1424 usal_prbytes("ATIP info:", (Uchar *)atp,
1425 len-usal_getresid(usalp));
1428 * Yamaha sometimes returns zeroed ATIP info for disks without ATIP
1430 if (atp->desc.lead_in[1] == 0 &&
1431 atp->desc.lead_in[2] == 0 &&
1432 atp->desc.lead_in[3] == 0 &&
1433 atp->desc.lead_out[1] == 0 &&
1434 atp->desc.lead_out[2] == 0 &&
1435 atp->desc.lead_out[3] == 0)
1438 if (atp->desc.lead_in[1] >= 0x90 && debug) {
1440 * Only makes sense with buggy Ricoh firmware.
1442 errmsgno(EX_BAD, "Converting ATIP from BCD\n");
1443 atp->desc.lead_in[1] = from_bcd(atp->desc.lead_in[1]);
1444 atp->desc.lead_in[2] = from_bcd(atp->desc.lead_in[2]);
1445 atp->desc.lead_in[3] = from_bcd(atp->desc.lead_in[3]);
1447 atp->desc.lead_out[1] = from_bcd(atp->desc.lead_out[1]);
1448 atp->desc.lead_out[2] = from_bcd(atp->desc.lead_out[2]);
1449 atp->desc.lead_out[3] = from_bcd(atp->desc.lead_out[3]);
1458 get_pma(SCSI *usalp)
1464 fillbytes((caddr_t)atp, sizeof (*atp), '\0');
1467 * Used to be 2 instead of sizeof (struct tocheader), but all
1468 * other places in the code use sizeof (struct tocheader) too and
1469 * some Y2k ATAPI drives as used by IOMEGA create a DMA overrun if we
1470 * try to transfer only 2 bytes.
1472 /* if (read_toc(usalp, (caddr_t)atp, 0, 2, 1, FMT_PMA) < 0)*/
1473 /* if (read_toc(usalp, (caddr_t)atp, 0, 2, 0, FMT_PMA) < 0)*/
1474 if (read_toc(usalp, (caddr_t)atp, 0, sizeof (struct tocheader), 0, FMT_PMA) < 0)
1476 /* len = a_to_u_2_byte(atp->hd.len);*/
1477 len = a_to_u_2_byte(atp);
1479 /* ret = read_toc(usalp, (caddr_t)atp, 0, len, 1, FMT_PMA);*/
1480 ret = read_toc(usalp, (caddr_t)atp, 0, len, 0, FMT_PMA);
1483 usal_prbytes("PMA:", (Uchar *)atp,
1484 len-usal_getresid(usalp));
1486 ret = read_toc(usalp, (caddr_t)atp, 0, len, 1, FMT_PMA);
1489 usal_prbytes("PMA:", (Uchar *)atp,
1490 len-usal_getresid(usalp));
1495 #endif /* PRINT_ATIP */
1498 init_mmc(SCSI *usalp, cdr_t *dp)
1500 return (speed_select_mmc(usalp, dp, NULL));
1504 getdisktype_mdvd(SCSI *usalp, cdr_t *dp)
1507 dstat_t *dsp = dp->cdr_dstat;
1509 struct track_info track_info;
1511 printf("HINT: use dvd+rw-mediainfo from dvd+rw-tools for information extraction.\n");
1512 /* if(getdisktype_mmc(usalp, dp)<0)
1516 /* read rzone info to get the space left on disk */
1517 /*ds_trlast is the last rzone on disk, can be invisible */
1518 if(read_rzone_info(usalp, (caddr_t)&track_info, sizeof(track_info))>=0)
1519 dsp->ds_maxblocks=a_to_u_4_byte(track_info.free_blocks)+a_to_4_byte(track_info.next_writable_addr);
1521 dsp->ds_disktype&= ~DT_CD;
1522 dsp->ds_disktype|= DT_DVD;
1529 getdisktype_mmc(SCSI *usalp, cdr_t *dp)
1532 dstat_t *dsp = dp->cdr_dstat;
1533 struct disk_info *dip;
1536 BOOL did_atip = FALSE;
1537 BOOL did_dummy = FALSE;
1540 msf.msf_min = msf.msf_sec = msf.msf_frame = 0;
1543 * It seems that there are drives that do not support to
1544 * read ATIP (e.g. HP 7100)
1545 * Also if a NON CD-R media is inserted, this will never work.
1546 * For this reason, make a failure non-fatal.
1549 if (get_atip(usalp, (struct atipinfo *)mode) >= 0) {
1550 struct atipinfo *atp = (struct atipinfo *)mode;
1552 msf.msf_min = mode[8];
1553 msf.msf_sec = mode[9];
1554 msf.msf_frame = mode[10];
1555 if (atp->desc.erasable) {
1556 dsp->ds_flags |= DSF_ERA;
1557 if (atp->desc.sub_type == 1)
1558 dsp->ds_flags |= DSF_HIGHSP_ERA;
1559 else if (atp->desc.sub_type == 2)
1560 dsp->ds_flags |= DSF_ULTRASP_ERA;
1561 else if (atp->desc.sub_type == 3)
1562 dsp->ds_flags |= DSF_ULTRASP_ERA | DSF_ULTRASPP_ERA;
1564 if (atp->desc.a1_v) {
1565 if (atp->desc.clv_low != 0)
1566 dsp->ds_at_min_speed = clv_to_speed[atp->desc.clv_low];
1567 if (atp->desc.clv_high != 0)
1568 dsp->ds_at_max_speed = clv_to_speed[atp->desc.clv_high];
1570 if (atp->desc.erasable && atp->desc.sub_type == 1) {
1571 if (atp->desc.clv_high != 0)
1572 dsp->ds_at_max_speed = hs_clv_to_speed[atp->desc.clv_high];
1575 if (atp->desc.a2_v && atp->desc.erasable && (atp->desc.sub_type == 2 || atp->desc.sub_type == 3)) {
1579 vlow = (atp->desc.a2[0] >> 4) & 0x07;
1580 vhigh = atp->desc.a2[0] & 0x0F;
1582 dsp->ds_at_min_speed = us_clv_to_speed[vlow];
1584 dsp->ds_at_max_speed = us_clv_to_speed[vhigh];
1591 if ((dp->cdr_dstat->ds_cdrflags & RF_PRATIP) != 0 && did_atip) {
1592 print_atip(usalp, (struct atipinfo *)mode);
1593 pr_manufacturer(&msf,
1594 ((struct atipinfo *)mode)->desc.erasable,
1595 ((struct atipinfo *)mode)->desc.uru);
1599 dip = (struct disk_info *)buf;
1600 if (get_diskinfo(usalp, dip) < 0)
1604 * Check for non writable disk first.
1607 /* DVD+RW does not need to be blanked */
1608 rplus = dsp->ds_cdrflags;
1609 if (dp->profile == 0x1A) rplus = RF_BLANK;
1611 if (dip->disk_status == DS_COMPLETE &&
1612 (rplus & dsp->ds_cdrflags & (RF_WRITE|RF_BLANK)) == RF_WRITE) {
1614 int xspeed = 0xFFFF;
1615 int oflags = dp->cdr_cmdflags;
1618 * Try to clear the dummy bit to reset the virtual
1619 * drive status. Not all drives support it even though
1620 * it is mentioned in the MMC standard.
1623 printf("Trying to clear drive status.\n");
1625 dp->cdr_cmdflags &= ~F_DUMMY;
1626 speed_select_mmc(usalp, dp, &xspeed);
1627 dp->cdr_cmdflags = oflags;
1632 * Trying to clear drive status did not work...
1634 reload_media(usalp, dp);
1636 if (get_diskinfo(usalp, dip) < 0)
1638 di_to_dstat(dip, dsp);
1639 if (!did_atip && dsp->ds_first_leadin < 0)
1640 lba_to_msf(dsp->ds_first_leadin, &msf);
1642 if ((dp->cdr_dstat->ds_cdrflags & RF_PRATIP) != 0 && !did_atip) {
1643 print_min_atip(dsp->ds_first_leadin, dsp->ds_last_leadout);
1644 if (dsp->ds_first_leadin < 0)
1645 pr_manufacturer(&msf,
1649 dsp->ds_maxrblocks = disk_rcap(&msf, dsp->ds_maxblocks,
1656 if (get_atip(usalp, (struct atipinfo *)mode) < 0)
1659 * Get pma gibt Ärger mit CW-7502
1660 * Wenn Die Disk leer ist, dann stuerzt alles ab.
1661 * Firmware 4.02 kann nicht get_pma
1663 if (dip->disk_status != DS_EMPTY) {
1666 printf("ATIP lead in: %ld (%02d:%02d/%02d)\n",
1667 msf_to_lba(mode[8], mode[9], mode[10], FALSE),
1668 mode[8], mode[9], mode[10]);
1669 printf("ATIP lead out: %ld (%02d:%02d/%02d)\n",
1670 msf_to_lba(mode[12], mode[13], mode[14], TRUE),
1671 mode[12], mode[13], mode[14]);
1673 print_atip(usalp, (struct atipinfo *)mode);
1675 #endif /* PRINT_ATIP */
1676 return (drive_getdisktype(usalp, dp));
1681 #define DOES(what, flag) printf(" Does %s%s\n", flag?"":"not ", what);
1682 #define IS(what, flag) printf(" Is %s%s\n", flag?"":"not ", what);
1683 #define VAL(what, val) printf(" %s: %d\n", what, val[0]*256 + val[1]);
1684 #define SVAL(what, val) printf(" %s: %s\n", what, val);
1687 print_di(struct disk_info *dip)
1689 static char *ds_name[] = { "empty", "incomplete/appendable", "complete", "illegal" };
1690 static char *ss_name[] = { "empty", "incomplete/appendable", "illegal", "complete", };
1692 IS("erasable", dip->erasable);
1693 printf("disk status: %s\n", ds_name[dip->disk_status]);
1694 printf("session status: %s\n", ss_name[dip->sess_status]);
1695 printf("first track: %d number of sessions: %d first track in last sess: %d last track in last sess: %d\n",
1698 dip->first_track_ls,
1699 dip->last_track_ls);
1700 IS("unrestricted", dip->uru);
1701 printf("Disk type: ");
1702 switch (dip->disk_type) {
1704 case SES_DA_ROM: printf("CD-DA or CD-ROM"); break;
1705 case SES_CDI: printf("CDI"); break;
1706 case SES_XA: printf("CD-ROM XA"); break;
1707 case SES_UNDEF: printf("undefined"); break;
1708 default: printf("reserved"); break;
1712 printf("Disk id: 0x%lX\n", a_to_u_4_byte(dip->disk_id));
1714 printf("last start of lead in: %ld\n",
1715 msf_to_lba(dip->last_lead_in[1],
1716 dip->last_lead_in[2],
1717 dip->last_lead_in[3], FALSE));
1718 printf("last start of lead out: %ld\n",
1719 msf_to_lba(dip->last_lead_out[1],
1720 dip->last_lead_out[2],
1721 dip->last_lead_out[3], TRUE));
1724 printf("Disk bar code: 0x%lX%lX\n",
1725 a_to_u_4_byte(dip->disk_barcode),
1726 a_to_u_4_byte(&dip->disk_barcode[4]));
1728 if (dip->num_opc_entries > 0) {
1729 printf("OPC table:\n");
1733 char *cdr_subtypes[] = {
1734 "Normal Rewritable (CLV) media",
1735 "High speed Rewritable (CAV) media",
1736 "Medium Type A, low Beta category (A-)",
1737 "Medium Type A, high Beta category (A+)",
1738 "Medium Type B, low Beta category (B-)",
1739 "Medium Type B, high Beta category (B+)",
1740 "Medium Type C, low Beta category (C-)",
1741 "Medium Type C, high Beta category (C+)",
1744 char *cdrw_subtypes[] = {
1745 "Normal Rewritable (CLV) media",
1746 "High speed Rewritable (CAV) media",
1747 "Ultra High speed Rewritable media",
1748 "Ultra High speed+ Rewritable media",
1749 "Medium Type B, low Beta category (B-)",
1750 "Medium Type B, high Beta category (B+)",
1751 "Medium Type C, low Beta category (C-)",
1752 "Medium Type C, high Beta category (C+)",
1756 atip_printspeed(char *fmt, int speedindex, char speedtab[])
1759 if (speedtab[speedindex] == 0) {
1760 printf(" %2d (reserved val %2d)",
1761 speedtab[speedindex], speedindex);
1763 printf(" %2d", speedtab[speedindex]);
1768 print_atip(SCSI *usalp, struct atipinfo *atp)
1771 char *speedvtab = clv_to_speed;
1774 usal_prbytes("ATIP info: ", (Uchar *)atp, sizeof (*atp));
1776 printf("ATIP info from disk:\n");
1777 printf(" Indicated writing power: %d\n", atp->desc.ind_wr_power);
1778 if (atp->desc.erasable || atp->desc.ref_speed)
1779 printf(" Reference speed: %d\n", clv_to_speed[atp->desc.ref_speed]);
1780 IS("unrestricted", atp->desc.uru);
1781 /* printf(" Disk application code: %d\n", atp->desc.res5_05);*/
1782 IS("erasable", atp->desc.erasable);
1783 if (atp->desc.erasable)
1784 sub_type = cdrw_subtypes[atp->desc.sub_type];
1786 sub_type = cdr_subtypes[atp->desc.sub_type];
1787 if (atp->desc.sub_type)
1788 printf(" Disk sub type: %s (%d)\n", sub_type, atp->desc.sub_type);
1789 printf(" ATIP start of lead in: %ld (%02d:%02d/%02d)\n",
1790 msf_to_lba(atp->desc.lead_in[1],
1791 atp->desc.lead_in[2],
1792 atp->desc.lead_in[3], FALSE),
1793 atp->desc.lead_in[1],
1794 atp->desc.lead_in[2],
1795 atp->desc.lead_in[3]);
1796 printf(" ATIP start of lead out: %ld (%02d:%02d/%02d)\n",
1797 msf_to_lba(atp->desc.lead_out[1],
1798 atp->desc.lead_out[2],
1799 atp->desc.lead_out[3], TRUE),
1800 atp->desc.lead_out[1],
1801 atp->desc.lead_out[2],
1802 atp->desc.lead_out[3]);
1803 if (atp->desc.a1_v) {
1804 if (atp->desc.erasable && atp->desc.sub_type == 1) {
1805 speedvtab = hs_clv_to_speed;
1807 if (atp->desc.a2_v && (atp->desc.sub_type == 2 || atp->desc.sub_type == 3)) {
1808 speedvtab = us_clv_to_speed;
1810 if (atp->desc.clv_low != 0 || atp->desc.clv_high != 0) {
1811 atip_printspeed(" 1T speed low",
1812 atp->desc.clv_low, speedvtab);
1813 atip_printspeed(" 1T speed high",
1814 atp->desc.clv_high, speedvtab);
1818 if (atp->desc.a2_v) {
1822 vlow = (atp->desc.a2[0] >> 4) & 0x07;
1823 vhigh = atp->desc.a2[0] & 0x0F;
1825 if (vlow != 0 || vhigh != 0) {
1826 atip_printspeed(" 2T speed low",
1828 atip_printspeed(" 2T speed high",
1833 if (atp->desc.a1_v) {
1834 printf(" power mult factor: %d %d\n", atp->desc.power_mult, atp->desc.tgt_y_pow);
1835 if (atp->desc.erasable)
1836 printf(" recommended erase/write power: %d\n", atp->desc.rerase_pwr_ratio);
1838 if (atp->desc.a1_v) {
1839 printf(" A1 values: %02X %02X %02X\n",
1840 (&atp->desc.res15)[1],
1841 (&atp->desc.res15)[2],
1842 (&atp->desc.res15)[3]);
1844 if (atp->desc.a2_v) {
1845 printf(" A2 values: %02X %02X %02X\n",
1850 if (atp->desc.a3_v) {
1851 printf(" A3 values: %02X %02X %02X\n",
1857 #endif /* PRINT_ATIP */
1860 speed_select_mmc(SCSI *usalp, cdr_t *dp, int *speedp)
1865 struct cd_mode_page_05 *mp;
1866 struct ricoh_mode_page_30 *rp = NULL;
1868 BOOL forcespeed = FALSE;
1869 BOOL dummy = (dp->cdr_cmdflags & F_DUMMY) != 0;
1875 * Do not reset mp->test_write (-dummy) here.
1877 deflt_writemodes_mmc(usalp, FALSE);
1879 fillbytes((caddr_t)mode, sizeof (mode), '\0');
1881 if (!get_mode_params(usalp, 0x05, "CD write parameter",
1882 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len))
1887 mp = (struct cd_mode_page_05 *)
1888 (mode + sizeof (struct scsi_mode_header) +
1889 ((struct scsi_mode_header *)mode)->blockdesc_len);
1891 usal_prbytes("CD write parameter:", (Uchar *)mode, len);
1896 /* but it does not work on DVD+RW and -RAM, also bail out on other
1897 * types that have not been tested yet */
1898 int profile=get_curprofile(usalp);
1907 "Dummy mode not possible with %s.\n",
1908 mmc_obtain_profile_name(profile) );
1917 usal_prbytes("CD write parameter:", (Uchar *)mode, len);
1919 if (!set_mode_params(usalp, "CD write parameter", mode, len, 0, -1))
1923 * Neither set nor get speed.
1929 rp = get_justlink_ricoh(usalp, moder);
1930 if (mmc_isyamaha(usalp)) {
1932 } else if (mmc_isplextor(usalp) && (dp->cdr_flags & CDR_FORCESPEED) != 0) {
1935 pwr = check_powerrec_plextor(usalp);
1937 forcespeed = (pwr == 0);
1938 } else if ((dp->cdr_flags & CDR_FORCESPEED) != 0) {
1939 forcespeed = rp && rp->AWSCD != 0;
1942 if (lverbose && (dp->cdr_flags & CDR_FORCESPEED) != 0)
1943 printf("Forcespeed is %s.\n", forcespeed?"ON":"OFF");
1945 if (!forcespeed && (dp->cdr_dstat->ds_cdrflags & RF_FORCESPEED) != 0) {
1946 printf("Turning forcespeed on\n");
1949 if (forcespeed && (dp->cdr_dstat->ds_cdrflags & RF_FORCESPEED) == 0) {
1950 printf("Turning forcespeed off\n");
1953 if (mmc_isplextor(usalp) && (dp->cdr_flags & CDR_FORCESPEED) != 0) {
1954 powerrec_plextor(usalp, !forcespeed);
1956 if (!mmc_isyamaha(usalp) && (dp->cdr_flags & CDR_FORCESPEED) != 0) {
1959 rp->AWSCD = forcespeed?1:0;
1960 set_mode_params(usalp, "Ricoh Vendor Page", moder, moder[0]+1, 0, -1);
1961 rp = get_justlink_ricoh(usalp, moder);
1966 * 44100 * 2 * 2 = 176400 bytes/s
1968 * The right formula would be:
1969 * tmp = (((long)curspeed) * 1764) / 10;
1971 * But the standard is rounding the wrong way.
1972 * Furtunately rounding down is guaranteed.
1977 if (mmc_isyamaha(usalp) && forcespeed) {
1978 if (force_speed_yamaha(usalp, -1, val) < 0)
1980 } else if (mmc_set_speed(usalp, -1, val, ROTCTL_CLV) < 0) {
1984 if (scsi_get_speed(usalp, 0, &val) >= 0) {
1986 fprintf(stderr, "Speed set to %d KB/s\n", val);
1987 curspeed = val / 176;
1995 * Some drives do not round up when writespeed is e.g. 1 and
1996 * the minimum write speed of the drive is higher. Try to increment
1997 * the write speed unti it gets accepted by the drive.
2000 mmc_set_speed(SCSI *usalp, int readspeed, int writespeed, int rotctl)
2008 if (scsi_get_speed(usalp, &rs, &ws) >= 0) {
2014 if (writespeed < 0 || writespeed > 0xFFFF)
2018 while (writespeed <= 0xFFFF) {
2019 ret = scsi_set_speed(usalp, readspeed, writespeed, rotctl);
2022 c = usal_sense_code(usalp);
2023 k = usal_sense_key(usalp);
2025 * Abort quickly if it does not make sense to repeat.
2026 * 0x24 == Invalid field in cdb
2027 * 0x24 means illegal speed.
2029 if ((k != SC_ILLEGAL_REQUEST) || (c != 0x24)) {
2030 if (usalp->silent <= 1)
2031 usal_printerr(usalp);
2037 if (ret < 0 && usalp->silent <= 1)
2038 usal_printerr(usalp);
2045 speed_select_mdvd(SCSI *usalp, cdr_t *dp, int *speedp)
2049 int write_speed = *speedp * 1385;
2051 /* For the moment we just divide the CD speed by 7*/
2054 (*speedp)=(*speedp)*8;
2056 memset(perf_desc, 0, sizeof(perf_desc));
2058 /* Write Rotation Control = ROTCTL_CLV
2059 * | Restore Logical Unit Defaults = 0
2061 * | Random Access = 0)
2063 perf_desc[0]= ROTCTL_CLV << 3 | 0 << 2 | 0 << 1 | 0;
2064 /* Start LBA to 0 */
2069 /* End LBA set to 0 (setting to 0xffffffff failed on my LG burner
2075 /* Read Speed = 0xFFFF */
2078 perf_desc[14] = 0xFF;
2079 perf_desc[15] = 0xFF;
2080 /* Read Time = 1s */
2081 perf_desc[18] = 1000 >> 8;
2082 perf_desc[19] = 1000 & 0xFF;
2084 perf_desc[20] = write_speed >> 24;
2085 perf_desc[21] = write_speed >> 16 & 0xFF;
2086 perf_desc[22] = write_speed >> 8 & 0xFF;
2087 perf_desc[23] = write_speed & 0xFF;
2088 /* Write Time = 1s */
2089 perf_desc[26] = 1000 >> 8;
2090 perf_desc[27] = 1000 & 0xFF;
2092 /* retcode = scsi_set_streaming(usalp, NULL, 0); */
2093 retcode = scsi_set_streaming(usalp, perf_desc, sizeof(perf_desc));
2094 if (retcode == -1) return retcode;
2095 retcode = speed_select_mmc(usalp, dp, speedp);
2097 (*speedp)=(*speedp)/7;
2102 next_wr_addr_mmc(SCSI *usalp, track_t *trackp, long *ap)
2104 struct track_info track_info;
2110 * Reading info for current track may require doing the read_track_info
2111 * with either the track number (if the track is currently being written)
2112 * or with 0xFF (if the track hasn't been started yet and is invisible
2115 if (trackp != 0 && trackp->track > 0 && is_packet(trackp)) {
2117 result = read_track_info(usalp, (caddr_t)&track_info, TI_TYPE_TRACK,
2119 sizeof (track_info));
2124 if (read_track_info(usalp, (caddr_t)&track_info, TI_TYPE_TRACK, 0xFF,
2125 sizeof (track_info)) < 0) {
2126 errmsgno(EX_BAD, "Cannot get next writable address for 'invisible' track.\n");
2127 errmsgno(EX_BAD, "This means that we are checking recorded media.\n");
2128 errmsgno(EX_BAD, "This media cannot be written in streaming mode anymore.\n");
2129 errmsgno(EX_BAD, "If you like to write to 'preformatted' RW media, try to blank the media first.\n");
2134 usal_prbytes("track info:", (Uchar *)&track_info,
2135 sizeof (track_info)-usal_getresid(usalp));
2136 next_addr = a_to_4_byte(track_info.next_writable_addr);
2143 write_leadin_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp)
2148 /* if (flags & F_SAO) {*/
2149 if (wm_base(dp->cdr_dstat->ds_wrmode) == WM_SAO) {
2150 if (debug || lverbose) {
2151 printf("Sending CUE sheet...\n");
2154 if ((*dp->cdr_send_cue)(usalp, dp, trackp) < 0) {
2155 errmsgno(EX_BAD, "Cannot send CUE sheet.\n");
2159 (*dp->cdr_next_wr_address)(usalp, &trackp[0], &startsec);
2160 if (trackp[0].flags & TI_TEXT) {
2161 startsec = dp->cdr_dstat->ds_first_leadin;
2162 printf("SAO startsec: %ld\n", startsec);
2163 } else if (startsec <= 0 && startsec != -150) {
2165 fprintf(stderr, "WARNING: Drive returns wrong startsec (%ld) using -150\n",
2170 printf("SAO startsec: %ld\n", startsec);
2172 if (trackp[0].flags & TI_TEXT) {
2174 errmsgno(EX_BAD, "CD-Text must be in first session.\n");
2177 if (debug || lverbose)
2178 printf("Writing lead-in...\n");
2179 if (write_cdtext(usalp, dp, startsec) < 0)
2182 dp->cdr_dstat->ds_cdrflags |= RF_LEADIN;
2183 } else for (i = 1; i <= trackp->tracks; i++) {
2184 trackp[i].trackstart += startsec +150;
2187 if (debug || lverbose)
2188 printf("Writing lead-in...\n");
2190 pad_track(usalp, dp, &trackp[1], -150, (Llong)0,
2194 /* if (flags & F_RAW) {*/
2195 if (wm_base(dp->cdr_dstat->ds_wrmode) == WM_RAW) {
2197 * In RAW write mode, we now write the lead in (TOC).
2199 (*dp->cdr_next_wr_address)(usalp, &trackp[0], &startsec);
2200 if (startsec > -4500) {
2202 * There must be at least 1 minute lead-in.
2204 errmsgno(EX_BAD, "WARNING: Drive returns wrong startsec (%ld) using %ld from ATIP\n",
2205 startsec, (long)dp->cdr_dstat->ds_first_leadin);
2206 startsec = dp->cdr_dstat->ds_first_leadin;
2208 if (startsec > -4500) {
2209 errmsgno(EX_BAD, "Illegal startsec (%ld)\n", startsec);
2212 if (debug || lverbose)
2213 printf("Writing lead-in at sector %ld\n", startsec);
2214 if (write_leadin(usalp, dp, trackp, startsec) < 0)
2216 dp->cdr_dstat->ds_cdrflags |= RF_LEADIN;
2223 TM_DATA, /* 1 ST_ROM_MODE1 */
2224 TM_DATA, /* 2 ST_ROM_MODE2 */
2226 0, /* 4 ST_AUDIO_NOPRE */
2227 TM_PREEM, /* 5 ST_AUDIO_PRE */
2233 next_wr_addr_mdvd(SCSI *usalp, track_t *trackp, long *ap)
2236 struct track_info track_info;
2239 struct disk_info disk_info;
2241 track = trackp->trackno;
2244 if (trackp != 0 && track > 0 && is_packet(trackp)) {
2246 result = read_track_info(usalp, (caddr_t)&track_info, TI_TYPE_SESS, track, sizeof(track_info));
2248 if (scsi_in_progress(usalp)){
2255 /* Get the last rzone*/
2256 if(read_disk_info(usalp,(caddr_t)&disk_info,8)<0)
2259 /* if (read_track_info(usalp, (caddr_t)&track_info, TI_TYPE_SESS, 0xFF, sizeof(track_info)) < 0) */
2260 if (read_rzone_info(usalp, (caddr_t)&track_info, sizeof(track_info)) < 0)
2264 usal_prbytes("track info:", (Uchar *)&track_info,
2265 sizeof(track_info)-usal_getresid(usalp));
2266 next_addr = a_to_4_byte(track_info.next_writable_addr);
2273 open_track_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp)
2277 struct cd_mode_page_05 *mp;
2279 if (!is_tao(trackp) && !is_packet(trackp)) {
2280 if (trackp->pregapsize > 0 && (trackp->flags & TI_PREGAP) == 0) {
2282 printf("Writing pregap for track %d at %ld\n",
2283 (int)trackp->trackno,
2284 trackp->trackstart-trackp->pregapsize);
2287 * XXX Do we need to check isecsize too?
2289 pad_track(usalp, dp, trackp,
2290 trackp->trackstart-trackp->pregapsize,
2291 (Llong)trackp->pregapsize*trackp->secsize,
2297 fillbytes((caddr_t)mode, sizeof (mode), '\0');
2299 if (!get_mode_params(usalp, 0x05, "CD write parameter",
2300 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len))
2305 mp = (struct cd_mode_page_05 *)
2306 (mode + sizeof (struct scsi_mode_header) +
2307 ((struct scsi_mode_header *)mode)->blockdesc_len);
2310 /* mp->track_mode = ???;*/
2311 mp->track_mode = st2mode[trackp->sectype & ST_MASK];
2312 /* mp->copy = ???;*/
2313 mp->dbtype = trackp->dbtype;
2315 /*i_to_short(mp->audio_pause_len, 300);*/
2316 /*i_to_short(mp->audio_pause_len, 150);*/
2317 /*i_to_short(mp->audio_pause_len, 0);*/
2319 if (is_packet(trackp)) {
2320 mp->write_type = WT_PACKET;
2321 mp->track_mode |= TM_INCREMENTAL;
2322 mp->fp = (trackp->pktsize > 0) ? 1 : 0;
2323 i_to_4_byte(mp->packet_size, trackp->pktsize);
2324 } else if (is_tao(trackp)) {
2325 mp->write_type = WT_TAO;
2327 i_to_4_byte(mp->packet_size, 0);
2329 errmsgno(EX_BAD, "Unknown write mode.\n");
2333 mp->ISRC[0] = 0x80; /* Set ISRC valid */
2334 strncpy((char *)&mp->ISRC[1], trackp->isrc, 12);
2337 fillbytes(&mp->ISRC[0], sizeof (mp->ISRC), '\0');
2341 usal_prbytes("CD write parameter:", (Uchar *)mode, len);
2343 if (!set_mode_params(usalp, "CD write parameter", mode, len, 0, trackp->secsize))
2350 open_track_mdvd(SCSI *usalp, cdr_t *dp, track_t *trackp)
2354 struct cd_mode_page_05 *mp;
2356 if (is_packet(trackp)) {
2357 fillbytes((caddr_t)mode, sizeof(mode), '\0');
2359 if (!get_mode_params(usalp, 0x05, "DVD write parameter",
2360 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len))
2365 mp = (struct cd_mode_page_05 *)
2366 (mode + sizeof(struct scsi_mode_header) +
2367 ((struct scsi_mode_header *)mode)->blockdesc_len);
2369 mp->write_type = WT_PACKET;
2371 /*For now we set the link size to 0x10(32k) because Pioneer-A03 only support this */
2374 i_to_4_byte(mp->packet_size, trackp->pktsize);
2379 if (!set_mode_params(usalp, "CD write parameter", mode, len, 0, trackp->secsize))
2386 close_track_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp)
2390 if (!is_tao(trackp) && !is_packet(trackp))
2393 if (scsi_flush_cache(usalp, (dp->cdr_cmdflags&F_IMMED) != 0) < 0) {
2394 printf("Trouble flushing the cache\n");
2397 wait_unit_ready(usalp, 300); /* XXX Wait for ATAPI */
2398 if (is_packet(trackp) && !is_noclose(trackp)) {
2399 /* close the incomplete track */
2400 ret = scsi_close_tr_session(usalp, CL_TYPE_TRACK, 0xFF,
2401 (dp->cdr_cmdflags&F_IMMED) != 0);
2402 wait_unit_ready(usalp, 300); /* XXX Wait for ATAPI */
2409 close_track_mdvd(SCSI *usalp, cdr_t *dp, track_t *trackp)
2412 if (!is_packet(trackp))
2415 if (scsi_flush_cache(usalp, (dp->cdr_cmdflags&F_IMMED) != 0) < 0) {
2416 printf("Trouble flushing the cache\n");
2419 wait_unit_ready(usalp, 300); /* XXX Wait for ATAPI */
2420 if (is_packet(trackp) && !is_noclose(trackp)) {
2421 /* close the incomplete track */
2422 ret = scsi_close_tr_session(usalp, 1, 0xFF, (dp->cdr_cmdflags&F_IMMED) != 0);
2423 wait_unit_ready(usalp, 300); /* XXX Wait for ATAPI */
2430 SES_DA_ROM, /* CD-DA */
2431 SES_DA_ROM, /* CD-ROM */
2432 SES_XA, /* CD-ROM XA mode 1 */
2433 SES_XA, /* CD-ROM XA MODE 2 */
2435 SES_DA_ROM, /* Invalid - use default */
2436 SES_DA_ROM, /* Invalid - use default */
2440 open_session_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp)
2444 struct cd_mode_page_05 *mp;
2446 fillbytes((caddr_t)mode, sizeof (mode), '\0');
2448 if (!get_mode_params(usalp, 0x05, "CD write parameter",
2449 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len))
2454 mp = (struct cd_mode_page_05 *)
2455 (mode + sizeof (struct scsi_mode_header) +
2456 ((struct scsi_mode_header *)mode)->blockdesc_len);
2458 mp->write_type = WT_TAO; /* fix to allow DAO later */
2460 * We need to set the right dbtype here because Sony drives
2461 * don't like multi session in to be set with DB_ROM_MODE1
2462 * which is set by us at the beginning as default as some drives
2463 * have illegal default values.
2465 mp->track_mode = st2mode[trackp[0].sectype & ST_MASK];
2466 mp->dbtype = trackp[0].dbtype;
2468 if (!is_tao(trackp) && !is_packet(trackp)) {
2469 mp->write_type = WT_SAO;
2470 if (dp->cdr_dstat->ds_cdrflags & RF_AUDIOMASTER)
2473 mp->dbtype = DB_RAW;
2475 if (is_raw(trackp)) {
2476 mp->write_type = WT_RAW;
2479 if (is_raw16(trackp)) {
2480 mp->dbtype = DB_RAW_PQ;
2481 } else if (is_raw96r(trackp)) {
2482 mp->dbtype = DB_RAW_PW_R;
2484 mp->dbtype = DB_RAW_PW;
2488 mp->multi_session = (track_base(trackp)->tracktype & TOCF_MULTI) ?
2490 mp->session_format = toc2sess[track_base(trackp)->tracktype & TOC_MASK];
2493 mp->media_cat_number[0] = 0x80; /* Set MCN valid */
2494 strncpy((char *)&mp->media_cat_number[1], trackp->isrc, 13);
2497 fillbytes(&mp->media_cat_number[0], sizeof (mp->media_cat_number), '\0');
2500 usal_prbytes("CD write parameter:", (Uchar *)mode, len);
2502 if (!set_mode_params(usalp, "CD write parameter", mode, len, 0, -1))
2509 open_session_mdvd(SCSI *usalp, cdr_t *dp, track_t *trackp)
2512 int tracks = trackp->tracks;
2515 struct cd_mode_page_05 *mp;
2520 fillbytes((caddr_t)mode, sizeof(mode), '\0');
2522 if (!get_mode_params(usalp, 0x05, "DVD write parameter",
2523 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len))
2528 mp = (struct cd_mode_page_05 *)
2529 (mode + sizeof(struct scsi_mode_header) +
2530 ((struct scsi_mode_header *)mode)->blockdesc_len);
2531 if(is_packet(trackp)){
2532 mp->write_type=WT_PACKET;
2537 mp->write_type = WT_SAO;
2540 mp->multi_session = (track_base(trackp)->tracktype & TOCF_MULTI) ?
2542 mp->session_format = toc2sess[track_base(trackp)->tracktype & TOC_MASK];
2544 /* Enable Burnfree by default, allow to disable. XXX Sucks, duplicated functionality. */
2545 if (dp->cdr_cdcap->BUF != 0) {
2548 "BURN-Free is %s.\n"
2549 "Turning BURN-Free on\n",
2550 mp->BUFE?"ON":"OFF");
2553 if (driveropts != NULL) {
2554 if ((strcmp(driveropts, "noburnproof") == 0 ||
2555 strcmp(driveropts, "noburnfree") == 0)) {
2557 fprintf(stderr, "Turning BURN-Free off\n");
2560 else if ((strcmp(driveropts, "burnproof") == 0 ||
2561 strcmp(driveropts, "burnfree") == 0)) {
2562 /* a NOP, we enable burnfree by default */
2564 fprintf(stderr, "Found burnproof/burnfree in driveropts, those options are enabled by default now.");
2566 else if (strcmp(driveropts, "help") == 0) {
2570 errmsgno(EX_BAD, "Bad driver opts '%s'.\n", driveropts);
2571 mmc_opthelp(dp, EX_BAD);
2576 if (!set_mode_params(usalp, "DVD write parameter", mode, len, 0, -1))
2581 for(i=1;i<=tracks;i++) {
2582 totalsize+=trackp[i].tracksecs;
2585 profile = get_curprofile(usalp);
2586 if(!is_packet(trackp) && profile != 0x1A){
2587 /* in DAO mode we need to reserve space for the track*/
2588 if(reserve_track(usalp, totalsize)<0)
2595 waitfix_mmc(SCSI *usalp, int secs)
2603 for (i = 0; i < secs/W_SLEEP; i++) {
2604 if (read_disk_info(usalp, dibuf, sizeof (dibuf)) >= 0) {
2608 key = usal_sense_key(usalp);
2609 if (key != SC_UNIT_ATTENTION && key != SC_NOT_READY)
2619 fixate_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp)
2624 struct timeval starttime;
2625 struct timeval stoptime;
2626 int dummy = (track_base(trackp)->tracktype & TOCF_DUMMY) != 0;
2629 printf("fixate_mmc\n");
2630 starttime.tv_sec = 0;
2631 starttime.tv_usec = 0;
2632 stoptime = starttime;
2633 gettimeofday(&starttime, (struct timezone *)0);
2635 if (dummy && lverbose)
2636 printf("WARNING: Some drives don't like fixation in dummy mode.\n");
2640 printf("is_tao: %d,is_packet: %d\n", is_tao(trackp), is_packet(trackp));
2641 if (is_tao(trackp) || is_packet(trackp)) {
2642 ret = scsi_close_tr_session(usalp, CL_TYPE_SESSION, 0,
2643 (dp->cdr_cmdflags&F_IMMED) != 0);
2645 if (scsi_flush_cache(usalp, (dp->cdr_cmdflags&F_IMMED) != 0) < 0) {
2646 if (!scsi_in_progress(usalp))
2647 printf("Trouble flushing the cache\n");
2651 key = usal_sense_key(usalp);
2652 code = usal_sense_code(usalp);
2655 if (debug && !unit_ready(usalp)) {
2656 fprintf(stderr, "Early return from fixating. Ret: %d Key: %d, Code: %d\n", ret, key, code);
2661 wait_unit_ready(usalp, 420/curspeed); /* XXX Wait for ATAPI */
2662 waitfix_mmc(usalp, 420/curspeed); /* XXX Wait for ATAPI */
2666 if ((dummy != 0 && (key != SC_ILLEGAL_REQUEST)) ||
2668 * Try to suppress messages from drives that don't like fixation
2672 (((key != SC_UNIT_ATTENTION) && (key != SC_NOT_READY)) ||
2673 ((code != 0x2E) && (code != 0x04))))) {
2675 * UNIT ATTENTION/2E seems to be a magic for old Mitsumi ATAPI drives
2676 * NOT READY/ code 4 qual 7 (logical unit not ready, operation in progress)
2677 * seems to be a magic for newer Mitsumi ATAPI drives
2678 * NOT READY/ code 4 qual 8 (logical unit not ready, long write in progress)
2679 * seems to be a magic for SONY drives
2680 * when returning early from fixating.
2681 * Try to supress the error message in this case to make
2682 * simple minded users less confused.
2684 usal_printerr(usalp);
2685 usal_printresult(usalp); /* XXX restore key/code in future */
2688 if (debug && !unit_ready(usalp)) {
2689 fprintf(stderr, "Early return from fixating. Ret: %d Key: %d, Code: %d\n", ret, key, code);
2692 wait_unit_ready(usalp, 420); /* XXX Wait for ATAPI */
2693 waitfix_mmc(usalp, 420/curspeed); /* XXX Wait for ATAPI */
2696 (ret >= 0 || (key == SC_UNIT_ATTENTION && code == 0x2E))) {
2698 * Some ATAPI drives (e.g. Mitsumi) imply the
2699 * IMMED bit in the SCSI cdb. As there seems to be no
2700 * way to properly check for the real end of the
2701 * fixating process we wait for the expected time.
2703 gettimeofday(&stoptime, (struct timezone *)0);
2704 timevaldiff(&starttime, &stoptime);
2705 if (stoptime.tv_sec < (220 / curspeed)) {
2709 printf("Actual fixating time: %ld seconds\n",
2710 (long)stoptime.tv_sec);
2712 secs = (280 / curspeed) - stoptime.tv_sec;
2714 printf("ATAPI early return: sleeping %d seconds.\n",
2724 fixate_mdvd(SCSI *usalp, cdr_t *dp, track_t *trackp)
2727 if (scsi_flush_cache(usalp, (dp->cdr_cmdflags&F_IMMED) != 0) < 0) {
2728 printf("Trouble flushing the cache\n");
2731 wait_unit_ready(usalp, 300); /* XXX Wait for ATAPI */
2732 /*set a really BIG timeout and call fixate_mmc
2733 The BIG timeout is needed in case there was a very short rzone to write at the
2734 beginning of the disk, because lead-out needs to be at some distance.
2737 printf("fixate_mdvd\n");
2738 usal_settimeout(usalp, 1000);
2739 if(is_packet(trackp) || dp->profile == 0x1B){
2740 scsi_close_tr_session(usalp, CL_TYPE_SESSION, 0, FALSE);
2742 ret = fixate_mmc(usalp, dp, trackp);
2743 if (dp->profile == 0x2B) {
2744 scsi_close_tr_session(usalp, CL_TYPE_OPEN_SESSION, 0, FALSE);
2745 scsi_close_tr_session(usalp, CL_TYPE_FINALISE_MINRAD, 0, FALSE);
2747 usal_settimeout(usalp, 200);
2752 char *blank_types[] = {
2758 "closing of last session",
2760 "reserved blanking type",
2763 char *format_types[] = {
2765 "background format",
2770 blank_mmc(SCSI *usalp, cdr_t *dp, long addr, int blanktype)
2772 BOOL cdrr = FALSE; /* Read CD-R */
2773 BOOL cdwr = FALSE; /* Write CD-R */
2774 BOOL cdrrw = FALSE; /* Read CD-RW */
2775 BOOL cdwrw = FALSE; /* Write CD-RW */
2778 mmc_check(usalp, &cdrr, &cdwr, &cdrrw, &cdwrw, NULL, NULL);
2780 return (blank_dummy(usalp, dp, addr, blanktype));
2782 if (dp->profile == 0x1A) {
2783 printf("Error: this media does not support blanking, ignoring.\n");
2784 return (blank_dummy(usalp, dp, addr, blanktype));
2787 printf("Blanking %s\n", blank_types[blanktype & 0x07]);
2791 ret = scsi_blank(usalp, addr, blanktype, (dp->cdr_cmdflags&F_IMMED) != 0);
2795 wait_unit_ready(usalp, 90*60/curspeed); /* XXX Wait for ATAPI */
2796 waitfix_mmc(usalp, 90*60/curspeed); /* XXX Wait for ATAPI */
2800 static int format_mdvd(SCSI *usalp, cdr_t *dp, int formattype)
2803 BOOL dvdwr = FALSE; /* Write DVD */
2807 struct disk_info *dip;
2809 if (debug || lverbose > 2)
2810 printf("format_mdvd\n");
2811 mmc_check(usalp, NULL, NULL, NULL, NULL, NULL, &dvdwr);
2813 return (format_dummy(usalp, dp, formattype));
2815 if (debug || lverbose > 2)
2816 printf("format_mdvd: drive is a dvd burner.\n");
2817 profile = get_curprofile(usalp);
2818 if (profile != 0x1A) {
2819 printf("Error: only support DVD+RW formating, ignoring.\n");
2820 return (format_dummy(usalp, dp, formattype));
2822 dip = (struct disk_info *)buf;
2823 if (get_diskinfo(usalp, dip) < 0)
2826 if (dip->disk_status & 3 && formattype != FORCE_FORMAT) {
2827 printf("Error: disk already formated, ignoring.\n");
2830 addr[0] = 0; /* "Reserved" */
2831 addr[1] = 2; /* "IMMED" flag */
2832 addr[2] = 0; /* "Descriptor Length" (MSB) */
2833 addr[3] = 8; /* "Descriptor Length" (LSB) */
2838 addr[4+4] = 0x26<<2;
2842 if (formattype == FORCE_FORMAT) {
2843 printf("format_mdvd: forcing reformat.\n");
2844 formattype = FULL_FORMAT;
2851 printf("format_mdvd: media is unformated.\n");
2855 printf("Formating %s\n", format_types[formattype & 0x07]);
2858 if (formattype == FULL_FORMAT) {
2859 ret = scsi_format(usalp, (caddr_t)&addr, sizeof(addr), FALSE);
2861 ret = scsi_format(usalp, (caddr_t)&addr, sizeof(addr), TRUE);
2866 wait_unit_ready(usalp, 90*60/curspeed); /* XXX Wait for ATAPI */
2867 waitfix_mmc(usalp, 90*60/curspeed); /* XXX Wait for ATAPI */
2872 send_opc_mmc(SCSI *usalp, caddr_t bp, int cnt, int doopc)
2877 ret = send_opc(usalp, bp, cnt, doopc);
2885 * Hack for a mysterioys drive ....
2886 * Device type : Removable CD-ROM
2888 * Response Format: 1
2889 * Vendor_info : 'RWD '
2890 * Identifikation : 'RW2224 '
2892 * Device seems to be: Generic mmc CD-RW.
2895 * CDB: 54 01 00 00 00 00 00 00 00 00
2896 * Sense Bytes: 70 00 06 00 00 00 00 0A 00 00 00 00 5A 03 00 00
2897 * Sense Key: 0x6 Unit Attention, Segment 0
2898 * Sense Code: 0x5A Qual 0x03 (operator selected write permit) Fru 0x0
2899 * Sense flags: Blk 0 (not valid)
2902 if (usal_sense_key(usalp) == SC_UNIT_ATTENTION &&
2903 usal_sense_code(usalp) == 0x5A &&
2904 usal_sense_qual(usalp) == 0x03)
2908 * Do not make the condition:
2909 * "Power calibration area almost full" a fatal error.
2910 * It just flags that we have a single and last chance to write now.
2912 if ((usal_sense_key(usalp) == SC_RECOVERABLE_ERROR ||
2913 usal_sense_key(usalp) == SC_MEDIUM_ERROR) &&
2914 usal_sense_code(usalp) == 0x73 &&
2915 usal_sense_qual(usalp) == 0x01)
2919 * Send OPC is optional.
2921 if (usal_sense_key(usalp) != SC_ILLEGAL_REQUEST) {
2922 if (usalp->silent <= 0)
2923 usal_printerr(usalp);
2930 opt1_mmc(SCSI *usalp, cdr_t *dp)
2932 int oflags = dp->cdr_dstat->ds_cdrflags;
2934 if ((dp->cdr_dstat->ds_cdrflags & RF_AUDIOMASTER) != 0) {
2935 printf("Turning Audio Master Q. R. on\n");
2936 if (set_audiomaster_yamaha(usalp, dp, TRUE) < 0)
2938 if (!debug && lverbose <= 1)
2939 dp->cdr_dstat->ds_cdrflags &= ~RF_PRATIP;
2940 if (getdisktype_mmc(usalp, dp) < 0) {
2941 dp->cdr_dstat->ds_cdrflags = oflags;
2944 dp->cdr_dstat->ds_cdrflags = oflags;
2945 if (oflags & RF_PRATIP) {
2947 lba_to_msf(dp->cdr_dstat->ds_first_leadin, &msf);
2948 printf("New start of lead in: %ld (%02d:%02d/%02d)\n",
2949 (long)dp->cdr_dstat->ds_first_leadin,
2953 lba_to_msf(dp->cdr_dstat->ds_maxblocks, &msf);
2954 printf("New start of lead out: %ld (%02d:%02d/%02d)\n",
2955 (long)dp->cdr_dstat->ds_maxblocks,
2961 if (mmc_isplextor(usalp)) {
2964 if ((dp->cdr_flags & (CDR_SINGLESESS|CDR_HIDE_CDR)) != 0) {
2965 if (ss_hide_plextor(usalp,
2966 (dp->cdr_dstat->ds_cdrflags & RF_SINGLESESS) != 0,
2967 (dp->cdr_dstat->ds_cdrflags & RF_HIDE_CDR) != 0) < 0)
2971 if ((dp->cdr_flags & CDR_SPEEDREAD) != 0) {
2972 if (speed_rd_plextor(usalp,
2973 (dp->cdr_dstat->ds_cdrflags & RF_SPEEDREAD) != 0) < 0)
2977 if ((dp->cdr_cmdflags & F_SETDROPTS) ||
2978 (wm_base(dp->cdr_dstat->ds_wrmode) == WM_SAO) ||
2979 (wm_base(dp->cdr_dstat->ds_wrmode) == WM_RAW))
2980 gcode = do_gigarec_plextor(usalp);
2982 gcode = gigarec_plextor(usalp, 0);
2986 dp->cdr_dstat->ds_first_leadin =
2987 gigarec_mult(gcode, dp->cdr_dstat->ds_first_leadin);
2988 dp->cdr_dstat->ds_maxblocks =
2989 gigarec_mult(gcode, dp->cdr_dstat->ds_maxblocks);
2991 if (oflags & RF_PRATIP) {
2992 lba_to_msf(dp->cdr_dstat->ds_first_leadin, &msf);
2993 printf("New start of lead in: %ld (%02d:%02d/%02d)\n",
2994 (long)dp->cdr_dstat->ds_first_leadin,
2998 lba_to_msf(dp->cdr_dstat->ds_maxblocks, &msf);
2999 printf("New start of lead out: %ld (%02d:%02d/%02d)\n",
3000 (long)dp->cdr_dstat->ds_maxblocks,
3011 opt2_mmc(SCSI *usalp, cdr_t *dp)
3016 struct cd_mode_page_05 *mp;
3017 struct ricoh_mode_page_30 *rp = NULL;
3018 BOOL burnfree = FALSE;
3020 fillbytes((caddr_t)mode, sizeof (mode), '\0');
3022 if (!get_mode_params(usalp, 0x05, "CD write parameter",
3023 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len))
3028 mp = (struct cd_mode_page_05 *)
3029 (mode + sizeof (struct scsi_mode_header) +
3030 ((struct scsi_mode_header *)mode)->blockdesc_len);
3033 rp = get_justlink_ricoh(usalp, moder);
3035 if (dp->cdr_cdcap->BUF != 0) {
3036 burnfree = (mp->BUFE != 0);
3037 } else if ((dp->cdr_flags & CDR_BURNFREE) != 0) {
3038 burnfree = (rp && (rp->BUEFE != 0));
3041 if (lverbose>2 && (dp->cdr_flags & CDR_BURNFREE) != 0)
3042 printf("BURN-Free is %s.\n", burnfree?"ON":"OFF");
3044 if (!burnfree && (dp->cdr_dstat->ds_cdrflags & RF_BURNFREE) != 0) {
3046 printf("Turning BURN-Free on\n");
3049 if (burnfree && (dp->cdr_dstat->ds_cdrflags & RF_BURNFREE) == 0) {
3051 printf("Turning BURN-Free off\n");
3054 if (dp->cdr_cdcap->BUF != 0) {
3055 mp->BUFE = burnfree?1:0;
3057 else if ((dp->cdr_flags & CDR_BURNFREE) != 0) {
3060 rp->BUEFE = burnfree?1:0;
3064 * Clear Just-Link counter
3066 i_to_2_byte(rp->link_counter, 0);
3068 usal_prbytes("Mode Select Data ", moder, moder[0]+1);
3070 if (!set_mode_params(usalp, "Ricoh Vendor Page", moder, moder[0]+1, 0, -1))
3072 rp = get_justlink_ricoh(usalp, moder);
3076 usal_prbytes("CD write parameter:", (Uchar *)mode, len);
3078 if (!set_mode_params(usalp, "CD write parameter", mode, len, 0, -1))
3081 if (mmc_isplextor(usalp)) {
3083 * Clear Burn-Proof counter
3086 bpc_plextor(usalp, 1, NULL);
3089 do_varirec_plextor(usalp);
3096 opt1_mdvd(SCSI *usalp, cdr_t *dp)
3098 int oflags = dp->cdr_dstat->ds_cdrflags;
3100 if ((dp->cdr_dstat->ds_cdrflags & RF_AUDIOMASTER) != 0) {
3101 printf("Turning Audio Master Q. R. on\n");
3102 if (set_audiomaster_yamaha(usalp, dp, TRUE) < 0)
3104 if (!debug && lverbose <= 1)
3105 dp->cdr_dstat->ds_cdrflags &= ~RF_PRATIP;
3106 if (getdisktype_mdvd(usalp, dp) < 0) {
3107 dp->cdr_dstat->ds_cdrflags = oflags;
3110 dp->cdr_dstat->ds_cdrflags = oflags;
3111 if (oflags & RF_PRATIP) {
3113 lba_to_msf(dp->cdr_dstat->ds_first_leadin, &msf);
3114 printf("New start of lead in: %ld (%02d:%02d/%02d)\n",
3115 (long)dp->cdr_dstat->ds_first_leadin,
3119 lba_to_msf(dp->cdr_dstat->ds_maxblocks, &msf);
3120 printf("New start of lead out: %ld (%02d:%02d/%02d)\n",
3121 (long)dp->cdr_dstat->ds_maxblocks,
3131 scsi_sony_write(SCSI *usalp,
3132 caddr_t bp /* address of buffer */,
3133 long sectaddr /* disk address (sector) to put */,
3134 long size /* number of bytes to transfer */,
3135 int blocks /* sector count */,
3136 BOOL islast /* last write for track */)
3138 return (write_xg5(usalp, bp, sectaddr, size, blocks));
3142 0x00, /* 0 2352 bytes of raw data */
3143 0xFF, /* 1 2368 bytes (raw data + P/Q Subchannel) */
3144 0xFF, /* 2 2448 bytes (raw data + P-W Subchannel) */
3145 0xFF, /* 3 2448 bytes (raw data + P-W raw Subchannel)*/
3146 0xFF, /* 4 - Reserved */
3147 0xFF, /* 5 - Reserved */
3148 0xFF, /* 6 - Reserved */
3149 0xFF, /* 7 - Vendor specific */
3150 0x10, /* 8 2048 bytes Mode 1 (ISO/IEC 10149) */
3151 0x30, /* 9 2336 bytes Mode 2 (ISO/IEC 10149) */
3152 0xFF, /* 10 2048 bytes Mode 2! (CD-ROM XA form 1) */
3153 0xFF, /* 11 2056 bytes Mode 2 (CD-ROM XA form 1) */
3154 0xFF, /* 12 2324 bytes Mode 2 (CD-ROM XA form 2) */
3155 0xFF, /* 13 2332 bytes Mode 2 (CD-ROM XA 1/2+subhdr) */
3156 0xFF, /* 14 - Reserved */
3157 0xFF, /* 15 - Vendor specific */
3161 gen_cue_mmc(track_t *trackp, void *vcuep, BOOL needgap)
3163 int tracks = trackp->tracks;
3165 struct mmc_cue **cuep = vcuep;
3166 struct mmc_cue *cue;
3178 for (i = 0; i <= tracks; i++) {
3179 ctl = (st2mode[trackp[i].sectype & ST_MASK]) << 4;
3180 if (is_copy(&trackp[i]))
3181 ctl |= TM_ALLOW_COPY << 4;
3182 if (is_quadro(&trackp[i]))
3183 ctl |= TM_QUADRO << 4;
3184 df = db2df[trackp[i].dbtype & 0x0F];
3185 if (trackp[i].tracktype == TOC_XA2 &&
3186 trackp[i].sectype == (SECT_MODE_2_MIX|ST_MODE_RAW)) {
3188 * Hack for CUE with MODE2/CDI and
3189 * trackp[i].dbtype == DB_RAW
3194 if (trackp[i].isrc) { /* MCN or ISRC */
3196 cue = realloc(cue, ncue * sizeof (*cue));
3199 cp->cs_ctladr = 0x02;
3200 movebytes(&trackp[i].isrc[0], &cp->cs_tno, 7);
3202 cp->cs_ctladr = 0x02;
3203 movebytes(&trackp[i].isrc[7], &cp->cs_tno, 7);
3205 cp->cs_ctladr = 0x03;
3207 movebytes(&trackp[i].isrc[0], &cp->cs_index, 6);
3209 cp->cs_ctladr = 0x03;
3211 movebytes(&trackp[i].isrc[6], &cp->cs_index, 6);
3214 if (i == 0) { /* Lead in */
3215 df &= ~7; /* Mask off data size & nonRAW subch */
3220 if (trackp[0].flags & TI_TEXT) /* CD-Text in Lead-in*/
3222 lba_to_msf(-150, &m);
3223 cue = realloc(cue, ++ncue * sizeof (*cue));
3225 fillcue(cp, ctl|0x01, i, 0, df, 0, &m);
3229 if (is_scms(&trackp[i]))
3231 pgsize = trackp[i].pregapsize;
3232 if (pgsize == 0 && needgap)
3234 lba_to_msf(trackp[i].trackstart-pgsize, &m);
3235 cue = realloc(cue, ++ncue * sizeof (*cue));
3237 fillcue(cp, ctl|0x01, i, 0, df, scms, &m);
3239 if (trackp[i].nindex == 1) {
3240 lba_to_msf(trackp[i].trackstart, &m);
3241 cue = realloc(cue, ++ncue * sizeof (*cue));
3243 fillcue(cp, ctl|0x01, i, 1, df, scms, &m);
3248 ncue += trackp[i].nindex;
3249 idxlist = trackp[i].tindex;
3250 cue = realloc(cue, ncue * sizeof (*cue));
3252 for (idx = 1; idx <= trackp[i].nindex; idx++) {
3253 lba_to_msf(trackp[i].trackstart + idxlist[idx], &m);
3255 fillcue(cp, ctl|0x01, i, idx, df, scms, &m);
3261 ctl = (st2mode[trackp[tracks+1].sectype & ST_MASK]) << 4;
3262 if (is_copy(&trackp[i]))
3263 ctl |= TM_ALLOW_COPY << 4;
3264 if (is_quadro(&trackp[i]))
3265 ctl |= TM_QUADRO << 4;
3266 df = db2df[trackp[tracks+1].dbtype & 0x0F];
3267 if (trackp[i].tracktype == TOC_XA2 &&
3268 trackp[i].sectype == (SECT_MODE_2_MIX|ST_MODE_RAW)) {
3270 * Hack for CUE with MODE2/CDI and
3271 * trackp[i].dbtype == DB_RAW
3275 df &= ~7; /* Mask off data size & nonRAW subch */
3280 lba_to_msf(trackp[tracks+1].trackstart, &m);
3281 cue = realloc(cue, ++ncue * sizeof (*cue));
3283 fillcue(cp, ctl|0x01, 0xAA, 1, df, 0, &m);
3286 for (i = 0; i < ncue; i++) {
3287 usal_prbytes("", (Uchar *)&cue[i], 8);
3298 fillcue(struct mmc_cue *cp /* The target cue entry */,
3299 int ca /* Control/adr for this entry */,
3300 int tno /* Track number for this entry */,
3301 int idx /* Index for this entry */,
3302 int dataform /* Data format for this entry */,
3303 int scms /* Serial copy management */,
3304 msf_t *mp /* MSF value for this entry */)
3306 cp->cs_ctladr = ca; /* XXX wie lead in */
3309 cp->cs_dataform = dataform; /* XXX wie lead in */
3311 cp->cs_min = mp->msf_min;
3312 cp->cs_sec = mp->msf_sec;
3313 cp->cs_frame = mp->msf_frame;
3317 send_cue_mmc(SCSI *usalp, cdr_t *dp, track_t *trackp)
3324 for (i = 1; i <= trackp->tracks; i++) {
3325 if (trackp[i].tracksize < (tsize_t)0) {
3326 errmsgno(EX_BAD, "Track %d has unknown length.\n", i);
3330 ncue = (*dp->cdr_gen_cue)(trackp, &cp, FALSE);
3333 ret = send_cue_sheet(usalp, (caddr_t)cp, ncue*8);
3337 errmsgno(EX_BAD, "CUE sheet not accepted. Retrying with minimum pregapsize = 1.\n");
3338 ncue = (*dp->cdr_gen_cue)(trackp, &cp, TRUE);
3339 ret = send_cue_sheet(usalp, (caddr_t)cp, ncue*8);
3342 "CUE sheet still not accepted. Please try to write in RAW (-raw96r) mode.\n");
3350 stats_mmc(SCSI *usalp, cdr_t *dp)
3353 struct ricoh_mode_page_30 *rp;
3356 if (mmc_isplextor(usalp) && lverbose) {
3362 * Run it in silent mode as old drives do not support it.
3363 * As this function looks to be a part of the PowerRec
3364 * features, we may want to check
3365 * dp->cdr_flags & CDR_FORCESPEED
3368 if (get_speeds_plextor(usalp, &sels, &maxs, &lasts) >= 0) {
3369 printf("Last selected write speed: %dx\n",
3371 printf("Max media write speed: %dx\n",
3373 printf("Last actual write speed: %dx\n",
3379 if ((dp->cdr_dstat->ds_cdrflags & RF_BURNFREE) == 0)
3382 if (mmc_isplextor(usalp)) {
3387 * Read Burn-Proof counter
3390 ret = bpc_plextor(usalp, 2, &i);
3396 * Clear Burn-Proof counter
3398 bpc_plextor(usalp, 1, NULL);
3400 rp = get_justlink_ricoh(usalp, mode);
3402 count = a_to_u_2_byte(rp->link_counter);
3408 printf("BURN-Free was never needed.\n");
3410 printf("BURN-Free was %d times used.\n",
3415 /*--------------------------------------------------------------------------*/
3417 mmc_isplextor(SCSI *usalp)
3419 if (usalp->inq != NULL &&
3420 strncmp(usalp->inq->vendor_info, "PLEXTOR", 7) == 0) {
3427 mmc_isyamaha(SCSI *usalp)
3429 if (usalp->inq != NULL &&
3430 strncmp(usalp->inq->vendor_info, "YAMAHA", 6) == 0) {
3437 do_varirec_plextor(SCSI *usalp)
3442 p = hasdrvopt(driveropts, "varirec=");
3443 if (p == NULL || curspeed != 4) {
3444 if (check_varirec_plextor(usalp) >= 0)
3445 varirec_plextor(usalp, FALSE, 0);
3447 if (*astoi(p, &voff) != '\0')
3449 "Bad varirec value '%s'.\n", p);
3450 if (check_varirec_plextor(usalp) < 0)
3451 comerrno(EX_BAD, "Drive does not support VariRec.\n");
3452 varirec_plextor(usalp, TRUE, voff);
3457 * GigaRec value table
3464 { 0x00, 0, "off", },
3465 { 0x00, 0, "1.0", },
3466 { 0x01, 2, "1.2", },
3467 { 0x02, 3, "1.3", },
3468 { 0x03, 4, "1.4", },
3469 { 0x81, -2, "0.8", },
3470 { 0x82, -3, "0.7", },
3471 { 0x83, -4, "0.6", },
3476 do_gigarec_plextor(SCSI *usalp)
3479 int val = 0; /* Make silly GCC happy */
3481 p = hasdrvopt(driveropts, "gigarec=");
3483 if (check_gigarec_plextor(usalp) >= 0)
3484 gigarec_plextor(usalp, 0);
3488 for (; gp->name != NULL; gp++) {
3489 if (streql(p, gp->name)) {
3494 if (gp->name == NULL)
3496 "Bad gigarec value '%s'.\n", p);
3497 if (check_gigarec_plextor(usalp) < 0)
3498 comerrno(EX_BAD, "Drive does not support GigaRec.\n");
3499 return (gigarec_plextor(usalp, val));
3505 drivemode_plextor(SCSI *usalp, caddr_t bp, int cnt, int modecode, void *modeval)
3507 register struct usal_cmd *scmd = usalp->scmd;
3509 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
3510 scmd->flags = SCG_DISRE_ENA;
3511 if (modeval == NULL) {
3512 scmd->flags |= SCG_RECV_DATA;
3516 scmd->cdb.g5_cdb.res = 0x08;
3518 scmd->cdb_len = SC_G5_CDBLEN;
3519 scmd->sense_len = CCS_SENSE_LEN;
3520 scmd->cdb.g5_cdb.cmd = 0xE9;
3521 scmd->cdb.g5_cdb.lun = usal_lun(usalp);
3522 scmd->cdb.g1_cdb.addr[0] = modecode;
3524 movebytes(modeval, &scmd->cdb.g1_cdb.addr[1], 6);
3526 i_to_2_byte(&scmd->cdb.g1_cdb.count[2], cnt);
3528 usalp->cmdname = "plextor drive mode";
3530 if (usal_cmd(usalp) < 0)
3536 * #defines for drivemode_plextor()...
3538 #define MODE_CODE_SH 0x01 /* Mode code for Single Session & Hide-CDR */
3539 #define MB1_SS 0x01 /* Single Session Mode */
3540 #define MB1_HIDE_CDR 0x02 /* Hide CDR Media */
3542 #define MODE_CODE_VREC 0x02 /* Mode code for Vari Rec */
3544 #define MODE_CODE_GREC 0x04 /* Mode code for Giga Rec */
3546 #define MODE_CODE_SPEED 0xbb /* Mode code for Speed Read */
3547 #define MBbb_SPEAD_READ 0x01 /* Spead Read */
3548 /* Danach Speed auf 0xFFFF 0xFFFF setzen */
3551 drivemode2_plextor(SCSI *usalp, caddr_t bp, int cnt, int modecode, void *modeval)
3553 register struct usal_cmd *scmd = usalp->scmd;
3555 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
3556 scmd->flags = SCG_DISRE_ENA;
3557 if (modeval == NULL) {
3558 scmd->flags |= SCG_RECV_DATA;
3562 scmd->cdb.g5_cdb.res = 0x08;
3564 scmd->cdb_len = SC_G5_CDBLEN;
3565 scmd->sense_len = CCS_SENSE_LEN;
3566 scmd->cdb.g5_cdb.cmd = 0xED;
3567 scmd->cdb.g5_cdb.lun = usal_lun(usalp);
3568 scmd->cdb.g1_cdb.addr[0] = modecode;
3570 scmd->cdb.g5_cdb.reladr = *(char *)modeval != 0 ? 1 : 0;
3572 i_to_2_byte(&scmd->cdb.g1_cdb.count[1], cnt);
3574 usalp->cmdname = "plextor drive mode2";
3576 if (usal_cmd(usalp) < 0)
3583 check_varirec_plextor(SCSI *usalp)
3588 fillbytes(getmode, sizeof (getmode), '\0');
3590 if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) {
3600 check_gigarec_plextor(SCSI *usalp)
3605 fillbytes(getmode, sizeof (getmode), '\0');
3607 if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) {
3617 varirec_plextor(SCSI *usalp, BOOL on, int val)
3623 fillbytes(getmode, sizeof (getmode), '\0');
3625 if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) {
3632 usal_prbytes("Modes", getmode, sizeof (getmode));
3635 fillbytes(setmode, sizeof (setmode), '\0');
3636 setmode[0] = on?1:0;
3638 if (val < -2 || val > 2)
3639 comerrno(EX_BAD, "Bad VariRec offset %d\n", val);
3640 printf("Turning Varirec on.\n");
3641 printf("Varirec offset is %d.\n", val);
3644 setmode[1] = val & 0x7F;
3646 setmode[1] = (-val) & 0x7F;
3651 if (drivemode_plextor(usalp, NULL, 0, modecode, setmode) < 0)
3654 fillbytes(getmode, sizeof (getmode), '\0');
3655 if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0)
3659 usal_prbytes("Modes", getmode, sizeof (getmode));
3665 gigarec_plextor(SCSI *usalp, int val)
3671 fillbytes(getmode, sizeof (getmode), '\0');
3673 if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) {
3680 usal_prbytes("Modes", getmode, sizeof (getmode));
3683 fillbytes(setmode, sizeof (setmode), '\0');
3686 if (drivemode_plextor(usalp, NULL, 0, modecode, setmode) < 0)
3689 fillbytes(getmode, sizeof (getmode), '\0');
3690 if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0)
3694 usal_prbytes("Modes", getmode, sizeof (getmode));
3699 for (; gp->name != NULL; gp++) {
3700 if (getmode[3] == gp->val)
3703 if (gp->name == NULL)
3704 printf("Unknown GigaRec value 0x%X.\n", getmode[3]);
3706 printf("GigaRec %sis %s.\n", gp->val?"value ":"", gp->name);
3708 return (getmode[3]);
3712 gigarec_mult(int code, Int32_t val)
3717 for (; gp->name != NULL; gp++) {
3718 if (code == gp->val)
3724 add = val * gp->vadd / 10;
3729 check_ss_hide_plextor(SCSI *usalp)
3734 fillbytes(getmode, sizeof (getmode), '\0');
3736 if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) {
3742 return (getmode[2] & 0x03);
3746 check_speed_rd_plextor(SCSI *usalp)
3748 int modecode = 0xBB;
3751 fillbytes(getmode, sizeof (getmode), '\0');
3753 if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) {
3759 return (getmode[2] & 0x01);
3763 check_powerrec_plextor(SCSI *usalp)
3768 fillbytes(getmode, sizeof (getmode), '\0');
3770 if (drivemode2_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) {
3783 ss_hide_plextor(SCSI *usalp, BOOL do_ss, BOOL do_hide)
3791 fillbytes(getmode, sizeof (getmode), '\0');
3793 if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) {
3800 usal_prbytes("Modes", getmode, sizeof (getmode));
3803 is_ss = (getmode[2] & MB1_SS) != 0;
3804 is_hide = (getmode[2] & MB1_HIDE_CDR) != 0;
3807 printf("Single session is %s.\n", is_ss ? "ON":"OFF");
3808 printf("Hide CDR is %s.\n", is_hide ? "ON":"OFF");
3811 fillbytes(setmode, sizeof (setmode), '\0');
3812 setmode[0] = getmode[2]; /* Copy over old values */
3815 setmode[0] |= MB1_SS;
3817 setmode[0] &= ~MB1_SS;
3821 setmode[0] |= MB1_HIDE_CDR;
3823 setmode[0] &= ~MB1_HIDE_CDR;
3826 if (do_ss >= 0 && do_ss != is_ss)
3827 printf("Turning single session %s.\n", do_ss?"on":"off");
3828 if (do_hide >= 0 && do_hide != is_hide)
3829 printf("Turning hide CDR %s.\n", do_hide?"on":"off");
3831 if (drivemode_plextor(usalp, NULL, 0, modecode, setmode) < 0)
3834 fillbytes(getmode, sizeof (getmode), '\0');
3835 if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0)
3839 usal_prbytes("Modes", getmode, sizeof (getmode));
3845 speed_rd_plextor(SCSI *usalp, BOOL do_speedrd)
3847 int modecode = 0xBB;
3852 fillbytes(getmode, sizeof (getmode), '\0');
3854 if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) {
3861 usal_prbytes("Modes", getmode, sizeof (getmode));
3864 is_speedrd = (getmode[2] & MBbb_SPEAD_READ) != 0;
3867 printf("Speed-Read is %s.\n", is_speedrd ? "ON":"OFF");
3869 fillbytes(setmode, sizeof (setmode), '\0');
3870 setmode[0] = getmode[2]; /* Copy over old values */
3871 if (do_speedrd >= 0) {
3873 setmode[0] |= MBbb_SPEAD_READ;
3875 setmode[0] &= ~MBbb_SPEAD_READ;
3878 if (do_speedrd >= 0 && do_speedrd != is_speedrd)
3879 printf("Turning Speed-Read %s.\n", do_speedrd?"on":"off");
3881 if (drivemode_plextor(usalp, NULL, 0, modecode, setmode) < 0)
3884 fillbytes(getmode, sizeof (getmode), '\0');
3885 if (drivemode_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0)
3889 usal_prbytes("Modes", getmode, sizeof (getmode));
3892 * Set current read speed to new max value.
3894 if (do_speedrd >= 0 && do_speedrd != is_speedrd)
3895 scsi_set_speed(usalp, 0xFFFF, -1, ROTCTL_CAV);
3901 powerrec_plextor(SCSI *usalp, BOOL do_powerrec)
3909 fillbytes(getmode, sizeof (getmode), '\0');
3911 if (drivemode2_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0) {
3918 usal_prbytes("Modes", getmode, sizeof (getmode));
3921 is_powerrec = (getmode[2] & 1) != 0;
3923 speed = a_to_u_2_byte(&getmode[4]);
3926 printf("Power-Rec is %s.\n", is_powerrec ? "ON":"OFF");
3927 printf("Power-Rec write speed: %dx (recommended)\n", speed / 176);
3930 fillbytes(setmode, sizeof (setmode), '\0');
3931 setmode[0] = getmode[2]; /* Copy over old values */
3932 if (do_powerrec >= 0) {
3939 if (do_powerrec >= 0 && do_powerrec != is_powerrec)
3940 printf("Turning Power-Rec %s.\n", do_powerrec?"on":"off");
3942 if (drivemode2_plextor(usalp, NULL, 0, modecode, setmode) < 0)
3945 fillbytes(getmode, sizeof (getmode), '\0');
3946 if (drivemode2_plextor(usalp, (caddr_t)getmode, sizeof (getmode), modecode, NULL) < 0)
3950 usal_prbytes("Modes", getmode, sizeof (getmode));
3956 get_speeds_plextor(SCSI *usalp, int *selp, int *maxp, int *lastp)
3958 register struct usal_cmd *scmd = usalp->scmd;
3962 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
3963 fillbytes((caddr_t)buf, sizeof (buf), '\0');
3964 scmd->flags = SCG_DISRE_ENA;
3965 scmd->flags |= SCG_RECV_DATA;
3967 scmd->size = sizeof (buf);
3968 scmd->cdb_len = SC_G5_CDBLEN;
3969 scmd->sense_len = CCS_SENSE_LEN;
3970 scmd->cdb.g5_cdb.cmd = 0xEB;
3971 scmd->cdb.g5_cdb.lun = usal_lun(usalp);
3973 i_to_2_byte(&scmd->cdb.g1_cdb.count[1], sizeof (buf));
3975 usalp->cmdname = "plextor get speedlist";
3977 if (usal_cmd(usalp) < 0)
3980 i = a_to_u_2_byte(&buf[4]);
3984 i = a_to_u_2_byte(&buf[6]);
3988 i = a_to_u_2_byte(&buf[8]);
3996 bpc_plextor(SCSI *usalp, int mode, int *bpp)
3998 register struct usal_cmd *scmd = usalp->scmd;
4002 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
4003 fillbytes((caddr_t)buf, sizeof (buf), '\0');
4004 scmd->flags = SCG_DISRE_ENA;
4005 scmd->flags |= SCG_RECV_DATA;
4007 scmd->size = sizeof (buf);
4008 scmd->cdb_len = SC_G5_CDBLEN;
4009 scmd->sense_len = CCS_SENSE_LEN;
4010 scmd->cdb.g5_cdb.cmd = 0xF5;
4011 scmd->cdb.g5_cdb.lun = usal_lun(usalp);
4013 scmd->cdb.g5_cdb.addr[1] = 0x08;
4014 scmd->cdb.g5_cdb.addr[2] = mode;
4016 i_to_2_byte(&scmd->cdb.g1_cdb.count[1], sizeof (buf));
4018 usalp->cmdname = "plextor read bpc";
4020 if (usal_cmd(usalp) < 0)
4023 if (usal_getresid(usalp) > 2)
4026 i = a_to_u_2_byte(buf);
4034 set_audiomaster_yamaha(SCSI *usalp, cdr_t *dp, BOOL keep_mode)
4039 struct cd_mode_page_05 *mp;
4041 if (xdebug && !keep_mode)
4042 printf("Checking for Yamaha Audio Master feature: ");
4045 * Do not reset mp->test_write (-dummy) here.
4047 deflt_writemodes_mmc(usalp, FALSE);
4049 fillbytes((caddr_t)mode, sizeof (mode), '\0');
4052 if (!get_mode_params(usalp, 0x05, "CD write parameter",
4053 mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) {
4062 mp = (struct cd_mode_page_05 *)
4063 (mode + sizeof (struct scsi_mode_header) +
4064 ((struct scsi_mode_header *)mode)->blockdesc_len);
4066 usal_prbytes("CD write parameter:", (Uchar *)mode, len);
4070 * Do not set mp->test_write (-dummy) here. It should be set
4071 * only at one place and only one time.
4077 mp->dbtype = DB_RAW;
4079 if (!set_mode_params(usalp, "CD write parameter", mode, len, 0, -1))
4083 * Do not reset mp->test_write (-dummy) here.
4085 if (!keep_mode || ret < 0)
4086 deflt_writemodes_mmc(usalp, FALSE);
4093 ricoh_mode_page_30 *get_justlink_ricoh(SCSI *usalp, Uchar *mode)
4097 struct ricoh_mode_page_30 *mp;
4100 if (!get_mode_params(usalp, 0x30, "Ricoh Vendor Page", mode, modec, NULL, NULL, &len)) {
4102 return ((struct ricoh_mode_page_30 *)0);
4107 * SCSI mode header + 6 bytes mode page 30.
4108 * This is including the Burn-Free counter.
4111 return ((struct ricoh_mode_page_30 *)0);
4114 fprintf(stderr, "Mode len: %d\n", len);
4115 usal_prbytes("Mode Sense Data ", mode, len);
4116 usal_prbytes("Mode Sence CData", modec, len);
4119 mp = (struct ricoh_mode_page_30 *)
4120 (mode + sizeof (struct scsi_mode_header) +
4121 ((struct scsi_mode_header *)mode)->blockdesc_len);
4124 * 6 bytes mode page 30.
4125 * This is including the Burn-Free counter.
4127 if ((len - ((Uchar *)mp - mode) -1) < 5)
4128 return ((struct ricoh_mode_page_30 *)0);
4131 fprintf(stderr, "Burnfree counter: %d\n", a_to_u_2_byte(mp->link_counter));
4137 force_speed_yamaha(SCSI *usalp, int readspeed, int writespeed)
4139 register struct usal_cmd *scmd = usalp->scmd;
4141 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
4142 scmd->flags = SCG_DISRE_ENA;
4143 scmd->cdb_len = SC_G5_CDBLEN;
4144 scmd->sense_len = CCS_SENSE_LEN;
4145 scmd->cdb.g5_cdb.cmd = 0xBB;
4146 scmd->cdb.g5_cdb.lun = usal_lun(usalp);
4149 i_to_2_byte(&scmd->cdb.g5_cdb.addr[0], 0xFFFF);
4151 i_to_2_byte(&scmd->cdb.g5_cdb.addr[0], readspeed);
4153 i_to_2_byte(&scmd->cdb.g5_cdb.addr[2], 0xFFFF);
4155 i_to_2_byte(&scmd->cdb.g5_cdb.addr[2], writespeed);
4157 scmd->cdb.cmd_cdb[11] = 0x80;
4159 usalp->cmdname = "yamaha force cd speed";
4161 if (usal_cmd(usalp) < 0)
4167 get_tattoo_yamaha(SCSI *usalp, BOOL print, Int32_t *irp, Int32_t *orp)
4176 if (!get_mode_params(usalp, 0x31, "Yamaha Tattoo Page", mode, NULL, NULL, NULL, &len)) {
4183 * SCSI mode header + 16 bytes mode page 31.
4184 * This is including the Burn-Free counter.
4190 (mode + sizeof (struct scsi_mode_header) +
4191 ((struct scsi_mode_header *)mode)->blockdesc_len);
4194 * 10 bytes mode page 31.
4195 * This is including the Burn-Free counter.
4197 if ((len - ((Uchar *)mp - mode) -1) < 10)
4200 ival = a_to_u_3_byte(&mp[4]);
4201 oval = a_to_u_3_byte(&mp[7]);
4208 if (print && ival > 0 && oval > 0) {
4209 printf("DiskT@2 inner r: %d\n", (int)ival);
4210 printf("DiskT@2 outer r: %d\n", (int)oval);
4211 printf("DiskT@2 image size: 3744 x %d pixel.\n",
4212 (int)(oval-ival)+1);
4219 do_tattoo_yamaha(SCSI *usalp, FILE *f)
4225 char *buf = usalp->bufptr;
4226 long bufsize = usalp->maxbuf;
4230 nsecs = bufsize / 2048;
4231 bufsize = nsecs * 2048;
4233 if (!get_tattoo_yamaha(usalp, FALSE, &ival, &oval)) {
4234 errmsgno(EX_BAD, "Cannot get DiskT@2 info.\n");
4238 if (ival == 0 || oval == 0) {
4239 errmsgno(EX_BAD, "DiskT@2 info not valid.\n");
4243 lines = oval - ival + 1;
4244 fsize = filesize(f);
4245 if ((fsize % 3744) != 0 || fsize < (lines*3744)) {
4246 errmsgno(EX_BAD, "Illegal DiskT@2 file size.\n");
4249 if (fsize > (lines*3744))
4253 printf("Starting to write DiskT@2 data.\n");
4254 fillbytes(buf, bufsize, '\0');
4255 if ((amt = fileread(f, buf, bufsize)) <= 0) {
4256 errmsg("DiskT@2 file read error.\n");
4260 if (yamaha_write_buffer(usalp, 1, 0, ival, amt/2048, buf, amt) < 0) {
4261 errmsgno(EX_BAD, "DiskT@2 1st write error.\n");
4264 amt = (amt+2047) / 2048 * 2048;
4268 fillbytes(buf, bufsize, '\0');
4269 if ((amt = fileread(f, buf, bufsize)) <= 0) {
4270 errmsg("DiskT@2 file read error.\n");
4273 amt = (amt+2047) / 2048 * 2048;
4275 if (yamaha_write_buffer(usalp, 1, 0, 0, amt/2048, buf, amt) < 0) {
4276 errmsgno(EX_BAD, "DiskT@2 write error.\n");
4281 if (yamaha_write_buffer(usalp, 1, 0, oval, 0, buf, 0) < 0) {
4282 errmsgno(EX_BAD, "DiskT@2 final error.\n");
4286 wait_unit_ready(usalp, 1000); /* Wait for DiskT@2 */
4287 waitfix_mmc(usalp, 1000); /* Wait for DiskT@2 */
4293 * Yamaha specific version of 'write buffer' that offers an additional
4294 * Parameter Length 'parlen' parameter.
4297 yamaha_write_buffer(SCSI *usalp, int mode, int bufferid, long offset,
4298 long parlen, void *buffer, long buflen)
4300 register struct usal_cmd *scmd = usalp->scmd;
4303 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
4304 scmd->addr = buffer;
4305 scmd->size = buflen;
4306 scmd->flags = SCG_DISRE_ENA;
4307 scmd->cdb_len = SC_G1_CDBLEN;
4308 scmd->sense_len = CCS_SENSE_LEN;
4309 scmd->cdb.g1_cdb.cmd = 0x3B;
4311 CDB = (Uchar *)scmd->cdb.cmd_cdb;
4314 i_to_3_byte(&CDB[3], offset);
4315 i_to_3_byte(&CDB[6], parlen);
4317 usalp->cmdname = "write_buffer";
4319 if (usal_cmd(usalp) >= 0)
4325 dvd_dual_layer_split(SCSI *usalp, cdr_t *dp, long tsize)
4327 unsigned char xb[12];
4330 /* Get the Layer 0 defined data zone*/
4331 if (read_dvd_structure(usalp, (caddr_t)xb, 12, 0, 0, 0x20) >= 0) {
4332 if ((xb[1] | xb[0] << 8) < 13) {
4333 fprintf(stderr, "dvd_dual_layer_split: read_dvd_structure returns invalid data\n");
4337 printf("L0 zone size already set\n");
4340 l0_size = xb[11] | xb[10] << 8 | xb[9] << 16 | xb[8] << 24;
4341 if (tsize < l0_size) {
4342 fprintf(stderr, "track size smaller than one layer, use --force to force burning.");
4345 printf("L0 size: %ld (track size %ld)\n", l0_size, tsize);
4346 l0_size = tsize / 2;
4347 l0_size = l0_size - 1 + 16 - (l0_size - 1) % 16;
4348 printf("New L0 size: %ld\n", l0_size);
4350 memset (xb, 0, sizeof(xb));
4351 xb[1] = sizeof(xb) - 2;
4352 xb[8] = l0_size >> 24;
4353 xb[9] = l0_size >> 16;
4354 xb[10] = l0_size >> 8;
4356 if (send_dvd_structure(usalp, (caddr_t)xb, 12, 0, 0x20)) {
4357 fprintf(stderr, "dvd_dual_layer_split: send_dvd_structure failed, could not set middle zone location.\n");