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 #include <unistd.h> 32 #include "trackio.h" 33 #include "main.h" 34 #include "util.h" 35 #include "bstream.h" 36 #include "misc_scsi.h" 37 #include "msgs.h" 38 #include "device.h" 39 #include "mmc.h" 40 #include "transport.h" 41 42 void 43 write_image(void) 44 { 45 bstreamhandle h; 46 off_t size; 47 int no_size, ret; 48 49 get_media_type(target->d_fd); 50 51 /* DVD+RW does not have blanking and can be overwritten */ 52 if (device_type != DVD_PLUS_W) { 53 (void) check_device(target, CHECK_DEVICE_NOT_READY | 54 CHECK_DEVICE_NOT_WRITABLE | CHECK_MEDIA_IS_NOT_WRITABLE | 55 EXIT_IF_CHECK_FAILED); 56 } else { 57 (void) check_device(target, CHECK_DEVICE_NOT_READY | 58 EXIT_IF_CHECK_FAILED); 59 } 60 61 /* 62 * Simulation writing can't happen on DVD+RW's 63 * or DVD+R's. According to the MMC spec this 64 * operation is not supported. So we should 65 * bail out if the user tries to do a simulation 66 * write. 67 */ 68 if (simulation && (device_type == DVD_PLUS_W || 69 device_type == DVD_PLUS)) { 70 err_msg(gettext("Media does not support simulated writing.\n")); 71 exit(1); 72 } 73 74 write_init(TRACK_MODE_DATA); 75 76 if (image_file) { 77 h = open_iso_read_stream(image_file); 78 } else { 79 h = open_stdin_read_stream(); 80 } 81 82 if (h == NULL) { 83 err_msg(gettext("Cannot open %s: %s\n"), 84 image_file ? image_file : "stdin", get_err_str()); 85 exit(1); 86 } 87 no_size = 0; 88 ret = h->bstr_size(h, &size); 89 if (ret == 0) { 90 if ((str_errno == STR_ERR_NO_REG_FILE)) { 91 no_size = 1; 92 } else { 93 err_msg(gettext("Cannot stat input file: %s\n"), 94 get_err_str()); 95 exit(1); 96 } 97 } 98 if ((no_size == 0) && (size == 0)) { 99 err_msg(gettext("Input size(0) not valid\n")); 100 exit(1); 101 } 102 if (no_size == 0) { 103 off_t cap; 104 struct track_info *ti; 105 uint_t bsize; 106 107 ti = (struct track_info *)my_zalloc(sizeof (*ti)); 108 if (write_mode == TAO_MODE) 109 if (!build_track_info(target, -1, ti)) { 110 err_msg( 111 gettext("Unable to find out writable " 112 "address\n")); 113 exit(1); 114 } 115 if (device_type == CD_RW) { 116 if ((cap = get_last_possible_lba(target)) <= 0) { 117 if ((cap = read_format_capacity(target->d_fd, 118 &bsize)) <= 0) { 119 err_msg(gettext("Unable to determine " 120 "media capacity. Defaulting to " 121 "650 MB (74 minute) disc.\n")); 122 cap = MAX_CD_BLKS; 123 } 124 } 125 } else { 126 /* 127 * For DVD drives use read_format_capacity to 128 * find media size, it can be 3.6, 3.9, 4.2, 129 * 4.7, 9.2 130 */ 131 cap = read_format_capacity(target->d_fd, 132 &bsize); 133 /* 134 * Sanity check; Default to 4.7 GB if cap unreasonable 135 */ 136 if (cap < MAX_CD_BLKS) 137 cap = MAX_DVD_BLKS; 138 } 139 140 if (device_type == CD_RW) 141 cap = (cap + 1 - ti->ti_start_address) * 2048; 142 else 143 cap *= 2048 + 1; 144 145 if (size > cap) { 146 err_msg(gettext("Size required (%lld bytes) is greater " 147 "than available space (%lld bytes).\n"), size, cap); 148 exit(1); 149 } 150 151 if (device_type == DVD_MINUS) { 152 (void) printf(gettext("Preparing to write DVD\n")); 153 154 /* streamed file, we dont know the size to reserve */ 155 if (no_size == 1) { 156 size = cap - 1; 157 } 158 159 /* DAO requires that we reserve the size to write */ 160 if (debug) 161 (void) printf( 162 "DAO_MODE:reserving track size of = 0x%x\n", 163 (uint32_t)(size/2048)); 164 165 if (!set_reservation(target->d_fd, size/2048)) { 166 (void) printf(gettext( 167 "Setting reservation failed\n")); 168 exit(1); 169 } 170 } else if (device_type == DVD_PLUS_W) { 171 /* 172 * DVD+RW requires that we format the media before 173 * writing. 174 */ 175 (void) print_n_flush(gettext("Formatting media...")); 176 if (!format_media(target->d_fd)) { 177 (void) printf(gettext( 178 "Could not format media\n")); 179 exit(1); 180 } else { 181 int counter; 182 uchar_t *di; 183 184 /* poll until format is done */ 185 di = (uchar_t *)my_zalloc(DISC_INFO_BLOCK_SIZE); 186 (void) sleep(10); 187 for (counter = 0; counter < 200; counter++) { 188 189 ret = read_disc_info(target->d_fd, di); 190 191 if ((SENSE_KEY(rqbuf) == 2) && 192 (ASC(rqbuf) == 4)) { 193 (void) print_n_flush("."); 194 (void) sleep(5); 195 } else { 196 break; 197 } 198 } 199 } 200 201 (void) printf(gettext("done\n")); 202 } 203 204 205 free(ti); 206 } 207 208 write_next_track(TRACK_MODE_DATA, h); 209 210 h->bstr_close(h); 211 write_fini(); 212 fini_device(target); 213 exit(0); 214 } 215