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 2007 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 uint32_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 (use_media_stated_capacity) { 116 cap = get_last_possible_lba(target); 117 if (cap == 0) { 118 cap = read_format_capacity(target->d_fd, 119 &bsize); 120 } 121 } else { 122 /* 123 * For DVD drives use read_format_capacity to retrieve 124 * the media size, it could be 3.6, 3.9, 4.2, 4.7, 9.2 125 */ 126 if (device_type == CD_RW) { 127 cap = MAX_CD_BLKS; 128 } else { 129 /* 130 * For DVD drives use read_format_capacity to 131 * find media size, it can be 3.6, 3.9, 4.2, 132 * 4.7, 9.2 133 */ 134 cap = read_format_capacity(target->d_fd, 135 &bsize); 136 /* sanity if not reasonable default to 4.7 GB */ 137 if (cap < MAX_CD_BLKS) 138 cap = MAX_DVD_BLKS; 139 } 140 } 141 if (cap == 0) { 142 err_msg(gettext("Unable to find out media capacity\n")); 143 exit(1); 144 } 145 if (device_type == CD_RW) 146 cap = (cap + 1 - ti->ti_start_address) * 2048; 147 else 148 cap *= 2048 + 1; 149 150 if (size > cap) { 151 err_msg(gettext("Size required (%lld bytes) is greater " 152 "than available space (%lld bytes).\n"), size, cap); 153 exit(1); 154 } 155 156 if (device_type == DVD_MINUS) { 157 (void) printf(gettext("Preparing to write DVD\n")); 158 159 /* streamed file, we dont know the size to reserve */ 160 if (no_size == 1) { 161 size = cap - 1; 162 } 163 164 /* DAO requires that we reserve the size to write */ 165 if (debug) 166 (void) printf( 167 "DAO_MODE:reserving track size of = 0x%x\n", 168 (uint32_t)(size/2048)); 169 170 if (!set_reservation(target->d_fd, size/2048)) { 171 (void) printf(gettext( 172 "Setting reservation failed\n")); 173 exit(1); 174 } 175 } else if (device_type == DVD_PLUS_W) { 176 /* 177 * DVD+RW requires that we format the media before 178 * writing. 179 */ 180 (void) print_n_flush(gettext("Formatting media...")); 181 if (!format_media(target->d_fd)) { 182 (void) printf(gettext( 183 "Could not format media\n")); 184 exit(1); 185 } else { 186 int counter; 187 uchar_t *di; 188 189 /* poll until format is done */ 190 di = (uchar_t *)my_zalloc(DISC_INFO_BLOCK_SIZE); 191 (void) sleep(10); 192 for (counter = 0; counter < 200; counter++) { 193 194 ret = read_disc_info(target->d_fd, di); 195 196 if ((SENSE_KEY(rqbuf) == 2) && 197 (ASC(rqbuf) == 4)) { 198 (void) print_n_flush("."); 199 (void) sleep(5); 200 } else { 201 break; 202 } 203 } 204 } 205 206 (void) printf(gettext("done\n")); 207 } 208 209 210 free(ti); 211 } 212 213 write_next_track(TRACK_MODE_DATA, h); 214 215 h->bstr_close(h); 216 write_fini(); 217 fini_device(target); 218 exit(0); 219 } 220