Imported Upstream version 1.1.11
[platform/upstream/cdrkit.git] / wodim / cdr_drv.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 /* @(#)cdr_drv.c        1.36 04/03/02 Copyright 1997-2004 J. Schilling */
14 /*
15  *      CDR device abstraction layer
16  *
17  *      Copyright (c) 1997-2004 J. Schilling
18  */
19 /*
20  * This program is free software; you can redistribute it and/or modify
21  * it under the terms of the GNU General Public License version 2
22  * as published by the Free Software Foundation.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License along with
30  * this program; see the file COPYING.  If not, write to the Free Software
31  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32  */
33
34 #include <mconfig.h>
35 #include <stdio.h>
36 #include <stdxlib.h>
37 #include <unixstd.h>    /* Include sys/types.h to make off_t available */
38 #include <standard.h>
39 #include <schily.h>
40
41 #include <usal/scsidefs.h>
42 #include <usal/scsireg.h>
43 #include <usal/scsitransp.h>
44
45 #include "wodim.h"
46
47 extern  int     xdebug;
48
49 extern  cdr_t   cdr_oldcd;
50 extern  cdr_t   cdr_cd;
51 extern  cdr_t   cdr_mmc;
52 extern  cdr_t   cdr_mdvd;
53 extern  cdr_t   cdr_mmc_sony;
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
72 cdr_t   *drive_identify(SCSI *usalp, cdr_t *, struct scsi_inquiry *ip);
73 int     drive_attach(SCSI *usalp, cdr_t *);
74 int     attach_unknown(void);
75 int     blank_dummy(SCSI *usalp, cdr_t *, long addr, int blanktype);
76 int     format_dummy(SCSI *usalp, cdr_t *, int fmtflags);
77 int     drive_getdisktype(SCSI *usalp, cdr_t *dp);
78 int     cmd_ill(SCSI *usalp);
79 int     cmd_dummy(SCSI *usalp, cdr_t *);
80 int     no_sendcue(SCSI *usalp, cdr_t *, track_t *trackp);
81 int     buf_dummy(SCSI *usalp, long *sp, long *fp);
82 BOOL    set_cdrcmds(char *name, cdr_t **dpp);
83 cdr_t   *get_cdrcmds(SCSI *usalp);
84
85 /*
86  * List of CD-R drivers
87  */
88 cdr_t   *drivers[] = {
89         &cdr_cd_dvd,
90         &cdr_mmc,
91         &cdr_mdvd,
92         &cdr_mmc_sony,
93         &cdr_cd,
94         &cdr_oldcd,
95         &cdr_philips_cdd521O,
96         &cdr_philips_dumb,
97         &cdr_philips_cdd521,
98         &cdr_philips_cdd522,
99         &cdr_tyuden_ew50,
100         &cdr_kodak_pcd600,
101         &cdr_pioneer_dw_s114x,
102         &cdr_plasmon_rf4100,
103         &cdr_yamaha_cdr100,
104         &cdr_ricoh_ro1060,
105         &cdr_ricoh_ro1420,
106         &cdr_sony_cdu924,
107         &cdr_teac_cdr50,
108         &cdr_cw7501,
109         &cdr_cdr_simul,
110         &cdr_dvd_simul,
111         (cdr_t *)NULL,
112 };
113
114 cdr_t *
115 drive_identify(SCSI *usalp, cdr_t *dp, struct scsi_inquiry *ip)
116 {
117         return (dp);
118 }
119
120 int 
121 drive_attach(SCSI *usalp, cdr_t *dp)
122 {
123         return (0);
124 }
125
126 int 
127 attach_unknown()
128 {
129         errmsgno(EX_BAD, "Unsupported drive type\n");
130         return (-1);
131 }
132
133 int 
134 blank_dummy(SCSI *usalp, cdr_t *dp, long addr, int blanktype)
135 {
136         printf("This drive or media does not support the 'BLANK media' command\n");
137         return (-1);
138 }
139
140 int 
141 format_dummy(SCSI *usalp, cdr_t *dp, int fmtflags)
142 {
143         printf("This drive or media does not support the 'FORMAT media' command\n");
144         return (-1);
145 }
146
147 int 
148 drive_getdisktype(SCSI *usalp, cdr_t *dp)
149 {
150 /*      dstat_t *dsp = dp->cdr_dstat;*/
151         return (0);
152 }
153
154 int 
155 cmd_ill(SCSI *usalp)
156 {
157         errmsgno(EX_BAD, "Unspecified command not implemented for this drive.\n");
158         return (-1);
159 }
160
161 int 
162 cmd_dummy(SCSI *usalp, cdr_t *dp)
163 {
164         return (0);
165 }
166
167 int 
168 no_sendcue(SCSI *usalp, cdr_t *dp, track_t *trackp)
169 {
170         errmsgno(EX_BAD, "SAO writing not available or not implemented for this drive.\n");
171         return (-1);
172 }
173
174 int 
175 buf_dummy(SCSI *usalp, long *sp, long *fp)
176 {
177         return (-1);
178 }
179
180 BOOL 
181 set_cdrcmds(char *name, cdr_t **dpp)
182 {
183         cdr_t   **d;
184         int     n;
185
186         for (d = drivers; *d != (cdr_t *)NULL; d++) {
187                 if (streql((*d)->cdr_drname, name)) {
188                         if (dpp != NULL)
189                                 *dpp = *d;
190                         return (TRUE);
191                 }
192         }
193         if (dpp == NULL)
194                 return (FALSE);
195
196         if (!streql("help", name))
197                 fprintf(stderr, "Illegal driver type '%s'.\n", name);
198
199         fprintf(stderr, "Driver types:\n");
200         for (d = drivers; *d != (cdr_t *)NULL; d++) {
201                 fprintf(stderr, "%s%n",
202                         (*d)->cdr_drname, &n);
203                 fprintf(stderr, "%*s%s\n",
204                         20-n, "",
205                         (*d)->cdr_drtext);
206         }
207         if (streql("help", name))
208                 exit(0);
209         exit(EX_BAD);
210         return (FALSE);         /* Make lint happy */
211 }
212
213 cdr_t *
214 get_cdrcmds(SCSI *usalp)
215 {
216         cdr_t   *dp = (cdr_t *)0;
217         cdr_t   *odp = (cdr_t *)0;
218         BOOL    is_wr = FALSE;
219         BOOL    is_cd = FALSE;
220         BOOL    is_dvd = FALSE;
221         BOOL    is_dvdplus = FALSE;
222         BOOL    is_ddcd = FALSE;
223         BOOL    is_cdwr = FALSE;
224         BOOL    is_dvdwr = FALSE;
225         BOOL    is_dvdpluswr = FALSE;
226         BOOL    is_ddcdwr = FALSE;
227
228         /*
229          * First check for SCSI-3/mmc-3 drives.
230          */
231         if (get_proflist(usalp, &is_wr, &is_cd, &is_dvd,
232                                                 &is_dvdplus, &is_ddcd) >= 0) {
233
234                 get_wproflist(usalp, &is_cdwr, &is_dvdwr,
235                                                 &is_dvdpluswr, &is_ddcdwr);
236                 if (xdebug) {
237                         fprintf(stderr, 
238                         "Found MMC-3 %s CD: %s/%s DVD-: %s/%s DVD+: %s/%s DDCD: %s/%s.\n",
239                                         is_wr ? "writer": "reader",
240                                         is_cd?"r":"-",
241                                         is_cdwr?"w":"-",
242                                         is_dvd?"r":"-",
243                                         is_dvdwr?"w":"-",
244                                         is_dvdplus?"r":"-",
245                                         is_dvdpluswr?"w":"-",
246                                         is_ddcd?"r":"-",
247                                         is_ddcdwr?"w":"-");
248                 }
249                 if (!is_wr) {
250                         dp = &cdr_cd;
251                 } else {
252                         dp = &cdr_cd_dvd;
253                 }
254         } else
255         /*
256          * First check for SCSI-3/mmc drives.
257          */
258         if (is_mmc(usalp, &is_cdwr, &is_dvdwr)) {
259                 if (xdebug) {
260                         fprintf(stderr, "Found MMC drive CDWR: %d DVDWR: %d.\n",
261                                                         is_cdwr, is_dvdwr);
262                 }
263
264                 if (is_cdwr && is_dvdwr)
265                         dp = &cdr_cd_dvd;
266                 else
267                         dp = &cdr_mmc;
268
269         } else switch (usalp->dev) {
270
271         case DEV_CDROM:         dp = &cdr_oldcd;                break;
272         case DEV_MMC_CDROM:     dp = &cdr_cd;                   break;
273         case DEV_MMC_CDR:       dp = &cdr_mmc;                  break;
274         case DEV_MMC_CDRW:      dp = &cdr_mmc;                  break;
275         case DEV_MMC_DVD_WR:    dp = &cdr_cd_dvd;               break;
276
277         case DEV_CDD_521_OLD:   dp = &cdr_philips_cdd521O;      break;
278         case DEV_CDD_521:       dp = &cdr_philips_cdd521;       break;
279         case DEV_CDD_522:
280         case DEV_CDD_2000:
281         case DEV_CDD_2600:      dp = &cdr_philips_cdd522;       break;
282         case DEV_TYUDEN_EW50:   dp = &cdr_tyuden_ew50;          break;
283         case DEV_PCD_600:       dp = &cdr_kodak_pcd600;         break;
284         case DEV_YAMAHA_CDR_100:dp = &cdr_yamaha_cdr100;        break;
285         case DEV_MATSUSHITA_7501:dp = &cdr_cw7501;              break;
286         case DEV_MATSUSHITA_7502:
287         case DEV_YAMAHA_CDR_400:dp = &cdr_mmc;                  break;
288         case DEV_PLASMON_RF_4100:dp = &cdr_plasmon_rf4100;      break;
289         case DEV_SONY_CDU_924:  dp = &cdr_sony_cdu924;          break;
290         case DEV_RICOH_RO_1060C:dp = &cdr_ricoh_ro1060;         break;
291         case DEV_RICOH_RO_1420C:dp = &cdr_ricoh_ro1420;         break;
292         case DEV_TEAC_CD_R50S:  dp = &cdr_teac_cdr50;           break;
293
294         case DEV_PIONEER_DW_S114X: dp = &cdr_pioneer_dw_s114x;  break;
295
296         default:                dp = &cdr_mmc;
297         }
298         odp = dp;
299
300         if (xdebug) {
301                 fprintf(stderr, "Using driver '%s' for identify.\n",
302                         dp != NULL ?
303                         dp->cdr_drname :
304                         "<no driver>");
305         }
306
307         if (dp != (cdr_t *)0)
308                 dp = dp->cdr_identify(usalp, dp, usalp->inq);
309
310         if (xdebug && dp != odp) {
311                 fprintf(stderr, "Identify set driver to '%s'.\n",
312                         dp != NULL ?
313                         dp->cdr_drname :
314                         "<no driver>");
315         }
316
317         return (dp);
318 }