1 /* @(#)cdr_drv.c 1.49 10/12/19 Copyright 1997-2010 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)cdr_drv.c 1.49 10/12/19 Copyright 1997-2010 J. Schilling";
6 #endif
7 /*
8 * CDR device abstraction layer
9 *
10 * Copyright (c) 1997-2010 J. Schilling
11 */
12 /*
13 * The contents of this file are subject to the terms of the
14 * Common Development and Distribution License, Version 1.0 only
15 * (the "License"). You may not use this file except in compliance
16 * with the License.
17 *
18 * See the file CDDL.Schily.txt in this distribution for details.
19 * A copy of the CDDL is also available via the Internet at
20 * http://www.opensource.org/licenses/cddl1.txt
21 *
22 * When distributing Covered Code, include this CDDL HEADER in each
23 * file and include the License file CDDL.Schily.txt from this distribution.
24 */
25
26 #include <schily/mconfig.h>
27 #include <schily/stdio.h>
28 #include <schily/stdlib.h>
29 #include <schily/unistd.h> /* Include sys/types.h to make off_t available */
30 #include <schily/standard.h>
31 #include <schily/schily.h>
32 #include <schily/nlsdefs.h>
33
34 #include <scg/scsidefs.h>
35 #include <scg/scsireg.h>
36 #include <scg/scsitransp.h>
37
38 #include "cdrecord.h"
39
40 extern int xdebug;
41
42 extern cdr_t cdr_oldcd;
43 extern cdr_t cdr_cd;
44 extern cdr_t cdr_mmc;
45 extern cdr_t cdr_mmc_sony;
46 extern cdr_t cdr_dvd;
47 extern cdr_t cdr_dvdplus;
48 extern cdr_t cdr_dvdplusr;
49 extern cdr_t cdr_dvdplusrw;
50 extern cdr_t cdr_bd;
51 extern cdr_t cdr_bdrom;
52 extern cdr_t cdr_bdr;
53 extern cdr_t cdr_bdre;
54 extern cdr_t cdr_cd_dvd;
55 extern cdr_t cdr_philips_cdd521O;
56 extern cdr_t cdr_philips_dumb;
57 extern cdr_t cdr_philips_cdd521;
58 extern cdr_t cdr_philips_cdd522;
59 extern cdr_t cdr_tyuden_ew50;
60 extern cdr_t cdr_kodak_pcd600;
61 extern cdr_t cdr_pioneer_dw_s114x;
62 extern cdr_t cdr_plasmon_rf4100;
63 extern cdr_t cdr_yamaha_cdr100;
64 extern cdr_t cdr_sony_cdu924;
65 extern cdr_t cdr_ricoh_ro1060;
66 extern cdr_t cdr_ricoh_ro1420;
67 extern cdr_t cdr_teac_cdr50;
68 extern cdr_t cdr_cw7501;
69 extern cdr_t cdr_cdr_simul;
70 extern cdr_t cdr_dvd_simul;
71 extern cdr_t cdr_bd_simul;
72
73 EXPORT cdr_t *drive_identify __PR((SCSI *scgp, cdr_t *, struct scsi_inquiry *ip));
74 EXPORT int drive_attach __PR((SCSI *scgp, cdr_t *));
75 EXPORT int attach_unknown __PR((void));
76 EXPORT int blank_dummy __PR((SCSI *scgp, cdr_t *, long addr, int blanktype));
77 EXPORT int blank_simul __PR((SCSI *scgp, cdr_t *, long addr, int blanktype));
78 EXPORT int format_dummy __PR((SCSI *scgp, cdr_t *, int fmtflags));
79 EXPORT int drive_getdisktype __PR((SCSI *scgp, cdr_t *dp));
80 EXPORT int cmd_ill __PR((SCSI *scgp));
81 EXPORT int cmd_dummy __PR((SCSI *scgp, cdr_t *));
82 EXPORT int no_sendcue __PR((SCSI *scgp, cdr_t *, track_t *trackp));
83 EXPORT int no_diskstatus __PR((SCSI *scgp, cdr_t *));
84 EXPORT int buf_dummy __PR((SCSI *scgp, long *sp, long *fp));
85 EXPORT BOOL set_cdrcmds __PR((char *name, cdr_t **dpp));
86 EXPORT cdr_t *get_cdrcmds __PR((SCSI *scgp));
87
88 /*
89 * List of CD-R drivers
90 */
91 cdr_t *drivers[] = {
92 &cdr_cd_dvd,
93 &cdr_bd,
94 &cdr_bdrom,
95 &cdr_bdr,
96 &cdr_bdre,
97 &cdr_dvdplus,
98 &cdr_dvdplusr,
99 &cdr_dvdplusrw,
100 &cdr_dvd,
101 &cdr_mmc,
102 &cdr_mmc_sony,
103 &cdr_cd,
104 &cdr_oldcd,
105 &cdr_philips_cdd521O,
106 &cdr_philips_dumb,
107 &cdr_philips_cdd521,
108 &cdr_philips_cdd522,
109 &cdr_tyuden_ew50,
110 &cdr_kodak_pcd600,
111 &cdr_pioneer_dw_s114x,
112 &cdr_plasmon_rf4100,
113 &cdr_yamaha_cdr100,
114 &cdr_ricoh_ro1060,
115 &cdr_ricoh_ro1420,
116 &cdr_sony_cdu924,
117 &cdr_teac_cdr50,
118 &cdr_cw7501,
119 &cdr_cdr_simul,
120 &cdr_dvd_simul,
121 &cdr_bd_simul,
122 (cdr_t *)NULL,
123 };
124
125 EXPORT cdr_t *
drive_identify(scgp,dp,ip)126 drive_identify(scgp, dp, ip)
127 SCSI *scgp;
128 cdr_t *dp;
129 struct scsi_inquiry *ip;
130 {
131 return (dp);
132 }
133
134 EXPORT int
drive_attach(scgp,dp)135 drive_attach(scgp, dp)
136 SCSI *scgp;
137 cdr_t *dp;
138 {
139 return (0);
140 }
141
142 EXPORT int
attach_unknown()143 attach_unknown()
144 {
145 errmsgno(EX_BAD, _("Unsupported drive type\n"));
146 return (-1);
147 }
148
149 EXPORT int
blank_dummy(scgp,dp,addr,blanktype)150 blank_dummy(scgp, dp, addr, blanktype)
151 SCSI *scgp;
152 cdr_t *dp;
153 long addr;
154 int blanktype;
155 {
156 printf(_("This drive or media does not support the 'BLANK media' command\n"));
157 return (-1);
158 }
159
160 EXPORT int
blank_simul(scgp,dp,addr,blanktype)161 blank_simul(scgp, dp, addr, blanktype)
162 SCSI *scgp;
163 cdr_t *dp;
164 long addr;
165 int blanktype;
166 {
167 track_t *trackp = dp->cdr_dstat->ds_trackp;
168 int secsize = trackp->secsize;
169 Llong padbytes = 0; /* Make stupid GCC happy */
170 int ret = -1;
171
172 switch (blanktype) {
173
174 case BLANK_MINIMAL:
175 padbytes = 1000 * secsize;
176 break;
177 case BLANK_DISC:
178 if (dp->cdr_dstat->ds_maxblocks > 0)
179 padbytes = dp->cdr_dstat->ds_maxblocks * (Llong)secsize;
180 break;
181 default:
182 printf(_("Unsupported blank type for simulation mode.\n"));
183 printf(_("Try blank=all or blank=fast\n"));
184 padbytes = 0;
185 }
186 if (padbytes > 0) {
187 printf(_("Running pad based emulation to blank the medium.\n"));
188 printf(_("secsize %d padbytes %lld padblocks %lld maxblocks %d\n"),
189 secsize, padbytes, padbytes/secsize, dp->cdr_dstat->ds_maxblocks);
190
191 ret = pad_track(scgp, dp, trackp, 0, padbytes, TRUE, NULL);
192 printf("\n");
193 flush();
194 }
195 if (0) {
196 printf(_("This drive or media does not support the 'BLANK media' command\n"));
197 return (-1);
198 }
199 return (ret);
200
201 }
202
203 EXPORT int
format_dummy(scgp,dp,fmtflags)204 format_dummy(scgp, dp, fmtflags)
205 SCSI *scgp;
206 cdr_t *dp;
207 int fmtflags;
208 {
209 printf(_("This drive or media does not support the 'FORMAT media' command\n"));
210 return (-1);
211 }
212
213 EXPORT int
drive_getdisktype(scgp,dp)214 drive_getdisktype(scgp, dp)
215 SCSI *scgp;
216 cdr_t *dp;
217 {
218 /* dstat_t *dsp = dp->cdr_dstat;*/
219 return (0);
220 }
221
222 EXPORT int
cmd_ill(scgp)223 cmd_ill(scgp)
224 SCSI *scgp;
225 {
226 errmsgno(EX_BAD, _("Unspecified command not implemented for this drive.\n"));
227 return (-1);
228 }
229
230 EXPORT int
cmd_dummy(scgp,dp)231 cmd_dummy(scgp, dp)
232 SCSI *scgp;
233 cdr_t *dp;
234 {
235 return (0);
236 }
237
238 EXPORT int
no_sendcue(scgp,dp,trackp)239 no_sendcue(scgp, dp, trackp)
240 SCSI *scgp;
241 cdr_t *dp;
242 track_t *trackp;
243 {
244 errmsgno(EX_BAD, _("SAO writing not available or not implemented for this drive.\n"));
245 return (-1);
246 }
247
248 EXPORT int
no_diskstatus(scgp,dp)249 no_diskstatus(scgp, dp)
250 SCSI *scgp;
251 cdr_t *dp;
252 {
253 errmsgno(EX_BAD, _("Printing of disk status not implemented for this drive.\n"));
254 return (-1);
255 }
256
257 EXPORT int
buf_dummy(scgp,sp,fp)258 buf_dummy(scgp, sp, fp)
259 SCSI *scgp;
260 long *sp;
261 long *fp;
262 {
263 return (-1);
264 }
265
266 EXPORT BOOL
set_cdrcmds(name,dpp)267 set_cdrcmds(name, dpp)
268 char *name;
269 cdr_t **dpp;
270 {
271 cdr_t **d;
272 int n;
273
274 for (d = drivers; *d != (cdr_t *)NULL; d++) {
275 if (streql((*d)->cdr_drname, name)) {
276 if (dpp != NULL)
277 *dpp = *d;
278 return (TRUE);
279 }
280 }
281 if (dpp == NULL)
282 return (FALSE);
283
284 if (!streql("help", name))
285 error(_("Illegal driver type '%s'.\n"), name);
286
287 error(_("Driver types:\n"));
288 for (d = drivers; *d != (cdr_t *)NULL; d++) {
289 error("%s%n",
290 (*d)->cdr_drname, &n);
291 error("%*s%s\n",
292 20-n, "",
293 (*d)->cdr_drtext);
294 }
295 if (streql("help", name))
296 exit(0);
297 exit(EX_BAD);
298 return (FALSE); /* Make lint happy */
299 }
300
301 EXPORT cdr_t *
get_cdrcmds(scgp)302 get_cdrcmds(scgp)
303 SCSI *scgp;
304 {
305 cdr_t *dp = (cdr_t *)0;
306 cdr_t *odp = (cdr_t *)0;
307 BOOL is_wr = FALSE;
308 BOOL is_cd = FALSE;
309 BOOL is_dvd = FALSE;
310 BOOL is_dvdplus = FALSE;
311 BOOL is_ddcd = FALSE;
312 BOOL is_cdwr = FALSE;
313 BOOL is_dvdwr = FALSE;
314 BOOL is_dvdpluswr = FALSE;
315 BOOL is_ddcdwr = FALSE;
316
317 /*
318 * First check for SCSI-3/mmc-3 drives.
319 */
320 if (get_proflist(scgp, &is_wr, &is_cd, &is_dvd,
321 &is_dvdplus, &is_ddcd) >= 0) {
322
323 get_wproflist(scgp, &is_cdwr, &is_dvdwr,
324 &is_dvdpluswr, &is_ddcdwr);
325 if (xdebug) {
326 error(
327 _("Found MMC-3 %s CD: %s/%s DVD-: %s/%s DVD+: %s/%s DDCD: %s/%s.\n"),
328 is_wr ? _("writer"): _("reader"),
329 is_cd?"r":"-",
330 is_cdwr?"w":"-",
331 is_dvd?"r":"-",
332 is_dvdwr?"w":"-",
333 is_dvdplus?"r":"-",
334 is_dvdpluswr?"w":"-",
335 is_ddcd?"r":"-",
336 is_ddcdwr?"w":"-");
337 }
338 if (!is_wr) {
339 dp = &cdr_cd;
340 } else {
341 dp = &cdr_cd_dvd;
342 }
343 } else
344 /*
345 * First check for SCSI-3/mmc drives.
346 */
347 if (is_mmc(scgp, &is_cdwr, &is_dvdwr)) {
348 if (xdebug) {
349 error(_("Found MMC drive CDWR: %d DVDWR: %d.\n"),
350 is_cdwr, is_dvdwr);
351 }
352
353 if (is_cdwr && is_dvdwr)
354 dp = &cdr_cd_dvd;
355 else
356 if (is_dvdwr)
357 dp = &cdr_dvd;
358 else
359 dp = &cdr_mmc;
360
361 } else switch (scgp->dev) {
362
363 case DEV_CDROM: dp = &cdr_oldcd; break;
364 case DEV_MMC_CDROM: dp = &cdr_cd; break;
365 case DEV_MMC_CDR: dp = &cdr_mmc; break;
366 case DEV_MMC_CDRW: dp = &cdr_mmc; break;
367 case DEV_MMC_DVD_WR: dp = &cdr_cd_dvd; break;
368
369 case DEV_CDD_521_OLD: dp = &cdr_philips_cdd521O; break;
370 case DEV_CDD_521: dp = &cdr_philips_cdd521; break;
371 case DEV_CDD_522:
372 case DEV_CDD_2000:
373 case DEV_CDD_2600: dp = &cdr_philips_cdd522; break;
374 case DEV_TYUDEN_EW50: dp = &cdr_tyuden_ew50; break;
375 case DEV_PCD_600: dp = &cdr_kodak_pcd600; break;
376 case DEV_YAMAHA_CDR_100:dp = &cdr_yamaha_cdr100; break;
377 case DEV_MATSUSHITA_7501:dp = &cdr_cw7501; break;
378 case DEV_MATSUSHITA_7502:
379 case DEV_YAMAHA_CDR_400:dp = &cdr_mmc; break;
380 case DEV_PLASMON_RF_4100:dp = &cdr_plasmon_rf4100; break;
381 case DEV_SONY_CDU_924: dp = &cdr_sony_cdu924; break;
382 case DEV_RICOH_RO_1060C:dp = &cdr_ricoh_ro1060; break;
383 case DEV_RICOH_RO_1420C:dp = &cdr_ricoh_ro1420; break;
384 case DEV_TEAC_CD_R50S: dp = &cdr_teac_cdr50; break;
385
386 case DEV_PIONEER_DW_S114X: dp = &cdr_pioneer_dw_s114x; break;
387 case DEV_PIONEER_DVDR_S101:dp = &cdr_dvd; break;
388
389 default: dp = &cdr_mmc;
390 }
391 odp = dp;
392
393 if (xdebug) {
394 error(_("Using driver '%s' for identify.\n"),
395 dp != NULL ?
396 dp->cdr_drname :
397 _("<no driver>"));
398 }
399
400 if (dp != (cdr_t *)0)
401 dp = dp->cdr_identify(scgp, dp, scgp->inq);
402
403 if (xdebug && dp != odp) {
404 error(_("Identify set driver to '%s'.\n"),
405 dp != NULL ?
406 dp->cdr_drname :
407 _("<no driver>"));
408 }
409
410 return (dp);
411 }
412