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