1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <sys/types.h>
27 #include <stdlib.h>
28 #include <libintl.h>
29
30 #include "msgs.h"
31 #include "mmc.h"
32 #include "misc_scsi.h"
33 #include "device.h"
34 #include "main.h"
35 #include "util.h"
36 #include "toshiba.h"
37
38 void
info(void)39 info(void)
40 {
41 uchar_t *toc, *p, *conf;
42 int ret, toc_size;
43 uint_t bsize;
44 size_t cap = 0;
45 char *msg;
46 struct track_info *ti;
47
48 msg = gettext("Cannot read Table of contents\n");
49
50 get_media_type(target->d_fd);
51
52 (void) printf(gettext("\nDevice : %.8s %.16s\n"),
53 &target->d_inq[8], &target->d_inq[16]);
54 (void) printf(gettext("Firmware : Rev. %.4s (%.12s)\n"),
55 &target->d_inq[32], &target->d_inq[36]);
56
57 if (check_device(target, CHECK_DEVICE_NOT_READY)) {
58 (void) check_device(target, CHECK_NO_MEDIA |
59 EXIT_IF_CHECK_FAILED);
60 (void) check_device(target, CHECK_DEVICE_NOT_READY |
61 EXIT_IF_CHECK_FAILED);
62 }
63
64 if (verbose != 0) {
65 /*
66 * Determine the media type by reading the active profile
67 * from the profile list.
68 */
69 (void) printf(gettext("Media Type : "));
70
71 conf = (uchar_t *)my_zalloc(MMC_FTR_HDR_LEN);
72
73 if (get_configuration(target->d_fd, MMC_FTR_PRFL_LIST,
74 MMC_FTR_HDR_LEN, conf))
75 print_profile_name(read_scsi16(&conf[6]), 0, 1);
76 else
77 (void) printf(gettext("UNKNOWN\n"));
78
79 free(conf);
80
81 /*
82 * Get the start address of the last possible lead out.
83 */
84 cap = get_last_possible_lba(target);
85
86 /*
87 * The start address of the last possible leadout will only
88 * be zero if the disc is full or this drive does not support
89 * this method of determining capacity.
90 */
91 if (cap == 0)
92 cap = read_format_capacity(target->d_fd, &bsize);
93
94 /*
95 * Since both methods of determining the capacity of the
96 * media count the correct number of blocks, just multiply
97 * the capacity by the block size.
98 */
99 cap *= target->d_blksize;
100
101 if (device_type == CD_RW) {
102 (void) printf(gettext("Media Capacity : %.2f MB "),
103 ((double)cap/ONE_MB_BASE2));
104 } else {
105 /*
106 * For DVD's make sure we print out "Formatted Media
107 * Capacity". Don't do this for CD-RWs as only
108 * DVDs are formatted.
109 */
110 (void) printf(gettext("Formatted Media Capacity : "
111 "%.2f GB "), ((double)cap/ONE_GB_BASE10));
112 }
113
114 cap /= target->d_blksize;
115 (void) printf(gettext("(%u blocks)\n"), (uint_t)cap);
116 }
117
118 if (!check_device(target, CHECK_MEDIA_IS_NOT_BLANK)) {
119 (void) printf(gettext("Media is blank\n"));
120 exit(0);
121 }
122
123 /* Find out the number of entries in the toc */
124 toc = (uchar_t *)my_zalloc(12);
125 if (!read_toc(target->d_fd, 0, 1, 4, toc)) {
126 err_msg(msg);
127 } else {
128 toc_size = 256*toc[0] + toc[1] + 2;
129 free(toc);
130
131 /* allocate enough space for each track entry */
132 toc = (uchar_t *)my_zalloc(toc_size);
133
134 if (!read_toc(target->d_fd, 0, 1, toc_size, toc)) {
135 err_msg(msg);
136 exit(1);
137 }
138 (void) printf("\n");
139
140 /* l10n_NOTE : Preserve column numbers of '|' character */
141 (void) printf(gettext("Track No. |Type |Start address\n"));
142 (void) printf("----------+--------+-------------\n");
143
144
145 /* look at each track and display it's type. */
146
147 for (p = &toc[4]; p < (toc + toc_size); p += 8) {
148 if (p[2] != 0xAA)
149 (void) printf(" %-3d |", p[2]);
150 else
151 (void) printf("Leadout |");
152 (void) printf("%s |", (p[1] & 4) ? gettext("Data ") :
153 gettext("Audio"));
154 (void) printf("%u\n", read_scsi32(&p[4]));
155 }
156 }
157 (void) printf("\n");
158 ret = read_toc(target->d_fd, 1, 0, 12, toc);
159 if ((ret == 0) || (toc[1] != 0x0a))
160 /* For ATAPI drives or old Toshiba drives */
161 ret = read_toc_as_per_8020(target->d_fd, 1, 0, 12, toc);
162
163 if (ret && (toc[1] == 0x0a)) {
164 (void) printf(gettext("Last session start address: %u\n"),
165 read_scsi32(&toc[8]));
166 }
167 free(toc);
168 ti = (struct track_info *)my_zalloc(sizeof (struct track_info));
169
170 if (build_track_info(target, -1, ti) && (ti->ti_flags & TI_NWA_VALID)) {
171 (void) printf(gettext("Next writable address: %u\n"),
172 ti->ti_nwa);
173 }
174 free(ti);
175 exit(0);
176 }
177