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