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 #pragma ident "%Z%%M% %I% %E% SMI"
27
28 #include <sys/types.h>
29 #include <stdlib.h>
30 #include <libintl.h>
31
32 #include "msgs.h"
33 #include "mmc.h"
34 #include "misc_scsi.h"
35 #include "device.h"
36 #include "main.h"
37 #include "util.h"
38 #include "toshiba.h"
39
40 void
info(void)41 info(void)
42 {
43 uchar_t *toc, *p, *conf;
44 int ret, toc_size;
45 uint_t bsize;
46 size_t cap = 0;
47 char *msg;
48 struct track_info *ti;
49
50 msg = gettext("Cannot read Table of contents\n");
51
52 get_media_type(target->d_fd);
53
54 (void) printf(gettext("\nDevice : %.8s %.16s\n"),
55 &target->d_inq[8], &target->d_inq[16]);
56 (void) printf(gettext("Firmware : Rev. %.4s (%.12s)\n"),
57 &target->d_inq[32], &target->d_inq[36]);
58
59 if (check_device(target, CHECK_DEVICE_NOT_READY)) {
60 (void) check_device(target, CHECK_NO_MEDIA |
61 EXIT_IF_CHECK_FAILED);
62 (void) check_device(target, CHECK_DEVICE_NOT_READY |
63 EXIT_IF_CHECK_FAILED);
64 }
65
66 if (verbose != 0) {
67 /*
68 * Determine the media type by reading the active profile
69 * from the profile list.
70 */
71 (void) printf(gettext("Media Type : "));
72
73 conf = (uchar_t *)my_zalloc(MMC_FTR_HDR_LEN);
74
75 if (get_configuration(target->d_fd, MMC_FTR_PRFL_LIST,
76 MMC_FTR_HDR_LEN, conf))
77 print_profile_name(read_scsi16(&conf[6]), 0, 1);
78 else
79 (void) printf(gettext("UNKNOWN\n"));
80
81 free(conf);
82
83 /*
84 * Get the start address of the last possible lead out.
85 */
86 cap = get_last_possible_lba(target);
87
88 /*
89 * The start address of the last possible leadout will only
90 * be zero if the disc is full or this drive does not support
91 * this method of determining capacity.
92 */
93 if (cap == 0)
94 cap = read_format_capacity(target->d_fd, &bsize);
95
96 /*
97 * Since both methods of determining the capacity of the
98 * media count the correct number of blocks, just multiply
99 * the capacity by the block size.
100 */
101 cap *= target->d_blksize;
102
103 if (device_type == CD_RW) {
104 (void) printf(gettext("Media Capacity : %.2f MB "),
105 ((double)cap/ONE_MB_BASE2));
106 } else {
107 /*
108 * For DVD's make sure we print out "Formatted Media
109 * Capacity". Don't do this for CD-RWs as only
110 * DVDs are formatted.
111 */
112 (void) printf(gettext("Formatted Media Capacity : "
113 "%.2f GB "), ((double)cap/ONE_GB_BASE10));
114 }
115
116 cap /= target->d_blksize;
117 (void) printf(gettext("(%u blocks)\n"), (uint_t)cap);
118 }
119
120 if (!check_device(target, CHECK_MEDIA_IS_NOT_BLANK)) {
121 (void) printf(gettext("Media is blank\n"));
122 exit(0);
123 }
124
125 /* Find out the number of entries in the toc */
126 toc = (uchar_t *)my_zalloc(12);
127 if (!read_toc(target->d_fd, 0, 1, 4, toc)) {
128 err_msg(msg);
129 } else {
130 toc_size = 256*toc[0] + toc[1] + 2;
131 free(toc);
132
133 /* allocate enough space for each track entry */
134 toc = (uchar_t *)my_zalloc(toc_size);
135
136 if (!read_toc(target->d_fd, 0, 1, toc_size, toc)) {
137 err_msg(msg);
138 exit(1);
139 }
140 (void) printf("\n");
141
142 /* l10n_NOTE : Preserve column numbers of '|' character */
143 (void) printf(gettext("Track No. |Type |Start address\n"));
144 (void) printf("----------+--------+-------------\n");
145
146
147 /* look at each track and display it's type. */
148
149 for (p = &toc[4]; p < (toc + toc_size); p += 8) {
150 if (p[2] != 0xAA)
151 (void) printf(" %-3d |", p[2]);
152 else
153 (void) printf("Leadout |");
154 (void) printf("%s |", (p[1] & 4) ? gettext("Data ") :
155 gettext("Audio"));
156 (void) printf("%u\n", read_scsi32(&p[4]));
157 }
158 }
159 (void) printf("\n");
160 ret = read_toc(target->d_fd, 1, 0, 12, toc);
161 if ((ret == 0) || (toc[1] != 0x0a))
162 /* For ATAPI drives or old Toshiba drives */
163 ret = read_toc_as_per_8020(target->d_fd, 1, 0, 12, toc);
164
165 if (ret && (toc[1] == 0x0a)) {
166 (void) printf(gettext("Last session start address: %u\n"),
167 read_scsi32(&toc[8]));
168 }
169 free(toc);
170 ti = (struct track_info *)my_zalloc(sizeof (struct track_info));
171
172 if (build_track_info(target, -1, ti) && (ti->ti_flags & TI_NWA_VALID)) {
173 (void) printf(gettext("Next writable address: %u\n"),
174 ti->ti_nwa);
175 }
176 free(ti);
177 exit(0);
178 }
179