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