17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 51b01eaa0Szk194757 * Common Development and Distribution License (the "License"). 61b01eaa0Szk194757 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*4df0f9a3Sec158148 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate #include <sys/types.h> 297c478bd9Sstevel@tonic-gate #include <stdlib.h> 307c478bd9Sstevel@tonic-gate #include <libintl.h> 317c478bd9Sstevel@tonic-gate #include <unistd.h> 327c478bd9Sstevel@tonic-gate #include "trackio.h" 337c478bd9Sstevel@tonic-gate #include "main.h" 347c478bd9Sstevel@tonic-gate #include "util.h" 357c478bd9Sstevel@tonic-gate #include "bstream.h" 367c478bd9Sstevel@tonic-gate #include "misc_scsi.h" 377c478bd9Sstevel@tonic-gate #include "msgs.h" 387c478bd9Sstevel@tonic-gate #include "device.h" 397c478bd9Sstevel@tonic-gate #include "mmc.h" 407c478bd9Sstevel@tonic-gate #include "transport.h" 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate void 437c478bd9Sstevel@tonic-gate write_image(void) 447c478bd9Sstevel@tonic-gate { 457c478bd9Sstevel@tonic-gate bstreamhandle h; 467c478bd9Sstevel@tonic-gate off_t size; 477c478bd9Sstevel@tonic-gate int no_size, ret; 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate get_media_type(target->d_fd); 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate /* DVD+RW does not have blanking and can be overwritten */ 527c478bd9Sstevel@tonic-gate if (device_type != DVD_PLUS_W) { 537c478bd9Sstevel@tonic-gate (void) check_device(target, CHECK_DEVICE_NOT_READY | 547c478bd9Sstevel@tonic-gate CHECK_DEVICE_NOT_WRITABLE | CHECK_MEDIA_IS_NOT_WRITABLE | 557c478bd9Sstevel@tonic-gate EXIT_IF_CHECK_FAILED); 567c478bd9Sstevel@tonic-gate } else { 577c478bd9Sstevel@tonic-gate (void) check_device(target, CHECK_DEVICE_NOT_READY | 587c478bd9Sstevel@tonic-gate EXIT_IF_CHECK_FAILED); 597c478bd9Sstevel@tonic-gate } 607c478bd9Sstevel@tonic-gate 611b01eaa0Szk194757 /* 621b01eaa0Szk194757 * Simulation writing can't happen on DVD+RW's 631b01eaa0Szk194757 * or DVD+R's. According to the MMC spec this 641b01eaa0Szk194757 * operation is not supported. So we should 651b01eaa0Szk194757 * bail out if the user tries to do a simulation 661b01eaa0Szk194757 * write. 671b01eaa0Szk194757 */ 681b01eaa0Szk194757 if (simulation && (device_type == DVD_PLUS_W || 691b01eaa0Szk194757 device_type == DVD_PLUS)) { 701b01eaa0Szk194757 err_msg(gettext("Media does not support simulated writing.\n")); 711b01eaa0Szk194757 exit(1); 721b01eaa0Szk194757 } 731b01eaa0Szk194757 747c478bd9Sstevel@tonic-gate write_init(TRACK_MODE_DATA); 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate if (image_file) { 7729c5e6ceSzk194757 h = open_iso_read_stream(image_file); 787c478bd9Sstevel@tonic-gate } else { 797c478bd9Sstevel@tonic-gate h = open_stdin_read_stream(); 807c478bd9Sstevel@tonic-gate } 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate if (h == NULL) { 837c478bd9Sstevel@tonic-gate err_msg(gettext("Cannot open %s: %s\n"), 847c478bd9Sstevel@tonic-gate image_file ? image_file : "stdin", get_err_str()); 857c478bd9Sstevel@tonic-gate exit(1); 867c478bd9Sstevel@tonic-gate } 877c478bd9Sstevel@tonic-gate no_size = 0; 887c478bd9Sstevel@tonic-gate ret = h->bstr_size(h, &size); 897c478bd9Sstevel@tonic-gate if (ret == 0) { 907c478bd9Sstevel@tonic-gate if ((str_errno == STR_ERR_NO_REG_FILE)) { 917c478bd9Sstevel@tonic-gate no_size = 1; 927c478bd9Sstevel@tonic-gate } else { 937c478bd9Sstevel@tonic-gate err_msg(gettext("Cannot stat input file: %s\n"), 947c478bd9Sstevel@tonic-gate get_err_str()); 957c478bd9Sstevel@tonic-gate exit(1); 967c478bd9Sstevel@tonic-gate } 977c478bd9Sstevel@tonic-gate } 987c478bd9Sstevel@tonic-gate if ((no_size == 0) && (size == 0)) { 997c478bd9Sstevel@tonic-gate err_msg(gettext("Input size(0) not valid\n")); 1007c478bd9Sstevel@tonic-gate exit(1); 1017c478bd9Sstevel@tonic-gate } 1027c478bd9Sstevel@tonic-gate if (no_size == 0) { 10373e1749cSzk194757 off_t cap; 1047c478bd9Sstevel@tonic-gate struct track_info *ti; 1057c478bd9Sstevel@tonic-gate uint_t bsize; 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate ti = (struct track_info *)my_zalloc(sizeof (*ti)); 1087c478bd9Sstevel@tonic-gate if (write_mode == TAO_MODE) 1097c478bd9Sstevel@tonic-gate if (!build_track_info(target, -1, ti)) { 1107c478bd9Sstevel@tonic-gate err_msg( 1114d218355Szk194757 gettext("Unable to find out writable " 1124d218355Szk194757 "address\n")); 1137c478bd9Sstevel@tonic-gate exit(1); 1147c478bd9Sstevel@tonic-gate } 1157c478bd9Sstevel@tonic-gate if (device_type == CD_RW) { 116*4df0f9a3Sec158148 if ((cap = get_last_possible_lba(target)) <= 0) { 117*4df0f9a3Sec158148 if ((cap = read_format_capacity(target->d_fd, 118*4df0f9a3Sec158148 &bsize)) <= 0) { 119*4df0f9a3Sec158148 err_msg(gettext("Unable to determine " 120*4df0f9a3Sec158148 "media capacity. Defaulting to " 121*4df0f9a3Sec158148 "650 MB (74 minute) disc.\n")); 1227c478bd9Sstevel@tonic-gate cap = MAX_CD_BLKS; 123*4df0f9a3Sec158148 } 124*4df0f9a3Sec158148 } 1257c478bd9Sstevel@tonic-gate } else { 1267c478bd9Sstevel@tonic-gate /* 1277c478bd9Sstevel@tonic-gate * For DVD drives use read_format_capacity to 1287c478bd9Sstevel@tonic-gate * find media size, it can be 3.6, 3.9, 4.2, 1297c478bd9Sstevel@tonic-gate * 4.7, 9.2 1307c478bd9Sstevel@tonic-gate */ 1317c478bd9Sstevel@tonic-gate cap = read_format_capacity(target->d_fd, 1327c478bd9Sstevel@tonic-gate &bsize); 133*4df0f9a3Sec158148 /* 134*4df0f9a3Sec158148 * Sanity check; Default to 4.7 GB if cap unreasonable 135*4df0f9a3Sec158148 */ 1367c478bd9Sstevel@tonic-gate if (cap < MAX_CD_BLKS) 1377c478bd9Sstevel@tonic-gate cap = MAX_DVD_BLKS; 1387c478bd9Sstevel@tonic-gate } 139*4df0f9a3Sec158148 1407c478bd9Sstevel@tonic-gate if (device_type == CD_RW) 1417c478bd9Sstevel@tonic-gate cap = (cap + 1 - ti->ti_start_address) * 2048; 1427c478bd9Sstevel@tonic-gate else 1437c478bd9Sstevel@tonic-gate cap *= 2048 + 1; 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate if (size > cap) { 1467c478bd9Sstevel@tonic-gate err_msg(gettext("Size required (%lld bytes) is greater " 1477c478bd9Sstevel@tonic-gate "than available space (%lld bytes).\n"), size, cap); 1487c478bd9Sstevel@tonic-gate exit(1); 1497c478bd9Sstevel@tonic-gate } 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate if (device_type == DVD_MINUS) { 1527c478bd9Sstevel@tonic-gate (void) printf(gettext("Preparing to write DVD\n")); 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate /* streamed file, we dont know the size to reserve */ 1557c478bd9Sstevel@tonic-gate if (no_size == 1) { 1567c478bd9Sstevel@tonic-gate size = cap - 1; 1577c478bd9Sstevel@tonic-gate } 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate /* DAO requires that we reserve the size to write */ 1607c478bd9Sstevel@tonic-gate if (debug) 1617c478bd9Sstevel@tonic-gate (void) printf( 1627c478bd9Sstevel@tonic-gate "DAO_MODE:reserving track size of = 0x%x\n", 1637c478bd9Sstevel@tonic-gate (uint32_t)(size/2048)); 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate if (!set_reservation(target->d_fd, size/2048)) { 1667c478bd9Sstevel@tonic-gate (void) printf(gettext( 1677c478bd9Sstevel@tonic-gate "Setting reservation failed\n")); 1687c478bd9Sstevel@tonic-gate exit(1); 1697c478bd9Sstevel@tonic-gate } 1707c478bd9Sstevel@tonic-gate } else if (device_type == DVD_PLUS_W) { 1717c478bd9Sstevel@tonic-gate /* 1727c478bd9Sstevel@tonic-gate * DVD+RW requires that we format the media before 1737c478bd9Sstevel@tonic-gate * writing. 1747c478bd9Sstevel@tonic-gate */ 1757c478bd9Sstevel@tonic-gate (void) print_n_flush(gettext("Formatting media...")); 1767c478bd9Sstevel@tonic-gate if (!format_media(target->d_fd)) { 1777c478bd9Sstevel@tonic-gate (void) printf(gettext( 1787c478bd9Sstevel@tonic-gate "Could not format media\n")); 1797c478bd9Sstevel@tonic-gate exit(1); 1807c478bd9Sstevel@tonic-gate } else { 1817c478bd9Sstevel@tonic-gate int counter; 1827c478bd9Sstevel@tonic-gate uchar_t *di; 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate /* poll until format is done */ 1857c478bd9Sstevel@tonic-gate di = (uchar_t *)my_zalloc(DISC_INFO_BLOCK_SIZE); 1867c478bd9Sstevel@tonic-gate (void) sleep(10); 1877c478bd9Sstevel@tonic-gate for (counter = 0; counter < 200; counter++) { 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate ret = read_disc_info(target->d_fd, di); 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate if ((SENSE_KEY(rqbuf) == 2) && 1927c478bd9Sstevel@tonic-gate (ASC(rqbuf) == 4)) { 1937c478bd9Sstevel@tonic-gate (void) print_n_flush("."); 1947c478bd9Sstevel@tonic-gate (void) sleep(5); 1957c478bd9Sstevel@tonic-gate } else { 1967c478bd9Sstevel@tonic-gate break; 1977c478bd9Sstevel@tonic-gate } 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate } 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate (void) printf(gettext("done\n")); 2027c478bd9Sstevel@tonic-gate } 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate free(ti); 2067c478bd9Sstevel@tonic-gate } 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate write_next_track(TRACK_MODE_DATA, h); 2097c478bd9Sstevel@tonic-gate 2107c478bd9Sstevel@tonic-gate h->bstr_close(h); 2117c478bd9Sstevel@tonic-gate write_fini(); 2127c478bd9Sstevel@tonic-gate fini_device(target); 2137c478bd9Sstevel@tonic-gate exit(0); 2147c478bd9Sstevel@tonic-gate } 215