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 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