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
40void
41info(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