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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/types.h> 30 #include <stdlib.h> 31 #include <libintl.h> 32 #include <unistd.h> 33 #include "trackio.h" 34 #include "main.h" 35 #include "util.h" 36 #include "bstream.h" 37 #include "misc_scsi.h" 38 #include "msgs.h" 39 #include "device.h" 40 #include "mmc.h" 41 #include "transport.h" 42 43 void 44 write_image(void) 45 { 46 bstreamhandle h; 47 off_t size; 48 int no_size, ret; 49 50 get_media_type(target->d_fd); 51 52 /* DVD+RW does not have blanking and can be overwritten */ 53 if (device_type != DVD_PLUS_W) { 54 (void) check_device(target, CHECK_DEVICE_NOT_READY | 55 CHECK_DEVICE_NOT_WRITABLE | CHECK_MEDIA_IS_NOT_WRITABLE | 56 EXIT_IF_CHECK_FAILED); 57 } else { 58 (void) check_device(target, CHECK_DEVICE_NOT_READY | 59 EXIT_IF_CHECK_FAILED); 60 } 61 62 write_init(TRACK_MODE_DATA); 63 64 if (image_file) { 65 h = open_file_read_stream(image_file); 66 } else { 67 h = open_stdin_read_stream(); 68 } 69 70 if (h == NULL) { 71 err_msg(gettext("Cannot open %s: %s\n"), 72 image_file ? image_file : "stdin", get_err_str()); 73 exit(1); 74 } 75 no_size = 0; 76 ret = h->bstr_size(h, &size); 77 if (ret == 0) { 78 if ((str_errno == STR_ERR_NO_REG_FILE)) { 79 no_size = 1; 80 } else { 81 err_msg(gettext("Cannot stat input file: %s\n"), 82 get_err_str()); 83 exit(1); 84 } 85 } 86 if ((no_size == 0) && (size == 0)) { 87 err_msg(gettext("Input size(0) not valid\n")); 88 exit(1); 89 } 90 if (no_size == 0) { 91 off_t cap; 92 struct track_info *ti; 93 uint_t bsize; 94 95 ti = (struct track_info *)my_zalloc(sizeof (*ti)); 96 if (write_mode == TAO_MODE) 97 if (!build_track_info(target, -1, ti)) { 98 err_msg( 99 gettext("Unable to find out writable address\n")); 100 exit(1); 101 } 102 if (use_media_stated_capacity) { 103 cap = get_last_possible_lba(target); 104 if (cap <= 0) { 105 cap = read_format_capacity(target->d_fd, 106 &bsize); 107 } 108 } else { 109 /* 110 * For DVD drives use read_format_capacity to retrieve 111 * the media size, it could be 3.6, 3.9, 4.2, 4.7, 9.2 112 */ 113 if (device_type == CD_RW) { 114 cap = MAX_CD_BLKS; 115 } else { 116 /* 117 * For DVD drives use read_format_capacity to 118 * find media size, it can be 3.6, 3.9, 4.2, 119 * 4.7, 9.2 120 */ 121 cap = read_format_capacity(target->d_fd, 122 &bsize); 123 /* sanity if not reasonable default to 4.7 GB */ 124 if (cap < MAX_CD_BLKS) 125 cap = MAX_DVD_BLKS; 126 } 127 } 128 if (cap == 0) { 129 err_msg(gettext("Unable to find out media capacity\n")); 130 exit(1); 131 } 132 if (device_type == CD_RW) 133 cap = (cap + 1 - ti->ti_start_address) * 2048; 134 else 135 cap *= 2048 + 1; 136 137 if (size > cap) { 138 err_msg(gettext("Size required (%lld bytes) is greater " 139 "than available space (%lld bytes).\n"), size, cap); 140 exit(1); 141 } 142 143 if (device_type == DVD_MINUS) { 144 (void) printf(gettext("Preparing to write DVD\n")); 145 146 /* streamed file, we dont know the size to reserve */ 147 if (no_size == 1) { 148 size = cap - 1; 149 } 150 151 /* DAO requires that we reserve the size to write */ 152 if (debug) 153 (void) printf( 154 "DAO_MODE:reserving track size of = 0x%x\n", 155 (uint32_t)(size/2048)); 156 157 if (!set_reservation(target->d_fd, size/2048)) { 158 (void) printf(gettext( 159 "Setting reservation failed\n")); 160 exit(1); 161 } 162 } else if (device_type == DVD_PLUS_W) { 163 /* 164 * DVD+RW requires that we format the media before 165 * writing. 166 */ 167 (void) print_n_flush(gettext("Formatting media...")); 168 if (!format_media(target->d_fd)) { 169 (void) printf(gettext( 170 "Could not format media\n")); 171 exit(1); 172 } else { 173 int counter; 174 uchar_t *di; 175 176 /* poll until format is done */ 177 di = (uchar_t *)my_zalloc(DISC_INFO_BLOCK_SIZE); 178 (void) sleep(10); 179 for (counter = 0; counter < 200; counter++) { 180 181 ret = read_disc_info(target->d_fd, di); 182 183 if ((SENSE_KEY(rqbuf) == 2) && 184 (ASC(rqbuf) == 4)) { 185 (void) print_n_flush("."); 186 (void) sleep(5); 187 } else { 188 break; 189 } 190 } 191 } 192 193 (void) printf(gettext("done\n")); 194 } 195 196 197 free(ti); 198 } 199 200 write_next_track(TRACK_MODE_DATA, h); 201 202 h->bstr_close(h); 203 write_fini(); 204 fini_device(target); 205 exit(0); 206 } 207