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_philips.c 1.69 05/05/16 Copyright 1997-2005 J. Schilling */
15 * CDR device implementation for
16 * Philips/Yamaha/Ricoh/Plasmon
18 * Copyright (c) 1997-2005 J. Schilling
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License version 2
23 * as published by the Free Software Foundation.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License along with
31 * this program; see the file COPYING. If not, write to the Free Software
32 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
38 #include <unixstd.h> /* Include sys/types.h to make off_t available */
43 #include <usal/scsireg.h>
44 #include <usal/scsitransp.h>
45 #include <usal/usalcmd.h>
46 #include <usal/scsidefs.h> /* XXX Only for DEV_RICOH_RO_1060C */
53 static int load_unload_philips(SCSI *usalp, int);
54 static int philips_load(SCSI *usalp, cdr_t *dp);
55 static int philips_unload(SCSI *usalp, cdr_t *dp);
56 static int philips_dumbload(SCSI *usalp, cdr_t *dp);
57 static int philips_dumbunload(SCSI *usalp, cdr_t *dp);
58 static int plasmon_buf(SCSI *, long *, long *);
59 static int recover_philips(SCSI *usalp, cdr_t *dp, int);
60 static int speed_select_yamaha(SCSI *usalp, cdr_t *dp, int *speedp);
61 static int speed_select_philips(SCSI *usalp, cdr_t *dp, int *speedp);
62 static int speed_select_oldphilips(SCSI *usalp, cdr_t *dp, int *speedp);
63 static int speed_select_dumbphilips(SCSI *usalp, cdr_t *dp, int *speedp);
64 static int speed_select_pioneer(SCSI *usalp, cdr_t *dp, int *speedp);
65 static int philips_init(SCSI *usalp, cdr_t *dp);
66 static int philips_getdisktype(SCSI *usalp, cdr_t *dp);
67 static BOOL capacity_philips(SCSI *usalp, long *lp);
68 static int first_writable_addr_philips(SCSI *usalp, long *, int, int, int,
70 static int next_wr_addr_philips(SCSI *usalp, track_t *trackp, long *ap);
71 static int reserve_track_philips(SCSI *usalp, unsigned long);
72 static int scsi_cdr_write_philips(SCSI *usalp, caddr_t bp, long sectaddr,
73 long size, int blocks, BOOL islast);
74 static int write_track_info_philips(SCSI *usalp, int);
75 static int write_track_philips(SCSI *usalp, long, int);
76 static int open_track_philips(SCSI *usalp, cdr_t *dp, track_t *trackp);
77 static int open_track_plasmon(SCSI *usalp, cdr_t *dp, track_t *trackp);
78 static int open_track_oldphilips(SCSI *usalp, cdr_t *dp, track_t *trackp);
79 static int open_track_yamaha(SCSI *usalp, cdr_t *dp, track_t *trackp);
80 static int close_track_philips(SCSI *usalp, cdr_t *dp, track_t *trackp);
81 static int fixation_philips(SCSI *usalp, cdr_t *dp, track_t *trackp);
83 static int philips_attach(SCSI *usalp, cdr_t *);
84 static int plasmon_attach(SCSI *usalp, cdr_t *);
85 static int ricoh_attach(SCSI *usalp, cdr_t *);
86 static int philips_getlilo(SCSI *usalp, long *lilenp, long *lolenp);
89 struct cdd_52x_mode_page_21 { /* write track information */
90 MP_P_CODE; /* parsave & pagecode */
91 Uchar p_len; /* 0x0E = 14 Bytes */
99 struct cdd_52x_mode_page_23 { /* speed selection */
100 MP_P_CODE; /* parsave & pagecode */
101 Uchar p_len; /* 0x06 = 6 Bytes */
108 #if defined(_BIT_FIELDS_LTOH) /* Intel byteorder */
110 struct yamaha_mode_page_31 { /* drive configuration */
111 MP_P_CODE; /* parsave & pagecode */
112 Uchar p_len; /* 0x02 = 2 Bytes */
118 #else /* Motorola byteorder */
120 struct yamaha_mode_page_31 { /* drive configuration */
121 MP_P_CODE; /* parsave & pagecode */
122 Uchar p_len; /* 0x02 = 2 Bytes */
129 struct cdd_52x_mode_data {
130 struct scsi_mode_header header;
132 struct cdd_52x_mode_page_21 page21;
133 struct cdd_52x_mode_page_23 page23;
134 struct yamaha_mode_page_31 page31;
139 cdr_t cdr_philips_cdd521O = {
141 CDR_TAO|CDR_TRAYLOAD,
144 "philips_cdd521_old",
145 "driver for Philips old CDD-521",
157 speed_select_oldphilips,
159 next_wr_addr_philips,
160 reserve_track_philips,
161 scsi_cdr_write_philips,
162 (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */
164 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
165 open_track_oldphilips,
167 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy,
169 cmd_dummy, /* abort */
170 read_session_offset_philips,
172 cmd_dummy, /* stats */
175 (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */
176 cmd_dummy, /* opt1 */
177 cmd_dummy, /* opt2 */
180 cdr_t cdr_philips_dumb = {
182 CDR_TAO|CDR_TRAYLOAD,
186 "driver for Philips CDD-521 with pessimistic assumptions",
198 speed_select_dumbphilips,
200 next_wr_addr_philips,
201 reserve_track_philips,
202 scsi_cdr_write_philips,
203 (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */
205 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
206 open_track_oldphilips,
208 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy,
210 cmd_dummy, /* abort */
211 read_session_offset_philips,
213 cmd_dummy, /* stats */
216 (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */
217 cmd_dummy, /* opt1 */
218 cmd_dummy, /* opt2 */
221 cdr_t cdr_philips_cdd521 = {
223 CDR_TAO|CDR_TRAYLOAD,
227 "driver for Philips CDD-521",
239 speed_select_philips,
241 next_wr_addr_philips,
242 reserve_track_philips,
243 scsi_cdr_write_philips,
244 (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */
246 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
249 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy,
251 cmd_dummy, /* abort */
252 read_session_offset_philips,
254 cmd_dummy, /* stats */
257 (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */
258 cmd_dummy, /* opt1 */
259 cmd_dummy, /* opt2 */
262 cdr_t cdr_philips_cdd522 = {
264 /* CDR_TAO|CDR_SAO|CDR_TRAYLOAD,*/
265 CDR_TAO|CDR_TRAYLOAD,
269 "driver for Philips CDD-522",
281 speed_select_philips,
283 next_wr_addr_philips,
284 reserve_track_philips,
285 scsi_cdr_write_philips,
286 (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */
288 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
291 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy,
293 cmd_dummy, /* abort */
294 read_session_offset_philips,
296 cmd_dummy, /* stats */
299 (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */
300 cmd_dummy, /* opt1 */
301 cmd_dummy, /* opt2 */
304 cdr_t cdr_tyuden_ew50 = {
306 CDR_TAO|CDR_TRAYLOAD|CDR_SWABAUDIO,
310 "driver for Taiyo Yuden EW-50",
322 speed_select_philips,
324 next_wr_addr_philips,
325 reserve_track_philips,
326 scsi_cdr_write_philips,
327 (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */
329 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
332 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy,
334 cmd_dummy, /* abort */
335 read_session_offset_philips,
337 cmd_dummy, /* stats */
340 (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */
341 cmd_dummy, /* opt1 */
342 cmd_dummy, /* opt2 */
345 cdr_t cdr_kodak_pcd600 = {
347 CDR_TAO|CDR_TRAYLOAD,
351 "driver for Kodak PCD-600",
363 speed_select_philips,
365 next_wr_addr_philips,
366 reserve_track_philips,
367 scsi_cdr_write_philips,
368 (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */
370 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
371 open_track_oldphilips,
373 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy,
375 cmd_dummy, /* abort */
376 read_session_offset_philips,
378 cmd_dummy, /* stats */
381 (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */
382 cmd_dummy, /* opt1 */
383 cmd_dummy, /* opt2 */
386 cdr_t cdr_plasmon_rf4100 = {
388 CDR_TAO|CDR_TRAYLOAD,
392 "driver for Plasmon RF 4100",
404 speed_select_philips,
406 next_wr_addr_philips,
407 reserve_track_philips,
408 scsi_cdr_write_philips,
409 (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */
411 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
414 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy,
416 cmd_dummy, /* abort */
417 read_session_offset_philips,
419 cmd_dummy, /* stats */
422 (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */
423 cmd_dummy, /* opt1 */
424 cmd_dummy, /* opt2 */
427 cdr_t cdr_pioneer_dw_s114x = {
429 CDR_TAO|CDR_TRAYLOAD|CDR_SWABAUDIO,
433 "driver for Pioneer DW-S114X",
445 speed_select_pioneer,
447 next_wr_addr_philips,
448 reserve_track_philips,
449 scsi_cdr_write_philips,
450 (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */
452 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
453 /* open_track_yamaha,*/
454 /*???*/ open_track_oldphilips,
456 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy,
458 cmd_dummy, /* abort */
459 read_session_offset_philips,
461 cmd_dummy, /* stats */
464 (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */
465 cmd_dummy, /* opt1 */
466 cmd_dummy, /* opt2 */
469 cdr_t cdr_yamaha_cdr100 = {
471 /* CDR_TAO|CDR_SAO|CDR_CADDYLOAD|CDR_SWABAUDIO,*/
472 CDR_TAO|CDR_CADDYLOAD|CDR_SWABAUDIO,
476 "driver for Yamaha CDR-100 / CDR-102",
490 next_wr_addr_philips,
491 reserve_track_philips,
492 scsi_cdr_write_philips,
493 (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */
495 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
498 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy,
500 cmd_dummy, /* abort */
501 read_session_offset_philips,
503 cmd_dummy, /* stats */
506 (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */
507 cmd_dummy, /* opt1 */
508 cmd_dummy, /* opt2 */
511 cdr_t cdr_ricoh_ro1060 = {
513 /* CDR_TAO|CDR_SAO|CDR_CADDYLOAD,*/
514 CDR_TAO|CDR_CADDYLOAD,
518 "driver for Ricoh RO-1060C",
532 next_wr_addr_philips,
533 reserve_track_philips,
534 scsi_cdr_write_philips,
535 (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */
537 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
540 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy,
542 cmd_dummy, /* abort */
543 read_session_offset_philips,
545 cmd_dummy, /* stats */
548 (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */
549 cmd_dummy, /* opt1 */
550 cmd_dummy, /* opt2 */
553 cdr_t cdr_ricoh_ro1420 = {
555 /* CDR_TAO|CDR_SAO|CDR_CADDYLOAD,*/
556 CDR_TAO|CDR_CADDYLOAD,
560 "driver for Ricoh RO-1420C",
574 next_wr_addr_philips,
575 reserve_track_philips,
576 scsi_cdr_write_philips,
577 (int(*)(track_t *, void *, BOOL))cmd_dummy, /* gen_cue */
579 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
582 (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy,
584 cmd_dummy, /* abort */
585 read_session_offset_philips,
587 cmd_dummy, /* stats */
590 (int(*)(SCSI *, caddr_t, int, int))NULL, /* no OPC */
591 cmd_dummy, /* opt1 */
592 cmd_dummy, /* opt2 */
596 static int load_unload_philips(SCSI *usalp, int load)
598 register struct usal_cmd *scmd = usalp->scmd;
600 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
601 scmd->flags = SCG_DISRE_ENA;
602 scmd->cdb_len = SC_G1_CDBLEN;
603 scmd->sense_len = CCS_SENSE_LEN;
604 scmd->cdb.g1_cdb.cmd = 0xE7;
605 scmd->cdb.g1_cdb.lun = usal_lun(usalp);
606 scmd->cdb.g1_cdb.count[1] = !load;
608 usalp->cmdname = "philips medium load/unload";
610 if (usal_cmd(usalp) < 0)
616 philips_load(SCSI *usalp, cdr_t *dp)
618 return (load_unload_philips(usalp, 1));
622 philips_unload(SCSI *usalp, cdr_t *dp)
624 return (load_unload_philips(usalp, 0));
628 philips_dumbload(SCSI *usalp, cdr_t *dp)
633 ret = load_unload_philips(usalp, 1);
636 return (scsi_load(usalp, dp));
641 philips_dumbunload(SCSI *usalp, cdr_t *dp)
646 ret = load_unload_philips(usalp, 0);
649 return (scsi_unload(usalp, dp));
654 plasmon_buf(SCSI *usalp,
655 long *sp /* Size pointer */,
656 long *fp /* Free space pointer */)
659 * There's no way to obtain these values from the
660 * Plasmon RF41xx devices. This function stub is only
661 * present to prevent cdrecord.c from calling the READ BUFFER
662 * SCSI cmd which is implemented non standard compliant in
663 * the Plasmon drive. Calling READ BUFFER would only jam the Plasmon
664 * as the non standard implementation in the Plasmon firmware
665 * expects different parameters.
673 return (100); /* 100 % */
677 recover_philips(SCSI *usalp, cdr_t *dp, int track)
679 register struct usal_cmd *scmd = usalp->scmd;
681 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
682 scmd->flags = SCG_DISRE_ENA;
683 scmd->cdb_len = SC_G1_CDBLEN;
684 scmd->sense_len = CCS_SENSE_LEN;
685 scmd->cdb.g1_cdb.cmd = 0xEC;
686 scmd->cdb.g1_cdb.lun = usal_lun(usalp);
688 usalp->cmdname = "philips recover";
690 if (usal_cmd(usalp) < 0)
696 speed_select_yamaha(SCSI *usalp, cdr_t *dp, int *speedp)
698 struct scsi_mode_page_header *mp;
702 struct yamaha_mode_page_31 *xp;
703 struct cdd_52x_mode_data md;
706 BOOL dummy = (dp->cdr_cmdflags & F_DUMMY) != 0;
711 fillbytes((caddr_t)mode, sizeof (mode), '\0');
713 if (!get_mode_params(usalp, page, "Speed/Dummy information",
714 (Uchar *)mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) {
720 mp = (struct scsi_mode_page_header *)
721 (mode + sizeof (struct scsi_mode_header) +
722 ((struct scsi_mode_header *)mode)->blockdesc_len);
724 xp = (struct yamaha_mode_page_31 *)mp;
728 fillbytes((caddr_t)&md, sizeof (md), '\0');
730 count = sizeof (struct scsi_mode_header) +
731 sizeof (struct yamaha_mode_page_31);
734 md.pagex.page31.p_code = 0x31;
735 md.pagex.page31.p_len = 0x02;
736 md.pagex.page31.speed = speed;
737 md.pagex.page31.dummy = dummy?1:0;
739 return (mode_select(usalp, (Uchar *)&md, count, 0, usalp->inq->data_format >= 2));
743 speed_select_philips(SCSI *usalp, cdr_t *dp, int *speedp)
745 struct scsi_mode_page_header *mp;
749 struct cdd_52x_mode_page_23 *xp;
750 struct cdd_52x_mode_data md;
753 BOOL dummy = (dp->cdr_cmdflags & F_DUMMY) != 0;
758 fillbytes((caddr_t)mode, sizeof (mode), '\0');
760 if (!get_mode_params(usalp, page, "Speed/Dummy information",
761 (Uchar *)mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) {
767 mp = (struct scsi_mode_page_header *)
768 (mode + sizeof (struct scsi_mode_header) +
769 ((struct scsi_mode_header *)mode)->blockdesc_len);
771 xp = (struct cdd_52x_mode_page_23 *)mp;
775 fillbytes((caddr_t)&md, sizeof (md), '\0');
777 count = sizeof (struct scsi_mode_header) +
778 sizeof (struct cdd_52x_mode_page_23);
780 md.pagex.page23.p_code = 0x23;
781 md.pagex.page23.p_len = 0x06;
782 md.pagex.page23.speed = speed;
783 md.pagex.page23.dummy = dummy?1:0;
785 return (mode_select(usalp, (Uchar *)&md, count, 0, usalp->inq->data_format >= 2));
789 speed_select_pioneer(SCSI *usalp, cdr_t *dp, int *speedp)
791 if (speedp != 0 && *speedp < 2) {
794 printf("WARNING: setting to minimum speed (2).\n");
796 return (speed_select_philips(usalp, dp, speedp));
800 speed_select_oldphilips(SCSI *usalp, cdr_t *dp, int *speedp)
802 BOOL dummy = (dp->cdr_cmdflags & F_DUMMY) != 0;
805 printf("WARNING: ignoring selected speed.\n");
807 errmsgno(EX_BAD, "Cannot set dummy writing for this device.\n");
814 speed_select_dumbphilips(SCSI *usalp, cdr_t *dp, int *speedp)
816 if (speed_select_philips(usalp, dp, speedp) < 0)
817 return (speed_select_oldphilips(usalp, dp, speedp));
822 philips_init(SCSI *usalp, cdr_t *dp)
824 return ((*dp->cdr_set_speed_dummy)(usalp, dp, NULL));
828 #define IS(what, flag) printf(" Is %s%s\n", flag?"":"not ", what);
831 philips_getdisktype(SCSI *usalp, cdr_t *dp)
833 dstat_t *dsp = dp->cdr_dstat;
842 dummy = (*dp->cdr_next_wr_address)(usalp, (track_t *)0, &lilen);
846 * Check for "Command sequence error" first.
848 if ((dsp->ds_cdrflags & RF_WRITE) != 0 &&
850 (usal_sense_key(usalp) != SC_ILLEGAL_REQUEST ||
851 usal_sense_code(usalp) != 0x2C)) {
852 reload_media(usalp, dp);
856 if (read_subchannel(usalp, sbuf, 0, 12, 0, 1, 0xf0) >= 0) {
857 if (sbuf[2] == 0 && sbuf[3] == 8)
858 audio = (sbuf[7] & 0x40) != 0;
862 if ((dp->cdr_dstat->ds_cdrflags & RF_PRATIP) != 0 &&
863 dummy >= 0 && lilen == 0) {
865 dummy = philips_getlilo(usalp, &lilen, &lolen);
869 /* printf("lead-in len: %d lead-out len: %d\n", lilen, lolen);*/
870 lba_to_msf(-150 - lilen, &msf);
872 printf("ATIP info from disk:\n");
874 IS("unrestricted", audio);
875 if (audio == 1 || (audio == 0 && (sbuf[7] & 0x3F) != 0x3F))
876 printf(" Disk application code: %d\n", sbuf[7] & 0x3F);
877 printf(" ATIP start of lead in: %ld (%02d:%02d/%02d)\n",
878 -150 - lilen, msf.msf_min, msf.msf_sec, msf.msf_frame);
880 if (capacity_philips(usalp, &lolen)) {
881 lba_to_msf(lolen, &msf);
883 " ATIP start of lead out: %ld (%02d:%02d/%02d)\n",
884 lolen, msf.msf_min, msf.msf_sec, msf.msf_frame);
886 lba_to_msf(-150 - lilen, &msf);
887 pr_manufacturer(&msf,
888 FALSE, /* Always not erasable */
889 audio > 0); /* Audio from read subcode */
893 if (capacity_philips(usalp, &lolen)) {
894 dsp->ds_maxblocks = lolen;
895 dsp->ds_maxrblocks = disk_rcap(&msf, dsp->ds_maxblocks,
896 FALSE, /* Always not erasable */
897 audio > 0); /* Audio from read subcode */
900 /*read_subchannel(usalp, bp, track, cnt, msf, subq, fmt); */
902 if (read_subchannel(usalp, sbuf, 0, 14, 0, 0, 0xf1) >= 0)
903 usal_prbytes("Disk bar code:", (Uchar *)sbuf, 14 - usal_getresid(usalp));
906 return (drive_getdisktype(usalp, dp));
910 capacity_philips(SCSI *usalp, long *lp)
916 if (read_B0(usalp, FALSE, NULL, &l) >= 0) {
918 printf("lead out B0: %ld\n", l);
920 } else if (read_trackinfo(usalp, 0xAA, &l, NULL, NULL, NULL, NULL) >= 0) {
922 printf("lead out AA: %ld\n", l);
924 } if (read_capacity(usalp) >= 0) {
925 l = usalp->cap->c_baddr + 1;
927 printf("lead out capacity: %ld\n", l);
943 first_writable_addr_philips(SCSI *usalp, long *ap, int track, int isaudio,
947 register struct usal_cmd *scmd = usalp->scmd;
949 fillbytes((caddr_t)&fwa, sizeof (fwa), '\0');
950 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
951 scmd->addr = (caddr_t)&fwa;
952 scmd->size = sizeof (fwa);
953 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
954 scmd->cdb_len = SC_G1_CDBLEN;
955 scmd->sense_len = CCS_SENSE_LEN;
956 scmd->cdb.g1_cdb.cmd = 0xE2;
957 scmd->cdb.g1_cdb.lun = usal_lun(usalp);
958 scmd->cdb.g1_cdb.addr[0] = track;
959 scmd->cdb.g1_cdb.addr[1] = isaudio ? (preemp ? 5 : 4) : 1;
961 scmd->cdb.g1_cdb.count[0] = npa?1:0;
962 scmd->cdb.g1_cdb.count[1] = sizeof (fwa);
964 usalp->cmdname = "first writeable address philips";
966 if (usal_cmd(usalp) < 0)
970 *ap = a_to_4_byte(fwa.addr);
975 next_wr_addr_philips(SCSI *usalp, track_t *trackp, long *ap)
978 /* if (first_writable_addr_philips(usalp, ap, 0, 0, 0, 1) < 0)*/
979 if (first_writable_addr_philips(usalp, ap, 0, 0, 0, 0) < 0)
985 reserve_track_philips(SCSI *usalp, unsigned long len)
987 register struct usal_cmd *scmd = usalp->scmd;
989 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
990 scmd->flags = SCG_DISRE_ENA;
991 scmd->cdb_len = SC_G1_CDBLEN;
992 scmd->sense_len = CCS_SENSE_LEN;
993 scmd->cdb.g1_cdb.cmd = 0xE4;
994 scmd->cdb.g1_cdb.lun = usal_lun(usalp);
995 i_to_4_byte(&scmd->cdb.g1_cdb.addr[3], len);
997 usalp->cmdname = "philips reserve_track";
999 if (usal_cmd(usalp) < 0)
1005 scsi_cdr_write_philips(SCSI *usalp,
1006 caddr_t bp /* address of buffer */,
1007 long sectaddr /* disk address (sector) to put */,
1008 long size /* number of bytes to transfer */,
1009 int blocks /* sector count */,
1010 BOOL islast /* last write for track */)
1012 return (write_xg0(usalp, bp, 0, size, blocks));
1016 write_track_info_philips(SCSI *usalp, int sectype)
1018 struct cdd_52x_mode_data md;
1019 int count = sizeof (struct scsi_mode_header) +
1020 sizeof (struct cdd_52x_mode_page_21);
1022 fillbytes((caddr_t)&md, sizeof (md), '\0');
1023 md.pagex.page21.p_code = 0x21;
1024 md.pagex.page21.p_len = 0x0E;
1025 /* is sectype ok ??? */
1026 md.pagex.page21.sectype = sectype & ST_MASK;
1027 md.pagex.page21.track = 0; /* 0 : create new track */
1029 return (mode_select(usalp, (Uchar *)&md, count, 0, usalp->inq->data_format >= 2));
1033 write_track_philips(SCSI *usalp,
1034 long track /* track number 0 == new track */,
1037 register struct usal_cmd *scmd = usalp->scmd;
1039 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
1040 scmd->flags = SCG_DISRE_ENA|SCG_CMD_RETRY;
1041 /* scmd->flags = SCG_DISRE_ENA;*/
1042 scmd->cdb_len = SC_G1_CDBLEN;
1043 scmd->sense_len = CCS_SENSE_LEN;
1044 scmd->cdb.g1_cdb.cmd = 0xE6;
1045 scmd->cdb.g1_cdb.lun = usal_lun(usalp);
1046 g1_cdbaddr(&scmd->cdb.g1_cdb, track);
1047 scmd->cdb.g1_cdb.res6 = sectype & ST_MASK;
1049 usalp->cmdname = "philips write_track";
1051 if (usal_cmd(usalp) < 0)
1057 open_track_philips(SCSI *usalp, cdr_t *dp, track_t *trackp)
1059 if (select_secsize(usalp, trackp->secsize) < 0)
1062 if (write_track_info_philips(usalp, trackp->sectype) < 0)
1065 if (write_track_philips(usalp, 0, trackp->sectype) < 0)
1072 open_track_plasmon(SCSI *usalp, cdr_t *dp, track_t *trackp)
1074 if (select_secsize(usalp, trackp->secsize) < 0)
1077 if (write_track_info_philips(usalp, trackp->sectype) < 0)
1084 open_track_oldphilips(SCSI *usalp, cdr_t *dp, track_t *trackp)
1086 if (write_track_philips(usalp, 0, trackp->sectype) < 0)
1093 open_track_yamaha(SCSI *usalp, cdr_t *dp, track_t *trackp)
1095 if (select_secsize(usalp, trackp->secsize) < 0)
1098 if (write_track_philips(usalp, 0, trackp->sectype) < 0)
1105 close_track_philips(SCSI *usalp, cdr_t *dp, track_t *trackp)
1107 return (scsi_flush_cache(usalp, FALSE));
1110 static int fixation_philips(SCSI *usalp, cdr_t *dp, track_t *trackp)
1112 register struct usal_cmd *scmd = usalp->scmd;
1114 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
1115 scmd->flags = SCG_DISRE_ENA;
1116 scmd->cdb_len = SC_G1_CDBLEN;
1117 scmd->sense_len = CCS_SENSE_LEN;
1118 scmd->timeout = 8 * 60; /* Needs up to 4 minutes */
1119 scmd->cdb.g1_cdb.cmd = 0xE9;
1120 scmd->cdb.g1_cdb.lun = usal_lun(usalp);
1121 scmd->cdb.g1_cdb.count[1] =
1122 ((track_base(trackp)->tracktype & TOCF_MULTI) ? 8 : 0) |
1123 (track_base(trackp)->tracktype & TOC_MASK);
1125 usalp->cmdname = "philips fixation";
1127 if (usal_cmd(usalp) < 0)
1132 static const char *sd_cdd_521_error_str[] = {
1133 "\003\000tray out", /* 0x03 */
1134 "\062\000write data error with CU", /* 0x32 */ /* Yamaha */
1135 "\063\000monitor atip error", /* 0x33 */
1136 "\064\000absorbtion control error", /* 0x34 */
1137 #ifdef YAMAHA_CDR_100
1138 /* Is this the same ??? */
1139 "\120\000write operation in progress", /* 0x50 */
1141 "\127\000unable to read TOC/PMA/Subcode/ATIP", /* 0x57 */
1142 "\132\000operator medium removal request", /* 0x5a */
1143 "\145\000verify failed", /* 0x65 */
1144 "\201\000illegal track number", /* 0x81 */
1145 "\202\000command now not valid", /* 0x82 */
1146 "\203\000medium removal is prevented", /* 0x83 */
1147 "\204\000tray out", /* 0x84 */
1148 "\205\000track at one not in PMA", /* 0x85 */
1149 "\240\000stopped on non data block", /* 0xa0 */
1150 "\241\000invalid start adress", /* 0xa1 */
1151 "\242\000attampt to cross track-boundary", /* 0xa2 */
1152 "\243\000illegal medium", /* 0xa3 */
1153 "\244\000disk write protected", /* 0xa4 */
1154 "\245\000application code conflict", /* 0xa5 */
1155 "\246\000illegal blocksize for command", /* 0xa6 */
1156 "\247\000blocksize conflict", /* 0xa7 */
1157 "\250\000illegal transfer length", /* 0xa8 */
1158 "\251\000request for fixation failed", /* 0xa9 */
1159 "\252\000end of medium reached", /* 0xaa */
1161 "\253\000non reserved reserved track", /* 0xab */
1163 "\253\000illegal track number", /* 0xab */
1165 "\254\000data track length error", /* 0xac */
1166 "\255\000buffer under run", /* 0xad */
1167 "\256\000illegal track mode", /* 0xae */
1168 "\257\000optical power calibration error", /* 0xaf */
1169 "\260\000calibration area almost full", /* 0xb0 */
1170 "\261\000current program area empty", /* 0xb1 */
1171 "\262\000no efm at search address", /* 0xb2 */
1172 "\263\000link area encountered", /* 0xb3 */
1173 "\264\000calibration area full", /* 0xb4 */
1174 "\265\000dummy data blocks added", /* 0xb5 */
1175 "\266\000block size format conflict", /* 0xb6 */
1176 "\267\000current command aborted", /* 0xb7 */
1177 "\270\000program area not empty", /* 0xb8 */
1178 #ifdef YAMAHA_CDR_100
1179 /* Used while writing lead in in DAO */
1180 "\270\000write leadin in progress", /* 0xb8 */
1182 "\271\000parameter list too large", /* 0xb9 */
1183 "\277\000buffer overflow", /* 0xbf */ /* Yamaha */
1184 "\300\000no barcode available", /* 0xc0 */
1185 "\301\000barcode reading error", /* 0xc1 */
1186 "\320\000recovery needed", /* 0xd0 */
1187 "\321\000cannot recover track", /* 0xd1 */
1188 "\322\000cannot recover pma", /* 0xd2 */
1189 "\323\000cannot recover leadin", /* 0xd3 */
1190 "\324\000cannot recover leadout", /* 0xd4 */
1191 "\325\000cannot recover opc", /* 0xd5 */
1192 "\326\000eeprom failure", /* 0xd6 */
1193 "\340\000laser current over", /* 0xe0 */ /* Yamaha */
1194 "\341\000servo adjustment over", /* 0xe0 */ /* Yamaha */
1198 static const char *sd_ro1420_error_str[] = {
1199 "\004\000logical unit is in process of becoming ready", /* 04 00 */
1200 "\011\200radial skating error", /* 09 80 */
1201 "\011\201sledge servo failure", /* 09 81 */
1202 "\011\202pll no lock", /* 09 82 */
1203 "\011\203servo off track", /* 09 83 */
1204 "\011\204atip sync error", /* 09 84 */
1205 "\011\205atip/subcode jumped error", /* 09 85 */
1206 "\127\300subcode not found", /* 57 C0 */
1207 "\127\301atip not found", /* 57 C1 */
1208 "\127\302no atip or subcode", /* 57 C2 */
1209 "\127\303pma error", /* 57 C3 */
1210 "\127\304toc read error", /* 57 C4 */
1211 "\127\305disk informatoion error", /* 57 C5 */
1212 "\144\200read in leadin", /* 64 80 */
1213 "\144\201read in leadout", /* 64 81 */
1214 "\201\000illegal track", /* 81 00 */
1215 "\202\000command not now valid", /* 82 00 */
1216 "\220\000reserve track check error", /* 90 00 */
1217 "\220\001verify blank error", /* 90 01 */
1218 "\221\001mode of last track error", /* 91 01 */
1219 "\222\000header search error", /* 92 00 */
1220 "\230\001header monitor error", /* 98 01 */
1221 "\230\002edc error", /* 98 02 */
1222 "\230\003read link, run-in run-out", /* 98 03 */
1223 "\230\004last one block error", /* 98 04 */
1224 "\230\005illegal blocksize", /* 98 05 */
1225 "\230\006not all data transferred", /* 98 06 */
1226 "\230\007cdbd over run error", /* 98 07 */
1227 "\240\000stopped on non_data block", /* A0 00 */
1228 "\241\000invalid start address", /* A1 00 */
1229 "\243\000illegal medium", /* A3 00 */
1230 "\246\000illegal blocksize for command", /* A6 00 */
1231 "\251\000request for fixation failed", /* A9 00 */
1232 "\252\000end of medium reached", /* AA 00 */
1233 "\253\000illegal track number", /* AB 00 */
1234 "\255\000buffer underrun", /* AD 00 */
1235 "\256\000illegal track mode", /* AE 00 */
1236 "\257\200power range error", /* AF 80 */
1237 "\257\201moderation error", /* AF 81 */
1238 "\257\202beta upper range error", /* AF 82 */
1239 "\257\203beta lower range error", /* AF 83 */
1240 "\257\204alpha upper range error", /* AF 84 */
1241 "\257\205alpha lower range error", /* AF 85 */
1242 "\257\206alpha and power range error", /* AF 86 */
1243 "\260\000calibration area almost full", /* B0 00 */
1244 "\261\000current program area empty", /* B1 00 */
1245 "\262\000no efm at search address", /* B2 00 */
1246 "\264\000calibration area full", /* B4 00 */
1247 "\265\000dummy blocks added", /* B5 00 */
1248 "\272\000write audio on reserved track", /* BA 00 */
1249 "\302\200syscon rom error", /* C2 80 */
1250 "\302\201syscon ram error", /* C2 81 */
1251 "\302\220efm encoder error", /* C2 90 */
1252 "\302\221efm decoder error", /* C2 91 */
1253 "\302\222servo ic error", /* C2 92 */
1254 "\302\223motor controller error", /* C2 93 */
1255 "\302\224dac error", /* C2 94 */
1256 "\302\225syscon eeprom error", /* C2 95 */
1257 "\302\240block decoder communication error", /* C2 A0 */
1258 "\302\241block encoder communication error", /* C2 A1 */
1259 "\302\242block encoder/decoder path error", /* C2 A2 */
1260 "\303\000CD-R engine selftest error", /* C3 xx */
1261 "\304\000buffer parity error", /* C4 00 */
1262 "\305\000data transfer error", /* C5 00 */
1263 "\340\00012V failure", /* E0 00 */
1264 "\341\000undefined syscon error", /* E1 00 */
1265 "\341\001syscon communication error", /* E1 01 */
1266 "\341\002unknown syscon error", /* E1 02 */
1267 "\342\000syscon not ready", /* E2 00 */
1268 "\343\000command rejected", /* E3 00 */
1269 "\344\000command not accepted", /* E4 00 */
1270 "\345\000verify error at beginning of track", /* E5 00 */
1271 "\345\001verify error at ending of track", /* E5 01 */
1272 "\345\002verify error at beginning of lead-in", /* E5 02 */
1273 "\345\003verify error at ending of lead-in", /* E5 03 */
1274 "\345\004verify error at beginning of lead-out", /* E5 04 */
1275 "\345\005verify error at ending of lead-out", /* E5 05 */
1276 "\377\000command phase timeout error", /* FF 00 */
1277 "\377\001data in phase timeout error", /* FF 01 */
1278 "\377\002data out phase timeout error", /* FF 02 */
1279 "\377\003status phase timeout error", /* FF 03 */
1280 "\377\004message in phase timeout error", /* FF 04 */
1281 "\377\005message out phase timeout error", /* FF 05 */
1286 philips_attach(SCSI *usalp, cdr_t *dp)
1288 usal_setnonstderrs(usalp, sd_cdd_521_error_str);
1293 plasmon_attach(SCSI *usalp, cdr_t *dp)
1295 usalp->inq->data_format = 1; /* Correct the ly */
1297 usal_setnonstderrs(usalp, sd_cdd_521_error_str);
1302 ricoh_attach(SCSI *usalp, cdr_t *dp)
1304 if (dp == &cdr_ricoh_ro1060) {
1305 errmsgno(EX_BAD, "No support for Ricoh RO-1060C\n");
1308 usal_setnonstderrs(usalp, sd_ro1420_error_str);
1313 philips_getlilo(SCSI *usalp, long *lilenp, long *lolenp)
1317 register struct usal_cmd *scmd = usalp->scmd;
1319 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
1321 scmd->size = sizeof (buf);
1322 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
1323 scmd->cdb_len = SC_G1_CDBLEN;
1324 scmd->sense_len = CCS_SENSE_LEN;
1325 scmd->cdb.g1_cdb.cmd = 0xEE; /* Read session info */
1326 scmd->cdb.g1_cdb.lun = usal_lun(usalp);
1327 g1_cdblen(&scmd->cdb.g1_cdb, sizeof (buf));
1329 usalp->cmdname = "philips read session info";
1331 if (usal_cmd(usalp) < 0)
1335 usal_prbytes("Session info data: ", (Uchar *)buf, sizeof (buf) - usal_getresid(usalp));
1337 li = a_to_u_2_byte(buf);
1338 lo = a_to_u_2_byte(&buf[2]);