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 /* @(#)scsi_mmc.c 1.13 05/05/16 Copyright 2002-2005 J. Schilling */
15 * SCSI command functions for cdrecord
16 * covering MMC-3 level and above
18 * Copyright (c) 2002-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.
36 Includes code from http://libburnia.pykix.org/browser/libburn/trunk/libburn/mmc.c?format=txt
57 #include <usal/usalcmd.h>
58 #include <usal/scsidefs.h>
59 #include <usal/scsireg.h>
60 #include <usal/scsitransp.h>
69 int get_configuration(SCSI *usalp, caddr_t bp, int cnt, int st_feature,
71 static int get_conflen(SCSI *usalp, int st_feature, int rt);
72 int get_curprofile(SCSI *usalp);
73 static int get_profiles(SCSI *usalp, caddr_t bp, int cnt);
74 int print_profiles(SCSI *usalp);
75 int get_proflist(SCSI *usalp, BOOL *wp, BOOL *cdp, BOOL *dvdp, BOOL *dvdplusp,
77 int get_wproflist(SCSI *usalp, BOOL *cdp, BOOL *dvdp, BOOL *dvdplusp,
84 get_configuration(SCSI *usalp, caddr_t bp, int cnt, int st_feature, int rt)
86 register struct usal_cmd *scmd = usalp->scmd;
88 fillbytes((caddr_t)scmd, sizeof (*scmd), '\0');
91 scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
92 scmd->cdb_len = SC_G1_CDBLEN;
93 scmd->sense_len = CCS_SENSE_LEN;
94 scmd->cdb.g1_cdb.cmd = 0x46;
95 scmd->cdb.g1_cdb.lun = usal_lun(usalp);
97 scmd->cdb.g1_cdb.reladr = 1;
99 scmd->cdb.g1_cdb.res = 1;
101 i_to_2_byte(scmd->cdb.g1_cdb.addr, st_feature);
102 g1_cdblen(&scmd->cdb.g1_cdb, cnt);
104 usalp->cmdname = "get_configuration";
106 return (usal_cmd(usalp));
110 * Retrieve feature code list length
113 get_conflen(SCSI *usalp, int st_feature, int rt)
119 fillbytes(cbuf, sizeof (cbuf), '\0');
121 i = get_configuration(usalp, (char *)cbuf, sizeof (cbuf), st_feature, rt);
125 i = sizeof (cbuf) - usal_getresid(usalp);
129 flen = a_to_u_4_byte(cbuf);
136 get_curprofile(SCSI *usalp)
144 fillbytes(cbuf, sizeof (cbuf), '\0');
146 i = get_configuration(usalp, (char *)cbuf, sizeof (cbuf), 0, 0);
151 amt = sizeof (cbuf) - usal_getresid(usalp);
154 flen = a_to_u_4_byte(cbuf);
158 profile = a_to_u_2_byte(&cbuf[6]);
161 usal_prbytes("Features: ", cbuf, amt);
164 printf("feature len: %d current profile 0x%04X (%s) len %d\n",
166 mmc_obtain_profile_name(profile), amt);
172 get_profiles(SCSI *usalp, caddr_t bp, int cnt)
178 flen = get_conflen(usalp, 0, 0);
184 fillbytes(bp, cnt, '\0');
186 i = get_configuration(usalp, (char *)bp, flen, 0, 0);
190 amt = flen - usal_getresid(usalp);
192 flen = a_to_u_4_byte(bp);
200 print_profiles(SCSI *usalp)
210 flen = get_profiles(usalp, (caddr_t)cbuf, sizeof (cbuf));
216 usal_prbytes("Features: ", cbuf, flen);
218 curprofile = a_to_u_2_byte(&p[6]);
220 printf("feature len: %d current profile 0x%04X (%s)\n",
222 mmc_obtain_profile_name(curprofile));
224 printf("Current: 0x%04X (%s)\n", curprofile,
225 mmc_obtain_profile_name(curprofile));
227 p += 8; /* Skip feature header */
228 n = p[3]; /* Additional length */
232 for (i = 0; i < n; i++) {
233 profile = a_to_u_2_byte(p);
235 printf("Profile: 0x%04X (%s)", profile,
236 mmc_obtain_profile_name(profile));
239 printf("0x%04X (%s) %s\n", profile,
240 mmc_obtain_profile_name(profile),
241 p[2] & 1 ? "(current)":"");
248 get_proflist(SCSI *usalp, BOOL *wp, BOOL *cdp, BOOL *dvdp, BOOL *dvdplusp,
261 BOOL dvdplus = FALSE;
264 flen = get_profiles(usalp, (caddr_t)cbuf, sizeof (cbuf));
270 usal_prbytes("Features: ", cbuf, flen);
272 curprofile = a_to_u_2_byte(&p[6]);
274 printf("feature len: %d current profile 0x%04X (%s)\n",
276 mmc_obtain_profile_name(curprofile));
278 p += 8; /* Skip feature header */
279 n = p[3]; /* Additional length */
283 for (i = 0; i < n; i++) {
284 profile = a_to_u_2_byte(p);
286 if (profile >= 0x0008 && profile < 0x0010)
288 if (profile > 0x0008 && profile < 0x0010)
291 if (profile >= 0x0010 && profile < 0x0018)
293 if (profile > 0x0010 && profile < 0x0018)
296 if (profile >= 0x0018 && profile < 0x0020)
298 if (profile > 0x0018 && profile < 0x0020)
301 if (profile >= 0x0020 && profile < 0x0028)
303 if (profile > 0x0020 && profile < 0x0028)
321 get_wproflist(SCSI *usalp, BOOL *cdp, BOOL *dvdp, BOOL *dvdplusp, BOOL *ddcdp)
332 BOOL dvdplus = FALSE;
335 flen = get_profiles(usalp, (caddr_t)cbuf, sizeof (cbuf));
339 curprofile = a_to_u_2_byte(&p[6]);
341 p += 8; /* Skip feature header */
342 n = p[3]; /* Additional length */
346 for (i = 0; i < n; i++) {
347 profile = a_to_u_2_byte(p);
349 if (profile > 0x0008 && profile < 0x0010)
351 if (profile > 0x0010 && profile < 0x0018)
353 if (profile > 0x0018 && profile < 0x0020)
355 if (profile > 0x0020 && profile < 0x0028)
371 char *mmc_obtain_profile_name(int profile_number) {
372 static char *texts[0x53] = {NULL};
373 static char *reserved="Reserved/Unknown";
374 int i, max_pno = 0x53;
376 if (texts[0] == NULL) {
377 for (i = 0; i<max_pno; i++)
379 /* mmc5r04c.pdf , Table 88, human readable profile names */
380 texts[0x01] = "Non-removable disk";
381 texts[0x02] = "Removable disk";
382 texts[0x03] = "MO erasable";
383 texts[0x04] = "Optical write once";
384 texts[0x05] = "AS-MO";
385 texts[0x08] = "CD-ROM";
386 texts[0x09] = "CD-R";
387 texts[0x0a] = "CD-RW";
388 texts[0x10] = "DVD-ROM";
389 texts[0x11] = "DVD-R sequential recording";
390 texts[0x12] = "DVD-RAM";
391 texts[0x13] = "DVD-RW restricted overwrite";
392 texts[0x14] = "DVD-RW sequential recording";
393 texts[0x15] = "DVD-R/DL sequential recording";
394 texts[0x16] = "DVD-R/DL layer jump recording";
395 texts[0x1a] = "DVD+RW";
396 texts[0x1b] = "DVD+R";
397 texts[0x2a] = "DVD+RW/DL";
398 texts[0x2b] = "DVD+R/DL";
399 texts[0x40] = "BD-ROM";
400 texts[0x41] = "BD-R sequential recording";
401 texts[0x42] = "BD-R random recording";
402 texts[0x43] = "BD-RE";
403 texts[0x50] = "HD-DVD-ROM";
404 texts[0x51] = "HD-DVD-R";
405 texts[0x52] = "HD-DVD-RAM";
407 if (profile_number<0 || profile_number>=max_pno)
409 return texts[profile_number];