Imported Upstream version 1.1.11
[platform/upstream/cdrkit.git] / wodim / drv_philips.c
1 /*
2  * This file has been modified for the cdrkit suite.
3  *
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).
6  *
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.
10  *
11  */
12
13 /* @(#)drv_philips.c    1.69 05/05/16 Copyright 1997-2005 J. Schilling */
14 /*
15  *      CDR device implementation for
16  *      Philips/Yamaha/Ricoh/Plasmon
17  *
18  *      Copyright (c) 1997-2005 J. Schilling
19  */
20 /*
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.
24  *
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.
29  *
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.
33  */
34
35 #include <mconfig.h>
36
37 #include <stdio.h>
38 #include <unixstd.h>    /* Include sys/types.h to make off_t available */
39 #include <standard.h>
40 #include <intcvt.h>
41 #include <schily.h>
42
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 */
47
48 #include "wodim.h"
49
50 extern  int     debug;
51 extern  int     lverbose;
52
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, 
69                                                                                                                  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);
82
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);
87
88
89 struct cdd_52x_mode_page_21 {   /* write track information */
90                 MP_P_CODE;              /* parsave & pagecode */
91         Uchar   p_len;                  /* 0x0E = 14 Bytes */
92         Uchar   res_2;
93         Uchar   sectype;
94         Uchar   track;
95         Uchar   ISRC[9];
96         Uchar   res[2];
97 };
98
99 struct cdd_52x_mode_page_23 {   /* speed selection */
100                 MP_P_CODE;              /* parsave & pagecode */
101         Uchar   p_len;                  /* 0x06 = 6 Bytes */
102         Uchar   speed;
103         Uchar   dummy;
104         Uchar   res[4];
105
106 };
107
108 #if defined(_BIT_FIELDS_LTOH)   /* Intel byteorder */
109
110 struct yamaha_mode_page_31 {    /* drive configuration */
111                 MP_P_CODE;              /* parsave & pagecode */
112         Uchar   p_len;                  /* 0x02 = 2 Bytes */
113         Uchar   res;
114         Ucbit   dummy           : 4;
115         Ucbit   speed           : 4;
116 };
117
118 #else                           /* Motorola byteorder */
119
120 struct yamaha_mode_page_31 {    /* drive configuration */
121                 MP_P_CODE;              /* parsave & pagecode */
122         Uchar   p_len;                  /* 0x02 = 2 Bytes */
123         Uchar   res;
124         Ucbit   speed           : 4;
125         Ucbit   dummy           : 4;
126 };
127 #endif
128
129 struct cdd_52x_mode_data {
130         struct scsi_mode_header header;
131         union cdd_pagex {
132                 struct cdd_52x_mode_page_21     page21;
133                 struct cdd_52x_mode_page_23     page23;
134                 struct yamaha_mode_page_31      page31;
135         } pagex;
136 };
137
138
139 cdr_t   cdr_philips_cdd521O = {
140         0, 0,
141         CDR_TAO|CDR_TRAYLOAD,
142         CDR_CDRW_NONE,
143         2, 2,
144         "philips_cdd521_old",
145         "driver for Philips old CDD-521",
146         0,
147         (dstat_t *)0,
148         drive_identify,
149         philips_attach,
150         philips_init,
151         philips_getdisktype,
152         philips_load,
153         philips_unload,
154         buf_dummy,
155         recovery_needed,
156         recover_philips,
157         speed_select_oldphilips,
158         select_secsize,
159         next_wr_addr_philips,
160         reserve_track_philips,
161         scsi_cdr_write_philips,
162         (int(*)(track_t *, void *, BOOL))cmd_dummy,     /* gen_cue */
163         no_sendcue,
164         (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
165         open_track_oldphilips,
166         close_track_philips,
167         (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy,
168         cmd_dummy,
169         cmd_dummy,                                      /* abort        */
170         read_session_offset_philips,
171         fixation_philips,
172         cmd_dummy,                                      /* stats        */
173         blank_dummy,
174         format_dummy,
175         (int(*)(SCSI *, caddr_t, int, int))NULL,        /* no OPC       */
176         cmd_dummy,                                      /* opt1         */
177         cmd_dummy,                                      /* opt2         */
178 };
179
180 cdr_t   cdr_philips_dumb = {
181         0, 0,
182         CDR_TAO|CDR_TRAYLOAD,
183         CDR_CDRW_NONE,
184         2, 2,
185         "philips_dumb",
186         "driver for Philips CDD-521 with pessimistic assumptions",
187         0,
188         (dstat_t *)0,
189         drive_identify,
190         philips_attach,
191         philips_init,
192         philips_getdisktype,
193         philips_dumbload,
194         philips_dumbunload,
195         buf_dummy,
196         recovery_needed,
197         recover_philips,
198         speed_select_dumbphilips,
199         select_secsize,
200         next_wr_addr_philips,
201         reserve_track_philips,
202         scsi_cdr_write_philips,
203         (int(*)(track_t *, void *, BOOL))cmd_dummy,     /* gen_cue */
204         no_sendcue,
205         (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
206         open_track_oldphilips,
207         close_track_philips,
208         (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy,
209         cmd_dummy,
210         cmd_dummy,                                      /* abort        */
211         read_session_offset_philips,
212         fixation_philips,
213         cmd_dummy,                                      /* stats        */
214         blank_dummy,
215         format_dummy,
216         (int(*)(SCSI *, caddr_t, int, int))NULL,        /* no OPC       */
217         cmd_dummy,                                      /* opt1         */
218         cmd_dummy,                                      /* opt2         */
219 };
220
221 cdr_t   cdr_philips_cdd521 = {
222         0, 0,
223         CDR_TAO|CDR_TRAYLOAD,
224         CDR_CDRW_NONE,
225         2, 2,
226         "philips_cdd521",
227         "driver for Philips CDD-521",
228         0,
229         (dstat_t *)0,
230         drive_identify,
231         philips_attach,
232         philips_init,
233         philips_getdisktype,
234         philips_load,
235         philips_unload,
236         buf_dummy,
237         recovery_needed,
238         recover_philips,
239         speed_select_philips,
240         select_secsize,
241         next_wr_addr_philips,
242         reserve_track_philips,
243         scsi_cdr_write_philips,
244         (int(*)(track_t *, void *, BOOL))cmd_dummy,     /* gen_cue */
245         no_sendcue,
246         (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
247         open_track_philips,
248         close_track_philips,
249         (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy,
250         cmd_dummy,
251         cmd_dummy,                                      /* abort        */
252         read_session_offset_philips,
253         fixation_philips,
254         cmd_dummy,                                      /* stats        */
255         blank_dummy,
256         format_dummy,
257         (int(*)(SCSI *, caddr_t, int, int))NULL,        /* no OPC       */
258         cmd_dummy,                                      /* opt1         */
259         cmd_dummy,                                      /* opt2         */
260 };
261
262 cdr_t   cdr_philips_cdd522 = {
263         0, 0,
264 /*      CDR_TAO|CDR_SAO|CDR_TRAYLOAD,*/
265         CDR_TAO|CDR_TRAYLOAD,
266         CDR_CDRW_NONE,
267         2, 2,
268         "philips_cdd522",
269         "driver for Philips CDD-522",
270         0,
271         (dstat_t *)0,
272         drive_identify,
273         philips_attach,
274         philips_init,
275         philips_getdisktype,
276         philips_load,
277         philips_unload,
278         buf_dummy,
279         recovery_needed,
280         recover_philips,
281         speed_select_philips,
282         select_secsize,
283         next_wr_addr_philips,
284         reserve_track_philips,
285         scsi_cdr_write_philips,
286         (int(*)(track_t *, void *, BOOL))cmd_dummy,     /* gen_cue */
287         no_sendcue,
288         (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
289         open_track_philips,
290         close_track_philips,
291         (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy,
292         cmd_dummy,
293         cmd_dummy,                                      /* abort        */
294         read_session_offset_philips,
295         fixation_philips,
296         cmd_dummy,                                      /* stats        */
297         blank_dummy,
298         format_dummy,
299         (int(*)(SCSI *, caddr_t, int, int))NULL,        /* no OPC       */
300         cmd_dummy,                                      /* opt1         */
301         cmd_dummy,                                      /* opt2         */
302 };
303
304 cdr_t   cdr_tyuden_ew50 = {
305         0, 0,
306         CDR_TAO|CDR_TRAYLOAD|CDR_SWABAUDIO,
307         CDR_CDRW_NONE,
308         2, 2,
309         "tyuden_ew50",
310         "driver for Taiyo Yuden EW-50",
311         0,
312         (dstat_t *)0,
313         drive_identify,
314         philips_attach,
315         philips_init,
316         philips_getdisktype,
317         philips_load,
318         philips_unload,
319         buf_dummy,
320         recovery_needed,
321         recover_philips,
322         speed_select_philips,
323         select_secsize,
324         next_wr_addr_philips,
325         reserve_track_philips,
326         scsi_cdr_write_philips,
327         (int(*)(track_t *, void *, BOOL))cmd_dummy,     /* gen_cue */
328         no_sendcue,
329         (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
330         open_track_philips,
331         close_track_philips,
332         (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy,
333         cmd_dummy,
334         cmd_dummy,                                      /* abort        */
335         read_session_offset_philips,
336         fixation_philips,
337         cmd_dummy,                                      /* stats        */
338         blank_dummy,
339         format_dummy,
340         (int(*)(SCSI *, caddr_t, int, int))NULL,        /* no OPC       */
341         cmd_dummy,                                      /* opt1         */
342         cmd_dummy,                                      /* opt2         */
343 };
344
345 cdr_t   cdr_kodak_pcd600 = {
346         0, 0,
347         CDR_TAO|CDR_TRAYLOAD,
348         CDR_CDRW_NONE,
349         6, 6,
350         "kodak_pcd_600",
351         "driver for Kodak PCD-600",
352         0,
353         (dstat_t *)0,
354         drive_identify,
355         philips_attach,
356         philips_init,
357         philips_getdisktype,
358         philips_load,
359         philips_unload,
360         buf_dummy,
361         recovery_needed,
362         recover_philips,
363         speed_select_philips,
364         select_secsize,
365         next_wr_addr_philips,
366         reserve_track_philips,
367         scsi_cdr_write_philips,
368         (int(*)(track_t *, void *, BOOL))cmd_dummy,     /* gen_cue */
369         no_sendcue,
370         (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
371         open_track_oldphilips,
372         close_track_philips,
373         (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy,
374         cmd_dummy,
375         cmd_dummy,                                      /* abort        */
376         read_session_offset_philips,
377         fixation_philips,
378         cmd_dummy,                                      /* stats        */
379         blank_dummy,
380         format_dummy,
381         (int(*)(SCSI *, caddr_t, int, int))NULL,        /* no OPC       */
382         cmd_dummy,                                      /* opt1         */
383         cmd_dummy,                                      /* opt2         */
384 };
385
386 cdr_t   cdr_plasmon_rf4100 = {
387         0, 0,
388         CDR_TAO|CDR_TRAYLOAD,
389         CDR_CDRW_NONE,
390         2, 4,
391         "plasmon_rf4100",
392         "driver for Plasmon RF 4100",
393         0,
394         (dstat_t *)0,
395         drive_identify,
396         plasmon_attach,
397         philips_init,
398         philips_getdisktype,
399         philips_load,
400         philips_unload,
401         plasmon_buf,
402         recovery_needed,
403         recover_philips,
404         speed_select_philips,
405         select_secsize,
406         next_wr_addr_philips,
407         reserve_track_philips,
408         scsi_cdr_write_philips,
409         (int(*)(track_t *, void *, BOOL))cmd_dummy,     /* gen_cue */
410         no_sendcue,
411         (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
412         open_track_plasmon,
413         close_track_philips,
414         (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy,
415         cmd_dummy,
416         cmd_dummy,                                      /* abort        */
417         read_session_offset_philips,
418         fixation_philips,
419         cmd_dummy,                                      /* stats        */
420         blank_dummy,
421         format_dummy,
422         (int(*)(SCSI *, caddr_t, int, int))NULL,        /* no OPC       */
423         cmd_dummy,                                      /* opt1         */
424         cmd_dummy,                                      /* opt2         */
425 };
426
427 cdr_t   cdr_pioneer_dw_s114x = {
428         0, 0,
429         CDR_TAO|CDR_TRAYLOAD|CDR_SWABAUDIO,
430         CDR_CDRW_NONE,
431         2, 4,
432         "pioneer_dws114x",
433         "driver for Pioneer DW-S114X",
434         0,
435         (dstat_t *)0,
436         drive_identify,
437         philips_attach,
438         philips_init,
439         philips_getdisktype,
440         scsi_load,
441         scsi_unload,
442         buf_dummy,
443         recovery_needed,
444         recover_philips,
445         speed_select_pioneer,
446         select_secsize,
447         next_wr_addr_philips,
448         reserve_track_philips,
449         scsi_cdr_write_philips,
450         (int(*)(track_t *, void *, BOOL))cmd_dummy,     /* gen_cue */
451         no_sendcue,
452         (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
453 /*      open_track_yamaha,*/
454 /*???*/ open_track_oldphilips,
455         close_track_philips,
456         (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy,
457         cmd_dummy,
458         cmd_dummy,                                      /* abort        */
459         read_session_offset_philips,
460         fixation_philips,
461         cmd_dummy,                                      /* stats        */
462         blank_dummy,
463         format_dummy,
464         (int(*)(SCSI *, caddr_t, int, int))NULL,        /* no OPC       */
465         cmd_dummy,                                      /* opt1         */
466         cmd_dummy,                                      /* opt2         */
467 };
468
469 cdr_t   cdr_yamaha_cdr100 = {
470         0, 0,
471 /*      CDR_TAO|CDR_SAO|CDR_CADDYLOAD|CDR_SWABAUDIO,*/
472         CDR_TAO|CDR_CADDYLOAD|CDR_SWABAUDIO,
473         CDR_CDRW_NONE,
474         2, 4,
475         "yamaha_cdr100",
476         "driver for Yamaha CDR-100 / CDR-102",
477         0,
478         (dstat_t *)0,
479         drive_identify,
480         philips_attach,
481         philips_init,
482         drive_getdisktype,
483         scsi_load,
484         philips_unload,
485         buf_dummy,
486         recovery_needed,
487         recover_philips,
488         speed_select_yamaha,
489         select_secsize,
490         next_wr_addr_philips,
491         reserve_track_philips,
492         scsi_cdr_write_philips,
493         (int(*)(track_t *, void *, BOOL))cmd_dummy,     /* gen_cue */
494         no_sendcue,
495         (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
496         open_track_yamaha,
497         close_track_philips,
498         (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy,
499         cmd_dummy,
500         cmd_dummy,                                      /* abort        */
501         read_session_offset_philips,
502         fixation_philips,
503         cmd_dummy,                                      /* stats        */
504         blank_dummy,
505         format_dummy,
506         (int(*)(SCSI *, caddr_t, int, int))NULL,        /* no OPC       */
507         cmd_dummy,                                      /* opt1         */
508         cmd_dummy,                                      /* opt2         */
509 };
510
511 cdr_t   cdr_ricoh_ro1060 = {
512         0, 0,
513 /*      CDR_TAO|CDR_SAO|CDR_CADDYLOAD,*/
514         CDR_TAO|CDR_CADDYLOAD,
515         CDR_CDRW_NONE,
516         2, 2,
517         "ricoh_ro1060c",
518         "driver for Ricoh RO-1060C",
519         0,
520         (dstat_t *)0,
521         drive_identify,
522         ricoh_attach,
523         philips_init,
524         philips_getdisktype,
525         scsi_load,
526         scsi_unload,
527         buf_dummy,
528         recovery_needed,
529         recover_philips,
530         speed_select_yamaha,
531         select_secsize,
532         next_wr_addr_philips,
533         reserve_track_philips,
534         scsi_cdr_write_philips,
535         (int(*)(track_t *, void *, BOOL))cmd_dummy,     /* gen_cue */
536         no_sendcue,
537         (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
538         open_track_philips,
539         close_track_philips,
540         (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy,
541         cmd_dummy,
542         cmd_dummy,                                      /* abort        */
543         read_session_offset_philips,
544         fixation_philips,
545         cmd_dummy,                                      /* stats        */
546         blank_dummy,
547         format_dummy,
548         (int(*)(SCSI *, caddr_t, int, int))NULL,        /* no OPC       */
549         cmd_dummy,                                      /* opt1         */
550         cmd_dummy,                                      /* opt2         */
551 };
552
553 cdr_t   cdr_ricoh_ro1420 = {
554         0, 0,
555 /*      CDR_TAO|CDR_SAO|CDR_CADDYLOAD,*/
556         CDR_TAO|CDR_CADDYLOAD,
557         CDR_CDRW_NONE,
558         2, 2,
559         "ricoh_ro1420c",
560         "driver for Ricoh RO-1420C",
561         0,
562         (dstat_t *)0,
563         drive_identify,
564         ricoh_attach,
565         philips_init,
566         philips_getdisktype,
567         scsi_load,
568         scsi_unload,
569         buf_dummy,
570         recovery_needed,
571         recover_philips,
572         speed_select_yamaha,
573         select_secsize,
574         next_wr_addr_philips,
575         reserve_track_philips,
576         scsi_cdr_write_philips,
577         (int(*)(track_t *, void *, BOOL))cmd_dummy,     /* gen_cue */
578         no_sendcue,
579         (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy, /* leadin */
580         open_track_philips,
581         close_track_philips,
582         (int(*)(SCSI *, cdr_t *, track_t *))cmd_dummy,
583         cmd_dummy,
584         cmd_dummy,                                      /* abort        */
585         read_session_offset_philips,
586         fixation_philips,
587         cmd_dummy,                                      /* stats        */
588         blank_dummy,
589         format_dummy,
590         (int(*)(SCSI *, caddr_t, int, int))NULL,        /* no OPC       */
591         cmd_dummy,                                      /* opt1         */
592         cmd_dummy,                                      /* opt2         */
593 };
594
595
596 static int load_unload_philips(SCSI *usalp, int load)
597 {
598         register struct usal_cmd        *scmd = usalp->scmd;
599
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;
607
608         usalp->cmdname = "philips medium load/unload";
609
610         if (usal_cmd(usalp) < 0)
611                 return (-1);
612         return (0);
613 }
614
615 static int 
616 philips_load(SCSI *usalp, cdr_t *dp)
617 {
618         return (load_unload_philips(usalp, 1));
619 }
620
621 static int 
622 philips_unload(SCSI *usalp, cdr_t *dp)
623 {
624         return (load_unload_philips(usalp, 0));
625 }
626
627 static int 
628 philips_dumbload(SCSI *usalp, cdr_t *dp)
629 {
630         int     ret;
631
632         usalp->silent++;
633         ret = load_unload_philips(usalp, 1);
634         usalp->silent--;
635         if (ret < 0)
636                 return (scsi_load(usalp, dp));
637         return (0);
638 }
639
640 static int 
641 philips_dumbunload(SCSI *usalp, cdr_t *dp)
642 {
643         int     ret;
644
645         usalp->silent++;
646         ret = load_unload_philips(usalp, 0);
647         usalp->silent--;
648         if (ret < 0)
649                 return (scsi_unload(usalp, dp));
650         return (0);
651 }
652
653 static int 
654 plasmon_buf(SCSI *usalp, 
655             long *sp /* Size pointer */, 
656             long *fp /* Free space pointer */)
657 {
658         /*
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.
666          */
667
668         if (sp)
669                 *sp = 0L;
670         if (fp)
671                 *fp = 0L;
672
673         return (100);   /* 100 % */
674 }
675
676 static int 
677 recover_philips(SCSI *usalp, cdr_t *dp, int track)
678 {
679         register struct usal_cmd        *scmd = usalp->scmd;
680
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);
687
688         usalp->cmdname = "philips recover";
689
690         if (usal_cmd(usalp) < 0)
691                 return (-1);
692         return (0);
693 }
694
695 static int 
696 speed_select_yamaha(SCSI *usalp, cdr_t *dp, int *speedp)
697 {
698         struct  scsi_mode_page_header   *mp;
699         char                            mode[256];
700         int                             len = 16;
701         int                             page = 0x31;
702         struct yamaha_mode_page_31      *xp;
703         struct cdd_52x_mode_data md;
704         int     count;
705         int     speed = 1;
706         BOOL    dummy = (dp->cdr_cmdflags & F_DUMMY) != 0;
707
708         if (speedp) {
709                 speed = *speedp;
710         } else {
711                 fillbytes((caddr_t)mode, sizeof (mode), '\0');
712
713                 if (!get_mode_params(usalp, page, "Speed/Dummy information",
714                         (Uchar *)mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) {
715                         return (-1);
716                 }
717                 if (len == 0)
718                         return (-1);
719
720                 mp = (struct scsi_mode_page_header *)
721                         (mode + sizeof (struct scsi_mode_header) +
722                         ((struct scsi_mode_header *)mode)->blockdesc_len);
723
724                 xp = (struct yamaha_mode_page_31 *)mp;
725                 speed = xp->speed;
726         }
727
728         fillbytes((caddr_t)&md, sizeof (md), '\0');
729
730         count  = sizeof (struct scsi_mode_header) +
731                 sizeof (struct yamaha_mode_page_31);
732
733         speed >>= 1;
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;
738
739         return (mode_select(usalp, (Uchar *)&md, count, 0, usalp->inq->data_format >= 2));
740 }
741
742 static int 
743 speed_select_philips(SCSI *usalp, cdr_t *dp, int *speedp)
744 {
745         struct  scsi_mode_page_header   *mp;
746         char                            mode[256];
747         int                             len = 20;
748         int                             page = 0x23;
749         struct cdd_52x_mode_page_23     *xp;
750         struct cdd_52x_mode_data        md;
751         int                             count;
752         int                             speed = 1;
753         BOOL                            dummy = (dp->cdr_cmdflags & F_DUMMY) != 0;
754
755         if (speedp) {
756                 speed = *speedp;
757         } else {
758                 fillbytes((caddr_t)mode, sizeof (mode), '\0');
759
760                 if (!get_mode_params(usalp, page, "Speed/Dummy information",
761                         (Uchar *)mode, (Uchar *)0, (Uchar *)0, (Uchar *)0, &len)) {
762                         return (-1);
763                 }
764                 if (len == 0)
765                         return (-1);
766
767                 mp = (struct scsi_mode_page_header *)
768                         (mode + sizeof (struct scsi_mode_header) +
769                         ((struct scsi_mode_header *)mode)->blockdesc_len);
770
771                 xp = (struct cdd_52x_mode_page_23 *)mp;
772                 speed = xp->speed;
773         }
774
775         fillbytes((caddr_t)&md, sizeof (md), '\0');
776
777         count  = sizeof (struct scsi_mode_header) +
778                 sizeof (struct cdd_52x_mode_page_23);
779
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;
784
785         return (mode_select(usalp, (Uchar *)&md, count, 0, usalp->inq->data_format >= 2));
786 }
787
788 static int 
789 speed_select_pioneer(SCSI *usalp, cdr_t *dp, int *speedp)
790 {
791         if (speedp != 0 && *speedp < 2) {
792                 *speedp = 2;
793                 if (lverbose)
794                         printf("WARNING: setting to minimum speed (2).\n");
795         }
796         return (speed_select_philips(usalp, dp, speedp));
797 }
798
799 static int 
800 speed_select_oldphilips(SCSI *usalp, cdr_t *dp, int *speedp)
801 {
802         BOOL    dummy = (dp->cdr_cmdflags & F_DUMMY) != 0;
803
804         if (lverbose)
805                 printf("WARNING: ignoring selected speed.\n");
806         if (dummy) {
807                 errmsgno(EX_BAD, "Cannot set dummy writing for this device.\n");
808                 return (-1);
809         }
810         return (0);
811 }
812
813 static int 
814 speed_select_dumbphilips(SCSI *usalp, cdr_t *dp, int *speedp)
815 {
816         if (speed_select_philips(usalp, dp, speedp) < 0)
817                 return (speed_select_oldphilips(usalp, dp, speedp));
818         return (0);
819 }
820
821 static int 
822 philips_init(SCSI *usalp, cdr_t *dp)
823 {
824         return ((*dp->cdr_set_speed_dummy)(usalp, dp, NULL));
825 }
826
827
828 #define IS(what, flag)  printf("  Is %s%s\n", flag?"":"not ", what);
829
830 static int 
831 philips_getdisktype(SCSI *usalp, cdr_t *dp)
832 {
833         dstat_t *dsp = dp->cdr_dstat;
834         char    sbuf[16];
835         long    dummy;
836         long    lilen;
837         long    lolen;
838         msf_t   msf;
839         int     audio = -1;
840
841         usalp->silent++;
842         dummy = (*dp->cdr_next_wr_address)(usalp, (track_t *)0, &lilen);
843         usalp->silent--;
844
845         /*
846          * Check for "Command sequence error" first.
847          */
848         if ((dsp->ds_cdrflags & RF_WRITE) != 0 &&
849             dummy < 0 &&
850             (usal_sense_key(usalp) != SC_ILLEGAL_REQUEST ||
851                                                 usal_sense_code(usalp) != 0x2C)) {
852                 reload_media(usalp, dp);
853         }
854
855         usalp->silent++;
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;
859         }
860         usalp->silent--;
861
862         if ((dp->cdr_dstat->ds_cdrflags & RF_PRATIP) != 0 &&
863                                                 dummy >= 0 && lilen == 0) {
864                 usalp->silent++;
865                 dummy = philips_getlilo(usalp, &lilen, &lolen);
866                 usalp->silent--;
867
868                 if (dummy >= 0) {
869 /*                      printf("lead-in len: %d lead-out len: %d\n", lilen, lolen);*/
870                         lba_to_msf(-150 - lilen, &msf);
871
872                         printf("ATIP info from disk:\n");
873                         if (audio >= 0)
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);
879
880                         if (capacity_philips(usalp, &lolen)) {
881                                 lba_to_msf(lolen, &msf);
882                                 printf(
883                                 "  ATIP start of lead out: %ld (%02d:%02d/%02d)\n",
884                                 lolen, msf.msf_min, msf.msf_sec, msf.msf_frame);
885                         }
886                         lba_to_msf(-150 - lilen, &msf);
887                         pr_manufacturer(&msf,
888                                         FALSE,          /* Always not erasable */
889                                         audio > 0);     /* Audio from read subcode */
890                 }
891         }
892
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 */
898         }
899         usalp->silent++;
900         /*read_subchannel(usalp, bp, track, cnt, msf, subq, fmt); */
901
902         if (read_subchannel(usalp, sbuf, 0, 14, 0, 0, 0xf1) >= 0)
903                 usal_prbytes("Disk bar code:", (Uchar *)sbuf, 14 - usal_getresid(usalp));
904         usalp->silent--;
905
906         return (drive_getdisktype(usalp, dp));
907 }
908
909 static BOOL 
910 capacity_philips(SCSI *usalp, long *lp)
911 {
912         long    l = 0L;
913         BOOL    succeed = TRUE;
914
915         usalp->silent++;
916         if (read_B0(usalp, FALSE, NULL, &l) >= 0) {
917                 if (debug)
918                         printf("lead out B0: %ld\n", l);
919                 *lp = l;
920         } else if (read_trackinfo(usalp, 0xAA, &l, NULL, NULL, NULL, NULL) >= 0) {
921                 if (debug)
922                         printf("lead out AA: %ld\n", l);
923                 *lp = l;
924         } if (read_capacity(usalp) >= 0) {
925                 l = usalp->cap->c_baddr + 1;
926                 if (debug)
927                         printf("lead out capacity: %ld\n", l);
928         } else {
929                 succeed = FALSE;
930         }
931         *lp = l;
932         usalp->silent--;
933         return (succeed);
934 }
935
936 struct  fwa {
937         char    len;
938         char    addr[4];
939         char    res;
940 };
941
942 static int 
943 first_writable_addr_philips(SCSI *usalp, long *ap, int track, int isaudio, 
944                                                                                 int preemp, int npa)
945 {
946         struct  fwa     fwa;
947         register struct usal_cmd        *scmd = usalp->scmd;
948
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;
960
961         scmd->cdb.g1_cdb.count[0] = npa?1:0;
962         scmd->cdb.g1_cdb.count[1] = sizeof (fwa);
963
964         usalp->cmdname = "first writeable address philips";
965
966         if (usal_cmd(usalp) < 0)
967                 return (-1);
968
969         if (ap)
970                 *ap = a_to_4_byte(fwa.addr);
971         return (0);
972 }
973
974 static int 
975 next_wr_addr_philips(SCSI *usalp, track_t *trackp, long *ap)
976 {
977
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)
980                 return (-1);
981         return (0);
982 }
983
984 static int 
985 reserve_track_philips(SCSI *usalp, unsigned long len)
986 {
987         register struct usal_cmd        *scmd = usalp->scmd;
988
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);
996
997         usalp->cmdname = "philips reserve_track";
998
999         if (usal_cmd(usalp) < 0)
1000                 return (-1);
1001         return (0);
1002 }
1003
1004 static int 
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 */)
1011 {
1012         return (write_xg0(usalp, bp, 0, size, blocks));
1013 }
1014
1015 static int 
1016 write_track_info_philips(SCSI *usalp, int sectype)
1017 {
1018         struct cdd_52x_mode_data md;
1019         int     count = sizeof (struct scsi_mode_header) +
1020                         sizeof (struct cdd_52x_mode_page_21);
1021
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 */
1028
1029         return (mode_select(usalp, (Uchar *)&md, count, 0, usalp->inq->data_format >= 2));
1030 }
1031
1032 static int 
1033 write_track_philips(SCSI *usalp, 
1034                                                         long track /* track number 0 == new track */, 
1035                         int sectype)
1036 {
1037         register struct usal_cmd        *scmd = usalp->scmd;
1038
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;
1048
1049         usalp->cmdname = "philips write_track";
1050
1051         if (usal_cmd(usalp) < 0)
1052                 return (-1);
1053         return (0);
1054 }
1055
1056 static int 
1057 open_track_philips(SCSI *usalp, cdr_t *dp, track_t *trackp)
1058 {
1059         if (select_secsize(usalp, trackp->secsize) < 0)
1060                 return (-1);
1061
1062         if (write_track_info_philips(usalp, trackp->sectype) < 0)
1063                 return (-1);
1064
1065         if (write_track_philips(usalp, 0, trackp->sectype) < 0)
1066                 return (-1);
1067
1068         return (0);
1069 }
1070
1071 static int 
1072 open_track_plasmon(SCSI *usalp, cdr_t *dp, track_t *trackp)
1073 {
1074         if (select_secsize(usalp, trackp->secsize) < 0)
1075                 return (-1);
1076
1077         if (write_track_info_philips(usalp, trackp->sectype) < 0)
1078                 return (-1);
1079
1080         return (0);
1081 }
1082
1083 static int 
1084 open_track_oldphilips(SCSI *usalp, cdr_t *dp, track_t *trackp)
1085 {
1086         if (write_track_philips(usalp, 0, trackp->sectype) < 0)
1087                 return (-1);
1088
1089         return (0);
1090 }
1091
1092 static int 
1093 open_track_yamaha(SCSI *usalp, cdr_t *dp, track_t *trackp)
1094 {
1095         if (select_secsize(usalp, trackp->secsize) < 0)
1096                 return (-1);
1097
1098         if (write_track_philips(usalp, 0, trackp->sectype) < 0)
1099                 return (-1);
1100
1101         return (0);
1102 }
1103
1104 static int 
1105 close_track_philips(SCSI *usalp, cdr_t *dp, track_t *trackp)
1106 {
1107         return (scsi_flush_cache(usalp, FALSE));
1108 }
1109
1110 static int fixation_philips(SCSI *usalp, cdr_t *dp, track_t *trackp)
1111 {
1112         register struct usal_cmd        *scmd = usalp->scmd;
1113
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);
1124
1125         usalp->cmdname = "philips fixation";
1126
1127         if (usal_cmd(usalp) < 0)
1128                 return (-1);
1129         return (0);
1130 }
1131
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 */
1140 #endif
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 */
1160 #ifdef  REAL_CDD_521
1161         "\253\000non reserved reserved track",          /* 0xab */
1162 #else
1163         "\253\000illegal track number",                 /* 0xab */
1164 #endif
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 */
1181 #endif
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 */
1195         NULL
1196 };
1197
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 */
1282         NULL
1283 };
1284
1285 static int 
1286 philips_attach(SCSI *usalp, cdr_t *dp)
1287 {
1288         usal_setnonstderrs(usalp, sd_cdd_521_error_str);
1289         return (0);
1290 }
1291
1292 static int 
1293 plasmon_attach(SCSI *usalp, cdr_t *dp)
1294 {
1295         usalp->inq->data_format = 1;    /* Correct the ly */
1296
1297         usal_setnonstderrs(usalp, sd_cdd_521_error_str);
1298         return (0);
1299 }
1300
1301 static int 
1302 ricoh_attach(SCSI *usalp, cdr_t *dp)
1303 {
1304         if (dp == &cdr_ricoh_ro1060) {
1305                 errmsgno(EX_BAD, "No support for Ricoh RO-1060C\n");
1306                 return (-1);
1307         }
1308         usal_setnonstderrs(usalp, sd_ro1420_error_str);
1309         return (0);
1310 }
1311
1312 static int 
1313 philips_getlilo(SCSI *usalp, long *lilenp, long *lolenp)
1314 {
1315         char    buf[4];
1316         long    li, lo;
1317         register struct usal_cmd        *scmd = usalp->scmd;
1318
1319         fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
1320         scmd->addr = buf;
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));
1328
1329         usalp->cmdname = "philips read session info";
1330
1331         if (usal_cmd(usalp) < 0)
1332                 return (-1);
1333
1334         if (usalp->verbose)
1335                 usal_prbytes("Session info data: ", (Uchar *)buf, sizeof (buf) - usal_getresid(usalp));
1336
1337         li = a_to_u_2_byte(buf);
1338         lo = a_to_u_2_byte(&buf[2]);
1339
1340         if (lilenp)
1341                 *lilenp = li;
1342         if (lolenp)
1343                 *lolenp = lo;
1344
1345         return (0);
1346 }